在C中,为什么不能打印负值?

时间:2017-02-22 01:04:59

标签: c printf octal

所以当我运行时:

printf("%o", -1);

打印出37777777777

为什么我会得到这个输出?

我认为它是-1的第一个补充,但为什么3一开始呢?

3 个答案:

答案 0 :(得分:9)

根据ISO C标准(C11 7.21.6.1 The fprintf function /8),%o以八进制打印出无符号值:

  

o,u,x,X - unsigned int参数转换为无符号八进制(o),无符号十进制(u)或无符号十六进制表示法(xX)...

根据您的输出,您有一个32位二进制补码int类型,其中-1表示为二进制:

11111111 11111111 11111111 11111111
\/\_/\_/ \_/\_/\__/\_/\_/\__/\_/\_/
 3 7  7   7  7   7  7  7   7  7  7

底线显示八进制表示(您所看到的)。

原因为什么你在前面看到3是因为每个八进制数字代表三位而32不能被三整除。

但是,您应该记住任何行为都可以接受。根据上面的ISO报价,%o需要unsigned int,并且根据后面的小节/9

  

如果任何参数不是相应转换规范的正确类型,则行为未定义。

如果您的int是64位,则会略有不同(显然也会更长)。 32位值在前面有两个额外位(32 % 3 == 2),但64位值只有一个(64 % 3 == 1)。所以你最终会得到:

11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
|\_/\_/\__/\_/\_/ \_/\_/\__/\_/\_/\__/\_/\_/ \_/\_/\__/\_/\_/\__/\_/\_/
1 7  7   7  7  7   7  7   7  7  7   7  7  7   7  7   7  7  7   7  7  7

答案 1 :(得分:0)

没有直接的方法可以用八进制甚至十六进制打印负数!!幸运的是,这样做的需要非常罕见。您当然可以测试数字是否为负并在其前打印一个减号:

 if (i < 0)
    printf("-%o",-i);
 else 
    printf("%o",i);

答案 2 :(得分:-1)

虽然在十进制以外的任何基数中显示有符号数字通常没有多大意义,但十进制没有什么特别之处,它表示它是唯一可以显示负数的基数。

例如,如果您有两个地址,您可能想知道它们之间的区别,这可能是负面的。当然,您希望将结果视为十六进制。

事实上,Python本身显示负十六进制值完全没问题。

所以,这是一种使用%d以外的说明符显示负数的方法,即%o

int x = -1;
printf("%s%o", x<0 ? "-" : "", x<0 ? 0u-x : 0u+x);