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

指针入门疑问:%i值一致但%p值不同的原因解析

指针与int变量的printf输出问题解析

先看你的代码:

int main(void)
{
    int n = 50;
    int *p = &n;
    int t = &n;
    // using %p below
    printf("%p\n", p);
    printf("%p\n", &n);
    printf("%p\n", t);
    // using %i below
    printf("%i\n", p);
    printf("%i\n", &n);
    printf("%i\n", t);
}

示例输出:

0x7ffc3f503cd8
0x7ffc3f503cd8
0x3f503cd8
1062223064
1062223064
1062223064

核心问题根源

代码里int t = &n;是关键:你把8字节的内存地址(指针类型)直接赋值给了4字节的int变量t,地址的高4字节被截断丢失,只保留低4字节存在t中。


一、为什么%i输出完全一致?

%i是打印十进制整数的格式符:

  • 打印p或&n时,printf会把8字节的指针值强制转换成int类型(只取低4字节),输出这部分的十进制数值。
  • 打印t时,t本身存的就是地址的低4字节,直接输出它的十进制值即可。
    三者的%i输出本质都是原地址低4字节的十进制表示,所以完全相同。

二、为什么%p输出t和另外两个不同?

%p是专门打印内存地址的格式符,要求传入void*类型(8字节):

  • 打印p或&n时,int*类型的指针会自动转为void*,printf输出完整的8字节地址,也就是0x7ffc3f503cd8。
  • 打印t时,t是4字节的int变量,传给printf后会被当成void*处理,但它只有4字节的有效数据(原地址的低4字节),高4字节补0,所以输出的是0x3f503cd8——也就是被截断后的地址片段,自然和完整地址不同。

重要提醒

这种将指针直接赋值给int变量的行为属于C语言未定义行为,不同系统、编译器下可能出现不同结果,实际开发中绝对不能这么写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:50:34