收藏 分享(赏)

第八章_函数two.ppt

上传人:j35w19 文档编号:8229555 上传时间:2019-06-15 格式:PPT 页数:64 大小:350.50KB
下载 相关 举报
第八章_函数two.ppt_第1页
第1页 / 共64页
第八章_函数two.ppt_第2页
第2页 / 共64页
第八章_函数two.ppt_第3页
第3页 / 共64页
第八章_函数two.ppt_第4页
第4页 / 共64页
第八章_函数two.ppt_第5页
第5页 / 共64页
点击查看更多>>
资源描述

1、,第八章,函数(2),本章要点,函数的概念 函数的定义与调用 函数的递归调用 变量的作用域 函数的作用域,主要内容,8.1 概述 8.函数定义的一般形式8.函数参数和函数的值8. 函数的调用 8. 函数的嵌套调用8.函数的递归调用 8.数组作为函数参数8.8 局部变量和全局变量8.变量的存储类别 8.10 内部函数和外部函数,8.6 函数的递归调用,在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。语言的特点之一就在于允许函数的递归调用。 例如:int f ( int ) ,;();return(*);,例 8.7: 有个人坐在一起,问第个人多少岁?他说比第个人大岁。

2、问第个人岁数,他说比第个人大岁。问第个人,又说比第个人大岁。问第个人,说比第个人大岁。最后问第个人,他说是岁。请问第个人多大。,age(5)= age (4)+2 age(4)= age (3)+2 age(3)= age (2)+2 age(2)= age (1)+2 age(1)= 10 用数学公式表述如下: age(n)= 10 () age(n-1)+2 (),可以用一个函数来描述上述递归过程:int age(int ) *求年龄的递归函数* int ; * 用作存放函数的返回值的变量 *if() ;else ();return(); ,运行结果如下: ,用一个主函数调用age函数,求

3、得第5人的年龄。 #include void main() printf(,age();,例8.用递归方法求!,求!也可以用递归方法,即!等于!,而!。 可用下面的递归公式表示:! (,)()! (),例8.9 Hanoi(汉诺塔)问题:,将个盘子从座移到座可以分解为以下3个步骤:1.将上个盘借助座先移到座上。2.把座上剩下的一个盘移到座上。3.将个盘从座借助于座移到座上。,程序如下: #include void main() void hanoi(int n,char one,char two,char three); /* 对hanoi函数的声明 */int m;printf(“input

4、 the number of diskes:“);scanf(“%d”,void hanoi(int n,char one,char two,char three) /* 定义hanoi函数,将个盘从one座借助two座,移到three座 */void move(char x,char y); /* 对move函数的声明 */if(n=1) move(one,three);else hanoi(n-1,one,three,two);move(one,three);hanoi(n-1,two,one,three); void move(char x,char y) /* 定义move函数 */p

5、rintf(“%c%cn“,x,y);,运行情况如下: input the number of diskes:3The steps to moving 3 diskes:,8.数组作为函数参数,8.7.1 数组元素作函数实参,由于实参可以是表达式,而数组元素可以是表达式的组成部分,因此数组元素可以作为函数的实参,与用变量作实参一样,是单向传递,即“值传送”方式。,例 8.10 有两个数组和,各有个元素,将它们对应地逐个相比(即与比,与比)。如果数组中的元素大于数组中的相应元素的数目多于b数组中元素大于a数组中相应元素的数目(例如,aibi6次,biai3次,其中i每次为不同的值),则认为a数组

6、大于b数组,并分别统计出两个数组相应元素大于、等于、小于的次数。,#include void main() int large(int x,int y); /* 函数声明 */int 10,10,,;printf(enter array a);for(;)scanf(,);printf();printf( enter array);for(;)scanf (,);printf();for(;) if(large (i,i )= ) ;else if( large (i,i )=) =+;else ;,printf(“aibi %d timesnai=bi %d timesnaik) print

7、f(“array a is larger than array bn“);else if (nk) printf(“array a is smaller than array bn“);else printf(“array a is equal to array bn“); large(int ,int ) int ;if();else if()flag;else flag;return(flag); ,运行情况如下:enter array a: enter array b: 5 3 8 9 1 3 5 6 0 4 array a is smaller than array b,8.7.2 数

8、组名作函数参数,用数组名作函数参数时,此时形参应当用数组名或用指针变量 。,例8.11 有一个一维数组score,内放10个学生成绩,求平均成绩。,#include void main() float average(float array10); /* 函数声明 */float score10 , aver;int ;printf(input scores:);for(; )scanf(,score);printf();averaverage( score );printf ( average score is .n, aver); ,float average (float array10

9、) int ;float aver,;for (;);return(aver); ,运行情况如下: input 10 scores:100 56 78 98.5 76 87 99 67.5 75 97 average score is 83.40,例 8.形参数组不定义长度 #include void main() float average(float array,int n)float score_15 98.5,97, 91.5,60,55;float score_210= 67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5;printf(“the ave

