为什么大于x7F的十六进制编码字符在printf函数中显示不同?

时间:2016-09-05 16:46:59

标签: c hex printf

我希望下面的代码显示两条相等的行:

#include <stdio.h>

int main(void) {
    //printf("%x %x %x\n", '\x7F', (unsigned char)'\x8A', (unsigned char)'\x8B');
    printf("%x %x %x\n", '\x7F', '\x8A', '\x8B');
    printf("%x %x %x\n", 0x7F, 0x8A, 0x8B);
    return 0;
}

我的输出:

7f ffffff8a ffffff8b
7f 8a 8b

我知道这可能是溢出的情况。但为什么 ffffff 8a(4个字节)......?

1 个答案:

答案 0 :(得分:1)

根据{{​​3}},

'\x8A'

  

单字节整数字符常量,例如'a''\n''\13'

特别有趣的是以下内容。

  

此类常量具有类型int,并且值等于执行字符集中 c-char 的表示形式,作为映射到{{1的类型char的值}}

这意味着int到unsigned int的转换是实现定义的,因为'\x8A'可以是有符号或无符号的,具体取决于系统。如果char已签名,因为您似乎就是这种情况(并且很常见),那么char(为负)的值为32位'\x8A'int(也是否定的)。但是,如果0xFFFFFF8A未签名,则会变为char(这就是为什么代码中的注释行可以正常工作,因为您认为应该这样做。)

printf格式说明符0x0000008A用于cppreference。虽然%x期望printf并且您给它unsigned int,但即使标准说将错误类型传递给int(通常)是未定义的行为,它也不是#39;在你的情况下。这是因为从printfint的转换是明确定义的,即使相反也不是。