c语言函数形参实参,C语言-实参到函数形参传递的理解

问题

在C语言函数参数设置过程中,有些时候总是不能达到预期的效果。书上总是对这个C语言参数传递描述:传值方式、传到调用函数的是副本,然后就是常规的swap函数说明这个问题,但是还是不能以swap描述所有的问题,看了这个例子总是给人一种感觉:考虑到要在函数内部改变数据,在调用函数里边也真正改变了数据就用指针,这个感觉还是有漏洞,需要完善一下这个规则。

C语言参数传递:传值方式

有传值方式,还有传引用方式,传引用方式就是实参和形参是同一个变量(地址都一样,使用使用同一个内存),这个主要在C++里边。对于传值方式,就是在一个函数里边,通过形参传进来的是这个变量的一个副本,大小或者值是一样的,但是不是一样的存储地址:简单理解一下---传进去的值是一样的,但是样品,函数调用结束后,传进去的那个值没变。

值没变?那swap(&a,&b)怎么实现的呢:

似乎总是没有认真想想传值方式,传进去的是地址&a,调用结束以后a的地址当然没变了,变的是a里边存储的值。

另外还有一种情况:

/*

* 使用链表表示多项式

*/

#include

#include

typedef struct list_poly *list_point;

typedef struct list_poly{

float coef;

int expon;

list_point link;

}list_poly;

void add(list_point *front,list_point *rear,float coef,int expon);

void adderror(list_point front,list_point rear,float coef,int expon);

//list_point front=NULL;

//list_point rear=NULL;

int main(int argc,char *argv[])

{

list_point front=(list_point)malloc(sizeof(list_poly));

list_point rear=NULL;

front->coef = 9.9;

front->expon = 7;

front->link = NULL;

rear = front;

adderror(front,rear,5.1,5);

adderror(front,rear,4.7,3);

adderror(front,rear,2.5,2);

adderror(front,rear,1.3,1);

for(;front;front=front->link){

printf("coef = %3.1f,expon = %3d",front->coef,front->expon);

printf("\n");

}

printf("\n");

printf("coef = %3.1f,expon = %3d",rear->coef,rear->expon);

printf("\n");

return 0;

}

void adderror(list_point front,list_point rear,float coef,int expon)

{

list_point new = (list_point)malloc(sizeof(list_poly));

new->coef = coef;

new->expon = expon;

new->link = NULL;

if(front){

rear->link = new;

rear = new;

//printf("coef = %3.1f,expon = %3d",(*rear)->coef,(*rear)->expon);

//printf("\n");

}

else{

front = new;

rear = new;

//printf("front2 = %d\n",*front);

}

}上面就是一个简单例子----改变传指针就行的观点。

一个简单的使用链表表示多项式的例子,需要往链表后边陆续加上多项式的每一项。但是结果总是没有加到后边。

解释一下上面的程序:list_point 是一个类指针,后面的两个front和rear都是一个结构图指针(刚开始是NULL),front始终指向的链表的开始,而rear始终指向的链表的尾,插入一个多项式成员,rear往后移一个。

但是上面没有达到预期的效果-------想了想,我是传的指针呀,函数的形参也声明的是指针呀,这个情况就像下面这个:

swap(int a,int b)

{

int t;

t = a;

a = b;

b = t;

}

调用结束以后,a、b都还是原来的值,嗯嗯,与传值方式的性质:不改变传进去的值相符合。不同的是我这可传的指针呀!!!按原来的传指针就行的观念是对的呀

那上面链表的程序问题出哪了,我们传进去的是一个指针,调用结束以后指针没变,嗯嗯,这里是对的,但是我们在adderror函数里边有:

rear = new;

这就有问题了,我们试图改变我们传进去的指针,函数里边是改变了,出来句恢复原样了。

这个函数应该改成:

//在函数声明和函数实体处改成:

void add(list_point *front,list_point *rear);

//在调用时,改成

add(&front,&rear,5.1,5)

按上面的核心思想:我们虽然声明的是一个指针,但是我们希望在程序里边移动这个指针,因此需要传入指针的指针。

总结:

在变量---变量的指针---变量的指针的指针,这个等级上理解,传入的值不变,想改变这个值,就需要传这个值的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值