You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

&地址与指针地址的差异:十六进制与指针类型数据解析

指针地址输出:%x与%p的差异解析

核心问题:格式符用途与地址位数不匹配

你看到的输出差异,本质是错误使用格式符导致的地址截断,具体细节如下:

  • %x的本质:%x是C标准中用于输出32位无符号整数的十六进制格式符。当你用它打印64位系统下的指针(指针为8字节/64位)时,会仅保留地址的低32位,直接丢弃高位字节。你看到的a6bff9c4就是完整地址的低32位部分。
  • %p的本质:%p是C标准专门为指针设计的格式符,会根据当前系统的指针位数(32位/64位)完整输出指针的全部字节。在64位系统下,它会输出完整的64位十六进制地址,也就是你看到的000000f5a6bff9c4——其中000000f5就是被%x截断的高位部分。

为什么会出现"前加000000f5"的现象

在64位Windows环境中,用户态进程的虚拟地址通常低48位有效,部分场景下会有高位扩展(比如你的例子里的000000f5)。但无论高位值是什么,%x都会只截取低32位输出,%p则会输出完整的指针值,所以看起来像是%p的结果在%x的结果前补充了高位字节。

重要规范:禁止用%x打印指针

用%x打印指针属于未定义行为——%x期望接收unsigned int类型参数,但64位系统下指针是unsigned long long类型,类型不匹配会导致不可预期的输出。打印指针地址的正确做法永远是使用%p。

验证代码

如果想直观确认完整地址,可使用%llx(输出64位无符号整数的十六进制)打印强制转换后的指针,结果会和%p完全一致:

#include <stdio.h>

int main() {
    int a=8;
    int *ptr=&a;

    printf("\n&a (%%x): %x\n",&a);
    printf("\nptr (%%p): %p \n",ptr);
    printf("\n&a (完整64位地址 %%llx): %llx\n", (unsigned long long)&a);
    return 0;
}

内容的提问来源于stack exchange,提问作者NeuronB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:39:59