C 为什么在引用int变量的大小时必须使用%ld?

C 为什么在引用int变量的大小时必须使用%ld?,c,printf,C,Printf,我定义一个int,如下所示: int a; printf("int size is %ld\n", sizeof(a)); 当我想查找此int的大小时,我必须使用格式说明符%ld,如下所示: int a; printf("int size is %ld\n", sizeof(a)); 使用%d作为格式说明符时,出现以下错误: foo.c:7:10: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 ha

我定义一个int,如下所示:

int a;
printf("int size is %ld\n", sizeof(a));
当我想查找此int的大小时,我必须使用格式说明符%ld,如下所示:

int a;
printf("int size is %ld\n", sizeof(a));
使用%d作为格式说明符时,出现以下错误:

foo.c:7:10: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
    printf("int size is %d\n", sizeof(a));
问题是,当函数的参数为int时,为什么sizeof()的结果定义为长无符号int

sizeof(anything)的类型是
size\u t
,它是一些无符号整数常量。要打印它,您应该使用
%zu

“当函数的参数为int时?”

首先,
sizeof
是一个运算符,而不是一个函数

第二,为什么您认为它的结果类型应该与它的参数类型相同?如果要获得结构的大小,该怎么办?还是数组?还是指针?它应该如何产生一个结构的大小作为一个结构?这根本没有道理


它产生一个大小,因此其结果的类型是
size\u t
,您应该根据C标准使用
%zu

打印(6.5.3.4运算符的大小和对齐方式)

5两个运算符的结果值都是实现定义的, 其类型(无符号整数类型)为size\u t,在中定义
(和其他标题)

和(7.19通用定义

size_t,它是 sizeof算子

和(7.21.6.1 fprintf功能)

z指定以下d、i、o、u、x或x转换说明符 适用于大小\u t

因此,书写更为正确

printf( "int size is %zu\n", sizeof( a ) );
                     ^^^
运算符
sizeof
应用于什么类型的对象并不重要。它返回给定类型的对象占用的字节数,返回的字节数具有type
size\t


编译器会发出警告,因为在系统中,类型
size\u t
的定义类似于
unsigned long int
,但您使用的是
signed int
。使用格式说明符
%ld
时似乎不会发出警告,因为有符号长整型的秩等于对应于大小t的无符号长整型的秩。

sizeof
给出了操作数占用的存储单元数。结果类型是
size\t
,它是一种无符号类型,宽度足以表示系统能够存储的最大对象的大小。操作数的类型不影响结果的类型

使用C89编译器,您可以使用
%ld
打印
大小\u t
值,并将参数强制转换为
无符号长

 printf( "sizeof x = %ld\n", (unsigned long) sizeof x );
对于C99及更高版本的编译器,请使用
%zu

 printf( "sizeof x = %zu\n", sizeof x );

%zu
不可移植;它需要一个C99库。例如,MinGW:

$ cat zu.c
#include <stdio.h>

int main(void)
{
  printf("%zu\n", sizeof (int));
  return 0;
}

$ gcc zu.c -o zu

$ ./zu.exe
zu
如果对象的大小可能不适合int类型,请尝试使用unsigned long int:

printf("sizeof int == %lu\n", (unsigned long) sizeof object);
这可能仅在具有较小的
int
的系统(如16位)上才有必要,这样
int
只能增加到32767,而
无符号int
只能增加到65535,但可能存在大小超过这些值的对象


如果您确定该程序只需要移植到支持C99的目标,那么它就是。

对于类型为
size\u t
的参数,您应该使用
%zu
,例如
sizeof(x)
“当函数的参数为int时?”--两个错误。1)
sizeof
不是一个函数。这是一个接线员。2) 参数的类型无关紧要。If也可以是
char
long
etcThanks。有用的信息。打印
大小\u t
使用我最喜欢你的答案,因为它不会拖入不必要的C99垃圾;它显示了原始的、高度可移植的方法,如果您知道
x
是基本类型,您可以将其大小转换为
int
,并使用
%d
,或
无符号的
并使用
%u
。只有使用数组,或者非常大的结构,您才会担心大小不能用无符号整数表示。%lu与%zu一样不可移植,方式不同。如果您计算有多少实现的“size\u t”大于
无符号long
,有多少实现不支持
%zu
,我高度怀疑前者更少。@user3528438如果
sizeof
表达式的值适合
无符号long
(即在范围内[0,
ULONG\u MAX
),那么一切都很酷。类型
size\u t
本身是否比
unsigned long
宽并不重要。这个问题在答案中已经充分讨论过了。因此,每当出现未知宽度的变量/类型时,最好使用定义最宽的unsigned known type和类型转换进行打印:
printf(“sizeof int==%llu\n”,(unsigned long long)sizeof object);
@chux如果你知道类型是,比如说,某种内置的算术类型,而不是一个庞大的数组,那么这是完全不合理的。