c-是否存在%p格式说明符不会在0x中打印地址的情况.格式



在C中,我从控制台读取一个地址并将其存储在一个变量中。我需要用十六进制(0x…(格式记录地址。

我有两个选择:

  1. %p
  2. %x

我已经尝试了选项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实现中提供。

(constvolatile限定符与例程本身无关;它们的包含只是为了使带有或不带有它们的指针可以传递到例程,而不会受到编译器的抱怨。(