C语言关于传入子函数的指针形参的地址改变

C语言关于传入子函数的指针形参的地址改变,第1张

        这个问题是在学习链表时遇到的,在做实验二的过程中想要实现插入(或删除) *** 作时,我们会调用子函数传入首元结点地址作为指针形参,通过一系列变化(一般是循环)找到待处理结点后进行相应处理。


        我们总能轻易地改变非首元结点之间的链式关系,处理过后首元结点地址(即指针形参)显然是不会改变的。


但难免会出现新增一个结点插入在首元结点之前(或者删除掉首元结点)的情况,这时我们便想更改首元结点的地址,按照这个思路在子函数中给指针形参赋新生成结点的地址,运行结果却不尽人意。


        我们发现,即使是在子函数中更改了指针形参的地址,在子函数接下来的运行中确实更改,可当子函数结束后,主函数中当初传入子函数的实参地址并未发生上述相应的改变,也就是说,我们处理首元结点仅在子函数中生了效,在主函数中“头”还是“原来的头”。


案例一:

#include 
#include 

void test(int *p)
{
	printf("2:%p\n",p);
	p=NULL;
	printf("3:%p\n",p);
}

int main()
{
	int *p;
	p=malloc(sizeof(int));
	printf("1:%p\n",p);
	test(p);
	printf("4:%p\n",p);
	return 0;
}

测试结果:

 像上述案例,我们在子函数中给指针形参赋NULL,在之后子函数中未结束时指针形参确实发生了改变,可当跳出子函数回归主函数时,我们发现当初传入的指针实参又恢复到刚生成时的地址,并没有因为在子函数中发生的改变而改变。


        那我们如何实现修改首元结点地址(指针形参)呢?

        我们可以在声明定义函数时,在其参数表中数据类型定义为“二级指针”,相应的我们给子函数传入指针的指针,放在这里来说就是传入“首元结点地址的地址”,在子函数中我们通过“二级指针”(首元结点地址的地址)修改“一级指针”(首元结点地址),这样就可避免案例一中的问题。


案例二:

#include 
#include 

void test(int **p) //这里形参为“二级指针 ” 
{
	printf("2:%p\n",*p);
	*p=NULL;
	printf("3:%p\n",*p);
}

int main()
{
	int *p;
	p=malloc(sizeof(int));
	printf("1:%p\n",p);
	test(&p);//注意这里传入的是指针p的地址 
	printf("4:%p\n",p);
	return 0;
}

测试结果:

利用上述方法我们解决了这一问题,子函数中我们通过“二级指针”修改“一级指针”后,不仅在子函数中奏效,跳出子函数回归主函数时,我们发现当初传入的指针实参确实改变了地址。


        利用以上原理我们便可解决链表中各结点之间的关系问题,当处理的结点与首元结点无关,不用考虑首元结点地址的改变,当要改变首元结点地址,我们便采用上述方法。


但是要注意,此时的子函数形参为二级指针,所以接下来的 *** 作中不要忘记给传入参数名前加'*',用其一级指针进行连接删除相应 *** 作;在主函数中调用该子函数时,记得传入的实参为二级指针,给原来的首元结点地址前加'&'。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/563397.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-02
下一篇 2022-04-02

发表评论

登录后才能评论

评论列表(0条)

保存