函数的数据传递
C语言的程序是由函数组成,而在函数之间存在相互调用及调用时数据的传递问题。在C语言中,我们通过函数实现功能模块的定义,然后通过函数之间的调用来实现程序功能。因此,程序中的函数根据其在某个程序中的使用方式的不同分为主调函数和被调用函数。函数本身并没有这种区分。函数间也可互相调用。有参函数的参数是主调函数和被调用函数进行数据传递的主要方式。无参函数不需要数据传递。数据传递的方式有很多种包括:值传递、地址传递、全局变量传递方式等。以下介绍的是值传递方式和址传递方式。
一、值传递方式
1、形式参数和实际参数
一般,在调用有参函数时,主调函数和被调用函数之间有数据传递关系。通过函数调用的形式可知:在定义函数时函数名后面括号中的变量名称为“形式参数”(简称“形参”)或“虚拟参数”。在主调用函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”(简称“实参”)。实际参数可以是常量、变量或表达式。
2、实参和形参间的数据传递
在调用函数过程中,系统会把实参的值传递给被调用函数的形参。或者说,形参从实参得到一个值。该值在函数调用期间有效,可以参加该函数中的运算。在调用函数过程中发生的实参与形参间的数据传递,常称为“虚拟结合”。
例如:
输入两个整数,要求输出其中值较大者。要求用函数来找到大数。
本题的解题思路:
(1) 函数名。应是见名知意,反映函数的功能,今定名为max,
(2) 函数的类型。由于给定的两个数是整数,显然其中大者也是整数,也就是说max函数的值(即返回在主调函数的值)应该是整型。
(3) max函数的参数个数和类型。max函数应当有两个参数,以便从主函数接收两个整数,显然,参数的类型应当是整型。
在调用max函数时,应当给出两个整数作为实参,传给max函数中的两个形参。
程序如下:
(1) 先编写max函数
Intmax(int x,int y)
{
Int z;
z=x>y?x:y;
return(z);
}
(2)再编写主函数
#include<stdio.h>
Intmain()
Inta,b,c;
Printf(“pleaseenter two integer numbers:”);
Scanf(“%d,%d”,&a,&b);
C=max(a,b);
Printf(“maxis %d\n”,c);
Return 0;
}
通过对以上程序的分析:通过函数调用,在两个函数之间发生数据传递,实参a和b的值传递给形参x和y,在max函数中把x和y中的大者赋给变量z,z的值作为函数值返回main函数,赋给变量c。
注意:实参向形参的数据传递是“值传递”,单向传递,只能由实参传给形参,而不能由形参传给实参。实参和形参在内存中占有不同的存储单元,实参无法得到形参的值。
总的来说,值传递就是在函数中开辟出一个临时内存空间,将传递的数值保存在这个空间中,当子函数结束后,这个内存空间就会释放了。
二、址传递方式
实际上,因为地址本身也可以作为一个特殊的值,所以地址传递也是一种特殊的值传递。只是为了强调其特殊性,故称为“地址传递”。我们在学习过程中需将这两种方式区别对待,比如若参数传递的是简单数据类型的数值,则将其归类为值传递方式;若参数传递的是变量的地址,则其为地址传递方式。
在地址传递过程中,被调用函数的形参虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址,被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主函数中的实参变量。正因为如此,被调用函数对形参做的任何操作都影响了主调函数中的实参变量。
例如:
Void swap(int*p,int*q)
{int temp;
Temp=*p;
*p=*q;
*q=emp;
}
Void main()
{int a,b;
Int*pointe_1=&a,*pointer_2=&b;
Scanf(“%d,%d”,&a,&b);
If(a<b)swap(&a,&b);
Printf(“n%d,%d\n”,a,b);
}
假设我们从键盘中输入两个数据:5,9,先来看一下运行结果:9,5
在这个程序中用指针变量作参数,虽然传送的是变量的地址,但实参和形参之间的数据传递依然是单向的“值传递”,即调用函数不可能改变实参指针变量的值,但它不同于一般指传递的是,它可以通过指针间接访问的特点来改变指针变量所指变量的值,即最终到了改变实参的目的。