单链表---对传参为双指针的理解

​​​​​​​​​​​

 

上一篇中我们提到了单链表头指针的创建

           如果链表为空时,头指针为NULL。接下来要实现节点的插入和删除。

           在链表头部插入新节点,因此头指针指向的地址也应发生改变,即指向新节点的地址,因为在此时新节点就是头节点。此时我们就该考虑传参的问题。

                    我们先来看头指针是如何创建的

#include<stdio.h>
typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;
int main() {
	SListNode* plist = NULL;
	return NULL;
}

                              此处的plist就是头指针,并且此时链表为空 

 在此时我们在主函数中创建一个新节点,data为1。如下图:

int main() {
	SListNode* plist = NULL;
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	newnode->data = 1;
	return NULL;
}

         这时我们需要想一想如何把新节点链接到链表中?

 显而易见,我们需要把新节点的next,即newnode下一个指针的地址置为空,并且使plist的值改为新节点的地址就ok了。

int main() {
	SListNode* plist = NULL;
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	newnode->data = 1;
    newnode->next=plist;
    plist=newnode;
	return NULL;
}

                                           plist由NULL变为newnode 

从上述代码中,我们可很明显的感觉到,plist的值发生了改变,它由NULL变为新节点的指针newnode;接下来我们要求一个函数来实现链表的头插,显然这个函数必须要传入头指针(因为只有知道链表的头指针,我们才能找到完整的链表,正像上一篇我们说到链表的头指针是无论如何也不能丢失的)和头插的数据。但是此时就需要我们好好想想-------如果把plist传过去,是否会达到预期的结果?认真想一想,假设我们把plist传过去,用p来接受,会不会达到预想的结果?

void SLFrontPush(SListNode* p, int x) {

}

我们在上一步的基础上,在SLFrontPush函数中把p置为NULL;看一看会不会对plist有什么影响?

void SLFrontPush(SListNode* p, int x) {
	p == NULL;
}
int main() {
	SListNode* plist = NULL;
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	newnode->data = 1;
	newnode->next = plist;
	plist = newnode;
	printf("%p\n", plist);
	SLFrontPush(plist, 0);
	printf("%p\n", plist);
    return NULL;
}

 对操作前和操作后的地址分别进行打印

 结果是前后打印出的plist值没有发生改变。即把plist传到函数中,对形参p进行操作是不会对主函数中的plist值发生改变的。为什么会这样呢?我们知道函数的形参实际上是对实参的一份临时拷贝,拷贝的内容是实参的内容,只不过是把相同的内容放到了不同的地址上。

 我们改变p时,把p置为NULL时,实际上是在SLFrontPush函数中在p开辟的空间上,对p的值进行改变,并不会影响到main函数中plist的值。我们也就无法使头指针指向新节点的地址。那我们该如何实现对plist的改变呢?

在开头时,我们实现了对头指针的成功改变。我们是怎么实现的呢?

对,我们是直接把plist拿过来进行操作的,也就是说如果我们能在函数中知道plist的地址,那么我们就可以通过它的地址,对它地址上存储的数据进行改变。而它地址上存储的数据正是头指针!

那么显而易见:我们需要传plist的地址即形参为SListNode**p,实参为&plist。​​​​​​​

                                                                      代码:

void SLFrontPush(SListNode** p, int x) {
	*p = NULL;
}
int main() {
	SListNode* plist = NULL;
	printf("%p\n", &plist);
	plist = (SListNode*)malloc(sizeof(SListNode));
	printf("%p\n", plist);
	SLFrontPush(&plist,0);
	printf("%p\n", plist);
    return NULL;
}

 结果:

 

 

 

      

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值