《第8章函数PPT讲稿.ppt》由会员分享,可在线阅读,更多相关《第8章函数PPT讲稿.ppt(52页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第8章函数第1页,共52页,编辑于2022年,星期一C程序的结构如右图所示:程序的结构如右图所示:1.一个一个C程序可分为若干程序可分为若干个函数个函数2.每个程序有且只能有一每个程序有且只能有一个主函数(个主函数(main),其),其它函数都是子函数它函数都是子函数3.子函数可以互相调用,子函数可以互相调用,但主函数不能被调用但主函数不能被调用4.一个一个C源程序由一个或源程序由一个或多个文件构成,一个源多个文件构成,一个源程序文件是一个编译单程序文件是一个编译单位位8.1 概述概述mainabcfgdehfifai第2页,共52页,编辑于2022年,星期一说明:说明:(1)C程序的执行从程
2、序的执行从main函数开始函数开始调用其它函数后仍回到调用其它函数后仍回到main函数,函数,程序在程序在main函数结束时结束函数结束时结束(2)所有子函数都是平行的,任何)所有子函数都是平行的,任何子函数都不属于其它函数子函数都不属于其它函数(3)从用户的角度看,函数可分为:)从用户的角度看,函数可分为:标准函数(库函数)标准函数(库函数)自定义函数自定义函数(4)从函数的形式看,可分为:)从函数的形式看,可分为:无参数函数无参数函数 有参数函数有参数函数例例8.1#include void printstar()printf(“*”);void printmessage()printf(
3、“Hello World!”);printstar();void main()printstar();printmessage();概述(续)概述(续)第3页,共52页,编辑于2022年,星期一函数定义的一般形式:函数定义的一般形式:类型说明类型说明 函数名(函数名(形式参数说明形式参数说明)函数体函数体 形式参数说明方法:形式参数说明方法:类型说明类型说明 变量名变量名,类型说明符类型说明符 变量名变量名1.无参函数的定义形式无参函数的定义形式 类型说明类型说明 函数名()函数名()函数体函数体2.有参函数的定义形式有参函数的定义形式 类型说明类型说明 函数名(形式参数说明)函数名(形式参数
4、说明)函数体函数体3.空函数的定义形式空函数的定义形式 类型说明类型说明 函数名(函数名(形式参数说明形式参数说明)例例8.2#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);8.2 函数定义的一般形式函数定义的一般形式第4页,共52页,编辑于2022年,星期一 一般情况下,函数体由两部分一般情况下,函数体由两部分组成:组成:局部变量说明局部变量说明 语句语句 局部变量:函数体内定义的变量,
5、局部变量:函数体内定义的变量,其有效范围仅限于所在的函数内其有效范围仅限于所在的函数内部,离开函数体则无意义。部,离开函数体则无意义。#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);函数定义的一般形式(续)函数定义的一般形式(续)第5页,共52页,编辑于2022年,星期一 一个一个C程序由若干个函数构成,各函程序由若干个函数构成,各函数相互调用时经常需要传递一些数据,数相互调用时经常需要传
6、递一些数据,即主调函数把数据传递给被调用函数,即主调函数把数据传递给被调用函数,经被调用函数处理后,得到一个确定经被调用函数处理后,得到一个确定的结果,在返回主调函数时,把这个的结果,在返回主调函数时,把这个结果带回。结果带回。#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);c=max(a,b);主调用函数主调用函数int max(int x,int y)return(z);被调用函数被调
7、用函数a,bz函数间的信息来往是通过函数间的信息来往是通过参数传递参数传递和和返回语句返回语句实现的实现的8.3 函数参数和函数的值函数参数和函数的值第6页,共52页,编辑于2022年,星期一1.形式参数与实际参数形式参数与实际参数形式参数(形参):形式参数(形参):定义定义函数时使用的参数函数时使用的参数实际参数(实参):实际参数(实参):引用引用函数时使用的参数函数时使用的参数函数函数max有两个形式参数:有两个形式参数:x和和y形参形参x和和y只在函数只在函数max中使用中使用a和和b是主函数中定义的变量,是主函数中定义的变量,main函数函数调用函数调用函数max,a和和b为函数为函数
8、max的实参的实参#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);23 89Max is 89函数参数和函数的值(续)函数参数和函数的值(续)第7页,共52页,编辑于2022年,星期一说明:说明:(1)定义函数时,必须说明形参的类型。)定义函数时,必须说明形参的类型。形参只能是形参只能是变量变量或或数组数组。(2)函数被调用前,形参不占用内存;函)函数被调用前,形参不占用内存;函数调用结束
9、后,形参所占用的内存也将被数调用结束后,形参所占用的内存也将被回收回收(3)实参可以是)实参可以是常量、变量常量、变量或或表达式表达式(4)实参与形参的类型应相同或赋值兼容。实参与形参的类型应相同或赋值兼容。字符型和整形可以相互匹配。字符型和整形可以相互匹配。(5)C语言中,实参对形参的数据传递是语言中,实参对形参的数据传递是“值传递值传递”,单向传递,只能由实参传,单向传递,只能由实参传给形参,反之不行。它仅由参数的对应给形参,反之不行。它仅由参数的对应位置决定,与参数的名字无关。位置决定,与参数的名字无关。#include int max(int x,int y)int z;z=xy?x:
10、y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);思考:思考:将将max作如下变形会怎样?作如下变形会怎样?int max(int x,int y)x=xy?x:y;return(x);int max(int b,int a)int c;c=ba?b:a;return(c);函数参数和函数的值(续)函数参数和函数的值(续)第8页,共52页,编辑于2022年,星期一例例8.3 读程序,写出运行结果读程序,写出运行结果#include int sum(int a,int b)a
11、=a+b;b=a+b;return a;void main()int a=1,b=3,c;c=sum(a,b);printf(“Sum of%d,%d is%dn”,a,b,c);Sum of 1,3 is 413abab1347函数参数和函数的值(续)函数参数和函数的值(续)第9页,共52页,编辑于2022年,星期一2.函数的返回值函数的返回值(1)返回函数值的方法)返回函数值的方法 函数的返回值也就是函数值,函数的返回值也就是函数值,是一个确定的值。是一个确定的值。如果一个函数有返回值,就必须如果一个函数有返回值,就必须 使用使用return语句语句 一个函数中可以有一个以上的一个函数中可
12、以有一个以上的return 语句,但不论执行到哪个语句,但不论执行到哪个return都将都将 结束函数的调用返回主调函数结束函数的调用返回主调函数 return语句中的括号可以省略;语句中的括号可以省略;return 后面的值可以是一个表达式后面的值可以是一个表达式#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);if(xy)return x;return y;return(xy?x:y);
13、函数参数和函数的值(续)函数参数和函数的值(续)第10页,共52页,编辑于2022年,星期一(2)函数值的类型)函数值的类型 函数的类型即函数值的类型。例如:函数的类型即函数值的类型。例如:函数函数max是是int型的即函数值是型的即函数值是int 型的型的 省略了类型说明符的函数是省略了类型说明符的函数是int型的型的 return语句中表达式的值一般应与语句中表达式的值一般应与 函数类型一致函数类型一致 如果不一致,则需要进行类型转换。如果不一致,则需要进行类型转换。只有数值型数据可以进行自动类型只有数值型数据可以进行自动类型 转换,以函数类型为准转换,以函数类型为准#include in
14、t max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);float a,b;int c;float z;1.5 2.5Max is 2(float x,float y)函数参数和函数的值(续)函数参数和函数的值(续)第11页,共52页,编辑于2022年,星期一(3)不需要返回值的函数)不需要返回值的函数 如果函数中没有使用如果函数中没有使用return语句,函语句,函数返回的是一个不确定的数值数返回的是一个不确定的数值
15、 如果一个函数不需要返回值(表示一如果一个函数不需要返回值(表示一个过程),可以用个过程),可以用void作类型说明作类型说明 如果一个函数被声明为如果一个函数被声明为void类型,就不允类型,就不允许再引用它的返回值(即只能用函数语句许再引用它的返回值(即只能用函数语句形式进行调用)形式进行调用)#include void printstar()printf(“*”);void printmessage()printf(“Hello World!”);printstar();void main()printstar();printmessage();函数参数和函数的值(续)函数参数和函数的值
16、(续)第12页,共52页,编辑于2022年,星期一1.函数调用的一般形式函数调用的一般形式 函数名(实参表列)函数名(实参表列)说明:说明:如果调用无参函数,实参表列可以忽如果调用无参函数,实参表列可以忽略,但括号不能省略,但括号不能省 实参的个数和形参个数应相等实参的个数和形参个数应相等 实参与形参按顺序对应,类型应匹配,实参与形参按顺序对应,类型应匹配,必要时使用类型转换必要时使用类型转换注意:注意:不同系统中,实参的计算顺序不同。不同系统中,实参的计算顺序不同。微机上一般是从右到左。为避免由此引微机上一般是从右到左。为避免由此引起的混乱,一般应在调用函数前计算出起的混乱,一般应在调用函数
17、前计算出实参的值。实参的值。#include int max(int x,int y)int z;z=xy?x:y;return(z);void main()int a,b,c;scanf(“%d%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);float max(float x,float y)float z;z=xy?x:y;return(z);例例8.4 读程序,写出结果读程序,写出结果#include int f(int a,int b)int c;if(ab)c=1;else if(a=b)c=0;else c=1;return c;void m
18、ain()int i=2,p;p=f(i,i+);printf(“%d”,p);void main()int i=2,j,p;j=+i;p=f(i,j);printf(“%d”,p);8.4 函数的调用函数的调用第13页,共52页,编辑于2022年,星期一2.函数调用的方式函数调用的方式(1)函数语句)函数语句 形式为:形式为:函数名(实参表列)函数名(实参表列)例如:例如:printmessage()();说明:说明:这种方式不要求函数带返回值,函数仅完成一定的这种方式不要求函数带返回值,函数仅完成一定的操作操作(2)函数表达式)函数表达式 函数的返回值参与运算函数的返回值参与运算 例如:例
19、如:m=max(a,b);m=3*max(a,b);printf(“max is%dn”,max(a,b);说明:说明:这种方式不能用于这种方式不能用于void型函数型函数函数的调用(续)函数的调用(续)第14页,共52页,编辑于2022年,星期一3.函数调用的执行过程函数调用的执行过程 按从右向左的顺序,计算实按从右向左的顺序,计算实参中各表达式的值参中各表达式的值 按照位置,将实参的值一按照位置,将实参的值一 一一对应的传送给形参对应的传送给形参 执行被调用函数执行被调用函数 当遇到当遇到return(表达式表达式)语句时,语句时,计算表达式的值,并返回主调计算表达式的值,并返回主调函数函
20、数例例8.5 读程序,写出结果读程序,写出结果#include int iabs(float x)return(x0?x;-x);void main()float x=-1.2,y;y=iabs(2*x);printf(“x=%f,iabs(2*x)=%fn”,x,y);X=1.200000,iabs(2*x)=2.400000函数的调用(续)函数的调用(续)第15页,共52页,编辑于2022年,星期一4.函数的原形说明函数的原形说明在程序中调用函数需满足以下条件:在程序中调用函数需满足以下条件:(1)被调函数必须存在,且遵循)被调函数必须存在,且遵循 “先定义后使用先定义后使用”的原则的原则
21、(2)如果被调函数的定义在主函)如果被调函数的定义在主函 数之后,可以先给出数之后,可以先给出原形说原形说 明明。原形说明的形式:原形说明的形式:函数类型函数类型 函数名(参数类型函数名(参数类型 参数名参数名,参数类型参数类型 参数名参数名,);库函数的原形说明存放在头文件中,库函数的原形说明存放在头文件中,通过使用通过使用include预处理命令将这些预处理命令将这些原形说明插入程序中原形说明插入程序中例如(先定义后使用)例如(先定义后使用)#include float f(float x)return 2*x*x+3*x+1;void main()float x;scanf(“%f”,&
22、x);printf(“y=%fn”,f(x);例如(后定义先声明)例如(后定义先声明)#include float f(float);void main()float x;scanf(“%f”,&x);printf(“y=%fn”,f(x);float f(float x)return 2*x*x+3*x+1;例如(使用库函数)例如(使用库函数)#include#include void main()float x,y;scanf(“%f”,&x);y=sin(x*3.1415926/180);printf(“sin(%f)=%fn”,x,y);函数的调用(续)函数的调用(续)第16页,共52
23、页,编辑于2022年,星期一嵌套调用是指在一个函数的函数体嵌套调用是指在一个函数的函数体中又调用了其它函数中又调用了其它函数程序的执行过程:程序的执行过程:第一层第一层 第二层第二层 第三层第三层main()printstar()printstar();printmessage()printstar()printmessage();printstar();例例8.1#include void printstar()printf(“*”);void printmessage()printf(“Hello World!”);printstar();void main()printstar();pr
24、intmessage();8.5 函数的嵌套调用函数的嵌套调用第17页,共52页,编辑于2022年,星期一例例8.6 用弦截法求方程的根用弦截法求方程的根 x3-5x2+16x 80=0f(x)x2f(x1)f(x2)f(x1)x1x算法分析:算法分析:对于对于f(x)=x3-5x2+16x 801.给定两个值给定两个值x1、x2,满足,满足x1x2且且f(x1)和和f(x2)符号相反符号相反2.过过(x1,f(x1),(x2,f(x2)两点做直线两点做直线(弦)(弦),交交x轴于轴于x,其中,其中3.求求f(x)。若。若f(x)与与f(x1)符号相同,则根符号相同,则根必在必在(x,x2)区
25、间内,令区间内,令x1=x;反之,;反之,根必在根必在(x1,x)区间内,区间内,x2=x4.重复重复2和和3,直到,直到|f(x)|(为一个很为一个很小的数,如小的数,如10-6)为止,此止,此时有有f(x)0 x1f(x2)x2f(x1)f(x1)f(x2)x=函数的嵌套调用(续)函数的嵌套调用(续)第18页,共52页,编辑于2022年,星期一程序说明:程序说明:1.函数函数f 求求x3-5x2+16x 80 2.函数函数xpoint(x1,x2)求弦截点求弦截点x的坐标的坐标3.函数函数root(x1,x2)求区间求区间(x1,x2)上的根上的根输入输入x1,x2求求y1=f(x1),y
26、2=f(x2)直到直到y1,y2 异号异号求求f(x1)与与f(x2)连线与连线与x轴的交点轴的交点x计算计算y=f(x)y和和y1同号同号真真 假假x1=x x2=xy1=y y2=y直到直到|y|函数的嵌套调用(续)函数的嵌套调用(续)第19页,共52页,编辑于2022年,星期一#include#include float f(float x)return(x-5)*x+16)*x-80;float xpoint(float x1,float x2)return(x1*f(x2)-x2*f(x1)/f(x2)-f(x1);float root(float x1,float x2)int i
27、;float x,y y1;y1=f(x1);do x=xpoint(x1,x2);y=f(x);if(y*y10)y1=y;x1=x;else y2=y;x2=x;while(fabs(y)1e-6);return x;void main()float x,x1,x2,y1,y2;do printf(“Input x1,x2:”);scanf(“%f,%f”,&x1,&x2);y1=f(x1);y2=f(x2);while(y1*y20);x=root(x1,x2);printf(“a root is%fn”,x);函函数数的的嵌嵌套套调调用用第20页,共52页,编辑于2022年,星期一例例
28、8.7 编写求编写求 的程序的程序分析:分析:重复三次求阶乘运算重复三次求阶乘运算,只是,只是 每次的值不同每次的值不同 将求阶乘的过程编写成一个将求阶乘的过程编写成一个 函数函数fac,以不同的参数值,以不同的参数值k 来调用该函数来调用该函数 n!m!(n-m)!Cnm=fackk!#include#include float fac(int k)float t=1.;int I;for(i=2;i1)n!=1 (n=0)xxn-1 (n0)xn=程序执行过程:程序执行过程:f函数开始函数开始 调用调用f函数函数 f函数结束函数结束8.6 函数的递归调用函数的递归调用第22页,共52页,编
29、辑于2022年,星期一(2)间接递归调用)间接递归调用:int f1(int x)int f2(int t)int y,z;int a,c;.z=f2(y);c=f1(a);.程序执行过程:程序执行过程:f1函数开始函数开始 f2函数开始函数开始 调用调用f2函数函数 调用调用f1函数函数 f1函数结束函数结束 f2函数结束函数结束注意:注意:这两个递归都无法束,因这两个递归都无法束,因此应含有某条件控制递归此应含有某条件控制递归调用结束调用结束函数的递归调用(续)函数的递归调用(续)第23页,共52页,编辑于2022年,星期一例例8.7 5个人坐在一起,问第个人坐在一起,问第5个人多少岁?答
30、比第个人多少岁?答比第4个人大个人大2岁。第岁。第4个人说他比个人说他比第第3个人大个人大2岁,第岁,第3个人比第个人比第2个人大个人大2岁,第岁,第2个人比第个人比第1个人大个人大2岁,问第岁,问第1个人时回答是个人时回答是10岁。第岁。第5个人到底多大?个人到底多大?分析:分析:age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10用数学公式表示如下:用数学公式表示如下:用图表示求第用图表示求第5个人的年龄的过程:个人的年龄的过程:10 n=1age(n-1)+2 n1 age(n)=函数的递归调用
31、(续)函数的递归调用(续)第24页,共52页,编辑于2022年,星期一age(5)=age(4)+2age(3)=age(2)+2age(4)=age(3)+2age(2)=age(1)+2age(1)=10age(2)=12age(4)=16age(3)=14age(5)=18回推回推递推递推函数的递归调用(续)函数的递归调用(续)第25页,共52页,编辑于2022年,星期一age(5)输出输出age(5)c=age(4)+2c=age(3)+2c=age(2)+2c=age(1)+2c=10用图表示函数调用过程:用图表示函数调用过程:main n=5 n=4 n=3 n=2 n=1#inc
32、lude int age(int a)int c;if(n=1)c=10;else c=age(n-1)+2;return(c);void main()printf(“%dn”,age(5);递归结束条件函数的递归调用(续)函数的递归调用(续)第26页,共52页,编辑于2022年,星期一例例8.8 用递归法求用递归法求n!(n0)用循环做:用循环做:递归公式:递归公式:float fac(int n)float f=1;int i;if(n1)for(i=2;i1)n!=#include float fac(int n)float f;if(n1)f=fac(n-1)*n;else if(n=
33、0|n=1)f=1;else f=-1;return f;void main()int n;float y;printf(“Input an integer:”);scanf(“%d”,&n);y=fac(n);if(y0)printf(“Error%d0”,n);else printf(“%d!=%.0f”,n,y);函数的递归调用(续)函数的递归调用(续)第27页,共52页,编辑于2022年,星期一1.数组元素作函数实参数组元素作函数实参 与变量作实参一样,数组元素作与变量作实参一样,数组元素作 函数实参是函数实参是“值传递值传递”例例8.9:求:求10个任意数中的最大数个任意数中的最大数
34、#include int max(int x,int y)return(xy?x:y);void main()int a10,i,m;printf(“Input 10 integers:n”);for(i=0;i10;i+)scanf(“%d”,&ai);m=a0;for(i=1;i10;i+)m=max(m,ai);printf(“max is%d.n”,m);Input 10 integers:23 5 4 1 0 56 7 9 43 2max is 56.8.7 数组作为函数的参数数组作为函数的参数第28页,共52页,编辑于2022年,星期一2.一维数组与函数参数一维数组与函数参数 若函
35、数的形参是数组,对应的实参若函数的形参是数组,对应的实参 必须是数组名必须是数组名说明:说明:(1)实参数组和形参数组的类型必)实参数组和形参数组的类型必 须一致须一致(2)用数组名作参数时,传递的是)用数组名作参数时,传递的是 数组的首地址,因此形参数组数组的首地址,因此形参数组 也可以不指定大小。可以另设也可以不指定大小。可以另设 一形参,传递需处理的数组元一形参,传递需处理的数组元 素的个数素的个数#include int max(int x10)int i,m;m=x0;for(i=1;i10;i+)if(mxi)m=xi;return m;void main()int a10,i;p
36、rintf(“Input 10 integers:n”);for(i=0;i10;i+)scanf(“%d”,&ai);printf(“max is%d.n”,max(a);(int x,int n)max(a,10);数组作为函数的参数(续)数组作为函数的参数(续)第29页,共52页,编辑于2022年,星期一(3)数组作函数参数时,形参数组和实参数组共享同一内存单元)数组作函数参数时,形参数组和实参数组共享同一内存单元 如果形参数组的元素值被改变,实参数组的元素值也被改变如果形参数组的元素值被改变,实参数组的元素值也被改变 2 4 6 8 10 12 14 16 18 20 a0 a1 a2
37、 a3 a4 a5 a6 a7 a8 a9x0 x1 x2 x3 x4 x5 x6 x7 x8 x9起始地址起始地址 1000数组作为函数的参数(续)数组作为函数的参数(续)第30页,共52页,编辑于2022年,星期一例例8.10 用选择法排序用选择法排序 选择法排序基本思路:选择法排序基本思路:先从给出的先从给出的n个数中找到最小的数与个数中找到最小的数与a0交换;然后再从剩下的交换;然后再从剩下的n-1个数中找出最个数中找出最小的数与小的数与a1交换;交换;这样每比较一轮,找出未经排序的数中最小的一个。共需这样每比较一轮,找出未经排序的数中最小的一个。共需n-1轮比较。轮比较。选择法排序的
38、基本过程(选择法排序的基本过程(n=5为例):为例):a0 a1 a2 a3 a4 3 5 1 9 4 1 5 3 9 4 1 3 5 9 4 1 3 4 9 5 1 3 4 5 9初始情况初始情况将将5个数中最小的数个数中最小的数1与与a0交换交换将余下的将余下的4个数中最小的数个数中最小的数3与与a1交换交换将余下的将余下的3个数中最小的数个数中最小的数4与与a2交换交换将余下的将余下的2个数中最小的数个数中最小的数5与与a3交换交换数组作为函数的参数(续)数组作为函数的参数(续)第31页,共52页,编辑于2022年,星期一#include void sort(int x,int n)in
39、t i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jxj)k=j;t=ai;ai=ak;ak=t;void main()int a10,i;printf(“Input the array:”);for(i=0;i10;i+)scanf(“%d”,&ai);sort(a,10);printf(“the sorted array:n”);for(i=0;i10;i+)printf(“%5d”,ai);printf(“n”);数组作为函数的参数(续)数组作为函数的参数(续)第32页,共52页,编辑于2022年,星期一3.多维数组与函数参数多维数组与函数参数(1)多维数组
40、可以作为函数的参数)多维数组可以作为函数的参数(2)如果形参是多维数组,可以省)如果形参是多维数组,可以省 略第一维的大小,但不能省略略第一维的大小,但不能省略 其它维的大小其它维的大小(3)在第二维大小相同的前提下,形)在第二维大小相同的前提下,形 参数组的第一维可以与实参数组参数组的第一维可以与实参数组 不同不同判断以下形式哪些是正确的?判断以下形式哪些是正确的?int max(int x35)int max(int x5)int max(int x3)int max(int x)例例8.11 有一个有一个3 4的矩阵,的矩阵,求最大元素的值求最大元素的值#include int max(
41、x4)int i,j,m;m=x00;for(i=0;i3;i+)for(j=0;j4;j+)if(mxij)m=xij;return m;void main()int a34=1,3,5,7,2,4,6,8,15,13,17,5;printf(“max is%dn”,max(a);如:如:实参数组定义为实参数组定义为 int a510;而形参数组定义为而形参数组定义为 int b310;或或 int b810;均可以。均可以。数组作为函数的参数(续)数组作为函数的参数(续)第33页,共52页,编辑于2022年,星期一 实参实参 形参形参 传递方式传递方式常量、变量、表达式常量、变量、表达式
42、变量变量 传值(单向)传值(单向)数组元素数组元素 数组名数组名 数组数组 传数组首地址传数组首地址形参与实参的小结数组作为函数的参数(续)数组作为函数的参数(续)第34页,共52页,编辑于2022年,星期一1.局部变量局部变量 下列变量是局部变量下列变量是局部变量(1)在一个函数内部定义的变量)在一个函数内部定义的变量(2)函数的形式参数)函数的形式参数(3)在某个复合语句中定义的变量)在某个复合语句中定义的变量说明:说明:局部变量只在自己的范围内有效局部变量只在自己的范围内有效 如果局部变量的有效范围有重叠,如果局部变量的有效范围有重叠,则有效范围小的优先则有效范围小的优先float f1
43、(int n)int i,j;char f2(float x,float y)float z;void main()int a,b,c;i,j有效有效z有效有效a,b,c有效有效n有效有效x,y有效有效void main()int a,b,c;int d;d=a+b;d 有效有效void main()int a,b,c;int c;c=a+b;局部变量局部变量C有效有效8.8 局部变量与全局变量局部变量与全局变量第35页,共52页,编辑于2022年,星期一#include void main()int a,b,c=0;scanf(“%d%d”,&a,&b);int c;c=a+b;printf
44、(“%dn”,c);printf(“%dn”,c);2 350局部变量与全局变量(续)局部变量与全局变量(续)第36页,共52页,编辑于2022年,星期一2.全局变量全局变量(1)在函数之外定义的变量(外部)在函数之外定义的变量(外部 变量)是全局变量变量)是全局变量(2)全局变量的有效范围:)全局变量的有效范围:从定义从定义 变量的位置开始到源文件结束变量的位置开始到源文件结束(3)在一个函数中,既可以使用本)在一个函数中,既可以使用本 函数中定义的局部变量,也函数中定义的局部变量,也 可以使用有效的全局变量可以使用有效的全局变量int p=1,q=5;float f1(int a)int
45、b;int f2(int a)int b;void main()int m,n;全局变量全局变量p,q的有效范围的有效范围局部变量与全局变量(续)局部变量与全局变量(续)第37页,共52页,编辑于2022年,星期一说明:说明:(1)利用全局变量可以在函数间)利用全局变量可以在函数间 传递数据传递数据例例8.12 有有10个学生的学习成绩,个学生的学习成绩,求平均分,最高分,最低分求平均分,最高分,最低分分析:用一个函数返回分析:用一个函数返回3个数据,个数据,除了用函数值外,可以借助于全除了用函数值外,可以借助于全局变量局变量#include float max=0,min=0;float a
46、verage(float score,int n)int I;float sum=score0;max=min=score0;for(i=1;in;i+)sum=sum+scorei;if(maxscorei)min=scorei;return sum/n;void main()float avg,score10;int I;for(i=0;ib?a:b;return c;void main()int a=8;printf(“%dn”,max(a,b);局部变量与全局变量(续)局部变量与全局变量(续)第39页,共52页,编辑于2022年,星期一1.变量的动态存储和静态存储变量的动态存储和静态存
47、储 全局变量和局部变量:变量的作用域全局变量和局部变量:变量的作用域 静态存储变量和动态存储变量:变量的存储类别,即变量的生存期静态存储变量和动态存储变量:变量的存储类别,即变量的生存期内存中供用户使用的存储空间包括:内存中供用户使用的存储空间包括:程序区程序区 静态存储区:编译时分配空间静态存储区:编译时分配空间 动态存储区:执行时分配空间动态存储区:执行时分配空间 变量或函数的属性:变量或函数的属性:数据类型数据类型存储类别存储类别自动型自动型(auto)静态型静态型(static)寄存器型寄存器型(register)外部型外部型(extern)数据区数据区8.9 变量的存储类别变量的存储
48、类别第40页,共52页,编辑于2022年,星期一2.局部变量的存储类别局部变量的存储类别(1)自动变量:存储在动态存储区,用)自动变量:存储在动态存储区,用auto说明说明如:如:int func1(int a)auto int b,c=3;形参形参a,变量变量b、c都是自动变量。调用该函数时,系统自动给它们都是自动变量。调用该函数时,系统自动给它们分配存储空间,函数调用结束时自动释放存储空间。分配存储空间,函数调用结束时自动释放存储空间。通常将通常将auto省略。省略。(2)局部静态变量:占用静态存储区,用)局部静态变量:占用静态存储区,用static说明说明 变量的存储类别(续)变量的存储
49、类别(续)第41页,共52页,编辑于2022年,星期一说明:说明:局部静态变量属于静态存储类别。局部静态变量属于静态存储类别。在程序整个运行期间都不释放存储在程序整个运行期间都不释放存储空间空间 局部静态变量在编译时赋初值局部静态变量在编译时赋初值(仅赋一次值)(仅赋一次值)如果定义局部静态变量时没有赋如果定义局部静态变量时没有赋初值,编译时会自动赋初值初值,编译时会自动赋初值 局部静态变量只能在定义它的函局部静态变量只能在定义它的函数内被引用(它存在但不能被其它数内被引用(它存在但不能被其它函数使用)。函数使用)。例例8.13 输出输出15的阶乘的阶乘#include float fac(i
50、nt n)static float f=1;f=f*n;return f;void main()int j;for(j=1;jy?x:y;return(z);main()extern A,B;/*外部变量声明外部变量声明*/printf(%d,max(A,B);int A=13,B=-8;/*定义外部变量定义外部变量*/变量的存储类别(续)变量的存储类别(续)第44页,共52页,编辑于2022年,星期一如果两个文件中用同一个变量,不能在两个文件中同时定义,应该在一如果两个文件中用同一个变量,不能在两个文件中同时定义,应该在一个文件中定义,而在另一个文件中用个文件中定义,而在另一个文件中用ext