版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+高级语言程序设计第5章 函数北京邮电大学信息与通信工程学院程序设计中,把具有一定功能的程序模块用函数或类来实现。 2022/8/12北京邮电大学信息与通信工程学院-2-第5章 函数内容函数定义、声明、函数的调用、函数参数传递机制函数的特殊形式,包括递归函数、内联函数、带默认参数值的函数标识符的作用域和可见性变量的存储类型和生存期2022/8/12北京邮电大学信息与通信工程学院-3-5.1 函数概述 结构化程序设计,将整个程序自顶向下分为若干个程序模块,每个模块用来实现一个特定的功能。C + 中的模块以函数和类的形式实现。函数是具有一定功能又经常使用的相对独立代码段。无论是面向过程的程序设计
2、还是面向对象的程序设计,函数都是一种实现算法的重要形式。2022/8/12北京邮电大学信息与通信工程学院-4-5.1 函数概述 函数接口(规定接口形式)函数名(命名规则与变量相同,见名知意)函数类型(返回值类型)形式参数表函数体(实现算法三种基本结构组合而成)常用的函数C+的库函数自定义的函数2022/8/12北京邮电大学信息与通信工程学院-5-5.1.1 自定义函数概述编程者在处理具体问题时,将程序中多处使用的、实现一定功能的特定代码段定义成函数。这样的函数称为自定义函数。在同一个程序中,一个函数只能定义一次。一般是通过函数调用来使用函数。函数调用需要指定函数名并且提供被调用函数所需的信息(
3、即函数参数)。2022/8/12北京邮电大学信息与通信工程学院-6-5.1.1 自定义函数概述例如要打印某一年某一月的月历2022/8/12北京邮电大学信息与通信工程学院-7-5.1.2 库函数概述C+标准库提供了丰富的函数集合,可以进行常用的数学计算、字符串操作、字符操作、输入/输出、错误检查和许多其他操作。要熟悉C+标准库提供的类和函数集合,不要事事从头做起,要尽可能利用C+标准库提供的函数,以便减少程序开发的时间。这是程序设计的技巧之一。2022/8/12北京邮电大学信息与通信工程学院-8-5.1.2 库函数概述数学库函数实现常见的数学计算使用时,在程序中嵌入cmath头文件,按对应库函
4、数的接口形式写调用语句。调用数学函数: 函数名(参数1,参数n) 例如: double x; x=sqrt(900.0); coutx;数学函数库中的多数函数都返回double类型结果。2022/8/12北京邮电大学信息与通信工程学院-9-2022/8/12北京邮电大学信息与通信工程学院-10-常用数学库函数函 数说 明举 例ceil(x)将x取整为不小于x的最小整数ceil(9.2)=10ceil(9.8)=9cos(x)x(弧度)的余弦cos(0.0)=1.0exp(x)指数函数exexp(1.0) =2.71828exp(2.0)=7.38906fabs(x)x的绝对值fabs(5)=5
5、floor(x)将x取整为不大于x的最大整数floor(9.2)=9floor(9.8)=10fmod(x,y)x/y的浮点数余数fmod(13.657, 2.333)=1.992log(x)x的自然对数(底数为e)log(2.718282)=1.0 log(7.389056)=2.0log10(x)x的对数(底数为10)log(10.0)=1.0log(100.0)=2.0pow(x,y)x的y次方(xy)pow(2,7)=128pow(9,0.5)=3sin(x)x(弧度)的正弦sin(0.0)=0sqrt(x)x的平方根sqrt(900.0)=30.0tan(x)x(弧度)的正切tan(
6、0.0)=02022/8/12北京邮电大学信息与通信工程学院-11-#include #include using namespace std;int main() cout a b c;if ( (a != 0) & (b*b - 4*a*c 0) ) double radical = sqrt(b*b - 4*a*c);double root1 = (-b + radical) / (2*a);double root2 = (-b - radical) / (2*a);cout Roots: root1 root2; else cout Does not have two real roo
7、ts;return 0;调用函数 或主调函数被调函数库函数2022/8/12北京邮电大学信息与通信工程学院-12-#include using namespace std;float CircleArea(float r);int main() / manage circle computation cout MyRadius; float Area = CircleArea(MyRadius); cout Circle has area =y?x:y; return maxv;2022/8/12北京邮电大学信息与通信工程学院-15- float CircleArea (float r) co
8、nst float Pi = 3.1415;return Pi * r * r; 5.2.1 函数的定义 函数体返回值语句局部变量定义形式参数函数类型函数名5.2.1 函数的定义 函数名是函数体代码段的外部标识符函数定义之后,即可通过函数名调用函数。例:/ Sum(): compute sum of integers in a . bint Sum(int a, int b) int Total = 0;for (int i = a; i = b; +i) Total += i;return Total;2022/8/12北京邮电大学信息与通信工程学院-16-5.2.1 函数的定义 函数的形式
9、参数表,简称形参表 形式: (类型1 形式参数1,类型n 形式参数n) 2022/8/12北京邮电大学信息与通信工程学院-17-/ Sum(): compute sum of integers in a . bint Sum(int a, int b) int Total = 0;for (int i = a; i = b; +i) Total += i;return Total;形式参数表示主调函数和被调函数之间需要交换的信息(1)传给被调函数的待处理的数据;(2)控制被调函数执行操作的信息;(3)被调函数执行的结果。形式参数表从参数的类型、个数、排列顺序上规定了主调函数和被调函数之间信息交
10、换的形式。 float func(int k, int b, float x) return k*x+b; 2022/8/12北京邮电大学信息与通信工程学院-18-5.2.1 函数的定义 如果函数之间没有需要交换的信息,也可以没有形参,形参表内写void或空着。 int Read() cout Response;return Response;2022/8/12北京邮电大学信息与通信工程学院-19-5.2.1 函数的定义 5.2.1 函数的定义 函数体是实现函数功能的代码部分变量声明完成函数功能的语句两部分从组成结构看,函数体是由程序的三种基本控制结构即顺序、选择、循环结构组合而成的。 202
11、2/8/12北京邮电大学信息与通信工程学院-20-int Sum(int a, int b) int Total = 0;for (int i = a; i = b; +i) Total += i;return Total;2022/8/12北京邮电大学信息与通信工程学院-21-函数是由函数名、函数类型、形参表和函数体四部分组成的,使用时通过函数名和参数表调用函数. 例:编写一个函数cube,计算整数的立方。调用函数cube计算从1到10相邻整数的立方差。2022/8/12北京邮电大学信息与通信工程学院-22-尽可能避免在循环体内调用函数!/计算整数的立方#include using name
12、space std;int cube( int ); / 函数原型声明void main()int last, cb;last=1;cout the difference of cube: endl; for ( int x = 2; x = 10; x+ ) cb=cube( x ); cout cb-last ; last=cb; cout endl;/函数定义int cube( int y ) return y*y*y;2022/8/12北京邮电大学信息与通信工程学院-23-/ 在三个浮点中找出最大值#include using namespace std;float maximum(f
13、loat x, float y, float z); / 函数原型声明void main() float a, b, c; cout a b c; /调用maximum函数,a,b,c为实际参数 cout Maximum is: maximum( a, b, c ) =y?x:y; max = max=z?max:z; return max;5.2.1 函数的定义 注意如果没有函数原型声明,要先写函数定义,后调用函数。C+语言不允许函数嵌套定义,所有函数的定义都是自成一体,即函数体中只包含实现其自身功能的基本语句,不可包含其他函数的定义体。2022/8/12北京邮电大学信息与通信工程学院-25
14、-5.2.2 函数原型引用函数之前,要先指定函数的接口形式函数原型函数定义函数原型声明格式: 函数类型 函数名(形式参数表);例: int Max(int a, int b);函数原型声明使编译器获得关于函数名称、函数类型、函数形参个数、形参类型和形参顺序的信息。函数调用时,编译器根据函数原型声明验证函数调用正确与否。 2022/8/12北京邮电大学信息与通信工程学院-26-5.2.2 函数原型程序中,如果调用自定义的函数,且函数定义在后,调用在先,则必须在调用函数之前有函数原型声明。void subfun1(int x, float a, float b);/原型声明main() int x
15、 = 20; float a=1.0f, b=0.5f; subfun1();/函数调用 void subfun1(int x, float a, float b)/函数定义 2022/8/12北京邮电大学信息与通信工程学院-27-5.2.2 函数原型如果是函数定义在先,调用在后,则不必进行函数原型声明。因为编译器已经从函数定义得到关于函数的信息。 void subfun1(int x, float a, float b)/函数定义 main() subfun1(i, f1, f2);/函数调用 2022/8/12北京邮电大学信息与通信工程学院-28-5.2.2 函数原型源文件中,如果在所有函
16、数定义体之外声明函数原型,则该函数可被位于其原型声明之后的所有函数调用。 2022/8/12北京邮电大学信息与通信工程学院-29-void subfun1();/原型声明main() subfun1();/函数调用 void subfun2() subfun1();/函数调用 void subfun1()/函数定义 main() void subfun1();/函数原型声明 subfun1();/函数调用 void subfun2() subfun1();/函数调用, void subfun1() 2022/8/12北京邮电大学信息与通信工程学院-30-错误,编译器不识别sunfun1标识符。
17、5.2.2 函数原型库函数的声明在相应库的头文件中,使用库函数时要包含对应的头文件。例: #include 调用数学库函数: sqrt() sin() abs() 2022/8/12北京邮电大学信息与通信工程学院-31-2022/8/12北京邮电大学信息与通信工程学院-32-常用C+ 标准库头文件cassert包含增加诊断以帮助程序调试的宏和信息cctype 包含测试某些字符属性的函数原型和将小写字母变为 大写字母、将大写字母变为小写字母的函数原型cmath 包含数学库函数的函数原型cstdio 包含标准输入/输出库函数的函数原型及其使用的信息cstdlib 包含将数字变为文本、将文本变为数字
18、、内存分配、 随机数和各种其他工具函数的函数原型cstring 包含C语言方式的字符串处理函数原型ctime 包含操作时间和日期的函数原型和类型iostream 包含标准输入/输出函数原型iomanip 包含能够格式化数据流的流操纵运算子的函数原型fstream 包含和磁盘文件读/写有关的函数原型5.2.2 函数原型例5-2 计算3个整数绝对值的平均值。2022/8/12北京邮电大学信息与通信工程学院-33-2022/8/12北京邮电大学信息与通信工程学院-34-/例5-2 计算3个数绝对值的平均值 #include #include using namespace std; int CalA
19、bsMean(int a, int b, int c); /自定义函数的原型声明 void main() int a, b, c; coutabc; cout绝对值的均值为:CalAbsMean(a, b, c)endl; int CalAbsMean(int a, int b, int c) int sum = abs(a) + abs(b) + abs(c); sum /= 3; return sum; 运行结果: 输入 a,b,c: -10 20 -30 绝对值的均值为:20 5.2.3 return语句return语句使程序执行流程从被调函数返回主调函数,有两种形式: (1) 不返回值
20、的形式 return; (2) 返回值的形式 return 表达式;2022/8/12北京邮电大学信息与通信工程学院-35-int Sum(int a, int b) int Total = 0;for (int i = a; i = b; +i) Total += i;return Total;void DisplayMessage () cout只显示确定信息的简单函数不带参数endl; return;函数返回值类型规定了函数返回给主调函数的值的类型,也称为函数类型。 当被调函数只需要把一个数值结果返回给主调函数时,使用return语句返回比较合适。由return语句返回的值的类型必须与函
21、数返回值类型一致。若表达式的结果与函数类型不一致,不能通过编译,需要作强制类型转换,将表达式的类型强制成与函数类型。例如,如果mean是float型,而函数是int型,则return语句应为: return (int)mean; 2022/8/12北京邮电大学信息与通信工程学院-36-int Sum(int a, int b) int Total = 0;for (int i = a; i = b; +i) Total += i;return Total;5.2.3 return语句5.2.3 return语句注意如果不需要向主调函数返回值,函数可以定义成无类型的,函数类型写成void,函数结
22、束时也不必用return语句。 例: void display() cout“no return”endl; 2022/8/12北京邮电大学信息与通信工程学院-37-5.2.3 return语句例5-3 根据输入的颜色符号,显示不同的字符串表示的不同颜色。2022/8/12北京邮电大学信息与通信工程学院-38-2022/8/12北京邮电大学信息与通信工程学院-39-/例5-3 根据输入的颜色符号,显示不同的字符串表示的不同颜色#include using namespace std; void DispColor (char color); void main() char color; co
23、utcolor; DispColor (color); 2022/8/12北京邮电大学信息与通信工程学院-40-/根据输入,显示颜色字符串 void DispColor (char color) switch(color) case r: coutred. ; break; case g: coutgreen. ; break; case b: coutblue; break; default: break; return; 5.2.3 return语句例5-4 从输入文件中读入学生人数和每人考试成绩,统计成绩的平均值。2022/8/12北京邮电大学信息与通信工程学院-41-2022/8/12
24、北京邮电大学信息与通信工程学院-42-/例5-4.从输入文件中读入学生人数和每人考试成绩,统计成绩均值。#include #include using namespace std; int CalMean(char chFileName); /函数原型声明 void main() char chFileName80=; cout chFileName; /输入文件名 int mean=ChlMean(chFileName); /得到平均值 cout平均值= meanendl; 2022/8/12北京邮电大学信息与通信工程学院-43-/计算均值,函数定义如下 int CalMean(char c
25、hFileName) int count;/数据个数 int score;/分数 int sum(0), mean; ifstream infile(chFileName); if(!infile) cout!infileendl; infilecount; cout成绩个数:; coutcountendl; cout成绩:score)/从文件读取成绩,并累计总成绩; coutscore ; sum+=score;/累积分数 cout0) mean=sum/count; /计算平均值 else mean=0; return mean;/将平均值返回主调函数运行结果: 成绩个数:10 成绩: 5
26、9 39 24 36 87 98 52 67 52 60 平均值=575.2.4 函数调用方式函数语句函数语句形式: 函数名(实参数表);TriAreabySide(a, b, c); 函数表达式函数调用出现在表达式中,形式:函数名(实际参数表)x=max(a,b); y=sqrt(x);此时函数要使用return语句向主调函数返回一个确定的值,参与它所在的表达式的运算。 float max(float a,float b) return a=b?a:b; 函数参数函数参数调用方式是将函数调用写在另一次函数调用的实际参数位置。例如: m=max(a,max(b, c); 2022/8/12北京
27、邮电大学信息与通信工程学院-44-5.2.4 函数调用方式实际参数表可简称为实参表,是按与被调函数形式参数表一一对应的格式组织的参数表,即参数的类型、个数和排列顺序必须与被调函数声明的形式参数表严格一致。实际参数表的各实际参数以逗号间隔,实际参数可以是常量、变量或表达式,变量和表达式必须具有确定值。如果被调函数无形式参数,则实参表也是空的。实际编程中,从可读性考虑,一般使用变量作为实际参数。2022/8/12北京邮电大学信息与通信工程学院-45-例: 计算y=kx+b的函数 float func(int k,int b,float x) return k*x+b; void main() in
28、t k,b; float x,y; cinkbx; y=func(k,b,x);例:找最高分数 int FindMaxValue(int array, int n) int maxValue = array0; for(int k=1; k maxValue ) maxValue = arrayk; return maxValue; void main() int score30, num=30; for(int k=0; kscorek; int maxScore = FindMaxScore(score, num); coutmaxScoreendl; 2022/8/12北京邮电大学信息与
29、通信工程学院-46-实际参数以数据值(值传递)或实际存储空间(地址传递)提供了形式参数所需的内容。#includeusing namespace std;void DisplayMessage(); void main() DisplayMessage (); /函数调用语句void DisplayMessage () cout只显示确定信息的简单函数不带参数endl;2022/8/12北京邮电大学信息与通信工程学院-47-如果被调函数无形参,则实参表也是空的。5.2.4 函数调用方式5.2.4 函数调用方式例5-5 编写程序,实现坐标旋转公式:2022/8/12北京邮电大学信息与通信工程学院
30、-48-2022/8/12北京邮电大学信息与通信工程学院-49-/实现坐标旋转公式#include#include using namespace std;void main()const double PI=3.14; int x,y;/旋转后坐标int x0,y0;/原始坐标int angle; /旋转角度 /输入数据coutx0y0;coutangle;/计算旋转后的坐标double theta=angle*PI/180;x=x0*cos(theta)-y0*sin(theta);y=x0*sin(theta)+y0*cos(theta);/输出结果coutx=xendl;couty=y
31、endl;5.3 函数调用的执行机制和参数传递方式函数调用过程是如何实现的?程序执行流程能够从主调函数到被调函数,再由被调函数正确返回主调函数的断点继续执行,是基于函数调用工作栈来实现的。函数的参数传递方式值传递地址传递2022/8/12北京邮电大学信息与通信工程学院-50-5.3.1 函数调用的执行机制栈是函数调用正确执行的物理基础.栈是一种数据结构,它的工作原理就像在子弹匣压子弹一样,最先压入的子弹要等到最后才飞射出去,而最后压入的子弹则首先飞射出去。2022/8/12北京邮电大学信息与通信工程学院-51-004010560040105700401058004010590040105A00
32、40106BABCD栈的管理原则: 先进后出或 后进先出5.3.1 函数调用的执行机制函数调用能够正确执行的物理基础是操作系统在内存中开辟了一块叫做栈的内存空间。断点工作记录断点地址被调函数的形式参数自动局部变量2022/8/12北京邮电大学信息与通信工程学院-52-5.3.1 函数调用的执行机制例5-6 从键盘输入屏幕上两点的坐标(x, y),计算两点之间的距离。(分析函数调用时活动记录 )2022/8/12北京邮电大学信息与通信工程学院-53-2022/8/12北京邮电大学信息与通信工程学院-54-void main()int x1,y1,x2,y2;/两点坐标float dist; /两
33、点间距离coutx1y1;coutx2y2;dist=CalDistance(x1,y1,x2,y2);coutdistance between point (x1,y1) and point (x2,y2): distendl; 栈main函数中的自动局部变量 断点地址仅一个工作记录活动工作记录2022/8/12北京邮电大学信息与通信工程学院-55-/计算距离float CalDistance(int xx1, int yy1, int xx2, int yy2)int dx,dy;dx=xx2-xx1;dy=yy2-yy1;float dist=sqrt(dx*dx+dy*dy);retu
34、rn dist; 栈main函数中的自动局部变量断点地址工作记录示意工作记录CalDistance函数中的自动局部变量断点地址活动工作记录5.3.2 函数的参数传递方式函数之间的信息交换的一种重要形式是函数的参数传递,由函数的形式参数和实际参数实现。函数在没有被调用时,函数的形式参数并不占有实际的内存空间,也没有实际的值。C+语言中函数的参数传递方式分为两种:值传递地址传递2022/8/12北京邮电大学信息与通信工程学院-56-2022/8/12北京邮电大学信息与通信工程学院-57-值传递如果函数的形式参数为普通变量,当函数被调用时,系统为这些形式参数分配内存空间,并用实际参数值初始化对应的形
35、式参数,形式上实际参数的值传递给了形式参数。这就是函数调用时参数的值传递。值传递方式,实际参数和形式参数各自占有自己的内存空间;参数传递方向只能由实际参数到形式参数;不论函数对形式参数作任何修改,对相应的实际参数都没有影响。5.3.2 函数的参数传递方式5.3.2 函数的参数传递方式例5-7 从键盘输入两整数,交换次序后输出。 2022/8/12北京邮电大学信息与通信工程学院-58-2022/8/12北京邮电大学信息与通信工程学院-59-/演示函数参数值传递单向性的例程#includevoid swap(int a, int b);int main()int x(5), y(10);coutx
36、=x y=yendl;swap(x,y);coutx=x y=yendl;return 0;510 xy10241028运行结果:x=5 y=10 x=5 y=102022/8/12北京邮电大学信息与通信工程学院-60-void swap(int a, int b)int t;t=a;a=b;b=t;5a204810b2052t20565105编程技巧:交换两个变量的值,需要引入第三个变量缓存数据。例 如果一个数的所有真因子(包括1,但不包括这个数本身)之和正好等于这个数本身,则称此数为完美数。例如: 6=123,而 1+2+3=6; 28=147=1214, 而 1+2+4+7+14=28。
37、 如何确定完美数,欧几里得发现,只要是一个素数,则 一定是一个完美数。编写程序找出最小的5个完美数。2022/8/12北京邮电大学信息与通信工程学院-61-体会函数参数的值传递2022/8/12北京邮电大学信息与通信工程学院-62-/寻找最小的五个完美数#include #includeusing namespace std;bool DecidePrime(unsigned int number);unsigned int power(unsigned int x, unsigned int y);void main() unsigned int perfect_number;unsigne
38、d int num,temp;short n(2);short counter(0);/计数器2022/8/12北京邮电大学信息与通信工程学院-63-while (counter5) temp=power(2,n);num=temp-1;if(DecidePrime(num) perfect_number=temp/2*num; coutn=n,perfect number=perfect_numberendl; counter+;n+;2022/8/12北京邮电大学信息与通信工程学院-64-/计算指数unsigned int power(unsigned int x, unsigned in
39、t y)unsigned int mul(1);for(int i=1;i=y;i+)mul*=x;return mul;2022/8/12北京邮电大学信息与通信工程学院-65-/判别素数bool DecidePrime(unsigned int number)unsigned int i, k; k=sqrt(number); for(i=2; i=k+1) /判断number是否被小于number的数整除 return true;else return false;5.3.2 函数的参数传递方式地址传递地址变量做形参数组名指针变量引用2022/8/12北京邮电大学信息与通信工程学院-66-
40、5.3.2 函数的参数传递方式冒泡排序 int array5 = 5,4,3,2,1;2022/8/12北京邮电大学信息与通信工程学院-67-5.3.2 函数的参数传递方式例5-9 用整型数组存储数据,编写冒泡排序函数BubbleSort(),在主调函数中用随机数产生函数生成数组元素,并输出排序的结果。2022/8/12北京邮电大学信息与通信工程学院-68-2022/8/12北京邮电大学信息与通信工程学院-69-/例5-9 基于数组的冒泡排序例 #include #include using namespace std; void BubbleSort (int array,int n); /
41、函数原型声明 2022/8/12北京邮电大学信息与通信工程学院-70-void main() const int N = 20; int arrayN = 0; srand(unsigned int)time(NULL); int k; cout待排序数据:endl; for(k=0; kN; k+) /数据生成 arrayk = rand()%100; cout arrayk ,; BubbleSort (array, N); /调用排序函数 cout endl排序后数据:endl; for(k=0; kN; k+) /数据生成 cout arrayk ,; coutendl; 2022/8
42、/12北京邮电大学信息与通信工程学院-71-/冒泡排序 void BubbleSort (int a,int n) int temp; for(int pass=1; passn; pass+) /共比较size-1轮 for(int k=0; kak+1) temp=ak; ak=ak+1; ak+1=temp; 运行结果: 待排序数据: 37,99,56,87,48,96,71,88,63,44,34,21,59,0,36,92,53,25,4,20 排序后数据: 0,4,20,21,25,34,36,37,44,48,53,56,59,63,71,87,88,92,96,99注意(1)数
43、组名作为形式参数,只将数组的起始地址传递给了被调函数,数组的大小需要单独通过值传递的方式传给被调函数。例5-9中的用法是一维数组名形式参数,只传一个大小即可;如果是多维数组名作为函数的形式参数,则数组的每一维的大小都需要传给被调函数。例如,定义求一个矩阵的转置矩阵的函数TransposeMatrix(),矩阵用二维数组表示,函数接口如下:void TransposeMatrix(int matrixN, int tMatrixM, int rows ,int cols );2022/8/12北京邮电大学信息与通信工程学院-72-注意(2)多维数组名作为形式参数,只可以省略第一维(最左边)的大小
44、,也可以不省略。在被调函数中访问这个形式上的数组时,切忌下标越界问题。2022/8/12北京邮电大学信息与通信工程学院-73-5.4 递归函数和递归调用递归函数是函数的一种特殊形式,适合实现数学上的一些递归问题。使用递归函数可以简单明了地表达算法(算法的可读性好),但算法的效率一般不高。2022/8/12北京邮电大学信息与通信工程学院-74-5.4.1 嵌套调用C+的函数不能嵌套定义 C+的函数可以嵌套调用 2022/8/12北京邮电大学信息与通信工程学院-75-不能嵌套定义void main() int x,y; int sub(int a,int b) int c=a+b; 可以嵌套调用m
45、ain() DecidePrime() sqrt()if(DecidePrime(num) k=sqrt(number); 5.4.2 递归函数和递归调用递归函数是函数体内有调用函数自己的语句或通过其它函数间接调用函数自己的函数。 递归调用是调用递归函数而形成的一种函数调用方式。 递归函数用于实现数学中的递归问题比较直观方便。 2022/8/12北京邮电大学信息与通信工程学院-76-经典递归调用问题 阶乘定义式: 2022/8/12北京邮电大学信息与通信工程学院-77-2022/8/12北京邮电大学信息与通信工程学院-78-#include using namespace std;int fa
46、ctorial( int n);void main() coutn; n_fact=factorial(n); coutthe factorial of nis: n_factendl;返回地址12022/8/12北京邮电大学信息与通信工程学院-79-int factorial( int n) int fn; if(n=0) fn = 1; else fn=n*factorial(n-1); return fn;返回地址2n=3地址1栈状态fn=?n=2地址2fn=?n=1地址2fn=?n=0地址2断点地址参数局部变量toptoptoptop实例演示2022/8/12北京邮电大学信息与通信工程
47、学院-80-int factorial( int n) int fn; if(n=0) fn = 1; else fn=n*factorial(n-1); return fn;返回地址2n=3地址1栈状态fn=?n=2地址2fn=?n=1地址2fn=1n=0地址2topfn=1n=1地址2fn=2n=2地址2toptoptop递归问题的求解实际分成两个阶段:化简问题的递推阶段;达到递归终止条件得到基本情况的结果,并逐步回推结果阶段。递归函数的主要两部分 具有更简单参数的递归调用 停止递归的终止条件(递归终止条件) 2022/8/12北京邮电大学信息与通信工程学院-81-例5-11 整数x和y的
48、最大公约数是x和y能够整除的最大整数。编写一个递归函数GcommonDivisor,返回整数x和y的最大公约数。算法:整数x和y的最大公约数的递归实现:如果y等于0,则GcommonDivisor(x,y)为x;否则GcommonDivisor(x,y)为GcommonDivisor(y,x%y).其中%是求余运算符。 2022/8/12北京邮电大学信息与通信工程学院-82-xy1088220 xy1228281212440理解递归问题2022/8/12北京邮电大学信息与通信工程学院-83-/计算x和y的最大公约数(递归函数)#includeusing namespace std;int Gc
49、ommonDivisor(int x, int y);void main() int x,y; coutxy;coutthe greatest common divisor of xand y: GcommonDivisor(x,y)endl; 地址12022/8/12北京邮电大学信息与通信工程学院-84-int GcommonDivisor(int x, int y) int gcd;if (y=0)gcd=x;elsegcd=GcommonDivisor(y, x%y); return gcd; 以输入10,8为例地址2X(10)y(8)地址1gcd=?X(8)y(2)地址2gcd=?X(
50、2)y(0)地址2gcd=?X(2)y(0)地址2gcd=2X(2)y(0)地址2gcd=2X(8)y(2)地址2问题:用循环能实现吗?(作业)5.5 内 联 函 数 函数调用时,系统首先要保存主调函数的相关信息,再将控制转入被调函数,这些操作增加了程序执行的时间开销。 C+提供的内联函数形式可以减少函数调用的额外开销(时间空间开销),特别是一些常用的短小的函数适合采用内联函数形式。 2022/8/12北京邮电大学信息与通信工程学院-85-5.5 内 联 函 数内联函数的定义形式:inline 函数类型 函数名(形式参数表) 函数体 2022/8/12北京邮电大学信息与通信工程学院-86-5.
51、5 内 联 函 数例5-13 使用内联函数求三个整数中的最大值。 2022/8/12北京邮电大学信息与通信工程学院-87-2022/8/12北京邮电大学信息与通信工程学院-88-/内联函数例#includeusing namespace std;inline int max(int x, int y, int z) return (x=y) ? (x=z ? x : z) : (y=z ? y : z);void main() int a,b,c; coutabc; coutMaximum is max(a,b,c)=b) ? (a=c ? a : c) : (b=c ? b : c)2022
52、/8/12北京邮电大学信息与通信工程学院-89- 内联函数之所以能够减少函数调用时的系统空间和时间开销,是因为系统在编译程序时就已经把内联函数的函数体代码插入到相应的函数调用位置,成为主调函数内的一段代码,可以直接执行,不必再转换流程控制权。 这样的结构,自然节省了时间和空间开销,但使得主调函数代码变长。 一般是只把短小的函数写成内联函数。2022/8/12北京邮电大学信息与通信工程学院-90-注意:(1)内联函数体不能包含循环语句、switch语句和异常接口声明。(2)内联函数要先定义,后调用。因为编译器需要用内联函数的函数体代码替换对应的函数调用。如果内联函数不符合要求,编译器就将内联函数
53、当一般函数处理。5.6 重 载 函 数重载函数也是函数的一种特殊情况。 C+允许几个功能类似函数同名,但这些同名函数的形式参数必须不同,称这些同名函数为重载函数。 例:int max(int x, int y)return xy?x:y; float max(float x, float y) return xy?x:y; 2022/8/12北京邮电大学信息与通信工程学院-91-2022/8/12北京邮电大学信息与通信工程学院-92-各重载函数形式参数的不同是指参数的个数、类型或顺序彼此不同,不包括参数标识符的不同。如: int max(int a, int b)return ab?a:b;
54、int max(int x, int y)return xy?x:y; int max(int x, int y, int z) return (xy?x:y)z? (xy?x:y):z; 实际是一个函数,如果写在同一个文件中,编译时会出现编译错误。若或在同一个文件中可形成重载函数。编译器将以形式参数个数的不同来认定和区分重载函数。 2022/8/12北京邮电大学信息与通信工程学院-93-#includeusing namespace std;int min(int x, int y) return xy?x:y;double min(double x, double y) return xy
55、?x:y;void main() int ia(10),ib(20); double da(0.1), db(0.5); coutminimum of integer . is min(ia,ib)endl; coutminimum of double is min(da,db)endl;2022/8/12北京邮电大学信息与通信工程学院-94-在使用重载函数时需要注意下面三点:编译器不以形式参数的标识符区分重载函数。例int max(int a, int b);int max(int x, int y);编译器认为这是同一个函数声明两次,编译时出错。2022/8/12北京邮电大学信息与通信工程
56、学院-95-(2)编译器不以函数类型区分重载函数。float fun(int x,int y);int fun(int x,int y);如果函数名和形式参数表相同,只是函数类型不同,编译器同样认为它们是同一个函数声明两次,编译出错。(3)不应该将完成不同功能的函数写成重载函数,破坏程序的可读性。2022/8/12北京邮电大学信息与通信工程学院-96-重载函数常用于实现功能类似而所处理的数据类型不同的问题5.7 默认参数值的函数具有默认参数值的函数是一种特殊的函数形式, C+允许函数的形式参数有默认值。例如:计算圆面积的函数:double CircleArea(double radius=1.
57、0) const double PI=3.14; return PI*radius*radius; 2022/8/12北京邮电大学信息与通信工程学院-97-2022/8/12北京邮电大学信息与通信工程学院-98-调用具有默认参数值的函数时,如果提供实际参数值,则函数的形参值取自实际参数;如果不提供实际参数值,函数的形参采用默认参数值。例如调用CircleArea函数:#includeusing namespace std;void main() coutCircleArea(10.0)endl; /提供实际参数值 coutCircleArea()endl; /不提供实际参数值2022/8/12
58、北京邮电大学信息与通信工程学院-99-默认参数值函数如果有多个参数,而其中只有部分参数具有默认值,则这些具有默认值的参数值应该位于形参表的最右端。或者说,形参表中具有默认参数值的参数的右边,不能出现没有默认值的参数。例如:int CuboidVolume(int length=1, int width=1, int height=1); /正确int CuboidVolume(int length, int width=1, int height=1); /正确int CuboidVolume(int length, int width, int height=1); /正确int Cuboi
59、dVolume(int length=1, int width, int height=1); /错误int CuboidVolume(int length, int width=1, int height); /错误int CuboidVolume(int length=1, int width=1, int height); /错误2022/8/12北京邮电大学信息与通信工程学院-100-如果默认参数值函数是先声明,后定义的,则在声明函数原型时就指定默认参数值。如果函数定义在先(无需原型声明),则在函数定义的形参表中指定默认值。 例5-13 编写具有默认函数值的函数,计算直角三角形的面积。
60、 /使用默认形式参数值的函数编写计算直角三角形面积的程序#include using namespace std;float areaRATriangle( int side1 = 3, int side2 = 4);void main()cout The area of default right-angled triangle(3,4) is: “ areaRATriangle()endl; cout The area of right-angled triangle(6,4) is:“ areaRATriangle(6)endl; cout The area of right-angle
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024公司担保合同
- 医用胶布的材质选择与使用技巧考核试卷
- 信息系统的社交媒体与网络媒介考核试卷
- 广告与社会文化变革考核试卷
- 2024工程招标代理专用合同
- 2024装修材料贸易合同协议书
- 天然气开采的地理分布考核试卷
- 苏州科技大学天平学院《流体力学》2021-2022学年第一学期期末试卷
- 苏州科技大学天平学院《机械制造技术基础》2022-2023学年第一学期期末试卷
- 创业空间市场定位与规划案例考核试卷
- 【课件】Unit4+Section+B+(Project)课件人教版(2024)七年级英语上册
- 青少年法治教育实践基地建设活动实施方案
- 绿化养护续签合同申请书范文
- 教科(2024秋)版科学三年级上册2.6 我们来做“热气球”教学设计
- 4.3《课间》 (教案)-2024-2025学年一年级上册数学北师大版
- 追要工程款居间合同范本2024年
- 2024至2030年中国氮化硅轴承球行业市场全景调查及投资前景分析报告
- 三年级上《时分秒》教材解读
- 公司培训工作报告6篇
- 审计模拟实训教程第四版马春静版部分答案
- 政务服务中心物业服务投标方案(技术方案)
评论
0/150
提交评论