使用%d说明符在C中打印unsigned char时出现奇怪的结果

时间:2011-02-18 18:19:31

标签: c printf

有点奇怪。我只使用unsigned char类型和负值。我有以下代码。

 #include <stdio.h>

 int main(int argc, char* agrv[]){
   unsigned char c = -3;
   printf("%d, %u, %d, %u\n", c, c, ~c, ~c);
 }

输出是,

253, 253, -254, 4294967042

我无法弄清楚最后三个值。 %d和%u真的有什么作用?

4 个答案:

答案 0 :(得分:3)

%d格式打印出int%u打印出unsigned int。关于unsigned char值的所有算术都是通过先将它们转换为int并对int值进行操作来完成的,因此~c(等于-1 - (int)c )将返回负int值。在打印之前需要进行显式演员才能得到unsigned char结果(而printf的调用会将其转回int)。

答案 1 :(得分:1)

“%d”打印为带符号的数字,%u打印为无符号数字。

当您将char传递给int时,

printf会升级为printf。 {{1}}通常会将任何值发生在堆栈上,并将其解释为您使用格式指定的类型。在典型的机器上(显然包括你的机器)意味着它将位模式视为两个补码。

答案 2 :(得分:1)

c是11 11 11 01(2的补码)  1.当打印为有符号整数(%d)时,它解释32位c      00000000-00000000-00000000-11111101等于十进制253。  2.%u也打印与上面相同的数字(字)为正。

~c是1111111111-11111111-11111111-00000010

  1. 以%d打印时,其-254(再次为2'c补充)

  2. 解释为无符号时的数字(255 * 256 ^ 3 + 255 * 256 ^ 2 + 255 * 256 + 2),等于4294967042。

答案 3 :(得分:0)

好吧,我不会去printf()。我宁愿停在:

unsigned char c = -3;

并质疑这种自相矛盾的初始化的目的 - 使用-3来初始化unsigned char。

-3是有符号整数。如果使用符号幅度/ 1'补码/ 2的补码来表示该值,则-3(int)需要多于一个字节用于表示。当赋值给unsigned char时,该值将导致溢出,从而产生未定义的行为。