数据类型、字节对齐
1.在VC6,32位X86系统下,有下列程序:
#include <stdio.h>
void main()
{
union
{
int k;
char i[2];
}*s, a;
s = &a;
s->i[0] = 0x39;
s->i[1] = 0x38;
printf("%x\n", a.k);
}
输出结果是()a.3839 b.3938 c.380039 d.以上答案都不正确
答案:如果int是4字节的话打印出来应该是0xcccc3839.看样子应该是VC平台。
共用体里里面定义的成员共用相同的存储空间,空间大小按照成员中最大的空间分配。
所以k和i[2]共用一块4字节内存,Win32下低字节在前,所以在内存顺序是
k0 k1 k2 k3,但这4个字节又与i[2]共用,即k0与i[0]共用,k1与i[1]共用,
所以i[0]=0x39,i[1]=0x38后同时给k0,k1赋值了。
由于VC调试态下默认将内存空间初始化为0xcc/0xcd,所以会k2=0xcc,k3=0xcc
打印出来k就是k3 k2 k1 k0 就是0xcccc3839了
补充:字节序可以参考《c/c++随笔》字节序一节:所谓大字节序就是高位在低字节,低位在高字节;小字节序则反之。简记为“低位为低字节的是小字节序,低位是高字节的是大字节序”。
2.
UCHAR *pucCharArray[10][10];
typedef union unRec
{
ULONG ulIndex;
USHORT usLevel[6];
UCHAR ucPos;
}REC_S;
REC_S stMax,*pstMax;
int i = sizeof(pucCharArray);
i = sizeof(stMax);
i = sizeof(pstMax);
i = sizeof(*pstMax);
四字节对齐方式时,i的值分别是:400,12,4,12
3.
typedef union unHead
{
UCHAR aucSrc[6];
struct tagContent
{
UCHAR ucFlag[3];
ULONG ulNext;
}Content;
}HEAD_S;
32CPU,VC编译环境下:在强制一字节对齐情况下,sizeof(HEAD_S)的值?在强制二字节对齐情况下,sizeof(HEAD_S)的值?在强制四字节对齐情况下,sizeof(HEAD_S)的值?
答案:7,8,8
补充:参考《C/C++随笔》字节对齐。
4.
#include <stdio.h>
#pragma pack(4)/*编译选项,表示4字节对齐*/
void main(int argc, char* argv[])
{
struct tagTest1
{
short a;
char d;
long b;
long c;
};
struct tagTest2
{
long b;
short c;
char d;
long a;
};
struct tagTest3
{
short c;
long b;
char d;
long a;
};
struct tagTest1 stT1;
struct tagTest1 stT2;
struct tagTest1 stT3;
printf("%d%d%d", sizeof(stT1), sizeof(stT2), sizeof(stT3));
}
#pragma pack()/*编译选项结束*/
输出结果是:
答案:121212,vc2008下测试
5.
#include <stdio.h>
void main()
{
union tagAAAA
{
struct
{
char ucFirst;
short usSecond;
char ucThird;
}half;
long lI;
}number;
struct tagBBBB
{
char ucFirst;
short ucSecond;
char c;
short d;
}half;
struct tagCCCC
{
struct
{
char ucFirst;
short usSecond;
char ucThird;
}half;
long lI;
};
printf("%d%d%d", sizeof(union tagAAAA), sizeof(struct tagBBBB)
, sizeof(struct tagCCCC));
}
在字节对齐为1下输出?在字节对齐为4下输出?
答案:4 6 8,8 8 12
字节序、位序
1.网络上传输的字节序默认是大字节的,如果逐渐是小字节序,在网络通信时则须进行字节序转换,如果主机是大字节序,为了程序的一致性及可移植性,最好也在程序中加上字节序转换的操作(空操作)。
A正确B错误
答案:A
2.0x12345678在采用BigEndian中内存的排列顺序是(),在采用LittleEndian内存中的排列顺序是()。【答案从左到右内存地址依次增加,十六进制】
A.12 34 56 78 B.34 12 78 56 C.78 56 34 12 D.56 78 12 34
答案:A C
3.在VC6 X86的32位系统下:
#include <stdio.h>
void main()
{
unsigned long ulA = 0x11000000;
printf("%x\r\n", *(unsigned char *)&ulA);
}
输出是
答案:0。考察对字节序基本概念及类型转换等的理解程度。
4.
#include <stdio.h>
//#pragma pack(1)
void main()
{
struct tagAAA
{
unsigned char ucID:1;
unsigned char ucPara0:2;
unsigned char ucState:6;
unsigned char ucTail:4;
unsigned char ucAvail;
unsigned char ucTail2:4;
unsigned long ulData;
}AAA_S;
printf("%d", sizeof(struct tagAAA));
}
//#pragma pack()
问:AAA_S在字节对齐分别为1、4的情况下,占用的空间大小是多少?
答案:9,12。字节对齐对含有位域元素的结构体所占用空间大小的影响。
5.程序的输出结果是()
#pragma pack(4)
void main()
{
unsigned char puc[4];
struct tagPIM
{
unsigned char ucPim1;
unsigned char ucData0:1;
unsigned char ucData1:2;
unsigned char ucData2:3;
}*pstPimData;
pstPimData = (struct tagPIM*)puc;
memset(puc, 0, 4);
pstPimData->ucPim1 - 1;
pstPimData->ucData0 = 2;
pstPimData->ucData1 = 3;
pstPimData->ucData2 - 4;
printf("%02X %02X %02X %02X\n", puc[0], puc[1], puc[2], puc[3]);
}
#pragma pack()
变量赋值和初始化
1.局部变量可以和全局变量重名,编译的时候不会出现错误,但一旦不小心,就可能导致使用错误变量,所以在定义局部变量的时候,不要和全局变量重名。
A正确 B错误
答案:A
2.
#include <stdio.h>
//#pragma pack(4)
int fun(int x, int y)
{
static int m = 0;
static int i = 2;
i += m + 1;
m = i+x+y;
return m;
}
void main()
{
int j = 3;
int m = 1;
int k;
k = fun(j, m);
printf("%d ", k);
k = fun(j, m);
printf("%d\n", k);
}
//#pragma pack()
输出是?
答案:7 15
3.
#include <stdio.h>
int x = 3;
void incre();
void main()
{
int i;
for (i=1; i<x; i++)
{
incre();
}
}
void incre()
{
static int x = 1;
x *= (x + 1);
printf("%d ", x);
return;
}
输出?
答案:2 6
4.全局变量定义在被多个.C文件包含着的头文件中,是不符合规范的。
A正确 B错误
答案:A