本文转自:http://www.eefocus.com/thinkpower/blog/08-09/157051_2ea48.html
第六章 预处理、const与sizeof
1. 预处理当中的宏定义注意:有时候宏展开以后会出现二意性问题。所以要注意使用括号。
2. sizeof的总结
sizeof是运算符,它的作用是返回一个类型或变量的长度,长度的单位是字节。
(1)基本数据类型sizeof的结果
平台:Windows XP,32位cpu;
* VC++6.0.
![](http://www.eefocus.com/data/myspace/13/65164//blog/10c1751d.jpg)
使用.c和.cpp作为文件后缀得到的结果是同样的.(有的程序同样是在VC++6.0下,后缀名不同,用的编译器不同,结果也不同。谭浩强的C语言第二版上的有个union类型的例题就是这样,用.c就可以编译通过,用.cpp作为后缀,就有错误。)
* Turbo C下的结果是不相同的。int类型是2,long double是10.
(2)结构体的sizeof问题(数据对齐问题)
为了方便对结构体内元素的访问和管理,以结构体里面最长的数据元素的长度为对齐单位,也就是说,结构体的长度一定是最长元素的整数倍。(不管结构体内的元素是大于还是小于处理器的位数)。这点跟书上的不同。书上的经过VC++验证,反正在VC++下是错的。并且最大的单位就是8个字节,即使结构体中有其他结构体的变量,也最大是以8个字节为单位对齐的。8字节是基本数据类型中占空间最大的单位。
结构体内小于最长元素的元素,如果是单独的,则占用一个最长单位;如果有几个连续的放在一起的,可以按最长单位顺序存放。知道满了或者剩下的不够超出为止,即换到下一个最长长度单位。
例1:
struct tagD
{
short d1;
double d2;
short d3;
};
结果为: 。以8个字节为单位,不足8的补齐。第一个short占2个,但是后面紧跟着是double占8个字节,所以让第一个short占8个字节,接下来double再占8个字节。最后一个short一样处理,不足8补成8个字节。
例2
struct tagD
{
double d2;
short d1;
short d3;
};
结果为: 。以8为单位,后面的两个short加起来只占4个,不够8个单位,所以一共是2个8字节,一共是16.
对于结构体中的位运算中的位段,是以4字节,即int所占字节的大小为单位对齐的。如果位段结构体中还有其他类型,那么同样是以最大字节数为对齐单位。
(3)对类sizeof
1. 空类占1个字节;
2. 类中的成员函数不计算在内,只计算成员变量占多少个字节;
3. 静态成员变量不计算在内,因为静态成员变量存放在全局数据区,而sizeof是计算栈中分配的大小。
4. 如果有虚函数或者纯虚函数的话,不管有多少个,只增加4个字节,这四个字节是虚函数表的指针所占的空间。
5. 多重继承的话也不会增加所占字节数;
6. 虚继承,会增加4个字节。
7. 虚继承有虚函数的类,那么新类增加4+4个字节。如果自己还有虚函数,则再增加4个字节。
8. 但非虚继承有虚函数的类,新类增加4个字节,而且即使自己还有虚函数,也不再增加额外的4个字节。说明它们用的是同一个虚函数表。
(注)以上提及的增加,对于空类来说,只是由1个字节变为,而不是在1上增加。
例:
class A
{
};
class A2
{
};
class B
{
void virtual funB();
};
class B2
{
void virtual funB2()=0;
};
class C: public A
{
};
class D: public virtual A
{
};
class E: public A,public A2
{
};
class F1: public virtual B
{
};
class F2: public virtual B
{
void virtual funf(void); //自己有虚函数,还会再增加4个字节。
};
class G1: public B
{
};
class G2: public B
{
void virtual funH(void); //自己有虚函数,但不增加4个字节。
};
void main(void)
{
cout<<"class A: "< cout<<"class B(have virtual func): "< cout<<"class C(derived from A): "< cout<<"class D(virtual derived from A): "< cout<<"class E(multiple derived from A and A2): "< cout<<"class F1(virtual derived from B,B have virtual func,F1 don't have virtual func): "< cout<<"class F2(virtual derived from B,B have virtual func,F2 also have virtual func): "< cout<<"class G1(derived from B,B have virtual func,G1 don't have virtual func): "< cout<<"class G2(derived from B,B have virtual func,G2 also have virtual func): "< }
(4)对数组名sizeof(退化为指针的问题)
等于将其元素类型做sizeof的结果×数组元素的个数。
而当数组名作为函数参数时,有个退化的问题。即在函数内部用sizeof(数组名),则得到是一个指针的大小,即4字节,非上面数据类型×数组元素的个数。
例:
char var[10];
int test(char var[])
{
return sizeof(var);
}
cout<<br /> cout<<br /> 返回的是4,而非10. 运行结果为: