【发布时间】:2014-02-13 15:54:49
【问题描述】:
我最近在接受采访,被问到一个问题:
看看这段代码,写出它的输出:
unsigned char buff[] = { 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33 };
unsigned long *pD = (unsigned long *)buff;
unsigned short *pS = (unsigned short *)buff;
void *pEnd = &buff[sizeof(buff) - 1];
for (; pD < pEnd; pD++)
printf("0x%X\n", *pD);
for (; pS < pEnd; pS++)
printf("0x%X\n", *pS);
return 0;
现在假设系统是32bits,unsigned long是4个字节,答案是:
- 0x11111111
- 0x22222222
- 0x33333333
- 0x1111
- 0x1111
- 0x2222
- 0x2222
- 0x3333
- 0x3333
现在我的问题:
为什么它只用 unsigned short 变量打印 16 位? 我知道 unsigned short 是 2 个字节,但 printf 知道根据 %X 从堆栈中解析多少字节,读取为 unsigned int。我假设它会一直读取 4 个字节(无符号整数),有时会出现垃圾(或最终损坏的堆栈)。
你怎么看?
谢谢!
【问题讨论】:
-
请注意,从技术上讲,将
unsigned long传递给"%X"说明符是未定义的行为。它可以在大多数 32 位系统上工作(尽管人们可以很容易地想象一种实现方式它没有),但会在大多数 64 位系统上导致问题。 -
而在面试中问这个问题的人显然不是很能干。
-
unsigned long *pD = (unsigned long *)buff;可能会遇到对齐问题,并可能在各种平台上失败。unsigned short *pS = ...也。 -
@James Kanze
unsigned long到"%X"说明符也会在sizeof(int) < sizeof(long)与 16 位int和 32 位long一样失败,这在 2014 年的嵌入式系统中很常见。 -
@chux 是的。我刚刚提到了普通用户最常见的情况。