说明:本文所以程序都是基于32位系统,编译器为VS2010
首先需要明确的是sizeof是一个运算符,并不是一个函数,其次sizeof计算的是栈中对象所占的内存大小,所以对于全局变量和静态变量,sizeof就无法计算其所占内存大小。
1、 类型及变量
1.1、基本数据类型
对于C/C++语言中各基本类型,结果如下:
cout<<sizeof(char)<<endl; // 1
cout<<sizeof(short)<<endl; // 2
cout<<sizeof(int)<<endl; // 4
cout<<sizeof(long)<<endl; // 4
cout<<sizeof(long int)<<endl; // 4
cout<<sizeof(float)<<endl; // 4
cout<<sizeof(double)<<endl; // 8
cout<<sizeof(long double)<<endl; // 8
cout<<sizeof(long long)<<endl; // 8
cout<<sizeof(string)<<endl; // 32
// cout<<sizeof(void)<<endl; // 非法
对于sizeof(void),void是不完整的类型,而sizeof不允许使用不完整类型,所以出错。
1.2、 变量
int a;
cout<<sizeof(a)<<endl; // 合法
cout<<sizeof a<<endl; // 合法
//cout<<sizeof int<<endl; // 非法
上面前2条语句都是合法的,第3条是非法的,因为对于sizeof运算符来说,变量可以不用括号,但是对于类型名称,则必须要用括号。所以使用括号将会确保万无一失。
2、 指针
对于32位系统来说,指针始终占4个字节的存储空间(64位系统中,指针占8个字节),所以,不管是什么类型的指针变量,利用sizeof求得的结果都是4(只针对32位系统,其他位数系统可参考如下表格)。
8位系统 | 指针占1字节 |
16位系统 | 指针占2字节 |
32位系统 | 指针占4字节 |
64位系统 | 指针占8字节 |
char *b1;
int *b2;
double *b3;
cout<<sizeof(b1)<<endl; // 4
cout<<sizeof(b2)<<endl; // 4
cout<<sizeof(b3)<<endl; // 4
3、 数组
int a[5];
double *b[5];
double **c[5];
int (*e)[5];
int *(*f)[5];
cout<<sizeof(a)<<endl; // 20(4*5,见解释1)
cout<<sizeof(b)<<endl; // 20(4*5,见解释2)
cout<<sizeof(c)<<endl; // 20(4*5,见解释3)
cout<<sizeof(e)<<endl; // 4(见解释4)
cout<<sizeof(f)<<endl; // 4(见解释5)
解释1:a是一个含5个int型元素的一维数组,由于int型占4字节,所以大小为sizeof(int)*5= 4*5
解释2:b是一个含5个int*型元素的一维指针数组(一级指针),由于指针占4字节,所以大小为sizeof(int*)*5 = 4*5(如果改写为double* b[5]可能更好理解,两者写法都是一样的)。
解释3:c是一个含5个int**型元素的一维指针数组(二级指针),由于指针占4字节,所以大小为sizeof(int)*5 = 4*5(如果改写为double** c[5]可能更好理解,两者写法都是一样的)。
解释4:e是一个数组指针,指向一个含5个int型元素的一维数组,所以sizeof(e)等价于指针所占的字节数,所以大小为4
解释5:f是一个数组指针,指向一个含5个int*型元素的一维数组,所以sizeof(f)等价于指针所占的字节数,所以大小为4(如果改写为int* (*f)[5]可能更好理解,两者写法都是一样的)。
int aa[2][5];
double *bb[2][5];
double **cc[2][5];
int (*ee)[2][5];
int *(*ff)[2][5];
cout<<sizeof(aa)<<endl; // 40(4*2*5,见解释6)
cout<<sizeof(bb)<<endl; // 40(4*2*5,见解释7)
cout<<sizeof(cc)<<endl; // 40(4*2*5,见解释8)
cout<<sizeof(ee)<<endl; // 4(见解释9)
cout<<sizeof(ff)<<endl; // 4(见解释10)
解释6:aa是一个2*5的二维数组,数组中每个元素为int型,由于int型占4字节,所以大小为sizeof(int)*2*5 = 4*2*5
解释7:bb是一个含5个int*型元素的二维指针数组(一级指针),由于指针占4字节,所以大小为sizeof(int*)*2*5 = 4*2*5(如果改写为double* bb[2][5]可能更好理解,两者写法都是一样的)。
解释8:cc是一个含2*5个int**型元素的二维指针数组(二级指针),由于指针占4字节,所以大小为sizeof(int)*2*5 = 4*2*5(如果改写为double** cc[2][5]可能更好理解,两者写法都是一样的)。
解释9:ee是一个数组指针,指向一个含2*5个int型元素的二维数组,所以sizeof(ee)等价于指针所占的字节数,所以大小为4
解释10:ff是一个数组指针,指向一个含2*5个int*型元素的二维数组,所以sizeof(ff)等价于指针所占的字节数,所以大小为4(如果改写为int* (*ff)[2][5]可能更好理解,两者写法都是一样的)。
4、 表达式
先看一个例子程序:
int i = 3;
int j;
j = sizeof(++i + ++i);
printf("i=%d j=%d\n", i, j);
printf输出结果为i=3 j=4
从这个示例程序中,我们可以看到当sizeof中含有表达式的时候,那么表达式是不会做计算的,也就是不管加加减减,sizeof只是针对表达式中的变量计算大小。
下面将代码扩展了一下,看看大家能不能想到结果:
char m;
int n;
double dn;
cout<<sizeof (m + n)<<endl; // 4(见解释1)
cout<<sizeof (n + n)<<endl; // 4(见解释2)
cout<<sizeof (m * n)<<endl; // 4(见解释3)
cout<<sizeof (m * m)<<endl; // 4(见解释4)
cout<<sizeof (m + dn)<<endl; // 8(见解释5)
cout<<sizeof (m + m)<<endl; // 4(见解释6)
cout<<sizeof (2*m)<<endl; // 4(见解释7)
解释1:由于m是char,n是int,所以进行加法运算的时候,会将char型提升为int型,所以sizeof输出为4(但是不会计算m+n的结果值)。
解释2:不会进行类型提升,因为都是int型,所以输出4。
解释3:参考解释1。
解释4:参考解释2。
解释5:参考解释1。
解释6:参考解释2。
解释7:由于m是char,2是int,所以进行乘法法运算的时候,会将char型提升为int型,所以sizeof输出为4。
5、 函数
当用sizeof计算函数所占的内存空间的时候,输出结果等价于sizeof(函数返回值类型)。
double fun(double a, double b)
{
return a+b;
}
double da,db;
cout<<sizeof (fun(da,db))<<endl; // 8 (等价于sizeof(double))
未完待续。。。(下篇继续总结结构体,联合体,枚举类型,类等内容)