第7章 函数(第12,13,14,15次课)_第1页
第7章 函数(第12,13,14,15次课)_第2页
第7章 函数(第12,13,14,15次课)_第3页
第7章 函数(第12,13,14,15次课)_第4页
第7章 函数(第12,13,14,15次课)_第5页
已阅读5页,还剩109页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、,第 7 章 函数 FUNCTION,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.17.4 基本应用,7.57.7提高,7.87.11 相关知识,7.1 概述,7.1 概述,模块化程序设计思想:将一个大的程序按功能分解成一些小模块,使每一模块成为: 功能单一 结构清晰 接口简单 容易理解 的子程序。,C语言中的函数,f,#include #include

2、int main() void printstar(); /*声明函数printstar()*/ void print_message(); /*声明函数print_message()*/ printstar(); /*调用函数printstar()*/ print_message(); /*调用函数print_message()*/ printstar(); /*调用函数printstar()*/ return 0; void printstar() /*定义函数printstar()*/ char star=*,space= ; int i; for(i=0;istrlen(star);i

3、+) putchar(stari); putchar(space); printf(n); void print_message() /*定义函数print_message()*/ printf(How do you do!n); ,三要素:,【例7.1】函数调用的简单例子(P170),* * * * * * * * * * * * How do you do! * * * * * * * * * * * *,声明、,调用、,定义,/* 例1.3 求2个数中较大者。*/ #include void main( ) int max(int x,int y); /* 对被调用函数max的声明 */

