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

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/14028192.html】到电脑端继续下载(重复下载【60天内】不扣币)。

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

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(第 3 章(2)━━函数的递归调用、重载、默认参数.ppt)为本站上传会员【s4****5z】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

第 3 章(2)━━函数的递归调用、重载、默认参数.ppt

1、单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,C+,程序设计,第,3,章,(2),函数的递归调用、重载、默认参数,1,主要内容,函数的递归调用,递归函数的执行过程,函数的重载,重载函数的注意事项,带默认值的形参,内联函数,程序的多文件结构,编译预处理,2,函数的递归调用,函数的递归调用:,直接递归调用:,指在一个函数,A,的定义中,出现了调用自身,A,的情况,这种调用关系称为直接递归调用,而函数,A,就是递归函数。,间接递归调用:,指在一个函数,A,的定义中,调用了函数,B,,,而在函数,B,的定义中又调用了函数,A,,,这种调用关系称为间接递归调用

2、而函数,A,也是递归函数。,递归算法的关键在于:,确立递归的公式,分析递归的结束条件,递归函数设计的一般方法:,先判断递归结束条件,再进行递归调用,3,【,例,】,(,用递归算法求,n!,。,),分析:确立递归公式:,n!=n (n-1)!,分析递归结束条件:当,n=0,或,n=1,时,,n!,的值为,1,。,#include,#include,int,fun (,int,n,),/,函数,fun(),的功能是:求,n!,if (n=0|n=1),return 1,;,/,先判断递归结束条件,return (n*,fun(n-1),),;,/,再进行递归调用,void main(),int,

3、n;,cout,n;,if (n0),cout,“,输入数据有错!”,;,exit(0),;,cout,n “!=”,fun(n),endl,;,运行:,请输入一个正整数:,3 ,3!=6,4,main(),函数,调用,fun(3),时的执行过程:,main(),函数,调用,fun(3),时栈中的变化情况:,局部变量:,n=3,执行:,cout,fun(3),main(),函数,形参变量:,n=3,执行:,return 3*fun(2),fun(3),函数,形参变量:,n=2,执行:,return 2*fun(1),fun(2),函数,形参变量:,n=1,执行:,return 1,fun(1)

4、函数,递推,递推,递推,回归,回归,回归,3,操作系统执行,状态和返回地址,main(),局部变量,n,3,操作系统执行,状态和返回地址,main(),局部变量,n,3,main(),函数执行,状态和返回地址,fun(3),形参变量,n,3,操作系统执行,状态和返回地址,main(),局部变量,n,3,main(),函数执行,状态和返回地址,fun(3),形参变量,n,2,fun(3),函数执行,状态和返回地址,fun(2),形参变量,n,3,操作系统执行,状态和返回地址,main(),局部变量,n,3,main(),函数执行,状态和返回地址,fun(3),形参变量,n,2,fun(3),函

5、数执行,状态和返回地址,fun(2),形参变量,n,1,fun(2),函数执行,状态和返回地址,fun(1),形参变量,n,5,递归函数的执行过程,递归函数的执行过程:,递归函数的执行过程比较复杂,往往都存在着连续的递归调用,其执行过程可分为“递推”和“回归”两个阶段,先是一次一次不断的递推过程,直到符合递归结束条件,然后是一层一层的回归过程。,而其中的每一次递归调用,系统都要在栈中分配空间以保存该次调用的返回地址、参数、局部变量,因此在递推阶段,栈空间一直处于增长状态,直到遇到递归结束条件,然后进入回归阶段,栈空间反向依次释放。,在递归的执行过程中,递归结束条件非常重要,它控制“递推”过程的

6、终止,因此在任何一个递归函数中,递归结束条件都是必不可少的,否则将会一直“递推”下去。导致无穷递归。,递归算法的缺点:,内存消耗巨大,且连续地调用和返回操作占用较多的,CPU,时间。,递归算法的优点:,算法描述简洁易懂。,6,【,例,】,(,分析下面递归函数的执行过程,并给出程序运行结果。),#include,void,sub(,char c,),cout,c;,if (c=a ),return,;,sub(c-1);,cout,c;,return,;,void main(),char,ch,=e;,sub(,ch,);,运行:,e d c b a b c d e,局部变量:,ch,=e,执行

