【发布时间】:2011-04-17 18:39:02
【问题描述】:
main()
{
char i=255;
printf("\n%x\n",i);
}
输出:ffffffff
main()
{
u_char i=255;
printf("\n%x\n",i);
}
输出:ff
这里发生了什么?请通过一些好的链接向我解释输出。我猜这是一个非常基本的事情,我真的很困惑......
【问题讨论】:
main()
{
char i=255;
printf("\n%x\n",i);
}
输出:ffffffff
main()
{
u_char i=255;
printf("\n%x\n",i);
}
输出:ff
这里发生了什么?请通过一些好的链接向我解释输出。我猜这是一个非常基本的事情,我真的很困惑......
【问题讨论】:
您在此处看到的情况是由两件事引起的:
255 不在char 的范围内(请注意,char 是否等同于signed char 或unsigned char 是由实现定义的,但显然在您的平台上它是signed char)。产生的行为是实现定义的,但通常它会环绕并变为 -1;见two's complement。printf() 是variable-argument function。整型参数(如char)会自动提升为int。所以printf() 看到int 的值为-1,并相应地打印其十六进制表示。
对于unsigned 情况,没有环绕。 printf() 看到 int 的值为 255,并相应地打印其十六进制表示(省略前导零)。
【讨论】:
C 编译器必须扩展传递给printf 的值(这称为“提升”),因为printf 是一个可变参数函数(可以使用不同的参数调用它)。对于char 类型的值,提升的值是int 类型。由于您的编译器的 char 类型似乎是有符号的,因此提升的值是符号扩展的。二进制:
char i = 255 // or: 11111111 in binary
int promoted_i = -1 // or: 11....11111 (usually, 32 or 64 ones)
在未签名的情况下,不会发生符号扩展:
char u = 255 // or: 11111111 in binary, same as above but with different interpretation
unsigned int pu = i // or: 00....0011111111 (8 ones, preceded by the appropriate number of zeroes)
【讨论】:
char i = 255; 通过将值转换为它不适合的有符号类型来调用实现定义的行为(假设 char 只有 8 位,而普通的 char 是有符号的,两者都是特定于实现的.
【讨论】:
当您将一个 8 位有符号变量设置为值 255(它不能保持)时,在这种情况下,它似乎将负(高端)标志设置为 1,因此如果出现以下情况,该值将为 -1它已签名,但随后被转换为整数 -1,即ffffffff。
【讨论】: