【问题标题】:Difference between signed and unsigned data types?有符号和无符号数据类型之间的区别?
【发布时间】: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

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

【问题讨论】:

    标签: c unsigned


    【解决方案1】:

    您在此处看到的情况是由两件事引起的:

    • 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,并相应地打印其十六进制表示(省略前导零)。

    【讨论】:

    • 你能不能再解释一下?为什么要推广? 255是二进制的11111111,所以2的comp是000000001。所以不应该打印0f吗?
    • @Naman:它正在得到推广,因为这是 C 标准所说的应该发生的事情。当我说“二进制补码”时,我的意思是“二进制补码算术”,而不是“值的二进制补码”。
    【解决方案2】:

    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) 
    

    【讨论】:

      【解决方案3】:

      char i = 255; 通过将值转换为它不适合的有符号类型来调用实现定义的行为(假设 char 只有 8 位,而普通的 char 是有符号的,两者都是特定于实现的.

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-02
          • 2011-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-01
          • 1970-01-01
          • 2017-04-05
          相关资源
          最近更新 更多