提问人:Hemant 提问时间:3/17/2021 最后编辑:Hemant 更新时间:3/17/2021 访问量:139
是否有任何情况 %p 格式说明符不会在 0x 中打印地址。.格式
Is there any case where %p format specifier will not print address in 0x.. format
问:
在 C 语言中,我从控制台读取地址并将其存储在变量中。 我需要以十六进制 (0x...) 格式记录地址。
我有 2 个选择:
- %p
- %x
我尝试了选项 2 (%x)。它在 32 位和 64 位平台上的工作方式不同。这导致了不准确的程序行为。
现在,第二个选项 (%p) 也已定义实现。
因此,我想知道应该使用哪一个来在所有编译器和平台上保持一致的行为。
答:
1赞
Eric Postpischil
3/17/2021
#1
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);
}
这将确保使用十六进制来表示其位来打印指针。必须包含足够的信息来重现指针值(或等效值),因此显示必须包含有关指针的足够信息。但是,C 标准并未定义位的顺序和含义。保证至少打印 8 位数字(根据需要使用前导零),这在 32 位和 64 位指针的混合体系结构中具有一定的一致性,但 C 实现可以使用任意数量的位,因此可以打印更多数字的指针。如果您不考虑将位数固定为“一致”格式的一部分,则可以使用。uintptr_t
08
"0x%"
该类型是可选的,但很可能在现代 C 实现中提供。uintptr_t
(和限定符与例程本身无关;包含它们只是为了将带有它们的指针或不带有它们的指针传递给例程,而不会引起编译器的抱怨。const
volatile
评论
0赞
icebp
3/17/2021
您也可以将指针强制转换为 并使用 打印它。size_t
%zx
4赞
Eric Postpischil
3/17/2021
@icebp:C 标准不保证转换时保留有关指针的足够信息。C 实现可能具有 16 位,但需要 22 位来表示指针。size_t
size_t
评论
"%p"
%p