10、rage of class A is %6.2fn”,average(score_1,5);printf(“the average of class B is %6.2fn”,average(score_2,10);,float average(float array ,int n) int ;float aver,;for(; )sumsumarray;aversum;return(); ,运行结果如下: the average of class A is 80.40 The average of class is 78.20,例 8.13 用选择法对数组中10个整数按由小到大排序。,所谓选

11、择法就是先将10个数中最小的数与a0对换;再将a1到a9中最小的数与a1对换每比较一轮,找出一个未经排序的数中最小的一个。共比较9轮。,未排序时的情况: a0 a1 a2 a3 a43 6 1 9 4 将5个数中最小的数1与a0对换: 1 6 3 9 4 将余下的4个数中最小的数3与a1对换 1 3 6 9 4 将余下的3个数中最小的数4与a2对换 1 3 4 9 6 将余下的2个数中最小的数6与a3对换1 3 4 6 9,程序: #include void main() void sort(int ,int );int ,;printf(enter the array);for(; )sca

12、nf(,);sort(,);printf(the sorted array);for(; ) printf(,);printf();,void sort(int array,int )/*排序函数*/ int ,;for(;) ;/*k 记录最小值的下标*/for(;)if(array array )=;t=arrayk;arrayk=arrayi;arrayi=t;,8.7.3. 多维数组名作函数参数,程序: #include void main() max_value ( int 4);int a34=1,3,5,7,2,4,6,8,15,17,34,12;printf(max value

13、 is ,max_value(a) );,用多维数组名作为函数实参和形参。在被调函数中对形参数组定义时可以指定每一维的大小,也可以省略第一维的大小说明 。,max_value ( int array 4) int ,max;max=;for(=;)for(; )if(array)max= array ;return(max); ,运行结果如下: Max value is 34,8.8局部变量和全局变量,8.8.1局部变量,内部变量:在一个函数内部定义的变量称内部变量。它只在本函数范围内有效,即:只有在本函数内才能使用这些变量,故称为“局部变量” 。,例: float f1( int a) /*

14、函数f1 */ int b,c; /* a、b、c有效*/ char f2(int x,int y) /*函数f2 */ int i,j; /* x、y、i、j有效*/ void main( ) /*主函数*/ int m,n; /* m、n有效*/ ,主函数中定义的变量只在主函数中有效,而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。 (2) 不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。 (3) 形式参数也是局部变量。 (4) 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为“分程序”或“程序

15、块”。,void main ( ) int a,b; int c;c=a+b; c在此范围内有效 a,b在此范围内有效 ,8.8.2 全局变量,外部变量:函数之外定义的变量称为外部变量。外部变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。所以也称全局变量。,int p=1,q=5; /* 外部变量 */ float f1(int a) /* 定义函数f1 */ int b,c; char c1,c2; /* 外部变量*/ char f2 (int x, int y) /* 定义函数f2 */ int i,j; void main ( ) /*主函数*/ in

