《c语言程序设计教学资料》第7章-函数.ppt

上传人:wuy****n92 文档编号:72527206 上传时间:2023-02-12 格式:PPT 页数:120 大小:5.13MB
返回 下载 相关 举报
《c语言程序设计教学资料》第7章-函数.ppt_第1页
第1页 / 共120页
《c语言程序设计教学资料》第7章-函数.ppt_第2页
第2页 / 共120页
点击查看更多>>
资源描述

《《c语言程序设计教学资料》第7章-函数.ppt》由会员分享,可在线阅读,更多相关《《c语言程序设计教学资料》第7章-函数.ppt(120页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第第7 7章章 函数函数主要内容主要内容 模块化程序设计模块化程序设计 函数的定义函数的定义 向函数传递值和从函数返回值向函数传递值和从函数返回值 函数的调用函数的调用 函数的作用域和存储类别函数的作用域和存储类别 为什么要用函数为什么要用函数?问题:问题:p 如如果果程程序序的的功功能能比比较较多多,规规模模比比较较大大,把把所所有有代代码码都都写写在在main函函数数中中,就就会会使使主主函函数数变变得得庞庞杂杂、头头绪绪不不清清,阅阅读读和和维护变得困难维护变得困难p 有有时时程程序序中中要要多多次次实实现现某某一一功功能能,就就需需要要多多次次重重复复编编写写实现此功能的程序代码实现此

2、功能的程序代码,这使程序冗长,不精炼这使程序冗长,不精炼p 在设计一个较大的程序时,往往把它分为若干个程序模块,在设计一个较大的程序时,往往把它分为若干个程序模块,每一个模块包括一个或多个函数,每个函数实现一个特定的每一个模块包括一个或多个函数,每个函数实现一个特定的功能功能p 采用采用“分而治之分而治之”的办法简化程序设计的过程的办法简化程序设计的过程p C程序可由一个主函数和若干个其他函数构成程序可由一个主函数和若干个其他函数构成p 事先编好一批实现各种不同功能的函数事先编好一批实现各种不同功能的函数p 主函数调用其主函数调用其它它函数,其函数,其它它函数也可以互相调用函数也可以互相调用p

3、 同一个函数可以被一个或多个函数调用任意多次同一个函数可以被一个或多个函数调用任意多次用用模块化程序设计模块化程序设计mainabcfghdeie 功能分解功能分解-自顶而下、逐步求精的过程自顶而下、逐步求精的过程 模块化分解原则模块化分解原则-保证模块的相对独立性保证模块的相对独立性 高聚合高聚合(模块的功能独立、单一模块的功能独立、单一)、低耦合、低耦合(模块对外接口简单模块对外接口简单)设计好模块接口设计好模块接口-接口是指罗列出一个模块的所有与外部打交道的变量接口是指罗列出一个模块的所有与外部打交道的变量 -定义好后不要轻易改动定义好后不要轻易改动-在模块开头(文件的开头)进行函数声明

4、在模块开头(文件的开头)进行函数声明模块化程序设计方法模块化程序设计方法*How do you do!How do you do!*例例:输出以下的结果,用函数调用实现。输出以下的结果,用函数调用实现。在在输输出出的的文文字字上上下下分分别别有有一一行行“*”号号,显显然然不不必必重重复复写写这这段段代代码码,用用一一个个函函数数printstar来来实实现现输输出一行出一行“*”号的功能号的功能 再再写写一一个个print_message函函数数来来输输出出中中间间一一行行文文字信息字信息 用主函数分别调用这两个函数用主函数分别调用这两个函数解题思路:解题思路:例:例:函数调用的简单例子函数

5、调用的简单例子#include void main()void printstar();/*对对printstar函数声明函数声明*/void print_message();/*对对print_message函数声明函数声明*/printstar();/*调用调用printstar函数函数*/print_message();/*调用调用print_message函数函数*/printstar();/*调用调用printstar函数函数*/void printstar()/*定义定义printstar函数函数*/printf(*n);void print_message()/*定义定义prin

6、t_message函数函数*/printf(How do you do!n);运行情况如下:运行情况如下:*How do you do!How do you do!*(1)(1)一一个个C程程序序由由一一个个或或多多个个程程序序模模块块组组成成,每每一一个个程程序序模模块块作作为为一一个个源源程程序序文文件件。对对较较大大的的程程序序,一一般般不不希希望望把把所所有有内内容容全全放放在在一一个个文文件件中中,而而是是将将它它们们分分别别放放在在若若干干个个源源文文件件中中,由由若若干干个个源源程程序序文文件件组组成成一一个个C程程序序。这这样样便便于于分分别别编编写写、分分别别编编译译,提提高

7、高调调试试效率。一个源程序文件可以为多个效率。一个源程序文件可以为多个C程序共用。程序共用。说明:说明:(2)(2)一一个个源源程程序序文文件件由由一一个个或或多多个个函函数数以以及及其其他他有有关关内内容容(如如命命令令行行、数数据据定定义义等等)组组成成。一一个个源源程程序序文文件件是是一一个个编编译译单单位位,在在程程序序编编译译时时是是以以源源程程序序文文件件为为单单位位进进行行编编译译的的,而而不不是是以以函函数数为为单单位位进进行行编编译的。译的。(3)(3)C程程序序的的执执行行是是从从main函函数数开开始始的的,如如果果在在main函函数数中中调调用用其其他他函函数数,在在调

8、调用用后后流流程程返返回回到到main函数,在函数,在main函数中结束整个程序的运行。函数中结束整个程序的运行。(4)(4)所所有有函函数数都都是是平平行行的的,即即在在定定义义函函数数时时是是分分别别进进行行的的,是是互互相相独独立立的的。一一个个函函数数并并不不从从属属于于另另一一函函数数,即即函函数数不不能能嵌嵌套套定定义义。函函数数间间可可以以互互相相调调用用,但不能调用但不能调用main函数。函数。main函数是系统调用的。函数是系统调用的。(5)(5)从用户使用的角度看,函数有两种:从用户使用的角度看,函数有两种:标标准准函函数数,即即库库函函数数。这这是是由由系系统统提提供供的

9、的,用用户户不不必必自自己己定定义义这这些些函函数数,可可以以直直接接使使用用它它们们。不不同同的的C C系系统统提提供供的的库库函函数数的的数数量量和和功功能能会会有有一一些些不不同同,但但许许多多基本的函数是共同的。基本的函数是共同的。用户自己定义的函数用户自己定义的函数。用以解决用户的专门需要。用以解决用户的专门需要。(6)(6)从函数的形式看,函数分两类:从函数的形式看,函数分两类:无无参参函函数数。无无参参函函数数一一般般用用来来执执行行指指定定的的一一组组操操作作。在在调调用用无无参参函函数数时时,主主调调函函数数不不向向被被调调用用函函数数传传递递数据。数据。有有参参函函数数。主

10、主调调函函数数在在调调用用被被调调用用函函数数时时,通通过过参参数向被调用函数传递数据。数向被调用函数传递数据。怎样定义函数怎样定义函数?为什么要定义函数为什么要定义函数定义函数的方法定义函数的方法p C语言要求,在程序中用到的所有函数,必须语言要求,在程序中用到的所有函数,必须“先定义,后使用先定义,后使用”p 指定指定函数函数名字名字、函数、函数返回值类型返回值类型、函数实现的、函数实现的功能功能以及以及参数的个数与类型参数的个数与类型,将这些信息通知编,将这些信息通知编译系统。译系统。p 指定函数的名字,以便以后按名调用指定函数的名字,以便以后按名调用p 指定函数类型,即函数返回值的类型

11、指定函数类型,即函数返回值的类型p 指定函数参数的名字和类型,以便在调用函数时向它指定函数参数的名字和类型,以便在调用函数时向它们传递数据们传递数据p 指定函数的功能。这是最重要的,这是在函数体中解指定函数的功能。这是最重要的,这是在函数体中解决的决的p 对对于于库库函函数数,程程序序设设计计者者只只需需用用#include指指令令把把有关的头文件包含到本文件模块中即可有关的头文件包含到本文件模块中即可p 程程序序设设计计者者需需要要在在程程序序中中自自己己定定义义想想用用的的而而库库函函数并没有提供的函数数并没有提供的函数 函数定义的一般形式函数定义的一般形式 (1 1)无参函数的定义一般形

12、式)无参函数的定义一般形式(2 2)有参函数定义的一般形式)有参函数定义的一般形式(3 3)空函数)空函数 函数定义的一般形式函数定义的一般形式 (1 1)无参函数的定义一般形式)无参函数的定义一般形式 类型类型函数名函数名()()声明部分声明部分 语句部分语句部分 类类型型标标识识符符指指明明函函数数类类型型,函函数数的的类类型型实实际际上上是是函函数数返返回回值值的的类类型型。函函数数名名后后面面有有一一个个空空括括号号,其其中中无无参参数,但是括号不能少。数,但是括号不能少。类型类型函数名函数名(voidvoid)声明部分声明部分 语句部分语句部分 例如:例如:void hello()p

13、rintf(“hello world!n”);(2 2)有参函数定义的一般形式)有参函数定义的一般形式 类型类型函数名函数名(类型类型 形式参数形式参数1 1,类型,类型 形式参数形式参数2 2,)声明部分声明部分 语句部分语句部分 有有参参函函数数比比无无参参函函数数多多了了形形式式参参数数列列表表,它它们们可可以以是是各各种种类类型型的的变变量量,个个参参数数之之间间用用逗逗号号间间隔隔。进进行行函函数数调调用用时时,主主调调函函数数将将赋赋予予这这些些形形式式参参数数实实际际的的值值,形形参是变量,参是变量,必须在形参表中给出形参的类型说明必须在形参表中给出形参的类型说明例如:例如:in

14、t max(int x,int y)int z;/*函数体中的声明部分函数体中的声明部分*/z=xy?x:y;return(z);(3)(3)空函数空函数 类型类型函数名函数名(形参列表)(形参列表)例如:例如:Dummy(形参列表形参列表)先用空函数占一个位置,以后先用空函数占一个位置,以后逐步逐步扩充扩充 好好处处:程程序序结结构构清清楚楚,可可读读性性好好,以以后后扩扩充充新新功功能方便,对程序结构影响不大能方便,对程序结构影响不大调用函数调用函数函数的调用形式函数的调用形式函数调用时的数据传递函数调用时的数据传递函数调用的过程函数调用的过程函数的返回值函数的返回值函数调用的形式函数调用

