




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章
函数与编译预处理学习目标掌握函数的概念、定义和调用方法。理解递归的概念,并能运用递归的方法解决一些实际问题。理解变量的作用域与生存期的概念,能够理解全局变量、局部变量、静态变量的概念和用法。
理解编译预处理的概念。了解宏定义、文件包含和条件编译的概念,掌握它们的格式和使用方法。5.1函数的定义与调用人们在求解一个复杂的问题的时候,通常采用逐步分解、分而治之的方法。也就是把一个大问题分解为几个比较容易求解的小问题,然后分别求解。程序员在设计一个复杂的应用程序时,往往也是把整个程序划分为若干个功能较为单一的程序模块,然后分别予以实现,最后再把所有的程序模块象搭积木一样搭起来,这种在程序设计中分而治之的策略,被称为模块化程序设计方法。在C++中,这些模块就是一个个的函数。
5.1函数的定义与调用函数的本质有两点:函数由能完成特定任务的独立程序代码块组成,如有必要,也可调用其它函数,来产生最终的输出。函数内部工作对程序的其余部分是不可见的。C/C++是由函数构成的,函数是C/C++的基本模块。5.1函数的定义与调用一个程序必须有且只有一个主函数(main()函数),和若干个其它函数。C/C++从main()函数开始执行,由主函数调用其它函数,其它函数之间也可以互相调用。
main()fun2()fun1()fun3()fun1_1()fun2_1()fun2_2()图函数调用层次关系5.1函数的定义与调用库函数
C/C++系统以提供的函数,提供了丰富的功能。多少随系统而定,有一部分对所有的C/C++系统都有,格式也相同,称为标准函数,还有一部分与系统有关。使用说明:A)资料B)联机帮助用户自定义函数用户根据所需解决的问题而编写函数定义是编写的一段代码(并不执行)函数定义后就可使用它。称为函数调用5.1函数的定义与调用函数定义的一般形式:返回类型函数名(参数表列){
语句系列
return合适类型数值}说明:函数返回值指函数返回的值的类型,也有称为:函数类型函数返回值如果是void,意为无值返回函数返回值说明若没有,指函数返回整型数。也就是:若函数返回整型类型的数据,可省略函数返回值说明,否则不能省若参数表空,称为无参函数,否则称为有参函数。无参函数参数表可写成(void)或写成()5.1函数的定义与调用***********
Howdoyoudo!***********要求显示器输出:#include<iostream.h>#defineNUM11voidmain(){
inti;for(i=0;i<NUM;i++)
cout<<‘*’;
cout<<endl;
cout<<“Howdoyoudo!”<<endl;for(i=0;i<NUM;i++)
cout<<‘*’;
cout<<endl;}#include<iostream.h>#defineNUM11voidprint(){inti;for(i=0;i<NUM;i++)
cout<<‘*’;
cout<<endl;}
voidmain(){print();cout<<“Howdoyoudo!”<<endl;print();}在出现函数调用时,程序控制转到函数,函数执行结束后,回到调用点(主函数),继续执行后续语句。函数调用函数定义5.2.1形参、实参和函数的返回值#include<iostream.h>intmax(int
a,intb){
if(a>b)returna;elsereturnb;}voidmain(){
int
a,b,c,t;
cin>>a,b,c;t=max(a,b);t=max(t,c);
cout<<t<<endl;
cout<<max(a,b+10)<<end;}函数定义,a,b称为函数的形式参数,一般称为形参,每个形参前有形参的类型说明(不能写成inta,b),形参之间用逗号隔开;return格式为:return<表达式>或return,功能是立即结束函数,返回。若有表达式,先计算表达式,然后带值返回函数调用:(1)计算表达式值(该值称为实参)(2)转到函数首先值传递给对应的形参,然后开始执行函数体若从键盘输入:9423<Enter>输出是:?注意:形参与值参数原则上个数、类型应该相一致(特殊情况除外)调用power(4.6,3)函数power(4.6,3)return97.336
主程序后续语句n=3x=4.6c=‘a’【例】
说明实参和形参对应关系的示例。#include<iostream.h>#include<math.h>floatpower(floatx,intn){//求x的n次幂floatpow=1;while(n--)pow*=x;returnpow;}voidmain(){intn=3;floatx=4.6;charc='a';cout<<"power("<<x<<','<<n<<")="<<power(x,n)<<endl;cout<<"power("<<c<<','<<n<<")="<<power(c,n)<<endl;cout<<"power("<<n<<','<<x<<")="<<power(n,x)<<endl;}调用power('a',3)函数power('a',3)return912673
主程序后续语句n=3x=4.6c=‘a’【例】
说明实参和形参对应关系的示例。#include<iostream.h>#include<math.h>floatpower(floatx,intn){//求x的n次幂floatpow=1;while(n--)pow*=x;returnpow;}voidmain(){intn=3;floatx=4.6;charc='a';cout<<"power("<<x<<','<<n<<")="<<power(x,n)<<endl;cout<<"power("<<c<<','<<n<<")="<<power(c,n)<<endl;cout<<"power("<<n<<','<<x<<")="<<power(n,x)<<endl;}调用power(3,4.6)函数power(3,4.6)return81主程序后续语句n=3x=4.6c=‘a’【例】
说明实参和形参对应关系的示例。#include<iostream.h>#include<math.h>floatpower(floatx,intn){//求x的n次幂floatpow=1;while(n--)pow*=x;returnpow;}voidmain(){intn=3;floatx=4.6;charc='a';cout<<"power("<<x<<','<<n<<")="<<power(x,n)<<endl;cout<<"power("<<c<<','<<n<<")="<<power(c,n)<<endl;cout<<"power("<<n<<','<<x<<")="<<power(n,x)<<endl;}5.2.2函数的原型说明#include<iostream.h>voidmain(){inta,b,t;cin>>a>>b;print(a,b);t=max(a,b);cout<<t<<endl;}voidprint(int
a,intb){
for(i=0;i<max(a,b);i++)
cout<<‘*’;
cout<<endl;}max(int
x,inty){return(x>y)?x:y;}voidprint(int,int);int
max(int,int);intmax(int,int);intmax(int,int)voidprint(int,int);函数原型,函数若还没有定义,就先使用,就需要给出函数原型,此时只要提供函数返回值类型,函数名,形参类型即可。5.2.3函数的值调用在C/C++中,函数的参数传递都是值传递#include<iostream.h>voidchange(int
x,inty){
int
tmp;
tmp=y;y=x;x=tmp;
cout<<"x="<<x<<"y="<<y<<endl;}voidmain(){intx=3,y=4;
cout<<"x="<<x<<"x="<<y<<endl;change(x,y);
cout<<"x="<<x<<"y="<<y<<endl;}5.2.3函数的值调用5.2.3函数的值调用在每次调用一个函数事件,系统内部产生一个栈架(栈:插入删除只允许在一端进行的一种表),将函数执行结束后的位置记下,然后依此计算实参表达式并将结果放在栈架中,函数内说明的变量也在栈架中得到空间,函数在执行相应的代码时,在栈架中取对应的数据或变量。函数结束后,从栈架中取到返回的位置,并退去本函数此次的栈架。voidfun1(int,int);voidfun2(float);voidmain(){
intx=1;y=2;
fun1(x,y);}voidfun1(inta,intb){floatx=3;
fun2(x);}voidfun2(floaty){
intx;…}x栈顶栈底y3fun2()fun1()运行状态及返回地址x3b2a1fun1()main()运行状态及返回地址y2x1main()操作系统运行状态及返回地址#include<iostream.h>voidchange(int
x,inty){
int
tmp;
tmp=y;y=x;x=tmp;
cout<<"x="<<x<<"y="<<y<<endl;}voidmain(){intx=3,y=4;
cout<<"x="<<x<<"x="<<y<<endl;change(x,y);
cout<<"x="<<x<<"y="<<y<<endl;}main的返回地址3(x)4(y)main栈架change的返回地址3(x)4(y)子程序栈架tmpchange的返回地址3(x)4(y)子程序栈架4(tmp)change的返回地址3(x)3(y)子程序栈架4(tmp)change的返回地址4(x)3(y)子程序栈架4(tmp)5.2.3函数的值调用计算实际参数表中各表达式将表达式的值依此赋给各形式参数执行函数体当遇到return语句时,将控制返回到调用函数;当return语句中包含有表达式时,则计算表达式返回值当无return语句时,则执行到函数体末后返回调用函数参数以传值方式调用5.3函数的嵌套与递归调用C语言中,所有函数都是平行独立的,无主次、相互包含之分。函数可以嵌套调用,不可嵌套定义。函数的递归调用:若在函数定义时,调用了自己,称递归调用5.3函数的嵌套与递归调用n!=1n=1(n-1)!*nn>1unsignedlongfac(unsignedlongn){if(n==1)return1;elsereturnn*fac(n-1);}#include<iostream.h>voidmain(){unsignedlongn;
cin>>n;
cout<<fac(n)<<endl;}5.3函数的嵌套与递归调用递归是一种编程技术,并不是用于计算阶乘的。用非递归的方法计算阶乘效率更高,我们用递归来计算阶乘,是因为它的递归调用易于实现和理解。
5.3函数的嵌套与递归调用注意:编写递归的函数时,一定注意要有递归调用终止的条件,且每调用一次就向调用终止更靠近一步。这可确保递归调用能够正常结束,而不至于导致系统内存耗尽而崩溃。递归函数总比功能相同的非递归函数慢,因为每次调用函数时都有调用开销。任何用递归编写的函数都可使用循环结构代替,以消除递归。Hanoi塔hanoi(n,a,b,c)//n个盘a从移到c,允许利用的中间杆是b{hanoi(n-1,a,c,b);ac;//cout<<a<<“->”<<c<<endl;hanoi(n-1,b,a,c);}当只有一个盘时,上述不成立。应直接从a移到c
ABC#include<iostream.h>voidhanoi(intn,chara,charb,charc){if(n==1)cout<<a<<"->"<<c<<endl;else{hanoi(n-1,a,c,b);
cout<<a<<"->"<<c<<endl;hanoi(n-1,b,a,c);}}voidmain(){intn;
cin>>n;
hanoi(n,'A','B','C');}Hanoi塔
ABC#include<iostream.h>voidhanoi(intn,chara,charb,charc){if(n==1)cout<<a<<"->"<<c<<endl;else{hanoi(n-1,a,c,b);
cout<<a<<"->"<<c<<endl;hanoi(n-1,b,a,c);}}hanoi(3,'A','B','C');voidhanoi(3,'A','B','C'){if(n==1)cout<<a<<"->"<<c<<endl;else{hanoi(n-1,a,c,b);
cout<<a<<"->"<<c<<endl;hanoi(n-1,b,a,c);}}voidhanoi(3,'A','B','C'){hanoi(2,'A','C','B');A搬到C;
hanoi(2,'B','A','C');}Hanoi塔
ABChanoi(3,’A’,’B’,’C’){hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}A搬到CHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}A搬到CHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}
hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}A搬到CHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);
A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);
A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);
A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}C搬到BHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);
A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}C搬到BHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);
A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}C搬到BHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘A’,’C’,’B’){
hanoi(1,‘A’,‘B’,‘C’);
A搬到B;
hanoi(1,‘C’,‘A’,‘B’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}B搬到AHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}B搬到AHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}B搬到AHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}A搬到CHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}A搬到CHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}A搬到CHanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}hanoi(2,‘B’,’A’,’C’){
hanoi(1,‘B’,‘C’,‘A’);
B搬到C;
hanoi(1,‘A’,‘B’,‘C’);}Hanoi塔
ABChanoi(3,‘A’,’B’,’C’){
hanoi(2,‘A’,‘C’,‘B’);
A搬到C;
hanoi(2,‘B’,‘A’,‘C’);}5.4作用域和存储类在C++中,变量有效的范围(称为变量的作用域)和被存储的时间(称为变量的存储期或生存期)都是不同的。如果按变量的作用域来分类的话,变量可以分为局部变量和全局变量;如果按变量的存储期来分类的话,变量可以分为外部变量、静态变量、自动变量、寄存器变量。
5.4作用域和存储类在函数外说明的变量,从定义变量的位置开始到该程序文件结束,所有函数中均可使用,称为全局变量,全局变量的初值是0在块作用域内可通过作用域运算符“::”来使用与局部变量同名的全局变量#include<iostream.h>inti=100;//全局变量voidmain(void){
int
i,j=50;//局部变量i=18;
::i=::i+4; j=::i+i;
cout<<"::i="<<::i<<'\n';
cout<<"i="<<i<<'\n';cout<<"j="<<j<<'\n';}文件作用域规则:打印200调用func()函数func()200*2=400打印400n=100n=100*2=200全局变量的例子。#include<iostream.h>intn=100;voidfunc(){ n*=2;}voidmain(){ n*=2;
cout<<n<<endl;
func();
cout<<n<<endl;}5.4作用域和存储类打印main()中的t=3.5调用fun()函数fun()打印fun()中的t=5
打印main()中的t=3.5t=3.5t=5局部变量的例子#include<iostream.h>voidfun(){auto
int
t=5;//fun()中的局部变量,auto可省略cout<<"fun()中的t="<<t<<endl;}voidmain(){float
t=3.5;//main()函数中的局部变量cout<<"main()中的t="<<t<<endl;fun();cout<<"main()中的t="<<t<<endl;}5.4作用域和存储类5.4作用域和存储类标识符只能在说明它的分程序内有效,在分程序之外是不可见的。每个分程序可以有各自的命名法,外层分程序说明的名字如果在内层没有重新定义则在内层中继续有效;一旦内层中重新定义,则内层使用的是内层重新定义了的名字For语句中说明的循环控制变量作用域为包含for语句的那个内层块块作用域规则:全局n=100
200300内i=500内j=600内n=500+600=11001100500600100200+300=500500
500200300外部i=200外部j=300【例】
显示同名变量可见性。intn=100;#include<iostream.h>voidmain(){inti=200,j=300;cout<<n<<'\t'<<i<<'\t'<<j<<endl;{ //内部块
inti=500,j=600,n;n=i+j;
cout<<n<<'\t'<<i<<'\t'<<j<<endl;//输出局部变量n
cout<<::n<<endl;//输出全局变量n}n=i+j; //修改全局变量cout<<n<<'\t'<<i<<'\t'<<j<<endl;}5.4作用域和存储类在函数内说明的函数原型仅对本函数有效在函数外说明的函数原型对本文件有效函数作用域规则:5.4作用域和存储类存储类:规定了变量的生存期,确定何时为变量分配内存空间及何时收回该空间变量说明:<存储类型><类型>标识符;存储类可以是下面四种之一:自动的auto
外部的extern
寄存器的register
静态的static5.4作用域和存储类C/C++存储区域分配图堆区(动态数据)栈区(函数局部数据)全局数据区(全局、静态)代码区(程序代码)存放应用程序的可执行代码存放应用程序的全局数据和静态数据,它们的生命期与应用程序的生命期一相同,即从应用程序开始运行时起至停止运行时止。全局数据与静态数据的内存空间均是在编译时分配的
局部变量存放在栈中,它们的内存空间是在程序运行时动态分配的C++中,对内存用new命令创建用delete命令释放。
5.4作用域和存储类自动类变量:
auto
按缺省规则,不加存储类说明的为自动的。自动变量进入分程序分配空间(在栈顶),退出分程序,空间由系统回收(退栈)外部类变量:extern
在函数外面说明的变量称外部变量。外部变量的空间是固定的(存储在全局变量区),在程序运行其间一直有效,在程序运行完毕后由操作系统回收。若使用的全局变量先使用后定义或不在本文件中定义,需要使用则要在使用前加extern的说明。5.4作用域和存储类寄存器的register变量分配在寄存器中,以加快存储速度当资源限制做不到时,系统视为auto静态的static静态变量在退出分程序后仍保留其值,但分程序外不可见。静态变量的初始化仅在分配空间时做一次,若不初始化则系统自动置为0.5.4作用域和存储类局部静态变量和局部变量的对比#include<iostream.h>st(){staticintt=100;//局部静态变量
t++;returnt;}at(){
intt=100;//自动变量
t++;returnt;}voidmain(){
inti;for(i=0;i<5;i++)cout<<at()<<'\t';
cout<<endl;for(i=0;i<5;i++)cout<<st()<<'\t';
cout<<endl;}i=0t=100123451011011011011015.4作用域和存储类i=0t=10012101345102103104105局部静态变量和局部变量的对比#include<iostream.h>st(){staticintt=100;//局部静态变量
t++;returnt;}at(){
intt=100;//自动变量
t++;returnt;}voidmain(){
inti;for(i=0;i<5;i++)cout<<at()<<'\t';
cout<<endl;for(i=0;i<5;i++)cout<<st()<<'\t';
cout<<endl;}5.4作用域和存储类#include<iostream.h>
int
sum(int);voidmain(){//a=5;
cout<<sum(4)<<endl;
cout<<sum(4)<<endl;}sum(intn){
staticinta=1;a+=n;returna;}static的第二种作用:加在在外部变量或函数前。目的:则使该变量或函数仅在本文件内有效。输出是:595.5内联函数调用函数实际上将程序执行流程转移到被调函数中,被调函数的程序代码执行完后,再返回到调用的地方。这种调用操作要求调用前保护现场并记忆执行的地址,返回后恢复现场,并按原来保存的地址继续执行.内联函数是指编译器将函数体的代码插入到函数调用处,调用函数实质上是顺序执行直接插入的函数代码。
5.5内联函数注意:在一个文件中定义的内联函数不能在另一个文件中使用。它们通常放在头文件中共享。内联函数应该简洁,只有几个语句,如果语句较多,不适合于定义为内联函数。内联函数体中,不能有循环语句、if语句或switch语句,否则,函数定义时即使有inline关键字,编译器也会把该函数作为非内联函数处理。内联函数要在函数被调用之前声明。如将内联函数放在函数调用之后声明,不能起到预期的效果。内联函数的实质是用空间换时间。程序中多次调用同一内联函数时,增加了程序本身占用的存储空间;而内联函数仅调用一次时,并不增加程序占用的存储空间。5.5内联函数请看如下程序段,读入一行字符串,逐个判断是否为数字字符:
#include<iostream.h>inline
IsNumber(char
ch){returnch>=′0′&&ch<=′9′?1:0;}voidmain(){charch;
while(cin.get(ch),ch!=′\n′){if(IsNumber(ch))cout<<″是数字字符″<<endl;elsecout<<″不是数字字符″<<endl;}}因使用频度很高,说明为内联函数。5.6具有缺省参数值的函数
在C++中定义函数时,允许给参数指定一个缺省的值。在调用函数时,若明确给出了这种实参的值,则使用相应实参的值;若没有给出相应的实参,则使用缺省的值(C无此功能)。#include<iostream.h>floatfact(intn=10){ floatf=1; for(inti=2;i<=n;i++)f*=i; returnf;}voidmain(void){
cout<<fact(5)<<'\n';
cout<<fact()<<'\n';}5.6具有缺省参数值的函数注意:必须在函数调用前指定缺省参数的值参数的缺省值可以是常量表达式,表达式中使用的量必须是常量具有缺省值的函数参数可有多个,但缺省参数必须位于参数表中的最右边同一个具有缺省参数的函数,在不同地方调用时可使用不同的缺省参数值输入长方体的长度,宽度和高度,求出长方体的体积。#include<iostream.h>floatv(float,float=10,float=20); voidmain(void){ floatx,y,z;
cout<<"输入第一个长方体的长、宽、高:";
cin>>x>>y>>z;
cout<<"第一个长方体的体积为:"<<v(x,y,z)<<'\n';
cout<<"输入第二个长方体的长和宽:";
cin>>x>>y;
cout<<"第二个长方体的体积为:"<<v(x,y)<<'\n';
cout<<"输入第三个长方体的长度:";
cin>>x;
cout<<"第三个长方体的体积为:"<<v(x)<<'\n';}floatv(floata,floatb,floatc)
{ returna*b*c;} 例:对于同一个函数,可在不同的作用域内作不同的原型说明,定义不同的缺省参数值。floatfact(intn=10);
...voidbb(void){
floatfact(int=20);
... x=fact();
...}floatcc(void){
floatfact(int=30);
... y=fact();
...}floatdd(void){ ... z=fact();
...}floatfact(intn)
{ floatf=1; for(inti=2;i<=n;i++)f*=i; returnf;}参数的缺省值为20参数的缺省值为30参数的缺省值为10函数的定义函数的原型说明5.7函数的重载
函数的重载是指完成不同功能的函数可以具有相同的函数名。(C语言无此功能)调用重载函数时,C++编译器根据实参的类型或实参的个数来确定应该调用哪一个函数。函数重载体现了C++语言“同一接口,多种实现方法”的多态性机制。
注意:重载函数的参数个数或参数类型必须有不同仅返回值类型不同时,不能定义为重载函数5.7函数的重载3+5=调用sum(3,5)函数sum(3,5)return82.2+5.6=调用sum(2.2,5.6)函数doublesum(2.2,5.6)return7.83.5+4+8=调用sum(3.5,4,8)函数floatsum(3.5,4,8)return15.5结束87.815.5#include<iostream.h>sum(int
a,intb){ returna+b;}doublesum(doublea,doubleb){ returna+b;}floatsum(floata,floatb,floatc){ returna+b+c;}voidmain(){
cout<<"3+5="<<sum(3,5) <<endl;
cout<<"2.2+5.6=“ <<sum(2.2,5.6)<<endl;
cout<<"3.5+4+8=“ <<sum(3.5,4,8)<<endl;}5.8编译预处理源程序(文本文件)*.CPP目标文件(二进制文件)*.OBJ可执行文件(二进制文件)*.EXE库文件(各种函数)编译连接编译预处理
编译预处理指令不属于C++的语法范畴,为了区分,系统规定每条编译预处理指令用#号开头,单独占用一行。编译预处理指令可分为三种:包含文件、宏和条件编译。5.8.1“包含文件”处理编译预处理指令include指示将另一个源程序文件的全部内容包含(插入)到当前源程序文件中,替代该include指令行。替代后的结果写入临时文件,当前源程序文件并不改变。include指令的格式为:
#include“文件名”或#include<文件名>file1.cppBA#include“file2.cpp"ABfile1.cppfile2.cpp5.8.1“包含文件”处理注意:用双引号括起来的文件名表示要从当前工作目录开始查找该文件(通常与源程序文件在同一个文件目录中);若找不到该文件,再到C++编译器约定的include目录中查找该文件,若仍找不到则出错。用“<”和“>”括起来的文件名表示直接从C++编译器约定的include目录中查找该文件,若找不到则出错。头文件的扩展名通常为".h",也可以使用".cpp"。一条include指令只能包含一个文件。若要包含n个文件,则要使用n条include指令。包含文件可以嵌套,即在一个头文件中又包含其它的头文件。include指令可出现在源程序中的任何一行位置,但通常放在源程序的开头。5.8.2宏
编译预处理指令define用来定义宏。宏可分为有参数的宏和无参数的宏。
无参数的宏用一个指定的标识符(即名字)来代表一个字符串,这个标识符称为宏名。编译预处理时,凡是在程序中遇到这个标识符的地方都用对应的字符串来代替,这个过程称为“宏扩展”。无参宏的定义格式为:
#define标识符字符串5.8.2宏#definePRICE30voidmain(void){intnum,total;/*定义变量*/num=10;/*变量赋值*/total=num*PRICE;
cout<<"total="<<total<<endl;}编译前内部替代,作为total=num*305.8.2宏注意:宏名通常用大写字母表示;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 膀胱肿瘤考试题及答案
- 安全作业考试题库及答案
- 安全员试题及答案
- 安全管理试题及答案
- 顾客为先的培训课件
- 群发中暑急救培训课件
- 原谅的幼儿绘本课件
- 公司税务筹划课件
- 中国全国课件
- 中国元代美术课件
- 餐饮服务与管理课件 菜单的设计与制作
- 2025年度次季度工业级5G专网部署技术服务合同模板
- 大数据分析在食品检测精度提高中的应用策略
- 山东师范大学《大学英语本科(专升本)》期末考试复习题及参考答案
- Unit 6 A great week (教学设计)-2024-2025学年外研版(三起)(2024)英语三年级下册
- 2025版小细胞肺癌免疫治疗专家共识解读
- 职业技能培训:保健按摩师
- JJF(津) 5003-2024 汽车制造专用加注机校准规范
- 2025年绍兴市部分市属国有企业招聘笔试参考题库含答案解析
- 团队建设与团队管理培训
- 国家开放大学本科《行政法与行政诉讼法》期末纸质考试总题库2025春期考试版
评论
0/150
提交评论