6.3 sizeof(2)
解析:在访问内存时,如果地址按4字节对齐,则访问效率会高很多。这种现象的原因在于访问内存的硬件电路。一般情况下,地址总线总是按照对齐后的地址来访问的。例如你想得到0x00000001开始的4字节内容,系统首先需要以0x00000000读4字节,从中取得3字节,然后再用0x00000004作为开始地址,获得下一个4字节,再从中得到第一个字节,两次组合出你想得到的内容。但是如果地址一开始就是对齐到0x00000000,则系统只要一次读写即可。
考虑到性能方面,编译器会对结构进行对齐处理。考虑下面的结构:
- struct aStruct
- ...{
- char cValue;
- int iValue;
- };
直观地讲,这个结构的尺寸是sizeof(char)+sizeof(int)=6,但是在实际编译下,这个结构尺寸默认是8,因为第二个域iValue会被对齐到第4个字节。
在VC中,我们可以用pack预处理指令来禁止对齐调整。例如,下面的代码将使得结构尺寸更加紧凑,不会出现对齐到4字节问题:
- #pragma pack(1)
- struct aStruct...{
- char cValue;
- int iValue;
- };
- #pragma pack()
对于这个pack指令的含义,大家可以查询MSDN。请注意,除非你觉得必须,否则不要轻易做这样的调整,因为这将降低程序的性能。目前比较常见的用法有两种,一是这个结构需要被直接写入文件;二是这个结构需要通过网络传给其他程序。
注意:字节对齐是编译时决定的,一旦决定则不会再改变,因此即使有对齐的因素在,也不会出现一个结构在运行时尺寸发生变化的情况。
在本题中,第一种类的数据对齐是下面的情况:
¦bool¦----¦----¦----¦ < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
¦-------int---------¦
¦bool¦----¦----¦----¦
第二种类的数据对齐是下面的情况:
¦-------int---------¦
¦bool¦bool¦----¦----¦
所以类的大小分别是3×4和2×4。
答案:B类输出12字节,C类输出8字节。
面试例题3:求解下面程序的结果。[中国著名通信企业H公司面试题]
- #include <iostream>
- using namespace std;
-
- class A1
- {
- public:
- int a;
- static int b;
-
- A1();
- ~A1();
- };
-
- class A2
- {
- public:
- int a;
- char c;
- A2();
- ~A2();
- };
-
- class A3
- {
- public:
- float a;
- char c;
- A3();
- ~A3();
- };
-
- class A4
- {
- public:
- float a;
- int b;
- char c;
- A4();
- ~A4();
- };
-
- class A5
- {
- public:
- double d;
- float a;
- int b;
- char c;
- A5();
- ~A5();
- };
-
- int main() {
- cout<<sizeof(A1)<<endl;
- cout<<sizeof(A2)<<endl;
- cout<<sizeof(A3)<<endl;
- cout<<sizeof(A4)<<endl;
- cout<<sizeof(A5)<<endl;
- return 0;
- }
解析:因为静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,是不会计算在内的,所以sizeof(A1)是4。
为了照顾数据对齐,int大小为4,char大小为1,所以sizeof(A2)是8。
为了照顾数据对齐,float大小为4,char大小为1,所以sizeof(A3)是8。
为了照顾数据对齐,float大小为4,int大小为4,char大小为1,所以sizeof(A3)是12。
为了照顾数据对齐,double大小为8,float大小为4,int大小为4,char大小为1,所以sizeof(A3)是24。
答案:4,8,8,12,24。