有符号和无符号数据类型之间的区别?

时间:2011-04-17 18:39:03

标签: c unsigned

main()
{
    char i=255;
    printf("\n%x\n",i);
}

输出:ffffffff

main()
{
    u_char i=255;
    printf("\n%x\n",i);
}

输出:ff

这里发生了什么?请通过一些好的链接向我解释输出。这是我猜的一个非常基本的事情,我真的很困惑......

4 个答案:

答案 0 :(得分:10)

你在这里看到的是由两件事引起的:

  • 255不符合char的范围(请注意,char等同于signed charunsigned char是实施定义的,但是显然在你的平台上是signed char)。结果行为是实现定义的,但通常它将换行并变为-1;见two's complement
  • integer promotion,因为printf()variable-argument function。积分类型参数(如char)会自动提升为int

因此printf()看到int的值为-1,并相应地打印其十六进制表示。

对于unsigned案例,没有环绕。 printf()看到int的值为255,并相应地打印其十六进制表示(省略前导零)。

答案 1 :(得分:4)

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) 

答案 2 :(得分:0)

char i = 255;通过将值转换为不适合的有符号类型来调用实现定义的行为(假设char仅为8位且明文char已签名,两者都是这也是特定于实现的。

答案 3 :(得分:0)

当你将8位有符号变量设置为值255时,它不能保持,在这种情况下,它似乎将负(高端)标志设置为1,因此如果值为-1,则值为-1它被签名,但随后它被转换为整数-1,即ffffffff