&符号取的是指针变量p自身的地址,而非其指向的地址;要获取p指向的地址,直接使用p即可,因为p的值就是它所存储的目标地址。

直接用 & 取地址?不对,那是取指针变量本身的地址
很多人刚学时会误以为 &p 能拿到指针 p 指向的地址——其实不是。&p 返回的是指针变量 p 在栈/内存中的存放位置,而你真正想拿的,是它“存着的那个值”,也就是它指向的地址本身。
这个值就是指针变量的**值**,不需要任何运算符,直接用变量名即可:
int x = 42; int* p = &x; std::cout << p << std::endl; // 输出的就是 &x 的地址,例如 0x7ffeedb9a9ac
-
p是一个变量,类型是int*,它的值本来就是一个地址 - 打印时,
std::cout对int*类型默认以十六进制地址格式输出 - 如果要转成整数做计算(比如偏移),需显式转换:
uintptr_t addr = reinterpret_cast<uintptr_t>(p)</uintptr_t>
为什么 printf("%p", p) 要传 p 而不是 &p
因为 %p 期望接收一个地址值(void*),而 p 正好就是那个地址值;传 &p 会导致类型不匹配,且输出的是指针变量自身的地址,完全不是目标。
- 错误写法:
printf("%p", &p)→ 输出的是p这个变量在栈上的位置 - 正确写法:
printf("%p", static_cast<void>(p))</void>或直接printf("%p", p)(C++11 起允许隐式转void*) - 注意:不加
static_cast<void>(p)</void>在某些严格编译器(如启用-Wformat)下会报警
获取地址后想做算术?小心类型和对齐
指针值虽然是地址,但 C++ 中指针算术是按其所指类型的大小进行的。直接把地址当整数加减容易出错,除非你明确在做底层操作。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 比如
int* p,p + 1实际加的是sizeof(int)字节,不是 1 - 若真要按字节偏移,先转成
char*:char* base = reinterpret_cast<char>(p); base + 8</char> - 从整数地址重建指针必须用
reinterpret_cast,C 风格强制转换((int*)addr)在 C++ 中不推荐 - 读写非对齐地址(如把
int*强制指向奇数地址)可能触发硬件异常或未定义行为
调试时怎么看指针实际指向的地址
IDE(如 VS、CLion、VS Code + LLDB)调试器里,鼠标悬停或在监视窗口输入 p 就显示地址值;但要注意区分显示格式:
- GDB 中
print p显示地址,print *p才解引用看内容 - 某些调试器默认把指针显示为
0x...,但若类型被误识别(比如指针被当作整数),可能显示成十进制大数——这时应检查变量声明和符号表加载是否完整 - 释放后的指针(dangling pointer)仍可能保留旧地址值,不能靠“地址非零”判断是否有效
地址本身只是个数字,关键在它是否合法、可访问、未被回收——这点永远比“怎么打印出来”更重要。

















