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

C语言指针指向疑问:为何pa的值不等于变量a的地址?

问题核心原因:函数传参的局部变量副本

你的疑惑根源在于函数参数的按值传递机制,以及你在var_print函数中混淆了两个完全独立的a变量:

1. 两个a的本质区别

代码里存在两个毫无关联的a变量:

  • 主函数main中的int a = 0:属于main栈帧的局部变量,pa = &a让指针pa指向的是这个变量的地址。
  • var_print函数参数中的int a:调用var_print时,从main的a拷贝过来的局部变量,属于var_print的栈帧,和main的a地址完全不同。

你在var_print中打印的&a,是这个局部参数a的地址,而非main里a的地址;但pa参数的值是从main的pa拷贝过来的,仍然指向main里的a。这就是为什么pa的值和&a不相等——它们指向的是两个完全不同的内存位置。

2. 指针差值的逻辑解释

指针相减的结果是以指向类型的大小为单位的(比如int*相减,单位是sizeof(int),通常为4字节)。由于栈的生长方向通常是从高地址向低地址,main的栈帧位于更高的内存区域,var_print的栈帧在更低的地址区域:

  • main里的a地址(pa的值)高于var_print里局部a的地址(&a),所以pa - &a的结果是正数,数值等于两个地址的字节差除以sizeof(int)。
  • 当你新增pa2变量时,main的栈帧布局发生变化,main里a的地址和var_print局部a的地址的字节差改变,导致差值数值变化,但本质逻辑不变。

验证方法:修改代码区分变量

把var_print的参数名改成和main不同的名字,就能直观看到区别:

void var_print(int a_main, int b_main, int *pa, int *pb, long int dist) {
    printf("Variable\tValue\t\tAddress\t\t\tPoints to...\t\t&var - pointer-to-var\n\n");
    printf("func param a\t%d\t\t%p\n", a_main, &a_main); // 函数参数的地址,和main的a无关
    printf("*pa\t\t%d\t\t%p\t\t%p\t\t%d\n", *pa, &pa, pa, (int)(pa - &a_main));
    printf("func param b\t%d\t\t%p\n", b_main, &b_main);
    printf("*pb\t\t%d\t\t%p\t\t%p\t\t%d\n", *pb, &pb, pb, (int)(&b_main - pb));
    printf("dist\t\t%ld\t\t%p\n", dist, &dist);
}

如果想要在var_print中打印main里a的地址,需要传递&a作为指针参数,而非传递a的值。比如修改函数参数为int *a_ptr,调用时传&a,就能直接访问main里a的地址。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:45:01