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