C语言其实不简单:sizeof
来源:互联网 发布:网络打印机的安装 编辑:程序博客网 时间:2024/05/16 15:35
问:C语言中一共有多少个关键字?
答:32个。
答不上来的没关系,很正常,我们玩的是程序的艺术,而不是背数字。不过这个特殊的数字1<<5也是很好记的-.-。
问:sizeof是函数还是关键字?
第一次看到这个问题,你可能会觉得有点莫名其妙,sizeof当然是函数了,因为sizeof后面都跟了个括号,这显然是函数的象征。但是既然我这么问了,你可能也猜到了,sizeof不是个函数,它是个关键字!长期以来由于sizeof的"标准用法",导致sizeof极容易被理解为一个函数。尝试运行下面的代码:
#include <stdio.h>int main(){ int num = 5; printf("%d\n", sizeof(num)); printf("%d\n", sizeof(int)); printf("%d\n", sizeof num); getchar(); return 0;}sizeof num居然也能正确输出4,可见它真的不是函数。不过sizeof int就是错误的了,它会产生如下错误:
error: expected primary-expression before "int"因为int前面只能跟auto、unsigned等,况且sizeof int要怎么来理解?是想计算大小呢?还是想表示"sizeof"类型的int变量呢。
查阅相关资料后总结如下:
当要计算变量的大小,例如基本类型(int、double)的变量,结构体变量(实例)时,可以不用括号,
当要计算一个类型时,不能省略括号。
不管什么场合都加上个括号,一是统一,而是能使程序可读性更强,且不易出错。我的目的并不是为了省略这个括号,省略了并不会让事情变得更好。我所想要表达的是sizeof的另一方面:因为现在我们知道了sizeof不是函数而是关键字,所以其本质也就完全不同了。函数是在运行时确定的,而关键字是在编译时确定的。区别的话,尝试运行如下程序:
#include <stdio.h>int main(){ int cc[10]; printf("%d\n", sizeof cc[999999999]); getchar(); return 0;}
上面的程序并不会出错,而是正确输出了4。并不是因为sizeof真的去找相对于cc首地址偏移999999999个位置的那个内存,正如上文所述,sizeof在编译时确定,所以它根据cc[X]的类型来确定大小。因为sizeof没有去访问这些地址,所以上面程序语法上没有任何问题,只不过逻辑上来说好像没什么实际意义。你能不能想到一个能证明sizeof真的没去"执行"括号里的东西呢?其实挺简单,试试运行如下代码:
printf("%d\n", sizeof(printf("hactrox")));其结果为4,而且"hactrox并没有被输出!没被输出说明sizeof真的没有去调用括号里的东西,但是为什么是4呢?因为sizeof是根据类型来确定的,对于printf或者是函数,sizeof以其返回值类型来确定。因为printf返回输出字符的数量,这个数量是int类型的,所以就相当于sizeof(int),所以是4。可能你还不知道printf的这个特性,试试运行以下代码:
#include <stdio.h>int main(){int num = printf("hactrox\n"); printf("%d\n", num); getchar(); return 0;}一个更直接的例子如下:
#include <stdio.h>int fun(){ printf("hactrox"); return 5;}int main(){ printf("%d\n", sizeof(fun())); // 函数没有被执行,根据其返回值类型从而输出4 getchar(); return 0;}
关于sizeof还有一个需要注意的地方。试试在脑海中执行下面的程序,得出一个结果以后再去运行它:
#include <stdio.h>#define SIZE_OF_ARRAY (sizeof(array) / sizeof(array[0]))int main(){ int array[] = {1, 2, 3, 4, 5}; for(int d = -1; d < (SIZE_OF_ARRAY-1); d++) printf("%d\n", array[d+1]); printf("END\n"); getchar(); return 0;}是不是跟你想的不太一样?为什么数组一个都没输出?原因就在于sizeof返回的是unsigned int,当int与unsigned int比较的时候,int是要转成unsigned int的,当int <0的时候,这种强制转换自然也就悲剧了,其结果是MaxValue(unsigned int)-abs(int),那么当d = -1的时候,自然就转变成一个相当巨大的数了,for循环当然也就不执行了。
#include <stdio.h>int main(){ int a = -1; unsigned int b = 10000; if(a > b) printf("a > b\n"); else printf("a < b\n"); a = (unsigned int)a; printf("%u\n", a); // unsigned int要用%u输出而不要习惯地写成%d getchar(); return 0;}
最后,因为刚才提到了unsigned int的最大值,C语言中想要输出int或是unsigned int的最大值要怎么办呢?有个简单的小技巧:
#include <stdio.h>int main(){ printf("Max value of unsigned int is: %u\n", ~(unsigned int)0); // 结果只能用%u表示 printf("Max value of int is: %d\n", ~(unsigned int)0 >>1); // 结果用%d, %u表示均可 getchar(); return 0;}
- C语言其实不简单:sizeof
- C语言其实不简单:数组与指针
- 其实自己不简单
- 其实,前端一点也不简单
- 招人---其实不简单
- 组织一些活动其实不简单
- C语言中的sizeof
- C语言中的sizeof
- sizeof C 语言
- C语言:sizeof
- C语言--sizeof
- C语言函数sizeof
- C语言关键---sizeof
- C语言详解sizeof
- c语言详解sizeof
- C语言 sizeof使用
- C语言详解sizeof
- c语言详解sizeof
- hdu 1087 Super Jumping! Jumping! Jumping! 【最大上升子串和】
- iOS 图像处理 - 图像拼接
- C/C++产生随机数
- JQuery中.AddClass()和.RemoveClass()
- 思维逻辑面试题
- C语言其实不简单:sizeof
- java socket 编程(一)
- hdu2112HDU Today trie+map
- 自己动手写CPU之第七阶段(3)——简单算术操作指令实现过程(续)
- uva 10385 - Duathlon(三分)
- 关于在MyEclipse中的jsp文件中引入…
- android.support.v4.app的Fragment…
- WebView背景无法透明的设置方法
- 图的遍历-深度优先遍历