15、的形式p 函数调用的一般形式为:函数调用的一般形式为:函数名(实参表列)函数名(实参表列)p 如果是调用无参函数,则如果是调用无参函数,则“实参表列实参表列”可以没有,可以没有,但括号不能省略但括号不能省略p 如果实参表列包含多个实参,则各参数间用逗号如果实参表列包含多个实参,则各参数间用逗号隔开隔开。按按函函数数调调用用在在程程序序中中出出现现的的形形式式来来分分,可可以以有有以以下下3 3种函数调用方式种函数调用方式:(1 1)函数调用语句函数调用语句 把函数调用单独作为一个语句把函数调用单独作为一个语句 如如:printfstar()();这这时时不不要要求求函函数数带带回回值值,只只要

16、要求求函函数数完完成成一一定定的的操操作作(2 2)函数表达式函数表达式 函数调用出现在另一个表达式中函数调用出现在另一个表达式中 如如:c=2*max(a,b);这时要求函数带回一个确定的值以参加表达式的运算这时要求函数带回一个确定的值以参加表达式的运算(3 3)函数参数函数参数 函数调用作为另一函数调用时的实参函数调用作为另一函数调用时的实参 如如:mmax(a,max(b,c);其其中中max(b,c)是是一一次次函函数数调调用用,它它的的值值作作为为max另另一一次调用的实参次调用的实参p 函数参数:用于函数间数据的传递函数参数:用于函数间数据的传递 形式参数(形参):定义函数时给出的

17、参数形式参数(形参):定义函数时给出的参数 实际参数(实参):调用函数时给出的参数实际参数(实参):调用函数时给出的参数p 实参与形参的个数应相等,类型应匹配。实参与实参与形参的个数应相等,类型应匹配。实参与形参按顺序对应,一一传递数据。形参按顺序对应,一一传递数据。p 如果实参列表包括多个实参,对实参求值的顺序如果实参列表包括多个实参,对实参求值的顺序并不是确定的,有的系统按自左至右顺序求实参的并不是确定的,有的系统按自左至右顺序求实参的值,有的系统则按自右至左顺序。值,有的系统则按自右至左顺序。说明:说明:例例 :实参求值的顺序实参求值的顺序如果按自左至右顺序求实如果按自左至右顺序求实参的

18、值,则函数调用相当参的值,则函数调用相当于于f f(2,32,3)如果按自右至左顺序求实如果按自右至左顺序求实参的值,则函数调用相当参的值,则函数调用相当于于f f(3,33,3)函数调用时的数据传递函数调用时的数据传递p 形式参数:形式参数:函数名后面括号中的变量名称为函数名后面括号中的变量名称为“形形式参数式参数”(简称(简称“形参形参”)。)。p 实际参数:实际参数:主调函数中调用一个函数时,函数名主调函数中调用一个函数时,函数名后面括号中的参数后面括号中的参数(可以是一个表达式可以是一个表达式)称为称为“实际实际参数参数”(简称(简称“实参实参”)。)。p 实参和形参间的数据传递实参和

19、形参间的数据传递p 在调用函数过程中,系统会把实参的值传递给被在调用函数过程中,系统会把实参的值传递给被调用函数的形参调用函数的形参p 该值在函数调用期间有效,可以参加该值在函数调用期间有效,可以参加被调被调函数中函数中的运算的运算p用用return语句返回计算结果语句返回计算结果,通过函数调用使主调通过函数调用使主调函数得到的确定值。函数得到的确定值。例例:调用函数时的数据传递调用函数时的数据传递运行情况如下:运行情况如下:,max is 通过函数调用,可使两个函数中的数据发生联系。通过函数调用,可使两个函数中的数据发生联系。函数调用的过程函数调用的过程p 在定义函数中指定的形参,在未出现函

20、数调用时,在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。在发生函数调用时,它们并不占内存中的存储单元。在发生函数调用时,函数函数maxmax的形参被临时分配内存单元。的形参被临时分配内存单元。p 调用结束,形参单元被释放调用结束,形参单元被释放p 实参单元仍保留并维持原值,没有改变实参单元仍保留并维持原值,没有改变p 如果在执行一个被调用函数时,形参的值发生改如果在执行一个被调用函数时,形参的值发生改变,不会改变主调函数的实参的值变,不会改变主调函数的实参的值关于形参与实参的说明:关于形参与实参的说明:(1 1)在定义函数中指定的形参,在未出现函数调用在定义函数中指定

21、的形参,在未出现函数调用时,它们并不占内存中的存储单元。只有在发生函数时,它们并不占内存中的存储单元。只有在发生函数调用时,函数调用时,函数max中的形参才被分配内存单元。在调中的形参才被分配内存单元。在调用结束后,形参所占的内存单元也被释放。用结束后,形参所占的内存单元也被释放。(2 2)实参可以是常量、变量或表达式,实参可以是常量、变量或表达式,例如:例如:max(3,a+b);但要求它们有确定的值。在调用时将实参的值赋给但要求它们有确定的值。在调用时将实参的值赋给形参。形参。(3 3)在被定义的函数中,必须指定形参的类型。)在被定义的函数中,必须指定形参的类型。(4 4)实参与形参的类型

