《C++程序设计教程与实验指导》课件第3章 函数_第1页
《C++程序设计教程与实验指导》课件第3章 函数_第2页
《C++程序设计教程与实验指导》课件第3章 函数_第3页
《C++程序设计教程与实验指导》课件第3章 函数_第4页
《C++程序设计教程与实验指导》课件第3章 函数_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章函数3.1函数的递归调用3.2内联函数3.3函数重载3.4带默认参数值的函数3.5变量的存储类别3.6程序实例3.1函数的递归调用一个函数在它的函数体内,直接或间接地调用它自身,称为递归调用。这种函数称为递归函数。

直接或间接调用函数自身的情况如图:

第3章函数f函数调用f函数f1函数调用f2函数f2函数调用f1函数直接调用间接调用这两种递归调用都是无中止地调用自身,显然是不正确的。为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。例3.1用递归的方法求n!分析:计算n!的公式为:1n=1或0y=n*(n-1)!n>1

可以将求n!转化为求(n-1)!,再继续转化为求(n-2)!,到1时应停止递归#include<iostream>usingnamespacestd;longpower(intn);voidmain(){

intn;

longy;

cout<<"inputaintegernumber:";

cin>>n;

y=power(n);

cout<<n<<"!="

<<y<<endl;}第3章函数longpower(intn){

longf;

if(n>1)

f=n*power(n-1);

else

f=1;

returnf;}例3.1的递归过程分析第3章函数例3.2Hanoi塔问题

有三根针A、B、C,A针上有n个盘子,盘子大小不等,大的在下,小的在上,如图所示。要求将这n个盘子从A针移到C针,在移动过程中可以借助B针,每次只能移动一个盘子,并且在移动过程中三根针上的盘子都保持大盘在下,小盘在上。分析:将n个盘子从A针移到C针可以分解为以下三个步骤:(1)将A针上的n-1个盘子借助C针移到B针上;(2)将A针上剩下的一个盘子移到C针上;(3)将B针上的n-1个盘子借助A针移到C针上。第3章函数ABCn-1个盘子的Hanoi问题例3.2Hanoi塔问题源程序#include<iostream>usingnamespacestd;voidMove(charx,

chary);voidHanoi(intn,charone,chartwo,charthree);voidmain(){

intn;

cout<<"请输入盘子数:";

cin>>n;

cout<<n<<"个盘子的移动过程为:"<<endl;

Hanoi(n,'A','B','C');}//函数Move()将一个盘子从x针移到y针voidMove(charx,

chary){

cout<<x<<"-->"<<y<<endl;}第3章函数例3.2Hanoi塔问题源程序(续)//函数Hanoi()将n-1个盘子从one针借助two针移到three针voidHanoi(intn,charone,chartwo,charthree){

if(n==1)

Move(one,three);

else

{

Hanoi(n-1,one,three,two);

Move(one,three);

Hanoi(n-1,two,one,three);

}}第3章函数程序运行结果:A

CA

BC

BA

CB

AB

CA

C

返回运行演示3.2内联函数

内联函数与一般函数的区别在于它不是在调用时发生控制转移,而是在编译时将被调函数体嵌入到每一个函数调用处,节省了参数传递、控制转移等开销。对于一些规模较小、频繁调用的函数可声明为内联函数,能提高程序运行效率。

内联函数的定义:

inline

类型说明符函数名(参数及类型表){函数体}

注意:只有简单的函数才能成为内联函数,如函数体中不能有循环语句和switch语句等。内联函数的定义必须出现在内联函数第一次被调用之前。第3章函数例3.3使用内联函数#include<iostream>usingnamespacestd;inlineintAdd(inta,intb){ intx; x=a+b; returnx;}第3章函数程序运行结果:10+20=3010+50=6050+50=100

返回voidmain(){ inta,b,c; a=10; b=20; c=Add(a,b); cout<<a<<"+"<<b<<"="<<c<<endl; c=Add(a,50); cout<<a<<"+50"<<"="<<c<<endl; c=Add(50,50); cout<<"50+50"<<"="<<c<<endl;}

