C 不同规格的Sizeof
我想知道为什么C 不同规格的Sizeof,c,types,sizeof,C,Types,Sizeof,我想知道为什么sizeof不能使用不同类型的格式说明符 我知道sizeof通常与%zu格式说明符一起使用,但我想了解一下后面发生了什么,以及为什么与%f一起使用时会打印nan,或者与%lf一起使用时会打印一个长数字 int a = 0; long long d = 1000000000000; int s = a + d; printf("%d\n", sizeof(a + d)); // prints normal size of expression printf("%lf\n", siz
sizeof
不能使用不同类型的格式说明符
我知道sizeof
通常与%zu
格式说明符一起使用,但我想了解一下后面发生了什么,以及为什么与%f
一起使用时会打印nan
,或者与%lf
一起使用时会打印一个长数字
int a = 0;
long long d = 1000000000000;
int s = a + d;
printf("%d\n", sizeof(a + d)); // prints normal size of expression
printf("%lf\n", sizeof(s)); // prints big number
printf("%f", sizeof(d)); // prints nan
sizeof
计算为size\t
类型的值。C99中size\u t
的合适说明符是%zu
。您可以在系统上使用%u
,其中size\u t
和unsigned int
是相同的类型,或者至少具有相同的大小和表示形式。在64位系统上,size\u t
值有64位,因此大于32位整数。在64位linux和OS/X上,此类型定义为无符号长
,在64位Windows上定义为无符号长
,因此在这些系统上使用%lu
或%llu
也可以
为不兼容的转换规范传递大小\u t
,具有未定义的行为:
- 程序可能会崩溃(如果使用
,可能会崩溃)%s
- 该程序可能会显示预期值(与
一样)%d
- 该程序可能会为
生成奇怪的输出,如%f
,或其他nan
printf
,它们具有不同的表示形式。传递一个整数,其中printf
需要一个double
将允许printf
从具有随机内容的寄存器或内存位置检索浮点值。在您的情况下,浮点寄存器恰好包含一个nan
值,但它可能在程序中的其他地方包含不同的值,或者在以后的某个时间,无法预期任何结果,行为未定义
一些遗留系统不支持%zu
,尤其是Microsoft的C运行时。在这些系统上,您可以使用%u
或%lu
并使用转换将大小\u t
转换为无符号
或无符号长
:
inta=0;
长d=1000000000000;
int s=a+d;
printf(“%u\n”,(未签名)大小(a+d));//应该打印8
printf(“%lu\n”,(无符号长)sizeof(s));//应该打印4
printf(“%llu\n”,(无符号长)sizeof(d));//根据系统打印4或8
我想知道后面发生了什么,以及为什么与%f
一起使用时会打印nan
,或者与%lf
一起使用时会打印一个长数字
有几个原因
首先,printf
不知道实际传递给它的附加参数的类型。它依赖于格式字符串来告诉它期望的附加参数的数量和类型。如果将size\u t
作为附加参数传递,但告诉printf
期望float
,则printf
将附加参数的位模式解释为float
,而不是size\u t
。整型和浮点型具有完全不同的表示形式,因此您将获得不期望的值(包括NaN)
其次,不同的类型有不同的大小。如果您将一个16位的short
作为参数传递,但告诉printf
使用%f
期望一个64位的double
,那么printf
将立即查看该参数后面的额外字节。不能保证size\u t
和double
具有相同的大小,因此printf
可能忽略实际值的一部分,或者使用内存中不属于该值的字节
最后,这取决于参数的传递方式。有些体系结构使用寄存器传递参数(至少对于前几个参数)而不是堆栈,并且不同的寄存器用于浮点数与整数,因此如果您传递一个整数并告诉它使用%f
,则需要一个双精度,printf
可能完全看错了地方,打印出完全随机的内容
printf
不智能。它依赖于您为要传递的参数类型使用正确的转换说明符 尝试编号5
而不是sizeof
。您将得到一个类似但简化的问题。返回类型sizeof
始终是相同的,它不会改变。请看,我将让其他人选择适当的副本。…sizeof通常与%zu一起使用-不,sizeof应仅与%zu
一起使用。这不是“通常”,而是“只能”。