22、应相同或赋值兼容。)实参与形参的类型应相同或赋值兼容。(5 5)值传递)值传递:实参向形参的数据传递是单向实参向形参的数据传递是单向“值传递值传递”,只能由实参传给形参,而不能由形参传回来给实,只能由实参传给形参,而不能由形参传回来给实参。参。在调用函数时,给形参分配存储单元,并将实参对在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。实参单元仍保留并维持原值。函数的返回值说明:函数的返回值说明:(1 1)函数的)函数的返回值是通过函数中的返回值是通过函数中的return语句获得的语

23、句获得的。一个函数中可以有一个以上的一个函数中可以有一个以上的return语句,执行到哪语句,执行到哪一个一个return语句,哪一个语句起作用。语句,哪一个语句起作用。return语句后面的括弧也可以不要语句后面的括弧也可以不要 例如:例如:“return z;”等价于等价于“return(z);”return后面的值可以是一个表达式。后面的值可以是一个表达式。例如例如:max(int x,int y)return(?:););(2 2)函数的)函数的返回值应当属于某一个确定的类型返回值应当属于某一个确定的类型,在定,在定义函数时指定函数返回值的类型。义函数时指定函数返回值的类型。例如例如:

24、下面是下面是3个函数的首行:个函数的首行:int max(float x,float y)/*函数值为整型*/char letter(char c1,char c2)/*函数值为字符型*/double min(int x,int y)/*函数值为双精度型*/注意注意:凡不加类型说明的函数,自动按整型处理。凡不加类型说明的函数,自动按整型处理。(3 3)在定义函数时指定的函数类型一般应该和)在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致。语句中的表达式类型一致。如果函数值的类型和如果函数值的类型和return语句中表达式的值不语句中表达式的值不一致,则以函数类型为准。一致