3.3函数重载

在C++中可以定义多个相同名字的函数,只要它们形参的个数或类型不完全一致即可,编译程序根据实参与形参的类型及个数自动确定调用哪一个同名函数,这就是函数重载,这些同名函数称为重载函数。

例3.4

定义两个函数,分别求两个整数及两个实数的最大值。分析:在C语言中,要定义题中的函数,只能使用两个不同名函数实现,即定义intmax1(intx,inty)doublemax2(doublex,doubley)

在C++中,可通过定义两个重载函数实现,二者同名,如下:

intmax(intx,inty)doublemax(doublex,doubley)第3章函数例3.5源程序#include<iostream>usingnamespacestd;intmax(intx,inty);doublemax(doublex,doubley);voidmain(){ inta=10,b=20,c; doublex=200.3,y=400.6,z; c=max(a,b); z=max(x,y); cout<<c<<""<<z<<endl;}

第3章函数程序运行结果:intfunctionfloatfunction20,400.6

返回intmax(intx,inty){ cout<<"intfunction"<<endl; if(x>y)returnx; else returny;}doublemax(doublex,doubley){ cout<<"floatfunction"<<endl; if(x>y) returnx; else returny;}

3.4带默认参数值的函数3.4.1带默认参数值的函数

在函数的声明或定义中可以预先给出默认的形参值,函数调用时,按从左到右的次序将实参和形参结合,如给出对应的实参,则采用实参值,否则采用预先给出的默认形参值。

例3.6使用带默认参数值的函数求x的n次方(n是正整数)。

第3章函数#include<iostream>usingnamespacestd;doublepower(doublex=10.0,intn=2);voidmain(){ cout<<power(3,5)<<endl; cout<<power(3)<<endl; cout<<power()<<endl;}

doublepower(doublex,intn){ inti; doubles=1.0; for(i=1;i<=n;i++) s*=x; returns;}

3.4带默认参数值的函数3.4.1带默认参数值的函数(续)

注意:默认形参值必须由右向左的顺序定义。如果某个参数有默认值,则其右面的参数必须都有默认值;如果某个参数没有默认值,则其左面的参数都不能有默认值。例如:

intmax(inta,intb=10,intc=20);//正确intmax(inta,intb=10,intc);//错误intmax(inta=5,intb,intc=30);//错误在后两种情况下,调用语句x=max(20,30);会出错!注意:在使用带默认参数值的函数时,只能在函数定义或函数声明中的一个位置给出默认值,不能在两个位置同时给出。还要保证在函数调用之前给出默认值。第3章函数3.4带默认参数值的函数3.4.2带默认参数值函数产生的二义性

例3.7程序第3章函数#include<iostream>usingnamespacestd;intadd(intx=5,inty=6);floatadd(intx=5,floaty=10.0);voidmain(){ inta; floatb; a=add(10,20); b=add(10);

cout<<"a="<<a<<endl; cout<<"b="<<b<<endl;}

intadd(intx,inty){returnx+y;}floatadd(intx,floaty){returnx+y;}

b=add(10)语句产生二义性,可以认为该语句是调用第一个函数,也可以是第二个,因此编译器不能确定调用的是哪一个函数。

返回3.5变量的存储类别3.5.1内部变量与外部变量1.

内部变量在一个函数内部定义的变量是内部变量(也称为局部变量),它只在该函数范围内有效。

例如:

第3章函数voidf1(inta){intb,c;

……} voidmain(){intm,n;

……}a,b,c的有效范围m,n的有效范围inti,a;……for(i=0;i<10;i++){intb;……}

b的有效范围注意:在不同的作用范围内允许声明同名的变量3.5变量的存储类别3.5.1内部变量与外部变量(续)2.

外部变量在函数外部定义的变量是外部变量(也称为全局变量),它不属于任何一个函数。它的作用范围是:从外部变量的定义位置开始,到本文件的结尾。

例如:

第3章函数inta,b;

