C语言程序设计 第5章函数.pptx

上传人:小****库 文档编号:2917545 上传时间:2020-05-22 格式:PPTX 页数:97 大小:1.22MB
返回 下载 相关 举报
C语言程序设计 第5章函数.pptx_第1页
第1页 / 共97页
C语言程序设计 第5章函数.pptx_第2页
第2页 / 共97页
点击查看更多>>
资源描述

《C语言程序设计 第5章函数.pptx》由会员分享,可在线阅读,更多相关《C语言程序设计 第5章函数.pptx(97页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、第5章函数,C语言程序设计,5.1库函数与自定义函数,1.库函数C语言提供了丰富的库函数,包括常用的输入/输出函数、数学函数等。如C程序中经常出现的输入/输出函数:scanf()、printf()等。用户无需定义,只要提供必要的说明即可使用。若使用这些输入/输出函数,则必须在程序开头加上说明“#includestdio.h”或“#include”,其中,“stdio.h”称为标准输入输出头文件。include说明必须以“#”开头,系统提供的头文件以“.h”作为文件的后缀。如数学函数对应的头文件是“math.h”。include说明不是C语句,因此,不能在末尾加分号。,库函数调用的一般形式如下:

2、函数名(参数表)C语言中库函数的调用有两种方式:(1)在表达式中调用。如“x=pow(3,2);”是在赋值表达式中调用pow()函数来求x的值。(2)作为独立的语句完成某种操作。如“printf(Howareyou);”就是原样输出字符串信息。,5.1库函数与自定义函数,5.1库函数与自定义函数,2.自定义函数用户根据自己的需要编写的函数称为用户自定义函数。一个C语言的源程序是由一个主函数和用户自定义函数加上必要的说明组成的,从而实现程序的模块化。(1)函数定义的一般形式函数定义的一般形式如下:,注意:“类型说明符”指的是函数的类型,即该函数返回值的数据类型。这些数据类型可以是int,long

3、,char,float,double等。当类型为int时,int可以省略;当函数不需要返回值时,可用void来表示它的类型。“函数名”是标识符,可由用户指定。参数表部分可有可无,当有多个参数时,参数之间用逗号隔开。例如:,5.1库函数与自定义函数,该函数没有参数,但括号不能省略,每次调用函数get()时,得到一个整型值。例如:intpow(intx,inty)该函数有两个参数,参数之间用逗号隔开。,5.1库函数与自定义函数,函数中由最外一层“”括起的部分为函数体,包括变量说明和语句,其中变量说明可有可无,语句也可有可无。在没有特别说明时,函数体内定义的变量均为局部变量,它们只在函数执行时有定义

4、。因此,不同函数中的局部变量可以同名。另外,形参变量也是局部变量。局部变量只在函数被调用时才被临时分配内存单元,当退出函数时,这些临时开辟的存储单元全部被释放掉。局部变量只在函数体内部起作用,与其他函数体的内部变量无关。不允许在一个函数内部再定义另一个函数。,5.1库函数与自定义函数,(2)函数参数形参:在定义函数时,函数名后面括号中的变量名称为形式参数。实参:在调用函数时,函数名后面括号中的表达式称为实际参数。定义函数时,形参必须指定类型,实参与形参的类型、顺序及个数应该一致。其中实参可以是常量、变量或表达式,但变量和表达式要有确定的值。例如:当a=1,b=2时,则“c=pow(5,6);”

5、“c=pow(a,b);”和“c=max(a+b,a*b);”这三种调用均正确。C语言中,参数的传递是“值传递”,即单向传递。数据只能由实参传给形参,而不能由形参传回给实参,即调用结束后实参仍为原值。,5.1库函数与自定义函数,(3)函数的返回值函数的返回值是通过返回语句return实现的,返回语句的形式为“return;”或“return(表达式);”。前者函数返回值是不确定的,此时调用者对返回值不感兴趣,后者函数表示终止当前函数的执行,返回到它的调用函数继续执行,并带回return后表达式的值。return后的圆括号可省略。return0或return(0):在main()函数中,用于说明

6、程序的退出状态,即返回给操作系统。若为0表示正常退出。return(1)或return1:返回值为1,表示异常退出。如果return0或return1在其他函数里,则将返回值返回给调用函数。,5.1库函数与自定义函数,(4)函数调用的一般形式函数语句调用的一般形式如下:函数名(实参表列);例如:sum(a,a+b);函数表达式调用的一般形式如下:变量名=函数表达式;例如:c=max(a+b,a*b);,5.1库函数与自定义函数,【例5.1.1】用函数max()求两个表达式值的最大者。,5.1库函数与自定义函数,【分析】该程序中定义了max(intx,inty)函数,它有两个形参x和y,在主函数

7、中的语句“c=max(a+10,b);”中a+10和b是实参。函数与函数通过调用和参数传递发生联系。定义的max()函数出现在主函数调用之前,即先定义后调用。,5.1库函数与自定义函数,1.函数声明在C语言中对用户定义的函数应遵循“先定义后使用”的原则。若把函数定义在调用之后,应该在调用之前对函数进行说明。函数说明的一般形式如下:类型名函数名(参数类型1,参数类型2,);或类型名函数名(参数类型1参数名1,参数类型2参数名2,);,5.2函数的声明与递归调用,【例5.2.1】用函数max()求两个表达式值的最大者。,5.2函数的声明与递归调用,程序运行结果(键盘输入15,20):Maxis25

8、【分析】该程序是max()函数在主函数main()之后,在主函数调用max()函数时未进行声明。如果在函数调用前未进行函数声明,则有的编译器会出现警告错误,此时与编译器有关。,5.2函数的声明与递归调用,5.2函数的声明与递归调用,【分析】该程序中max()函数在调用函数之后,需要在函数调用前进行声明,本程序在main()函数外部进行声明,声明中给出了函数名、返回值类型、参数列表等与该函数有关的信息,以告知编译器与该函数有关的信息,让编译器知道函数的存在及存在的形式,即使函数暂时没有定义,也不会出错。如“intmax(intx,inty);”为声明函数,其后有分号,而“intmax(intx,

9、inty)”为定义函数不能有分号。所谓声明,就是告诉编译器我要使用这个函数,编译器没有找到该函数的定义不要紧,请不要报错,稍后我会把定义补上。函数声明的格式相当于去掉函数定义中的函数体再加上分号即可。当在函数的外部声明时,在声明语句的后面所有位置上都可以对该函数进行调用。,5.2函数的声明与递归调用,5.2函数的声明与递归调用,【分析】该程序中max()函数在调用函数之后,需要在函数调用前进行声明,本程序在main()函数内部进行声明,则只能在main()函数内部才能识别该函数。函数定义通常出现在函数调用之前,或者在函数调用前进行函数声明,程序执行时,总是从main()函数开始执行,当遇到函数

10、调用时,转去执行被调用函数,被调用函数执行完之后返回到它的调用函数继续执行,最终在main()函数结束。,5.2函数的声明与递归调用,【例5.2.2】用主函数调用自定义函数计算n的阶乘。,5.2函数的声明与递归调用,程序运行结果:su=120【分析】程序中intrfact(intx)是自定义函数,有一个形参x,在main()函数内部已声明该函数,调用时用实参n代替形参x。而dummy()是空函数,调用时什么也没做,但可以说明在此处能够调用一个其他函数,需要功能扩充时,可在此处进行添加。,5.2函数的声明与递归调用,2.函数的递归调用一个函数在它的函数体内直接或间接地调用它自身称为递归调用。递归

11、调用分为直接递归调用和间接递归调用。直接递归调用的形式如下:,5.2函数的声明与递归调用,间接递归调用的形式如下:,5.2函数的声明与递归调用,递归方法可使程序简洁、紧凑,可读性好,但占用存储空间大,运行速度慢。一个问题要采用递归方法来解决时,必须符合以下三个条件:(1)可以把需要求解的问题转化为一个新的问题,而这个新问题的解决方法仍与原来的解法相同,只是所处理的对象有规律地递增或递减。(2)可以应用这个转化过程使问题得以解决。(3)必定要有一个明确的结束递归的条件。,5.2函数的声明与递归调用,【例5.2.3】用递归的方法求n!。,5.2函数的声明与递归调用,【例5.2.4】计算f(x)=x

12、n。,5.2函数的声明与递归调用,相当于,5.2函数的声明与递归调用,1.变量的作用范围变量的说明是对一个变量的性质(例如变量的类型)加以说明,但并不分配存储空间,而变量的定义是对变量说明其性质并为其分配存储空间。变量按作用范围分为四种类型(也称为存储类):局部变量(又称为自动变量auto)、全局变量(又称为外部变量extern)、静态变量(static)和寄存器变量(register)。,5.3变量的作用范围与初始化,(1)局部变量局部变量又称为内部变量,在函数或复合语句内部以关键字auto说明,通常可以省略。它的作用域仅限于函数内,离开该函数后再使用这种变量是非法的。它们在函数被调用或执行

13、时,分配空间才自动产生,但不会初始化。函数返回时,在调用函数中它们又自动消失,其值只局限于被调用的函数。从一次调用到下一次调用之间,自动变量不保持值(即上一次调用时自动变量的值不会带到下一次调用中)。故在不同的函数(甚至在同一函数)中,可以定义同名的变量而互不影响。形式参数也是局部变量。例如:,5.3变量的作用范围与初始化,5.3变量的作用范围与初始化,在函数f1()内定义了三个变量,a为形参,b,c为一般变量。在函数f1()的范围内a,b,c有效,或者说a,b,c变量的作用域限于函数f1()内。同理,x,y,z的作用域限于函数f2()内。m,n的作用域限于函数main()内。关于局部变量的作

14、用域还要说明:主函数中定义的变量也只能在主函数中使用,不能在其他函数中使用。同时,主函数中不能使用其他函数中定义的变量。因为主函数也是一个函数,它与其他函数是平行关系。形参变量是属于该函数的局部变量。,5.3变量的作用范围与初始化,允许在不同的函数中使用相同的变量名,代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。如形参和实参的变量名都为n,是完全允许的。在复合语句中也可以定义变量,其作用域只在复合语句范围内。例如:,5.3变量的作用范围与初始化,本程序在main()函数中定义了i、j、k三个变量,“k=i+j”的值为5。而在复合语句内又定义了一个变量k,并赋初值为8。应该注意这两个

15、k不是同一个变量。在复合语句外由main()函数定义的k起作用,而在复合语句内则由在复合语句内定义的k起作用。因此,第一个输出的k值,应该输出8,因为该行在复合语句内,由复合语句内定义的k起作用;第二个输出的k值,应该输出5,因为该输出语句在复合语句外,这个k由main()函数定义的k起作用。,5.3变量的作用范围与初始化,(2)全局变量全局变量在函数外定义,未赋初值,编译时自动赋0,其作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其作用范围只限于定义处到文件的末尾。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对变量进行声明,就可

16、以从声明处起合法地使用该外部变量。如果在某个函数中要引用另一个文件中的全局变量,也需在该函数中对此全局变量加以extern关键字说明。全局变量在一次调用到下一次调用之间保持以前的值。例如:,5.3变量的作用范围与初始化,5.3变量的作用范围与初始化,从上例可以看出a、b、x、y都是在函数外部定义的外部变量,都是全局变量。但x、y定义在函数f1()之后,而在函数f1()内又没有对x、y的说明,所以它们在函数f1()内无效。a、b定义在源程序最前面,因此在函数f1()、f2()及main()内不加说明也可使用。,5.3变量的作用范围与初始化,【例5.3.1】输入长方体的长、宽、高l、w和h,求其体

17、积及三个面l*w、l*h和w*h的面积。,5.3变量的作用范围与初始化,【例5.3.2】用extern声明外部变量,扩展全局变量的作用域。,5.3变量的作用范围与初始化,【分析】在本程序文件的最后定义了外部变量A和B,但由于外部变量定义的位置在main()函数之后,因此本来在main()函数中不能引用外部变量A和B,但在main()函数中用extern对A和B进行“外部变量声明”,就可以从“声明”处起,合法地使用该外部变量A和B。,5.3变量的作用范围与初始化,【例5.3.3】全局变量与局部变量同名。,5.3变量的作用范围与初始化,程序运行结果:8注意:如果在同一个源文件中,全局变量与局部变量

18、同名,若在局部变量的作用范围内,局部变量起作用,外部变量则被屏蔽不起作用。,5.3变量的作用范围与初始化,【例5.3.4】对于多个文件,用extern声明外部变量。,5.3变量的作用范围与初始化,注意:如果程序由多个文件组成,对一个全局变量只能有一个定义,其他文件中可包含对它冠以关键字extern的说明以便进行存取。,5.3变量的作用范围与初始化,(3)静态变量静态变量以关键字static说明,可以是内部(局部)的,也可以是外部(全局)的。内部静态变量如同自动变量一样,局部于定义它的函数,出了这个函数,其他函数不能访问它,但它的值始终存在,即在一次调用到下一次调用之间保留原有的值。外部静态变量

19、在定义它的整个文件中是可以访问的,而外部变量是在整个程序的所有文件中起作用的。,5.3变量的作用范围与初始化,【例5.3.5】静态局部变量的值。,5.3变量的作用范围与初始化,程序运行结果:789【分析】自动变量在函数每次被调用时进行初始化,而静态变量只在编译阶段初始化一次,若未赋初值,则被初始化为0。本例中自动变量b每次调用时均进行初始化,即b的值为0,而静态变量c初始化时的值为3,执行“c=c+1;”后c的值为4,下次调用时不再初始化,此时c的值为4,执行“c=c+1;”后c的值为5,以此类推。,5.3变量的作用范围与初始化,(4)寄存器变量寄存器变量以关键字register说明,只适用于

20、局部的自动变量和函数的形参,对于局部静态变量就不能说明为寄存器变量。寄存器变量的值放在CPU的寄存器中,可以使程序执行速度加快,变量的数量不宜过多。,5.3变量的作用范围与初始化,【例5.3.6】使用寄存器变量。,5.3变量的作用范围与初始化,2.变量的初始化自动变量和寄存器变量在函数每次被调用时进行初始化,若未赋初值,则其值不确定;而外部变量和静态变量只在编译阶段初始化一次,若未赋初值,则被初始化为0。,5.3变量的作用范围与初始化,C语言的预处理主要包括宏定义、文件包含和条件编译三类。1.宏定义(1)不带参数的宏定义不带参数的宏定义格式如下:#define标识符字符串它的功能是用字符串替换

21、程序中所有出现的标识符,通常用来定义符号常量,标识符也称为宏名。例如:#definePI3.14在定义它的文件中,将用3.14替代程序中所有的PI。,5.4编译预处理,注意:宏名一般用大写字母表示,以区分变量名,也可用小写字母。宏定义不是语句,不必在行末加分号,如果加分号则当作字符串的一部分。宏定义必须写在函数之外,宏名的有效范围为定义命令之后到文件的结束,如要终止其作用域可使用“#undef命令”。例如:,5.4编译预处理,表示PI只在main()函数中有效,在函数f1()中无效。,5.4编译预处理,程序中若有单引号或双引号括起来的与宏名相同的字符串,则不进行替换。例如:,5.4编译预处理,

22、表示此时“OK”作为字符串处理,原样输出,不进行替换。若是“printf(OK,OK);”,则输出结果如下:OK100,(2)带参数的宏定义带参数的宏定义格式一般如下:#define宏名(参数表)字符串例如:#defineMAX(a,b)ab?a:b若在程序中有“c=MAX(9,13);”,则9代替参数a,13代替参数b。宏替换是在函数编译前就已处理,只占编译时间不占运行时间,而函数调用是运行时起作用,占运行时间(分配单元、保留现场、值传递、返回)。,5.4编译预处理,注意:宏名和形参之间不能有空格。如“#defineMAX(a,b)ab?a:b”表示将空格以后的字符都作为替代字符串,即MAX

23、用“(a,b)ab?a:b”来代替。形参不分配内存单元,不必做类型定义。如“defineMAX(a,b)ab?a:b”的形参a、b未进行类型说明。若“#defineSQ(y)y*y”,则“SQ(2+1)”表示“2+1*2+1”,只是进行替换。若“#defineSQ(y)(y)*(y)”,则“SQ(2+1)”表示“(2+1)*(2+1)”。,5.4编译预处理,对于函数的调用,例如:,5.4编译预处理,函数的调用存在值传递,先计算表达式的值2+1=3,再调用函数,则返回值为3*3=9。,2.文件包含文件包含是指一个源程序文件将另一个指定文件的全部内容包含进来,即将另一个文件包含到本文件之中。文件包

24、含预处理语句的一般形式如下:#include或#include包含文件源程序在编译之前,预编译程序将用指定文件中的内容来替换此命令行。对于“#include包含文件”,系统先在当前源程序所在的目录内查找指定的包含文件,如果找不到,再按照系统指定的标准方式到有关目录中去寻找。而对于“#include”,系统将直接按照指定的标准方式到有关目录中去寻找。,5.4编译预处理,一个“#include命令”只能指定一个包含文件,若要包含多个文件,则要用多个“#include命令”。,5.4编译预处理,3.条件编译预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文

25、件。这对于程序的移植和调试是很有用的。条件编译有三种形式:第一种:#ifdef标识符程序段1#else程序段2#endif,5.4编译预处理,它的功能是如果标识符已被“#define命令”定义过,则对程序段1进行编译,否则对程序段2进行编译。第二种:#ifndef标识符程序段1#else程序段2#endif它的功能是如果标识符未被“#define命令”定义过,则对程序段1进行编译,否则对程序段2进行编译。,5.4编译预处理,第三种:#if表达式程序段1#else程序段2#endif它的功能是如果表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。,5.4编译预处理,4.预处理

26、实例【例5.4.1】定义一个带参数的宏,使两个参数的值交互,并在程序中交换两个值。,5.4编译预处理,【例5.4.2】三角形的面积a、b、c分别为三角形的三条边长,定义两个宏,一个用来求s,另一个用来求area,并在主函数中调用它。,5.4编译预处理,【分析】调用时,AREA(3,4,5)与AREA(3,2+2,5)是不同的,要使其值相同,则需定义为:,5.4编译预处理,5.5函数程序实例,【例5.5.1】用两个自定义函数分别求出两个整数a和b的最大公约数和最小公倍数。,5.5函数程序实例,5.5函数程序实例,5.5函数程序实例,5.5函数程序实例,【例5.5.2】在主函数中调用某函数,判断一

27、个整数是否为素数。,5.5函数程序实例,5.5函数程序实例,【例5.5.3】输入一个整数s,从低位开始取出s中奇数位上的数字作为高位,依次构成一个新数输出。如输入“54321”,则输出“135”。,5.5函数程序实例,5.5函数程序实例,【例5.5.4】输入一个整数,从个位开始取出奇数位上所对应的数字,然后逆序排列。如输入“12345”,则输出“135”。,5.5函数程序实例,5.5函数程序实例,5.5函数程序实例,5.5函数程序实例,【例5.5.5】输入一个整数,将各个数位上能被3整除的数字,组成一个新数。如输入“652394”,则输出“639”。,5.5函数程序实例,5.5函数程序实例,【

28、例5.5.6】输入一个整数,将各个数位上能被3整除的数字,逆序排列,组成一个新数。(如输入“652394”,则输出“936”。),5.5函数程序实例,本章主要介绍了函数的定义、声明、调用及返回值,变量的作用域和预处理。掌握函数调用过程中的形参与实参,以及参数的值传递;掌握C语言变量的作用域;正确理解自动变量、静态变量、寄存器变量及外部变量的特点;掌握常用的宏定义、文件包含预处理命令。,本章小结,1.程序填空:要求输入两个数求最大值。,习题,2.程序填空:要求计算并输出给定整数n的所有因子(不包括1与自身)之和,规定n的值不大于1000。(如从键盘给n输入的值为“856”,则输出为“sum=76

29、3”。),习题,3.程序填空:设两个整数为u和v,用辗转相除法求最大公约数。,习题,4.程序填空:要求输出1到5的阶乘值。,习题,5.程序填空:要求用函数递归调用的方法求n!。,习题,6.程序填空:用递归法将一个整数n转换成字符串(n的位数不确定,可以是任意位数的整数,如输入“483”,输出字符串“483”)。,习题,7.下列程序的运行结果是。,习题,8.下列程序的运行结果是。,习题,9.下列程序的运行结果是。,习题,10.下列程序的运行结果是。,习题,11.运行以下程序,并输入100,那么程序的输出结果是。,习题,12.下列程序的运行结果是。,习题,13.下列程序的运行结果是。,习题,14.编程:打印出所有的“水仙花数”,其中编写一个函数fun()用来判断该数是否为水仙花数。,习题,15.编程:输出1000以内所有的“同构数”。其中编写一个函数fun()用来判断该数是否为同构数。(正整数n若是它平方数的尾部,则称n为同构数。如5的平方是25,25的平方是625,故5和25都是同构数。),习题,谢谢观看THANKYOU,

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

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com