链表处理函数中传递的参数为什么是指向指针的指针?而不是直接传递指针?

首先,我们看一下书中初始化链表的代码:

#include<stdio.h>

#define TSIZE 45

typedef struct film {
	char title[TSIZE];
	int rating;
} Item;//储存电影信息的结构

typedef struct node {
	Item item;         
	struct node * next;//指向下一结构的指针
} Node;//node结构构成了一个链表的节点

typedef Node * List;

void InitializeList(List * plist);

int main(void)
{
	
	List movies;//movies本身为一个指针,该指针指向一个ndoe结构
	printf("%p\n", movies);//后添加
	InitializeList(&movies);//传入指向链表的指针,初始化链表为空
	printf("%p\n", movies);//后添加
	return 0;
}
	
void InitializeList(List * plist)//初始化链表函数
{
	*plist = NULL;
	printf("%p\n", *plist);//后添加
}

为了方便显示程序结果,我在程序中加入了三条printf语句,分别显示初始化前、初始化函数中、回到主调函数中movies的值,程序运行结果如下:
在这里插入图片描述
可以看到,程序正常运行,并且movies的值已被初始化为NULL。
那么,如果我们将上面的语句更改为:

void InitializeList(List plist)//注意,函数原型也要更改
{
	plist = NULL;
	printf("%p\n", plist);
}

重新调用该函数InitializeList(movies),也就是说我们传递给该函数的参数为指针本身,而不是指向该指针的指针,再次运行程序,程序的运行结果如下:
在这里插入图片描述
可以看到,在初始化函数中,movies的值已被初始化为NULL,但是回到主调函数后,movies的值并没有发生改变,为什么?
我们先将问题简单化,解释指针的原理:
假设int n = 5; int * pn = &n; int ** p_pn = &pn; 它们的关系如下:
在这里插入图片描述
从上面的关系图可知:n == 5,&n == CCCCCCCC
*pn == n == 5,pn == &n == CCCCCCCC,&pn == DDDDDDDD
*p_pn ==pn == CCCCCCCC,p_pn == &pn == DDDDDDDD,&p_pn == EEEEEEEE。有点绕,但是好理解。

我们可以将上面程序中的movies看作是pn,因为它们都是一个指针,那么plist就可以看做p_pn,因为它们都是指向指针的指针。

我们都知道,如果需要在一个被调函数中改变一个主调函数的变量,一般采
用传递变量的地址,而不是直接传递变量,即采用change(pn);(调用函数语句,change()为被调函数),而不是采用change(n),因为如果传递的是变量,程序会将该变量备份,在被调函数中改变的只是备份的变量,而不是变量本身,退出被调函数后,该备份变量就会被销毁,这也就是为什么明明在被调函数显示变量已改变,但是回到主调函数后变量又变成原来的值。

同样,如果我们要改变pn,那么就不能传递pn本身,必须传递&pn,即p_pn,这也就是为什么我们在调用函数时传递的是&movies,而不是movies。因为movies指向一个链节,它的值为该链节的地址,如果我们要将它的值变为NULL,那么就要传递它的地址,然后通过解引用运算符*改变它的值。

说到这里,原因我们大概都清楚了,对指针也有了初步了解,但是有一个问题我们需要注意:
我们改变了pn的值,但是&n本身发生了改变吗?答案是并没有,用简单的程序测试一下:

#include<stdio.h>
void change(int ** ptr);
int main(void)
{
	int n = 5;
	int * pn = &n;
	int ** p_pn = &pn;
	printf("%p\n", &n);
	printf("%p\n", pn);
	change(p_pn);
	printf("%p\n", &n);
	printf("%p\n", pn);
	return 0;
}
void change(int ** ptr)
{
	*ptr = NULL;
}

运行结果如下:
在这里插入图片描述
可以看到pn的值已经被初始化为NULL,但是n本身的地址却并没有改变,因为pn的值以前是n所在的地址,但是改变pn的值后,pn不再指向n,n本身并没有改变,依然存在,其地址当然也不会改变。

由于我也是刚开始学,所以如果有错误,还请指正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值