第五章 函数及预处理

上传人:豆浆 文档编号:6401614 上传时间:2017-08-08 格式:PPT 页数:108 大小:473KB
返回 下载 相关 举报
第五章 函数及预处理_第1页
第1页 / 共108页
第五章 函数及预处理_第2页
第2页 / 共108页
第五章 函数及预处理_第3页
第3页 / 共108页
第五章 函数及预处理_第4页
第4页 / 共108页
第五章 函数及预处理_第5页
第5页 / 共108页
点击查看更多>>
资源描述

《第五章 函数及预处理》由会员分享,可在线阅读,更多相关《第五章 函数及预处理(108页珍藏版)》请在金锄头文库上搜索。

1、第五章 函数、预处理,函数预处理总结,(一)函数,内容,函数定义的一般形式函数参数和函数的值函数的调用函数的嵌套调用函数的递归调用数组作为函数参数局部变量和全局变量变量的存储类型内部函数和外部函数,概述,一个较大的程序一般应分为若干个程序模块,每一个模块用来实现一个特定的功能。用子程序实现模块的功能。在语言中,子程序的作用是由函数完成的。一个程序可由一个主函数和若干个函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。如下图所示:简单的函数调用见源码7-1.c,(1.1)函数定义的一般形式,函数分类,函数从定义形式来看,可以分为三类:1)无参数函

2、数。2)有参数函数。3)空函数。,无参数函数定义的一般形式,类型标识符函数名()变量声明部分函数实现部分类型标识符定义函数的返回值类型,若函数不需要返回值,则定义为void。,有参数函数定义的一般形式,类型标识符 函数名(形式参数表列)局部变量声明部分 函数实现部分例如:int max(int x,int y)int ; z xy?xy;return ;,空函数,类型说明符 函数名()/ 空函数体例如:void dummy()/ 空函数体,空函数的作用,在程序设计中往往根据需要确定若干模块, 分别由一些函数来实现。 而在第一阶段只设计最基本的模块, 其他一些次要功能或锦上添花的功能则在以后需要

3、时陆续补上。在编写程序的开始阶段,可以在将来准备扩充功能的地方写上一个空函数。这样做,程序的结构清楚,可读性好,以后扩充新功能方便,对程序结构影响不大。空函数在程序设计中常常是有用的。,(1.2)函数参数和函数的值,形式参数和实际参数(1/3),在调用函数时,大多数情况下,主调函数和被调用函数之间有数据传递关系。在定义函数时函数名后面括弧中的变量名称为“形式参数”(简称“形参”),在主调函数中调用一个函数时,函数名后面括弧中的参数(可以是一个表达式)称为“实际参数”(简称“实参”)。,形式参数和实际参数(2/3),例7.2 调用函数时的数据传递。#include int max(int x,

4、int y);/ 前向声明int main()int a;int b;int c;scanf(“d,d”, a, b); c = max(a,b);/ a、b是实参 printf(“max isd”, c);return 1;,形式参数和实际参数(3/3),int max(int x, int y)/ x、y是形参int ; z xy?xy; return ;,对形参和实参的说明(1/4),1)在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。如上例:只有在发生函数调用时,函数max中的形参才被分配内存单元。在调用结束后,形参所占的内存单元也被释放。2)实参可以是常量、变

5、量或表达式,如:max(3, ab);但要求它们有确定的值。在调用时将实参的值赋给形参。3)在被定义的函数中,必须指定形参的类型。,对形参和实参的说明(2/4),4)实参与形参的类型应相同或赋值兼容。相同则直接赋值,如果只是兼容,则要进行类型转换。如:在例7.2中,如果实参值a为3.5,而形参x为整型,则需将实数3.5转换成整数3,然后送到形参x中。,对形参和实参的说明(3/4),5)语言规定,实参变量对形参变量的数据传递都是“值传递”,即单向传递,只由实参传给形参,而不能由形参传回来给实参。在内存中,实参单元与形参单元是不同的单元。如图所示。因此,在执行一个被调用函数时,形参的值如果发生改变

6、,并不会改变主调函数的实参的值。,对形参和实参的说明(4/4),例:交换两个数的值(下面的程序不能达到目的)。int main()int a = 10;int b = 20;swap(a, b);return 1;void swap(int a, int b)int t;t = a;a = b;b = t;,函数的返回值(1/3),通常,希望通过函数调用使主调函数能得到一个确定的值,这就是函数的返回值。下面对函数值作一些说明:1)函数的返回值是通过函数中的return语句获得的。 return语句将被调用函数中的一个确定值带回主调函数中去。如果需要从被调用函数带回一个函数值(供主调函数使用),

7、被调用函数中必须包含return语句。如果不需要从被调用函数带回函数值可以不要return语句。一个函数中可以有一个以上的return语句,执行到哪一个return语句,哪一个语句起作用。,函数的返回值(2/3),2)返回值的类型。既然函数有返回值,这个值当然应属于某一个确定的类型,应当在定义函数时指定函数值的类型。例如:int max(float x, float y) char letter(char c1, char c2)double min(int x, int y),函数的返回值(3/3),3)如果函数返回值的类型和return语句中表达式的值不一致,则以函数返回值类型为准。如果不

