刚学C语言那会,对着sizeof什么意思纠结了好几天,一直误以为它是一个函数,写代码的时候还习惯性带上头文件,结果编译的时候直接报错,折腾半天才弄明白它的本质。

它不是普通函数,是C、C++里的运算符,作用就是算出一块数据在内存里占多少个字节。很多新手第一眼会把它当成函数,主要是写法上有括号,看起来和调用函数一模一样,这也是我当初踩的第一个误区。

写简单测试代码的时候,定义了int类型变量,套上sizeof,打印出来的结果是4。当时以为所有int都固定占4字节,后来换了别的编译环境,再跑一遍,结果就变了。才反应过来,这个数值不是写死的,会跟着操作系统、编译器、CPU架构发生变化,不是永远不变。

拿char来试的时候,输出永远是1,这点相对稳定。如果直接给类型,就要写括号,比如sizeof(int);但如果是变量,括号可以省略,直接写sizeofa就行。我第一次看到不带括号的写法,还以为代码写错了,反复核对了很久,才确认这种语法是合法的。

数组这块最容易混淆。声明一个数组chararr[10],用sizeof(arr)拿到的是整个数组全部字节,也就是10。但一旦把数组传入函数,函数参数里的数组会退化成指针,这时候再用sizeof,得到的就不是数组长度,而是指针本身的字节大小。当初写项目的时候,就是卡在这个地方,用它去算函数内部数组长度,算出来的数字完全不对,排查了一整个下午。

还有一个容易忽略的点,sizeof在编译阶段就完成计算,运行的时候不会执行里面的表达式。写了一句sizeof(i++),打印完i的值,发现i根本没有自增。当时愣了很久,以为代码逻辑有问题,后来才懂,括号里面的表达式不会被运行,编译器只看类型,不会去执行运算。

这只是我的个人感受,不是标准答案。不同编译器、不同平台下,sizeof的返回结果会有差别,实际写代码的时候,不能直接假定固定数值。

结构体的情况会更麻烦,里面会有内存对齐,不能简单把每个成员的sizeof结果相加。定义一个结构体,里面放char和int,单独算两个成员加起来是5,但是直接对结构体用sizeof,得到的却是8。编译器会自动填充空白字节,让内存地址对齐,提升访问效率,这也是很多初学者不会提前想到的。

平时写代码,最常用的场景就是动态分配内存,搭配malloc一起使用。malloc申请内存的时候,需要知道要开辟多少字节,直接写sizeof(类型),就不用手动去记字节大小,代码的可移植性会好很多。换别的平台编译,不用手动修改数字。

很长一段时间,我都习惯把sizeof的结果存进int变量,后来才发现,它本身返回的类型是size_t,是无符号整数类型。如果拿它和有符号的int做大小比较,很容易出现奇怪的逻辑错误,编译器有时候还不会给出警告,这种隐性问题很难排查。

到现在写代码,每次用到sizeof,都会下意识停下来确认,我现在取的是变量本身,还是指针,或是数组。很多bug不是语法写错,是脑子里默认它返回固定值,忽略了平台差异和数组退化的规则。

屏幕上光标停留在测试代码那一行,删掉之前写死的数字,换成sizeof写法,重新编译,程序正常跑通。