《C语言设计课件:第8章 函数》由会员分享,可在线阅读,更多相关《C语言设计课件:第8章 函数(46页珍藏版)》请在金锄头文库上搜索。
1、第第第第8 8 8 8章章章章 函数函数函数函数初识函数初识函数1 #include int main() /主函数主函数 int a,b; printf(“input a number:n”);/输出函数输出函数 scanf(“%d”,&a); /输入函数输入函数 b=sqrt(a); /求平方根函数求平方根函数 printf(“%d”,b); /输出函数输出函数 return 0;初识函数初识函数2/*从键盘输入从键盘输入3个数,求和并输出。个数,求和并输出。*/ #include int myAdd(int x,int y,int z) int s; s=x+y+z; return s;
2、 int main() /主函数主函数 int a,b,c,sum; printf(“input 3 numbers:n”);/输出函数输出函数 scanf(“%d%d%d”,&a,&b,&c); /输入函数输入函数 sum=myAdd(a,b,c); /用户自定义函数用户自定义函数printf(“sum=%d”,sum); /输出函数输出函数 return 0; 什么是函数?什么是函数?n函数:是能够完成某一独立功能的一段代码。函数:是能够完成某一独立功能的一段代码。 nC语言中,函数是实现模块化的工具。语言中,函数是实现模块化的工具。一个用函数解决问题的例子一个用函数解决问题的例子 定义若
3、干具有不同功能的函数,在定义若干具有不同功能的函数,在main函数中分函数中分别调用它们,用以解决这个学生信息输入、计算成绩、别调用它们,用以解决这个学生信息输入、计算成绩、查找、输出等问题。如:查找、输出等问题。如: main() /定义必要的变量定义必要的变量 inputScore(); /输入学生姓名及成绩信息输入学生姓名及成绩信息 computeTotalScore();/计算每个学生的总成绩计算每个学生的总成绩 searchByName(); /按名字查找某个学生的信息按名字查找某个学生的信息 printSearchInfo();/输出查找到的学生信息输出查找到的学生信息 main函
4、数只负责解决问题的流程;具体子问题函数只负责解决问题的流程;具体子问题的实现交给不同的函数去处理。的实现交给不同的函数去处理。 函数的定义函数的定义n除了系统提供的函数外除了系统提供的函数外,我们都需要对函数进,我们都需要对函数进行定义。行定义。 n函数定义的一般形式如下:函数定义的一般形式如下:函函数数类类型型 函函数数名名( (类类型型名名 形形式式参参数数1 1,类类型名型名 形式参数形式参数2 2,) ) /* /* 函数体函数体 * */ / 说明部分说明部分 语句部分语句部分 函数定义示例函数定义示例(1) n无参数无返回值的函数定义无参数无返回值的函数定义 如:定义如:定义pri
5、ntStar函数,用以在屏幕上输出函数,用以在屏幕上输出5个个*符号。符号。 void printStar( ) int star; for(star=1; star=5; star+) printf(*); printf(n) ; void:函数无返回:函数无返回值时使用的类型值时使用的类型n无参数无返回值的函数的调用无参数无返回值的函数的调用1 #include void printStar( ) int star; for(star=1; star=5; star+) printf(*); printf(n) ; int main( ) printStar( ); return 0;n
6、无参数无返回值的函数的调用无参数无返回值的函数的调用2#include void printStar( ); /函数声明函数声明 int main( ) printStar( ); /函数调用函数调用 return 0; void printStar( ) /函数定义函数定义(首部首部) int star; for(star=1; star=5; star+) printf(*); printf(n) ; 自定义函数的自定义函数的声明声明 n在程序的开头加上对应函数的声明,就不会出在程序的开头加上对应函数的声明,就不会出现函数未定义现函数未定义(或重复定义或重复定义)的错误。的错误。 n函数声
7、明的形式:函数声明的形式: 返回值类型返回值类型 函数名称函数名称(参数类型参数类型 参数参数1, ) ; 其中前面的与函数定义时的首部完全一样,但其中前面的与函数定义时的首部完全一样,但末尾必须加末尾必须加“;”。 n如对如对printStar函数的声明为:函数的声明为: void printStar( );函数定义示例函数定义示例(2)n无参数有返回值的函数定义无参数有返回值的函数定义 n如定义函数如定义函数sum_100,用以求,用以求1+2+3+100的的和,并将结果返回给调用它的函数。和,并将结果返回给调用它的函数。 int sum_100( ) int s=0, i; for(i=
8、1; i=100; i+) s=s+i; return s; /用用return返回一个值给主调函数返回一个值给主调函数 n无参数有返回值的函数调用无参数有返回值的函数调用 #include int sum_100( ); /函数声明函数声明 int main( ) int s1; s1 = sum_100( ); /函数调用函数调用 printf(和值为:和值为:%dn, s1); return 0; int sum_100( ) /函数定义函数定义(首部首部) int s=0, i; for(i=1; i=100; i+) s=s+i; return s; /返回值给主调函数返回值给主调函
9、数 小结小结 1、函数是一段能完成独立功能的代码、函数是一段能完成独立功能的代码 2、C程序是由函数构成的,每个程序是由函数构成的,每个C程序都是从程序都是从main函函数的第一条语句开始执行,至最后一条语句结束数的第一条语句开始执行,至最后一条语句结束 3、函数在调用前需要声明、函数在调用前需要声明 4、编写一个函数需要知道以下几件事:、编写一个函数需要知道以下几件事: (1) 返回值的类型是什么?返回值的类型是什么?(每个函数只能通过每个函数只能通过return语句返回一个值语句返回一个值) (2) 函数有无参数及各参数的类型?函数有无参数及各参数的类型? (3) 函数的具体功能是什么?函
10、数的具体功能是什么? 5、函数的调用方式、函数的调用方式函数定义示例函数定义示例(3) n有参数无返回值的函数定义有参数无返回值的函数定义 如定义如定义printStar_n()函数,用以在屏幕的一行函数,用以在屏幕的一行上输出上输出n个个*号。其中号。其中n的值是由调用该函数的函数传的值是由调用该函数的函数传递过来的。递过来的。 void printStar_n ( int n ) int star; for(star=1; star=n; star+) printf(*); printf(n); 形参表形参表n有参数无返回值的函数调用有参数无返回值的函数调用#include void pr
11、intStar2(int n); /函数声明函数声明 int main( ) int starNum; scanf(%d, &starNum); printStar_n ( starNum ); /函数调用函数调用 return 0; void printStar_n ( int n ) /函数定义函数定义(首部首部) int star; for(star=1; star=n; star+) printf(*); printf(n); 形参表形参表实参表实参表函数定义示例函数定义示例(4) n 有参数有返回值的函数定义有参数有返回值的函数定义 如定义函数如定义函数sum_n(),用以求,用以求
12、1+2+3+n的的和,并将结果返回给调用它的函数。和,并将结果返回给调用它的函数。 int sum_n( int n ) int s=0, i; for(i=1; i=n; i+) s=s+i; return s; /通过通过return返回一个值返回一个值 n有参数有返回值的函数调用有参数有返回值的函数调用#include int sum_n( int n ); /函数声明函数声明 int main( ) int s1, n; scanf(%d, &n); s1 = sum_n( n ); /函数调用函数调用 printf(和值为:和值为:%dn, s1); return 0; int su
13、m_n ( int n ) /函数定义函数定义 (首部首部) int s=0, i; for(i=1; i=n; i+) s=s+i; return s; /返回一个值给主调函数返回一个值给主调函数 printf(和值为:和值为:%dn, sum_n(n) ); 练习练习1、自定义函数、自定义函数mypower(),求,求x的的y次幂,并在次幂,并在主函数中调用主函数中调用mypower()函数,输出结果。函数,输出结果。 double mypower( double x, int y)2、自定义函数、自定义函数mymax3(),求出,求出3个参数中的最个参数中的最大值,将值返回给调用它的函数
14、。然后在主函大值,将值返回给调用它的函数。然后在主函数中调用数中调用myfac()函数,输出该结果。函数,输出该结果。 float mymax3(float x, float y, float z) 小结小结有参数函数的编写:有参数函数的编写: 1、需要明确参数有多少个,每个参数的数据类、需要明确参数有多少个,每个参数的数据类型是什么,函数的功能是什么?型是什么,函数的功能是什么? 2、函数定义中的参数称为形式参数、函数定义中的参数称为形式参数(可以看作可以看作是已经定义好的变量是已经定义好的变量),调用函数时的参数称,调用函数时的参数称为实在参数为实在参数(必须进行定义必须进行定义) 3、函
15、数在调用时,实在参数的值传递给了形式、函数在调用时,实在参数的值传递给了形式参数。参数。函数的参数传递函数的参数传递#include void myExchange( int x, int y); int main( ) int x1, y1; scanf(%d%d, &x1, &y1); printf(Before exchange:x1=%d, y1=%dn, x1,y1); myExchange(x1, y1); printf(After exchanged:x1=%d, y1=%dn, x1,y1); return 0; void myExchange(int x, int y) in
16、t t; printf(Before exchanging:x=%d, y=%dn, x, y); t=x; x=y; y=t; printf(After exchanging:x=%d, y=%dn, x, y); 思考:为何无法实现思考:为何无法实现x与与y的交换?的交换?如何用函数实现如何用函数实现x与与y交换?交换?#include void myExchange( int *x, int *y); int main( ) int x1, y1; scanf(%d%d, &x1, &y1); printf(Before exchange:x1=%d, y1=%dn, x1,y1); m
17、yExchange(&x1, &y1); printf(After exchanged:x1=%d, y1=%dn, x1,y1); return 0; void myExchange(int *x, int *y) int t; t=*x; *x=*y; *y=t; 函数定义示例函数定义示例(5) n形式参数为数组名的函数形式参数为数组名的函数(有返回值有返回值) 如编写函数如编写函数myMax(),找出某班的总成绩中的,找出某班的总成绩中的最高分并返回该值。在主函数中调用最高分并返回该值。在主函数中调用myMax()函数,最后在主函数中输出最高分。函数,最后在主函数中输出最高分。 int
18、myMax(int score, int n) /找出找出score数组中数组中n个元素的最大值个元素的最大值 /返回最大值返回最大值 形式参数为数组的函数形式参数为数组的函数 int myMax(int score, int n) int i, max_id; max_id = 0; /假定第假定第0个元素为最大值个元素为最大值 for (i=1; iscoremax_id) max_id = i ; return scoremax_id; 形式参数为数组的函数的调用形式参数为数组的函数的调用#include int myMax( int score, int n); int main()
19、int stu_score10, i,max; for(i=0; i10; i+) scanf(%d, &stu_scorei); max=myMax( stu_score , 10); /函数调用函数调用 printf(%d, max); return 0; int myMax( int score , int n) int i, max_id; max_id = 0; /假定第假定第0个元素为最大值个元素为最大值 for (i=1; iscoremax_id) max_id = i ; return scoremax_id; 函数定义示例函数定义示例(6) n形式参数为数组名的函数形式参数
20、为数组名的函数(无返回值无返回值) 如编写函数如编写函数mySort(),以对某班的总成绩进行,以对某班的总成绩进行按从高到低的顺序进行排序。在主函数中调用按从高到低的顺序进行排序。在主函数中调用mySort()函数,最后在主函数中输出排序后的结果。函数,最后在主函数中输出排序后的结果。 void mySort(int score, int n) /用选择法对用选择法对score数组中的数组中的n个元素按从高到个元素按从高到低的顺序进行排序低的顺序进行排序 所谓选择法就是先将所谓选择法就是先将n个数中最小的数与个数中最小的数与a0对换对换;再将再将a1到到an-1中最小的中最小的数与数与a1对
21、换对换每比较一轮每比较一轮,找出一个未找出一个未经排序的数中最小的一个。共比较经排序的数中最小的一个。共比较n-1轮。轮。未排序时的情况未排序时的情况: :a1 a2 a3 a4 a5a1 a2 a3 a4 a5 3 6 1 9 4 3 6 1 9 4 将将5 5个数中最小的数个数中最小的数1 1与与a a1 1对换对换: : 1 1 6 6 3 3 9 4 9 4 将余下的将余下的4 4个数中最小的数个数中最小的数3 3与与a a2 2对换对换 1 1 3 3 6 6 9 4 9 4 将余下的将余下的3 3个数中最小的数个数中最小的数4 4与与a a3 3对换对换 1 3 1 3 4 4 9
22、 9 6 6 将余下的将余下的2 2个数中最小的数个数中最小的数6 6与与a a4 4对换对换 1 3 4 1 3 4 6 6 9 9 形式参数为数组的函数形式参数为数组的函数 void mySort(int a, int n) /存放在存放在1.n int i, max_id, j, t; 比较比较n-1轮轮,每轮将每轮将aian之间的最大值与之间的最大值与ai进行交换进行交换 ? /假定假定ai是是aian之间的最大值之间的最大值 /顺序扫描顺序扫描ai+1.an,找更大值,记录其下标,找更大值,记录其下标 /以下三条语句将最大值交换到第以下三条语句将最大值交换到第i个位置上个位置上 t=
23、amax_id; amax_id = ai; ai = t; for (i=1; i=n-1; i+)max_id = i;for (j=i+1; jamax_id ) max_id = j ;形式参数为数组的函数的调用形式参数为数组的函数的调用#include void mySort( int a, int n); int main() int stu_score100, i,n; printf( input n: ); scanf( %d , &n); for(i=1; i=n; i+) scanf(%d, &stu_scorei); mySort( stu_score, n); /函数调
24、用函数调用 for(i=1; i1)-规律规律 1 (n=1)-递归结束条件递归结束条件int myFac( int n) if (n=1) return 1; /递归的结束条件递归的结束条件 return n*myFac(n-1); myFac(n)就是求就是求n!, myFac(n-1)就是求就是求(n-1) ! 例:用递归函数求例:用递归函数求n!的完整程序的完整程序#include int myFac(int n); main() int f, n; scanf(%d, &n); f = myFac(n); printf(%d!=%dn, n, f); int myFac( int n
25、) int s; if (n=1) s=1; /递归的结束条件递归的结束条件 else s= n*myFac(n-1); return s; 练习:求练习:求Fibonacci数列的第数列的第n个数。个数。int fibona( int n) if (n=1 |n=2) ; else return ; main( ) int n,l; printf(“enter n:”); sacnf(“%d”,&n); ; printf(“result : %d”, l);return 1return 1fibona(n-1)+fibona(n-2)fibona(n-1)+fibona(n-2)l=l=fi
26、bona(nfibona(n) )小结小结n递归函数的编写:递归函数的编写: 1、要分析出递归的表达式。、要分析出递归的表达式。 2、一定要在函数中明确递归函数在什么情况、一定要在函数中明确递归函数在什么情况下结束。下结束。 变量的存储类型变量的存储类型局部变量和全局变量局部变量和全局变量n按变量的定义位置可分为:按变量的定义位置可分为: 局部变量、全局变量局部变量、全局变量 n局部变量:定义在函数内部或复合语句中的变量局部变量:定义在函数内部或复合语句中的变量 作用范围:只在本函数内或分程序内有效。作用范围:只在本函数内或分程序内有效。 说明:说明:P184P184 n全局变量:定义在任何函
27、数外面的变量。全局变量:定义在任何函数外面的变量。 作用范围:从定义该变量的位置开始,到本源文作用范围:从定义该变量的位置开始,到本源文件结束。件结束。n同名变量:内层同名变量屏蔽外层同名变量同名变量:内层同名变量屏蔽外层同名变量 全局变量的应用:全局变量的应用:增加函数间数据联系的渠道增加函数间数据联系的渠道#includefloat s; /*全局变量全局变量*/float vs(float r,float h) float t; t=3.14*r*r*h; s=2*3.14*r*(r+h); return t;int main() float v; float r,h; printf(“
28、input the radius and height:n”); v=vs(r,h); printf(“v=%f, s=%fn”,v,s); return 0; 局部变量和全局变量小结:局部变量和全局变量小结:n局部变量:保证了函数之间的独立性。(常用)局部变量:保证了函数之间的独立性。(常用)n全局变量:增加了函数之间数据传递的通道,但降全局变量:增加了函数之间数据传递的通道,但降低了函数间的独立性,降低了程序的清晰性,因此低了函数间的独立性,降低了程序的清晰性,因此副作用太大。除非特别需要时,一般不用。副作用太大。除非特别需要时,一般不用。n占用内存情况:占用内存情况:局部变量仅当他所在的
29、函数被调用时才存在,执行完局部变量仅当他所在的函数被调用时才存在,执行完该函数返回后,该变量不再存在;该函数返回后,该变量不再存在;全局变量在程序的全部执行过程中一直存在,直至程全局变量在程序的全部执行过程中一直存在,直至程序执行完,才释放它所占的内存空间。序执行完,才释放它所占的内存空间。本章作业:本章作业:1、对、对ACM程序进行改写,要求改写后的主函数为:程序进行改写,要求改写后的主函数为: #define N 100 int main() int aN+1,n,m; scanf(“%d%d”,&n,&m); input(); /读入数组内容读入数组内容 reverse(); /第一次翻
30、手第一次翻手 reverse(); /第二次翻手第二次翻手 reverse(); /第三次翻手第三次翻手 output(); /输出数组内容输出数组内容 return 0; 2、编写两个函数、编写两个函数: is_prime()用于判断某正整数用于判断某正整数x是否素数,有返回值;是否素数,有返回值; print_prime()调用调用is_prime() ,用于输出,用于输出x(x=1)以内的所有素数,以内的所有素数,无返回值。无返回值。 输入有以下两种情况(输入有以下两种情况(x代表一个正整数):代表一个正整数): 当输入为当输入为+x,表示判断,表示判断x是否素数,输出为是否素数,输出为“Yes”或或“No”; 当输入为当输入为-x,表示输出,表示输出x以内的所有素数,每以内的所有素数,每行输出五个素数,以空格分隔。行输出五个素数,以空格分隔。