voidf1(){

……} intx,y;voidmain(){……}x,y的有效范围a,b的有效范围例3.8使用全局变量和局部变量#include<iostream>usingnamespacestd;inti=1;

//全局变量,文件作用域

voidmain(){

cout<<"全局变量i="<<i<<endl;

//输出1

inti=5;

//函数局部变量,块作用域

{

inti;//块局部变量,块作用域

i=7;

cout<<"块局部变量i="<<i<<endl;

//输出7

cout<<"全局变量i="<<::i<<endl;//输出1,::使用全局变量

}

cout<<"函数局部变量i="<<i<<endl;

//输出5

cout<<"全局变量i="<<::i<<endl;//输出1,::使用全局变量

}第3章函数程序运行结果:全局变量i=1块局部变量i=7全局变量i=1函数局部变量i=5全局变量i=1

3.5变量的存储类别3.5.2变量的存储类别变量在内存中的存储方式可以分为两大类,即静态存储方式与动态存储方式。

静态存储方式是指在程序运行期间,分配固定的存储空间。全局变量和静态局部变量是静态存储方式。

动态存储方式是在程序执行过程中,根据需要动态地分配存储空间。局部变量是动态存储方式。

1.

静态变量

定义形式:

static

数据类型变量名

特点:程序运行过程中变量始终存在,每次调用函数结束的值都被保留下来。仅初始化一次,每次调用它所在的函数时,不再重新初始化。若不指定初值,自动指定初值为0。第3章函数例8.9输出1~4的阶乘#include<iostream>usingnamespacestd;intfact(intn); voidmain(){ inti; for(i=1;i<=4;i++) cout<<i<<"!="<<fact(i)<<endl;}intfact(intn){ staticintf=1; //仅在第一次调用函数时执行一次 f*=n; returnf;}第3章函数程序运行结果:1!=12!=23!=64!=24

3.5变量的存储类别3.5.2变量的存储类别(续)2.

自动变量

定义形式:

auto

数据类型变量名

特点:定义变量时,若不指定static或auto,则默认为自动变量。自动变量是动态存储方式。

每次调用它所在的函数时,都要重新分配存储空间,并初始化。函数调用结束,存储空间就释放。若不初始化,则初值是不确定的。第3章函数例3.10静态变量与动态变量的使用#include<iostream>usingnamespacestd;voidother(void);inti=1;//i为全局变量,具有静态生存期。

voidmain(void){ staticinta;//a为静态局部变量,具有全局寿命,局部可见。

intb=-10;//b,c为动态局部变量,具有局部生存期。

intc=0; cout<<"---MAIN---\n"; cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl; c=c+8; other(); cout<<"---MAIN---\n"; cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl; i=i+10; other();}

第3章函数例3.10静态变量与动态变量的使用(续)voidother(void){

//a,b为静态局部变量,具有全局寿命,局部可见,

//只第一次进入函数时被初始化。

staticinta=2; staticintb; intc=10;//C为动态局部变量,每次进入函数时都初始化。

a=a+2; i=i+32; c=c+5; cout<<"---OTHER---\n"; cout<<"i:"<<i<<"a:"<<a<<"b:"<<b<<"c:"<<c<<endl; b=a;}

第3章函数程序运行结果:---MAIN---i:1a:0b:-10c:0---OTHER---i:33a:4b:0c:15---MAIN---i:33a:0b:-10c:8---OTHER---i:75a:6b:4c:15例3.11输出摄氏温度与华氏温度对照表分析:编写一个函数求出指定摄氏温度对应的华氏温度值,在主函数中通过循环求出摄氏温度从0~99度对应的华氏温度值,并输出。转换公式为:

F=9/5*C+32其中F表示华氏温度,C为摄氏温度。程序如下:

#include<iostream>#include<iomanip>usingnamespacestd;intConvert(intc){ intf; f=(int)(9.0/5*c+32); returnf;}第3章函数例3.11(续一)#voidmain(){ cout<<"|0123456789"<<endl; cout<<"---|-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论