函数
c语言程序可由一个主函数和若干其它函数构成,每个函数实现一个特定的功能。主函数调用其他函数,其它函数也可以互相调用。同一个函数可以被一个或者多个函数调用多次。
- 函数定义
c语言要求,在程序中用到的所有函数,必须“先定义,后使用”。例如想用max求两个数的最大值。必须先按规范对它进行定义,指定他的名字、函数返回类型、函数实现的功能以及参数的个数和类型,将这些信息通知给编译系统。这样程序执行max函数的时,编译系统就会按照定义式所指定的功能去执行。如果事先不定义,编译系统是无从知晓max是什么,要实现什么功能的。
- 无参函数
类型名 函数名(形式参数列表)
{
函数体
}
void printstar ()
{
}
函数没有返回值所以定义为void
- 有参函数
类型名 函数名(形式参数列表)
{
函数体
}
我们通过案例来理解,编写程序9-2.求出两个数的最大值。程序如下:
Alt text运算结果:
20
说明:
(1)在上述函数调用过程中,主调函数和被调函数之间存在数据传递的关系。在定义函数的时候函数名后面括号中的变量名称为“形式参数”(简称“形参”)(上例中为x和y),在调用语句c=max(a,b);
中,a和b称为“实际参数”(简称“实参”)。
(2)函数的调用过程:
- 在定义函数中指定的形参,在未出现函数调用时,他们并不占内存中的存储单元。在发生函数调用时,函数max的形参被临时分配内存单元。
- 将实参对应的值传递给形参。9-2例题中,实参的值a为10,b为20.把10和20传递给相应的形参x和y,这是形参x就得到了10,形参y得到值20.
- 在执行max函数期间,由于形参已经有值,就可以利用形参进行有关运算了
- 通过return语句将运算得到的z的值带回主调函数。应当注意返回值的类型和函数类型一致。如max函数为int型,返回值是变量z,也是int类型,两者一致。
- 函数的嵌套调用
c语言的函数定义是互相平行、独立的,也就是说,在定义函数时,一个函数内不能定义另一个函数,也就是不能嵌套定义,但是可以嵌套调用函数,也就是说,在调用一个函数的过程中,又可以调用另一个函数。
例如:
int fun(int a)
{
int b,c;
c=fun(b); //在执行的过程中又调用了函数fun
return(2*c);
}
在调用函数fun的过程中,又调用fun函数,这是直接调用本函数,见下图:
img这种调用都是无终止的调用,显然程序中不可能出现这种状况,而是应该出现有限次数的、有终止的递归调用,这可以用if语句来控制。
- 递归调用举例(计算阶乘)
#include <stdio.h>
int Recursionchart(int n);
int main()
{
int n,fn;
printf("n=");
scanf("%d",&n);
if(n<0)
{
printf("请重新输入:n=");
scanf("%d",&n);
}
else
{
fn=Recursionchart(n);
}
printf("f(%d)=%d",n,fn);
return 0;
}
int Recursionchart(int n)
{
int fn;
if(n==0||n==1)
{
fn=1;
}
else
fn=Recursionchart(n-1)*n;
return fn;
}
数组与函数
- 数组元素作为函数实参
数组元素可以作为函数实参,不能作为函数形参。因为形参是在函数被调用时临时分配的存储单元,不可能作为一个数组元素单独分配存储单元(数组是一个整体,在内存中占连续的一段存储单元)。在用数组元素作为函数实参时,把实参的值传给形参,是“值传递”的方式。
- 程序举例
输入10个数,要求输出其中值最大的元素和该数是第几个数。
解题思路:可以定义一个长度为10的数组。设计一个函数max,用来求两个数中的大者。在主函数中定义一个变量m,m的初值为a[0],每次调用max函数后的返回值存放在m中。用打擂台算法,将数组元素a[1]到a[9]与m比较,最后的到的m就是最大值。
编写程序:
#include<stdio.h>
int main()
{
int max(int x,int y);
int a[10],m,n,i;
printf("please enter 10 integer number:");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("\n");
for(i=1,m=a[0],n=0;i<10;i++)
{
if(max(m,a[i])>m) //若max函数返回值大于m
{
m=max(m,a[i]); //max函数的返回值取代m
n=i; //把数组元素的序号记下来,放到n中
}
}
printf("the largest number is %d\n it is the %dth number \n",m,n+1);
}
int max(int x,int y)
{
return(x>y?x:y);
}
- 数组名作为函数参数
除了可以用数组元素作为函数的参数外,还可以用数组名做函数参数(包括实参和形参)。应当注意的是:用数组元素作为实参时,向形参变量传递的是数组所对应数组元素的值,而用数组名做函数实参时,向形参(数组名或指针变量)传递的是数组首元素的地址,下一节指针大家会更加深入的理解该内容。
- 程序举例
编写程序9-6 有一个一位数组score,内放10个学生成绩,求平均成绩。
解题思路:用一个函数average来求平均成绩,不用数组元素作为函数实参,而是用数组名作为函数的实参,形参也用数组名,在average函数中引用各数组的元素,求平均成绩并返回main函数。
编写程序:
#include<stdio.h>
int main()
{
float average(float array[10]);
float score[10],aver;
int i;
printf("please enter 10 scores:");
for(i=0;i<10;i++)
scanf("%f",&score[i]);
printf("\n");
aver=average(score); //注意这里调用函数时,向形参传递的是数组首元素的地址
printf("average score is %5.2f\n ",aver);
return 0;
}
float average(float array[10])
{
int i;
float aver,sum=0;
for(i=0;i<10;i++)
sum=sum+array[i];
aver=sum/10;
return(aver);
}
注意:用数组名作为函数参数,应该在主调函数和被调用函数分别定义数组,例如array是形参的数组名,score是实参数组名,分别在其所在函数中定义。
参考文献
[1]实验楼 模块化程序设计(https://www.shiyanlou.com/courses/57/labs/367/document)
网友评论