sizeof是c语言保留字吗,c关键字-sizeof的种种

熟悉c的人都知道,sizeof是一个关键字而不是一个宏或者库函数什么的,他的值是在编译时确定的,如果这个不了解,可以现看看这篇文章和这篇文章。 既然如此,让我们先看下面几个小例子:

sizeof(int);

sizeof(char);

sizeof(double);

sizeof(int);

sizeof(char);

sizeof(double);

上面三行sizeof的值是多少呢?这里我们假定在32位的x86系统下。我们会得到答案:4,1,8。这个没什么吧,大多数人都应该知道。那么,下面这个:

sizeof(int);

sizeof(long);

sizeof(int);

sizeof(long);

在32位x86下,这两个是多少呢?4,8?

实际上,答案是4,4。我们需要注意,long类型在32位系统下是32位的。那么,64位下结果又如何呢?8,8?其实答案是4,8。另一个需要注意的是,64位下的int是32位的。

上面只是热热身,现在,让我们看sizeof的下面几种情形:

1、sizeof一个结构体。

这个我就不说啥了,具体的参考这篇文章。至于空的结构体,下面会解释。

2、sizeof数组、指针等 先看下面两个例子:

char a[100];

char b[100]="helloworld!";

char c[]="helloworld!";

char* d=b;

sizeof(a);

sizeof(b);

sizeof(c);

sizeof(d);

char a[100];

char b[100]="helloworld!";

char c[]="helloworld!";

char* d=b;

sizeof(a);

sizeof(b);

sizeof(c);

sizeof(d);

在32位x86系统下,以上各是多少呢?

答案是:100,100,12,4。

为什么不是100,12,12,12呢? sizeof一个数组名,返回的是数组的大小,不管你数组里面放的什么数据。所以,第一个数组大小是100,第二个数组大小是100,第三个数组大小是12(别忘记"\0")。第四个呢?第四个不是一个数组名,而是一个指针!32位下指针大小永远是4,不管你是指向一个数组还是一个int还是一个char。 好,这个问题搞清楚之后,看下面这个程序:

int func(char a[100])

{

printf("%d\n", sizeof(a));

}

int main()

{

char *m = "helloworld!";

func(m);

char n[100]="helloworld!";

func(n);

}

int func(char a[100])

{

printf("%d\n", sizeof(a));

}

int main()

{

char *m = "helloworld!";

func(m);

char n[100]="helloworld!";

func(n);

}

这个程序会打印出什么结果呢?

答案是:4, 4。 为什么结果都是4?不是应该返回数组长度么?

这里出现又一个需要注意的地方:在作为参数传递的时候,数组名会退化为指针。也就是说,这里的func里的参数,虽然看上去是个数组名,但实际上还是个指针。 你了解了么?下面是几个练习,自己实验下^_^

char *p = NULL;

sizeof(p);

sizeof(*p);

int a[100];

sizeof(a);

sizeof(a[100]);

sizeof(&a);

sizeof(&a[0]);

char *p = NULL;

sizeof(p);

sizeof(*p);

int a[100];

sizeof(a);

sizeof(a[100]);

sizeof(&a);

sizeof(&a[0]);

懒得实验?答案分别是4,1,400,4,4,4。为什么?自己想想。

3、sizeof一些诡异的东西

(enum,空类,空struct) 所谓的诡异的东西,就是一些你想到的想不到的东西拿来sizeof。比如说sizeof一个enum类型是多少?一个空struct呢?一个空类呢? 这些诡异的东西在标准C中都没有作出规定,很大程度上都是编译器和系统结构相关的。 先来看一个:

int main()

{

enum week{Mon, Tue, Wed, Thu, Fri, Sat, Sun};

printf("%d\n", sizeof(enum week));

}

int main()

{

enum week{Mon, Tue, Wed, Thu, Fri, Sat, Sun};

printf("%d\n", sizeof(enum week));

}