7、sub(e),main(),函数,形参变量:,c=e,执行:,cout,c;,sub(e-1),cout,c,return,sub(e),函数,形参变量:,c=d,执行:,cout,c;,sub(d-1),cout,c,return,sub(d),函数,递推,回归,递推,回归,形参变量:,c=b,执行:,cout,c;,sub(b-1),cout,c,return,sub(b),函数,形参变量:,c=a,执行:,cout,c;,if(c=a)return,sub(a),函数,递推,回归,形参变量:,c=c,执行:,cout,c;,sub(c-1),cout,c,return,sub(c),

8、函数,递推,回归,递推,回归,7,【,例,】,(,用递归算法,计算从,n,个人中选择,k,个人组成一个委员会的不同组合数。,),分析:确立递归的公式:,由,n,人中选,k,人的组合数,=,由,n-1,人中选,k,人的组合数,+,由,n-1,人中选,k-1,人的组合数,分析递归的结束条件:,当,n=k,或,k=0,时,组合数为,1,。,#include,#include,int,comm,(,int,n,int,k,),/,函数,comm,(),的功能是:求,n,人中选,k,人的组合数,if (nk),return 0,;,if (n=k|k=0),return 1,;,/,先判断递归结束条件,

9、return (,comm,(n-1,k),+,comm,(n-1,k-1),),;,/,再进行递归调用,void main(),int,n,k;,cout,n k;,if (n=0|k=0),cout,“,输入数据有错!”,;,exit(0),;,cout,“,由”,n “,人中选,”,k “,人的组合数,=”,comm,(n,k),endl,;,运行:,请输入正整数,n,和,k,:,8 5 ,由,8,人中选,5,人的组合数,=56,8,【,例,】,(汉诺塔问题:有,A,、,B,、,C,三根柱子,,A,柱上有,n,个大小不等的盘子,大盘在下,小盘在上。要求将这,n,个盘子从,A,柱移动到,C

10、柱,在移动的过程中可以借助,A,、,B,、,C,中任何一根柱子,但每次只允许移动一个盘子,且在移动过程中三根柱子上都必须保持大盘在下,小盘在上。),分析:,将,n,个盘子从,A,柱移动到,C,柱可分解为以下三个步骤:,将,A,柱上,n-1,个盘子移动到,B,柱(借助,C,柱),将,A,柱上剩下的一个盘子移动到,C,柱上,将,n-1,个盘子从,B,柱上移动到,C,柱上(借助,A,柱),分析得到,以上三个步骤包含两种操作:,将若干个盘子从一根柱上移动到另一根柱上,用递归函数,hanoi,(),实现。,将,1,个盘子从一根柱上移动到另一根柱上,用函数,move(),实现。,A,柱,B,柱,C,柱,

11、9,#include,void,move(,char get,char put,),/,函数,move(),的功能是:将一个盘子从,get,柱上移动到,put,柱上,cout,get “,柱 ”,put “,柱”,endl,;,void,hanoi,(,int,n,char one,char two,char three,),/,函数,hanoi,(),的功能是:将,n,个盘子从,one,柱移动到,three,柱(借助,two,柱),if (n=1 ),move(one,three),;,return,;,/,先判断递归结束条件,else,hanoi,(n-1,one,three,two,),

12、/,将,one,柱上,n-1,个盘子移动到,two,柱(借助,three,柱),进行递归调用,move(one,three),;,/,将,one,柱上剩下的一个盘子移动到,three,柱上,hanoi,(n-1,two,one,three,),;,/,将,two,柱上,n-1,个盘子移动到,three,柱(借助,one,柱),进行递归调用,10,void main(),int,n;,cout,n;,cout,“,将”,n “,个盘子从,A,柱移动到,C,柱的步骤:”,endl,;,hanoi,(,n,A,B,C,),;,运行:,请输入盘子数:,4 ,将,4,个盘子从,A,柱移动到,C,柱的

13、步骤:,A,柱,B,柱,A,柱,C,柱,B,柱,C,柱,A,柱,B,柱,C,柱,A,柱,C,柱,B,柱,A,柱,B,柱,A,柱,C,柱,B,柱,C,柱,B,柱,A,柱,C,柱,A,柱,B,柱,C,柱,A,柱,B,柱,A,柱,C,柱,B,柱,C,柱,11,函数的重载,函数的重载:,重载的含义:,就是重新赋予新的含义。在,C+,的一个程序中可以用同一个函数名来命名多个函数,这些同名的函数在参数个数、类型上一定有所不同,分别代表不同的函数,当同名的多个函数出现在同一个作用域内时,称为重载函数。,重载的目的:,程序中经常将功能相近的函数在相同作用域内以相同函数名命名,从而形成重载函数,目的是方便使用,

14、便于记忆。,【,例,】,int,add,(,int,x,int,y );,float,add,(,float,x,float,y );,float,add,(,double,x,double,y );,int,add,(,int,x,int,y );,int,add,(,int,x,int,y,int,z );,int,add,(,int,x,int,y,int,z,int,w );,函数名相同,但参数类型不同,函数名相同,但参数个数不同,12,重载函数的注意事项,注意事项:,重载函数的形参必须有所不同:参数个数或参数类型不同。,编译系统是根据实参与形参在类型及个数上的最佳匹配来选择调用哪一个

15、函数。,【,例,】,定义重载函数时,要避免二义性,以免编译系统无法确定到底调用哪一个函数。,【,例,】,int,add,(,int,x,int,y,);,int,add,(,int,a,int,b,);,编译器不以,形参名,来区分。,int,add,(,int,x,int,y );,void,add,(,int,x,int,y);,编译器不以,返回值,来区分。,int,add,(,int,x,int,y,);,int,add,(,char,a,char,b,);,当调用,add(200,A),时,编译器无法确定到底调用哪一个函数。,13,【,例,】,#include,int,add(,int,

16、x,int,y,),/,重载函数,cout,“,正在进行:两个,int,型数据相加,!tt”;,return (x+y),;,float,add(,float x,float y,),/,重载函数,cout,“,正在进行:两个,float,型数据相加,!tt”;,return (x+y),;,double,add(,double x,double y,),/,重载函数,cout,“,正在进行:两个,double,型数据相加,!tt”;,return (x+y),;,void main(),int,a1=5,b1=8;,float a2=5.1,b2=8.1;,double a3=5.2,b3=

17、8.2;,cout,add(a1,b1),endl,;,cout,add(a2,b2),endl,;,cout,add(a3,b3),endl,;,cout,add(2,4),endl,;,cout,add(2.1,4.1),endl,;,cout,add(A,2),endl,;,运行:,正在进行:两个,int,型数据相加,!13,正在进行:两个,float,型数据相加,!13.2,正在进行:两个,double,型数据相加,!13.4,正在进行:两个,int,型数据相加,!6,正在进行:两个,double,型数据相加,!6.2,正在进行:两个,int,型数据相加,!115,14,带默认值的形参

18、默认形参值的作用:,函数声明时可以给形参指定一个默认值,调用时若给出实参,则形参采用实参值,若没有给出相应的实参,则该形参采用预先给出的默认值。,【,例,】,#include,int,add(,int,x=10,int,y=20,),/,带默认形参值的函数,cout,“,正在进行:”,x “+”y “=”;,return (x+y),;,void main(),cout,add(30,40),endl,;,cout,add(50),endl,;,cout,add(),endl,;,cout,add(2,4),endl,;,cout,add(A,1),endl,;,cout,add(A ),e

19、ndl,;,运行:,正在进行:,30+40=70,正在进行:,50+20=70,正在进行:,10+20=30,正在进行:,50+4=54,正在进行:,65+49=114,正在进行:,65+20=85,15,带默认值的形参,带默认值的形参声明顺序:,函数必须按,从右往左,的顺序逐一声明带默认值的形参,且在带默认值的形参右面不能出现不带默认值的形参。只有这样规定后,在函数调用时才不会产生二义性。,【,例,】,int,add,(,int,x,int,y=2,int,z=3,);,当程序中调用,add(10),时,编译器调用,add(10,2,3),。,当程序中调用,add(10,20),时,编译器调

20、用,add(10,20,3),。,int,add,(,int,x=1,int,y,int,z=3,);,当程序中调用,add(10,20),时,编译器无法确定调用以下那一个:,add(10,20,3),或,add(1,10,20),int,add,(,int,x=1,int,y=2,int,z=3,);,当程序中调用,add(),时,编译器调用,add(1,2,3),。,当程序中调用,add(10),时,编译器调用,add(10,2,3),。,当程序中调用,add(10,20),时,编译器调用,add(10,20,3),。,16,带默认值的形参,默认形参值仅能声明一次:,若函数定义在前、调用在

21、后,默认形参值在函数定义时声明;若函数调用在前、定义在后,默认形参值必须在函数原型声明中给出,且在之后该函数定义时,不能再重复指定默认形参值。,【,例,】,#include,int,add(,int,x=1,int,y=2,);,/,带默认形参值的函数原型声明,void main(),cout,add(3,4),endl,;,cout,add(5),endl,;,cout,add(),endl,;,int,add(,int,x,int,y,),/,函数的定义性声明,cout,“,正在进行:”,x “+”y “=”;,return (x+y),;,运行:,正在进行:,3+4=7,正在进行:,5+

22、2=7,正在进行:,1+2=3,17,带默认值的形参,默认形参值的作用域:,同一个函数在相同的作用域内,默认形参值应保持唯一,但在不同的作用域内,可提供不同的默认形参值。,【,例,】,#include,int,add(,int,x=1,int,y=2,),;,/,函数,add(),的全局原型声明,void main(),int,add(,int,x=3,int,y=4,),;,/,函数,add(),局部原型声明,void,fun(),;,/,函数,fun(),的原型声明,cout,add(),endl,;,/,使用局部默认形参值(实现,3+4,),fun();,void,fun(),/,函数,

23、fun(),的定义性声明,cout,add(),endl,;,/,使用全局默认形参值(实现,1+2,),cout,add(10),endl,;,int,add(,int,x,int,y,),/,函数,add(),的定义性声明,cout,“,正在进行:”,x “+”y “=”;,return (x+y),;,运行:,正在进行:,3+4=7,正在进行:,1+2=3,正在进行:,10+2=12,18,内联函数,内联函数:,含义:,函数声明时前面加上,inline,为内联函数,含义是向编译系统建议:编译时在调用处用函数体进行置换,以节省了函数调用时控制转移、参数传递等开销。,实质:,是使用空间换取时间

24、的方法,以加速程序的执行,当出现多次调用同一个内联函数时,程序本身占用的空间有所增加,若内联函数仅调用一次时,并不增加程序本身占用的存储空间。,注意:,对于用户指定的内联函数,编译器是否作为内联函数来处理由编译器自行决定。另外内联函数体内不能有,循环,、,switch,等复杂的结构控制语句。,【,例,】,#include,inline,float,area(,float r,),/,内联函数,return (3.1415*r*r),;,void main(),cout,“,半径,=”3 “n,面积,=”,area(3),endl,;,cout,“,半径,=”5 “n,面积,=”,area(5)

25、endl,;,运行:,半径,=3,面积,=28.2735,半径,=5,面积,=78.5375,19,程序的多文件结构,多文件的程序:,在,C+,中,一个较大的程序通常被分解为若干个源程序文件,然后分别对各个源程序文件单独进行编译,这些源程序文件由一个工程文件进行管理,最后连接成一个完整的程序。,在多文件组成的程序中,一个源程序文件中定义的全局变量或函数,在另外一个源程序文件中被引用前,必须先对该全局变量或函数作外部声明。,外部类型变量的声明格式:,extern,类型 全局变量名,;,外部类型函数的声明格式:,extern,函数的原型声明,;,若一个源程序文件中定义的全局变量或函数,仅限于该源

26、程序文件中使用,不能被程序中的其他源程序文件使用,在定义该全局变量或函数时前面需加上,static,。,内部类型变量的声明格式:,static,类型 全局变量名,;,内,部类型函数的声明格式:,static,函数的原型声明,;,20,【,例,】,(本程序由两个文件组成:,c1.cpp,、,c2.cpp,),/,文件,c1.cpp,内容,#include,int,a=5;,/,定义,a,为一般全局变量,可拓展到外部文件使用,static,int,b=8;,/,定义,b,为静态全局变量,只能在本文件中使用,extern,int,f0(,int,x,);,/,函数,f0(),的外部声明,其定义部分在

27、c2.cpp,中,int,f1(,int,x,int,y,),/,函数,f1(),的定义性声明,可拓展到外部文件使用,cout,“,进入函数,f1(),了,!t”;,return (x+y+a+b),;,extern,int,f2(,int,x,);,/,函数,f2(),的外部声明,其定义部分在,c2.cpp,中,extern,int,f3(,);,/,函数,f3(),的外部声明,其定义部分在,c2.cpp,中,extern,int,f4(,int,x,int,y,);,/,函数,f4(),的外部声明,其定义部分在,c2.cpp,中,void main(),/,cout,f0(7),endl

28、/,此句编译通过,但连接出错,,f0(),仅能在,c2.cpp,中使用,cout,f1(1,2),endl,;,cout,f2(3),endl,;,cout,f3(),endl,;,cout,f4(5,6),endl,;,运行:,进入函数,f1(),了,!16,进入函数,f2(),了,!15,进入函数,f3(),了,!,进入函数,f0(),了,!216,进入函数,f4(),了,!180,21,/,文件,c2.cpp,内容,#include,extern,int,a;,/,全局变量,a,的外部声明,其定义部分在,c1.cpp,中,extern,int,b;,/,全局变量,b,的外部声明,其

29、定义部分在,c1.cpp,中,static,int,f0(,int,x,),/,函数,f0(),的定义性声明,只能在本文件中使用,cout,“,进入函数,f0(),了,!t”;,return (x*x),;,int,f2(,int,x,),/,函数,f2(),的定义性声明,可拓展到外部文件使用,cout,“,进入函数,f2(),了,!t”;,/b+;,/,此句编译通过,但连接出错,,b,仅能在,c1.cpp,中使用,return (x*a ),;,int,f3(,),/,函数,f3(),的定义性声明,可拓展到外部文件使用,cout,“,进入函数,f3(),了,!t”;,return (,f0(

30、a),*a ),;,int,f4(,int,x,int,y,),/,函数,f4(),的定义性声明,可拓展到外部文件使用,cout,“,进入函数,f4(),了,!t”;,return (x*y*a ),;,22,编译预处理,编译预处理:,指源程序文件在被编译之前,由编译预处理程序对其所做的加工处理工作。,编译预处理程序不是,C+,编译程序的组成部分。,编译预处理程序在处理源程序文件时,是将预处理好的程序写入到一个临时文件中,并将该临时文件作为编译程序的输入文件,即编译程序是对该临时文件进行编译,产生目标文件。,编译预处理不会影响源程序文件中的内容。,编译预处理命令:,一律以,#,开头,以回车符

31、结束,末尾不加分号,且单独占用一行。编译预处理命令通常放在源程序文件的开始部分。,编译预处理命令有三种:,包含文件,宏定义,条件编译,23,编译预处理,#include,命令,包含文件:,格式,1,:,#include,格式,2,:,#include,“,文件名,”,处理过程:,将命令中所指定的文件内容嵌入到当前源程序文件的该,#include,命令处,成为当前源程序文件的一个组成部分。,#include,:,表示按标准方式查找,即从,C+,系统目录下的,include,子目录中开始查找所要包含的文件。,C+,的,库函数一般都存放在编译器约定的,include,子目录下,当需要使用库函数时通常

32、采用该格式。,#include,“,文件名,”,:,表示先从当前目录(即当前源程序文件所在的目录)开始查找所要包含的文件,若找不到,再按标准方式查找,到,C+,系统目录下的,include,子目录中继续查找。当需要包含用户自定义的文件时,通常采用该格式。,#include,“,带路径的文件名,”,:,若所要包含的文件既不在,include,子目录中,也不在当前目录中,必须指明文件的路径。,例:,#include,“,E:ABC123file1,”,24,编译预处理,#define,命令,不带参数的宏定义:,格式,1,:,#define,宏名,格式,2,:,#define,宏名 宏体,处理过程:

33、定义一个宏名,若宏名后面跟有宏体,则将其后程序中所有出现该宏名的地方用相应的宏体替换之,这种替换过程称为“宏替换”或“宏展开”。,几点说明:,宏名是一个标识符,通常用大写字母表示,以便与程序中的变量名区别。,宏定义可以出现在程序中的任何位置,宏名的作用域是从定义处开始到文件结尾处结束。若要提前终止宏名的作用域,可使用预处理命令:,#,undef,宏名,在同一个作用域内,同一个宏名不允许定义两次或两次以上,否则编译预处理在进行宏替换时,会出现二义性。,在一个宏定义中可以使用前面已定义过的宏名。,25,编译预处理,#define,命令,宏替换时,只对宏名做简单的替换,不做任何计算,也不做任何语法

34、检查,若宏定义时书写不正确,会得到不正确的结果或编译时出现语法错误。,当宏名出现在字符串中时,编译预处理不进行宏替换。,【,例,】,#include,#define,A,3+5,#define,B,A,*,A,/,替换后:,#define B 3+5*3+5,#define,C,(,A,)*(,A,),/,替换后:,#define C (3+5)*(3+5),#define,D “,A,”,#define,E,“,输出:,t”,void main(),cout,E,“B,南,C,京,A”,endl,;,/,替换后:,cout,“,输出:,t”“B,南,C,京,A”,endl,;,cout,E,

35、A,endl,;,/,替换后:,cout,“,输出:,t”3+5,endl,;,cout,E,B,endl,;,/,替换后:,cout,“,输出:,t”3+5*3+5 ,endl,;,cout,E,C,endl,;,/,替换后:,cout,“,输出:,t”(3+5)*(3+5),endl,;,cout,E,D,endl,;,/,替换后:,cout,“,输出:,t”“A”,endl,;,运行:,输出:,B,南,C,京,A,输出:,8,输出:,23,输出:,64,输出:,A,26,编译预处理,#define,命令,带参数的宏定义:,格式:,#define,宏名,(,形参表,),宏体,形参表,由若干

36、个参数名组成,参数之间以逗号分隔。,宏体,由若干个参数组成的一个式子。,处理过程:,类似于函数的处理过程,先将宏调用中的实参替换宏定义中的形参,即先进行参数的替换,再进行宏替换。,几点说明:,宏名是一个标识符,与后面形参表的左括号之间不得有空格。,所谓参数的替换,是指用宏调用中的每一个实参字符序列去替换宏定义中的相应形参,且只做简单的替换,不做任何计算。,一个宏定义应在一行内定义完,以换行符结束,若多于一行在行尾加上转义符“,”,。,27,【,例,】,#include,#define,PRINT(a),cout,“a=”a,endl,;,#define,print(a,b),cout,“ab=

37、a*b,endl,;,cout,“ab=”a/b,endl,;,void main(),int,x,y;,cout,x y;,PRINT(x),/,替换后:,cout,“a=”x,endl,;,PRINT(y),/,替换后:,cout,“a=”y,endl,;,PRINT(x+y),/,替换后:,cout,“a=”x+y,endl,;,PRINT(1+2),/,替换后:,cout,“a=”1+2,endl,;,print(x,y),/*,替换后:,cout,“ab=”x*y,endl,;,cout,“ab=”x/y,endl,;*/,print(2+6,4+7),/*,替换后:,cout,“

38、ab=”,2+6*4+7,endl,;,cout,“ab=”,2+6/4+7,endl,;*/,运行:,请输入两个整数:,8 5 ,a=8,a=5,a=13,a=3,a b=40,a b=1,a b=33,a b=10,28,编译预处理,条件编译命令,使用宏名作为程序段是否被编译的条件:,格式,1,:,#,ifdef,宏名,格式,3,:,#,if,n,def,宏名,程序段 程序段,#,endif,#,endif,格式,2,:,#,ifdef,宏名,格式,4,:,#,if,n,def,宏名,程序段,1,程序段,1,#else#else,程序段,2,程序段,2,#,endif,#,endif,作用

39、通常源程序中的所有语句都将被编译,但有时希望源程序中的某个程序段只有在满足某种条件时才被编译,而条件不满足时则不被编译,就好像该程序段从源程序中消失了一样,此时可选用上面格式之一来实现有条件的编译。,29,编译预处理,条件编译命令,几点说明:,以格式,1,为例,当源程序中使用,#,ifdef,宏名,程序段,#,endif,结构时,若该程序段要被编译,可在该结构的前面加上一条定义宏名的预处理命令(,#define,宏名,);若该程序段不被编译,则将其前面的宏名定义命令删除掉(,删除,#define,宏名,),这种做法比从源程序中将该程序段整体删除要简单,且不容易出错。,编译时根据宏名是否被定

40、义,决定某程序段是否被编译,这种方法常用于程序调试中。调试程序时,常在程序中加入一些语句来输出调试信息,而调试结束后这些新加入的语句就不再需要了,因此可考虑将这些要加入的语句用条件编译结构括起来一同加入到程序中。,条件编译命令的另一重要用途:,将其应用于被包含的文件中,可实现在一个源程序文件中,若,多次出现,#include“,同一个被包含文件”,命令时,,只有第一次的包含命令起作用,其余的包含命令都不起作用。,30,【,例,】,/,文件,f1.h,中定义了一个求阶乘函数,aaa,(),double,aaa,(,int,n,),/,函数,aaa,(),的功能是:求,n!,double t=1;

41、for (,int,i=1;i=n;i+)t*=i;,return t;,/,文件,f2.h,中定义了一个求组合函数,bbb,(),#include “f1.h”,double,bbb,(,int,m,int,k,),/,函数,bbb,(),的功能是:求,C,m,k,=m!/(k!(m-k)!),return,(,aaa,(m),/(,aaa,(k),*,aaa,(m-k),);,/,文件,f3.cpp,中定义了,main(),函数求:,3!+C,8,5,+7!+C,9,8,+4!,#include,#include“f1.h”,#include“f2.h”,void main(),cout

42、3!+C,8,5,+7!+C,9,8,+4!,),=”;,cout,(,aaa,(3)+,bbb,(8,5)+,aaa,(7)+,bbb,(9,8)+,aaa,(4),),endl,;,编译出错!,在文件,f3.cpp,中文件,f1.h,被包含了两次,函数,aaa,(),出现重复定义,!,31,【,例,】,(上例中的文件,f1.h,、,f2.h,内容修改如下,文件,f3.cpp,内容不变),/,文件,f1.h,中定义了一个求阶乘函数,aaa,(),#,if,n,def,f1,#define f1,double,aaa,(,int,n ),/,函数,aaa,(),的功能是:求,n!,d

43、ouble t=1;,for (,int,i=1;i=n;i+)t*=i;,return t;,#,endif,/,文件,f2.h,中定义了一个求组合函数,bbb,(),#,if,n,def,f2,#define f2,#include “f1.h”,double,bbb,(,int,m,int,k ),/,函数,bbb,(),的功能是:求,C,m,k,=m!/(k!(m-k)!),return (,aaa,(m)/(,aaa,(k)*,aaa,(m-k);,#,endif,32,/,文件,f3.cpp,中定义了,main(),函数求:,3!+C,8,5,+7!+C,9,8,+4!,#include,#include“f1.h”,#include“f2.h”,void main(),cout,“,(,3!+C,8,5,+7!+C,9,8,+4!,),=”;,cout,(,aaa,(3)+,bbb,(8,5)+,aaa,(7)+,bbb,(9,8)+,aaa,(4),),endl,;,运行:,(,3!+C,8,5,+7!+C,9,8,+4!,),=5135,33,

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服