在尝试打印UTF-8字符的组成字节值时,我遇到了这个问题。
这是我编写的用于测试各种~0
操作的程序:
#include <stdio.h>
int main()
{
printf("%x\n", (char)~0); // ffffffff
printf("%x\n", (unsigned char)~0); // ff
printf("%d\n", sizeof(char) == sizeof(unsigned char)); // 1
printf("%d\n", sizeof(char) == sizeof(unsigned int)); // 0
printf("%d\n", (char)~0 == (unsigned int)~0); // 1
}
我不太明白为什么 char
会生成一个 int
大小的值,而 unsigned char
会生成一个 char
大小的值。
%x
期望一个unsigned int
。所以当你传入-1
时,它会被转换为最大的unsigned int
(在2's补码机器上)。我不知道这是否是标准,还是只发生在这里。使用%hhx
可以做正确的事情。但使用无符号类型会更有意义。 - ikegamichar
是有符号的,那么(char)~0
可能会被转换为(char)-1
。通过默认参数提升,(char)-1
会被转换为(int)-1
。 - Ian Abbottchar
传递给printf()
。在调用函数的过程中,它会自动转换为int
。当char
是有符号的(例如在您的实现中),(char)~0
是一个负值。当一个负值被重新解释为unsigned int
(当printf()
处理"%x"
时),它在最高有效位上有一堆二进制1
。 - pmg%x
需要一个unsigned int
。所以你传递的-1
(由于整数提升而成为int
)被解释为unsigned int
,在 2 的补码机器上得到最大的unsigned int
。使用%hhx
可以做正确的事情。但是使用无符号类型(例如unsigned char
)会更有意义。 - ikegami~0
将产生(int)-1
,因此将在有符号char
的范围内。 - Ian Abbott