资源描述
#1 Title 28 Pt.Arial Bold Title Case,Bullet level 24 pt.Arial bold sentence case,Second level 20 pt.Arial bold sentence case,Third level 18 pt.Arial sentence case,Third level 16 pt.Arial sentence case,1,HONEYWELL-CONFIDENTIAL,File Number,#1 Title 28 Pt.Arial Bold Title Case,Bullet level 24 pt.Arial bold sentence case,Second level 20 pt.Arial bold sentence case,Third level 18 pt.Arial sentence case,Third level 16 pt.Arial sentence case,第六章 函数和递推递归算法,第六章 函数和递推递归算法,第一节 函数,第二节 递推算法,第三节 递归算法,第一节 函数第二节 递推算法第三节 递归算法,第一节 函数,前面我们曾经学习了程序设计中的三种基本控制结构(顺序、分支、循环)。用它们可以组成任何程序。但在应用中,还经常用到子程序结构。,通常,在程序设计中,我们会发现一些程序段在程序的不同地方反复出现,此时可以将这些程序段作为相对独立的整体,用一个标识符给它起一个名字,凡是程序中出现该程序段的地方,只要简单地写上其标识符即可。这样的程序段,我们称之为子程序。,子程序的使用不仅缩短了程序,节省了内存空间及减少了程序的编译时间,而且有利于结构化程序设计。因为一个复杂的问题总可将其分解成若干个子问题来解决,如果子问题依然很复杂,还可以将它继续分解,直到每个子问题都是一个具有独立任务的模块。这样编制的程序结构清晰,逻辑关系明确,无论是编写、阅读、调试还是修改,都会带来极大的好处。,在一个程序中可以只有主程序而没有子程序(本章以前都是如此),但不能没有主程序,也就是说不能单独执行子程序。,在此之前,我们曾经介绍并使用了C+提供的各种标准函数,如abs(),sqrt()等等,这些系统提供的函数为我们编写程序提供了很大的方便。比如:求sin(1)+sin(2)+sin(100)的值。但这些函数只是常用的基本函数,编程时经常需要自定义一些函数。,第一节 函数 前面我们曾经学习了程序设计中的三种基本,例6.1 求:1!+2!+3!+10!,#include,using namespace std;,int main(),int sum=0;,for(int i=1;i=10;i+),sum+=js(i);,coutsum=sumy?x:y;,该函数返回值是整型,有两个整型的形参,用来接受实参传递的两个数据,函数体内的语句是求两个数中的较大者并将其返回主调函数。,2函数定义的例子,3函数的形式,函数的形式从结构上说可以分为三种:无参函数、有参函数和空函数。它们的定义形式都相同。,(1)无参函数,无参函数顾名思义即为没有参数传递的函数,无参函数一般不需要带回函数值,所以函数类型说明为,void,。,(2)有参函数,有参函数即有参数传递的函数,一般需要带回函数值。例如,int max(int x,int y),函数。,(3)空函数,空函数即函数体只有一对花括号,花括号内没有任何语句的函数。,例如,,函数名(),空函数不完成什么工作,只占据一个位置。在大型程序设计中,空函数用于扩充函数功能。,3函数的形式,编写一个阶乘的函数,我们给此函数取一个名字js。,int js(int n),int s=1;,for(int i=1;i=n;+i),s*=i;,return s;,在本例中,函数名叫js,只有一个int型的自变量n,函数js属int型。在本函数中,要用到两个变量i,s。在函数体中,是一个求阶乘的语句,n的阶乘的值在s中,最后由return语句将计算结果s值带回,js()函数执行结束,在主函数中js()值就是s的值。,在这里,函数的参数n是一个接口参数,说得更明确点是入口参数。如果我们调用函数:js(3),那么在程序里所有有n的地方,n被替代成3来计算。在这里,3就被称为实参。又如:sqrt(4),ln(5),这里4,5叫实参。而ln(x),sqrt(x)中的x,y叫形参。,编写一个阶乘的函数,我们给此函数取一个名字js。,二、参数传递-【函数】,1.非引用参数,普通的非引用类型的参数是通过复制对应的实参实现初始化。当用参数副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。举个例子:,#include,using namespace std;,void swap(int a,int b),int tmp=a;a=b;b=tmp;,int main(),int c=1,d=2;,swap(c,d);,coutc dendl;,return 0;,/程序输出为:1 2,在此例中,虽然在swap函数中交换了a,b两数的值,但是在main中却没有交换。因为swap函数只是交换c,d两变量副本的值。,二、参数传递-【函数】1.非引用参数,2.引用参数,引用参数直接关联到其所绑定的对象,而并非这些对象的副本。定义引用时,必须用与该引用绑定对象初始化该引用。引用形参完全以相同的方式工作。每次调用函数,引用形参被创建并与相应实参关联。现在用引用参数来实现swap:,#include,using namespace std;,void swap(int&a,int&b),int tmp=a;a=b;b=tmp;,int main(),i,nt c=1,d=2;,swap(c,d);/交换变量,coutc dendl;,return 0;,/程序输出为:2 1,在此例中,因为swap函数的参数为引用参数,所以,在函数swap中修改a,b的值相当于在主函数main中修改c,d的值。,2.引用参数,3.const形参,使用const修饰参数可避免在函数执行中修改参数。,举个例子:,void solve(const int&a),a=1;,/该函数是错误的,因为a是 const形参,所以在函数体中不能被修改。,使用const修饰参数也可使函数接受常量作为引用参数。,举个例子:,void fa(const int&a),void fb(int&a),int main(),fa(2);/正确,因为fa()使用了常量引用形参。,fb(2);/错误,因为fb()使用了非常量引用形参,不可以接受常量2。,3.const形参,三、函数的声明和调用-【函数】,1函数的声明,调用函数之前先要声明函数原型。在主调函数中,或所有函数定义之前,按如下形式声明:,类型说明符 被调函数名(含类型说明的形参表);,如果是在所有函数定义之前声明了函数原型,那么该函数原型在本程序文件中任何地方都有效,也就是说在本程序文件中任何地方都可以依照该原型调用相应的函数。如果是在某个主调函数内部声明了被调用函数原型,那么该原型就只能在这个函数内部有效。,函数原型和函数定义在返回值类型、函数名和参数个数与类型必须完全一致,否则,就会发生编译错误。下面对max()函数原型声明是合法的。,int max(int x,int y);,也可以:,int max(int,int);,可以看到函数原型声明与函数定义时的第一行类似,只多了一个分号,成为了一个声明语句而已。,三、函数的声明和调用-【函数】1函数的声明,2函数的调用,声明了函数原型之后,便可以按如下形式调用函数:,函数名(实参列表),实参列表中应给出与函数原型形参个数相同、类型相符的实参。在主调函数中的参数称为实参,实参一般应具有确定的值。实参可以是常量、表达式,也可以是已有确定值的变量,数组或指针名。函数调用可以作为一条语句,这时函数可以没有返回值。函数调用也可以出现在表达式中,这时就必须有一个明确的返回值。,2函数的调用,3函数的返回值,在组成函数体的各类语句中,值得注意的是返回语句return。它的一般形式是:,return(表达式);,其功能是把程序流程从被调函数转向主调函数并把表达式的值带回主调函数,实现函数的返回。所以,在圆括号表达式的值实际上就是该函数的返回值。其返回值的类型即为它所在函数的函数类型。当一个函数没有返回值时,函数中可以没有return语句(在TC+和VC+,函数类型定义为void,可以没有return语句;函数类型定义为int,必须有返回值),直接利用函数体的右花括号“”,作为没有返回值的函数的返回。也可以有return语句,但return后没有表达式。返回语句的另一种形式是:,return;,这时函数没有返回值,而只把流程转向主调函数。,3函数的返回值,四、函数的应用举例-【函数】,例6.2 求1!+2!+10!的值。,程序如下:,#include,using namespace std;,nt js(int);,int main(),int sum=0;,for(int i=1;i=10;+i),sum+=js(i);,coutsum=sumendl;,return 0;,int js(int n),i,nt s=1;,for(int i=1;i=n;+i),s*=i;,return s;,四、函数的应用举例-【函数】例6.2 求1!+2!+,例6.,3,任意输入10组三角形的三边,求其面积。,我们可以定义一个已知三角形三边求其面积的函数,设为area(a,b,c)。,程序如下:,#include,#include,using namespace std;,double area(double,double,double);,int main(),f,or(int i=1;i=10;+i),double a,b,c;,coutinput a,b,cabc;,if(a+b=c)|(a+c=b)|(b+c=a),c,outdata error!endl;,/判断三角形是否合法,else couts=area(a,b,c)endl;,return 0;,double area(double a,double b,double c)/此函数为 海伦秦九韶公式,double p=(a+b+c)/2;,return sqrt(p*(p-a)*(p-b)*(p-c);,在函数说明中,如果形参的个数不止一个,那么在程序中调用函数的实参个数一定要与形参的个数一致,第一个实参对应第一个形参,第二个实参对应第二个形参次序不能对调。,例6.3 任意输入10组三角形的三边,求其面积。doubl,例6.,4,定义一个函数check(n,d),让它返回一个布尔值。如果数字d在正整数n的某位中出现则送回true,否则送回false。,例如:check(325719,3)=true;check(77829,1)=false;,#include,using namespace std;,bool check(int,int);,int main(),int a,b;,coutinput n,dab;,if(check(a,b)=true)couttrueendl;,else coutfalseendl;,return 0;,bool check(int n,int d),while(n)/C+中 非0为真,int e=n%10;,n/=10;,if(e=d)return true;,return false;,例6.4 定义一个函数check(n,d),让它返回一个布尔,例6.,5,计算如图多边形的面积。,从图中可以看出,五边形的面积是三个三角形面积之和。,程序如下:,#include,#include /使用printf和scanf语句,调用cstdio库,#include,using namespace s
展开阅读全文