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

问题

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

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

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

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

似乎总是没有认真想想传值方式,传进去的是地址&a,调用结束以后a的地址当然没变了,变的是a里边存储的值。
另外还有一种情况:
/*
 * 使用链表表示多项式
 */

#include <stdio.h>
#include <stdlib.h>


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

总结:

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值