【问题标题】:Is there any situation where this C code would not work as intended?是否存在此 C 代码无法按预期工作的情况?
【发布时间】:2013-10-20 04:13:30
【问题描述】:

在 x86 或 x64 计算机上是否存在此程序不会输出 0xFFFF 的任何可能情况?还是保证可以正常工作?

#include <stdlib.h>
#include <stdio.h>


int main()
{
    unsigned short int s = 0;
    unsigned long int l = 0xFFFFFFFF;
    memcpy(&s, &l, sizeof(short));
    printf("0x%.4X", s);
    return 0;
}   

【问题讨论】:

  • 应该改为printf("0x%.4hX", s);,以停止 printf 将其参数解释为(普通)int?
  • memset(&amp;s, 0xFF, sizeof(short)) 应该在所有平台上生成FFFF

标签: c type-conversion memcpy


【解决方案1】:

由于 C 不保证数据类型的最大大小,只保证最小大小,如果您使用带有 unsigned long 的编译器占用超过 32 位,其中初始字节的地址对应于最高有效字节unsigned long(即大端)这不会产生 FFFF 结果。

【讨论】:

  • 你的意思是最低有效字节吗?
  • 是的,你是对的。我描述了大端,但写了小端。
【解决方案2】:

,因为printf.4 说明符指定了最小值,而不是最大值。如果short int 有 32 位而不是 16 位(这是允许的,因为它只有根据标准的最小大小)将改为打印“0xFFFFFFFF”。

否则,鉴于 x86 和 x64 是 little-endian,这通常会发生,因为“FF”字节存储在 long int 的开头。 long int 的位模式为“FF FF FF FF”,short int 是从头开始获取的。

即使 long int 是 64 位,“FF”字节仍将位于开头:“FF FF FF FF 00 00 00 00”。

即使是以下输出“0xFFFF”,我们在 long int 中的 FF 字节也更少:

#include <stdlib.h>
#include <stdio.h>


int main()
{
    unsigned short int s = 0;
    unsigned long int l = 0xFFFF;
    memcpy(&s, &l, sizeof(short));
    printf("0x%.4X", s);
    return 0;
}

【讨论】:

  • 好点,short 可能超过 16 位,尽管我在实践中从未见过。
【解决方案3】:

我认为答案是肯定的,因为 x86/x64 是 little-endian

【讨论】:

  • 字节顺序由 C 实现决定,而不是硬件。该问题询问是否存在任何可能的情况,程序不会输出“0xFFFF”。有:我们甚至可以在 little-endian 硬件上编写 big-endian C 实现。
猜你喜欢
  • 1970-01-01
  • 2012-01-17
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
  • 2011-10-28
  • 2021-06-15
  • 2022-11-04
相关资源
最近更新 更多