问:C语言中一共同拥有多少个keyword?

答:32个。

答不上来的没关系。非常正常。我们玩的是程序的艺术。而不是背数字。

只是这个特殊的数字1<<5也是非常好记的-.-。

问:sizeof是函数还是keyword?

第一次看到这个问题,你可能会认为有点莫名其妙,sizeof当然是函数了,由于sizeof后面都跟了个括号,这显然是函数的象征。

可是既然我这么问了。你可能也猜到了,sizeof不是个函数,它是个keyword!长期以来由于sizeof的"标准使用方法",导致sizeof极easy被理解为一个函数。

尝试执行以下的代码:

#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不是函数而是keyword,所以其本质也就全然不同了。函数是在执行时确定的,而keyword是在编译时确定的。差别的话。尝试执行例如以下程序:

#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())); // 函数没有被运行,依据其返回值类型从而输出4getchar();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");elseprintf("a < b\n");a = (unsigned int)a;printf("%u\n", a);  // unsigned int要用%u输出而不要习惯地写成%dgetchar();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;
}

转载于:https://www.cnblogs.com/mfrbuaa/p/5420224.html

C语言事实上不简单:sizeof相关推荐

  1. c语言详解sizeof

    原文地址:http://blog.sina.com.cn/s/blog_5da08c340100bmwu.html 一.sizeof的概念   sizeof是C语言的一种单目操作符,如C语言的其他操作 ...

  2. c语言 实现sizeof功能,C语言简单实现sizeof功能代码

    sizeof不是函数,而是运算符,C/C++语言编译器在预编译阶段的时候就已经处理完了sizeof的问题,也就是说sizeof类似于宏定义. 下面给出一个sizeof的一个宏定义实现版本 #defin ...

  3. c语言 sizeof_c语言详解sizeof

    一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等. 它并不是函数. sizeof操作符以字节形式给出了其操作数的存储大小. 操作数可以是一个表达式或括在括 ...

  4. c语言 手动实现sizeof,sizeof究竟是怎样实现的?

    sizeof,是在编译的时候,查找符号表,判断类型,然后根据基础类型来取值的,如果是struct则是看类型声明符号表来判定,如果字符串则是通过常 量表来判断,具体可以参考编译原理的符号表管理章节,一般 ...

  5. c++指针详解_c语言详解sizeof

    一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等. 它并不是函数. sizeof操作符以字节形式给出了其操作数的存储大小. 操作数可以是一个表达式或括在括 ...

  6. c语言面试题sizeof,C语言面试题——sizeof的注意点

    首先sizeof在C语言里是关键字,而不是一个函数,下面的语句执行之后,i的值是保持不变的, j = sizeof(++i + ++i); 下面是C语言里部分数据类型的sizeof的值: 下面是一道C ...

  7. c语言bnd文件,(((sizeof (X)) + (bnd)) (~(bnd)))

    1函数声明 首先,要实现类似printf()的变参函数,函数的最后一个参数要用...表示,如 int log(char * arg1, ...) 这样编译器才能知道这个函数是变参函数.这个参数与变参函 ...

  8. 装水体积c语言,C语言基础之--sizeof()运算符的使用以及注意

    sizeof是运算符,可用于任何变量名.类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号.它在编译时起作用,而不是运行时.让我们先看一个结构体: struct S1{ char c ...

  9. 黑马程序员--C语言基础之--sizeof()运算符的使用以及注意

    ------- IOS培训期待与您交流! ---------- sizeof是运算符,可用于任何变量名.类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号.它在编译时起作用,而不是运 ...

最新文章

  1. 英伟达发布史上最强GPU,却叫停了自动驾驶车路测
  2. “一碗牛肉面”引发的管理难题
  3. 目标检测学习笔记--DSSD算法
  4. SpringBoot:class path resource [xxxx.xml] cannot be opened because it does not exist
  5. CORS--跨域资源共享
  6. 来自看雪的手把手调试DebugPort清零
  7. xshell通过隧道连接_DNS安全之隧道攻击
  8. 前端学习(1948)vue之电商管理系统电商系统之排序
  9. 前段时间是Flash大战HTML5,现在是SliverLight“被遗弃”,我啊羡慕你们的热闹。...
  10. 【 Codeforces Round #552 (Div. 3) G】Minimum Possible LCM【埃氏筛】
  11. [XJTUSE编译原理] 第三章 上下文无关文法
  12. java中object类对象转换成int对象的两种方法
  13. 求最大值(三种方法)
  14. 在上海创业的日子之注册公司的详细流程
  15. Updating Scoop 遇到问题
  16. VINS-Mono代码阅读笔记(十三):posegraph中四自由度位姿优化
  17. 小鹿爬虫系列——静态网站页面爬取
  18. 【MV】ルカルカ ナイトフィーバー 鼻血姬、爱川饭拍版
  19. 通达信筹码循环指标源码 显示吸筹拉升出货的过程
  20. Win10打开软件提示comdlg32.ocx文件丢失?

热门文章

  1. 利用Aria2高速下载网盘文件
  2. 32 引脚_函数功能:定时器T0的中断服务子程序,使P3.7引脚输出音频方波
  3. java 对象视图框架_Stripes视图框架Java对象属性验证和prototype.js Ajax的测试
  4. 双极结型三极管的结构、特性、参数
  5. python随机函数笔记_Python笔记__random
  6. 4)lsof linux命令,***Linux命令实时监测系统(top,htop,iotop,lsof,tcpdump,netstat,vmstat,iostat)...
  7. 素筛打表(输出小于n最大素数)
  8. mysql树节点路径,关于mysql:从使用物化路径编码树的表中选择,按深度优先排序(无递归/ ltree)...
  9. android+引用非+android+工程,[非原创]编译android C++工程找不到exception handle的解决办法...
  10. 按冯诺依曼提出的计算机类型,2011年12月24日计算机一级考试题目广西