http://www.cnblogs.com/caixia/archive/2011/10/11/2206788.html
sizeof 在编译阶段处理的特性。由于 sizeof 不能被编译成机器码,所以 sizeof 作用范围内,也就是 () 里面的内容也不能被编译,而是被替换成类型。
int main()
{
int i=10;
printf("%d\n",i);
printf("%d\n",sizeof(i++));
printf("%d\n",i);
return 0;
}
正如网上人们所说,本人也被这个输出结果搞迷糊了,上网搜了下终于搞清楚了原委。
如果你觉得输出分别是,10,4,11,那么你就错了,错在了第三个,第一个是10没有什么问题,第二个是4,也没有什么问题,因为是32位机上一个int有4个字节。但是第三个为什么输出的不是11呢?居然还是10?
原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,sizeof()里面的任何表达式,编译器都不会运行的,只是会再编译期间使用所得结果进行替换。所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式。下面有一例子证明。
其实sizeof(xxx)中的xxx根本没有被编译成代码。
比如:
#include<stdio.h>
int f();
int main(void){
printf("%d\n", sizeof(f()));
return 0;
}
虽然f()根本没有函数体,但这个程序是可以被编译,连接的。因为其实根本没有生成调用f的代码。但如果f()不是在sizeof里面,连接的时候就会出错,说找不到f。从这个角度理解,也可以明白为什么i++不起作用了。
Size计算函数类型的问题
对函数使用sizeof,在编译阶段会被函数返回值的类型取代;无法对 void 类型使用sizeof,无法对函数指针使用 sizeof。
int f1(){return 0;};
double f2(){return 0.0;}
void f3(){}
cout<<sizeof(f1())<<endl; // f1() 返回值为 int ,因此被认为是 int
cout<<sizeof(f2())<<endl; // f2() 返回值为 double ,因此被认为是 double
cout<<sizeof(f3())<<endl; // 错误!无法对 void 类型使用 sizeof
cout<<sizeof(f1)<<endl; // 错误!无法对函数指针使用 sizeof
cout<<sizeof*f2<<endl; // *f2 ,和 f2() 等价,因为可以看作 object ,所以括号不是必要的。被认为是 double
利用sizeof考察c++和c标准对char类型定义的不同。
chara=’a’;
printf("%d\n",sizeof(a));
在c中结果是四,在c++结果是1.
C99标准的规定,'a'叫做整型字符常量(integer character constant),被看成是int型,所以在32位机器上占4字节。
ISO C++标准规定,'a'叫做字符字面量(character literal),被看成是char型,所以占1字节。
利用sizeof动态确定数组的长度
数组的大小是各维数的乘积*数组元素的大小。
char a[] = "abcdef";
int b[20] = {3, 4};
char c[2][3] = {"aa", "bb"};
cout<<sizeof(a)<<endl; // 7
cout<<sizeof(b)<<endl; // 20
cout<<sizeof(c)<<endl; // 6
数组a的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是7。c是多维数组,占用的空间大小是各维数的乘积,也就是6。可以看出,数组的大小就是他在编译时被分配的空间,也就是各维数的乘积*数组元素的大小。
int *d = new int[10];
cout<<sizeof(d)<<endl; // 4
d 是我们常说的动态数组,但是他实质上还是一个指针,所以sizeof(d)的值是4。
char*b="hellworld";
cout <<sizeof(b)/sizeof(b[0]) << endl; //这个时候b是指针类型,所以是
charc[]="helloworld";
cout << sizeof(c)/sizeof(c[0]) << endl;
再考虑下面的问题:
double* (*a)[3][6];
cout<<sizeof(a)<<endl; // 4
cout<<sizeof(*a)<<endl; // 72
cout<<sizeof(**a)<<endl; // 24
cout<<sizeof(***a)<<endl; // 4
cout<<sizeof(****a)<<endl; // 8
a 是一个很奇怪的定义,他表示一个指向double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。
既然a是执行double*[3][6]类型的指针,*a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。同样的,**a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof(double*)=24。***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。
另外还有使用sizeof考察内存字节对齐方式,在以前的博客中有详解。