版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第3章函數(shù)和編譯預(yù)處理優(yōu)化第2章的內(nèi)容,把功能上獨(dú)立、經(jīng)常使用的程序片段寫成函數(shù),在需要時(shí)調(diào)用這個(gè)函數(shù),避免在多個(gè)需要的地方重復(fù)書寫同樣的程序片段。這也是公用、通用程序共享的方法。3.1函數(shù)概述
3.2函數(shù)的定義和調(diào)用
3.3函數(shù)的參數(shù)傳遞
3.4函數(shù)的嵌套調(diào)用和遞歸調(diào)用
3.5內(nèi)置函數(shù)
3.6變量和函數(shù)的屬性
3.7編譯預(yù)處理
3.1概述把一個(gè)大程序劃分為若干個(gè)程序模塊(小程序單位
),每一個(gè)模塊實(shí)現(xiàn)一部分功能。不同的程序模塊可以由不同的人來(lái)完成。每個(gè)程序模塊可以單獨(dú)進(jìn)行編譯,如果發(fā)現(xiàn)錯(cuò)誤,可以在本程序模塊范圍內(nèi)查錯(cuò)并改正。這就是程序中運(yùn)用函數(shù)的思想。把實(shí)現(xiàn)某一特定功能的相關(guān)語(yǔ)句按某種格式組織在一起形成一個(gè)程序單位,并給程序單位取一個(gè)相應(yīng)的名稱,這樣的一個(gè)程序單位就叫函數(shù)(function)。函數(shù)有時(shí)也被稱作例程或過(guò)程;而給程序單位所起的相應(yīng)名稱被稱作函數(shù)名。
任何程序必須有一個(gè)、且只有一個(gè)主函數(shù)main();但可以有n個(gè)自定義函數(shù)(n≥0)。圖3.1是一個(gè)程序中函數(shù)調(diào)用的示意圖。圖3.1main()func1()func2()func3()func5()func4()例3.1在主函數(shù)中調(diào)用其他函數(shù)。//*****ex3_1.cpp*****#include<iostream>usingnamespacestd;doubleS1,S2;//定義變量S1和S2分別存放兩數(shù)和與兩數(shù)積doubleadd(doublex,doubley) //定義add()函數(shù){S1=x+y;returnS1;}doublemultiply(doublex,doubley) //定義multiply()函數(shù){S2=x*y;returnS2;}voidoutput(void) //定義output()函數(shù){cout<<"兩數(shù)和S1="<<S1<<","<<"兩數(shù)積S2="<<S2<<endl;} //輸出結(jié)果voidmain(void){doublea,b;cout<<"請(qǐng)輸入兩個(gè)數(shù):"<<endl;cin>>a>>b;S1=add(a,b); //調(diào)用add()函數(shù)
S2=multiply(a,b); //調(diào)用multiply()函數(shù)
output();//調(diào)用Output()函數(shù)}
若用戶從鍵盤輸入的數(shù)是9.05.0,則運(yùn)行結(jié)果如下:請(qǐng)輸入兩個(gè)數(shù):9.0
5.0↙兩數(shù)和S1=14,兩數(shù)積S2=45
從用戶使用的角度看,函數(shù)有兩種:(1)系統(tǒng)函數(shù),即庫(kù)函數(shù)。這是由編譯系統(tǒng)提供的,用戶不必自己定義這些函數(shù),可以直接使用它們。(2)用戶自己定義的函數(shù)。用以解決用戶的專門需要。從函數(shù)的形式看,函數(shù)分兩類:(1)無(wú)參函數(shù)。調(diào)用函數(shù)時(shí)不必給出參數(shù)。(2)有參函數(shù)。在調(diào)用函數(shù)時(shí),要給出參數(shù)。在主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞。3.2函數(shù)的定義和調(diào)用3.2.1定義函數(shù)的一般形式定義函數(shù)的一般形式如下:類型標(biāo)識(shí)符函數(shù)名([形式參數(shù)列表]){聲明語(yǔ)句執(zhí)行語(yǔ)句}(1)對(duì)庫(kù)函數(shù)的聲明在程序文件頭用#include語(yǔ)句將與庫(kù)函數(shù)有關(guān)的文件包含到本程序中來(lái),就完成了對(duì)庫(kù)函數(shù)的聲明。(2)對(duì)自定義函數(shù)的聲明須在調(diào)用某自定義函數(shù)之前寫如下聲明語(yǔ)句:函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型,參數(shù)1名稱][,參數(shù)2類型,參數(shù)2名稱][…]);
3.2.2函數(shù)的聲明(2)對(duì)自定義函數(shù)的聲明(續(xù))也可以用下列簡(jiǎn)略式聲明:函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型][,參數(shù)2類型][,…]);函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型,標(biāo)識(shí)符1][,參數(shù)2類型,標(biāo)識(shí)符2][,…]);C++的函數(shù)原型。其中,標(biāo)識(shí)符可用任何合法名稱。3.2.2函數(shù)的聲明【例3.2】函數(shù)聲明示例:設(shè)被調(diào)函數(shù)area()和volum()分別求園面積和圓柱體體積。程序代碼如下://*****ex3_2.cpp*****#include<iostream>usingnamespacestd;voidmain(){doublevolum(float,float); //聲明求圓柱體體積的volum()函數(shù)
doublearea(floatr); //聲明求園面積的area()函數(shù)
floatr,h;
doubles,v;cout<<"pleaseinputr,h:";cin>>r>>h;s=area(r);v=volum(r,h);cout<<"s="<<s<<","<<"v="<<v<<endl;}
doublevolum(floatx,floaty) //定義volum()函數(shù){doublearea(floatr);//聲明求園面積的area()函數(shù)
doublez1,z2;z1=area(x);z2=z1*y;return(z2);
}doublearea(floatx) //定義area()函數(shù){doublez;z=3.14*x*x;return(z);}程序的運(yùn)行結(jié)果如下:pleaseinputa,b:
10.02.0↙s=314,v=628
說(shuō)明:(1)對(duì)函數(shù)的定義和函數(shù)聲明是兩回事,不要混淆。(2)之所以函數(shù)原型中可以省略形式參數(shù)的名稱,是因?yàn)樾问絽?shù)的名稱是無(wú)關(guān)緊要的,且在調(diào)用前形參并不存在。(3)函數(shù)聲明語(yǔ)句的位置。函數(shù)聲明語(yǔ)句可以放在主調(diào)函數(shù)中,也可放在函數(shù)外面,只要出現(xiàn)在調(diào)用語(yǔ)句之前即聲明有效。3.2.3函數(shù)的返回值(1)函數(shù)的返回值是通過(guò)函數(shù)中的return語(yǔ)句獲得的。return語(yǔ)句將被調(diào)用函數(shù)中的一個(gè)確定值帶回主調(diào)函數(shù)中去。return語(yǔ)句后面的括號(hào)可以要,也可以不要。return后面的值可以是一個(gè)表達(dá)式。(2)函數(shù)值的類型。應(yīng)當(dāng)在定義函數(shù)時(shí)的首行開頭指定函數(shù)值的類型。(3)如果函數(shù)值的類型和return語(yǔ)句中表達(dá)式的值不一致,則以函數(shù)類型為準(zhǔn),即函數(shù)類型決定返回值的類型。對(duì)數(shù)值型數(shù)據(jù),可以自動(dòng)進(jìn)行類型轉(zhuǎn)換。編譯系統(tǒng)對(duì)聲明語(yǔ)句并不檢查參數(shù)名;因此參數(shù)名是什么都無(wú)所謂。上面程序中的聲明也可以寫成:floatadd(floata,floatb);
//參數(shù)名不用x、y,而用a、b,效果完全相同。應(yīng)當(dāng)保證函數(shù)原型聲明語(yǔ)句與函數(shù)首部寫法上的一致,即函數(shù)類型、函數(shù)名、參數(shù)個(gè)數(shù)、參數(shù)類型和參數(shù)順序必須相同。說(shuō)明:前面已說(shuō)明,如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必加以聲明。(2)函數(shù)聲明的位置可以在函數(shù)內(nèi),也可以在函數(shù)之外。例如,若下列inti(float,float)函數(shù)被其它所有函數(shù)調(diào)用,可以只寫一個(gè)聲明語(yǔ)句--寫在所有函數(shù)外面;若寫在函數(shù)內(nèi)部,則每個(gè)函數(shù)內(nèi)部都要寫聲明語(yǔ)句:
charletter(char,char);//函數(shù)聲明語(yǔ)句floatf(float,float);//函數(shù)聲明語(yǔ)句inti(float,float);//函數(shù)聲明語(yǔ)句intmain()//在main函數(shù)中不必作聲明而可以調(diào)用以上三個(gè)函數(shù){…}charletter(charc1,charc2)//定義letter函數(shù){…}floatf(floatx,floaty)//定義f函數(shù){…}
inti(floatj,floatk)//定義i函數(shù){…}如果一個(gè)函數(shù)被多個(gè)函數(shù)所調(diào)用,用這種方法比較好,不必在每個(gè)主調(diào)函數(shù)中重復(fù)聲明。函數(shù)調(diào)用的一般形式:函數(shù)名([實(shí)際參數(shù)列表])如果是調(diào)用無(wú)參函數(shù),則沒(méi)有“實(shí)際參數(shù)列表”,但函數(shù)名后面的括號(hào)()不能省略。如果實(shí)際參數(shù)列表包含多個(gè)實(shí)參,則各參數(shù)間用逗號(hào)隔開。實(shí)參與形參的個(gè)數(shù)應(yīng)相等,類型應(yīng)匹配(相同或賦值兼容)。實(shí)參與形參按順序?qū)?yīng),一對(duì)一地傳遞數(shù)據(jù)。但應(yīng)說(shuō)明,如果實(shí)參表列包括多個(gè)實(shí)參,對(duì)實(shí)參求值的順序并不是確定的。3.2.4函數(shù)的調(diào)用按函數(shù)在語(yǔ)句中的作用來(lái)分,可以有以下3種函數(shù)調(diào)用方式:1.函數(shù)語(yǔ)句把函數(shù)調(diào)用單獨(dú)作為一個(gè)語(yǔ)句,并不要求函數(shù)帶回一個(gè)值,只是要求函數(shù)完成一定的操作。如【例3.1】中的print_word()函數(shù)調(diào)用語(yǔ)句。2.函數(shù)表達(dá)式函數(shù)出現(xiàn)在一個(gè)表達(dá)式中,這時(shí)要求函數(shù)帶回一個(gè)確定的值以參加表達(dá)式的運(yùn)算。如:c=2*max(a,b);3.函數(shù)參數(shù)函數(shù)調(diào)用作為一個(gè)函數(shù)的實(shí)參。如m=max(a,max(b,c));//max(b,c)是函數(shù)調(diào)用,其值作為外層max函數(shù)調(diào)用的一個(gè)實(shí)參函數(shù)調(diào)用的方式3.3函數(shù)的參數(shù)傳遞
形參:在定義函數(shù)時(shí)函數(shù)名后面括號(hào)中的變量名稱為形式參數(shù)(formalparameter),簡(jiǎn)稱形參。形參是無(wú)內(nèi)存單元(因而不存在)的任何合法標(biāo)識(shí)符。實(shí)參:在調(diào)用一個(gè)函數(shù)時(shí),調(diào)用語(yǔ)句的函數(shù)名后面括號(hào)中的參數(shù)稱為實(shí)際參數(shù)(actualparameter),簡(jiǎn)稱實(shí)參。實(shí)參是實(shí)際存在(因而有特定值)的常量、變量或表達(dá)式。
【例3.3】形參和實(shí)參及其數(shù)據(jù)傳遞。//*****ex3_3.cpp*****#include<iostream>usingnamespacestd;doublepow(floatx,intn)
//定義函數(shù)pow,求x的n次冪,x和n是形參{inti;doubles=1;for(i=1;i<=n;i++)s=s*x;return(s);}voidmain(){floata;intm;doublec;cout<<"pleaseinputthevaluesofaandm:";cin>>a>>m;c=pow(a,m);
//調(diào)用函數(shù)pow(),a和m是實(shí)參。函數(shù)值賦給變量ccout<<"Theresultis:"<<c<<endl;}程序的運(yùn)行結(jié)果如下:pleaseinputthevaluesofaandm:2.03↙Theresultis:8有關(guān)形參與實(shí)參的說(shuō)明:(1)在定義函數(shù)時(shí)指定的形參,在未出現(xiàn)函數(shù)調(diào)用時(shí),它們并不占內(nèi)存中的存儲(chǔ)單元,因此稱它們是形式參數(shù)或虛擬參數(shù),表示它們并不是實(shí)際存在的數(shù)據(jù),只有在發(fā)生函數(shù)調(diào)用時(shí),函數(shù)max中的形參才被分配內(nèi)存單元,以便接收從實(shí)參傳來(lái)的數(shù)據(jù)。在調(diào)用結(jié)束后,形參所占的內(nèi)存單元也被釋放。(2)實(shí)參可以是常量、變量或表達(dá)式,如max(3,a+b);但要求a和b有確定的值。以便在調(diào)用函數(shù)時(shí)將實(shí)參的值賦給形參。(3)在定義函數(shù)時(shí),必須在函數(shù)首部指定形參的類型,至于形參使用何名字可隨意。
(4)實(shí)參與形參的類型應(yīng)相同或賦值兼容。如果提供的實(shí)參與形參的類型不一致,則調(diào)用時(shí)會(huì)把實(shí)參類型強(qiáng)制轉(zhuǎn)換成形參類型。3.3.2參數(shù)的值傳遞
值傳遞參數(shù)的實(shí)現(xiàn)是系統(tǒng)將實(shí)參拷貝一個(gè)副本給形參,拷貝后兩者就斷開關(guān)系。在被調(diào)函數(shù)中,形參可以被改變,但這只影響副本中的形參值,而不影響調(diào)用函數(shù)的實(shí)參值。所以這類函數(shù)有對(duì)原始數(shù)據(jù)保護(hù)的作用。換一句話說(shuō),這種參數(shù)傳遞機(jī)制是單向影響,即只能由實(shí)參將值傳給形參(實(shí)參影響形參);而形參在函數(shù)中的值如果發(fā)生修改,不會(huì)反過(guò)來(lái)影響與之對(duì)應(yīng)的實(shí)參?!纠?.4】參數(shù)值傳遞的演示。//*****ex3_4.cpp*****#include<iostream>usingnamespacestd;intmax(intx,inty) /定義有參函數(shù)max,求兩數(shù)最大值,x和y是形參{floatm;cout<<"x,y的初始值是:"<<x<<","<<y<<endl;m=x>y?x:y;
x=2*x;y=y+1;cout<<"x,y后來(lái)的值是:"<<x<<","<<y<<endl;return(m);}voidmain(){inta,b,c;cout<<"請(qǐng)輸入兩個(gè)整數(shù):";cin>>a>>b;c=max(a,b); //調(diào)用函數(shù)max,a和b是實(shí)參,函數(shù)值賦給變量ccout<<"兩數(shù)的較大數(shù)是:"<<c<<endl;cout<<"調(diào)用函數(shù)后的a、b值分別是:"<<a<<","<<b<<endl;}
程序的運(yùn)行結(jié)果如下:請(qǐng)輸入兩個(gè)整數(shù):
38↙x,y的初始值是:
3,8x,y后來(lái)的值是:6,9
3.3.3參數(shù)的地址傳遞除了3.3.2小節(jié)介紹的值傳遞參數(shù)方式外,函數(shù)調(diào)用還有一種特殊的值傳遞形式,即傳遞的值不是一般的數(shù)值,而是一些內(nèi)存單元地址編號(hào)(即地址),這時(shí),一般稱之為參數(shù)的地址傳遞。在這種參數(shù)傳遞形式中,無(wú)論在函數(shù)的定義中出現(xiàn)的形參還是在調(diào)用語(yǔ)句中出現(xiàn)的實(shí)參,都是代表一些內(nèi)存單元地址編號(hào)(即地址數(shù)值),而不是一般的數(shù)值。C++中的參數(shù)地址傳遞情況一般有如下幾種:實(shí)參可以是一個(gè)有確定值的普通變量的地址,或者是一個(gè)已經(jīng)初始化的指針變量;或者是一個(gè)初始化的數(shù)組名;或者是一個(gè)具體的函數(shù)名。而形參可以是一個(gè)任意普通變量的地址,或是一個(gè)任意指針變量,或是一個(gè)任意的數(shù)組名,或是一個(gè)指向函數(shù)的指針變量(對(duì)應(yīng)于實(shí)參是具體函數(shù)名)。實(shí)際上,這種參數(shù)傳遞機(jī)制就是在函數(shù)調(diào)用時(shí)把一個(gè)內(nèi)存單元地址傳遞給形參,使形參也具有實(shí)參的內(nèi)存單元地址(即兩者對(duì)應(yīng)同一個(gè)內(nèi)存單元),稱作形參和實(shí)參地址結(jié)合,兩者合二為一。這樣一來(lái),任何時(shí)候形參的值等于實(shí)參的值;而實(shí)參的值也等于形參的值。因此,形參在函數(shù)中發(fā)生變化后,也會(huì)引起實(shí)參跟著變化(因?yàn)樗鼈兪抢壴谝黄鸬?,一體化的)。這就意味著按地址傳遞的方式,在調(diào)用剛開始時(shí)實(shí)參的值影響了形參;而在被調(diào)函數(shù)執(zhí)行過(guò)程中形參值若發(fā)生了變化,它也會(huì)影響實(shí)參的值變化。即機(jī)制是雙向影響,這與普通值傳遞方式的單向影響機(jī)制形成對(duì)比。3.3.4帶默認(rèn)值的參數(shù)C++語(yǔ)言中,允許在函數(shù)聲明或定義時(shí)給一個(gè)或多個(gè)參數(shù)指定默認(rèn)值。例如下面的delay()函數(shù)作用是作時(shí)間延遲,不使用默認(rèn)值參數(shù)的聲明和定義如下(【例3.5】):#include<iostream>//*****ex3_5.cpp*****usingnamespacestd;
voiddelay(intloop);//函數(shù)聲明voidmain(){cout<<"begin"<<endl;delay(1000);//函數(shù)調(diào)用cout<<"end"<<endl;}voiddelay(intloop)//函數(shù)定義{if(loop==0)return;for(inti=0;i<loop;i++)cout<<i<<endl;//輸出i值是為了清楚看到程序執(zhí)行情況}如果每次調(diào)用延遲時(shí)間基本一樣,可以使用C++中默認(rèn)值參數(shù)函數(shù)形式來(lái)解決問(wèn)題。解決的方法就是在函數(shù)聲明(或定義)時(shí)給定默認(rèn)值即可。具體做法只要把delay()函數(shù)的聲明改為下列形式:voiddelay(intloop=1000);//指定參數(shù)默認(rèn)值為1000以后如果需要延遲相同時(shí)間1000,都可以不必指定實(shí)參的值而直接調(diào)用函數(shù):delay();//若不給定實(shí)參,形參將得到默認(rèn)值1000delay(500);//若給定實(shí)參,形參將得到所給的值(500)如果有多個(gè)形參,可以使每個(gè)形參有一個(gè)默認(rèn)值;也可以只對(duì)一部分形參指定默認(rèn)值。如前面的求圓柱體體積的函數(shù)volume,可以這樣聲明:floatvolume(floatr,floath=8.5);//只對(duì)形參h指定默認(rèn)值8.5這時(shí)函數(shù)調(diào)用可采用以下形式:volume(6.0);//相當(dāng)于volume(6.0,8.5)volume(6.0,7.2);//r的值為6.0,h的值為7.2C++中實(shí)參和形參的結(jié)合是從左至右進(jìn)行的,第1個(gè)實(shí)參必然與第1個(gè)形參結(jié)合,第2個(gè)實(shí)參必然與第2個(gè)形參結(jié)合,……。因此,指定默認(rèn)值的參數(shù)必須放在參數(shù)列表中的最右邊。3.4函數(shù)的嵌套調(diào)用和遞歸調(diào)用
C++不允許對(duì)函數(shù)作嵌套定義,也就是說(shuō)在一個(gè)函數(shù)中不能完整地包含另一個(gè)函數(shù)。在一個(gè)程序中每一個(gè)函數(shù)的定義都是互相平行和獨(dú)立的。雖然C++不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),也就是說(shuō),在調(diào)用一個(gè)函數(shù)的過(guò)程中,又調(diào)用另一個(gè)函數(shù)。見圖3.2示意。
圖3.2
在程序中實(shí)現(xiàn)函數(shù)嵌套調(diào)用時(shí),需要注意的是:在調(diào)用函數(shù)之前,需要對(duì)每一個(gè)被調(diào)用的函數(shù)作聲明(除非定義在前,調(diào)用在后)。【例3.6】編程求組合,要求用函數(shù)完成。分析:根據(jù)組合的計(jì)算公式,知組合函數(shù)有兩個(gè)形參:m和n,可以用自定義函數(shù)comb(intn,intm)表示求組合。而在comb函數(shù)中需要3次計(jì)算階乘,如果定義函數(shù)fac(k)求k的階乘,然后在comb函數(shù)中調(diào)用fac函數(shù),可以使程序代碼簡(jiǎn)單,只要在comb函數(shù)中寫一個(gè)語(yǔ)句“c=fac(m)/(fac(n)*fac(m-n));
”即可求出組合值?!纠?.6】程序代碼如下:#include<iostream>//*****ex3_6.cpp*****usingnamespacestd;longfac(intk)//定義求階乘的函數(shù){longf=1;inti;for(i=1;i<=k;i++)f=f*i;returnf;}longcomb(intn,intm)//定義組合函數(shù){longc;c=fac(m)/(fac(n)*fac(m-n));//嵌套調(diào)用階乘函數(shù)
returnc;}voidmain(){intn,m;longc;cout<<"pleaseinputtwointegernumbers:m,n"<<endl;cin>>m>>n;c=comb(n,m);//調(diào)用組合函數(shù)combcout<<"c="<<c<<endl;}主函數(shù)調(diào)用函數(shù)comb();comb()在執(zhí)行過(guò)程中又調(diào)用了函數(shù)fac()。fac()的調(diào)用被嵌套在函數(shù)comb()的調(diào)用中。在調(diào)用一個(gè)函數(shù)的過(guò)程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身的現(xiàn)象,稱為函數(shù)的遞歸(recursive)調(diào)用。C++允許函數(shù)的遞歸調(diào)用。例如:直接遞歸調(diào)用的代碼形式如下:intf1()//函數(shù)f1的定義{……//函數(shù)其他部分
z=f1();//直接調(diào)用自身
……//函數(shù)其他部分}以上是在函數(shù)f1()中,又直接調(diào)用了f1()函數(shù),直接遞歸調(diào)用過(guò)程如后面的圖3.3所示。3.4.2函數(shù)的遞歸調(diào)用間接遞歸調(diào)用可以表現(xiàn)為如下形式:intf2()//函數(shù)f2的定義{……//f2的其他部分x=f3();//調(diào)用f3()……//f2的其他部分
}intf3()//函數(shù)f3的定義{……//f3的其他部分y=f2();//調(diào)用f2()……//f3的其他部分
}函數(shù)f2()中調(diào)用了f3(),而f3()中又調(diào)用了f2(),相當(dāng)于f2()間接地調(diào)用了f2()。這種調(diào)用稱為間接遞歸調(diào)用,調(diào)用過(guò)程如圖3.4所示。
圖3.3函數(shù)的直接遞歸調(diào)用圖3.4函數(shù)的間接遞歸調(diào)用從圖上可以看到,這兩種遞歸調(diào)用都是無(wú)終止的自身調(diào)用。顯然,程序中不應(yīng)出現(xiàn)這種無(wú)終止的遞歸調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的、有終止的遞歸調(diào)用,這可以用if語(yǔ)句來(lái)控制,只有在某一條件成立時(shí)才繼續(xù)執(zhí)行遞歸調(diào)用,否則就不再繼續(xù)。包含遞歸調(diào)用的函數(shù)稱為遞歸函數(shù)。【例3.7】用遞歸計(jì)算n!。分析:n!本身就是以遞歸的形式定義的:求n!,應(yīng)先求(n-1)??;而求(n-1)!,又需要先求(n-2)!,而求(n–2)?。挥挚梢宰兂汕?n-3)!,如此繼續(xù),直到最后變成求0!的問(wèn)題,而根據(jù)公式有0!=1(這就是本問(wèn)題的遞歸終止條件)。由終止條件得到0!結(jié)果后,再反過(guò)來(lái)依次求出1!,2!……直到最后求出n!。設(shè)求n!的函數(shù)為fac(n),函數(shù)體內(nèi)求n!,只要n>0,可用n*fac(n-1)表示,即fac(n)的函數(shù)體內(nèi)將遞歸調(diào)用fac()本身;但一旦參數(shù)n為0時(shí),則終止調(diào)用函數(shù)自身并給出函數(shù)值1。程序如下:#include<iostream>//*****ex3_7.cpp*****usingnamespacestd;longfac(intn){longf;
if(n==0)f=1;elsef=n*fac(n-1);
//遞歸調(diào)用,求(n-1)!returnf;}voidmain(){longy;intn;cout<<"pleaseinputaintegern"<<endl;cin>>n;y=fac(n);//調(diào)用fac(n)求n!cout<<"n="<<n<<","<<"y="<<y<<endl;}運(yùn)行時(shí),如果輸入:3運(yùn)行結(jié)果如下:n=3,y=6圖3.5求3!的遞歸過(guò)程fac(3)fac()n=33*fac(2)return6main()fac()n=22*fac(1)return2n=0fac(0)=1return1n1*fac(0)return1fac()fac()⑦②①③④⑧⑥⑤
3!遞歸調(diào)用及返回過(guò)程如圖3.5所示,圖中的數(shù)字序號(hào)表示遞歸調(diào)用和返回的先后順序。從求n!的遞歸程序中可以看出,遞歸定義有兩個(gè)要素:(1)遞歸終止條件。也就是所描述問(wèn)題的最簡(jiǎn)單情況,它本身不再使用遞歸的定義,即程序必須終止。如上例,當(dāng)n=0時(shí),fac(n)=1,不再使用fac(n-1)來(lái)定義。(2)遞歸定義使問(wèn)題向終止條件轉(zhuǎn)化的規(guī)則。遞歸定義必須能使問(wèn)題越來(lái)越簡(jiǎn)單,即參數(shù)越來(lái)越接近終止條件的參數(shù);達(dá)到終止條件參數(shù)時(shí)函數(shù)有確定值。如上例,fac(n)由fac(n-1)定義,越來(lái)越靠近fac(0),即參數(shù)越來(lái)越接近終止條件參數(shù)0;達(dá)到終止條件參數(shù)時(shí)函數(shù)有確定的值是fac(0)=1。【例3.8】漢諾塔問(wèn)題漢諾塔(TowerofHanoi)問(wèn)題據(jù)說(shuō)來(lái)源于布拉瑪神廟。該問(wèn)題的裝置如圖3.6所示(圖上僅畫三個(gè)金片以簡(jiǎn)化問(wèn)題的原理,原問(wèn)題有64個(gè)金片),底座上有三根金鋼石的針,第一根針a上放著從大到小64個(gè)金片。解決該問(wèn)題就是要想法把所有金片從第一根針a上移到第三根針c上,第二根針b作為中間過(guò)渡。要求是每次只能移動(dòng)一個(gè)金片,并且任何時(shí)候不允許大的金片壓在小的金片上面。圖3.6三個(gè)金片的漢諾塔問(wèn)題裝置abc1.本問(wèn)題的遞歸終止條件。如果只有1個(gè)盤,顯然問(wèn)題的解就很明顯是:直接把金片從a移到c。因此終止條件是n=1;終止條件對(duì)應(yīng)的操作是直接把金片從a移到c,示意ac。2.本問(wèn)題的遞歸分析:移動(dòng)n個(gè)金片從a到c,必須先將n-1個(gè)金片從a借助c移動(dòng)到b,移動(dòng)n-1個(gè)金片與原問(wèn)題相同,但規(guī)模變小,即向終止條件接近,因此,此問(wèn)題可以用遞歸過(guò)程完成。遞歸過(guò)程可以用如下步驟表示:(1)將n-1個(gè)金片從a經(jīng)過(guò)c移動(dòng)到b。(2)將第n個(gè)金片從a直接移動(dòng)到c。(3)再將n-1個(gè)金片從b經(jīng)過(guò)a移動(dòng)到c。
一般地,設(shè)將n個(gè)金片從x針借助y針移動(dòng)到z針的函數(shù)原形為:voidhanoi(intn,charx,chary,charz)根據(jù)解題步驟,可以寫出求解n個(gè)金片的漢諾塔函數(shù)如下:#include<iostream>//*****ex3_8.cpp*****usingnamespacestd;voidhanoi(intn,charx,chary,charz){
if(n==1)//n=1時(shí),直接將金片從x移動(dòng)到zcout<<x<<"->"<<z<<endl;else
//n>1時(shí){hanoi(n-1,x,z,y);//先將n-1個(gè)金片從借助z移動(dòng)到y(tǒng)cout<<x<<"->"<<z<<endl;//然后將第n個(gè)金片從x移到zhanoi(n-1,y,x,z);//再將n-1個(gè)金片從y借助x移動(dòng)到z}}當(dāng)n>1時(shí),就遞歸調(diào)用hanoi(),每次n減1。最后當(dāng)n=1時(shí),直接移動(dòng)該金片就可以了。主函數(shù)如下:
voidmain(){intn;cout<<"inputn:"<<endl;cin>>n;hanoi(n,'a','b','c');//n個(gè)金片從a針借助b針移動(dòng)到c針}雖然遞歸調(diào)用在寫程序時(shí)很簡(jiǎn)單,但執(zhí)行起來(lái)卻很復(fù)雜(時(shí)間、存儲(chǔ)空間都開銷大)。對(duì)于漢諾塔問(wèn)題程序的執(zhí)行過(guò)程分析比較復(fù)雜,有興趣的讀者可參閱教材對(duì)3個(gè)盤情景的分析(圖3.7及其相應(yīng)文字?jǐn)⑹觯?。調(diào)用函數(shù)時(shí)需要一定的時(shí)間和空間的開銷。下圖表示的是一般函數(shù)調(diào)用的過(guò)程。一般函數(shù)調(diào)用過(guò)程3.5內(nèi)置函數(shù)3.5.1內(nèi)置函數(shù)的作用內(nèi)置函數(shù)也稱內(nèi)聯(lián)函數(shù)、內(nèi)嵌函數(shù)。引入內(nèi)置函數(shù)的目的是為了提高程序中函數(shù)調(diào)用的效率:即在編譯時(shí)將所調(diào)用函數(shù)的代碼直接嵌入到主調(diào)函數(shù)中。定義內(nèi)置函數(shù)的方法:只需在函數(shù)定義的首行左端加一個(gè)關(guān)鍵字inline即可,或者在函數(shù)聲明語(yǔ)句的開頭加inline?
。3.5.2定義和使用內(nèi)置函數(shù)內(nèi)置函數(shù)的定義格式如下:inline
函數(shù)名(形參列表){
……//函數(shù)體}內(nèi)置函數(shù)的聲明格式如下:inline
函數(shù)名(形參類型表);其實(shí),內(nèi)置函數(shù)只要在開頭一次性聲明為inline即可,而后面的函數(shù)定義仍可寫成一般函數(shù)定義的形式,編譯器也會(huì)將函數(shù)視為內(nèi)置函數(shù)。【例3.9】將被調(diào)函數(shù)max(int,int,int)指定為內(nèi)置函數(shù)。#include<iostream>usingnamespacestd;inlineintmax(int,
int,int);//函數(shù)聲明語(yǔ)句,注意左端有inlinevoidmain(void){inti=5,j=6,k=7,m;m=max(i,j,k);
//注意這第6行
cout<<"max="<<m<<endl;}inlineintmax(inta,
intb,
intc)//定義max為內(nèi)置函數(shù){if(b>a)a=b;//求a,b,c中的最大者
if(c>a)a=c;returna;}這樣,程序第6行“m=max(i,j,k);”就被置換成下列3行語(yǔ)句:if(j>i)i=j;if(k>i)i=k;m=i;
3.6變量和函數(shù)的屬性3.6.1變量的作用域3.6.2變量的生存期3.6.3內(nèi)部函數(shù)和外部函數(shù)局部變量:在一個(gè)函數(shù)內(nèi)部或復(fù)合語(yǔ)句中定義的變量,稱為局部變量。其有效范圍有限,如圖示意:3.6.1變量的作用域:局部變量和全局變量說(shuō)明:(1)主函數(shù)main中定義的變量(m,n)也只在主函數(shù)中有效。主函數(shù)也不能使用其他函數(shù)中定義的變量。(2)不同函數(shù)中可以使用同名的變量,它們代表不同的對(duì)象,在內(nèi)存中占不同的單元;互不干擾,不會(huì)混淆。(3)可以在一個(gè)函數(shù)內(nèi)的復(fù)合語(yǔ)句中定義變量,這些變量只在本復(fù)合語(yǔ)句中有效。(4)形式參數(shù)也是局部變量。例如f1函數(shù)中的形參a只在f1函數(shù)中有效;其他函數(shù)不能調(diào)用。(5)在函數(shù)聲明中出現(xiàn)的參數(shù)名,其作用范圍只在本行的括號(hào)內(nèi)。例如:intmax(inta,intb);
//函數(shù)聲明中出現(xiàn)的a、b,它們的作用范圍只在本行有效。
intmax(intx,inty)//函數(shù)定義,形參是x、y{cout<<x<<y<<endl;//合法,x、y在函數(shù)體中有效cout<<a<<b<<endl;//非法,a、b在函數(shù)體中無(wú)效}編譯時(shí)認(rèn)為max函數(shù)體中的a和b未經(jīng)定義。全局變量:在函數(shù)之外定義的變量是外部變量,稱為全局變量(或全程變量)。全局變量的有效范圍原則上是:從定義變量的位置開始到本源文件結(jié)束。全局變量作用范圍示意如下:變量的作用域:變量的有效范圍稱為變量的作用域(scope)。變量有4種不同的作用域:文件作用域、函數(shù)作用域、塊作用域、函數(shù)原型作用域。文件作用域是全局的,其他三者是局部的。除了變量之外,任何以標(biāo)識(shí)符代表的實(shí)體其實(shí)也都有作用域,概念與變量的作用域相似?!纠?.10】局部變量的使用。//*****ex3_10.cpp*****#include<iostream>usingnamespacestd;
doublefun1(doublea,doubleb)
//fun1函數(shù)中有2個(gè)局部變量,分別取名a、b{a++;b++;return(a*b);}doublefun2(doublea,doubleb)
//fun2函數(shù)中有2個(gè)局部變量也分別取名a、b{a--;b--;return(a*b);}voidmain()
//main函數(shù)中有2個(gè)局部變量,也分別取名a、b{doublea,b;cout<<"inputtwonumbers:";cin>>a>>b;cout<<"fun1(a,b)="<<fun1(a,b)<<endl;cout<<"fun2(a,b)="<<fun2(a,b)<<endl;cout<<"a="<<a<<",b="<<b<<endl;}程序的運(yùn)行結(jié)果如下:inputtwonumbers:3.55↙fun1(a,b)=27fun2(a,b)=10a=3.5,b=52.全局變量凡是定義在函數(shù)外面的變量都叫全局變量。全局變量的默認(rèn)作用域是從該變量的定義位置延續(xù)到到該文件的末尾?!纠?.11】全局變量的使用。程序的運(yùn)行結(jié)果如下:a的初值=0a的終值=1//*****ex3_11.cpp*****#include<iostream>usingnamespacestd;
inta;
//此a的作用域?yàn)檎麄€(gè)文件voidfun1(); //聲明fun1()函數(shù)voidmain()
{cout<<”a的初值=”<<a<<endl;
//main()函數(shù)中使用了全局變量afun1(); //調(diào)用fun1()函數(shù)
cout<<”a的終值=”<<a<<endl;
//main()函數(shù)中再次使用了全局變量a}voidfun1(){a=a+1;}
//fun1()函數(shù)中使用了全局變量a【例3.12】分別寫兩個(gè)函數(shù)求給定兩個(gè)數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù),而不用函數(shù)值返回。//*****ex3_12.cpp*****#include<iostream>usingnamespacestd;
intgcd(int,int); //聲明求最大公約數(shù)的函數(shù)gcd()intlcm(int,int); //聲明求最小公倍數(shù)的函數(shù)lcm()intmax,min;//全局變量max和min分別存放最大公約數(shù)、最小公倍數(shù)voidmain(){inta;intb;cout<<"請(qǐng)輸入a和b的值:";cin>>a>>b;gcd(a,b);lcm(a,b);cout<<a<<”與”<<b<<"的最大公約數(shù)是:"<<max<<endl;
//使用maxcout<<a<<”與”<<b<<"的最小公倍數(shù)是:"<<min<<endl;
//使用min}
intgcd(intx,inty)
//定義求最大公約數(shù)的函數(shù)gcd(){intt;intr;if(x<y){t=x;x=y;y=t;}r=x%y;while(r!=0){x=y;y=r;r=x%y;}max=y;returnmax; //使用全局變量max的值為函數(shù)返回值}intlcm(intx,inty)//定義求最小公倍數(shù)的函數(shù)lcm(){min=x*y/max;//使用全局變量max,求全局變量min的值
returnmin;
//使用全局變量min的值為函數(shù)返回值}程序的運(yùn)行結(jié)果如下:請(qǐng)輸入a和b的值:3615↙36和15的最大公約數(shù)是:336和15的最小公倍數(shù)是:1803.不同作用域的同名變量引用規(guī)則
【例3.13】不同作用域的同名變量引用規(guī)則示例。#include<iostream>usingnamespacestd;inta=5;
//全局變量aintfun();//聲明一個(gè)無(wú)參有返回值的函數(shù)main()
{inta;
//函數(shù)級(jí)局部變量aa=1;//此處引用的a是函數(shù)級(jí)局部變量acout<<a<<”,”;
//此處引用的a是函數(shù)級(jí)局部變量a{inta;
//程序塊級(jí)局部變量aa=2;
//此處引用的a是程序塊級(jí)局部變量acout<<a<<”,”;//此處引用的a是程序塊級(jí)局部變量a}a=3;
//此處引用的a是函數(shù)級(jí)局部變量acout<<a<<”,”;//此處引用的a是函數(shù)級(jí)局部變量acout<<fun()<<endl;}intfun(){returna;}//此處引用的a是全局變量a
程序運(yùn)行結(jié)果是:1,2,3,5
上一節(jié)已介紹了變量的一種屬性——作用域,作用域是從空間的角度來(lái)分析的,變量按照作用域可分為全局變量和局部變量。變量還有另一種屬性——存儲(chǔ)期(也稱生存期)。存儲(chǔ)期是指變量在內(nèi)存中的存在期間。這是從變量值存在的時(shí)間角度來(lái)分析的。存儲(chǔ)期可以分為靜態(tài)存儲(chǔ)期和動(dòng)態(tài)存儲(chǔ)期。這是由變量的靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式?jīng)Q定的。3.6.2變量的生存期:
動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式所謂靜態(tài)存儲(chǔ)方式是指在程序運(yùn)行期間,系統(tǒng)對(duì)變量分配固定的存儲(chǔ)空間。而動(dòng)態(tài)存儲(chǔ)方式則是在程序運(yùn)行期間,系統(tǒng)對(duì)變量動(dòng)態(tài)地分配存儲(chǔ)空間。先看一下內(nèi)存中供用戶使用的存儲(chǔ)空間的情況。這個(gè)存儲(chǔ)空間可以分為三部分,即:(1)程序區(qū)(2)靜態(tài)存儲(chǔ)區(qū)(3)動(dòng)態(tài)存儲(chǔ)區(qū)
數(shù)據(jù)分別存放在靜態(tài)存儲(chǔ)區(qū)和動(dòng)態(tài)存儲(chǔ)區(qū)中。全局變量全部存放在靜態(tài)存儲(chǔ)區(qū)中,在程序開始執(zhí)行時(shí)給全局變量分配存儲(chǔ)單元,程序執(zhí)行完畢就釋放這些空間。在程序執(zhí)行過(guò)程中它們占據(jù)固定的存儲(chǔ)單元,而不是動(dòng)態(tài)地進(jìn)行分配和釋放。在動(dòng)態(tài)存儲(chǔ)區(qū)中存放以下數(shù)據(jù):①函數(shù)形式參數(shù);②函數(shù)中的自動(dòng)變量(未加static的局部變量);③函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)保護(hù)和返回地址等。在C++中變量除了有數(shù)據(jù)類型的屬性之外,還有存儲(chǔ)類別的屬性。存儲(chǔ)類別指的是數(shù)據(jù)在內(nèi)存中存儲(chǔ)的方法,即分為靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ)兩大類。具體包含4種:自動(dòng)的(auto);靜態(tài)的(static);寄存器的(register);外部的(extern)。根據(jù)變量的存儲(chǔ)類別,可以知道變量的作用域和存儲(chǔ)期。(1)自動(dòng)變量
凡未附加static關(guān)鍵字定義的局部變量都是自動(dòng)變量
。也可以用關(guān)鍵字auto作為存儲(chǔ)類別的聲明。
定義方式:[auto]數(shù)據(jù)類型關(guān)鍵字變量名;或:數(shù)據(jù)類型關(guān)鍵字[auto]變量名;1.短生存期變量——?jiǎng)討B(tài)存儲(chǔ)方式
(2)寄存器變量
存儲(chǔ)在CPU內(nèi)部通用寄存器中的變量叫寄存器變量,它們也是動(dòng)態(tài)變量;定義寄存器變量要附加register關(guān)鍵字。
定義方式:register
數(shù)據(jù)類型關(guān)鍵字變量名;寄存器變量的使用應(yīng)注意以下問(wèn)題:(1)寄存器變量不宜定義過(guò)多。(2)寄存器變量的數(shù)據(jù)長(zhǎng)度與通用寄存器的長(zhǎng)度相當(dāng)。一般是char型和int型變量。
1.短生存期變量——?jiǎng)討B(tài)存儲(chǔ)方式
(1)外部變量外部變量是指定義在函數(shù)外面且沒(méi)附加static關(guān)鍵字的全局變量。
可以利用extern關(guān)鍵詞對(duì)文件末尾或文件外定義的外部變量作附加聲明,使其作用域擴(kuò)展到整個(gè)程序:即,在想使用外部變量的地方,先寫一句下列形式的聲明語(yǔ)句:extern外部變量名;
2.長(zhǎng)生存期變量——靜態(tài)存儲(chǔ)方式
(1)外部變量①對(duì)外部變量做提前引用聲明
【例3.14】對(duì)定義在同一文件后面位置的外部變量,作提前引用聲明,使其作用域擴(kuò)展到該變量定義點(diǎn)之前。程序代碼如下://*****ex3_14.cpp*****#include<iostream>usingnamespacestd;externx; //提前引用聲明voidmain()
{x=4;cout<<x<<endl;}
//在變量定義位置之前面引用變量xintx;
//外部變量x的定義位置在文件后部
2.長(zhǎng)生存期變量——靜態(tài)存儲(chǔ)方式
(1)外部變量②對(duì)外部變量做跨文件引用聲明
【例3.15】對(duì)定義在B文件中的外部變量,在A文件中作跨文件引用聲明,以擴(kuò)展其作用域到A文件。//*****ex3_15A.cpp*****(文件ex3_15A.cpp的內(nèi)容)#include<iostream>usingnamespacestd;externw; //跨文件引用聲明(因?yàn)閣是在另一文件定義的)intfun(intx,inty)//定義fun()函數(shù){return(x+y);}voidmain(){cout<<w+fun(3,2)<<endl;}
//引用了ex3_15B.cpp文件中定義的變量w //*****ex3_15B.cpp*****(文件ex3_15B.cpp的內(nèi)容)intw=10; //外部變量w的定義
程序的運(yùn)行結(jié)果是15。
2.長(zhǎng)生存期變量——靜態(tài)存儲(chǔ)方式
(2)靜態(tài)變量
①靜態(tài)局部變量。在局部變量定義語(yǔ)句開頭再添加一個(gè)static關(guān)鍵字,這樣定義的局部變量叫靜態(tài)局部變量。
靜態(tài)局部變量的生命周期延長(zhǎng)了(等于程序整個(gè)運(yùn)行期),但作用域仍為其定義所在的函數(shù)或程序塊內(nèi)。
2.長(zhǎng)生存期變量——靜態(tài)存儲(chǔ)方式
(2)靜態(tài)變量
①靜態(tài)局部變量。【例3.16】使用靜態(tài)局部變量的例子。//*****ex3_16.cpp*****#include<iostream>usingnamespacestd;voidfun();voidmain(){inti;for(i=0;i<3;i++)
fun();}voidfun(){inta=0;staticintb=0;
//定義靜態(tài)局部變量
a++;b++;cout<<a<<","<<b<<endl;}
2.長(zhǎng)生存期變量——靜態(tài)存儲(chǔ)方式
程序的運(yùn)行結(jié)果如下:1,11,21,3(2)靜態(tài)變量
②靜態(tài)全局變量。在全局變量的定義語(yǔ)句開頭再添加一個(gè)static關(guān)鍵字,這樣定義的全局變量叫靜態(tài)全局變量。
【例3.17】靜態(tài)全局變量的演示。//*****ex3_17A.cpp*****(文件ex3_17A.cpp的內(nèi)容)staticintu=10;//定義靜態(tài)全局變量uvoidfun(){cout<<"Thisisex3_17.cpp";}//*****ex3_17B.cpp*****(文件ex3_17B.cpp的內(nèi)容)#include<iostream>usingnamespacestd;externu;
//試圖對(duì)u作跨文件引用聲明,此時(shí)行不通voidmain(){cout<<u<<endl;}//出現(xiàn)"變量u未定義"錯(cuò)誤
2.長(zhǎng)生存期變量——靜態(tài)存儲(chǔ)方式
1.內(nèi)部函數(shù)如果某函數(shù)只能被函數(shù)所在的同一文件中的語(yǔ)句調(diào)用,則這樣的函數(shù)叫內(nèi)部函數(shù)。因此,內(nèi)部函數(shù)不能被同一程序中其他文件的語(yǔ)句調(diào)用。內(nèi)部函數(shù)定義時(shí),也是在函數(shù)類型前加static,所以也稱為靜態(tài)函數(shù),定義格式如下:static函數(shù)類型函數(shù)名([參數(shù)列表]){
函數(shù)體
}3.6.3內(nèi)部函數(shù)和外部函數(shù)
【例3.18】靜態(tài)函數(shù)的例子。//*****ex3_18A.cpp*****(文件ex3_18A.cpp中的內(nèi)容)#include<iostream>usingnamespacestd;staticvoidfun();voidmain()
{fun();}staticvoidfun() //文件ex3_18A.cpp中定義了靜態(tài)函數(shù)fun(){cout<<"這是文件ex3_18A.cpp輸出的!"<<endl;}//文件ex3_18B.cpp中也定義名為fun()的靜態(tài)函數(shù):#include<iostream>usingnamespacestd;staticvoidfun();staticvoidfun(){cout<<"這是文件ex3_18B.cpp輸出的!"<<endl;}3.6.3內(nèi)部函數(shù)和外部函數(shù)
程序的運(yùn)行結(jié)果如下:這是文件ex3_18A.cpp輸出的!2.外部函數(shù)外部函數(shù)是可以被整個(gè)程序各個(gè)文件中語(yǔ)句調(diào)用的函數(shù)。(1)外部函數(shù)的定義在函數(shù)類型前加存儲(chǔ)類型關(guān)鍵字extern,或缺省存儲(chǔ)類型關(guān)鍵字extern,定義格式如下:[extern]函數(shù)類型函數(shù)名([參數(shù)列表]){
函數(shù)體}
(2)外部函數(shù)的聲明文件A在需要調(diào)用文件B中所定義的外部函數(shù)時(shí),需要在文件A中用關(guān)鍵字extern對(duì)被調(diào)函數(shù)提出聲明,聲明格式如下:extern函數(shù)類型函數(shù)名(參數(shù)類型列表)3.6.3內(nèi)部函數(shù)和外部函數(shù)
【例3.19】文件ex3_19A.cpp利用文件ex3_19B.cpp中的外部函數(shù)實(shí)現(xiàn)求雙階乘。//*****ex3_19A.cpp*****(文件ex3_19A.cpp中的內(nèi)容)#include<iostream>usingnamespacestd;voidmain(){externdoublefac2(int);//聲明將要調(diào)用在其他文件中定義的fac2()函數(shù)
intn;
cout<<"請(qǐng)輸入一整數(shù)給變量n:"<<endl;cin>>n;cout<<n<<"!!="<<fac2(n)<<endl;}//*****ex3_19B.cpp*****(文件ex3_19B.cpp中的內(nèi)容)#include<iostream>usingnamespacestd;externdoublefac2(intm) //定義fac2()函數(shù){intn;doubles;s=1;n=m;while(n>=1)
{s=s*n;n=n-2;}returns;
}
3.6.3內(nèi)部函數(shù)和外部函數(shù)
程序的運(yùn)行結(jié)果如下:請(qǐng)輸入一整數(shù)給變量n:7↙7!!=105一個(gè)變量除了數(shù)據(jù)類型以外,還有3種屬性:(1)存儲(chǔ)類別:auto、static、register、extern4種存儲(chǔ)類別。(2)作用域:指程序中可以引用該變量的區(qū)域。(3)生存期:指變量在內(nèi)存中的存儲(chǔ)期限。要注意存儲(chǔ)類別的用法。auto,static和register3種存儲(chǔ)類別只能用于變量的定義語(yǔ)句中,如:變量屬性小結(jié)autocharc;//字符型自動(dòng)變量,在函數(shù)內(nèi)定義staticinta;//靜態(tài)整型變量定義(局部或外部)registerintd;
//整型寄存器變量,在函數(shù)內(nèi)定義externintb;//聲明一個(gè)已定義的外部整型變量說(shuō)明:extern只能用來(lái)聲明已定義的外部變量,而不能用于變量的定義。一看到extern,就可以斷定這是變量聲明語(yǔ)句,而不是變量的定義語(yǔ)句。變量屬性總結(jié):(1)從作用域角度分,有局部變量和全局變量。它們采用的存儲(chǔ)類別如下:●局部變量自動(dòng)變量,即動(dòng)態(tài)局部變量(離開函數(shù),值就消失)靜態(tài)局部變量(離開函數(shù),值仍保留)寄存器變量(離開函數(shù),值就消失)形式參數(shù)(可以定義為自動(dòng)變量或寄存器變量)●全局變量靜態(tài)外部變量(有static,只限本文件引用)一般外部變量(無(wú)static,允許其他文件引用)(2)從變量存儲(chǔ)期來(lái)區(qū)分,有動(dòng)態(tài)存儲(chǔ)和靜態(tài)存儲(chǔ)兩種類型?!駝?dòng)態(tài)存儲(chǔ)--壽命短自動(dòng)變量(本函數(shù)內(nèi)有效)寄存器變量(本函數(shù)內(nèi)有效)形式參數(shù)●靜態(tài)存儲(chǔ)--壽命長(zhǎng)靜態(tài)局部變量(函數(shù)內(nèi)有效)靜態(tài)外部變量(本文件內(nèi)有效)外部變量(其他文件可引用)(3)從變量值存放的位置來(lái)區(qū)分,可分為●內(nèi)存中靜態(tài)存儲(chǔ)區(qū)靜態(tài)局部變量靜態(tài)外部變量(函數(shù)外部靜態(tài)變量)外部變量(可為其他文件引用)●內(nèi)存中動(dòng)態(tài)存儲(chǔ)區(qū):自動(dòng)變量和形式參數(shù)●CPU中的寄存器:寄存器變量(4)關(guān)于作用域和存儲(chǔ)期的概念:空間、時(shí)間。二者有聯(lián)系但不是同一回事。下頁(yè)兩個(gè)圖分別是作用域、存儲(chǔ)期的示意圖。(5)Static的作用:Static加于局部變量定義前,
使變量由動(dòng)態(tài)存儲(chǔ)方式改變?yōu)殪o態(tài)存儲(chǔ)方式--延長(zhǎng)生存期;但不改作用域。Static加于全局變量定義前,
使變量縮小作用域(局限于本文件),但仍為靜態(tài)存儲(chǔ)方式(不改生存期)。請(qǐng)注意,用auto,register,static定義變量時(shí),是在變量的數(shù)據(jù)類型定義基礎(chǔ)上加上這些關(guān)鍵字,而不能單獨(dú)使用。如“statica;”是不合法的,應(yīng)寫成諸如“staticinta;”的形式。3.7編譯預(yù)處理C++提供的預(yù)處理功能主要有以下3種:(1)宏定義(2)文件包含(3)條件編譯分別用宏定義命令、文件包含命令、條件編譯命令來(lái)實(shí)現(xiàn)。為了與一般C++語(yǔ)句相區(qū)別,這些命令以符號(hào)“?!遍_頭,而且末尾不包含分號(hào)。宏定義的作用是實(shí)現(xiàn)文本替換。有兩種格式:不帶參數(shù)的宏定義;帶參數(shù)的宏定義。1.不帶參數(shù)的宏定義不帶參數(shù)宏定義的格式如下:#define宏名字符串其中,define是關(guān)鍵字,“宏名”是一個(gè)標(biāo)識(shí)符,“字符串”是字符序列。該語(yǔ)句的意思是“宏名”代表“字符串”。執(zhí)行該預(yù)處理代碼時(shí),編譯系統(tǒng)將對(duì)程序語(yǔ)句中出現(xiàn)的“宏名”統(tǒng)統(tǒng)用“字符串”替代。3.7.1宏定義【例3.20】本程序中有多處要用到圓周率計(jì)算面積、周長(zhǎng)、體積,為了方便一次性修改圓周率,將圓周率定義為宏。//*****ex3_20.cpp*****#include<iostream>usingnamespacestd;
#definePI3.14
//定義宏名PI,將用3.14替代voidmain(){doubler,h;cout<<"請(qǐng)輸入柱體底面半徑r和高度h:";cin>>r>>h;cout<<"園柱體的周長(zhǎng)是:"<<2*PI*r<<endl;cout<<"園柱體的底面積是:"<<PI*r*r<<endl;cout<<"園柱體的體積是
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 ISO 17956:2025 EN Rolling bearings - Method for calculating the effective static safety factor for universally loaded rolling bearings
- 醫(yī)學(xué)合作研究協(xié)議書5篇
- 牛頭包船課程設(shè)計(jì)
- 海報(bào)插圖課程設(shè)計(jì)
- 十四五大數(shù)據(jù)產(chǎn)業(yè)發(fā)展規(guī)劃
- 2024有關(guān)消防演練活動(dòng)總結(jié)(34篇)
- 美術(shù)微課程設(shè)計(jì)與制作
- 幼兒園美食實(shí)踐課程設(shè)計(jì)
- 康復(fù)科護(hù)士的工作體會(huì)
- 有趣的音樂(lè)游戲課程設(shè)計(jì)
- 舞蹈興趣小組活動(dòng)記錄
- 醫(yī)院檢驗(yàn)科實(shí)驗(yàn)室生物安全程序文件SOP
- 建立強(qiáng)大的人際影響力與領(lǐng)導(dǎo)力
- 九年級(jí)歷史期末考試質(zhì)量分析
- 視覺(jué)傳達(dá)設(shè)計(jì)教資面試
- 三創(chuàng)賽獲獎(jiǎng)-非遺文化創(chuàng)新創(chuàng)業(yè)計(jì)劃書
- 華師大版八年級(jí)下冊(cè)數(shù)學(xué)全冊(cè)課件
- 慢性高血壓并發(fā)重度子癇前期1
- 常用工具的正確使用
- 管材管件供貨計(jì)劃、運(yùn)輸方案及保障措施及售后服務(wù)
- (2024年)腸梗阻完整版課件
評(píng)論
0/150
提交評(píng)論