是否有任何情况 %p 格式说明符不会在 0x 中打印地址。.格式

Is there any case where %p format specifier will not print address in 0x.. format

提问人:Hemant 提问时间:3/17/2021 最后编辑:Hemant 更新时间:3/17/2021 访问量:139

问:

在 C 语言中,我从控制台读取地址并将其存储在变量中。 我需要以十六进制 (0x...) 格式记录地址。

我有 2 个选择:

  1. %p
  2. %x

我尝试了选项 2 (%x)。它在 32 位和 64 位平台上的工作方式不同。这导致了不准确的程序行为。

现在,第二个选项 (%p) 也已定义实现。

因此,我想知道应该使用哪一个来在所有编译器和平台上保持一致的行为。

c 指针 stdio 格式说明符 实现定义行为

评论

4赞 Yunnosch 3/17/2021
是的。 是针对具体实施的,没有保证。但更重要的是,无论你打算用这个输出做什么,你很可能都无法用它做你打算做的事情。 也就是说,我认为我们可能正在研究一个 meta.stackexchange.com/questions/66377/what-is-the-xy-problem 请描述您希望通过使用您所要求的知识实现的目标。"%p"
5赞 Yunnosch 3/17/2021
好吧,我把这当成“我不会告诉你的”。请理解,这种回答降低了许多 StackOverflow 用户的帮助情绪,至少像我这样的人。祝你好运。至少考虑指定环境的更多详细信息。如前所述,语法是特定于环境的实现和间接的。你甚至相应地标记了。所以目前的答案至少是“视情况而定”,也可能是“我不会告诉你的”。
2赞 Bodo 3/17/2021
正如你所写的关于“案例 [...]如果无法正常工作“或”程序行为不准确“或”所有编译器和平台的行为一致“,请在您的问题中说明您定义的”正常工作“或”准确行为“,以及您的用例需要什么”一致行为”。%p
1赞 3/17/2021
所有编译器和平台?我认为在 16 位 MS-DOS 和 64 位 big-endian RISC 之间获得一致的结果可能是一个有点不切实际的目标。
1赞 chux - Reinstate Monica 3/17/2021
Hemant,“我想从控制台读取地址并在变量中读取它”是打印地址的相反问题。您需要打印函数指针还是只打印对象指针?具体目标是什么,阅读指针、写作还是两者兼而有之?

答:

1赞 Eric Postpischil 3/17/2021 #1

C 标准不保证任何打印指针的方法在所有实现中都是完全“一致”的,并且不能这样做,因为指针本质上是特定于内存模型的,而内存模型不受 C 标准控制。

您可以控制打印指针的某些方面,例如确保它始终使用十六进制打印,方法是将其转换为并使用通常的转换控件:uintptr_tprintf

#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);
}

这将确保使用十六进制来表示其位来打印指针。必须包含足够的信息来重现指针值(或等效值),因此显示必须包含有关指针的足够信息。但是,C 标准并未定义位的顺序和含义。保证至少打印 8 位数字(根据需要使用前导零),这在 32 位和 64 位指针的混合体系结构中具有一定的一致性,但 C 实现可以使用任意数量的位,因此可以打印更多数字的指针。如果您不考虑将位数固定为“一致”格式的一部分,则可以使用。uintptr_t08"0x%"

该类型是可选的,但很可能在现代 C 实现中提供。uintptr_t

(和限定符与例程本身无关;包含它们只是为了将带有它们的指针或不带有它们的指针传递给例程,而不会引起编译器的抱怨。constvolatile

评论

0赞 icebp 3/17/2021
您也可以将指针强制转换为 并使用 打印它。size_t%zx
4赞 Eric Postpischil 3/17/2021
@icebp:C 标准不保证转换时保留有关指针的足够信息。C 实现可能具有 16 位,但需要 22 位来表示指针。size_tsize_t