模块化程序设计与语言函数.ppt
模块化程序设计与语言函数2023/4/4现在学习的是第1页,共66页u6.1.1 模块化程序设计模块化程序设计1.模块化程序模块化程序设计设计基本思想基本思想基本思想:基本思想:将程序按功能将程序按功能分割分割成小模块。成小模块。开发方法开发方法:FTTB,逐步分解逐步分解,分而治之分而治之。特点和作用:特点和作用:模块独立模块独立,功能单一功能单一,结构清晰结构清晰,接口简单。接口简单。控制了程序设计的复杂性。控制了程序设计的复杂性。提高模块元件的可靠性。提高模块元件的可靠性。缩短开发周期。缩短开发周期。避免程序开发的重复劳动。避免程序开发的重复劳动。易于维护和功能扩充。易于维护和功能扩充。FBTT方法与方法与FTTB方法方法6.1 模块化程序设计基础模块化程序设计基础What to do?How to do?2023/4/4现在学习的是第2页,共66页模块化程序设计的方法基础。模块化程序设计的方法基础。特点:特点:把复杂问题的求解过程分步骤进行。把复杂问题的求解过程分步骤进行。面向目标面向目标。采取。采取先全局先全局、后局部后局部的的逐步分逐步分解解思想。思想。有利于将更多精力集中于较小模块的局部有利于将更多精力集中于较小模块的局部设计中。设计中。避免了盲目性。降低了系统设计与实现的避免了盲目性。降低了系统设计与实现的整体工作量。整体工作量。FTTB(From Top To Bottom)2023/4/4现在学习的是第3页,共66页实践中:实践中:FBTT与与FTTB结合结合来解决问题。在来解决问题。在问问题求解步骤题求解步骤和和方法方法的确定上用的确定上用FTTB方法,在方法,在将所有模块将所有模块构成一个整体时构成一个整体时用用FBTT方法。方法。FBTT(From Bottom To Top)例例6-1 以以FTTB、逐步求精的模块化分解思想,分、逐步求精的模块化分解思想,分析析1948年下半年解放战争战略决战问题。年下半年解放战争战略决战问题。P125-1262023/4/4现在学习的是第4页,共66页例例6-2 求求1+2+100的和。的和。分析:分析:问题可分为三个部分,对应三个模块:问题可分为三个部分,对应三个模块:1)确定求值范围确定求值范围2)计算过程计算过程3)输出结果输出结果给定求和的上界给定求和的上界计算计算i从从1到给定上界的和到给定上界的和输出所求的和值输出所求的和值用选定方法求和用选定方法求和2023/4/4现在学习的是第5页,共66页 例例6-3 分析九九乘法表输出功能。分析九九乘法表输出功能。1.1.分析九九表的形状分析九九表的形状分析九九表的形状分析九九表的形状(例如第一种例如第一种例如第一种例如第一种)。2.2.打印九行,每行分成两个部分:前导空格和九九表打印九行,每行分成两个部分:前导空格和九九表打印九行,每行分成两个部分:前导空格和九九表打印九行,每行分成两个部分:前导空格和九九表的口诀内容。的口诀内容。的口诀内容。的口诀内容。右上角九九表右上角九九表输出九行输出九行输出某行输出某行i口诀构成:口诀构成:3*3 9 (即即i*j=i*j)输出第输出第i行行前导空格前导空格输出第输出第i行行口诀口诀输出第输出第输出第输出第i i行的行的行的行的i-1i-1个前个前个前个前导空格口诀导空格口诀导空格口诀导空格口诀输出第输出第输出第输出第i i行第行第行第行第k k个前导个前导个前导个前导空格口诀空格口诀空格口诀空格口诀输出第输出第输出第输出第i i行行行行9-i+19-i+1个口诀个口诀个口诀个口诀输出第输出第输出第输出第i i行第行第行第行第k k个口诀个口诀个口诀个口诀空格口诀与口诀空格口诀与口诀字符结构相同字符结构相同2023/4/4现在学习的是第6页,共66页2.模块化模块化程序程序的基本特征的基本特征模块的模块的IPO结构:结构:要注意模块功能的独立性、要注意模块功能的独立性、完成功能所需的参数和提供给外界的输出信完成功能所需的参数和提供给外界的输出信息。息。模块的接口问题:模块的接口问题:唯一的通信渠道。应保证唯一的通信渠道。应保证接口的接口的单入口单入口和和单出口单出口特征。特征。模块的功能问题:模块的功能问题:大小要合适大小要合适;具有较强的;具有较强的独立性独立性和相对简单性;内部实现方法也应按照和相对简单性;内部实现方法也应按照结构化程序设计思想进行组织和设计。结构化程序设计思想进行组织和设计。2023/4/4现在学习的是第7页,共66页u6.1.2 C语言对模块化程序设计技术的支持语言对模块化程序设计技术的支持1.函数式程序语言结构函数式程序语言结构函数函数带入函带入函数参数数参数带出计带出计算结果算结果图图6-6 C语言函数的基本结构语言函数的基本结构2023/4/4现在学习的是第8页,共66页float average(float fA,float fB,float fC)float fAve;fAve=(fA+fB+fC)/3;return fAve;/*End of average()*/外部向内部外部向内部传递信息传递信息内部控内部控制信息制信息由内部由内部由内部由内部向外传向外传向外传向外传递信息递信息递信息递信息1.允许进行模块内部及外部的信息交换允许进行模块内部及外部的信息交换3.具有编译预能力以方便模块化调试和移植具有编译预能力以方便模块化调试和移植2023/4/4现在学习的是第9页,共66页u6.2.1 C 语言程序的组织结构语言程序的组织结构6.2 函数的声明、定义和调用结构函数的声明、定义和调用结构源程序源程序n函数函数1函数函数2函数函数m源程序源程序i源程序源程序1C程序程序声明区声明区执行体执行体2023/4/4现在学习的是第10页,共66页u6.2.2 函数声明与定义函数声明与定义从用户角度分为:从用户角度分为:标准函数标准函数(库函数库函数):由系统提供。:由系统提供。用户用户自定义函数自定义函数:由程序员提供。:由程序员提供。从函数形式上分为:从函数形式上分为:无参函数无参函数有参函数有参函数使用使用库函数库函数应应注意:注意:1)函数完成的功能函数完成的功能 2)参数数目和顺序参数数目和顺序及各参数意义和及各参数意义和类型类型 3)返回值返回值的意义和类型的意义和类型4)调用函数所需的包含文件调用函数所需的包含文件(头文件头文件)先声明、后定先声明、后定义、再引用义、再引用2023/4/4现在学习的是第11页,共66页1.函数的声明函数的声明(Function Declaration)声明的作用:声明的作用:告诉编译器告诉编译器函数类型、参数个数函数类型、参数个数及类型,以便进行类型检验,保证调用的数及类型,以便进行类型检验,保证调用的数据传递的正确性。据传递的正确性。对被调用函数的要求:对被调用函数的要求:函数已经被定义,即函数已经被定义,即函数存在函数存在对库函数,知道库的头文件对库函数,知道库的头文件.h对自定义函数,有对自定义函数,有函数类型声明函数类型声明函数声明函数声明(函数原型声明函数原型声明)的的一般形式:一般形式:函数类型函数类型 函数名函数名(形参类型形参类型1 形参名形参名1,形参类型形参类型n 形参名形参名n);或或 函数类型函数类型 函数名函数名();P129:函数的声明函数的声明函数的声明函数的声明形参数据类型形参数据类型和顺序很重要和顺序很重要必须要必须要用分用分用分用分号号号号结束结束2023/4/4现在学习的是第12页,共66页函数定义函数定义与与函数声明函数声明不同不同函数声明的位置函数声明的位置(P133)下列情况,可不作函数声明:下列情况,可不作函数声明:u对对char或或int型函数型函数(隐含声明隐含声明)u函数的定义出现在主调函数之前函数的定义出现在主调函数之前有些系统要求函数声明指出函数返值和形参类有些系统要求函数声明指出函数返值和形参类型,即使对型,即使对void和和int型函数也要进行函数说明型函数也要进行函数说明(如如Borland C+)P130-1332023/4/4现在学习的是第13页,共66页一个完整形式的函数声明一个完整形式的函数声明/*exam0604a.c:完整形式的函数声明完整形式的函数声明*/#include int main(void)float fA=1,fB=2,fC=3;float sum(float fA,float fB,float fC);/*声明声明*/printf(sum=%fn,sum(fA,fB,fC);/*调用调用*/return 0;/*End of main()*/float sum(float fA,float fB,float fC)/*定义定义*/return(fA+fB+fC);/*End of sum()*/例例6-4 函数声明实例。函数声明实例。声明了一个声明了一个float型型函数函数sum()sum函数的定义函数的定义sum()函数有三函数有三个形式参数个形式参数观察函数的声明观察函数的声明和定义的区别和定义的区别2023/4/4现在学习的是第14页,共66页允许声明与定义的参数名字不同允许声明与定义的参数名字不同#include /*exam0604b.c*/int main(void)float x=1,y=2,z=3;float sum(float x,float y,float z);float sum(float x,float y,float z);/*声明参数名声明参数名*/printf(sum=%fn,sum(x+y,y,z);printf(sum=%fn,sum(x+y,y,z);/*/*实参名实参名*/return 0;return 0;/*End of main()*/*End of main()*/float sum(float a,float b,float c)float sum(float a,float b,float c)/*/*定义体参数名定义体参数名定义体参数名定义体参数名*/return(a+b+c);return(a+b+c);/*End of sum()*/2023/4/4现在学习的是第15页,共66页声明时可不给参数名,但类型要一一对应声明时可不给参数名,但类型要一一对应#include /*exam0604c.c*/int main(void)float x=1,y=2,z=3;float sum(float,float,float);/*声明声明*/printf(sum=%fn,sum(x,y,z);/*实参实参*/return 0;/*End of main()*/float sum(float a,float b,float c)return(a+b+c);/*End of sum()*/2023/4/4现在学习的是第16页,共66页/*exam0604d.c*/#include int main(void)float x=1,y=2,z=3;float sum(int a,float b,float c);/*声明声明*/printf(sum=%fn,sum(x,y,z);/*调用调用*/return 0;/*End of main()*/float sum(float a,float b,float c)/*定义定义*/return(a+b+c);/*End of sum()*/类型不一致类型不一致出错信息:出错信息:Type mismatch in redeclaration of sum2023/4/4现在学习的是第17页,共66页/*定义时参数名不能省略定义时参数名不能省略*/#include int main(void)float x=1,y=2,z=3;float sum(float a,float b,float c);/*声明声明*/printf(sum=%fn,sum(x,y,z);/*调用调用*/return 0;/*End of main()*/float sum(float,float,float)/*定义定义*/return(a+b+c);/*End of sum()*/定义时省略了参数名定义时省略了参数名出错信息:出错信息:Argument missing name in function sumUndefined symbol a in function sumUndefined symbol b in function sum Undefined symbol c in function sum2023/4/4现在学习的是第18页,共66页2.函数定义函数定义(Function Definition)是完成模块功能实现的主要工作。它对应是完成模块功能实现的主要工作。它对应一个分程序功能,也称为一个分程序功能,也称为函数体函数体。定义一般格式:定义一般格式:合法标识符合法标识符函数类型函数类型 函数名函数名(类型类型1 形参形参1,类型类型n 形参形参n)声明区域声明区域 /*变量或函数等的声明变量或函数等的声明*/执行语句区域执行语句区域 /*可执行命令序列可执行命令序列*/返回命令返回命令 /*retrun*/现代风格现代风格:函数体函数体函数返回值类型。缺省函数返回值类型。缺省函数返回值类型。缺省函数返回值类型。缺省时为时为时为时为int或或void2023/4/4现在学习的是第19页,共66页例例例例 有参函数有参函数有参函数有参函数(现代风格现代风格现代风格现代风格)int max(int max(int nX,int nYint nX,int nY)int nZ;int nZ;nZ=nXnY?nX:nY;nZ=nXnY?nX:nY;return(nZ);return(nZ);/*End of max()*/*End of max()*/例例例例 有参函数有参函数有参函数有参函数(现代风格现代风格现代风格现代风格)int max(int max(int nX,nYint nX,nY)int nZ;int nZ;nZ=nXnY?nX:nY;nZ=nXnY?nX:nY;return(nZ);return(nZ);/*End of max()*/*End of max()*/例例例例 空函数空函数空函数空函数dummy()dummy()/*End of dummy()*/*End of dummy()*/函数体为空函数体为空例例例例 无参函数无参函数无参函数无参函数printStar()printStar()printf(printf(*n);*n);/*End of printStar()*/*End of printStar()*/或或或或printStar(printStar(voidvoid)printf(*n”);printf(*n”);/*End of printStar()*/*End of printStar()*/2023/4/4现在学习的是第20页,共66页函数类型函数类型 函数名函数名(形参名形参名1,形参名形参名n)数据类型数据类型1 形参名形参名1;数据类型数据类型n 形参名形参名n;语句组语句组早期的函数定义经典方法早期的函数定义经典方法double sum(n1,n2,d1,d2)double d1,d2;int n1,n2;return(n1+n2+d1+d2);/*End of sum()*/函数类型函数类型形参名列表形参名列表声明次序声明次序和现代格和现代格式的区别式的区别参数类型参数类型2023/4/4现在学习的是第21页,共66页#include float average(float val_1,float val_2,float val_3);int main(void)float x=1,y=2,z=3,q=4,t=5;float ave_1,ave_2;/*存放返回结果存放返回结果*/ave_1=average(x,y,z);printf(ave_1=%fn,ave_1);ave_2=average(x,q,t);printf(ave_2=%fn,ave_2);return 0;/*End of main()*/float average(float val_1,float val_2,float val_3)float ave;ave=(val_1+val_2+val_3)/3.0;return ave;/*End of average()*/文件包含编译预处理命令文件包含编译预处理命令文件包含编译预处理命令文件包含编译预处理命令函数声明函数声明函数声明函数声明函数调用函数调用函数调用函数调用函数调用函数调用函数调用函数调用函数定义函数定义函数定义函数定义2023/4/4现在学习的是第22页,共66页3.函数的返回值函数的返回值返回语句返回语句格式:格式:return(表达式表达式);或或 return 表达式表达式;或或 return;功能:功能:使控制从被调用函数返回到调用函数,使控制从被调用函数返回到调用函数,同时把返值带给调用函数。同时把返值带给调用函数。说明:说明:一个函数可有多个一个函数可有多个一个函数可有多个一个函数可有多个returnreturn语句。语句。语句。语句。若无若无若无若无returnreturn语句,遇函数的语句,遇函数的语句,遇函数的语句,遇函数的 时,自动返回调时,自动返回调时,自动返回调时,自动返回调用函数。用函数。用函数。用函数。若函数类型与若函数类型与若函数类型与若函数类型与returnreturn语句中表达式值的类型不语句中表达式值的类型不语句中表达式值的类型不语句中表达式值的类型不一致,按前者为准,自动转换一致,按前者为准,自动转换一致,按前者为准,自动转换一致,按前者为准,自动转换函数调用转函数调用转函数调用转函数调用转换。换。换。换。voidvoid型函数。型函数。型函数。型函数。例例 无返回值函数。无返回值函数。void swap(int x,int y)int temp;temp=x;x=y;y=temp;/*End of swap()*/2023/4/4现在学习的是第23页,共66页printStar()printf(*);/*End of printStar*/int main(void)int nA;nA=printStar();printf(%d,nA);/*End of main()*/例例 函数带回不确定值。函数带回不确定值。输出:输出:*5void printStar()printf(*);/*End of printStar*/int main(void)int nA;nA=printStar();printf(%d,nA);/*End of main()*/编译错误!编译错误!Error:Not an allowed type in function main2023/4/4现在学习的是第24页,共66页例例 函数返回函数返回值类型转换值类型转换#include#includeint max(float fA,float fB);int max(float fA,float fB);int main(void)int main(void)float fA,fB;float fA,fB;int nCint nC;scanf(%f,%f,&fA,&fB);scanf(%f,%f,&fA,&fB);nC=max(fA,fB);nC=max(fA,fB);printf(Max is%dn,nC);printf(Max is%dn,nC);/*End of main()*/*End of main()*/int maxint max(float fX,float fY)(float fX,float fY)float fZfloat fZ;fZ=fXfY?fX:fY;fZ=fXfY?fX:fY;return(fZ);return(fZ);/*End of max()*/*End of max()*/返回值要自动返回值要自动转换成整型转换成整型!2023/4/4现在学习的是第25页,共66页u6.2.3 函数的调用函数的调用 参数是函数调用时的信息交换载体,其传递是参数是函数调用时的信息交换载体,其传递是函数调用过程的重要环节。函数调用过程的重要环节。C语言函数调用分为语言函数调用分为传值调用传值调用和和传地址调用传地址调用(第九章第九章)两种。两种。1.函数的传值调用函数的传值调用调用方法:调用方法:函数名函数名(实参表实参表)说明:说明:实参与形参个数相等,类型一致,按顺序实参与形参个数相等,类型一致,按顺序一一对应一一对应2023/4/4现在学习的是第26页,共66页float sum(float fA,float fB,float fC)return sum;/*End of sum()*/函数的函数的IO信息路径信息路径2023/4/4现在学习的是第27页,共66页注意函数参数求值顺序:注意函数参数求值顺序:自右向左。自右向左。#include#includeint f(int nA,int nB);int f(int nA,int nB);int main(void)int main(void)int i=2,nP;int i=2,nP;nP=f(nP=f(i,+ii,+i););printf(%d,%d,nP,i);printf(%d,%d,nP,i);return 0;return 0;/*End of main()*/*End of main()*/int f(int nA,int nB)int f(int nA,int nB)int nC;int nC;if(nAnB)nC=1;if(nAnB)nC=1;else if(else if(nA=nBnA=nB)nC=0;)nC=0;else nC=-1;else nC=-1;return(nC);return(nC);/*End of f()*/*End of f()*/运行结果:运行结果:0,3#include#includeint f(int nA,int nB);int f(int nA,int nB);int main(void)int main(void)int i=2,nP;int i=2,nP;nP=f(nP=f(i,i,i+i+););printf(%d,nP);printf(%d,nP);return 0;return 0;/*End of main()*/*End of main()*/int f(int nA,int nB)int f(int nA,int nB)int nC;int nC;if if(nAnB(nAnB)nC=1;)nC=1;else if(nA=nB)nC=0;else if(nA=nB)nC=0;else nC=-1;else nC=-1;return(nC);return(nC);/*End of f()*/*End of f()*/运行结果:运行结果:1,32023/4/4现在学习的是第28页,共66页函数调用可以用于表达式,可以单独成为一个语句,函数调用可以用于表达式,可以单独成为一个语句,也可以是其它函数的参数。因此,其调用形式有:也可以是其它函数的参数。因此,其调用形式有:函数调用作为单独的语句函数调用作为单独的语句 例例 printStar();printf(Hello,World!n);函数调用用作表达式的运算成分函数调用用作表达式的运算成分 例例 m=max(nA,nB)*2;函数调用作为其它函数的实参:函数调用作为其它函数的实参:例例 printf(%d,max(nA,nB);m=max(nA,max(nB,nC);2023/4/4现在学习的是第29页,共66页形参与实参形参与实参形参:形参:形参:形参:定义函数时定义函数时定义函数时定义函数时函数名后面括号中的函数名后面括号中的函数名后面括号中的函数名后面括号中的变量名变量名变量名变量名实参:实参:实参:实参:调用函数时调用函数时调用函数时调用函数时函数名后面括号中的函数名后面括号中的函数名后面括号中的函数名后面括号中的表达式表达式表达式表达式c=max(a,b);main()max()int max(int x,int y)int z;z=xy?x:y;return(z);/*End of max()*/例例 比较两个数并输出大者。比较两个数并输出大者。#include#includeint max(int x,int y);int max(int x,int y);int main(void)int main(void)int a,b,c;int a,b,c;scanf(%d,%d,&a,&b);scanf(%d,%d,&a,&b);c=c=max(a,b);max(a,b);printf(Max is%d,c);printf(Max is%d,c);/*End of main()*/*End of main()*/int max(int max(int x,int yint x,int y)int z;int z;z=xy?x:y;z=xy?x:y;return(z);return(z);/*End of max()*/*End of max()*/形参形参实参实参2023/4/4现在学习的是第30页,共66页说明:说明:u实参必须有确定的值实参必须有确定的值u形参必须指定类型形参必须指定类型u形参与实参形参与实参类型一致,个数相同类型一致,个数相同u若形参与实参类型不一致,自动按形参类型若形参与实参类型不一致,自动按形参类型转换转换函数调用转换函数调用转换u形参在形参在调用前调用前不占内存不占内存;调用执行时调用执行时为形参为形参分分配内存配内存;调用结束调用结束,释放空间释放空间。其存储空间是不。其存储空间是不固定的且值是固定的且值是不可继承不可继承的的u实参是特定存储空间中的值,在调用期间值不会实参是特定存储空间中的值,在调用期间值不会发生变化且存储空间相对固定发生变化且存储空间相对固定2023/4/4现在学习的是第31页,共66页例例6-7 形参和实参的虚实结合实例。形参和实参的虚实结合实例。#include float average(float val_1,float val_2,float val_3)float ave;ave=(val_1+val_2+val_3)/3.0;return ave;/*End of average()*/int main(void)float x=1,y=2,z=3,q=4,t=5;float ave_1,ave_2;ave_1=average(x,y,z);printf(ave_1=%fn,ave_1);ave_2=average(x,q,t);printf(ave_2=%fn,ave_2);return 0;/*End of main()*/6547065470654746547465486654866549065490654946549465478654786548265482 1.0000001.000000 2.0000002.000000 3.0000003.0000004.0000004.0000005.0000005.000000*x xy yt tave_1ave_1ave_2ave_2z zq q*val_2val_2val_1val_1val_3val_31.0000001.0000002.0000002.0000003.0000003.0000002.0000002.0000001.0000001.0000004.0000004.0000005.0000005.0000003.3333333.3333332023/4/4现在学习的是第32页,共66页参数传递方式参数传递方式值传递值传递方式:函数调用时为形参分配单元,方式:函数调用时为形参分配单元,并将实参值并将实参值复制复制到形参中;调用结束时形到形参中;调用结束时形参单元被释放,实参单元仍保留并维持原参单元被释放,实参单元仍保留并维持原值值值传递特点:值传递特点:形参与实参占用形参与实参占用不同不同的内存单的内存单元。元。单向单向传递。传递。2023/4/4现在学习的是第33页,共66页1020 x:y:调用前:调用前:调用后:调用后:1020 x:y:例例6-8 交换两个数。交换两个数。#include#include void swap(int a,int b);void swap(int a,int b);int main(void)int main(void)int x=10,y=20;int x=10,y=20;printf(x=%d,y=%dn,x,y);printf(x=%d,y=%dn,x,y);printf(swapped:n);printf(swapped:n);swap(x,y);swap(x,y);printf(x=%d,y=%dn,x,y);printf(x=%d,y=%dn,x,y);/*End of main()*/*End of main()*/void swap(void swap(int a,int bint a,int b)int temp;int temp;temp=a;a=b;b=temp;temp=a;a=b;b=temp;/*End of swap()*/*End of swap()*/调用:调用:1020a:b:1020 x:y:swap():1020 x:y:2010a:b:temp这里可以看:到这里可以看:到x,y的值并没有发生的值并没有发生变化,想要交换主函数中的变量变化,想要交换主函数中的变量x和和y的值,该如何处理呢的值,该如何处理呢?2023/4/4现在学习的是第34页,共66页地址传递方式:地址传递方式:函数调用时,将实参的函数调用时,将实参的存储地存储地址址作为作为参数值参数值传递给形参的参数传递方式。实传递给形参的参数传递方式。实质上也是值传递,不过穿的是形参的地址值,质上也是值传递,不过穿的是形参的地址值,而不是形参所在存储空间中的数据值。而不是形参所在存储空间中的数据值。传地址值的特点:传地址值的特点:J形参与实参占用形参与实参占用(指向指向)同样同样的存储单元的存储单元J“双向双向”传递传递J实参和形参必须是实参和形参必须是地址地址2023/4/4现在学习的是第35页,共66页例例 交换两个数交换两个数x59y调前:调前:xp159y调调swap:&x&yp2x95y交换:交换:p1&x&yp2x95y返回:返回:void swap(void swap(int*p1,int*p2int*p1,int*p2)int p;int p;p=*p1;*p1=*p2;*p2=p;p=*p1;*p1=*p2;*p2=p;/*End of swap()*/*End of swap()*/int main(void)int main(void)int x,y;int x,y;scanf(%d,%d,&x,&y);scanf(%d,%d,&x,&y);printf(x=%d,y=%dn,x,y);printf(x=%d,y=%dn,x,y);printf(swapped:n);printf(swapped:n);swap swap(&x,&y);(&x,&y);printf(x=%d,y=%dn,x,y);printf(x=%d,y=%dn,x,y);return 0;return 0;/*End of main()*/*End of main()*/2023/4/4现在学习的是第36页,共66页2.函数嵌套调用函数嵌套调用函数定义不可嵌套函数定义不可嵌套,但,但调用可以嵌套调用可以嵌套main()调用函数调用函数f1return 0;f1函数函数f2函数函数调用函数调用函数f22023/4/4现在学习的是第37页,共66页例例6-10 计算一个数的绝对值平方根。计算一个数的绝对值平方根。float absoluteValue(float x);float absoluteValue(float x);float squareRoot(float x);float squareRoot(float x);float float absoluteValueabsoluteValue(float x)(float x)if(x0)x=-x;if(x=epsilon)(guessValue*guessValue-x)=epsilon)guessValue=(x/guessValue+guessValue)/2.0;guessValue=(x/guessValue+guessValue)/2.0;return guessValue;return guessValue;/*End of square()*/*End of square()*/int main(void)int main(void)printf(SquareRoot(2.0)=%fn,squareRoot(2.0);printf(SquareRoot(2.0)=%fn,squareRoot(2.0);return 0;return 0;/*End of main()*/*End of main()*/main()squareRoot(2.0)squareRoot(2.0)return 0;squareRoot()absoluteValue()x=absoluteValue(x)x=absoluteValue(x)guessValue=absoluteValue(x/guessValue+guguessValue=absoluteValue(x/guessValue+guessValue)/2.0)essValue)/2.0)return guessValue;return x;return x;2023/4/4现在学习的是第38页,共66页3.函数的递归调用函数的递归调用*u函数直接或间接调用自己的调用函数直接或间接调用自己的调用f()调调f()调调f2()调调f1()f1()f2()int int f f(int nX)(int nX)int nY,nZ;int nY,nZ;nZ=nZ=f(nY)f(nY);.return(2*nZ);return(2*nZ);int int f1f1(int nX)(int nX)int nY,nZ;int nY,nZ;nZ=nZ=f2(nY)f2(nY);.return(2*nZ);return(2*nZ);int int f2f2(int nT)(int nT)int nA,nC;int nA,nC;nC=nC=f1(nA)f1(nA);.return(3+nC);return(3+nC);说明说明uC语言对递归函数的自调用次数没有限制语言对递归函数的自调用次数没有限制u每调用函数一次,系统将在内存堆栈区分配每调用函数一次,系统将在内存堆栈区分配空间,用于存放函数变量、返回值等信息。空间,用于存放函数变量、返回值等信息。所以递归次数过多可能引起堆栈溢出所以递归次数过多可能引起堆栈溢出2023/4/4现在学习的是第39页,共66页例例6-11 直接递归求直接递归求n的阶乘。的阶乘。int fact(int num)int fact(int num)if(num=1)return 1;if(num0)if(n0)/*n0/*n0时继续求时继续求时继续求时继续求n!*/n!*/nTemp=fact(n);nTemp=fact(n);printf(The%d!=%dn,n,nTemp);printf(The%d!=%dn,n,nTemp);else printf(n must be greater than zero!n);else printf(n must