微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决是否存在 %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 限定符与例程本身无关;包含它们只是为了将带有或不带有它们的指针传递给例程而不会受到编译器的抱怨。 )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。