我写了一个代码来打印C中不同数据类型的大小。
#include<stdio.h>
int main()
{
printf("%d", sizeof(int));//size of integer
printf("%d", sizeof(float));
printf("%d", sizeof(double));
printf("%d", sizeof(char));
}
这不起作用,但如果我将%d
替换为%ld
,则可行。我不明白为什么我必须用long int
来打印一个小范围的数字。
答案 0 :(得分:9)
这两个都是错误的,您必须使用%zu
来打印size_t
类型的值,这是sizeof
返回的值。
这是因为不同的值具有不同的大小,您必须匹配它们。
与你不匹配的未定义行为,所以任何事情都可能发生。
答案 1 :(得分:3)
这是因为尺寸不匹配。通过使用%zu
或使用%u
并转换为unsigned
,您可以解决问题。
目前,您的实施是未定义的行为。
printf("%u", (unsigned)sizeof(int));//size of integer
printf("%u", (unsigned)sizeof(float));
printf("%u", (unsigned)sizeof(double));
printf("%u", (unsigned)sizeof(char));
由于stdout
是新行缓冲,因此不要忘记在最后打印\n
以获取任何内容。
答案 2 :(得分:2)
sizeof
的返回类型为size_t
。从标准,
6.5.3.4 The sizeof and _Alignof operators
5两个运营商的结果的价值是 implementation-de fi ned,它的类型(无符号整数类型)是 size_t,在
<stddef.h>
(以及其他标题)中定义。
size_t
是实现定义的。在我的linux中,size_t被定义为__SIZE_TYPE__
。在这个主题上,可以找到详细信息here。
在您的情况下,发生size_t实现为长,超过int
。
答案 3 :(得分:0)
我不明白为什么我要用long int来打印一个小范围的数字。
因为size_t
可能代表比int
能够支持的值大得多的值;在我的特定实现中,最大大小值为18446744073709551615
,肯定不适合int
。
请记住sizeof
的操作数可能是带括号的类型名称或对象表达式:
static long double really_big_array[100000000];
...
printf( "sizeof really_big_array = %zu\n", sizeof really_big_array );
size_t
必须能够表示实现允许的最大对象的大小。
答案 4 :(得分:0)
你说它不起作用,但你没有说它是做什么的。出现这种意外行为的最可能原因是:
%d
需要int
值。 sizeof(int)
的类型size_t
是无符号的,在许多平台上,大于int
,导致未定义的行为。转换说明符和传递的参数的类型必须一致,因为不同的类型以不同的方式传递给vararg函数,如printf()
。如果您传递size_t
而printf
需要int
,则会从错误的位置检索该值并产生不一致的输出(如果有的话)。
如果我放%ld
,你说就可以了。此转换可能有效,因为size_t
恰好与您的平台long
具有相同的大小,但这只是巧合,在64位Windows上,size_t
大于{{1} }}
要解决此问题,您可以:
long
或%zu
。第一个是正确的修复,但有些C库不支持int
,最值得注意的是VS2013之前的Microsoft C运行时库。因此,我建议第二个对于明显具有小尺寸的类型和对象更具可移植性和足够性:
%zu
另请注意,您不输出换行符:根据环境的不同,在输出换行符或调用#include <stdio.h>
int main(void) {
printf("%d\n", (int)sizeof(int));
printf("%d\n", (int)sizeof(float));
printf("%d\n", (int)sizeof(double));
printf("%d\n", (int)sizeof(char));
return 0;
}
之前,用户将无法看到输出。甚至可能在程序退出时不将输出刷新到控制台,导致您观察到的行为,但这种环境并不常见。建议在有意义的输出结束时输出换行符。在您的情况下,不这样做会导致所有大小聚集在一起作为一系列数字,如fflush(stdout)
,这可能是您所期望的,也可能不是。