对于链表的create函数和插入、删除等函数,create的形参应该是节点的地址的地址,而其他函数的形参则仅仅是节点的地址。
而当我传给create函数的形参仅是节点的地址时候,程序死活运行不出来。这个问题出在哪了?
问题就是:
当我给头结点分配空间时,用这一条语句来实现 Plist L=(Plist)malloc(sizeof(list));
也就是把分配好的空间的地址赋值给头节点的地址L,这样头节点的地址(也就是形参L)确确实实发生了改变,但是实参L(也就是主函数里面的定义的L)却没有发生改变!!!这导致的结果是程序给形参创建了一条链表,但是主函数里面却没有真正的链表。 这就是程序运行不出来的症状所在。
为什么?
这是因为此时形参只是实参的拷贝,改变了形参的内容,却与实参的内容毫不相关。
怎么解决?
我们要知道,形参传完值,我们自己所定义的函数实现的操作仅仅是在拷贝上操作。
要想做到改变实参,* L=(Plist)malloc(sizeof(list));
我们就要把上面实参的地址作为参数,也就是节点的地址的地址作为形参,此时我们才抓住了根本,就像牵住了牛的鼻子。这时利用取地址符* L就可以实现我们的目标——改变主函数定义的头结点的指针的内容,让他保存的是分配好空间的一条链表的头结点的地址,这样指针L才真正指向一条链表。
插入、删除等其他函数的形参就应该是节点的指针,因为形参传进去节点的地址后,拷贝的是节点的地址,对节点地址的操作就能改变节点地址指向的节点里面的内容。
最后,我们怎么知道什么时候传送地址,什么时候传送地址的地址呢?
总而言之,我们想要改变一个目标,那么我们就传送这个目标的地址。比如我们想改变主函数中定义的节点地址的内容,此时节点地址就是目标,只需传送节点地址的地址。我们想改变链表中节点的内容,节点就是目标,只需传送节点的地址。