[英]Use of sizeof operator in C
我写了一个代码来打印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
才能打印出较小的数字。
这两个都是错误的,您必须使用%zu
来打印size_t
类型的值,即sizeof
返回的值。
这是因为不同的值具有不同的大小,因此您必须将它们匹配。
像您一样不匹配是不确定的行为,因此任何事情都可能发生。
这是因为尺寸不匹配。 通过使用%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
来显示任何内容。
sizeof
的返回类型为size_t
。 从标准来看
6.5.3.4 The sizeof and _Alignof operators
5这两个运算符的结果值均由实现定义,其类型(无符号整数类型)为size_t,由
<stddef.h>
(及其他标头)定义。
size_t
是实现定义的。 在我的Linux中,size_t定义为__SIZE_TYPE__
。 关于这个主题,可以在这里找到详细信息。
在您的情况下,发生的情况是size_t实现的时间长于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
必须能够表示实现允许的最大对象的大小。
您说它不起作用 ,但是您不说它能做什么。 此意外行为的最可能原因是:
%d
期望为int
值。 sizeof(int)
类型为size_t
,该类型是无符号的,并且在许多平台上大于int
,从而导致未定义的行为。 转换说明符和传递的参数的类型必须一致,因为不同的类型以不同的方式传递给vararg函数,例如printf()
。 如果传递size_t
并且printf
需要一个int
,它将从错误的位置检索该值并产生不一致的输出(如果有的话)。
您说如果我放%ld
它会起作用 。 此转换可能有效,因为size_t
恰好与平台的long
相同,但这只是一个巧合,在64位Windows上, size_t
大于long
。
要解决此问题,您可以:
%zu
或 int
。 首先是正确的修复程序,但是某些C库不支持%zu
,最著名的是VS2013之前的Microsoft C运行时库。 因此,我建议使用第二种方法,以便携带更方便,并且对于明显较小的类型和对象也足够:
#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)
之前,输出对用户不可见。 甚至有可能在程序退出时未将输出刷新到控制台,从而导致您观察到的行为,但是这种环境并不常见。 建议在有意义的输出末尾输出换行符。 在您的情况下,不这样做会导致所有大小都像4481
这样的数字序列聚集在一起,这可能与您期望的一样,也可能不是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.