这个你会得到什么样的结果呢?28? 在gcc或者vc下运行一把,你会得到答案:4。

为什么呢? 实际上,enum具体有多大取决于编译器的实现,目前大多数的编译器都将其实现为int类型。也就是说这里的enum被当作int类型(当然,使用上不一样)。这不是一成不变的,有些编译器,如VC++允许下面这种定义:

//注意这是个cpp文件

enum Color : unsigned char

{

red, green, blue

};

// assert(sizeof(Color) == 1);

//注意这是个cpp文件

enum Color : unsigned char

{

red, green, blue

};

// assert(sizeof(Color) == 1);

enum先说到这里,那么一个空的结构体是多大呢? 如果你擅长C语言,你可以很快的写出下面的程序:

//this is a *.c file

struct node{

}Node;

int main

{

printf("%d\n", sizeof(Node));

}

//this is a *.c file

struct node{

}Node;

int main

{

printf("%d\n", sizeof(Node));

}

很快,你可以验证出来结果是0。 没错,这很好理解。但是,如果你用的是c++呢?

//this is a *.cpp file

struct node{

}Node;

class node2{

}Node2;

int main()

{

printf("%d\n", sizeof(Node));

printf("%d\n", sizeof(Node2));

}

//this is a *.cpp file

struct node{

}Node;

class node2{

}Node2;

int main()

{

printf("%d\n", sizeof(Node));

printf("%d\n", sizeof(Node2));

}

(不怎么会写c++的我表示压力很大)以上这个c++的例子结果是多少呢?

为什么会得到1,1这个结果呢? 换句话说就是为什么sizeof一个空类和空结构体在c++下就是1呢?

这个原因要追朔到c++标准中的一句话:“no object shall have the same address in memory as any other variable”, 用中国话简单点说就是:不同的对象之间应该有不同的地址(为什么会有这样的规定?看这里)。

既然每个对象都必须有不同的地址,让我们假设上面代码中的Node的size是0,想想会出现什么样的后果?

Node a;

Node b;

Node a;

Node b;

a的大小是0,b的大小是0,那么,a和b的地址是不是很可能重复了?

所以,为了保证不同的对象拥有不同的地址,最简单的方法就是保证所有类型的大小都不是0。

所以,为了保证这点,大多数c++编译器都会给空结构或类加上一个冗余的字节保证类型不为空。

我的解释的清楚么?如果我的表达能力不够好,看这里,解释的足够详细。 当然,还有其他很多我没有想到的诡异的东西可以拿来sizeof,如果你想到了,欢迎跟我分享。至于c++中的sizeof类,基类,派生类,足够可以作为一个专门的文章了,先不再这里说,等我学会C++的再写一下相关内容(-_-")。

最后,给一个稍微给力点的程序,大家看看最终得到的结果是什么(注意这是一个c++程序):

//this is a cpp file

typedef struct weekday_st

{

enum week {sun=123456789,mon,tue,wed,thu,fri,sat,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak};

enum day{monring, moon, aftermoon};

}weekday_st;

int main(int argc, char *argv[])

{

printf( "sizeof(weekday_st)=%d\n ", sizeof(weekday_st));

printf( "sizeof(weekday)=%d\n ", sizeof(weekday_st::week));

printf( "sizeof(day)=%d\n ", sizeof(weekday_st::day));

return 0;

}

//this is a cpp file

typedef struct weekday_st

{

enum week {sun=123456789,mon,tue,wed,thu,fri,sat,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak};

enum day{monring, moon, aftermoon};

}weekday_st;

int main(int argc, char *argv[])

{

printf( "sizeof(weekday_st)=%d\n ", sizeof(weekday_st));

printf( "sizeof(weekday)=%d\n ", sizeof(weekday_st::week));

printf( "sizeof(day)=%d\n ", sizeof(weekday_st::day));

return 0;

}

anyShare分享到:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值