25、,则以函数类型为准。对数值型数据,可以自动进行类型转换。即函数对数值型数据,可以自动进行类型转换。即函数类型决定返回值的类型。类型决定返回值的类型。(4 4)对于不带回值的函数,应当用)对于不带回值的函数,应当用“void”定义函数定义函数为为“无类型无类型”(或称(或称“空类型空类型”)。此时在函数体中)。此时在函数体中不得出现不得出现return语句。语句。例例:返回值类型与函数类型不同返回值类型与函数类型不同运行情况如下:运行情况如下:1.5,2.5max is 2 1.52.62.62变为变为2main()函数函数p main()函数是由系统调用的,使得函数是由系统调用的,使得C C程

26、序从程序从main()函数开始执行,调用其它函数后流程返回到函数开始执行,调用其它函数后流程返回到main()函数,在函数,在main()中结束整条程序的运行。中结束整条程序的运行。p若定义若定义main()时没有指定返回值类型,也没有时没有指定返回值类型,也没有使用使用void,则返回值默认为,则返回值默认为int类型,虽然语法类型,虽然语法允许这样做,但实际编程时通常将允许这样做,但实际编程时通常将main()函数写函数写成如下形式:成如下形式:第一种形式:用第一种形式:用void指明函数没有返回值指明函数没有返回值第二种形式:第二种形式:return返回值的返回值的0等价于调用等价于调用

27、exit()时提供的参数。时提供的参数。第三种形式:进一步用第三种形式:进一步用void指出指出main函数没有函数没有参数参数在一个函数中调用另一函数(即被调用函数)需要具备哪些条件呢?p 首先被调用的函数必须是已经存在的函数(是库函数或用户首先被调用的函数必须是已经存在的函数(是库函数或用户自己定义的函数)。但光有这一条件还不够。自己定义的函数)。但光有这一条件还不够。p 如果使用库函数,还应该在本文件开头如果使用库函数,还应该在本文件开头#include 命令将调用命令将调用有关库函数时所需用到的信息有关库函数时所需用到的信息“包含包含”到本文件中来。到本文件中来。p 如果使用用户自己定

28、义的函数,而该函数的位置在调用它的如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面,应该在主调函数中对被调用的函函数(即主调函数)的后面,应该在主调函数中对被调用的函数作声明。数作声明。例:对被调用的函数作声明例:对被调用的函数作声明#include void main()()float add(float x,float y);/*对对被被调调用函数的声明用函数的声明*/float a,b,c;scanf(f,f,&a,&b););cadd(a,b);printf(sum is f n,c););float add(float x,float y)/*函数定函数定

29、义义*/float z;/*函数体函数体*/zxy;return(z););例例:对被调用的函数作声对被调用的函数作声明明#include float add(float x,float y)/*函数定函数定义义*/float z;/*函数体函数体*/zx+y;return(z);void main()float a,b,c;scanf(“%f,%f,&a,&b););cadd(a,b);printf(sum is%f n,c););p 函数原型的一般形式为函数原型的一般形式为:1.函数类型函数类型 函数名函数名(类型类型1,类型,类型2,);2.函数类型函数类型 函数名函数名(类型类型1,参

