【问题标题】:int16_t becomes int32_t F filledint16_t 变为 int32_t F 填充
【发布时间】:2013-11-30 20:19:44
【问题描述】:

我不明白为什么会这样

#include <stdio.h>
#include <stdint.h>


typedef int16_t my_type;

my_type value = 0xFC7F;

int main(int argc, const char * argv[])
{
  printf("0x%02X\n", value);
  printf("Type uses %lu bytes\n", sizeof(my_type));
}

输出这个

0xFFFFFC7F
Type uses 2 bytes
Program ended with exit code: 0

而不是

0xFC7F
Type uses 2 bytes
Program ended with exit code: 0

我在 OSX 10.9 上使用 XCode 5

【问题讨论】:

    标签: c


    【解决方案1】:

    您正在使用 printf 格式说明符 X 进行打印,它用于整数。

    使用h length specifier 将其显示为短片。

    Live demo

    【讨论】:

    • X 用于无符号整数。
    • 非常正确。 OP 应该使用 uint16_t,但 printf 没有抱怨。尽管从技术上讲,签名和未签名的混合很容易出错,但促销和强制都合谋提供了 OP 可能想要的东西。
    • @RayToal:我相信intunsigned int布局兼容的,所以它实际上很好(甚至到3.10/10),只是实现定义的。
    • 事实上,无论您是否使用h 标志,您都不能将%X 与具有负值的有符号类型一起使用。如果 OP 想要结果模 65536,则需要在将值传递给 printf 之前显式完成此模运算。
    【解决方案2】:

    每个[u]int_t 类型都带有printf 格式的宏。

    #include <inttypes.h>
    
    printf("%" PRId16 "\n", value);
    

    将正确打印您的值。

    应该使用宏名称中的d,因为这是一个有符号类型,16 代表类型的宽度。使用h 格式修饰符可能并不总是正确的,例如在int16_tint 相同而不是short 的机器上。

    编辑:如果你真的想看到你的 value 为十六进制,你应该首先使用不同的类型。 C 中的整数标记始终具有正值,因此在您的示例中 0xFC7F 大于 0x7FFF 并且绝对不适合 int16_t。十六进制常量的“第一次拟合”规则意味着它具有无符号或超过 16 位的类型。您的初始化以实现定义的方式将此正值转换为有符号值。不要那样做,这可能不便携。

    如果您对整数感兴趣只是因为它们的位模式(基本上是十六进制打印输出),请使用无符号类型

    uint16_t value = 0xFC7F;
    

    然后打印出来

    printf("%" PRIX16 "\n", value);
    

    或与

    printf("%#" PRIX16 "\n", value);
    

    如果你想让它带有 0x 前缀。

    【讨论】:

    • PRId16 是在哪里定义的?
    • @kilianc,对不起,我应该提到这一点,请查看我的编辑。
    • 应该是printf("0x%02" PRIX16 "\n", (uint16_t) value);
    • @kilianc,也许你应该试着倾听,抨击那些试图给你正确答案的人是让 me 伤心的原因。不,它不适合 2 字节有符号整数,INT16_MAX0x7FFF。您的初始化以实现定义的方式将该正值转换为int16_t
    • @JensGustedt 为我的咆哮道歉。感谢您的宝贵时间!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2011-03-13
    • 1970-01-01
    • 2019-12-05
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多