我像这样定义一个int:
int a;
当我想查询此int的大小时,我必须使用格式说明符%ld,如下所示:
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()的结果被定义为long unsigned int?
答案 0 :(得分:7)
sizeof(anything)
的类型是size_t
,这是一些无符号整数常量。要打印它,您应该使用%zu
。
答案 1 :(得分:5)
根据C标准(6.5.3.4 sizeof和alignof运算符)
5两个运算符的结果值是实现定义的, 它的类型(无符号整数类型)是 size_t ,定义于
<stddef.h>
(以及其他标题)。
和(7.19通用定义<stddef.h>
)
size_t,它是无符号整数类型的结果 sizeof运营商;
和(7.21.6.1 fprintf函数)
z 指定以下d,i,o,u,x或X转换说明符 适用于 size_t ....
因此写出
会更正确printf( "int size is %zu\n", sizeof( a ) );
^^^
运算符sizeof
应用于哪种类型的对象并不重要。它返回给定类型的对象占用的字节数,返回的数字类型为size_t
。
您的编译器会发出警告,因为系统类型size_t
的定义类似于unsigned long int
,但您使用的是signed int
。当您使用格式说明符%ld
时似乎不会发出警告,因为签名的long int类型的等级等于对应于size_t的无符号long int类型的等级。
答案 2 :(得分:3)
“当函数的参数是int?”
首先,sizeof
是一个操作员,而不是一个功能。
其次,为什么你认为它的结果类型应该与它的参数类型相同?如果你想获得结构的大小怎么办?还是阵列?还是一个指针?如何将结构的大小作为结构产生?它没有意义。
它产生一个大小,因此其结果类型为size_t
,您应使用%zu
进行打印。
答案 3 :(得分:2)
sizeof
给出操作数占用的存储单元数。结果类型为size_t
,这是一个宽度足以表示系统能够存储的最大对象大小的无符号类型。操作数的类型不会影响结果的类型。
使用C89编译器,您可以使用size_t
打印%ld
值并将参数转换为unsigned long
:
printf( "sizeof x = %ld\n", (unsigned long) sizeof x );
使用C99及更高版本的编译器,使用%zu
:
printf( "sizeof x = %zu\n", sizeof x );
答案 4 :(得分:0)
%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
糟糕!字面上打印的字符zu
,忽略了size参数。
对于您知道相当小的打印类型,请将大小调整为int
或unsigned
,并使用%d
或%u
转换说明符:
printf("sizeof int == %d\n", (int) sizeof (int));
如果对象的大小可能不适合int类型,请尝试unsigned long int:
printf("sizeof int == %lu\n", (unsigned long) sizeof object);
这可能仅在具有小int
的系统(例如16位)上是必需的,这样int
仅上升到32767并且unsigned int
到65535,但是可能存在对象其大小超过这些值。
如果您确定该程序只需要可移植到支持C99的目标,那么%zu
就是。