请看一下这段代码:
#include <stdio.h>
int main(void)
{
short s = -1;
printf("sizeof(short) = %lu\n", sizeof(short));
printf("sizeof(int) = %lu\n", sizeof(int));
printf("sizeof(long) = %lu\n", sizeof(long));
printf("s = %hd\n", s);
printf("s = %d\n", s);
printf("s = %ld\n", s);
return 0;
}
它输出为:
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 8
s = -1
s = -1
s = 4294967295
在最后一行中为什么s = 4294967295
代替s = -1
而不是this问题我开始知道在变量被提升时的C中,其值保持不变。
答案 0 :(得分:6)
s
正在升级为int
,此处为4字节类型。所有3例都发生了这种情况。在前两个中,int
是printf()
所期望的,因为格式说明符适用于将作为int
传递的类型。但是在最后一种情况下,你给出了一个格式说明符,它需要一个8字节的类型。
这是在调用未定义的行为。
在你的情况下,出现,在值的高字节中读取零,实际上零扩展到64位已经符号扩展为32位的值。但是,您无法依赖于执行此操作的结果 - 它可能是读取内存或未始终初始化的寄存器。明天可能会有所不同。
参数的提升不依赖于格式字符串 - 您必须始终确保为您指定的格式传递正确的参数。因此,int
不会被提升为long
。你需要自己转换它。
聪明的编译器应该给你一个警告。
答案 1 :(得分:1)
调用printf("s = %ld\n", s);
时,变量不会被提升为long。将其推广为正确的正确方法是printf("s = %ld\n", (long) s);
。