在 C 中,我从控制台读取地址并将其存储在变量中。我需要以十六进制(0x ...)格式记录地址。
我有两个选择:
- %p
- %X
我已经尝试过选项 2 (%x)。它在 32 位和 64 位平台上的工作方式不同。这导致程序行为不准确。
现在第二个选项 (%p) 也是实现定义的。
所以我想知道应该使用哪一个来在所有编译器和平台上保持一致的行为。
在 C 中,我从控制台读取地址并将其存储在变量中。我需要以十六进制(0x ...)格式记录地址。
我有两个选择:
我已经尝试过选项 2 (%x)。它在 32 位和 64 位平台上的工作方式不同。这导致程序行为不准确。
现在第二个选项 (%p) 也是实现定义的。
所以我想知道应该使用哪一个来在所有编译器和平台上保持一致的行为。
C 标准不保证任何打印指针的方法在所有实现中都是完全“一致的”,并且不能这样做,因为指针本质上是特定于内存模型的,不受 C 标准控制。
您可以控制打印指针的某些方面,例如确保它始终以十六进制打印,方法是将其转换为uintptr_t
并使用通常的printf
转换控件:
#include <inttypes.h> // Define PRIxPTR.
#include <stdint.h> // Define uintptr_t.
#include <stdio.h> // Declare printf.
void PrintPointer(const volatile void *p)
{
printf("0x%08" PRIxPTR, (uintptr_t) p);
}
这将确保使用十六进制打印指针以表示其位。必须包含足够的uintptr_t
信息来重现指针值(或等价物),因此显示必须包含有关指针的足够信息。但是,位的顺序和含义并未由 C 标准定义。08
保证至少打印八位数字(根据需要使用前导零),这使您在 32 位和 64 位指针的混合架构中具有一定的一致性,但 C 实现可以使用任意数量的位,因此可以打印指针更多的数字。"0x%"
如果您不考虑将位数固定为“一致”格式的一部分,则可以使用。
该uintptr_t
类型是可选的,但很可能在现代 C 实现中提供。
(const
andvolatile
限定符与例程本身无关;包含它们只是为了使带有或不带有它们的指针可以传递给例程而不会引起编译器的抱怨。)