吧唧吧唧的吃. . . . . . . . .

指针做函数参数的问题


C语言中指针做函数参数的易错问题

C语言中函数多个返回值问题

在第一次编写创建链表的函数时,我是这样写的;
是在主函数定义了:

struct student* p;
p=NULL;

将p作为input函数形参;而函数没有返回值;
如下:
void input(struct student* head)
{
	struct student* p2, * p1;
	p1 = p2 = (struct student*)malloc(LEN);
	scanf_s("%d", &p1->number);
	scanf_s("%s", &p1->name, 10);
	scanf_s("%f", &p1->mark);
	head = p1; //试图改变head指针,来改变p
	for (;p1->number != 0;)
	{
		p1 = (struct student*)malloc(LEN);
		scanf_s("%d", &p1->number);
		scanf_s("%s", &p1->name, 10);
		scanf_s("%f", &p1->mark);
		p2->next = p1;
		p2 = p1;
	}
}

试图这样改变主函数中的p;
而实际执行后主函数中的p并没有指向head;
p依然是NULL;

在翻书后发现书中使用函数返回值来实现改变p的指向;
于是,我作出如下改变,结果可行;

 struct student* input(void)
{
	struct student* p1, * p2, * head;
	p1 = p2 = (struct student*)malloc(LEN);
	scanf_s("%d", &p1->number);
	scanf_s("%s", &p1->name, 10);
	scanf_s("%f", &p1->mark);
	head = p1;
	for (;p1->number != 0;)
	{
		p1 = (struct student*)malloc(LEN);
		scanf_s("%d", &p1->number);
		scanf_s("%s", &p1->name, 10);
		scanf_s("%f", &p1->mark);
		p2->next = p1;
		p2 = p1;
	}
	return head;
}

可为什么最初的方法不行呢?指针不是传地址吗?
input函数中改变head的地址了呀;这令我百思不得其解;
直到我看到BraveY的一篇博客文章,
其中讲到:

指针形参也是一种‘值的传递’,只是因为传递的是一个对象的地址,
因此可以通过解引用符*来对该对象直接进行修改,
所以在被调用函数中可以直接根据地址来进行操作,
从而使得该地址的变量被修改。

正确写法:

首先明确这段代码的意图是想让p指针这个变量的值在被调用函数中发生变化,
因为需要修改实参变量的值,所以需要传入实参的地址,
指向指针的地址也就是一个二级指针。
所以形参应该是一个二级指针,
在被调用函数中使用*来对地址进行解引用。

看到这里我恍然大悟!

将代码改为:
主函数中:
input(&p);
input函数中:

void input(struct student** p)
{
	struct student* p1, * p2, * head;
	p1 = p2 = (struct student*)malloc(LEN);
	scanf_s("%d", &p1->number);
	scanf_s("%s", &p1->name, 10);
	scanf_s("%f", &p1->mark);
	head = p1;
	for (;p1->number != 0;)
	{
		p1 = (struct student*)malloc(LEN);
		scanf_s("%d", &p1->number);
		scanf_s("%s", &p1->name, 10);
		scanf_s("%f", &p1->mark);
		p2->next = p1;
		p2 = p1;
	}
	*p = head;
}

经测试,没有问题。
你可能会说,这么麻烦干嘛……(擦汗)
因为这样可以实现函数多个返回值(机智),
一次改变多个主函数数据,
同样的思路将需要改变的变量做参数即可,哈哈^_^


文章作者: 668rose
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 668rose !
评论
  目录