ImageVerifierCode 换一换
格式:PPT , 页数:92 ,大小:4.49MB ,
资源ID:5537865      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.docduoduo.com/d-5537865.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(第四章 函数.ppt)为本站会员(涵涵文库)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

第四章 函数.ppt

1、第三章 函数,3.1 函数的定义与调用,3. 5 作用域与标识符的可见性,3.4 函数调用机制,3.3 全局变量和局部变量,3.2 函数的参数传递,返回值及函数声明,3.10 编译预处理,3.9 头文件与多文件结构,3.6 存储类型与标识符的生命期,3.8 函数的一些高级议题,3.7 函数的递归调用,3.1 函数的定义与调用,3.1.1 函数概述,3.1.2 函数的定义,3.1.3 函数的调用,3,1.2 一个C+程序实例,# include using namespace std; / 使用标准库名字 int maxN(int i, int j) /Aif (i=j) return i; e

2、lse return j; int main() /Bcoutij; /从键盘上输入变量值int result=maxN(i, j); /调用max函数 coutresultendl; /输出提示和结果return 0; ,【例1.2】 一个简单的C+程序。,返回值类型,函数名,参数列表,函数体,3.1.1 函数概述,3.1.1结束,函数:具有名字的语句块。 通过调用函数的名字可以执行相应的代码块。,四个要素: 返回值类型(return type),函数名,参数列表(parameter)和函数体(语句块),3.1.2 函数的定义,无参函数定义格式为: 数据类型函数名( )函数体,说明:数据类型

3、指函数返回值类型(通过return 语句将结果返回)。没有返回值应将返回值类型定义为void。函数名采用合法标识符表示。对无参函数,参数括号中的void通常省略,但括号不能省略。函数体由一系列语句组成。函数体可以为空,称为空函数。,1 无参函数,3.1.2 函数的定义,例: 打印一个表头 void printTableHead ( ) cout*endl;cout* example *endl;cout*endl; ,调用函数:通过函数调用操作符“()“ int main() . printTableHead ( ) ; . ,2 有参函数,有参函数的定义格式为 数据类型函数名 (参数类型1

4、形式参数1,参数类型2 形式参数2,函数体,例: 返回两个整数中较大一个的值 int maxN (int a, int b) int x=a=b?a:b; return x; ,参数表:逐个列出所有形式参数(parameter)的类型和参数名称。形式参数简称形参,只能是左值,不允许是常量或表达式。,Why?,int main()int i=maxN(4,8);coutiendl; ,思考:参数和返回值的作用是什么?,找错误,int f()string s;cins;return s; ,/定义一个无返回值的函数 f2(int i)coutiendl; ,int f(int v1,int v2)

5、int x=v1+v2; ,double square(double x) return x*x;,3.1.3 函数的调用,函数调用:所谓函数调用,就是使程序转去执行函数体。说明:除了主函数外,其他任何函数都不能单独作为程序运行。任何函数功能的实现都是通过被主函数直接或间接调用进行的。无参函数的调用格式:函数名( )有参函数的调用格式:函数名(实际参数表) 其中实际参数简称实参(argument),用来将实际参数的值传递给形参,因此可以是常量、具有值的变量或表达式。,【例3.1】 输入两个实数,输出其中较大的数,函数的调用规则,1、调用函数时,函数名必须与调用处的函数名完全一致。 2、实参的个

6、数必须与形参的个数一致。 3、函数必须先定义,后调用。,int add (int x, int y ) int z ;z=x+y;return(z); int main() int a=100,b=200,c ;c =add(a,b);,错误: c=ad(a,b); c=add(a); c=add(“a“,“b“); c=add(4,5,0);,3.2 函数的参数传递、返回值及 函数声明,321 函数的参数传递及传值调用,323 函数声明,322 函数返回值,参数传递:函数调用首先要进行参数传递,参数传递的方向是由实参传递给形参。传递过程是,先计算实参表达式的值(注意求值次序),再将该值传递给

7、对应的形参对象。相对应的实参和形参类型应保持一致(符合赋值兼容的原值).,3.2.1 函数的参数传递及传值调用,传值调用和引用调用: 按照参数形式的不同,两种调用方式:传值调用和引用/指针调用。传值调用传递的是实参的值,本章介绍传值调用。,在调用函数时,一般 在主调函数和被调用函数之间有 信息传递 传递途径之一是由函数中的参数来完成的。,调用函数和被调用函数之间的参数传递,实际参数,形式参数,(实参),(形参),int main() int a=5,b=10, c ;c=maxN(a,b-1);coutcendl;return 0; ,int maxN(int x, int y) int t;

8、if (xy) t=x;else t=y; return t;,10,5,10,t,10,10,10,int main() int a=5,b=10, c ;c=maxN(a,b);printf(“c=%d”,c);return 0; ,信息传递原则:实参到形参 单向值传递,特点:实参与形参各占用不同的内存单元,5,临时对象,3.2.1 函数的参数传递及传值调用,传值调用: 将实参的值复制给形参,在函数中参加运算的是形参,而实参不会发生任何改变。传值调用起了一种隔离作用。,int add (int x, int y) int z ;z=(+x)+(+y) ;return z; int main

9、() int a=100,b=200,c ;c =add(a,b);printf(“c=%d”,c);return 0; ,101,201,A) 11 B) 20 C) 21 D) 31,请写出下列程序的运行结果,int main() int x=6,y=7,z=8,r ;r=f (x-,y+,x+y),z-);printf(“r=%d“,r);return 0;,C) 21,课下作业,查找资料,如何通过主函数main() 传递参数? 程序举例说明。,3.2.2 函数返回值,return语句的格式: return 表达式; 函数的计算结果通过该语句传递回主调函数。,思考:表达式值的类型和函数返

10、回值类型关系?,对于没有返回值的函数,应将返回值类型定义为void ,函数体内可以没有return语句,当需要在程序指定位置退出时,可以在该处放置一个:return ;,函数返回值通过临时对象返回到主调函数,int main() int a=5,b=10, c ;c=maxN(a,b);coutcendl;return 0; ,3.2.3 函数声明,函数声明是一条以分号结束的语句: 函数返回值类型函数名 (形参表);,语法上对程序文件中函数的排列次序要求满足先定义后使用。,其中形参表可以逐个列出每个参数的类型和参数名,也可以列出每个形参的类型,参数名可省略,各形参之间以逗号分隔。函数声明和所定

11、义的函数必须在返回值类型、函数名、形参个数和类型及次序等方面完全对应一致,否则将导致编译错误。,函数声明的引入:,函数声明的格式:,int add(int x, int y); /ok int add(int,int); /ok int add(int) /error float add(int,int); /errorint add(int x, int y) int t;t=x+y; return t;,/ add.cpp,有函数声明 #include using namespace std; int add(int x, int y); / 函数声明 int main() int a=1

12、00,b=200,c ;c =add(a,b);coutcendl;return 0; int add (int x, int y ) int z ;z=x+y;return(z); ,/ add.cpp 无函数声明 #include using namespace std; int add (int x, int y ) int z ;z=x+y;return(z); int main() int a=100,b=200,c ;c =add(a,b);coutcendl;return 0; ,3.2.3 函数声明,3.2.3 函数声明,【例3.4】 输出所有满足下列条件的正整数m:10m10

13、00且m、m2、m3均为回文数。,分析:回文指左右对称的序列。如121、353等就是回文数。判断整数是否回文数用函数实现,其思想是将该数各位拆开后反向组成新的整数,如果该整数与原数相等则为回文数。,运行结果:,3.3 全局变量和局部变量,331 变量的存储机制与C+的内存布局,332 全局变量,333 局部变量,3.3.1 变量的存储机制与C+的内存布局,操作系统为一个C+程序的运行所分配的内存分为四个区域,如图3.3 所示:,#include using namespace std; int x; /全局数据,x为0 static double y; /全局数据,y为0 int main()

14、 int a=20,c ; /局部数据 c为随机值int *p=new int(10); / 堆区return 0; ,3.3.2 全局变量,在所有函数之外定义的变量称为全局变量。,全局变量在编译时建立在全局数据区,在未给出初始化值时系统自动初始化为全0。,全局变量可定义在程序开头,也可定义在中间位置,该全局变量在定义处之后的任何位置都是可以访问的,称为其作用域。,【例3.5】 多个函数使用全局变量的例子。,全局变量引入:,3.3.3 局部变量,定义在函数内或块内的变量称为局部变量。,局部变量在程序运行到它所在的块时建立在栈中,该块执行完毕局部变量占有的空间即被释放。,局部变量在定义时若未初始

15、化就使用是危险的。,局部变量引入:,【例3.6】 使用局部变量的例子。,思考:如何确定一个对象为全局还是局部?,1、函数中定义的对象只用在该函数中有效;2、不同函数中可以使用相同的对象名,且它们代表不同的存储单元,互不干扰;3、形式参数也是局部对象。只能在该函数可见;4、在一个函数内部,可以在语句块中定义对象,这些变量只能在本复合语句中有效。,void fun()int t=5;cout“fun()中的t=“tendl; int main()float t=3.5;cout“main()中的t=“tendl;fun(); for(int i=0;i10;i+)float x=t+i;coutx

16、endl; coutxendl; / errorreturn 0; ,3.4 函数调用过程(略),局部变量占用的内存是在程序执行过程中“动态”地建立和释放的。这种“动态”是通过栈由系统自动管理进行的。,(1)建立栈空间;,(6)恢复现场:取主调函数运行状态及返回地址,释放栈空间;,(7)继续主调函数后续语句。,(5)释放被调函数中局部变量占用的栈空间;,(4)执行被调函数函数体;,(3)为被调函数中的局部变量分 配空间,完成参数传递;,(2)保护现场:主调函数运行 状态和返回地址入栈;,调用过程:,/ add.cpp,有函数声明 #include using namespace std; in

17、t add(int x, int y); / 函数声明 int main() int a=100,b=200,c ;c =add(a,b);coutcendl;return 0; int add (int x, int y ) int z ;z=x+y;return(z); ,3.5 作用域与标识符的可见性,3 文件作用域,2 函数声明作用域,作用域:指标识符能够被使用的范围。只有在作用域内标识符才可以被访问(称为可见)。,下面分别介绍:,1 块作用域,函数中定义的标识符,包括形参和函数体中定义的局部变量,作用域都在该函数内,也称作函数域。,块域,块指一对大括号括起来的程序段。块中定义的标识符

18、,作用域在块内。,复合语句是一个块。,函数也是一个块。,复合语句中定义的标识符,,作用域仅在该复合语句中。,【例3.7】 输入两数,按从大到小的顺序保存。,块的引入:,块域,由VC+平台运行,结果如下: 输入两整数: 3 5 调用前:实参a=3,b=5 调用中 交换前:形参a=3,b=5 交换后:形参a=5,b=3 调用后:实参a=3,b=5 交换失败,局部变量具有局部作用域使得程序在不同块中可以使用同名变量。这些同名变量各自在自己的作用域中可见,在其它地方不可见。,【例3.8】设计函数完成两数交换,用主函数进行测试。,作用域重叠,对于块中嵌套其它块的情况,如果嵌套块中有同名局部变量,服从局部

19、优先原则,即在内层块中屏蔽外层块中的同名变量,换句话说,内层块中局部变量的作用域为内层块;外层块中局部变量的作用域为外层除去包含同名变量的内层块部分。,在块内可以通过域运算符“:”访问同名的全局变量。,【例3.9】 显示同名变量可见性。,函数声明作用域,函数声明不是定义函数,在作函数声明时,其中的形参作用域只在声明中,即作用域结束于右括号。,形参名可省略,why?,3 文件作用域,文件作用域也称全局作用域。定义在所有函数之外 的标识符,具有文件作用域,作用域为从定义处到 整个源文件结束。,如果在一个文件里定义了一个全局对象, 如何在另外一个文件里访问?,存储类型(storage class)决

20、定标识符的存储区域,即编译系统在不同区域为不同存储类型的标识符分配空间。由于存储区域不同,标识符的生命期也不同。所谓生命期,指的是标识符从获得空间到空间释放之间的期间,标识符只有在生存期中、并且在其自己的作用域中才能被访问。,3.6 存储类型与标识符的生命期,一个对象的全部身世: 对象名、类型、内存结构、所支持的操作、生命周期和作用域,自动变量为块内的变量,生命期和作用域是一致的:开始于块的执行,结束于块的结束。 int i=4; ,3.6.1 存储类型,C+中关于存储类型的说明符(storage class specifier):static和extern (auto和register)。

21、注意:auto 在C+11已经被赋予新的含义。 根据表达式值的类型编译器自动推断所定义的对象的数据类型, 如 auto a=10; / a为int类型 vector v1; auto v2=v1; / v2为vector类型,1 自动存储类型(并非auto),static说明的变量称为静态变量。根据定义的位置不同,还分为局部静态变量和全局静态变量。静态变量均存储在全局数据区,如果程序未显式给出初始化值,系统自动初始化为全0,且初始化只进行一次;静态变量占有的空间要到整个程序执行结束才释放,故静态变量具有全局生命期。,3.6.1 存储类型,局部静态变量是定义在块中的静态变量,当块第一次被执行时,

22、执行初始化操作,该空间一直到整个程序结束才释放。局部静态变量具有局部作用域,但却具有全局生命期。,2 静态存储类型,【例3.10】 自动变量与局部静态变量的区别,int f( int a) int b=0;static int c=3;b=b+1;c=c+1;return(a+b+c);,int main() int a=2, i ;for(i=0; i 3; i +)cout f(a)endl; ,举,例,7,8,9,int fun(int a, int b)static int m, i=2;i+=m+1; m=i+a+b;return(m);,int main() int k=4,m=1

23、,p;p=fun(k,m); coutpendl;p=fun(k,m); coutpendl;,0,m,4,k,4,a,练习,1,m,1,b,p,2,i,3,8,8,12,0,17,8,17,8,17,int main() fun(); fun(); ,a0 a1 a2,0,2,4,0,4,8,3.6.1 存储类型,3 外部存储类型,一个C+程序可以由多个源程序文件组成。多文件程序系统可以通过extern关键字来声明已经定义过的对象或函数。,注意:外部的全局变量或函数加上static修饰,就成为静态全局变量或静态函数。静态的全局变量和函数作用域限制在本文件,其他文件即使使用外部声明也无法使用该

24、全局变量或函数。,【例3.11】外部存储类型的例子,全局变量的static: 如果程序是由多个源文件组成时,此静态全局变量的作用域只限于本文件中。,extern int y; int x; int main() ,3.6.2 生命期,生命周期: 对象被分配存储空间时生命周期开始,当对象所在的存储空间被释放时,对象的声明周期结束。,1. 静态生命期(Static storage duration)指的是标识符从程序开始运行时就存在,具有存储空间,到程序运行结束时消亡,释放存储空间。具有静态生命期的标识符存放在全局数据区,如全局变量、静态全局变量、静态局部变量。,/ 文件main.cpp int

25、global=100; static int oneFile=50; int main() . void fun() static int count=10; ,3.6.2 生命期,2. 局部生命期,在块内部定义的对象(static例外)具有局部生命期(Automatic storage duration),其生命期开始于执行到该函数或块的标识符定义处,结束于该函数或块的结束处。具有局部生命期的标识符必定具有局部作用域;但反之不然,静态局部变量具有局部作用域,但却具有静态生命期。,/ 文件main.cpp int global=100; static int oneFile=50; int m

26、ain() int i; void fun() static int count=10; int k=5; ,3.6.2 生命期,具有动态生命期(dynamic storage duration)的标识符存放在自由存储区,用new运算符为变量分配存储空间时,变量的生命期开始,而用delete运算符释放空间或程序结束时,变量生命期结束。关于new运算符和delete运算符将在第七章中介绍。,3. 动态生命期(后面章节介绍),3.7 函数的递归调用,递归是一种描述问题的方法,或称算法。递归的思想可以简单地描述为“自己调用自己”。例如用如下方法定义阶乘:,递归的引入:,递归定义的阶乘函数: int

27、fac(int n)if (n=0|n=1) return 1;else return n*fac(n-1); 只要设计主函数调用阶乘函数,即可实现计算阶乘。,3.7 函数的递归调用,【例3.12】 求4!,运行结果: 4 3 2 1 1 2 6 24 4!=24 说明: cout”n4!=”fac(4)endl; 执行时是先算函数值,然后再从左到右输出各表达式的值。 所以有两行输出,而不是第一行插在第二行赋值号与24之间。,3.7 函数的递归调用,递归的分类: 直接递归: 间接递归:本节只介绍直接递归。递归函数必须定义递归终止条件(Stopping condition),避免无穷递归(Inf

28、inite Recursion)。,void fun() . fun(); . ,void fun1() . fun2(); void fun2() . fun1(); . ,递归函数的执行分为“递推”和“回归”两个过程,这两个过程由递归终止条件控制,即逐层递推,直至递归终止条件,然后逐层回归。每次调用发生时都首先判断递归终止条件。递归调用发生时,递推的过程是一个逐层调用的过程,因此存在一个逐层连续的参数入栈过程,直至遇到递归终止条件时,才开始回归,这时才逐层释放栈空间,返回到上一层,直至最后返回到主调函数。,3.7 函数的递归调用,递归过程的分析:,3.7 函数的递归调用,从以上几例可以看出

29、,递归算法一般不需要借助循环,但通过不断递推和回归的过程实现了其他算法用循环完成的功能。因此,递归的终止条件非常重要,否则将会无休止地递归下去,陷入死循环状态。,【例3.14】 输入一个整数,用递归算法将整数倒序输出,【例3.13】 汉诺塔问题,同其他算法相比,用递归算法编制的程序非常简洁易读,但缺点是增加了内存的开销,在递推的过程中会占用大量栈空间,且连续的调用返回操作占用较多CPU时间。因此是否选择使用递归算法取决于所解决的问题及应用的场合。,3.7 函数的递归调用,3.8 函数的一些特殊议题,3.8.1 函数重载,3.8.2 缺省参数,3.8.3 内联函数,函数模板 引用参数,3.8.1

30、 函数重载,重载的引入: 在C+中,如果需要定义功能相似,而参数类型不同的函数,这些函数可以使用相同的函数名,这就是函数重载。 例: 求和函数对应不同的参数类型可以定义如下几个重载函数: int sum(int a,int b) double sum(double a,double b) float sum(float a,float b,float c),3.8.1 函数重载,重载匹配:匹配过程按如下步骤进行: (1)如果有严格匹配的函数,就调用该函数; (2)参数隐式类型(包括赋值兼容)转换后如果匹配,调用该函数; (3)否则编译器报错处理因此在定义重载函数时必须保证参数类型不同,仅仅返回

31、值类型不同是不行的。函数重载的好处在于,可以用相同的函数名来定义一组功能相同或类似的函数,程序的可读性增强。,【例3.16】 重载函数的应用,3.8.2 缺省参数,缺省参数的引入: 缺省参数指在声明函数(无声明情况,则定义)时为形参指定缺省值(默认值)。这样函数在调用时,既可以使用缺省的参数值或者使用指定的参数值。,【例3.16】 缺省参数,3.8.2 缺省参数,使用要点: 缺省参数可以有多个,但所有缺省参数必须放在参数表的右侧,即先定义所有的非缺省参数,再定义缺省参数。int harp(int m,int n=4,int j=5); /valid int chico(int n,int m=

32、3, int j); /invalid int sosp(int n=9,int m=0,int j=8); /ok int sosp(); /error,一个函数参数的缺省值只能被指定一次,不可以在声明和定义中同时指定缺省值。 int fun(int m=0); /声明 int fun(int m=0) /定义, error . ,习惯上,缺省参数在公共头文件包含的函数声明中指定,否则缺省实参只能用于包含该函数定义的文件中的函数调用。,课下上机完成此例,3.8.3 内联函数,内联函数的引入: 函数调用的时空代价:建立栈空间,保护现场,传递参数以及控制程序执行的转移等等。取消函数调用,直接将函

33、数的代码嵌入到调用处。 缺点:一是相同代码重复书写,大大降低程序的可读性。为了协调好效率和可读性之间的矛盾,C+提供了另一种方法,即定义内联函数,方法是在定义函数时用修饰词inline。,3.8.3 内联函数,请看如下程序段,读入一行字符串,逐个判断是否为数字字符: inline IsNumber(char ch) return ch=0 ,提示:内联函数的定义要放到头文件中,3.10 编译预处理(选读),3.10.1 宏定义指令,3.10.2 文件包含指令,3.10.3 条件编译指令,3.10.1 宏定义指令,1 不带参宏定义 用来产生与一个字符串对应的常量字符串,格式为: #define