30、数,参数1,参数,参数2,参数,参数2,);如:如:float add(float x,float y);float add(float,float);p 在调用函数时,需要进行函数原型声明在调用函数时,需要进行函数原型声明声明的作用:声明的作用:是把函数名、函数参数的个数和参数类型等信息通知是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。识别函数并检查调用是否合法。注意:注意:函数的函数的“定义定义”和和“声明声明”的区别:的区别:p 函数的定义是指对函数功能的确立,包括指定

31、函函数的定义是指对函数功能的确立,包括指定函数名,函数值类型、形参及其类型、函数体等,它是数名,函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。一个完整的、独立的函数单位。p 函数的声明的作用则是把函数的名字、函数类型函数的声明的作用则是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便在以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。调用该函数时系统按此进行对照检查。函数小函数小结函数的嵌套调用和递归调用函数的嵌套调用和递归调用p 嵌套调用:在定义一个函数时,其函数体内又包含嵌套调用:在定义一个函数时,其函数体内又包含另一个

32、函数的完整定义另一个函数的完整定义 。p 递归调用:递归调用:在调用一个函数的过程中又出现直接或在调用一个函数的过程中又出现直接或间接地调用该函数本身间接地调用该函数本身。解题思路:解题思路:main中调用中调用max4函数,找函数,找4个数中最大者个数中最大者max4中再调用中再调用max2,找两个数中的大者找两个数中的大者max4中多次调用中多次调用max2,可找,可找4个数中的大者,然后把个数中的大者,然后把它作为函数值返回它作为函数值返回main函数函数main函数中输出结果函数中输出结果例例:输入输入4 4个整数,找出其中最大的数。用函数的嵌个整数,找出其中最大的数。用函数的嵌套调用

33、来处理。套调用来处理。#include int main()int max4(int a,int b,int c,int d);/*对对被被调调用函数用函数max4的声明的声明*/int a,b,c,d,max;printf(“4 interger numbers:);scanf(%d,%d,%d,%d,&a,&b,&c,&d);max=max4(a,b,c,d);printf(max=%d n,max);return 0;int max4(int a,int b,int c,int d)/*max4函数函数*/int max2(int a,int b);/*对被调用函数对被调用函数max2的

34、声明的声明*/int m;m=max2(a,b);/*a,b中较大者中较大者*/m=max2(m,c);/*a,b,c中较大者中较大者*/m=max2(m,d);/*a,b,c,d中较大者中较大者*/return(m);int max2(int a,int b)/*max2函数函数*/if(a=b)return a;else return b;return(ab?a:b);int max4(int a,int b,int c,int d)/*max4函数函数*/int max2(int a,int b);/*对被调用函数对被调用函数max2的声明的声明*/int m;m=max2(a,b);/

