33192-00课件cpp09_第1页
33192-00课件cpp09_第2页
33192-00课件cpp09_第3页
33192-00课件cpp09_第4页
33192-00课件cpp09_第5页
已阅读5页,还剩109页未读 继续免费阅读

下载本文档

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

文档简介

,课件制作:C/C+教材编写组哈尔滨理工大学计算中心,基于计算思维,第1章初识C/C+程序设计语言,第2章数据类型、运算符与表达式,第3章顺序结构程序设计,第5章循环结构程序设计,第6章数组,第7章字符串,第8章指针,总复习,第4章选择结构程序设计,课程概述,第9章函数,第11章类与对象自定义数据类型,第12章继承与多态自定义数据类型,第13章C+输入/输出流类库,第14章异常处理,第15章图形界面编程简介,第10章自定义数据类型,函数,第9章,函数是能完成某一特定功能并且可以反复使用的程序模块,也称为子程序。一个C/C+程序由一个主函数和若干个子函数组成。,函数的定义及调用函数的原型函数重载函数参数的缺省函数模板变量的作用域、生存期和存储类别多文件组织结构和名空间,9.1案例剖析,问题的提出:输入3个数,将3个数按从大到小的顺序输出。输出时,如果该数大于等于85,就在该数后面输出字符A;如果该数小于85且大于70,则输出字符B;如果该数小于70且大于等于60,则输出字符C;如果小于60,则输出D。,程序实例:对输入数据的排序并按等级输出,9.1案例剖析,这个任务可以分成3个部分,输入、排序和输出。定义三个全局变量:inta,b,c;输入3个数;可以调用I/O标准库函数完成,即:cinabc;3个数的排序功能可以由排序函数sortabc()完成。if(ab)交换a和b的值;if(b=70)return(B);elseif(x=60)return(C);elsereturn(D);输出分数和等级。分别调用grade()函数,输出返回值。,算法及程序设计分析:,9.1案例剖析,在主函数中分别调用3个函数,就可以完成全部任务。/ch09_1.cpp#includeusingnamespacestd;floata,b,c;voidsortabc()floatt;if(ab)t=a;a=b;b=t;if(b=70)return(B);elseif(x=60)return(C);elsereturn(D);voidputabc()charg;g=grade(a);couta等级gendl;g=grade(b);coutb等级gendl;g=grade(c);coutc等级gbc;sortabc();putabc();return0;,源程序及说明:,输入,排序,输出a,b,c3个数及其相应的等级,9.1案例剖析,程序运行结果:,思考:为什么将a、b,c定义成全局变量?,9.2常用系统函数,例如,程序中要计算一个数的平方根,C+的系统库中提供了几百个函数可供程序员使用。程序员应当了解所使用的C+系统提供了哪些函数,以便根据需要选用。doublesqrt(double);这个函数接受一个双精度类型的数值,返回一个双精度值来表示所求的平方根。如:coutThesquarerootof100.0issqrt(100.0);当程序被编译时,编译器自动在c+系统目录中查找相应的头文件,并将其嵌入到程序中。,在程序中使用:sqrt(),C+系统库中提供的函数说明为:,这个函数的原型说明在头文件cmath中,9.2常用系统函数,常用数学函数,按功能不同,C+提供的系统函数分别放在不同的头文件文件中。例如,常用数学函数(如求指数函数、对数函数、绝对值函数、三角函数、平方根函数等)放在cmath中,如表9-1;字符串处理函数(如求字符串长度、字符串连接、字符串拷贝、字符串比较等)放在cstring中等。,表9-1常用数学函数,9.2常用系统函数,使用系统函数时应注意以下问题,首先要了解C+开发环境提供了哪些系统函数。不同的编译系统提供的系统函数不同,因此使用时需要查阅系统函数的参考手册或联机帮助,清楚每个函数的功能、名称、参数及函数返回值的使用方法,以便根据需要选用。要了解系统函数在哪个头文件中。各头文件中给出了各类函数的原型说明。使用时,需在程序中用#include命令嵌入相应的头文件,否则调试程序时产生编译错误。,/ex09_1.cpp#include#include#includeusingnamespacestd;voidmain()intalphas,digits,spaces,others;chars80;intnum;alphas=digits=spaces=others=0;cout输入一串字符(可含空格):;cin.getline(s,80);,例9.1,9.2常用系统函数,从键盘输入一个字符串,统计输出其中字母、数字、空格和其他字符的个数及字符总个数。,字符串函数头文件,字符处理函数头文件,各种字符计数器,输入以回车作为结束的一行字符,num=strlen(s);for(inti=0;inum;i+)if(isalpha(si)alphas+;elseif(isdigit(si)digits+;elseif(isspace(si)spaces+;elseothers+;cout字符总数为:numendl;cout所含字母个数为:alphasendl;cout所含数字个数为:digitsendl;cout所含空格符个数为:spacesendl;cout其他字符个数为:othersendl;,例9.1,9.2常用系统函数,计算s中的字符个数,判断si中的字符是否为字母,判断si中的字符是否为数字,判断si中的字符是否为空格,程序运行结果,9.2常用系统函数,/ex09_2.cpp#include#include#includeusingnamespacestd;intmain()constdoublepi=3doublea=90;coutsin(a)=sin(a/360*2*pi)endl;coutcos(a)=cos(a/360*2*pi)endl;coutsqrt(a)=sqrt(a)endl;coutpow(a,2)=pow(a,2)=70)return(B);elseif(x=60)return(C);elsereturn(D);,例如:,函数的返回值是字符型,grade为函数名,floatx为参数的类型和标识符,将返回值返回到调用处,9.3自定义函数,说明,类型:就是该函数的类型,也就是该函数的返回值的类型,可以是普通类型、指针类型和引用类型等。函数名:是一个有效的C+标识符。在函数名后面必须跟一对小括号“()”。形式参数表:写在函数名后面的一对圆括号内。可包含任意多个(含0个)参数说明项,参数说明项之间必须用逗号分开。每个参数说明项由一种已定义的数据类型和一个变量标识符组成,该变量标识符称为该函数的形式参数,简称形参。函数体:是一条复合语句。它以左花括号开始,到右花括号结束,中间为一条或若干条C+语句,用于实现函数执行的功能。,9.3自定义函数,return语句,当一个函数执行后需要将一个值带回到调用函数时,可以使用return语句。return语句的形式为:return表达式;或:return;,注意:return语句中的表达式值就是所求函数值。当此表达式值的类型与函数返回值的不一致时,则以函数类型为准,由系统自动进行转换。,/ex09_3.cpp#includeusingnamespacestd;intfunc(intn)if(n0)return1;elseif(n=0)return0;elsereturn-1;,例9.3:给出以下程序的运行结果,9.3自定义函数,intmain()intn;coutn;coutntheresult:func(n)t)t=c;returnt;,例9.4:分析函数调用过程。,9.3自定义函数,voidmain()intx,y,z;coutxyz;intm=max(x,y,z);coutThemaxis:mendl;,返回计算结果,函数调用并获得返回值,9.3自定义函数,函数嵌套调用,C+函数不能嵌套定义,但允许嵌套调用。,例如:func1(inta,floatb)floatc;c=func2(b-1,b+1);intfunc2(floatx,floaty)函数体func1()和func2()是分别独立定义的函数,互不从属。,/ex09_5.cpp#includeusingnamespacestd;longfact(intn);longsum(intn);intmain()longs;s=sum(9);cout1!+3!+5!+7!+9!=sendl;return0;,例9.5:求表达式1!+3!+5!+7!+9!之和。,9.3自定义函数,longsum(intn)longs=0;for(inti=1;i1;n-)f*=n;returnf;,函数的声明,被调用函数出现在主调函数之后时需进行函数声明,9.3自定义函数,分析与说明,程序定义了3个函数:主函数main()、求和函数sum()、求阶乘函数fact()。它们在定义格式上互相独立,在执行任务时又通过一定的调用语句互通有无,从而顺利完成整个任务。程序从main()函数开始执行,在main()函数中调用sum()函数;sum函数又调用fact()函数。这就是函数的嵌套调用。具体调用过程如图9-9所示。,9.3自定义函数,函数递归调用,利用函数的递归调用,可将一个复杂问题分解为一个相对简单且可直接求解的子问题(“递推”阶段);然后将这个子问题的结果逐层进行回代求值,最终求得原来复杂问题的解(“回归”阶段)。,/ex09_6.cpp#includeusingnamespacestd;longf(intn)if(n0)couterror!endl;return(-1);elseif(nn;coutn!=f(n)n;g=gcd(m,n);coutm和n的最大公约数是gendl;return0;,例9.7:用递归算法求最大公约数。,9.3自定义函数,intgcd(inta,intb)if(0=b)returna;elsereturngcd(b,a%b);,9.3自定义函数,函数的参数传递,函数可以从函数之外获得所需数据,也可以将处理的结果返回给函数的调用者。这些数据交换主要是通过函数的参数和返回值传递实现的。在C+中实参和形参有三种结合方式,分别为:值传递地址传递引用传递,9.3自定义函数,值传递,实参与形参值传递是单向的传递,调用时实参仅将其值赋给形参,因此在被调用函数中,对形参值的任何修改都不会影响到实参的值。参数值传递减少了调用函数和被调用函数之间的数据依赖,增强了函数自身的独立性。,/ex09_8cpp#includeusingnamespacestd;#definePI3.14159voidCircleFun(doubleradius,doubleperim,doublearea)perim=2*PI*radius;area=PI*radius*radius;coutperim=perim,area=areaendl;,例9.8:用一个函数计算圆的周长和面积。,9.3自定义函数,intmain()doublep=0,a=0;CircleFun(10,p,a);cout“圆的周长=”p“,面积=aendl;return0;,9.3自定义函数,分析与说明,函数被调用前形参不占内存,当实参的值传递给形参时,形参才占有内存,存储的是实参值的一个备份,在被调用函数中改变形参中的值时,改变的是这个备份中的值,实参的值不受影响。如下图所示。,9.3自定义函数,地址传递,地址传递是一种“特殊”的值传递,实参传递给形参的是在调用函数中有实际意义的地址,形参变量接受了的地址值,则形参与实参在同一存储区。当形参变量所指向的存储空间中的值发生了改变,相应的实参值随之改变。,/ex09_9.cpp#includeusingnamespacestd;#definePI3.14159voidCircleFun(doubleradius,double*pPerim,double*pArea)*pPerim=2*PI*radius;*pArea=PI*radius*radius;,例9.9:地址传递方式计算圆的周长和面积。,9.3自定义函数,intmain()doublep=0,a=0;CircleFun(10,9.3自定义函数,分析与说明,程序中定义的函数CircleFun()的功能是计算圆的周长和面积,三个形参变量中,radius是普通变量,pPerim和pArea是指针变量。实参对应的是一个常量和两个变量的地址。当程序运行到调用CircleFun()函数时,将常量10传递给radius,p和a的地址#definePI3.14159voidCircleFun(doubleconst,例9.10:引用传递方式计算圆的周长和面积。,9.3自定义函数,intmain()doublep=0,a=0;CircleFun(10,p,a);cout圆的周长=p,面积=a1;day-)coutpeach;add1(peach)*=2;coutpeachendl;cout“猴子第”day“天摘下peach个桃子endl;return0;,把多吃的一个加上,把当天吃的一半加上,9.3自定义函数,分析与说明,程序中定义的函数add1的形参ref是引用,其功能是使引用的变量增1,函数的返回值是ref引用的变量的引用。当程序运行到add1函数时,用主调函数中的变量peach初始化引用类型的形参ref。add1函数内,ref增1,实际是主调函数中的peach增1。add1函数的返回值是peach的引用。程序返回到主调函数后,对add1函数的调用进行乘复合赋值运算,实际是对peach进行的运算。通过以上的分析,可以看出,增1和乘2都是对peach进行的。在定义返回引用的函数时,注意不要返回函数的非引用类型形参的引用,也不要返回函数内定义的变量的引用。因为函数的形参和函数内定义的变量在函数调用结束后就结束它们的生存期,释放存储空间。所返回的引用也就成了无效的引用。,9.3自定义函数,函数的默认参数,在调用函数时,可能会要填写很多的参数,如果我们也将函数的参数预置好,那么我们同样可以不必填写参数就能让函数运作起来。这些预置的参数称为默认参数。,/ex09_12.cpp#includeusingnamespacestd;voidcreate(intn=100);intmain()create();create(5);return0;,例12:定义默认参数示例。,9.3自定义函数,voidcreate(intn)cout要创建n个空间endl;,在函数声明中定义默认参数,默认实参为100,人工设置实参,假设该函数的作用是创建空间,注意:当调用create()函数,不填写参数时,系统自动将参数n设置为100;而当实参有值时,以正常形式传递执行。,9.3自定义函数,函数的默认参数,在定义默认参数时,必须在函数声明中定义。当对多个参数设置默认参数时,需要注意默认参数的设置顺序。定义默认参数的方向是从右向左的,即以最后一个参数定位的;而匹配调用参数的方向是从左向右的,即以第一个参数定位的。如果要定义默认参数,那么必须从最后一个参数定义起,并且逐渐向前(左)定义,不可以跳过某个参数。如果调用一个定义了默认参数的函数,那么填写的第一个实参一定是和最左边形参匹配,并且逐渐向后(右)匹配,不可以中途省略某一个参数,直到所有未被设置默认值的形参都已经有参数。,9.3自定义函数,函数的声明,函数声明也称函数模型(或函数原型)。在主调函数中,如果要调用另一个函数,则须在本函数或本文件中的开头将要被调用的函数事先作一声明。声明函数的目的,就是告诉编译器函数的返回类型、名称和形参表构成,以便编译系统对函数的调用进行检查。函数声明的一般格式为:函数类型函数名(形式参数表);,/ex09_13.cpp#includeusingnamespacestd;intf1(void),f2(void),f3(void);intmain()coutthisismain()n;coutf1()endl;return0;intf1(void)coutthisisf1()n;coutf3()endl;return1;,例13:分析该程序并输出结果。,9.3自定义函数,intf2(void)coutthisisf2()n;return2;intf3(void)coutthisisf3()n;coutf2()ab;coutThemaximumismax(a,b)=0?x:-x;doubleabs(doublex)returnx=0?x:-x;,例15:根据参数类型重载函数。,9.5函数重载,intmain()inta=21;longb=345678;doublec=-3.14159265;cout|a|=abs(a)endl;cout|b|=abs(b)endl;cout|c|=abs(c)endl;cout|c|=abs(c)endl;cout|3.2|=abs(3.2)endl;return0;,调用intabs(int),调用longabs(long),调用doubleabs(double),调用intabs(int),调用doubleabs(double),/ex09_16.cpp#includeusingnamespacestd;intfun(inta,intb)returna+b;intfun(inta)returna*a;,例16:根据参数个数重载函数。,9.5函数重载,intmain()coutfun(2,3)=fun(2,3)endl;coutfun(2)=fun(2)y)?x:y;,9.6函数模板,函数模板,这两个函数的功能相同,只是参数的类型和函数返回值的类型不同。为了减少程序代码的书写量,避免相同信息的重复,将上面程序段中的类型int和double参数化,即将int和double用一个参数T代替。这样,便得到下面通用的代码段:Tmax(Tx,Ty)return(xy)?x:y;当需要求某两个整数的最大值时,系统将通用代码段中的T换成int;求两个实数的最大值时,将T换成double,就可以得到上边的函数。,9.6函数模板,函数模板一般格式,temple类型函数名(形参表)函数体其中T代表在函数模板中使用的通用类型,既可以代表系统提供的基本数据类型,也可以代表用户自定义类型。函数模板不是一个完全的函数。它是一类函数的抽象,使用时将它的模板参数T实例化后,即可实现具体的函数。,9.7变量的作用域、生存期和存储类别,变量的作用域、生存期和存储类别,程序中每一个变量都有各自的作用域(scope)、生存期(storageduration)和存储类别(storageclass)。作用域指明变量的有效范围生存期指变量分配到内存空间到释放内存空间所经历的时间存储类别指明了变量的存储形式,9.7变量的作用域、生存期和存储类别,变量的作用域,一个标识符在程序中能够被引用的那个区域称为作用域。C+中有5种作用域分别为:文件作用域块作用域函数作用域函数原型作用域类作用域。,9.7变量的作用域、生存期和存储类别,变量的作用域,文件作用域有如下程序段:inti;voidfun_a()i+;intmain()i=20;fun_a();couti=endl;,/全局变量i定义在函数外,拥有文件作用域,其作用域从说明点开始,在文件结束处结束,/在子函数中访问变量i,/在主函数中访问变量i,9.7变量的作用域、生存期和存储类别,变量的作用域,块作用域块作用域中说明的变量称作局部变量。函数的形参具有块作用域,在函数中定义的变量也具有块作用域,它们都是局部变量,作用域从定义开始到函数结束。,/ex09_17.cpp#includeusingnamespacestd;inti;/全局变量i具有文件作用域voidf(intj)cout在函数f内:i=if:,例17:全局变量和局部变量可见性演示。,9.7变量作用域、生存期和存储类别,intmain()i=5;inti;i=7;couti=it,/输出全局变量i的值和地址,/块作用域,/局部变量i赋值,/输出局部变量i的值和地址,/块作用域终止,/输出全局变量i的值和地址,/输出全局变量i的值和地址,9.7变量的作用域、生存期和存储类别,变量的作用域,函数作用域具有函数作用域的标识符在该函数内的任何地方可见。在c+中,goto语句的标号具有函数作用域。因此,标号在一个函数内必须唯一,在函数中说明了两个同名的标号是错误的。函数原型作用域只有在函数原型声明参数表中声明的标识符才具有函数原型的作用域,该作用域终止于函数原型声明的末尾。在函数原型声明中,不要求写出形参的名称,只要求给出类型,因此编译程序会忽略这些名称。,9.7变量的作用域、生存期和存储类别,变量的生存期和存储类别,动态生存期自动变量:关键字auto作存储类别的声明,可以省略例如,在函数体中:autointa;intb,c;/b和c也是自动变量。寄存器变量:寄存器变量用关键字register定义例如:registerintd;形式参数:形参可以是自动变量,也可以是寄存器变量。例如:voidfun(registerinta,autointb),9.7变量的作用域、生存期和存储类别,变量的生存期和存储类别,静态生存期静态局部变量:在局部变量的定义前加上static存储类别的声明就构成了静态局部变量。静态局部变量具有以下特点:静态局部变量的定义及赋初值语句写在函数内,作用域与自动变量相同。静态局部变量属于静态存储方式,具有静态生存期,即生存期为整个程序。静态局部变量在它的整个生存期内只初始化一次。第一次调用静态局部变量所在的函数时,静态局部变量保存着初始值,调用结束后,静态局部变量继续存在,变量的值不丢失。再次调用该函数时,静态局部变量不再赋初值,继续保存着前一次调用后留下的值。,/ex09_18.cpp#includeusingnamespacestd;voidpeach()inta=1;staticintb=1;coutab0;day-)peach();return0;,/ex09_19.cpp#include#includeusingnamespacestd;voidfib(boolnewline)statica(1),b(1);coutsetw(8)asetw(8)b;if(newline)coutendl;a+=b;b+=a;,例19:输出Fibonacci数列30个数。,9.7变量作用域、生存期和存储类别,intmain()for(inti=1;i=15;i+)fib(!(i%3);return0;,控制每行输出数的个数为6个数,9.7变量的作用域、生存期和存储类别,变量的生存期和存储类别,静态生存期外部变量:外部变量(即全局变量)分配在静态存储区,具有静态生存期。有时需要用extern来声明外部变量,以扩展外部变量的作用域。在一个文件内声明外部变量外部变量的有效范围只限于定义处到文件结束,如果在定义点之前使用,则应使用extern对该变量作“外部变量声明”,表示该外部变量是已经定义的外部变量。在多文件程序中声明外部变量。一个C+程序可以由多个源程序文件组成。当一个文件中定义的函数引用另一个文件中定义的外部变量时,需要在函数所在的文件中,使用extern对相应变量进行声明。,程序文件一:/ex09_20_1.cpp#includeusingnamespacestd;voidfun();externdoublegLength,gWidth,gPerim,gArea;intmain()gLength=5;gWidth=6;fun();cout周长=gPerim,面积=gAreaendl;return0;doublegLength,gWidth,gPerim,gArea;,程序实例20:通过外部变量的定义与声明计算矩形的周长和面积。,9.7变量作用域、生存期和存储类别,函数声明,外部函数,声明外部变量,文件内扩展,定义外部变量,程序文件二:/ex09_20_2.cppexterndoublegLength,gWidth,gPerim,gArea;voidfun()gPerim=2*(gLength+gWidth);gArea=gLength*gWidth;,程序实例20:通过外部变量的定义与声明计算矩形的周长和面积。,9.7变量作用域、生存期和存储类别,声明外部变量,扩展到其他文件,外部函数,9.7变量的作用域、生存期和存储类别,变量的生存期和存储类别,静态生存期静态全局变量:在全局变量的定义前加上static存储类别的声明就构成了静态全局变量,也称为静态外部变量。静态全局变量的存储方式和生存期与外部变量相同。两者不同之处在于作用域的扩展上。静态全局变量只能在文件内扩展,不能扩展到其他文件。例如:在file1.cpp中定义的静态全局变量,只能在文件内扩展:externintx;/可以在文件内扩展staticintx;/静态全局变量在file2.cpp中,就不能声明使用外部变量:externintx;/编译能通过,连接时出错,9.8多文件组织结构及编译预处理,多文件组织结构,不同源文件之间的函数调用源文件之间的访问分为两种情况,源文件之间对全局变量的访问以及源文件之间对函数的访问。源文件之间对全局变量的访问如果在本文件中声明的全局变量属于本文件私用,也就是说,不允许别的文件访问,则需要在全局变量类型前加标识符static。源文件之间对函数的访问函数是具有文件作用域的函数。对它的访问和全局变量类同。如果不允许别的文件访问,在函数或函数原型声明前加标识符static。如果要用到其他的文件中允许访问的函数,应先按照要做一个函数原型声明。加一个标识符extern以表明这个函数是外来的,已在别的文件中声明。,9.8多文件组织结构及编译预处理,多文件组织结构,多文件的编译和连接两种方法实现:文件包含工程文件文件包含的方法使用标准库的“头文件”,也可以自己定义头文件,自定义的头文件应以.h结尾。自定义的头文件可以用#include来包含。使用工程文件的方法将多个源文件添加在一个工程文件中。新建项目,将所写的多个源文件(.cpp)添加到该项目中,然后依次打开各个源文件(.cpp),对项目进行编译、连接,生成可执行文件。,9.8多文件组织结构及编译预处理,编译预处理,C+提供的预处理功能主要有以下3种:宏定义文件包含条件编译可以在C+源程序中加入一些“预处理命令”(preprocessordirectives),以改进程序设计环境,提高编程效率。预处理命令是C+统一规定的,但是它不是C+语言程序本身的组成部分,不能直接对它们进行编译(因为编译程序不能识别它们)。,为了与一般C+语句相区别,这些命令以符号“#”开头,而且末尾不包含分号。,9.8多文件组织结构及编译预处理,编译预处理,文件包含文件包含是指,一个源文件可以将另一个源文件的全部内容包含进来。文件包含的格式include包含文件名或:include两种格式的区别:使用双引号:系统首先到当前目录下查找被包含文件,如果没找到,再到系统指定的“包含文件目录”(由用户在配置环境时设置)去查找。使用尖括号:直接到系统指定的“包含文件目录”去查找。,9.8多文件组织结构及编译预处理,编译预处理,文件包含文件包含的优点一个大程序,通常分为多个模块,并由多个程序员分别编程。有了文件包含处理功能,就可以将多个模块共用的数据(如符号常量和数据结构)或函数,集中到一个单独的文件中。这样,凡是要使用其中数据或调用其中函数的程序员,只要使用文件包含处理功能,将所需文件包含进来即可,不必再重复定义它们,从而减少重复劳动。,9.8多文件组织结构及编译预处理,编译预处理,文件包含编译预处理时,预处理程序将查找指定的被包含文件,并将其复制到#include命令出现的位置上。常用在文件头部的被包含文件,称为“标题文件”或“头部文件”,常以“h”(head)作为后缀,简称头文件。在头文件中,除可包含宏定义外,还可包含外部变量定义、结构类型定义等。一条包含命令,只能指定一个被包含文件。如果要包含n个文件,则要用n条包含命令。文件包含可以嵌套,即被包含文件中又包含另一个文件。,9.8多文件组织结构及编译预处理,编译预处理,#define宏定义可以用#define命令将一个指定的标识符(即宏名)来代表一个字符串。定义宏的作用一般是用一个短的名字代表一个长的字符串。它的一般形式为:#define标识符字符串这就是已经介绍过的定义符号常量。如:#definePI3.1415926,9.8多文件组织结构及编译预处理,编译预处理,还可以用#define命令定义带参数的宏定义。其定义的一般形式为:#define宏名(参数表)字符串例如:#defineS(a,b)a*b/定义宏S,a、b为宏的参数使用的形式如下:area=S(3,2)用3、2分别代替宏定义中的形式参数a和b,即用3*2代替S(3,2)。因此赋值语句展开为:area=3*2;,9.8多文件组织结构及编译预处理,编译预处理,条件编译一般格式#ifdef宏名程序段1;#else程序段2;#endif功能:当宏名已经被#define命令定义过,则编译程序段1;否则编译程序段2。如果没有程序段2(它为空),即可以写为:#ifdef宏名程序段#endif,9.8多文件组织结构及编译预处理,编译预处理,条件编译关于#ifndef#endif命令格式与#ifdef#endif命令一样,功能正好与之相反。#ifndef宏名程序段1#else程序段2#endif它的功能是:如果宏名未被#define命令过,则对程序段1进行编译,否则对程序段2进行编译。这与第一种形式的功能正相反。,9.8多文件组织结构及编译预处理,编译预处理,条件编译关于#if#endif命令#if常量表达式程序段1#else程序段2#endif它的功能是:如果常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。,9.8多文件组织结构及编译预处理,编译预处理,条件编译说明:条件编译允许只编译源程序中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销并提高了程序的效率。利用条件编译,还可使同一源程序即适合于调试(进行程序跟踪、打印较多的状态或错误信息),又适合高效执行要求。,9.8多文件组织结构及编译预处理,内部函数与外部函数,内部函数内部函数又称静态函数,只能在定义它的文件中被调用,而不能被其他文件中的函数所调用。在函数定义前面使用static关键字,内部函数定义形式为:static类型标识符函数名(形参表)例如:staticintfun_a(intx,inty);,9.8多文件组织结构及编译预处理,内部函数与外部函数,外部函数在定义函数时,如果在函数类型前冠以关键字extern,则表示此函数是外部函数,可供其他文件调用。如函数首部可以写为:externintfun(inta,intb);这样,函数fun就可以为其他文件调用。如果在定义函数时省略extern,则默认为外部函数。在需要调用此函数的文件中,用extern声明所调用的函数是外部函数。,9.9名空间,定义名空间的机制,定义作用域的机制,在名空间定义中,不仅可以放置传统上C和C+的全局变量的定义和外部函数的声明或定义,而且可以包含常量的定义、类的定义、嵌套的名空间定义等等。例如:namespaceAvoidf(int);voidf(char);voidf(double);classstring/*/,9.9名空间,定义名空间的机制,原始的名空间定义和所有对它的扩展定义合并成一个名空间。访问名空间的成员采用名空间名加作用域运算符“:”的方式,即:名空间名:成员名例如:A:strings1=”哈尔滨理工大学计算中心”;voidg()A:f(A:PI);,9.9名空间,为名空间的名字声明局部别名的机制,有时名空间的名字可能很长,不便于记忆和使用。这种情况下,可以采用名空间的名字声明局部别名的机制。例如:namespacea_very_long_namespace_name可以用如下形式为长名空间名a_very_long_namespace_name声明别名,即namespaceAVLNN=a_very_long_namespace_name;AVLNN成为名空间a_very_long_namespace_name的别名,可以使用别名访问其成员。,9.9名空间,用using声明语句机制,可以用using声明语句指定被访问的名空间成员,允许不显示地写出名空间的名字,从而简化了访问名空间成员的形式。例如:,namespaceBvoidf(int);voidf(double);namespaceCvoidf(int);voidf(double);voidf(char);,voidh()usingB:f;f(1);f(5.234);usingC:f;f(h);f(6);,using声明语句:引入B:f(int)和:f(double),调用B:f(int),调用B:f(double),using声明语句:引入C:f(int),C:f(double)andC:(char),调用C:f(char),错误:调用B:f(int)还是C:f(int),9.9名空间,用using命令的机制,用using命令可以使指定名空间的全体成员能够直接访问,从而简化了访问名空间成员的形式。例如:,namespaceDintd1;voidf(int);voidf(char);usingnamespaceD;intd1;/与D:d1不冲突namespaceEinte;voidf(int);,namespaceDintd2;usingnamespaceE;voidf(int);voidf()d1+;:d1+;D:d1+;d2+;e+;f(a);f(1);,名空间扩展,允许与该名空间的原声明重复,错误:是d1还是D:d1?,正确:引用全局变量d1,正确:引用名空间D的d1,正确:引用名空间D的d2,正确:引用名空间E的e,正确:引用D:f(char),错误:是D:f(int)还是E:f(int)?,/ex09_21.cpp#includeusingnamespacestd;intmyInt=98;namespaceExampleconstdoublePI=3.14159;constdoubleE=2.71828;intmyInt=8;voidprintValues();namespaceInnerenumYearsFISCAL1=1990,FISCAL2,FISCAL3;,例21:名空间使用示例。,9.9名空间,使用std名空间,全局变量,定义名空间,嵌套的名空间定义,namespacedoubled=88.22;intmain()coutd=d;coutn(全局变量)m

温馨提示

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

评论

0/150

提交评论