Printf %X 标识符 - 指针的奇怪行为

Printf %X identifier - Weird behaviour with pointers

本文关键字:指针 标识符 Printf      更新时间:2023-10-16

我最近在一次面试中被问到一个问题:


查看此代码并编写其输出:

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%Xn", *pD);
for (; pS < pEnd; pS++)
    printf("0x%Xn", *pS);
return 0;

现在假设系统是 32 位,无符号长是 4 个字节,答案是:

  • 0x11111111
  • 0x22222222
  • 0x33333333
  • 0x1111
  • 0x1111
  • 0x2222
  • 0x2222
  • 0x3333
  • 0x3333

现在回答我的问题:

为什么它只打印带有无符号短变量的 16 位?我知道无符号短是 2 个字节,但 printf 知道根据 %X 从堆栈中解析多少字节,该 %X 被读取为无符号 int。我假设它会始终读取 4 个字节(无符号 int),有时会是垃圾(或最终损坏的堆栈)。

你觉得怎么样?

谢谢!

*pS的类型为无符号短,因此使用此值。尽管 printf 需要 %X 的 int,但您提供了一个无符号的短整型,该短整型将提升为 int。所以顺序是:从数组中读取前 2 个字节,因为 *pS 是无符号短的。然后将此无符号短值提升为 int。

输出中没有指针。通过取消引用,您告诉 printf 输出一个短文,这就是它的作用。%X 仅将其显示为十六进制。