签名字符的unsigned char输出

时间:2017-12-01 18:08:46

标签: c types

我有以下代码:

char x = -1;
int y = x;

printf("%u\n", x);
printf("%u\n", y);

输出结果为:

4294967295
4294967295

我不明白为什么x可以得到这样的值。我知道unsigned char的最大值是255,而signed char 127的最大值。如何才能是4294967295?

4 个答案:

答案 0 :(得分:2)

对于使用可变参数的printf函数,任何小于intcharshort)的整数类型都会隐式提升为int。浮点数也是如此,float被提升为double

因此,您的char已被签名扩展为int,其值为-1,并且由于您将其打印为无符号,因此在2的补码中,您获得UINT_MAX

编辑:如下面的chux所述,如果您的char默认为无符号(这取决于您的编译器/平台),则答案为255。促销发生时,该值将为零扩展而不是符号扩展。

答案 1 :(得分:1)

变量的值为-1。 但是你在printf中指定了%u(unsigned int)

int是32位所以 2 ^ 32 = 4294967296 => -1 + 4294967296 = 4294967295 希望你能理解这一点。

答案 2 :(得分:0)

你因为这个而误用了一个格式说明符并调用了未定义的行为。我的理解是在每种情况下,转换为它的两个恭维二进制表示的数量对于-1或4294967295是相同的这就是为什么%u for signed通过忽略-ve leftmost bit来打印4294967295。当%d用于signed int时,它使用最左边的位作为-ve标志并打印-1。类似地,%u表示无符号打印无符号值,但%d导致它将数字视为有符号,因此打印-1

答案 3 :(得分:-1)

如果您的输入限定符为signed,请注意符号位,如果符号位为1,您将获得负值。虽然xsigned char,但您期望1 byte值,但由于符号位副本机制,您获得4 byte值。

x 值:

x =  -1 = 0000 0000 0000 0000 0000 0000 1111  1111
                                        |
                                        sign bit, this bit get's copied into remaining bytes, so it becomes like

        = 1111 1111 1111 1111 1111 11111 1111 1111 => calculates this => 4294967295 
        = |
         sign bit , now you are printing  in %u format i.e unsigned so it will ignore signed bit and you are getting big value.

如果您使用%d%i格式

进行打印,则相同
printf("%d\n", x); // it prints -1 bcz %d will check sign bit which is 1 i.e it will prints -ve value, so it's prints -1 

我只是试图解释为什么你得到这样的输出,但如果你没有使用正确的格式说明符,那么在某些评论中提到它是undefined behaviour。你可以参考不同的C标准。

编辑:为了证明我的观点(linux机器),让我们考虑下面的代码

int main()
{
        unsigned char x = -1;
        printf("%u\n",x);
        /*In above printf input is unsigned, so compiler won't 
         check sign bit, even though sign bit is 1, result 
        will be +ve only. */

        printf("%d\n",x);//some of you may expects -1 because of %d, it's wrong.
       /* In above printf it's printing 255 not because of format 
        specifier, it's because of your input qualifier(which is 
        unsigned in this case) */

        return 0;
}