4、 int a,b,c; scanf(%d,%d, ,to student利用1.3求3个数的最大值.C,说明:P171,(1) (2)一个源程序文件( .c )由一个或多个函数构成。 (3) c程序的执行从 函数开始;执行过程中调用其他函数,该函数执行结束后返回 函数;在 函数中结束整个程序的运行。一个程序中有且只有一个 函数 (4)所有函数的 是平行的,不能嵌套。 (5)从用户使用的角度看,函数分为: 函数和 函数 (6)从函数的形式看函数分两类: 函数。 函数。一般情况下,执行被调函数时会得到一个函数值,供主调函数使用。,main,main,main,main,定义,库,自定义,无参,有参

5、,7.2 函数定义的一般形式,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,(1)无参函数的一般形式 函数类型 函数名( ) /*函数头*/ 声明部分; /*包括变量的声明和函数的声明*/ 可执行语句部分; ,无参数,7.2 函数定义的一般形式,void printstar() /*定义函数printstar()*/ char star=*,space= ; i

6、nt i; for(i=0;istrlen(star);i+) putchar(stari); putchar(space); printf(n); ,(2)有参函数的一般形式 函数类型 函数名( 形式参数表列 ) /*函数头*/ 声明部分; 可执行语句部分; ,有形参,逗号间隔,int max(int x int y) /*定义一个求最大值的函数max*/ int z; /*声明部分*/ z=xy?x:y; return(z); ,形参要说明类型,(3)可以有“空函数” 类型说明符 函数名() ,【练习】,to student求实数的和和积.c,/*补充程序:写出求两个实数和、积的函数sum

7、和product*/,#include void main() /*函数声明*/ float a,b,s,p; printf(输入两个任意实数(逗号间隔):n); scanf(%f,%f, ,7.3 函数的调用,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.3.1 形式参数和实际参数,函数的参数分为 和 两种。 形参:个数和类型是根据 设定的。 实参:个数和

8、类型是根据 设定的。,7.3函数的调用,形参,实参,形参的个数和类型,发生函数调用时,主调函数把实参的值复制1份,传送给被调用函数的形参,从而实现主调函数向被调用函数的数据传送。,函数的功能,主调函数(实参),被调函数(形参),传值,#include int main() /*函数声明*/ int a,b,c; printf(input two numbers:n); scanf(%d,%d, ,int max(int x, int y);,max(a,b),实参a,b,形参x,y,【例7.2】有参函数的调用,#include void main() int max(int a, int b)

9、; int a,b,c; printf(input two numbers:n); scanf(%d,%d, ,input two numbers: 2,3,执行情况:,2,3,2,3,3,3,函数声明,函数调用,函数定义,max=3 _,x,y,说明:P177,(1)只有发生函数 时才给形参分配内存单元,并进行值的传递。执行完毕后形参占用的内存单元被 。,(2)实参向形参传递值单向传递。内存中,实参和形参占据(不同,相同)的内存单元,形参值的改变(能,不能)影响实参的值。,调用,释放,a,b,2,3,x,y,10,11,说明:P177,(3)实参可以是常量、变量或表达式。,(4) 函数定义时

10、必须指定形参的数据类型。,(5)实参与形参的类型应相同或兼容。,(6)通过return 语句将函数值带回到主调函数。,7.3.2 函数的返回值,从被调函数带回的值(P178),(1)函数返回值是通过函数中的 语句来获得的,从“被调函数”返回“主调函数”时,可以带回 个值。,return语句的一般格式:,return (返回值表达式);,return 返回值表达式;,或:,提示:,如:return (y); return (3+x);,如:return y; return 3+x;,return,1,(2)函数返回值的类型,int max(float x,float y) /*函数值为整型*/

11、char letter(char c1,char c2) /*函数值为字符型*/ double min(int x,int y) /*函数值为浮点型*/,(3)函数返回值的类型应与函数中return语句中“返回值表达式”的类型 。 如果不一致,则以 为准。,一致,函数类型,int max(int a, int b) int c; c=ab?a:b; return(c); ,int max(int a, int b) float c; c=ab?a:b; return(c); ,P178(3),对于不带回值的函数,其类型应当定义为 类型。,P179(4),void,(即空类型),此时,被调函数体

12、内不允许出现 语句。,return,函数调用的一般形式为(P174),函数名(实参表列),函数名(),或者:,hcf(u,v),切记:实参的个数、类型和顺序,应该与被调用函数所要求的 个数、类型和顺序一致,才能正确地进行数据传递。,形参,7.3 函数的调用,printstar( ),int hcf(int u,int v) ,7.3.3 函数调用的形式,(1)函数调用语句。C语言中的函数可以只进行某些操作而不返回函数值,这时的函数调用可作为一条独立的语句。 例如: printstar(); print_message(); (2)函数表达式。被调函数出现在表达式(或语句)中,作为表达式(或语句

13、)的一项,以函数返回值参与表达式(或语句)的运算。这种方式要求函数是有返回值的。 例如: c= max(a,b); (3)函数参数。函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的。 例如:printf(最大公约数为:%dn, hcf(u,v);,在语言中,可以用以下几种方式调用函数(P175):,无分号,包含多个函数的C程序,其三个要素 为: 、 、 。,函数声明,函数调用,函数定义,其中:,把函数名、函数类型以及形参的类型、个数和顺序通知编译系统,编译系统据此对实参进行检查。,是函数功能的确立,包括函数类型、函数名、形参的类型

14、、个数和顺序等,它是一个完整的、独立的函数单位。,函数定义,函数声明,简单回顾,由于函数声明的形式与函数头一致,因此,函数声明也称为 。,函数原型,7.4 对被调函数的声明和函数原型,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.4 对被调用函数的声明和函数原型,在一个函数调用另一个函数(即被调函数)需要具备如下条件:p179,(1)首先被调用的函数必须是已

15、经定义好的函数(是库函数或用户自己定义的函数)。但仅这一条还不够。,(2)如果使用库函数,应该在本文件开头用#include指令将调用有关库函数时所需用到得信息包含到本文件中。,(3)如果使用用户自己定义的函数,而该函数的位置在调用它的函数(主调函数)之后,则应该在主调函数中对被调函数作声明。,【例7.4】输入两个实数,求其和。,#include int main() float add(float a, float b); float a,b,c; printf(input two numbers:n); scanf(%f,%f, ,函数声明,定义时,不能省略变量名,7.4 对被调用函数的声

16、明和函数原型,函数原型的形式(2种):,函数类型 函数名(形参类型1 形参名1,形参类型2 形参名2,形参类型n 形参名n),int max(int a, int b);,函数类型 函数名(形参类型1 ,形参类型2 ,形参类型n),int max(int , int );,如果函数定义写在调用函数之前,可省略声明 如果已在源文件(.c程序)的开头(所有函数之前),对本文件中所调用的函数进行了声明,则在各函数中不必对这些函数再进行声明,可以直接调用。,友情提示:,P182,void ascending(int a10) /函数定义 int i,j,t; for(i=0;iaj+1) t=aj;

17、aj=aj+1; aj+1=t; printf(the sorted numbers:n); for(i=0;i10;i+) printf(%d ,ai); ,void main() int x10,i; void ascending(int a10) ; /函数声明 printf(input 10 numbers:n); for(i=0;i10;i+) scanf(%d, /调用函数实现数组排序 ,#include ,/函数声明符合省略条件,#include float sum1(int); float sum2(int); float sum3(int); void main() int

18、n1=100,n2=50,n3=10; float s1,s2,s3; s1=sum1(n1); s2=sum2(n2); s3=sum3(n3); printf(sum=%8.2fn,s1+s2+s3); ,float sum1(int n) /*定义求和函数,n=n1*/ float k,s=0; for(k=1;k=n;k+) s=s+k; return(s); ,float sum2(int n) /*定义求平方和函数,n=n2 */ float k,s=0; for(k=1;k=n;k+) s=s+k*k; return(s); ,float sum3(int n) /*定义求倒数和

19、函数,n=n3 */ float k,s=0; for(k=1;k=n;k+) s=s+1/k; return(s); ,如果已在文件的开头(所有函数之前),对本文件中所调用的函数进行了声明,则在各函数中不必对这些函数再进行声明,可以直接调用,#include float sum1(int); float sum2(int); float sum3(int); void main() int n1=100,n2=50,n3=10; float s1,s2,s3; s1=sum1(n1); s2=sum2(n2); s3=sum3(n3); printf(sum=%8.2fn,s1+s2+s3)

20、; ,float sum1(int n) /*定义求和函数,n=n1*/ float k,s=0; for(k=1;k=n;k+) s=s+k; return(s); ,float sum2(int n) /*定义求平方和函数,n=n2 */ float k,s=0; for(k=1;k=n;k+) s=s+k*k; return(s); ,float sum3(int n) /*定义求倒数和函数,n=n3 */ float k,s=0; for(k=1;k=n;k+) s=s+1/k; return(s); ,作业,/函数实现: /判定一个任意整数是否为“素数”。,/函数实现:参考P135例

21、5.9 /判定一个任意整数是否为“素数”。 #include #include void main() int x,flag; int prime(int); printf(输入一个任意的整数:); scanf(%d, ,/方法1: int prime(int x) int i; for(i=2;isqrt(x) return 1; else return 0; ,/方法2: int prime(int x) int i,f=1; for(i=2;i=sqrt(x);i+) if(x%i=0) f=0; break; return f; ,7.1 概述 7.2 函数定义的一般形式 7.3 函数

22、的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.5 函数的嵌套调用,7.5 函数的嵌套调用,基本点:函数的定义是 ,函数的调用可以 。,平行的,嵌套,函数的嵌套调用是指,在执行被调用函数时,被调用函数又调用了其它函数。,P182,例7.5 输入个数,找出其中最大的数。,#include int main() int max4(int,int,int,int); int a,b,c,d,max; scanf(%d%

23、d%d%d, ,int max4(int a,int b,int c,int d) int max2(int a,int b); int m; m=max2(a,b); m=max2(m,c); m=max2(m,d); return m; ,int max2(int x,int y) int r; r=xy?x:y; return r; ,执行流程:,main( ),调用函数max4,输出结束,max4函数,max2函数,调用函数max2,调用函数max2 调用函数max2,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调

24、用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.6 函数的递归调用,函数的递归调用是指,一个函数在它的函数体内,直接或间接地调用它自身。,7.6 函数的递归调用,什么是递归调用:,如果函数funA在执行过程又调用函数funA自己,则称函数funA为直接递归。 如果函数funA在执行过程中先调用函数funB,函数funB在执行过程中又调用函数funA,则称函数funA为间接递归。,P184,例 7.6 有5个人站在一起,问第5个人多少岁?他说比第4人大2岁。问第4个人多少岁?他

25、说比第3人大2岁。问第3个人多少岁?他说比第2人大2岁。问第2个人多少岁?他说比第1个人大2岁,最后问第1个人多少岁?他说是10岁。请问第5个人多大?,10岁,第i个人的岁数:,10+2*(i-1),递推,递归,例 7.6 有5个人站在一起,问第5个人多少岁?他说比第4人大2岁。问第4个人多少岁?他说比第3人大2岁。问第3个人多少岁?他说比第2人大2岁。问第2个人多少岁?他说比第1人大2岁。问第1个人多少岁?他说是10岁。请问第5个人多大?,10岁,age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10

26、,age(n) /*求第n个人年龄*/,递归算法,10 (n=1) age(n-1)+2 (n1),age(n)=,int age(int n) int c; if(n=1) c=10; else c=age(n-1)+2; return c; ,#include void main( ) printf(%dn,age(5); ,/*递归结束条件递归出口*/,/*递归表达式*/,写递归算法的两个要素,age(5),c=age(4)+2,return c,age(5)=18,age函数 n=5,c=age(2)+2,return c,age(3)=14,age函数 n=3,c=age(1)+2,

27、return c,age(2)=12,age函数 n=2,c=10,age(1)=10,return c,age函数 n=1,main函数,递归函数age的执行过程:,输出age(5),int age(int n) int c; if(n=1) c=10; else c=age(n-1)+2; return c; ,#include void main( ) printf(%dn,age(5); ,递推,age函数 n=4,c=age(3)+2,return c,age(3)=16,例7.7 用递归法计算n!。,fac(n-1)*n,fac(n)=,(n1),(n=1),1,/*递归结束条件递

28、归出口*/,/*递归表达式*/,float fac(int n) float f; if(n=1) f=1; else f=fac(n-1)*n; return(f); ,#include int main( ) float fac(int n); int n; float y; printf(input an integer: ); scanf(%d, ,例7.7 用递归法计算n!。,fac(n-1)*n,fac(n)=,(n1),(n=1),1,/*递归结束条件递归出口*/,/*递归表达式*/,float fac(int n) if(n=1) return 1; else return f

29、ac(n-1)*n; ,#include int main( ) float fac(int n); int n; float y; printf(input an integer: ); scanf(%d, ,n1,printf(),递归的 优点:使程序设计简洁 缺点:占用的较多的内存空间,n=4 fac()函数,n=3 fac()函数,n=2 fac()函数,n=1 fac()函数,递归函数fac的执行过程:,古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这64个盘子从A座移动到座上,但规定每次只允许移动一个盘子,且在移

30、动过程中在3个座上都始终保持大盘在下,小盘在上。,例7.8 汉诺塔(Hanoi)问题。用递归解题的典型例子。,古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这64个盘子从A座移动到座上,但规定每次只允许移动一个盘子,且在移动过程中在3个座上都始终保持大盘在下,小盘在上。,例7.8 汉诺塔(Hanoi)问题。用递归解题的典型例子。,例7.8 汉诺塔(Hanoi)问题。用递归解题的典型例子。,古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个老和尚想把这64个盘子从A座移动

31、到座上,但规定每次只允许移动一个盘子,且在移动过程中在3个座上都始终保持大盘在下,小盘在上。,将n个盘子从a柱(源柱)借助b柱(工作柱)移到c柱(目标柱)。,算法分析: 如果 n=1,ac 否则: 将n-1个盘子从a柱(源柱)借助c柱(目标柱)移到b柱(工作柱); ac; 将n-1个盘子从b柱(工作柱) 借助a柱(源柱)移到c柱(目标柱),将n个盘子从a柱(源柱)借助b柱(工作柱)移到c柱(目标柱)。,算法分析: 如果 n=1,ac 否则: 将n-1个盘子从a柱(源柱)借助c柱(目标柱)移到b柱(工作柱); ac; 将n-1个盘子从b柱(工作柱) 借助a柱(源柱)移到c柱(目标柱),void

32、hanoi(int n,char a,char b,char c) /函数头,if (n= =1) move(a,c); /*一个盘子直接移*/ / 这是递归结束条件,else hanoi(n-1, a,c,b); / n-1个盘子a c b,move (a,c) ; / ac,hanoi(n-1,b,a, c); / n-1个盘子b a c ,void move (char x,char y) printf (“%c-%cn”,x,y) ; ,主函数调用 H(3,a,b,c),(3,a,b,c) H(2,a,c,b) M(a,c) H(2,b,a,c),n=1:m(,) n1: Hanoi(

33、n-1,) Move(,) Hanoi(n-1,),(2,a,c,b) H(1,a,b,c) M(a,b) H(1,c,a,b),(2,b,a,c) H(1,b,c,a) M(b,c) H(1,a,b,c),(1,a,b,c) M(a,c),1,(1,c,a,b) M(c,b),(1,b,c,a) M(b,a),(1,a,b,c) M(a,c),2,3,4,5,6,7,ac ab cb ac ba bc ac,取n=3,#include int main() void hanoi(int n,char one,char two,char three); int m; printf(input

34、the number of diskes: ); scanf(%d, ,void move(char x,char y) printf(“%c-%cn”,x,y); ,移动次数,2n-1,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.7 数组作为函数参数,如果函数调用时,不想将整个数组传递,只想传递数组中的某个元素怎么办呢?,7.7.1 数组元素作为函数实参

35、,(1)数组元素可以作函数实参,但不能做形参,其用法与 相同,是单向的 传递方式,从实参到形参。,(2)用数组元素作实参时,形参必须是 。,即:形参值改变 影响数组元素的值。,普通变量,普通变量,不会,值,P193,举例:把某个数组元素作为函数的实参使用,例7.9 输入10个数,要求输出其中值最大的元素和该数是第几个数?,#include /*例7.9*/ int main() int max(int ,int ); int a10,m,n,i; printf(enter array a:n); for(i=0;im) n=i+1; m=ai; printf(“the largest numb

36、er is %dnit is the %dth number.n”,m,n); return 0; ,int max(int x,int y) return (xy?x:y); ,原则上:,数组元素在单个使用时,与普通变量法则相同,无法体现数组特色; 数组只有在整体使用时,才有它自己的特色。,7.7.2 数组名作为函数参数,特别强调 :用数组名作为函数实参,其本质不是把数组元素的值从一个数组(实参数组)传递给另一个数组(形参数组)的过程,而是通过 把实参数组的 传送给形参数组名; 这样,两个数组共同占用一段 。,首地址,内存空间,P195,实参数组名,因此,形参数组和实参数组都可以修改数组元素

37、的值。,P194,float average(float array10) /定义average函数 int i; float aver,sum=array0; for(i=1;i=9;i+) sum=sum+arrayi; aver=sum/10; return aver; ,int main() float average(float array10); float score10,aver; int i; printf(input 10 scores:n); for(i=0;i10;i+) scanf(%f, ,#include ,aver=average(score);,C语言中,可以

38、用数组名实现数组的整体传值,例7.10 有一个一维数组score,内放10个学生成绩,求平均成绩。,用数组名做函数参数,应在主调函数和被调函数中分别定义数组,而不能只在一方定义。 实参数组与形参数组的类型应一致。 用数组名向形参传递 。 内存中,实参数组和形参数组占据(不同,相同)的内存单元,形参数组值的改变(能,不能)影响实参数组元素的值。,数组首地址,程序分析:,友情提示:,P195,实际上,指定形参数组的大小是不起任何作用的即,无意义,形参数组可以不指定大小,在定义数组时在数组名后面跟一个方括号。 方括号 不能省 !,void invert(int xN),void invert(int

39、 x ),形参数组的大小由 决定。,实参数组,有时为了在被调用函数中处理数组元素的需要,可以另设一个形参,传递需要处理的数组元素。,P195,void main( ) float score15=98.5,97.91,97,60,55; float score210=67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5; printf(“the average of class a is %6.2fn”,average(score1,5); printf(“the average of class b is %6.2fn”,average(score2,10);

40、return 0;,/例7.11有两个班级,分别有5名和10名学生,调用 /一个average函数,分别求这两个班的学生的平均成绩。 #include ,/例7.11有两个班级,分别有5名和10名学生,调用 /一个average函数,分别求这两个班的学生的平均成绩。 #include float average(float array,int n) int i; float aver,sum=array0; for(i=1;in;i+) sum=sum+arrayi; /求数组和 aver=sum/n; return aver; ,void main( ) float score15=98.5

41、,97.91,97,60,55; float score210=67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5; printf(“the average of class a is %6.2fn”,average(score1,5); printf(“the average of class b is %6.2fn”,average(score2,10); return 0;,#include /用选择法对数组中的10个整数排序 void ascending(int a,int n) /将已知数组a升序排序 int i,j,k,t; for(i=0;in-1

42、;i+) k=i; for(j=i+1;jn;j+) if(ajak) k=j; t=ai; ai=ak; ak=t; ,int main() int x10,i; printf(input 10 numbers:n); for(i=0;i10;i+) scanf(%d, ,被调函数ascending()中数组a的改变也改变了主调函数main()中的数组x,数组名是数组首地址,#include void ascending(int a10) /a数组元素被排序 ,void main() /定义并输入x数组值 ascending(x); /排序 /输出x数组值 ,main()函数,执行过程,开辟

43、实参数组x空间,x,3 7 6 5 9 2 11 8 20 4,调用函数ascending(),a,定义形参数组a,x0 x1 x2 x9,#include void ascending(int a10) /a数组元素被排序 ,void main() /定义并输入x数组值 ascending(x); /排序 /输出x数组值 ,main()函数,执行过程,开辟实参数组x空间,3 7 6 5 9 2 11 8 20 4,调用函数ascending(),a,定义形参数组a,a0 a1 a2 a9,#include void ascending(int a10) /a数组元素被排序 ,void mai

44、n() /定义并输入x数组值 ascending(x); /排序 /输出x数组值 ,main()函数,执行过程,开辟实参数组x空间,2 3 4 5 6 7 8 9 11 20,调用函数ascending(),a,定义形参数组a,a0 a1 a2 a9,返回主调函数main(),#include void ascending(int a10) /a数组元素被排序 ,void main() /定义并输入x数组值 ascending(x); /排序 /输出x数组值 ,main()函数,执行过程,开辟实参数组x空间,2 3 4 5 6 7 8 9 11 20,x,x0 x1 x2 x9,由于主调函数向

45、被调函数传送 ,导致形参数组使用了实参数组的 ,使得形参数组值的改变影响了实参数组。,数组首地址,结论:,内存空间,整体传送 整体返回,首地址,7.7.3 多维数组名作为函数参数,可以用多维数组名作为函数实参和形参,在被调函数中对形参数组定义时可以指定每一维的大小,也可以省略第一维的大小说明。,P197,例如:int array310,int array10,#include /有一个3*4的矩阵,求所有元素中的最大值。 int max_value(int array4) int i,j,max; max=array00 for(i=0;i3;i+) for(j=0;j4;j+) if(max

46、arrayij) max=arrayij; return max; ,int main() int i,j,m; int x34=1,3,5,7,2,4,6,8,15,17,34,12; m=max_value(x); /调用函数求最大值 printf(“%d”,m); return 0; ,7.1 概述 7.2 函数定义的一般形式 7.3 函数的调用 7.4 对被调函数的声明和函数原型 7.5 函数的嵌套调用 7.6 函数的递归调用 7.7 数组作为函数参数 7.8 局部变量和全局变量 7.9 变量的存储类别 7.10 变量的声明和定义 7.11 内部函数和外部函数,7.8 局部变量和全局变

47、量,7.8 局部变量与全局变量,在一个函数中定义的变量,在其他函数中能否被引用?在不同位置定义的变量,在什么范围内有效?,7.8 局部变量与全局变量,语言中所有的变量都有自己的作用域。变量说明的位置不同,其作用域也不同,据此将语言中的变量分为局部变量和全局变量。,7.8.1 局部变量,即:在一个函数内部说明的变量,它只在该函数范围内有效。P199,#include int f1(int a) /*函数f1定义*/ int b,c; f2(b,c); /*调用函数f2*/ int f2(int x,int y) /*函数f2定义*/ int i,j; void main() /*main函数*/

48、 int a,b,c,x,y; int c; c=a+b; m=f1(c); /*调用函数f1*/ ,举例:不同的班级相同的学生姓名,但是两个不同的人。,#include int f1(int a) /*函数f1定义*/ int b,c; f2(b,c); /*调用函数f2*/ int f2(int x,int y) /*函数f2定义*/ int i,j; void main() /*main函数*/ int a,b,c,x,y; int c; c=a+b; m=f1(c); /*调用函数f1*/ ,main( ),执行流程,f1( ),f2( ),请说明各变量的作用域,#include in

49、t f1(int a) /*函数f1定义*/ int b,c; f2(b,c); /*调用函数f2*/ int f2(int x,int y) /*函数f2定义*/ int i,j; void main() /*main函数*/ int a,b,c,x,y; int c; c=a+b; m=f1(c); /*调用函数f1*/ ,main( ),执行流程,f1( ),f2( ),P200(1),主函数中定义的变量只在主函数中有效。,#include int f1(int a) /*函数f1定义*/ int b,c; f2(b,c); /*调用函数f2*/ int f2(int x,int y)

50、/*函数f2定义*/ int i,j; void main() /*main函数*/ int a,b,c,x,y; int c; c=a+b; m=f1(c); /*调用函数f1*/ ,main( ),执行流程,f1( ),f2( ),P200(2),不同函数中可以使用同名的变量。,#include int f1(int a) /*函数f1定义*/ int b,c; f2(b,c); /*调用函数f2*/ int f2(int x,int y) /*函数f2定义*/ int i,j; void main() /*main函数*/ int a,b,c,x,y; int c; c=a+b; m=f

51、1(c); /*调用函数f1*/ ,main( ),执行流程,f1( ),f2( ),P200(3),形式参数也是局部变量。,#include int f1(int a) /*函数f1定义*/ int b,c; f2(b,c); /*调用函数f2*/ int f2(int x,int y) /*函数f2定义*/ int i,j; void main() /*main函数*/ int a,b,c,x,y; int c; c=a+b; m=f1(c); /*调用函数f1*/ ,main( ),执行流程,f1( ),f2( ),P200(4),在一个函数内部,可以在复合语句中定义变量,该变量只在本复

52、合语句中有效。,7.8.2 全局变量(外部变量),即:在函数外部定义的变量。P200,#include int p=1,q=5; float f1(int a) int b,c; char c1,c2; char f2(int x,int y) int i,j; int main() int m,n; return 0; ,外部变量(即,全局变量)不属于任何一个函数,“全局变量”的作用域是: 从 位置开始, 到 为止。,全局变量的定义,本源文件结束,(P200),#include int p=1,q=5; float f1(int a) int b,c; char c1,c2; char f2

53、(int x,int y) int i,j; int main() int m,n; return 0; ,p,q的作用域:,c1,c2的作用域:,f1(),f2(),main(),f2(),main(),#include int p=1,q=5; float f1(int a) int b,c; char c1,c2; char f2(int x,int y) int i,j; int main() int m,n; return 0; ,应用全局变量的好处:,增加了函数间数据联系的渠道。P201,由于return语句只能带回 个返回值,因此有时可以利用全局变量增加函数间的联系渠道,通过函数

54、调用能得到1个以上的值。,1,为了区别全局变量和局部变量,在程序设计人员有个习惯,将全局变量名的第1个字母用大写表示。,#include float Max=0,Min=0; /全局变量 float average(float array,int n) int i; float aver,sum=array0; Max=Min=array0; for(i=1;iMax) Max=arrayi; else if(arrayiMin) Min=arrayi; sum=sum+arrayi; aver=sum/n; return aver; ,int main() float ave,score10

55、; int i; for(i=0; i10; i+) scanf(%f, ,例7.14 有一个数组,存放10个学生成绩,求平均分,最高分和最低分。,与课本例题的区别p201,建议不在必要时不要使用全局变量,原因如下:,(1)全局变量在程序的全部执行过程中都占用存储单元。 (2)降低了程序的可靠性和通用性。移动某一个函数的同时要同时移动外部变量。 (3)使用全局变量过多,会降低程序的清晰性,程序容易出错。,#include int p=1,q=5; int f1(int a) int b,c; int f2(int x,int y) int i,j; int c1,c2,c; void main

56、() int m,n,a,b,p; int c; c=a+b; m=f1(c); ,在作用域内,全局变量和局部变量有重名现象。 若重名,则: 变量将被屏蔽而不起作用,全局,(P203),#include int a=3,b=5; /全局变量 int main() int max(int a,int b); int a=8; printf(“max=%dn”,max(a,b); return 0; ,int max(int a,int b) int c; c=ab?a:b; return c; ,例7.15 如果外部变量与局部变量同名,分析结果。,/函数声明,a,b是形参,/a是局部变量,/局部

57、变量a的作用范围 /全局变量b的作用范围,/a,b是局部变量,形参a,b的作用范围,结果,max=8,习题1:以下程序的输出结果是( ) #include void main() int i=1,j=3; printf(%2d,i+); int i=0; i+=j*2; printf(%2d%2d,i,j); printf(%2d%2d,i,j); ,A) 1 6 3 1 3 B) 1 6 3 2 3 C) 1 6 3 6 3 D) 1 7 3 2 3,B,本题考查的知识点是同名局部变量的作用域。程序中的第一个和第三个printf语句输出外层的变量i和j; 第二个printf语句输出内层的i和j,因为内层没有定义j,所以内层仍然沿用外层的j。,习题2:以下程序的输出结果是( ) #include int m=13; int fun(int x,int y) int m=3; return(x*y-m); void main() int a=7,b=5; printf(%d,fun(a,b)/m); ,A)1 B)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论