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
一起使用。这不是“通常”,而是“只能”。