关于sizeof

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的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是7c是多维数组,占用的空间大小是各维数的乘积,也就是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考察内存字节对齐方式,在以前的博客中有详解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值