16、t m,n; ,全局变量p,q的作用范围,全局变量c1,c2的作用范围,例8.15 有一个一维数组,内放个学生成绩 ,写一个函数,求出平均分、最高分和最低分。 #include float Max,Min; *全局变量* void main() float average(float array ,int n);float ave,score10;int ;for(;)scanf(,);ave= average(,);printf(“max=%6.2fn min=%6.2fnaverage=%6.2fn”,Max,Min,ave);,float average(float array ,int

17、 n) * 定义函数,形参为数组 */ int ;float aver,sum=array;Max=Min=array;for(=;) if(arrayMax)Maxarray;else if(arrayMin)Min array;sum=sum+array;aver;return(); ,运行情况如下: 99 45 78 97 100 67.5 89 92 66 43 ,建议:不必要时不要使用全局变量,原因如下:, 全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。 使用全局变量过多,会降低程序的清晰性。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限

18、制使用全局变量。,降低函数的通用性。因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件的变量同名时,就会出现问题,降低了程序的可靠性和通用性。一般要求把程序中的函数做成一个封闭体,除了可以通过“实参形参”的渠道与外界发生联系外,没有其他渠道。,例 8.6 外部变量与局部变量同名 #include int a=3,b=5; /* a,b为外部变量*/ a,b作用范围 void main ( ) int a=8; /*a为局部变量 */ 局部变量a作用范围printf (%d, max (a,b); 全局变量b的

19、作用范围 max (int a, int b) /*a,b为局部变量 */ int c;c=ab?ab; 形参a、b作用范围return (c); ,运行结果为 8,8. 变量的存储类别,8.9.1 动态存储方式与静态存储方式,从变量的作用域(即从空间)角度来分,可以分为全局变量和局部变量。 从变量值存在的时间角度来分,又可以分为静态存储方式和动态存储方式。,静态存储方式:指在程序运行期间由系统分配固定的存储空间的方式。 动态存储方式:则是在程序运行期间根据需要进行动态的分配存储空间的方式。 存储空间可以分为三部分:1.程序区 2.静态存储区 3.动态存储区,变量和函数有两个属性:数据类型和数

20、据的存储类别。存储类别指的是数据在内存中存储的方式。 存储方式分为两大类:静态存储类和动态存储类。包含: 自动的(auto); 静态的(static); 寄存器的(register); 外部的(extern)。根据变量的存储类别,可以知道变量的作用域和生存期。,8.9.2 auto变量,自动变量auto:不专门声明为static存储类别的局部变量都是动态分配存储空间,在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。因此这类局部变量称为自动变量。 函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量),都属此类。 自动变量用关键字auto作存储类别的声明。

21、,例如: int (int ) *定义f函数,为形参 * auto int ,;/*定义、为自动变量 * ,8.9.3 用static声明局部变量,当函数中的局部变量的值在函数调用结束后不消失而保留原值时,该变量称为静态局部变量。用关键字static进行声明。,例87 考察静态局部变量的值 #include void main() int f(int);int ,;for(; )printf( ,(); int f(int ) auto int ;static ;return();,运行结果为 7 8 9,对静态局部变量的说明: (1) 静态局部变量属于静态存储类别,在静态存储区内分配存储单元

22、。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占动态存储区空间而不占静态存储区空间,函数调用结束后即释放。 (2)对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。,(3)如在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值。(4)虽然静态局部变量在函数调用结束后仍然存在,但其他函数不能引用它。,例8.8 输出到的阶乘值 #include void main() i

23、nt fac(int );int ;for(;)printf(%!=,fac(); int fac(int ) static int ;*;return();,8.9.4 register变量,变量的值是存放在内存中的。当程序中用到哪一个变量的值时,由控制器发出指令将内存中该变量的值送到运算器中。 经过运算器进行运算,如果需要存数,再从运算器将数据送到内存存放。,如果有一些变量使用频繁,则为存取变量的值要花费不少时间。为提高执行效率,语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。由于对寄存器的存取速度远高于对内存的存取速度,因此这样做可以

24、提高执行效率。这种变量叫做寄存器变量,用关键字register作声明。,例819使用寄存器变量 #include void main ( ) long fac(long);long i,n;scanf(“%ld“, ,8.9.5 用extern声明外部变量,外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。用extern来声明外部变量,以扩展外部变量的作用城。,1. 在一个文件内声明外部变量,例820 用extern声明外部变量,扩展它在程序文件中的作用域 #includ

25、e void main() int max(int,int); *外部变量声明*extern A,B; printf(“%dn“,max(A,B); int A=13,B=-8; *定义外部变量*int max(int x,int y) *定义函数 * int z;z=xy?x:y;return(z);,2. 在多文件的程序中声明外部变量,#include int A; /*定义外部变量*/ void main() int (int); /*函数声明*/int ,;printf(enter the number a and its power m:n);scanf(,A,);A*;printf

