提问人:Sovereign 提问时间:8/13/2023 更新时间:8/13/2023 访问量:156
为什么在 C 中打印内存地址时不显示 0x?
Why does 0x not appear when I print a memory address in C?
问:
我正在尝试用 C 打印内存地址,这是我正在使用的代码
#include <stdio.h>
int main() {
int v = 10;
printf("Address of the v: %p\n",&v);
return 0;
}
输出应该以 0x 开头,但我没有这个东西,它表明我正在使用 MingW32 gcc 编译器
我将其更改为 64,当我再次输入代码时,输出是0061FF14
000000A57A7FF67C
当我使用 https://www.onlinegdb.com/ 输出正常时为 0x
我的机器是 64 位,我正在使用 vscode 编辑器,如何使地址显示为正常 0x
答:
2赞
0___________
8/13/2023
#1
为什么在 C 中打印内存地址时不显示 0x?
因为它不是标准规定的。实现可以选择是否打印它。
- 代码调用未定义的行为,因为指针必须具有指向 void (
void *
) 的类型指针。 - 如果实现不打印,只需将其添加到格式字符串中即可。
"0x"
printf("Address of the v: 0x%p\n",(void *)&v);
或者您的实现是否支持
它
printf("Address of the v: %#p\n",(void *)&v);
评论
0赞
Fredrik
8/13/2023
不是 DV,我正要评论说你永远不需要强制转换为 (void*),因为这是隐含的,但现在我发现有一个例外,那就是 printf 中的 %p,每天都能学到新东西。
1赞
Jonathan Leffler
8/13/2023
请注意,C 标准说(对于 printf()
修饰符): #
结果被转换为“替代形式”。对于 o 转换,...对于 x(或 X)转换,...对于 a、A、e、E、f、F、g 和 G 转换,...对于其他转换,行为是未定义的。转化说明符是“其他转化”之一,即使用未定义的行为。显然,平台可以定义行为,但在生产代码中使用它之前,您必须先确定它。#
p
%#p
1赞
Toby Speight
8/13/2023
@Fredrik,在任何 varargs 函数中使用时都需要强制转换;家庭只是其中最常遇到的。printf
评论
p
0x
%p
主要用于调试。进程中的地址通常甚至不能移植到同一系统的其他进程,更不用说其他系统了,这就是为什么该格式保留为实现定义,而不是由 C 标准更全面地指定。如果要对格式设置进行更精细的控制,可以将地址转换为类型(在整数类型中定义并使用整数类型提供的更完整的格式修改,包括对 中定义的格式使用宏。uintptr_t
<stdint.h>
PRIxPTR
<inttypes.h>
#include <inttypes.h>
printf("0x%" PRIXPTR "\n", (uintptr_t)pointer);
0xABCD0123EF456789
x
PRIxPTR
printf("0x%.12" PRIXPTR "\n", (uintptr_t)pointer)