函数的参数分为两种,分别是形式参数与实际参数。
①形式参数:
在定义函数时函数名后面括号中的变量名称称为形式参数(简称形参),即形参出现在函数定义中。形参变量只有在被调用时才会为其分配内训单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效,只有当函数被调用时,系统才为形参分配存储单元,并完成实参与形参的数据传递。在函数未被调用时,函数的形参并不占用实际的存储单元,也没有实际值。
②实际参数:
主调函数中调用一个函数时,函数名后面括号中的参数称为实际参数(简称实参),即实参出现在主调函数中。
实参可以是常量,变量,表达式,函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传递给形参。因此应预先用赋值,输入等办法使实参获得确定值。
说明:在被定义的函数中,必须指定形参的类型。实参与形参的类型应相同或赋值兼容。实参和形参在数量上,类型上,顺序上应该严格一致,否则会发生类型不匹配的错误。
C语言中函数的值传递有两种,一种是传递数值(即传递基本类型的数据,结构体数据),另一种是传递地址(即传递存储单元的地址)。
1.传数值:
调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,形参的值的改变并不会影响实参。调用结束后,形参所占内存单元被释放,实参仍保持原值不变。该方法只能是实参向形参传递数据,即该方法是单向传递。
传数值,实参的值时基本数据类型,结构体类型数据,实参可以是常量,变量或表示式,其值类型是整形,实型,字符型,数组元素等数据而不能是数组名或指针等数据。当函数调用时,先为形参分配独立的存储单元,同时将实参的值赋值给形参变量。因此,在函数体执行中,形参函数的任何改变都不会改变实参的值。
数值传递中,形参的值改变不会影响实参实例:
#include <stdio.h>
int main()
{
int n,m;
void swap(int,int); //声明函数
printf("please input two numbers:");
scanf("%d%d",&n,&m);
printf("n=%d,m=%d\n",n,m); //第一次输出
swap(n,m); //第二次输出
printf("n=%d,m=%d\n",n,m); //第三输出
}
void swap(int x,int y) //定义函数
{
int i;
i=x;
x=y;
y=i;
printf("x=%d,y=%d\n",x,y);
}
运行结果:
please input two numbers:5 7
n=5,m=7
x=7,y=5
n=5,m=7
由此可见,调用swap函数只交换了两个形参的值,而实参的值并没有发生变换。
2.传地址:
在实际应用中,往往需要将形参的返回值给实参,所以需要双向传递,这时可以使用传地址方式。当用表示地址的数组名或者指针变量作为函数参数进行参数传递时就不是传输至,实际上传递的是地址,即把实参所存放的地址赋予形参。由于形参在调用所得到的是实参所值的地址,因而形参和实参将占用同一片内存空间,即两者指向同一个对象,在函数体重可以通过地址,访问相应的变量,而达到改变主调函数中的变量值。因此在被调用函数中对形参所做的操作都会影响到实参。
采用传地址方式时,函数定义中的形参可以是数组作为形参或指针变量作为形参。数组是内存中的一块存储区域,数组名表示这块存储区域的首地址,通过首地址可以实现对数组中各元素的访问。数组作为函数的参数,其本质是把数组的首地址传给形参,使形参数组与实参数组成为同一个数组,使用同一块存储区域,即形参数组的存储区域就是是参数组的存储区域,因此在被调用函数中对形参数组的访问,就是对主调函数中数组的访问,而达到引用主调函数中数组元素。
下面来看实例:
//将数组中的n个整数,按值从小到大排序。
#include <stdio.h>
int main()
{
int b[10]={1,6,2,3,10,23,11,0,21,8};
int i;
printf("排序前:\n");
for(i=0;i<10;i++)
printf("%d\t",b[i]);
printf("\n");
void sort(int a[],int n); //调用选择排序法函数
sort(b,10);
printf("排序后:\n");
for(i=0;i<10;i++)
printf("%d\t",b[i]);
}
//选择排序法
void sort(int a[],int n)
{
int i,j,k,t;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(a[k]>a[j])
k=j;
t=a[k];a[k]=a[i];a[i]=t;
}
}
//冒泡排序法
void sort1(int a[],int n)
{
int i,j;
int temp; //中间变量
for(i=0;i<n;i++)
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
选择排序法比冒泡排序法的程序要更好一点,但是也更不易理解一点。
基础好一点的可以用选择排序法,基础差一点可以选择用冒泡排序法。