8、一致,则要进行类型转换。例7.3 返回值类型与函数类型不同。程序代码见源码7-3.c4)对于不带返回值的函数,应当用“void”定义函数的返回值(即函数的返回值为“空类型”)。,(1.4)函数的调用,函数调用的一般形式,函数调用的一般形式为:函数名(实参表列);如果是调用无参函数,则“实参表列”可以没有,但括弧不能省略。实参与形参的个数应相等,类型应一致。实参与形参按顺序对应,一一传递数据。但应说明,如果实参表列包括多个实参,对实参求值的顺序并不是确定的,有的系统按自左至右顺序求实参的值,有的系统则按自右至左顺序。例 7.4 实参求值的顺序(代码见源码8-4.c),函数调用的方式(1/2),有

9、如下三种方式:1)函数语句把函数调用作为一个语句;如例8.1中:printstar();这时不要求函数带返回值,只要求函数完成一定的操作。2)函数表达式函数出现在一个表达式中,这种表达式称为函数表达式。例如:c = 2*max(a, b)这时要求函数带一个确定的返回值以参加表达式的运算。,函数调用的方式(2/2),3)函数参数函数调用作为一个函数的实参。例如:m = max(a, max(b, c);函数调用作为函数的参数,实质上也是函数表达式形式调用的一种,因为函数的参数本来就要求是表达式形式。,对被调用函数的声明,在一个函数中调用另一函数(即被调用函数)需要具备哪些条件呢?1)在函数调用点

10、,需知道被调用函数的原型,不然编译将通不过。例如:我们前面在使用printf和scanf函数时,需保含头文件stdio.h,因为在该头文件中,就声明了这两个函数的原型。又如在例8.4中,我们使用前向声明函数f。2)被调用的函数必须是已经存在的函数(是库函数或用户自己定义的函数)。声明函数,只能保证在编译的时候不出错,如果在链接时找不到函数定义,会报找不到函数定义错误。,函数的一般用法,函数的一般用法是先声明后定义。并且在函数的调用点上,必须能看到函数的声明或者定义。所谓函数声明,是写出原型,不写函数体。如:int max(int x, int y);/ 函数声明int max(int x, i

11、ny)/ 函数定义return x y ? x : y;void myfunc()/ 函数定义/ 函数体为空,函数的嵌套调用,语言的函数定义都是互相平行、独立的,也就是说在定义函数时,一个函数内不能包含另一个函数。语言不能嵌套定义函数,但可以嵌套调用函数,也就是说,在调用一个函数的过程中,又调用另一个函数。如图所示:,函数的递归调用,在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。C语言的特点之一就在于允许函数的递归调用。,函数递归调用示例(例8.7),例6.7 有5个人坐在一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第3个

12、人,又说比第2个人大2岁。问第2个人,说比第1个人大2岁。最后问第1个人,他说是10岁。请问第5个人多大。分析:显然,这是一个递归问题:age(5)age(4)2age(4)age(3)2age(3)age(2)2age(2)age(1)2age(1)10可以用式子表述如下:age(n) =10(n=1)age(n) = age(n-1)+2(n1),#include int age(int n);/ 前向声明int main()printf(“%dn”, age(5);int age(int n)int c;if (n = 1)c = 10;elsec = age(n-1) + 2;retu

13、rn c;,(1.5)数组作为函数参数,数组作为函数参数,前面已经介绍了可以用变量作函数参数,此外,数组元素也可以作函数实参,其用法与变量相同。数组名也可以作实参和形参,传递的是数组首元素的地址。,数组元素作函数实参,例7.10 有两个数组a、b,各有10个元素,将它们对应地逐个相比(即a0与b0比,a1与b1比)。如果a数组中的元素大于b数组中的相应元素的数目,多于b数组中元素大于a数组中相应元素的数目(例如,aibi6次,biai3次,其中i每次为不同的值),则认为a数组大于b数组,并分别统计出两个数组相应元素大于、等于、小于的次数。程序代码见源码8-10.c,数组名作函数参数(1/2),

14、可以用数组名作函数参数,此时实参与形参都应用数组名(或用指针变量,见第10章)。例7.11有一个一维数组score,内放10个学生成绩,求平均成绩。程序代码见7-11.c例7.12 形参数组不定义长度。程序代码见7-12.c,数组名作函数参数(2/2),例7.13 用选择法对数组中10个整数按由小到大排序。所谓选择法就是先将10个数中最小的数与a0对换;再将a1到a9中最小的数与a1对换每比较一轮,找出一个未经排序的数中最小的一个。共比较9轮。程序代码见7-13.c,数组名作参数说明(1/2),1)用数组名作函数参数,应该在主调函数和被调用函数分别定义数组,例中array是形参数组名,scor

15、e是实参数组名,分别在其所在函数中定义,不能只在一方定义。2)实参数组与形参数组类型应一致,如不一致,结果将出错。3)在被调用函数中声明了形参数组的大小没有任何作用,因为编译对形参数组大小不做检查,只是将实参数组的首地址传给形参数组。因此,例11和12中的scoren和arrayn指的是同一单元。4)形参数组也可以不指定大小,在定义数组时在数组名后面跟一个空的方括号,为了在被调用函数中处理数组元素的需要,可以另设一个参数,传递数组元素的个数。如例7.12。,数组名作参数说明(2/2),5)用数组名作函数实参时,不是把数组的值传递给形参,而是把实参数组的起始地址传递给形参数组,这样两个数组就共占同一段内存单元。参见例13。,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号