第八章函数 重点 1、了解模块化程序设计的思想 2、熟悉掌握函数的使用 3、了解变量的作用范围 [例1]函数调用 main i printf( This is a test! n") p print message printstarO printstarO printf((“************n3); print message printf(" How do you do!n); 81函数( function)介绍 说明: 1.一个源程序文件有一个或多个函数组成 2.一个C程序可以有多个源程序文件组成。 3.任何C程序都从main函数开始执行,当main的最后一条指令 执行完,程序结束 4.所有函数都是独立的,可以互相调用,main不能被调用。 5.函数分为标准函数和用户自定义函数 6.函数分为无参函数和有参函数。 为什么要ⅲ nclude文件? pint, scanfo, putchar o: getchar, puts, gets都在 stdio h中 8.2函数定义及函数声明 1.函数定义 (1).无参数函数的定义 类型标识符函数名()
第八章 函 数 重点: 1、 了解模块化程序设计的思想 2、 熟悉掌握函数的使用 3、 了解变量的作用范围 [例 1:] 函数调用 main() { printf("This is a test!\n"); printstar(); print_message(); printstar(); } printstar() { printf(“* * * * * * * * * * * * \n”); } print_message() { printf(“ How do you do!\n”); } 8.1 函数(function)介绍 说明: 1. 一个源程序文件有一个或多个函数组成。 2. 一个 C 程序可以有多个源程序文件组成。 3. 任何 C 程序都从 main 函数开始执行,当 main 的最后一条指令 执行完,程序结束. 4. 所有函数都是独立的,可以互相调用,main 不能被调用。 5. 函数分为标准函数和用户自定义函数。 6. 函数分为无参函数和有参函数。 为什么要 include 文件? printf();scanf(),putchar();getchar();puts();gets()都在 stdio.h 中。 8.2 函数定义及函数声明 1.函数定义 (1). 无参数函数的定义 类型标识符 函数名( )
(声明部分 语句 (2).有参数函数的定义 类型标识符函数名(形式参数表列) 声明部分 语句 形式参数表列:对形式参数的说明;有两种方法: ① int max(intx,inty) 函数体; ② int max(x,y) Int x,y; 函数体; 注意:在①中xy的数据类型一致,也不能写成 int max( Intx,y) 的型式 (3)可以有空函数 void函数名(参数) 2.函数参数及函数的值 (1)形参和实参 形参:在函数定义时,函数名括号后面的变量名。 实参:在函数被子调用是,函数名括号后面的表达式 (2)调用函数和被调用函数 (3)函数的值 例2:求一个整数的绝对值 int absolute value(int x) i return(X>0=? X:-X) maino i int x,y printf("please input a int x=); scanf(" %d”,&x); y=value(x); printf("In%d absolute is %dn x,y) (4)说明: ①实际参数可以是变量、常量、表达式,它们的值传给形式参 数。实参对形参传递的是值
{ 声明部分 语句 } (2). 有参数函数的定义 类型标识符 函数名(形式参数表列 ) {声明部分 语句 } 形式参数表列:对形式参数的说明;有两种方法: ① int max(int x , int y) { 函数体; } ② int max(x , y) int x,y; { 函数体; } 注意:在①中 x,y 的数据类型一致,也不能写成 int max(int x,y) 的型式。 (3) 可以有空函数 void 函数名( 参数 ) 2.函数参数及函数的值 (1)形参和实参 形参:在函数定义时,函数名括号后面的变量名。 实参:在函数被子调用是,函数名括号后面的表达式。 (2) 调用函数和被调用函数 (3)函数的值。 例 2: 求一个整数的绝对值 int absolute_value(int x) { return(X>0=? X: -X); } main() { int x,y; printf(“please input a int x=”); scanf(“%d”,&x); y=value(x); printf(“\n %d absolute is %d\n”,x,y); } (4)说明: ① 实际参数可以是变量、常量、表达式,它们的值传给形式参 数。实参对形参传递的是值;
②形参在未调用时,并没有分配到内存单元,只有被子调用 时才分配内存单元,调用完后释放内存单元 ③实参与形参的个数、类型要匹配 ④实参与形参是自左向右一一配对的 ⑤形参在函数中被改变并不影响实参的值。 B] 3: float max( float x, floaty, float z) float t t=t>z?t:z return(t) ma i float x, y, z, maxvale printf("please input ax, y, z: ) scanf( %of%of%of, &x, &y, &z) maxvale=max(x, y, z) printf(" In the max is %fn,, max); 3函数的返回值 (1)若要从函数中返回一个值,在函数中要用 return语句; 格式: return(表达式 return 程序执行到 return语句时就退出被调用的程序,返回到被调 用的语句处。 例. void sp(intn) i int I; for(1=0; K<n; 1++) printf("; return 例4.解下述表达式 <0 3(x>=0) float ix(float x) i if (x<0 return(x*x-x+1) eise return(xx*x+x+3) main(
② 形参在未调用时,并没有分配到内存单元,只有被子调用 时才分配内存单元,调用完后释放内存单元。 ③实参与形参的个数、类型要匹配。 ④实参与形参是自左向右一一配对的。 ⑤形参在函数中被改变并不影响实参的值。 例 3:float max(float x,float y,float z) {float t; t=x>y ? x : y; t=t>z?t : z; return(t); } main() { float x,y,z,maxvale; printf(“please input a x,y,z :”); scanf(“%f%f%f”,&x,&y,&z); maxvale=max(x,y,z); printf(“\n the max is %f\n”, max); } 3.函数的返回值 (1)若要从函数中返回一个值,在函数中要用 return 语句; 格式:return ( 表达式); return; 程序执行到 return 语句时就退出被调用的程序,返回到被调 用的语句处。 例. void spc(int n) { int I; for ( I=0;I<n;I++) printf(“ “); return;} 例 4. 解下述表达式 x*x-x+1 (x<0) y= x*x*x+x+3 (x>=0) float fx(float x) { if (x<0) return(x*x-x+1); else return(x*x*x+x+3); } main() { float x,y;
printf( please input ax ) scanf( %of, &x) y=fx(x) printf(n whten x is %f, x) printf(" n the y is %fy); 4.对被调用函数的说明 (1)一个函数中调用另一函数需具备的条件: ①被调用的函数必须存在 ②如果使用库函数,还应用# include命令调用头文件 (2)如果用户自定义的函数,一般还应在主调函数中对被调函 数的返回值的类型说明。型式为: 类型标识符被调用函数名() 例5: main float max(),/*对被调函数的说明,也可表示为foat* /*max(float x, float y, float z)/ float*/ /*max(float, float, float * float x,y printf("please inputax, y, z: ) scanf( %of%of%f, &x, &y, &z) printf( n the max is %fn", max(x, y, z); float max(float x, float y, float z) float t. y?X y return(t): (3)以下几种情况可以不在调函数前对被调用函数作类型说 明 ①如果数的值(函数返回的值)是整型或字符型,系统对 它们自动按整型说明 ②如果被调用函数的定义出现在主调函数之前,可以不必 加以说明。 ③如果已在所有函数定义之前,在文件的开头,在函数的 外部已说明了函数类型,则在各调用函数中不用再说明。 83函数调用 831函数调用的一般形式 1.函数名(实参表列)
printf(“please input a x :”); scanf(“%f”,&x); y=fx(x); printf(“\n whten x is %f”,x); printf(“\n the y is %f”,y); } 4.对被调用函数的说明 (1)一个函数中调用另一函数需具备的条件: ①被调用的函数必须存在。 ②如果使用库函数,还应用#include 命令调用头文件; (2)如果用户自定义的函数,一般还应在主调函数中对被调函 数的返回值的类型说明。型式为: 类型标识符 被调用函数名( ); 例 5: main() { float max( ); /*对被调函数的说明,也可表示为 float*/ /*max(float x,float y,float z) 及 float*/ /*max(float,float,float )*/ float x,y,z; printf(“please input a x,y,z :”); scanf(“%f%f%f”,&x,&y,&z); printf(“\n the max is %f\n”, max(x,y,z)); } float max(float x,float y,float z) {float t; t=x>y ? x : y; t=t>z?t : z; return(t); } (3)以下几种情况可以不在调函数前对被调用函数作类型说 明。 ①如果数的值(函数返回的值)是整型或字符型,系统对 它们自动按整型说明。 ②如果被调用函数的定义出现在主调函数之前,可以不必 加以说明。 ③如果已在所有函数定义之前,在文件的开头,在函数的 外部已说明了函数类型,则在各调用函数中不用再说明。 8.3 函数调用 8.3.1 函数调用的一般形式 1.函数名(实参表列)
实参表列的实参与实参之间用逗号隔开,实参可为表达式, 实参的个数要与形参一一对应 2.函数在程序中的位置。 ①作为一般语句。 Printf ②作为一个表达式的一部份。C=2*max(a,b) ③作为另一个函数的参数。M=max(a,max(bc) 832函数的嵌套调用 在一个函数中调用一函数,在被调函数中又调用另一函数。 ●函数中调用其它函数叫函数的嵌套 ◆C中函数的定义是平行的,除了main以外,都可以互相调用 函数不可以嵌套定义。 main a 调a调b 8.3.3函数的递归调用 函数自己调用自己,即函数的递归调用,递归调用可以使程序简 洁、代码紧凑,但要牺牲内存空间作处理时的堆栈。 要点:在函数中要有终止递归调用的i语句 例6:如要求一个n(n的阶乘)的值可用下面递归调用: n- nf(n-1)n≠1 # include“ stdio. h main( i long mul( int n); int m printf("Calculate n!n=?n") scanf("%od",&m); *键盘输入数据*/ printf("o%dl=%ldn",m,mu(m)/*调用子程序计算并输出* getcho long mul( int n)
实参表列的实参与实参之间用逗号隔开,实参可为表达式, 实参的个数要与形参一一对应。 2.函数在程序中的位置。 ①作为一般语句。 Printf(); ②作为一个表达式的一部份。C=2*max(a,b); ③作为另一个函数的参数。 M=max(a,max(b,c)); 8.3.2 函数的嵌套调用 在一个函数中调用一函数,在被调函数中又调用另一函数。 函数中调用其它函数叫函数的嵌套。 C 中函数的定义是平行的,除了 main 以外,都可以互相调用。 函数不可以嵌套定义。 8.3.3 函数的递归调用 函数自己调用自己, 即函数的递归调用, 递归调用可以使程序简 洁、代码紧凑, 但要牺牲内存空间作处理时的堆栈。 要点:在函数中要有终止递归调用的 if 语句。 例 6:如要求一个 n!(n 的阶乘)的值可用下面递归调用: 1 n=1 f(n)= n*f(n-1) n≠1 #include “stdio.h” main() { long mul( int n); int m; printf("Calculate n! n=?\n"); scanf("%d", &m); /*键盘输入数据*/ printf("%d!=%ld\n", m, mul(m));/*调用子程序计算并输出*/ getch(); } long mul( int n)