【问题标题】:How do format specifiers work internally? [duplicate]格式说明符如何在内部工作? [复制]
【发布时间】:2016-11-04 09:00:05
【问题描述】:

考虑:

int x=0xdeadbeef;
char c=x;
printf("%x",c);

输出为ffffffef。 如何?为什么不是000000ef

【问题讨论】:

    标签: c


    【解决方案1】:

    32 位整数不适合 8 位字符,因此 char c=x;c=0xef 相同。

    那么显然char 已在您的编译器上签名并且0xef 大于127,因此它被转换为某个负值-17。

    当传递给printf 时,负值char 被提升为int,符号被保留(这被称为“默认参数提升”并且被所有可变参数函数使用)。 32 位二进制补码表示 -17 是 ffffffef。对于%x,您使用了错误的格式说明符; printf 期望 unsigned int。它尝试将已签名的数字显示为未签名。

    您可以通过将char 替换为uint8_t 来修复此错误。

    总体而言,此代码非常有问题,因为它依赖于许多未明确指定的行为。你不应该溢出有符号整数,你不应该使用char 来存储值,你应该努力使用正确的格式说明符。

    【讨论】:

      【解决方案2】:

      这不是“格式化说明符如何工作”的问题,而是“char 如何工作”的问题。

      没有任何其他类型信息的char 可以是有符号或无符号值,具体取决于编译器。如果你想要一个特定的签名,你应该使用unsigned charsigned char

      %x 格式指令需要一个 unsigned int,因此(本质上)将首先将 char 转换为 int,然后将其解释为 unsigned int。如果您的 char 已签名,它将在转换为 int 时进行符号扩展,这就是您获得所看到的值的原因。

      【讨论】:

        猜你喜欢
        • 2021-03-29
        • 2017-08-04
        • 1970-01-01
        • 1970-01-01
        • 2020-02-06
        • 1970-01-01
        • 1970-01-01
        • 2019-12-08
        • 2015-07-29
        相关资源
        最近更新 更多