26、(*,A,);();printf(*n,A,);,例8.21 用extern将外部变量的作用域扩展到其他文件。本程序的作用是给定的值,输入和,求和am的值。文件file.中的内容为:,文件file中的内容为: extern A; /*声明A为一个已定义的外部变量*/int power(int ); int ,;for(;)*A;return();,8.9.6 用static声明外部变量,在程序设计中,某些外部变量只限于被本文件引用,而不能被其他文件引用。这时可以在定义外部变量时加一个staitic声明。 例如: file1.c file2.c static int A; extern int

27、A; void main ( ) void fun (int n) A=A*n; ,8.9.7 关于变量的声明和定义,定义性声明:需要建立存储空间的(如:int a; )声明。 引用性声明:不需建立存储空间的声明(extern a;)。 注意:声明包括定义,但并非所有的声明都是定义。对“int a;” 而言,它既是声明,又是定义。而对“extern a;” 而言,它是声明而不是定义。,8.10 内部函数和外部函数,根据函数能否被其他源文件调用,将函数区分为内部函数和外部函数。,8.10.1内部函数,如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型的

28、前面加static。即 static 类型标识符 函数名(形参表) 例如: static int fun ( int a , int b ),8.10.2 外部函数,(1) 定义函数时,如果在函数首部的最左端加关键字extern,则表示此函数是外部函数,可供其他文件调用。例如,函数首部可以写为extern int fun (int a, int b),这样,函数fun就可以为其他文件调用。如果在定义函数时省略extern,则隐含为外部函数。,(2) 在需要调用此函数的文件中,用extern对函数作声明,表示该函数是在其他文件中定义的外部函数 。,例 8.22 有一个若干字符的字符串,今输入一个

29、字符,要求程序将字符串中该字符删去。用外部函数实现。 File.c(文件) #include void main() extern void enter_string(char str); extern void delete_string(char str,char ch);extern void print_string(char str);*以上3行声明在本函数中将要调用的在其他文件中定义的3个函数*char c;char str80;enter_string(str);scanf(“%c“, ,file(文件)#include void enter_string(char str80)

30、 * 定义外部函数enter-string* gets(str); *向字符数组输入字符串* file(文件) void delete_string(char str,char ch) *定义外部函数delete_string * int i,j;for(i=j=0;stri!=0;i+)if(stri!=ch)strj+=stri;strj=0; ,file(文件) #include void print_string(char str) printf(“%sn“,str); ,运行情况如下: (输入) (输入要删去的字符) (输出已删去指定字符的字符串),作业:,1、练习书上例题 2、自行练习P2038.17 3、ppt后面练习题(不交),1、以下程序运行后的输出结果是_。 #include void fun() static int a;a+=2;printf(“%d”,a); main() int cc;for(cc=1;cc=4;cc+) fun();printf(“n”); ,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报