【问题标题】:Endianness -- why do chars put in an Int16 print backwards?字节序——为什么字符会向后放入 Int16 打印?
【发布时间】:2011-10-21 12:45:28
【问题描述】:

以下 C 代码,在 XCode 中编译并运行:

UInt16 chars = 'ab';
printf("\nchars: %2.2s", (char*)&chars);

打印“ba”,而不是“ab”。

为什么?

【问题讨论】:

  • 'ab' 是否允许作为文字?那是哪个编译器(平台)?
  • 它是 C.g++(我认为)在 XCode 后面运行。

标签: c xcode char endianness


【解决方案1】:

该特定实现似乎以 little-endian 格式存储多字符常量。在常量'ab' 中,字符'b' 是最低有效字节(小端),而字符'a' 是最高有效字节。如果您将chars 视为一个数组,它将是chars[0] = 'b'chars[1] = 'a',因此printf 会将其视为"ba"

另外,我不确定你认为维基百科有多准确,但关于 C syntax 它有这个部分:

多字符常量(例如'xy')是有效的,虽然很少 有用——他们让一个整数存储多个字符(例如 4 ASCII 字符可以适合 32 位整数,8 适合 64 位整数)。 由于字符被打包到一个 int 中的顺序不是 指定的、可移植的多字符常量的使用是困难的。

所以看来'ab' 多字符常量格式一般应该避免。

【讨论】:

    【解决方案2】:

    这取决于您正在编译/运行程序的系统。

    显然,在您的系统上,short 值以 0x6261 (ba) 的形式存储在内存中:小端方式。

    当您要求解码字符串时,printf 会逐字节读取您存储在内存中的值,实际上是 'b',然后是 'a'。因此你的结果。

    【讨论】:

      【解决方案3】:

      多字符字面量是实现定义的:

      C99 6.4.4.4p10:“包含多个字符(例如,'ab')或包含不映射到单字节执行字符的字符或转义序列的整数字符常量的值是实现定义。”

      gcc 和 icl 在 Windows 7 上打印 ba。tcc 打印 a 并完全删除第二个字母...

      【讨论】:

      • 实现定义的值和未定义的行为是不同的东西。
      【解决方案4】:

      您的问题的答案可以在您的标签中找到:Endianness。在小端机器上,首先存储最低有效字节。这是一个约定,根本不影响效率。

      当然,这意味着你不能简单地将它转换为字符串,因为字符的顺序是错误的,因为字符串中没有重要的字节,而只是一个序列。

      如果您想查看变量中的字节,我建议使用可以读取实际字节的调试器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-13
        • 1970-01-01
        相关资源
        最近更新 更多