大清早收到消息,好久前写的帖子(链接)下,有人问我问题:
原函数是这样的:
void Attach(int c, int e, Polynomial *pRear){Polynomial P;P = (Polynomial)malloc(sizeof(struct PolyNode));P->coef=c;P->expon=e;P->link = NULL;(*pRear)->link = P;*pRear=P;}Attach(P1->coef, P1->expon, &rear);
他问,为什么要写成指针呢?写成下面这样不好吗?
void Attach(int c, int e, Polynomial pRear){Polynomial P;P = (Polynomial)malloc(sizeof(struct PolyNode));P->coef=c;P->expon=e;P->link = NULL;pRear->link = P;pRear=P;}Attach(P1->coef, P1->expon, rear);
原因很简单,我做出的解答如下:
(1)首先明确pRear
是一个指针,指向一个结点,那pRear
本身就是一个地址变量;
(2)其次,明确C
中都是传值调用。
在你的Attach(P1->coef, P1->expon, rear)
中:
pRear->link = P;
上面这句话本身是没有问题的,可以对 link 进行赋值。
pRear=P;
但是这句话就不能起到赋值的效果,因为:
调用 Attach(P1->coef, P1->expon, rear) 时,将rear的值(因为rear
是一个指针,所以其值是一个地址变量)赋值一份,给局部变量pRear赋上此时 pRear 中保存地址变量,但其本身并不是指向 *rear 的指针;换句话说,如果 pRear 的值改变,那么不对 rear 造成影响。因此,想要改变 rear 的值,应该将 rear 的地址传入,而非将其本身。
这就涉及到一个基础问题:C/C++中,如何理解传值引用与调用引用?
有很多高手做了很精简凝练的回答,比如下面这个:
链接:只需要记住一句话,传值引用一般就是生成一个临时对象,而引用调用是调用参数本身。
说得对,且对于初学者而言这种理解再好不过。但通过一段时间的深入学习你会发现,所谓“传值引用”与“调用引用”其实是一回事。
对于“传值引用”,假设我们有如下代码:
int x = 0;int foo(int x):x = 10;y = 20;return y
则调用了foo(x)
后,x
的值不变,还是0
。
但若是“调用引用”,假设我们有如下代码:
int x = 0;int foo(int *p):*p = 10;y = 20;return y
则调用了foo(&x)
后,x
的值变化为10
。
为什么要加&
与*
这么多奇奇怪怪的符号?那就要牵扯到“指针”这个概念了。计算机中,每个变量都要有一个“住址”,就可以理解为变量的“地址”。
小明住在南开路92号,在计算机中的表达为:南开路92号(指针)指向小明(变量)。
在我们的例子中,&x
表示的是x
的地址;int foo(int *p)
表示的是把一个指向int
类型的指针p
传入;*p
表示让“p
本身是一个地址(指针)的前提下,p
所指向的东西”;*p=10
表示让这个地址所指向的变量赋值整数10
。
可以看出,对于函数的传参,都是复制该参数的值,然后再传入,即都是“传值引用”。
之所以能做到“调用引用”,是因为对变量的指针进行了“传值引用”,指针的值被赋值,但是复制后其指向的依然是我们要修改的变量。
【C/C++】理解传值引用和调用引用:函数调用中 为变量赋值 传入其指针;为指针赋值 传入指针的指针