您的位置:首页 > 其它

sizeof用法大总结(上)

2015-10-05 22:19 323 查看
说明:本文所以程序都是基于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))


未完待续。。。(下篇继续总结结构体,联合体,枚举类型,类等内容)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: