版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5章
函數(shù)與編譯預(yù)處理學(xué)習(xí)目標(biāo)掌握函數(shù)的概念、定義和調(diào)用方法。理解遞歸的概念,并能運(yùn)用遞歸的方法解決一些實(shí)際問(wèn)題。理解變量的作用域與生存期的概念,能夠理解全局變量、局部變量、靜態(tài)變量的概念和用法。
理解編譯預(yù)處理的概念。了解宏定義、文件包含和條件編譯的概念,掌握它們的格式和使用方法。5.1函數(shù)的定義與調(diào)用人們?cè)谇蠼庖粋€(gè)復(fù)雜的問(wèn)題的時(shí)候,通常采用逐步分解、分而治之的方法。也就是把一個(gè)大問(wèn)題分解為幾個(gè)比較容易求解的小問(wèn)題,然后分別求解。程序員在設(shè)計(jì)一個(gè)復(fù)雜的應(yīng)用程序時(shí),往往也是把整個(gè)程序劃分為若干個(gè)功能較為單一的程序模塊,然后分別予以實(shí)現(xiàn),最后再把所有的程序模塊象搭積木一樣搭起來(lái),這種在程序設(shè)計(jì)中分而治之的策略,被稱為模塊化程序設(shè)計(jì)方法。在C++中,這些模塊就是一個(gè)個(gè)的函數(shù)。
5.1函數(shù)的定義與調(diào)用函數(shù)的本質(zhì)有兩點(diǎn):函數(shù)由能完成特定任務(wù)的獨(dú)立程序代碼塊組成,如有必要,也可調(diào)用其它函數(shù),來(lái)產(chǎn)生最終的輸出。函數(shù)內(nèi)部工作對(duì)程序的其余部分是不可見(jiàn)的。C/C++是由函數(shù)構(gòu)成的,函數(shù)是C/C++的基本模塊。5.1函數(shù)的定義與調(diào)用一個(gè)程序必須有且只有一個(gè)主函數(shù)(main()函數(shù)),和若干個(gè)其它函數(shù)。C/C++從main()函數(shù)開(kāi)始執(zhí)行,由主函數(shù)調(diào)用其它函數(shù),其它函數(shù)之間也可以互相調(diào)用。
main()fun2()fun1()fun3()fun1_1()fun2_1()fun2_2()圖函數(shù)調(diào)用層次關(guān)系5.1函數(shù)的定義與調(diào)用庫(kù)函數(shù)
C/C++系統(tǒng)以提供的函數(shù),提供了豐富的功能。多少隨系統(tǒng)而定,有一部分對(duì)所有的C/C++系統(tǒng)都有,格式也相同,稱為標(biāo)準(zhǔn)函數(shù),還有一部分與系統(tǒng)有關(guān)。使用說(shuō)明:A)資料B)聯(lián)機(jī)幫助用戶自定義函數(shù)用戶根據(jù)所需解決的問(wèn)題而編寫(xiě)函數(shù)定義是編寫(xiě)的一段代碼(并不執(zhí)行)函數(shù)定義后就可使用它。稱為函數(shù)調(diào)用5.1函數(shù)的定義與調(diào)用函數(shù)定義的一般形式:返回類型函數(shù)名(參數(shù)表列){
語(yǔ)句系列
return合適類型數(shù)值}說(shuō)明:函數(shù)返回值指函數(shù)返回的值的類型,也有稱為:函數(shù)類型函數(shù)返回值如果是void,意為無(wú)值返回函數(shù)返回值說(shuō)明若沒(méi)有,指函數(shù)返回整型數(shù)。也就是:若函數(shù)返回整型類型的數(shù)據(jù),可省略函數(shù)返回值說(shuō)明,否則不能省若參數(shù)表空,稱為無(wú)參函數(shù),否則稱為有參函數(shù)。無(wú)參函數(shù)參數(shù)表可寫(xiě)成(void)或?qū)懗桑ǎ?.1函數(shù)的定義與調(diào)用***********
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();}在出現(xiàn)函數(shù)調(diào)用時(shí),程序控制轉(zhuǎn)到函數(shù),函數(shù)執(zhí)行結(jié)束后,回到調(diào)用點(diǎn)(主函數(shù)),繼續(xù)執(zhí)行后續(xù)語(yǔ)句。函數(shù)調(diào)用函數(shù)定義5.2.1形參、實(shí)參和函數(shù)的返回值#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;}函數(shù)定義,a,b稱為函數(shù)的形式參數(shù),一般稱為形參,每個(gè)形參前有形參的類型說(shuō)明(不能寫(xiě)成inta,b),形參之間用逗號(hào)隔開(kāi);return格式為:return<表達(dá)式>或return,功能是立即結(jié)束函數(shù),返回。若有表達(dá)式,先計(jì)算表達(dá)式,然后帶值返回函數(shù)調(diào)用:(1)計(jì)算表達(dá)式值(該值稱為實(shí)參)(2)轉(zhuǎn)到函數(shù)首先值傳遞給對(duì)應(yīng)的形參,然后開(kāi)始執(zhí)行函數(shù)體若從鍵盤(pán)輸入:9423<Enter>輸出是:?注意:形參與值參數(shù)原則上個(gè)數(shù)、類型應(yīng)該相一致(特殊情況除外)調(diào)用power(4.6,3)函數(shù)power(4.6,3)return97.336
主程序后續(xù)語(yǔ)句n=3x=4.6c=‘a(chǎn)’【例】
說(shuō)明實(shí)參和形參對(duì)應(yīng)關(guān)系的示例。#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;}調(diào)用power('a',3)函數(shù)power('a',3)return912673
主程序后續(xù)語(yǔ)句n=3x=4.6c=‘a(chǎn)’【例】
說(shuō)明實(shí)參和形參對(duì)應(yīng)關(guān)系的示例。#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;}調(diào)用power(3,4.6)函數(shù)power(3,4.6)return81主程序后續(xù)語(yǔ)句n=3x=4.6c=‘a(chǎn)’【例】
說(shuō)明實(shí)參和形參對(duì)應(yīng)關(guān)系的示例。#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函數(shù)的原型說(shuō)明#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);函數(shù)原型,函數(shù)若還沒(méi)有定義,就先使用,就需要給出函數(shù)原型,此時(shí)只要提供函數(shù)返回值類型,函數(shù)名,形參類型即可。5.2.3函數(shù)的值調(diào)用在C/C++中,函數(shù)的參數(shù)傳遞都是值傳遞#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函數(shù)的值調(diào)用5.2.3函數(shù)的值調(diào)用在每次調(diào)用一個(gè)函數(shù)事件,系統(tǒng)內(nèi)部產(chǎn)生一個(gè)棧架(棧:插入刪除只允許在一端進(jìn)行的一種表),將函數(shù)執(zhí)行結(jié)束后的位置記下,然后依此計(jì)算實(shí)參表達(dá)式并將結(jié)果放在棧架中,函數(shù)內(nèi)說(shuō)明的變量也在棧架中得到空間,函數(shù)在執(zhí)行相應(yīng)的代碼時(shí),在棧架中取對(duì)應(yīng)的數(shù)據(jù)或變量。函數(shù)結(jié)束后,從棧架中取到返回的位置,并退去本函數(shù)此次的棧架。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()運(yùn)行狀態(tài)及返回地址x3b2a1fun1()main()運(yùn)行狀態(tài)及返回地址y2x1main()操作系統(tǒng)運(yùn)行狀態(tài)及返回地址#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函數(shù)的值調(diào)用計(jì)算實(shí)際參數(shù)表中各表達(dá)式將表達(dá)式的值依此賦給各形式參數(shù)執(zhí)行函數(shù)體當(dāng)遇到return語(yǔ)句時(shí),將控制返回到調(diào)用函數(shù);當(dāng)return語(yǔ)句中包含有表達(dá)式時(shí),則計(jì)算表達(dá)式返回值當(dāng)無(wú)return語(yǔ)句時(shí),則執(zhí)行到函數(shù)體末后返回調(diào)用函數(shù)參數(shù)以傳值方式調(diào)用5.3函數(shù)的嵌套與遞歸調(diào)用C語(yǔ)言中,所有函數(shù)都是平行獨(dú)立的,無(wú)主次、相互包含之分。函數(shù)可以嵌套調(diào)用,不可嵌套定義。函數(shù)的遞歸調(diào)用:若在函數(shù)定義時(shí),調(diào)用了自己,稱遞歸調(diào)用5.3函數(shù)的嵌套與遞歸調(diào)用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函數(shù)的嵌套與遞歸調(diào)用遞歸是一種編程技術(shù),并不是用于計(jì)算階乘的。用非遞歸的方法計(jì)算階乘效率更高,我們用遞歸來(lái)計(jì)算階乘,是因?yàn)樗倪f歸調(diào)用易于實(shí)現(xiàn)和理解。
5.3函數(shù)的嵌套與遞歸調(diào)用注意:編寫(xiě)遞歸的函數(shù)時(shí),一定注意要有遞歸調(diào)用終止的條件,且每調(diào)用一次就向調(diào)用終止更靠近一步。這可確保遞歸調(diào)用能夠正常結(jié)束,而不至于導(dǎo)致系統(tǒng)內(nèi)存耗盡而崩潰。遞歸函數(shù)總比功能相同的非遞歸函數(shù)慢,因?yàn)槊看握{(diào)用函數(shù)時(shí)都有調(diào)用開(kāi)銷。任何用遞歸編寫(xiě)的函數(shù)都可使用循環(huán)結(jié)構(gòu)代替,以消除遞歸。Hanoi塔hanoi(n,a,b,c)//n個(gè)盤(pán)a從移到c,允許利用的中間桿是b{hanoi(n-1,a,c,b);ac;//cout<<a<<“->”<<c<<endl;hanoi(n-1,b,a,c);}當(dāng)只有一個(gè)盤(pán)時(shí),上述不成立。應(yīng)直接從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作用域和存儲(chǔ)類在C++中,變量有效的范圍(稱為變量的作用域)和被存儲(chǔ)的時(shí)間(稱為變量的存儲(chǔ)期或生存期)都是不同的。如果按變量的作用域來(lái)分類的話,變量可以分為局部變量和全局變量;如果按變量的存儲(chǔ)期來(lái)分類的話,變量可以分為外部變量、靜態(tài)變量、自動(dòng)變量、寄存器變量。
5.4作用域和存儲(chǔ)類在函數(shù)外說(shuō)明的變量,從定義變量的位置開(kāi)始到該程序文件結(jié)束,所有函數(shù)中均可使用,稱為全局變量,全局變量的初值是0在塊作用域內(nèi)可通過(guò)作用域運(yùn)算符“::”來(lái)使用與局部變量同名的全局變量#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';}文件作用域規(guī)則:打印200調(diào)用func()函數(shù)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作用域和存儲(chǔ)類打印main()中的t=3.5調(diào)用fun()函數(shù)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()函數(shù)中的局部變量cout<<"main()中的t="<<t<<endl;fun();cout<<"main()中的t="<<t<<endl;}5.4作用域和存儲(chǔ)類5.4作用域和存儲(chǔ)類標(biāo)識(shí)符只能在說(shuō)明它的分程序內(nèi)有效,在分程序之外是不可見(jiàn)的。每個(gè)分程序可以有各自的命名法,外層分程序說(shuō)明的名字如果在內(nèi)層沒(méi)有重新定義則在內(nèi)層中繼續(xù)有效;一旦內(nèi)層中重新定義,則內(nèi)層使用的是內(nèi)層重新定義了的名字For語(yǔ)句中說(shuō)明的循環(huán)控制變量作用域?yàn)榘琭or語(yǔ)句的那個(gè)內(nèi)層塊塊作用域規(guī)則:全局n=100
200300內(nèi)i=500內(nèi)j=600內(nèi)n=500+600=11001100500600100200+300=500500
500200300外部i=200外部j=300【例】
顯示同名變量可見(jiàn)性。intn=100;#include<iostream.h>voidmain(){inti=200,j=300;cout<<n<<'\t'<<i<<'\t'<<j<<endl;{ //內(nèi)部塊
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作用域和存儲(chǔ)類在函數(shù)內(nèi)說(shuō)明的函數(shù)原型僅對(duì)本函數(shù)有效在函數(shù)外說(shuō)明的函數(shù)原型對(duì)本文件有效函數(shù)作用域規(guī)則:5.4作用域和存儲(chǔ)類存儲(chǔ)類:規(guī)定了變量的生存期,確定何時(shí)為變量分配內(nèi)存空間及何時(shí)收回該空間變量說(shuō)明:<存儲(chǔ)類型><類型>標(biāo)識(shí)符;存儲(chǔ)類可以是下面四種之一:自動(dòng)的auto
外部的extern
寄存器的register
靜態(tài)的static5.4作用域和存儲(chǔ)類C/C++存儲(chǔ)區(qū)域分配圖堆區(qū)(動(dòng)態(tài)數(shù)據(jù))棧區(qū)(函數(shù)局部數(shù)據(jù))全局?jǐn)?shù)據(jù)區(qū)(全局、靜態(tài))代碼區(qū)(程序代碼)存放應(yīng)用程序的可執(zhí)行代碼存放應(yīng)用程序的全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù),它們的生命期與應(yīng)用程序的生命期一相同,即從應(yīng)用程序開(kāi)始運(yùn)行時(shí)起至停止運(yùn)行時(shí)止。全局?jǐn)?shù)據(jù)與靜態(tài)數(shù)據(jù)的內(nèi)存空間均是在編譯時(shí)分配的
局部變量存放在棧中,它們的內(nèi)存空間是在程序運(yùn)行時(shí)動(dòng)態(tài)分配的C++中,對(duì)內(nèi)存用new命令創(chuàng)建用delete命令釋放。
5.4作用域和存儲(chǔ)類自動(dòng)類變量:
auto
按缺省規(guī)則,不加存儲(chǔ)類說(shuō)明的為自動(dòng)的。自動(dòng)變量進(jìn)入分程序分配空間(在棧頂),退出分程序,空間由系統(tǒng)回收(退棧)外部類變量:extern
在函數(shù)外面說(shuō)明的變量稱外部變量。外部變量的空間是固定的(存儲(chǔ)在全局變量區(qū)),在程序運(yùn)行其間一直有效,在程序運(yùn)行完畢后由操作系統(tǒng)回收。若使用的全局變量先使用后定義或不在本文件中定義,需要使用則要在使用前加extern的說(shuō)明。5.4作用域和存儲(chǔ)類寄存器的register變量分配在寄存器中,以加快存儲(chǔ)速度當(dāng)資源限制做不到時(shí),系統(tǒng)視為auto靜態(tài)的static靜態(tài)變量在退出分程序后仍保留其值,但分程序外不可見(jiàn)。靜態(tài)變量的初始化僅在分配空間時(shí)做一次,若不初始化則系統(tǒng)自動(dòng)置為0.5.4作用域和存儲(chǔ)類局部靜態(tài)變量和局部變量的對(duì)比#include<iostream.h>st(){staticintt=100;//局部靜態(tài)變量
t++;returnt;}at(){
intt=100;//自動(dòng)變量
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作用域和存儲(chǔ)類i=0t=10012101345102103104105局部靜態(tài)變量和局部變量的對(duì)比#include<iostream.h>st(){staticintt=100;//局部靜態(tài)變量
t++;returnt;}at(){
intt=100;//自動(dòng)變量
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作用域和存儲(chǔ)類#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的第二種作用:加在在外部變量或函數(shù)前。目的:則使該變量或函數(shù)僅在本文件內(nèi)有效。輸出是:595.5內(nèi)聯(lián)函數(shù)調(diào)用函數(shù)實(shí)際上將程序執(zhí)行流程轉(zhuǎn)移到被調(diào)函數(shù)中,被調(diào)函數(shù)的程序代碼執(zhí)行完后,再返回到調(diào)用的地方。這種調(diào)用操作要求調(diào)用前保護(hù)現(xiàn)場(chǎng)并記憶執(zhí)行的地址,返回后恢復(fù)現(xiàn)場(chǎng),并按原來(lái)保存的地址繼續(xù)執(zhí)行.內(nèi)聯(lián)函數(shù)是指編譯器將函數(shù)體的代碼插入到函數(shù)調(diào)用處,調(diào)用函數(shù)實(shí)質(zhì)上是順序執(zhí)行直接插入的函數(shù)代碼。
5.5內(nèi)聯(lián)函數(shù)注意:在一個(gè)文件中定義的內(nèi)聯(lián)函數(shù)不能在另一個(gè)文件中使用。它們通常放在頭文件中共享。內(nèi)聯(lián)函數(shù)應(yīng)該簡(jiǎn)潔,只有幾個(gè)語(yǔ)句,如果語(yǔ)句較多,不適合于定義為內(nèi)聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)體中,不能有循環(huán)語(yǔ)句、if語(yǔ)句或switch語(yǔ)句,否則,函數(shù)定義時(shí)即使有inline關(guān)鍵字,編譯器也會(huì)把該函數(shù)作為非內(nèi)聯(lián)函數(shù)處理。內(nèi)聯(lián)函數(shù)要在函數(shù)被調(diào)用之前聲明。如將內(nèi)聯(lián)函數(shù)放在函數(shù)調(diào)用之后聲明,不能起到預(yù)期的效果。內(nèi)聯(lián)函數(shù)的實(shí)質(zhì)是用空間換時(shí)間。程序中多次調(diào)用同一內(nèi)聯(lián)函數(shù)時(shí),增加了程序本身占用的存儲(chǔ)空間;而內(nèi)聯(lián)函數(shù)僅調(diào)用一次時(shí),并不增加程序占用的存儲(chǔ)空間。5.5內(nèi)聯(lián)函數(shù)請(qǐng)看如下程序段,讀入一行字符串,逐個(gè)判斷是否為數(shù)字字符:
#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<<″是數(shù)字字符″<<endl;elsecout<<″不是數(shù)字字符″<<endl;}}因使用頻度很高,說(shuō)明為內(nèi)聯(lián)函數(shù)。5.6具有缺省參數(shù)值的函數(shù)
在C++中定義函數(shù)時(shí),允許給參數(shù)指定一個(gè)缺省的值。在調(diào)用函數(shù)時(shí),若明確給出了這種實(shí)參的值,則使用相應(yīng)實(shí)參的值;若沒(méi)有給出相應(yīng)的實(shí)參,則使用缺省的值(C無(wú)此功能)。#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具有缺省參數(shù)值的函數(shù)注意:必須在函數(shù)調(diào)用前指定缺省參數(shù)的值參數(shù)的缺省值可以是常量表達(dá)式,表達(dá)式中使用的量必須是常量具有缺省值的函數(shù)參數(shù)可有多個(gè),但缺省參數(shù)必須位于參數(shù)表中的最右邊同一個(gè)具有缺省參數(shù)的函數(shù),在不同地方調(diào)用時(shí)可使用不同的缺省參數(shù)值輸入長(zhǎng)方體的長(zhǎng)度,寬度和高度,求出長(zhǎng)方體的體積。#include<iostream.h>floatv(float,float=10,float=20); voidmain(void){ floatx,y,z;
cout<<"輸入第一個(gè)長(zhǎng)方體的長(zhǎng)、寬、高:";
cin>>x>>y>>z;
cout<<"第一個(gè)長(zhǎng)方體的體積為:"<<v(x,y,z)<<'\n';
cout<<"輸入第二個(gè)長(zhǎng)方體的長(zhǎng)和寬:";
cin>>x>>y;
cout<<"第二個(gè)長(zhǎng)方體的體積為:"<<v(x,y)<<'\n';
cout<<"輸入第三個(gè)長(zhǎng)方體的長(zhǎng)度:";
cin>>x;
cout<<"第三個(gè)長(zhǎng)方體的體積為:"<<v(x)<<'\n';}floatv(floata,floatb,floatc)
{ returna*b*c;} 例:對(duì)于同一個(gè)函數(shù),可在不同的作用域內(nèi)作不同的原型說(shuō)明,定義不同的缺省參數(shù)值。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;}參數(shù)的缺省值為20參數(shù)的缺省值為30參數(shù)的缺省值為10函數(shù)的定義函數(shù)的原型說(shuō)明5.7函數(shù)的重載
函數(shù)的重載是指完成不同功能的函數(shù)可以具有相同的函數(shù)名。(C語(yǔ)言無(wú)此功能)調(diào)用重載函數(shù)時(shí),C++編譯器根據(jù)實(shí)參的類型或?qū)崊⒌膫€(gè)數(shù)來(lái)確定應(yīng)該調(diào)用哪一個(gè)函數(shù)。函數(shù)重載體現(xiàn)了C++語(yǔ)言“同一接口,多種實(shí)現(xiàn)方法”的多態(tài)性機(jī)制。
注意:重載函數(shù)的參數(shù)個(gè)數(shù)或參數(shù)類型必須有不同僅返回值類型不同時(shí),不能定義為重載函數(shù)5.7函數(shù)的重載3+5=調(diào)用sum(3,5)函數(shù)sum(3,5)return82.2+5.6=調(diào)用sum(2.2,5.6)函數(shù)doublesum(2.2,5.6)return7.83.5+4+8=調(diào)用sum(3.5,4,8)函數(shù)floatsum(3.5,4,8)return15.5結(jié)束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編譯預(yù)處理源程序(文本文件)*.CPP目標(biāo)文件(二進(jìn)制文件)*.OBJ可執(zhí)行文件(二進(jìn)制文件)*.EXE庫(kù)文件(各種函數(shù))編譯連接編譯預(yù)處理
編譯預(yù)處理指令不屬于C++的語(yǔ)法范疇,為了區(qū)分,系統(tǒng)規(guī)定每條編譯預(yù)處理指令用#號(hào)開(kāi)頭,單獨(dú)占用一行。編譯預(yù)處理指令可分為三種:包含文件、宏和條件編譯。5.8.1“包含文件”處理編譯預(yù)處理指令include指示將另一個(gè)源程序文件的全部?jī)?nèi)容包含(插入)到當(dāng)前源程序文件中,替代該include指令行。替代后的結(jié)果寫(xiě)入臨時(shí)文件,當(dāng)前源程序文件并不改變。include指令的格式為:
#include“文件名”或#include<文件名>file1.cppBA#include“file2.cpp"ABfile1.cppfile2.cpp5.8.1“包含文件”處理注意:用雙引號(hào)括起來(lái)的文件名表示要從當(dāng)前工作目錄開(kāi)始查找該文件(通常與源程序文件在同一個(gè)文件目錄中);若找不到該文件,再到C++編譯器約定的include目錄中查找該文件,若仍找不到則出錯(cuò)。用“<”和“>”括起來(lái)的文件名表示直接從C++編譯器約定的include目錄中查找該文件,若找不到則出錯(cuò)。頭文件的擴(kuò)展名通常為".h",也可以使用".cpp"。一條include指令只能包含一個(gè)文件。若要包含n個(gè)文件,則要使用n條include指令。包含文件可以嵌套,即在一個(gè)頭文件中又包含其它的頭文件。include指令可出現(xiàn)在源程序中的任何一行位置,但通常放在源程序的開(kāi)頭。5.8.2宏
編譯預(yù)處理指令define用來(lái)定義宏。宏可分為有參數(shù)的宏和無(wú)參數(shù)的宏。
無(wú)參數(shù)的宏用一個(gè)指定的標(biāo)識(shí)符(即名字)來(lái)代表一個(gè)字符串,這個(gè)標(biāo)識(shí)符稱為宏名。編譯預(yù)處理時(shí),凡是在程序中遇到這個(gè)標(biāo)識(shí)符的地方都用對(duì)應(yīng)的字符串來(lái)代替,這個(gè)過(guò)程稱為“宏擴(kuò)展”。無(wú)參宏的定義格式為:
#define標(biāo)識(shí)符字符串5.8.2宏#definePRICE30voidmain(void){intnum,total;/*定義變量*/num=10;/*變量賦值*/total=num*PRICE;
cout<<"total="<<total<<endl;}編譯前內(nèi)部替代,作為total=num*305.8.2宏注意:宏名通常用大寫(xiě)字母表示;
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024高考化學(xué)一輪復(fù)習(xí)第四章非金屬及其化合物第一節(jié)碳硅及其重要化合物學(xué)案新人教版
- 2024高考?xì)v史一輪復(fù)習(xí)第10講近代西方民主政治的確立與發(fā)展學(xué)案含解析人民版
- 2024高考地理一輪復(fù)習(xí)第二章自然環(huán)境中的物質(zhì)運(yùn)動(dòng)和能量交換第10講氣候類型教案湘教版
- 小學(xué)2024-2025學(xué)年度第二學(xué)期美育學(xué)科教研計(jì)劃
- 2024年初中學(xué)校安全演練計(jì)劃
- 看月亮科學(xué)教案5篇
- 市政管道施工質(zhì)量控制措施
- 二零二五年航空航天零部件生產(chǎn)合作合同2篇
- 北京市豐臺(tái)區(qū)2023-2024學(xué)年八年級(jí)上學(xué)期期末語(yǔ)文試題(原卷版)
- 廣東省梅州市興寧一中人教版2024-2025學(xué)年八年級(jí)上學(xué)期第一次月考英語(yǔ)試題
- 旅游文本翻譯策略之轉(zhuǎn)換法-語(yǔ)態(tài)轉(zhuǎn)換
- 食品進(jìn)駐超市的談判計(jì)劃書(shū)
- 辦公區(qū)域巡檢與安全檢查規(guī)定
- 宮頸癌篩查及預(yù)防講課課件
- 《跟單信用證統(tǒng)一慣例》UCP600中英文對(duì)照版
- 2023年數(shù)學(xué)競(jìng)賽AMC8試卷(含答案)
- SMA分子檢測(cè)進(jìn)展
- 醫(yī)師定期考核機(jī)構(gòu)信息登記表
- 風(fēng)力發(fā)電風(fēng)機(jī)拆除方案
- 杭州出租車(chē)區(qū)域考試復(fù)習(xí)備考題庫(kù)(含答案)
- 普通高中地理課程標(biāo)準(zhǔn)簡(jiǎn)介課件
評(píng)論
0/150
提交評(píng)論