第08章 函数

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
[案例8.6] 写一函数,统计字符串中字母的个数。 int isalp(char c) {
if (c>='a'&&c<='z'||c>='A'&&c<='Z') return(1);
else return(0); }
main() {
int i,num=0; char str[255]; printf("Input a string: "); gets(str); for(i=0;str[i]!='\0';i++) if (isalp(str[i])) num++; puts(str); printf("num=%d\n",num); getch(); }
8.5 函数的嵌套调用和递归调用
8.5.1 函数的嵌套调用 函数的嵌套调用是指,在执行被调用函数时,被调用 函数又调用了其它函数。这与其它语言的子程序嵌套调 用的情形是类似的,其关系可表示如图8-1。
[案例8.4] 计算s=1k+2k+3k+……+N k
ห้องสมุดไป่ตู้
#define K 4
#define N 5
参(举一个数据交换的例子)。
a2
b3
x2 y3
(4)实参和形参占用不同的内存单元,即使同名也 互不影响。
C语言的函数兼有其它语言中的函数和过程两种功能,从
这个角度看,又可把函数分为有返回值函数和无返回值函数
两种。
2.函数类型 对函数进行定义,函数类型应与return语句中返回值表达 式的类型一致。 如果不一致,则以函数类型为准。如果缺省函数类型,则 系统一律按整型处理。 例如: int max(float x, float y)
for(i=0;i<10;i++)
scanf("%f",&score[i]);
aver=average(score); //调用函数,实参为一数组名
printf("average score is %5.2f\n",aver);
getch();
}
[程序演示]
说明:
(1)用数组名作函数参数,应该在调用函数和被调 用函数中分别定义数组,且数据类型必须一致,否则结 果将出错。例如,在本案例中,形参数组为a[ ],实参数 组为score[ ],它们的数据类型相同。
(5) 从用户使用的角度来看,函数分两种:库函数、用户自 定义函数。
(6) 从函数的形式看,函数分两类:无参函数、有参函数。
8.2 函数定义的一般形式
任何函数(包括主函数main())都是由函数说明和 函数体两部分组成。
1 无参函数的定义形式 函数类型 函数名( void ) { 说明语句部分; 可执行语句部分; }
char letter(char c1, char c2) double min(int x, int y)
void sub(double x) add(float x, float y)
3.函数返回值与return语句 有参函数的返回值,是通过函数中的return语句来获得
的。 (1)return语句的一般格式:return (返回值表达式 ); (2)return语句的功能:返回调用函数,并将“返回值
C语言允许函数的递归调用。在递归调用中,调用 函数又是被调用函数,执行递归函数将反复调用其自身。 每调用一次就进入新的一层。
为了防止递归调用无终止地进行,必须在函数内有 终止递归调用的手段。常用的办法是加条件判断,满足 某种条件后就不再作递归调用,然后逐层返回。
[案例8.5] 用递归法计算n!。
long power(int n) {
表达式”的值带给调用函数。
例如:8.2
说明: (1)调用函数中无return语句,并不是不返回一个值, 而是一个不确定的值。为了明确表示不返回值,可以用 “void”定义成“无(空)类型”。 (2)如果函数值的类型与return语句中表达式的值不一 致,则以函数类型为准。
[案例8.3] 返回值类型与函数类型不一致。 int max(float x, float y) /*定义一个函数max()*/ { float z; z=x>y?x:y; return (z); }
1 形式参数与实际参数
函数的参数分为形参和实参两种,作用是实现数据传送。
形参出现在函数定义中,只能在该函数体内使用。发生函 数调用时,调用函数把实参的值复制1份,传送给被调用函数 的形参,从而实现调用函数向被调用函数的数据传送。
[案例8.2] 实参对形参的数据传递。
说明:
(1)实参可以是常量、变量、表达式、函数等。无论实 参是何种类型的量,在进行函数调用时,它们都必须具有确 定的值,以便把这些值传送给形参。
第8章 函 数
8.1 概述 8.2 函数定义的一般形式 8.3 函数参数和函数的值 8.4 函数的调用 8.5 函数中的变量 8.6 局部函数和全局函数
8.1 概述
C语言是通过函数来实现模块化程序设计的。所以较大的C语言 应用程序,往往是由一个主函数和多个子函数组成的,每个函数分别
完成相应的功能。由主函数调用其他子函数,子函数之间也可以相互 调用。同一个函数可以被一个或多个函数调用任意多次。
for(i=1;i<=n;i++) sum += f1(i, k);
return sum;
}
main()
{ printf("Sum of %d powers of integers from 1 to %d = ",K,N);
printf("%d\n",f2(N,K));
}
8.5.2 函数的递归调用 函数的递归调用是指,一个函数在它的函数体内, 直接或间接地调用它自身。
说明:如果实参表中包括多个参数,对实参的求值顺
序随系统而异。有的系统按自左向右顺序求实参的值, 有的系统则相反。Turbo C和MS C是按自右向左的顺序进 行的 。
3 对被调函数的声明和函数原型 对被调用函数进行说明,其一般格式如下:
函数类型 函数名(参数类型1 参数名1, 参数类型2 ,参数名2,…); 或
long f; if(n>1)
f=power(n-1)*n; else
f=1; return(f); }
main() {
int n; long y; printf(“请输入一个整数:\n"); scanf("%d",&n); y=power(n); printf("%d!=%ld\n",n,y); }
为了与调用函数提供的实际参数区别开,将函数定义中 的参数表称为形式参数表,简称形参表。将函数调用中的参数 表称为实际参数表,简称实参表
3 空函数 函数类型 函数名( ) { }
[案例8.2] 定义一个有参函数,用于求两个数中的大数。 int max(int x, int y) /*定义一个函数max()*/ { int z; z=x>y?x:y; return (z); }
函数类型 函数名(参数类型1, 参数类型2 ,…);
有以下2种情况,可以省去对被调函数的说明: (1)当被调用函数的函数定义出现在调用函数之前
时。因为在调用之前,编译系统已经知道了被调用函数的 函数类型、参数个数、类型和顺序。
(2)如果在所有函数定义之前,在函数外部(例如 文件开始处)预先对各个函数进行了说明,则在调用函数 中可缺省对被调用函数的说明。
power(1) =1
8.7 数组作为函数参数
数组用作函数参数有两种形式:一种是把数组元素 (又称下标变量)作为实参使用;另一种是把数组名作 为函数的形参和实参使用。
8.3.1 数组元素作为函数实参 8.3.2 数组名作为函数的形参和实参
8.7.1 数组元素作为函数实参
数组元素就是下标变量,它与普通变量并无区别。 数组元素只能用作函数实参,其用法与普通变量完全相同: 在发生函数调用时,把数组元素的值传送给形参,实现单 向值传送。
在程序中,是通过对函数的调用来执行函数体的,其 过程与其它语言的子程序调用相似。
1 函数调用的一般形式为: 函数名(实参列表) 例如:8.2
切记:实参的个数、类型和顺序,应该与被调用函数
所要求的参数个数、类型和顺序一致,才能正确地进行 数据传递。
2 函数的调用方式 1)函数表达式。2)函数语句。3)函数实参。
函数的递归调用过程如下:
power(5) =5*power(4)
power(4) =4*power(3)
power(3) =3*power(2)
power(2) =2*power(1)
power(5) =5*4*3*2*1 power(4) =4*3*2*1
power(3) =3*2*1 power(2) =2*1
说明:
(1) 一个源程序文件由一个或多个函数组成。 (2) 一个C程序由一个或多个源程序文件组成。 (3) C程序的执行是从main函数开始,调用其他函数后流程 返回到main函数,在main函数中结束整个程序的运行。 (4) 所有函数都是平行的,即在定义函数时是互相独立的, 一个函数并不从属于另一个函数,即函数不能嵌套定义。
main() { int max(int x, int y); /*函数说明*/
int a, b, c; printf("input two numbers:\n"); scanf(“%d%d”, &a, &b);
c=max(num1,num2); printf("max=%d\n", c);
}
8. 4 函数的调用
[Return]
8.7.2 数组名作为函数的形参和实参
数组名作函数参数时,既可以作形参,也可以作实参。 数组名作函数参数时,要求形参和相对应的实参都必 须是类型相同的数组(或指向数组的指针变量),都必 须有明确的数组说明
[案例8.7] 已知10个学生的成绩,求平均成绩。
float average(float a[10])
[例8.1] 简单的函数调用 main() { printstar();
print_message();
printstar();
}
printstar()
{
printf(“********************\n”);
}
print_message()
{ printf(“
}
How do you do!\n”);
因此,应预先用赋值、输入等办法,使实参获得确定的值。
(2)形参变量只有在被调用时,才分配内存单元;
调用结束时,即刻释放所分配的内存单元。
因此,形参只有在该函数内有效。调用结束,返回调
用函数后,则不能再使用该形参变量。
(3)实参对形参的数据传送是单向的,即只能把实
参的值传送给形参,而不能把形参的值反向地传送给实
main() { int max(int x, int y); /*函数说明*/
int a, b, c; printf("input two numbers:\n"); scanf(“%d%d”, &a, &b);
c=max(a, b); printf("max=%d\n", c);
}
8.3 函数的参数与返回值
注意:在旧标准中,函数可以缺省参数表。但在新
标准中,函数不可缺省参数表;如果不需要参数,则用 “void”表示,主函数main()例外。
2 有参函数的定义形式 函数类型 函数名( 数据类型 参数,数据类型 参数2…… ) {
说明语句部分; 可执行语句部分; } 有参函数比无参函数多了一个参数表。调用有参函数时, 调用函数将赋予这些参数实际的值。
说明: (1)用数组元素作实参时,只要数组类型和函数的 形参类型一致即可,并不要求函数的形参也是下标变量。 换句话说,对数组元素的处理是按普通变量对待的。 (2)在普通变量或下标变量作函数参数时,形参变 量和实参变量是由编译系统分配的两个不同的内存单元。 在函数调用时发生的值传送,是把实参变量的值赋予形 参变量。
/*求平均值函数*/
{ int i;
float aver, sum=a[0];
for(i=1;i<10;i++)
sum= sum + a[i];
aver= sum/10;
return aver;
}
void main()
{
float score[10],aver;
int i;
printf("\ninput 10 scores:\n");
long f1(int n,int k)
/*计算n的k次方*/
{ long power=n;
int i;
for(i=1;i<k;i++) power *= n;
return power;
}
long f2(int n,int k)
/*计算1到n的k次方之累加和*/
{ long sum=0;
int i;
相关文档
最新文档