4

请看一下这段代码:

#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通过这个问题,我才知道在 C 中,当变量被提升时,它的值保持不变。

4

2 回答 2

6

s正在升级为int,这里是 4 字节类型。这在所有 3 种情况下都发生。在前两个中, anintprintf()预期的,因为格式说明符用于将作为 传递的类型int。但是在最后一种情况下,您给出了一个格式说明符,它需要一个 8 字节的类型。

这是调用未定义的行为。

在您的情况下,它似乎在值的高字节中读取了零,有效地将已经符号扩展为 32 位的值零扩展到 64 位。但是,您不能依赖于执行此操作的结果 - 它可能正在读取内存或未一致初始化的寄存器。明天可能会有所不同。

参数的提升不依赖于格式字符串 - 您必须始终确保为您指定的格式传递正确的参数。所以 anint不会被提升为 a long。你需要自己转换它。

一个聪明的编译器应该给你一个警告。

于 2013-02-07T13:13:09.853 回答
1

调用 时,该变量不会提升为 long printf("s = %ld\n", s);。将其提升到 long 的正确方法是printf("s = %ld\n", (long) s);.

于 2013-02-07T13:13:27.070 回答