34、宏名 常量串 预处理后文件中凡出现该字符串处均用其对应的常量串代替。 例如, #define PI 3.1415926float area,r=1.0; area=PI*pow(r,2);,3.10.1 宏定义指令,2 带参数的宏定义 带参宏定义的形式很象定义一个函数,格式为: #define 宏名 ( 形参表 ) 表达式串 例如作如下宏定义: #define S(a,b) (a)*(b)/2程序中可使用S(a,b),其中S(a,b)被替换成(a)*(b)/2。注意,如果定义: #define S(a,b) a*b/2 那么程序中的S(3+5,4+2)就会被宏展开为3+5*4+2/2,3.10

35、.2 文件包含指令,文件包含用#include指令,预处理后将指令中指明的源程序文件嵌入到当前源程序文件的指令位置处。格式为: #include :用于包含C/C+库文件 #include #include 或 #include “文件名“:用于用 户自定义文件,/避免重定义错误,3.9.1 头文件,多文件程序,作业,1. 局部变量存储在 (1) 区,在 (2) 时候建立,生存期为(3) ,如定义时未显式初始化,则其初值为 (4) 。 2. 设有函数说明如下:f(int x, int y) return x%y+1; 假定a=10,b=4,c=5,下列语句的执行结果分别是 (1) 和 (2)

36、。 (1) cout int a,b; void f(int j) static int i=a; int m,n; m=i+j; i+; j+; n=i*j; a+; printf(“i=%d t j=%d t“,i,j); printf(“m=%dtn=%dn“,m,n); ,int main()a=1; b=2;f(b); f(a);printf(“a=%d t b=%d n“,a,b);return 0; ,作业,4. 下列程序的输出结果为。 #include float sqr(float a)return a*a; float p(float x,int n)printf(“in-

