主函数传入函数的变量叫实参,而函数中的对应变量叫形参。形参实际上是实参的拷贝,所以如果我们修改形参的值,实参不会发生变化。
后来学习了指针,指针就相当于钥匙,能打开对应房间(地址)的门。当指针作为函数参数时,实参和形参相当于拷贝的两把钥匙,但他们都指向同一个房间,同一个地址。借由形参访问地址,并改变地址中的值,能够真正修改地址中的值。
而在学习结构体、链表时,常常进行的操作是对结构体指针赋值。
比如添加新链表结点add函数,传入实参head(要修改的链表的头指针)先将新结点的内容赋给临时结构体指针p,然后将p的值赋给head或last->next,即挂在链表的结尾。
head=p;//当head为NULL的时候
last->next=p;//当head不为NULL的时候
最后返回head指针。
但是这样做并不会直接对主函数中的head指针进行修改,为什么?
因为我们修改的不是指针对应地址中的值,而是直接修改指针的值,改变了指针的指向(对钥匙本身的修改,让这把钥匙指向另一个房间;而不是对钥匙指向房间里的内容的修改)。当我们令head=p时,相当于让head自身的地址值改变,和指针p指向的地址一样。这就和修改普通变量一样,对形参的修改不会影响实参。
解决方法:(翁恺老师的建议)
- head定义为全局变量,这样在所有函数中都能访问。但这种方法并不好,只对这个链表的head生效。如果还定义了其他链表,此add函数就不能对其他链表生效了。
- add函数返回新的我们想要的head结构体指针,在原函数中把add函数的返回值赋给head.
- 既然可以传递指针对应地址的值,我们就让指针所指的地址中的值是我们要修改的指针,即传入**phead指向指针的指针。这样就可以直接修改*phead的值了。
- 我们定义一个结构list,其中包含*head。在原函数中定义list,list.head=NULL;然后把list的指针
&list
传入add函数,add的参数是list的指针,在函数中就可以对list->head进行修改。