35、*a,b中较大者中较大者*/m=max2(m,c);/*a,b,c中较大者中较大者*/m=max2(m,d);/*a,b,c,d中较大者中较大者*/return(m);int max2(int a,int b)/*max2函数函数*/return(ab?a:b);m=max2(max2(a,b),c);m=max2(max2(max2(a,b),c),d);return(max2(max2(max2(a,b),c),d);#include int main()int max4(int a,int b,int c,int d);/*对对被被调调用函数用函数max4的声明的声明*/int a,b,

36、c,d,max;printf(“4 interger numbers:);scanf(%d,%d,%d,%d,&a,&b,&c,&d);max=max4(a,b,c,d);printf(max=%d n,max);return 0;int max4(int a,int b,int c,int d)/*max4函数函数*/int max2(int a,int b);return(max2(max2(max2(a,b),c),d);int max2(int a,int b)/*max2函数函数*/return(ab?a:b);int max2(int a,int b)/*max2函数函数*/ret

37、urn ab?a:b;int max4(int a,int b,int c,int d)/*max4函数函数*/return max2(max2(max2(a,b),c),d);#include int main()int a,b,c,d,max;printf(4 interger numbers:);scanf(%d,%d,%d,%d,&a,&b,&c,&d);max=max4(a,b,c,d);printf(max=%dn,max);return 0;例例:函数递归函数递归 有有5 5个人坐在一起,问第个人坐在一起,问第5 5个人多少岁?他说比第个人多少岁?他说比第4 4个人大个人大2 2

38、岁。岁。问第问第4 4个人岁数,他说比第个人岁数,他说比第3 3个人大个人大2 2岁。问第岁。问第3 3个人,又说比第个人,又说比第2 2个人大个人大2 2岁。问第岁。问第2 2个人,说比第个人,说比第1 1个人大个人大2 2岁。最后问第岁。最后问第1 1个人,个人,他说是他说是1010岁。请问第岁。请问第5 5个人多大。个人多大。解题思路解题思路:要求第要求第5个年龄,就必须先知道第个年龄,就必须先知道第4个年龄个年龄 要求第要求第4个年龄必须先知道第个年龄必须先知道第3个年龄个年龄 第第3个年龄又取决于第个年龄又取决于第2个年龄个年龄 第第2个年龄取决于第个年龄取决于第1个年龄个年龄 每个

39、学生年龄都比其前每个学生年龄都比其前1个学生的年龄大个学生的年龄大2age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10用数学公式表述如下:用数学公式表述如下:age(n)=10()()age(n-1)+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(2)=12 age(3)=14 age(4)=16 age(5)=18 回溯阶段回溯阶段 递推阶段递推阶段结束递归的条件结束递归的条件可以用一个函数

40、来描述上述递归过程:可以用一个函数来描述上述递归过程:int age(int n)/求年龄的递归函求年龄的递归函 int c;/c用作存放函数的返回值的变量用作存放函数的返回值的变量 if(n=1)c=10;else c=age(n-1)+2;return c;运行结果如下:运行结果如下:18 用一个主函数调用用一个主函数调用age函数,求得第函数,求得第5人的年龄。人的年龄。#include int main()printf(%d,age(5);return 0;例例:用递归方法求!用递归方法求!解题思路:解题思路:求求n!也也可可以以用用递递归归方方法法,即即5!等等于于4!5,而而4!=

41、3!4,!=可用下面的递归公式表示:可用下面的递归公式表示:!#include int main()int fac(int n);int n,y;printf(input an integer number:);scanf(%d,&n);y=fac(n);printf(%d!=%dn,n,y);return 0;int fac(int n)int f;if(n0)printf(n0,data error!);else if(n=0|n=1)f=1;else f=fac(n-1)*n;return(f);注意溢出注意溢出 局部变量和全局变量局部变量和全局变量p 语句块:程序中被语句块:程序中被括

42、起来的语句。括起来的语句。p 作作用用域域:每每个个变变量量仅仅在在定定义义它它的的语语句句块块内内有有效效,并且拥有自己的存储空间并且拥有自己的存储空间p 同同一一个个语语句句块块内内不不可可以以定定义义同同名名变变量量,不不同同语语句句块内可以定义同名变量块内可以定义同名变量p 在在函函数数内内部部或或复复合合语语句句内内部部定定义义的的变变量量称称为为“局局部变量部变量”。p 在在一一个个函函数数内内部部定定义义的的变变量量只只在在本本函函数数范范围围内内有有效效p 在在复复合合语语句句内内定定义义的的变变量量只只在在本本复复合合语语句句范范围围内内有效有效局部变量局部变量:例:例:fl

43、oat f1(int a)/*函数函数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有效有效*/例:例:float f1(int a)int b,c;char f2(int x,int y)int i,j;int main()int a,b;return 0;a、b也也仅仅在在此此函数内函数内有效有效类类似似于于不不同同班同名学生班同名学生p主函数中定义的变量只在主函数中有效主函数中定义的变量只在主函数中有效,而不因为

44、在主函而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。其他函数中定义的变量。p不同函数中可以使用相同名字的变量不同函数中可以使用相同名字的变量,它们代表不同的对它们代表不同的对象象,互不干扰。互不干扰。p形式参数也是局部变量。形式参数也是局部变量。p进入语句块时获得内存,仅能由语句块内语句访问,退出进入语句块时获得内存,仅能由语句块内语句访问,退出语句块时释放内存,不在有效。语句块时释放内存,不在有效。说明:说明:全局变量全局变量p 在在函函数数内内定定义义的的变变量量是是局局部部变变量量,而而在在函函数数

45、之之外外定义的变量称为外部变量定义的变量称为外部变量p 外部变量是全局变量外部变量是全局变量(也称全程变量也称全程变量)p 全局变量可以为本文件中其全局变量可以为本文件中其它它函数所共用函数所共用p 有有效效范范围围为为从从定定义义变变量量的的位位置置开开始始到到本本源源文文件件结结束束p从从程程序序运运行行起起即即占占据据内内存存,程程序序运运行行过过程程中中可可以以随随时访问,程序退出时释放内存时访问,程序退出时释放内存int p=1,q=5;/*外部变量外部变量*/float f1(int a)/*定义函数定义函数f1*/int b,c;char c1,c2;/*外部变量外部变量*/ch

46、ar f2(int x,int y)/*定义函数定义函数f2*/int i,j;全局变量全局变量p,q的作用范围的作用范围 全局变量全局变量c1,c2的作用范围的作用范围void main()/*主函数主函数*/int m,n;p、q的有效范围的有效范围c1、c2的有效范围的有效范围建议:不必要时不要使用全局变量,原因如下:建议:不必要时不要使用全局变量,原因如下:全局变量在程序的全部执行过程中都占用存储单全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。元,而不是仅在需要时才开辟单元。使用全局变量过多,会降低程序的清晰性。在各使用全局变量过多,会降低程序的清晰性。在各

47、个函数执行时都可能改变外部变量的值,程序容易个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限制使用全局变量。出错。因此,要限制使用全局变量。降低函数的通用性。因为函数在执行时要依赖于降低函数的通用性。因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移到另一个文其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件的变量同名时,就会出但若该外部变量与其他文件的变量同名时,就会出现问题,降低了程序的可靠性和通用性。一般要求现问题,降低了程序的可靠性和通用性。一般要求把把C程序中

48、的函数做成一个封闭体,除了可以通过程序中的函数做成一个封闭体,除了可以通过“实参实参形参形参”的渠道与外界发生联系外,没有其的渠道与外界发生联系外,没有其他渠道。他渠道。例例 外部变量与局部变量同名外部变量与局部变量同名#include int a=3,b=5;/*a,b为外部变量为外部变量*/void main()int max(int a,int b);int a=8;/*a为局部变量为局部变量*/printf(%d,max(a,b);/*全局变量全局变量b的作用范围的作用范围*/max(int a,int b)/*a,b为局部变量为局部变量*/int c;c=ab?a b;形参形参a、b

49、作用范围作用范围 return(c);运行结果为运行结果为 8 分析:分析:设置两个函数设置两个函数f、fact。f用于求平方用于求平方fact用于求阶乘用于求阶乘 变量的存储类型变量的存储类型 p 从变量的从变量的作用域作用域(即从空间)角度来分,可以分为(即从空间)角度来分,可以分为全局变量和局部变量全局变量和局部变量。p 从变量值从变量值存在的时间存在的时间角度来分,又可以分为角度来分,又可以分为静态存静态存储方式和动态存储方式储方式和动态存储方式。静态存储方式:静态存储方式:指在程序运行期间由系统分配固定指在程序运行期间由系统分配固定的存储空间的方式。的存储空间的方式。动态存储方式:动

50、态存储方式:在程序运行期间根据需要进行动态在程序运行期间根据需要进行动态的分配存储空间的方式。的分配存储空间的方式。程序区程序区静态存储区静态存储区动态存储区动态存储区用户存储空间可以分为三个部分:用户存储空间可以分为三个部分:将将数据存放在数据存放在此区此区全全局局变变量量全全部部存存放放在静态存储区中在静态存储区中函函数数形形式式参参数数函函数数中中定定义义的的没没有有用用关关键键字字staticstatic声声明明的的变变量量函函数数调调用用时时的的现现场场保保护护和和返返回回地地址址等等存放在动态存储区存放在动态存储区程程序序开开始始执执行行时时给给全全局局变变量量分分配配存存储储区区

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

当前位置:首页 > 教育专区 > 大学资料

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

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