为何函数接收指针参数时传递变量地址而非指针变量?
传递地址 vs 指针变量:把这个困惑彻底讲清楚
Hey there, let's break this down in plain, relatable terms so it clicks right away. First, let's lock in two core definitions to avoid mix-ups:
- 内存地址: 一个数值(比如
0x7ffeefbff5ac),代表变量在计算机内存里的具体位置,相当于变量的"门牌号"。 - 指针变量: 一种专门用来存储内存地址的变量,它自己占一块内存空间,里面装的就是上面说的"门牌号"。
现在结合你的两个示例,一步步看逻辑:
示例1:直接传递地址值
void foo(int *ptr) { /* some code */ } int main() { int x = 5; foo(&x); }
&x是取地址运算符,它的作用就是直接拿到变量x的内存"门牌号"(比如0x7ffeefbff5ac)。- 调用
foo(&x)时,我们把这个"门牌号"直接传给foo的形参ptr。ptr是一个指针变量,它会接住这个地址值,之后就指向了x所在的内存位置。
示例2:通过指针变量传递地址值
void foo(int *ptr) { /* some code */ } int main() { int x = 5; int *ptr = &x; foo(ptr); }
- 这里我们先在
main里创建了一个指针变量ptr,然后把x的"门牌号"赋值给它(相当于把x的地址写进了这个指针变量里)。 - 调用
foo(ptr)时,我们传递的不是这个指针变量本身,而是它里面装的那个"门牌号"(也就是x的地址)。foo的形参ptr会复制这个地址值,最终效果和示例1完全一样——形参ptr同样指向x的内存位置。
为什么文章说"传递的是地址而非指针"?
这句话里的"指针",指的是指针变量本身,不是地址值。关键点在这:
- 两个示例里,我们都没有传递指针变量本身(如果要传递指针变量,得用
int **这种指向指针的指针做形参,然后调用foo(&ptr))。 - 我们传递的始终是地址值:示例1直接传地址,示例2传的是指针变量里存储的地址值,本质都是同一个"门牌号"。
- 这其实就是C语言里标准的值传递:传参时传递的是值的副本。示例1传的是地址值的副本,示例2传的是指针变量里地址值的副本——最终到
foo手里的,都是x的内存地址。
打个比方:指针变量就像一个装着地址的信封,foo(ptr)相当于把信封里的地址抄一份,放进foo的新信封里,而不是把你手里的原信封寄过去。我们传递的是地址(抄件),不是装地址的信封(指针变量)。
内容的提问来源于stack exchange,提问作者egor
相关产品推荐
相关产品推荐

