问: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())); // 函数没有被运行,依据其返回值类型从而输出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的更多相关文章

  1. C语言事实上不简单:数组与指针

    之前在写C的时候,没怎么留意数组.就这么定义一个.然后颠来倒去的使用即可了.只是后来碰到了点问题.解决后决定写这么一篇博客,数组离不开指针.索性就放一起好了. 如今我定义了一个数组:int cc[10 ...

  2. c语言详解sizeof

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

  3. C语言简单实现sizeof功能代码

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

  4. C语言进阶——enum, sizeof, typedef 分析11

    枚举类型的使用方法: enum是C语言的 一种自定义类型 enum值是可以根据需要自定义的整型值 第一个enum的值默认为0 默认情况下的enum值是在前一个定义值的基础上加 1 enum类型的变量只 ...

  5. C语言关键字之sizeof

    C语言关键字 sizeof 是一个操作符,返回对象或类型所占内存字节数,类型为size_t(定义在<stddef.h>),有2种用法: sizeof unary-expression si ...

  6. 聊聊 C 语言中的 sizeof 运算

    聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...

  7. C语言 malloc()与sizeof运算的盲点

    //malloc()与sizeof运算的盲点 #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  8. C语言——strlen()和sizeof的区别

    strlen()和sizeof()的区别: strlen()——>C字符串库函数,返回字符串的真实长度.它是从内存某位置开始扫描,直到碰到结束符'\0'停止,返回计数器值. sizeof()—— ...

  9. sizeof既是关键字,又是运算符(操作符),但不是函数!

    sizeof是关键字吗 sizeof是关键字,这一点毋庸置疑.你不能将sizeof定义为任何标识符.查看C语言标准文档里的说明: sizeof是运算符(操作符)吗 C语言中,sizeof是运算符(操作 ...

随机推荐

  1. python魔法函数(二)之__getitem__、__len__、__iter__

    魔法函数会增强python类的类型,独立存在 __getitem class Company: def __init__(self, employees): self.employees = empl ...

  2. Luogu P4945 【最后的战役】

    本来以为做法一样,就是少带个$log$,结果发现看不懂出题人的题解(我好菜啊) 那就自己写一篇吧 比较简单的$DP$思路 状态定义: 前两个转移很好处理,第三个好像就不好办了 不妨暴力定义进状态里 设 ...

  3. CF 449D 题解(状压+容斥)

    状压妙啊... 本题的主体思路:状压+容斥原理(或状压+数位dp) 记g[i]表示按位与后结果所有位上至少有i个1的方案数 那么根据容斥原理,ans=g[0]-g[1]+g[2]-g[3]+g[4]. ...

  4. python3笔记(一)初识Python

    基础资料 什么是Python? Python官方网站 安装Python python的优点 完成同一个任务,C语言要写1000行代码,Java只需要写100行,而Python可能只要20行. pyth ...

  5. python 全栈开发,Day134(爬虫系列之第1章-requests模块)

    一.爬虫系列之第1章-requests模块 爬虫简介 概述 近年来,随着网络应用的逐渐扩展和深入,如何高效的获取网上数据成为了无数公司和个人的追求,在大数据时代,谁掌握了更多的数据,谁就可以获得更高的 ...

  6. python 全栈开发,Day105(路飞其他数据库表结构,立即结算需求)

    考试第三部分:Django 16.  列列举你熟悉的Http协议头以及作用.(1分) Accept-Charset: 用于告诉浏览器,客户机采用的编码 Host: 客户机通过这个头告诉服务器,想访问的 ...

  7. 步步为营-11-List<T>泛型的简单练习

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. DDD领域模型数据访问权限之权限(十二)

    实现权限的领域对象:BAS_Permission public partial class BAS_Permission:AggreateRoot { private IRepository<B ...

  9. 扩展BSGS算法

    求解A^x ≡ B mod P (P不一定是质数)的最小非负正整数解 先放几个同余定理: 一.判断如果B==1,那么x=0,算法结束 二.若gcd(A,P)不能整除 B,则 无解,算法结束 三.若gc ...

  10. python函数式编程——偏函数

    当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单. import functools def te ...