37、process: x=%f t n=%dn“,x,n);if(n=0) return 1;else if(n%2!=0) return x*sqr(p(x,n/2);else return sqr(p(x,n/2); int main()printf(“%f n”,p(2.0,13);return 0; ,上机 实验六 3和4题;实验七1和2题 实验八 2题;实验九1和2题,第三章 函数,再见,谢谢!,3.1.3 函数的调用【例3.1】,main( )函数,调用max(2.5,4.7 ),函数max(2.5,4.7 ),return 4.7,主程序后续语句,【例3.1】 输入两个实数,输出其中

38、较大的数。其中求两个实数中的较大数用函数完成。 程序如下: #include using namespace std; float maxN(float a,float b)return(a=b?a:b); int main() float x,y; coutxy; coutx“和“y“中较大数为“maxN(x,y)endl; return 0; ,形式参数,实际参数,【例3.3】程序: float TriangleArea(float a, float b, float c)if (a+babc;area=TriangleArea(a,b,c);if(area=-1) cout(a,b, c

39、)“不能构成三角形!“endl;else cout“三角形(“a,b,c“)面积为:“areaendl;return 0;,bool palindrome(int n) /判断回文数int digit10; /n=121int m=n,i=0;dodigiti=n%10; n/=10;i+;while(n0);for(int j=0;ji;j+) n=n*10+digitj;return (n=m); ,【例3.4】 输出回文数,3.3.2 全局对象【例3.5】,打印 200,调用 func( ),函数 func( ),200*2 =400,打印 400,n=100,n=100*2 =200,

40、【例3.5】 多个函数使用全局对象的例子。int n=100; void func()n*=2; int main()n*=2;coutnendl;func();coutnendl; return 0;,思考:C+引入全局对象的好处和坏处?,int fun(int n)return n*=2; int main()int n=200;n=fun(n);coutnendl; ,好处:减少参数传递的开销 坏处:程序可读性变差,3.3.3 局部变量,打印main()中的t=3.5,调用 fun( ),函数 fun( ),打印fun()中的t=5,打印main()中的t=3.5,t = 5,【例3.6

41、】 使用局部变量的例子。void fun() int t=5; / fun()中的局部变量 cout“fun()中的t=“tendl; int main() float t=3.5; /main()函数中的局部变量 cout“main()中的t=“tendl; fun(); cout“main()中的t=“tendl; return 0;,注意auto关键字所表示含义和功能在C+11中已经改变,块域【例3.7】,3,5,a=3 b=5,a=5 b=3,【例3.7】 输入两数,按从大到小的顺序保存,并输出结果。,结果,栈,t,= 3,int main() int a,b; /具有函数域couta

42、b;cout=a)int t; /具有块域 t=a; a=b; b=t; /交换a,b的值cout“a=“at“b=“bendl;return 0;,上述程序若在最后一个cout语句处增加: couttendl; 则编译时会提示错误,因为变量t的作用域只在if语句中,其它地方不可见。,思考: 如何通过形参完成两个实参数值的交换?,200 300,内 i= 500,内 j= 600,内n=500+600=1100,1100 500 600,100,200+300=500,500,500 200 300,外部 i=200,外部 j=300,【例3.9】 显示同名变量可见性。int n=100;in

43、t main() int i=200,j=300; cout ntitjendl; /内部块int i=500,j=600,n;n=i+j;cout ntitj endl;/输出局部变量ncout:nendl;/输出全局变量n n=i+j; /修改全局变量 cout ntitj endl; return 0;,【例3.10】 局部变量与局部静态变量的区别 int st()static int t=100; /局部静态变量t+; return t; int at()int t=100; /局部变量t+;return t; int main()int i;for(i=0;i5;i+) coutat

44、()t;coutendl;for(i=0;i5;i+) coutst()t;coutendl;return 0;,3.6.1 存储类型,1,2,3,4,5,101,101,101,101,101,3.6.1 存储类型,1,2,101,3,4,5,102,103,104,105,【例3.10】 局部变量与局部静态变量的区别 int st()static int t=100; /局部静态变量t+; return t; int at()int t=100; /局部变量t+;return t; int main()int i;for(i=0;i5;i+) coutat()=t;coutendl;for

45、(i=0;i5;i+) coutst()t;coutendl;return 0;,【例3.11】外部存储类型的例子。,【例3.12】 求4! #include int fac(int n)int y; coutnt;if(n=0|n=1) y=1; else y=n*fac(n-1);coutyt;return y; int main()cout“n4!=“fac(4)endl;return 0; ,n=4,cout4; y=4*fac(3);,fac(4)=,cout2; y=2*fac(1);,n=2,cout1; y=1; cout1; return 1;,n=1,n=3,cout3;

46、y=3*fac(2);,cout24; return 24;,cout6; return 6;,cout2; return 2;,24,3.7 函数的递归调用【例3.13】,【例3.13】 汉诺塔问题。有A、B、C三根柱子,A柱上有n个大小不等的盘子,大盘在下,小盘在上。要求将所有盘子由A柱搬动到C柱上,每次只能搬动一个盘子,搬动过程中可以借助任何一根柱子,但必须满足大盘在下,小盘在上。打印出搬动的步骤。,分析: 1 A柱只有一个盘子的情况: A柱C柱; 2 A柱有两个盘子的情况:小盘A柱B柱,大盘A柱C柱,小盘B柱C柱。 3 A柱有n个盘子的情况:将此问题看成上面n-1个盘子和最下面第n个盘

47、子的情况。n-1个盘子A柱B柱,第n个盘子A柱C柱,n-1个盘子B柱C柱。问题转化成搬动n-1个盘子的问题,同样,将n-1个盘子看成上面n-2个盘子和下面第n-1个盘子的情况,进一步转化为搬动n-2个盘子的问题,类推下去,一直到最后成为搬动一个盘子的问题。 这是一个典型的递归问题,递归结束于只搬动一个盘子。,3.7 函数的递归调用【例3.13】,3.7 函数的递归调用【例3.13】,算法: 1 n-1个盘子A柱B柱,借助于C柱; 2 第n个盘子A柱C柱; 3 n-1个盘子B柱C柱,借助于A柱; 其中步骤1和步骤3继续递归下去,直至搬动一个盘子为止。由此,可以定义两个函数,一个是递归函数,命名为hanoi(int n, char source, char temp, char target),实现将n个盘子从源柱source借助中间柱temp搬到目标柱target;另一个命名为move(char source, char target),用来输出搬动一个盘子的提示信息。,

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报