C++实际操作链表参数需用指向指针的指针

阅读《剑指offer》时产生的疑问,为什么链表头结点要用一个指向指针的指针?书中源代码如下:


```cpp

void AddToTail(ListNode** pHead, int value) {
	ListNode* pNew = new ListNode();
	pNew->val = value;
	pNew->next = NULL;
 
	if (*pHead == NULL) {
		*pHead = pNew;
	}
	else {
		ListNode* p = *pHead;
		while (p->next != NULL) {
			p = p->next;
		}
		p->next = pNew;
	}
}


pHead是指向头结点指针的指针,据书中解释,之所以这样写是因为如果插入的是空链表,那么新的结点就是头指针,这时会改变头指针,所以必须把pHead设为指向指针的指针,否则出了这个函数pHead依然是一个空指针。
要理解上面这段话一是要熟悉C++的内存四区,二是要弄清楚传参的情况:是传值调用还是传址调用。
先看看传递的是指针的情况:


```cpp
#include <iostream>
#include <string>
using namespace std;

struct ListNode
{
	int val;
	ListNode* next;
};

void AddToTail(ListNode* pHead, int value)
{
	ListNode* pNew = new ListNode();
	pNew->val = value;
	pNew->next = NULL;

	if (pHead == NULL) 
	{
		pHead = pNew;传递的是实参的复制品,子函数在栈区分配了一块内存空间给phead,phead指向new,子函数结束后,栈区内的空间会自动销毁,所有导致下一次子函数,phead仍然是指向空,而只有取phead的地址,才能保存phead所指向的内容。
	}
	else 
	{
		ListNode* p = pHead;
		while (p->next != NULL) 
		{
			p = p->next;
		}
		p->next = pNew;
	}
}
int main() 
{
	ListNode* head = NULL;
	AddToTail(head, 10);
	AddToTail(head, 56);
	if (head != NULL) 
	{
		cout << head->val << endl;
	}
	else {
		cout << "head is NULL.." << endl;
	}
	system("pause");

}

运行结果:
`在这里插入图片描述``

解释:
(1)AddToTail()函数的pHead传参是传值调用,不能因为实参和形参是指针就认为是传址调用(传址调用:形参指针,实参地址。)
注意:数组名不可以简单地理解为指针
(2)由于是传值调用,也就是形参复制了实参的值,在函数运行时,栈区开辟一个4字节的空间来存放pHead,当函数运行结束时栈区里的值被自动释放,所以pHead为null。

总结:
简单来说,修改头指针则必须传递头指针的地址,

不修改头指针就传一级指针(即头指针本身)。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值