面向?qū)ο笤O(shè)計(jì)與C++課件第3章_函數(shù)和編譯預(yù)處理-_第1頁(yè)
面向?qū)ο笤O(shè)計(jì)與C++課件第3章_函數(shù)和編譯預(yù)處理-_第2頁(yè)
面向?qū)ο笤O(shè)計(jì)與C++課件第3章_函數(shù)和編譯預(yù)處理-_第3頁(yè)
面向?qū)ο笤O(shè)計(jì)與C++課件第3章_函數(shù)和編譯預(yù)處理-_第4頁(yè)
面向?qū)ο笤O(shè)計(jì)與C++課件第3章_函數(shù)和編譯預(yù)處理-_第5頁(yè)
已閱讀5頁(yè),還剩106頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第3章 函數(shù)和編譯預(yù)處理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è)人從頭至尾地完成,更不可能把所有的內(nèi)容都放在一個(gè)主函數(shù)中。為了便于規(guī)劃、組織、編程和調(diào)試,一般的做法是把一個(gè)大的程序劃分為若干個(gè)程序模塊(即程序文件),每一個(gè)模塊實(shí)現(xiàn)一部分功能。不同的程序模塊可以由不同的人來(lái)完成。在程序進(jìn)行編譯時(shí),以程序模塊為編譯單位,即分別對(duì)每一個(gè)編譯單位進(jìn)行編譯。如果發(fā)現(xiàn)錯(cuò)誤,可以在本程序模塊范圍內(nèi)查錯(cuò)并改正。在分別通過(guò)編譯后,才進(jìn)行連接,把各模

2、塊的目標(biāo)文件以及系統(tǒng)文件連接在一起形成可執(zhí)行文件。在一個(gè)程序文件中可以包含若干個(gè)函數(shù)。無(wú)論把一個(gè)程序劃分為多少個(gè)程序模塊,只能有一個(gè)main函數(shù)。程序總是從main函數(shù)開(kāi)始執(zhí)行的。在程序運(yùn)行過(guò)程中,由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。在C語(yǔ)言中沒(méi)有類和對(duì)象,在程序模塊中直接定義函數(shù)??梢哉J(rèn)為,一個(gè)C程序是由若干個(gè)函數(shù)組成的,C語(yǔ)言被認(rèn)為是面向函數(shù)的語(yǔ)言。C+面向過(guò)程的程序設(shè)計(jì)沿用了C語(yǔ)言使用函數(shù)的方法。在C+面向?qū)ο蟮某绦蛟O(shè)計(jì)中,主函數(shù)以外的函數(shù)大多是被封裝在類中的。主函數(shù)或其他函數(shù)可以通過(guò)類對(duì)象調(diào)用類中的函數(shù)。無(wú)論是C還是C+,程序中的各項(xiàng)操作基本上都是由函數(shù)來(lái)實(shí)現(xiàn)的,程序編寫者要

3、根據(jù)需要編寫一個(gè)個(gè)函數(shù),每個(gè)函數(shù)用來(lái)實(shí)現(xiàn)某一功能。因此,讀者必須掌握函數(shù)的概念以及學(xué)會(huì)設(shè)計(jì)和使用函數(shù)。 “函數(shù)”這個(gè)名詞是從英文function翻譯過(guò)來(lái)的,其實(shí)function的原意是“功能”。顧名思義,一個(gè)函數(shù)就是一個(gè)功能。在實(shí)際應(yīng)用的程序中,主函數(shù)寫得很簡(jiǎn)單,它的作用就是調(diào)用各個(gè)函數(shù),程序各部分的功能全部都是由各函數(shù)實(shí)現(xiàn)的。主函數(shù)相當(dāng)于總調(diào)度,調(diào)動(dòng)各函數(shù)依次實(shí)現(xiàn)各項(xiàng)功能。開(kāi)發(fā)商和軟件開(kāi)發(fā)人員將一些常用的功能模塊編寫成函數(shù),放在函數(shù)庫(kù)中供公共選用。程序開(kāi)發(fā)人員要善于利用庫(kù)函數(shù),以減少重復(fù)編寫程序段的工作量。圖3.是一個(gè)程序中函數(shù)調(diào)用的示意圖。 圖3.main()func1()func2()f

4、unc3()func5()func4()例31 在主函數(shù)中調(diào)用其他函數(shù)。#include /*ex3_1.cpp*int calc_sum(int n) /定義calc_sum()函數(shù) int k,s; s=0; for (k=1;k=n;k+) s=s+k; return s; void print_word(void) /定義print_word()函數(shù) coutHello,C+!n; if (n1) coutthe sum is: calc_sum(n)endl; /調(diào)用calc_sum()函數(shù) print_word(); /調(diào)用rint_word()函數(shù) 若用戶從鍵盤輸入的數(shù)是4, 運(yùn)

5、行情況如下:the sum is:10Hello,C+! 從用戶使用的角度看,函數(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 定義無(wú)參函數(shù)的一般形式定義函數(shù)的一般形式如下:類型標(biāo)識(shí)符 函數(shù)名(形式參數(shù)列表) 聲明語(yǔ)句執(zhí)行語(yǔ)句【例3.1】的print_word函數(shù)是無(wú)參函數(shù),它的定義中首句也可以寫成:

6、void print_word( ) /定義print_word()函數(shù)的首部; 或:void print_word(void) /定義print_word()函數(shù)的首部【例3.1】的calc_sum函數(shù)是有參函數(shù),不過(guò)它只有一個(gè)參數(shù),參數(shù)的類型是整數(shù)類型。 int calc_sum(int n) /定義calc_sum()函數(shù) C+要求在定義函數(shù)時(shí)必須指定函數(shù)的類型。下面的函數(shù)f則有兩個(gè)參數(shù),第一個(gè)是整數(shù)類型,第二個(gè)是單精度實(shí)數(shù)類型,而函數(shù)的返回值是雙精度實(shí)數(shù)類型:double f(int x, float y) /定義f( )函數(shù)的首部 (1)對(duì)庫(kù)函數(shù)的聲明其實(shí),對(duì)庫(kù)函數(shù)的聲明語(yǔ)句已經(jīng)寫在

7、有關(guān)包含文件中了,因此只要在程序文件頭用include語(yǔ)句將這些包含文件包含到本程序中來(lái),就完成了對(duì)庫(kù)函數(shù)的聲明。 (2)對(duì)自定義函數(shù)的聲明必須在調(diào)用某自定義函數(shù)的語(yǔ)句之前寫上如下聲明語(yǔ)句:函數(shù)類型關(guān)鍵字 函數(shù)名(參數(shù)1類型,參數(shù)1名稱,參數(shù)2類型,參數(shù)2名稱); 3.2.2 函數(shù)的聲明(2)對(duì)自定義函數(shù)的聲明 (續(xù))也可以在聲明語(yǔ)句中略去參數(shù)的名稱,或?qū)懸粋€(gè)任意名稱,這叫做函數(shù)原型(function prototype),即聲明函數(shù)原型。函數(shù)原型有下列兩種表示形式:函數(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+中的

8、函數(shù)原型說(shuō)明了函數(shù)的類型、函數(shù)名、函數(shù)各形式參數(shù)類型。使用函數(shù)原型是C和C+的一個(gè)重要特點(diǎn)。 3.2.2 函數(shù)的聲明【例3.2】 對(duì)被調(diào)函數(shù)做聲明的示例。#include /*ex3_2.cpp*void main() float add(float x,float y); /對(duì)add函數(shù)作聲明 float subtract(float,float); /對(duì)subtract函數(shù)作聲明,用函數(shù)原型 double multiply(float p,float q); /對(duì)multiply函數(shù)作聲明,參數(shù)名任意 float a,b,c1,c2; double c3; cout ab; c1=add(

9、a,b); c2=subtract(a,b); c3=multiply(a,b); cout c1,c2,c3endl; float add(float x,float y) /定義add函數(shù) float z; z=x+y; return (z);float subtract(float x,float y) /定義subtract函數(shù) float z; z=x-y; return (z);double multiply(float x,float y) /定義multiply函數(shù) double z; z=x*y; return (z);運(yùn)行情況如下:please input a,b:4.25

10、 2.00 6.25,2.25,8.5 說(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ù)值的類型。既然函數(shù)有返回值,這個(gè)值當(dāng)然應(yīng)屬于某一

11、個(gè)確定的類型,應(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)換。第(1)種形式是基本的形式。為了便于閱讀程序,也允許在函數(shù)原型中加上參數(shù)名,就成了第(2)種形式。但編譯系統(tǒng)并不檢查參數(shù)名。因此參數(shù)名是什么都無(wú)所謂。上面程序中的聲明也可以寫成float add(float a,float b); /參數(shù)名不用x、y,而用a、b 效果完全相同。應(yīng)當(dāng)保證函數(shù)原型與函數(shù)首部寫法上的一致,即函數(shù)類型、函數(shù)名、參數(shù)個(gè)數(shù)、參數(shù)類型和參數(shù)順序必須相同。在函數(shù)調(diào)用時(shí)函數(shù)名、實(shí)參類型和實(shí)

12、參個(gè)數(shù)應(yīng)與函數(shù)原型一致。說(shuō)明: (1) 前面已說(shuō)明,如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必加以聲明。因?yàn)榫幾g系統(tǒng)已經(jīng)事先知道了已定義的函數(shù)類型,會(huì)根據(jù)函數(shù)首部提供的信息對(duì)函數(shù)的調(diào)用作正確性檢查。有經(jīng)驗(yàn)的程序編制人員一般都把main函數(shù)寫在最前面,這樣對(duì)整個(gè)程序的結(jié)構(gòu)和作用一目了然,統(tǒng)覽全局,然后再具體了解各函數(shù)的細(xì)節(jié)。此外,用函數(shù)原型來(lái)聲明函數(shù),還能減少編寫程序時(shí)可能出現(xiàn)的錯(cuò)誤。由于函數(shù)聲明的位置與函數(shù)調(diào)用語(yǔ)句的位置比較近,因此在寫程序時(shí)便于就近參照函數(shù)原型來(lái)書寫函數(shù)調(diào)用,不易出錯(cuò)。所以應(yīng)養(yǎng)成對(duì)所有用到的函數(shù)作聲明的習(xí)慣。這是保證程序正確性和可讀性的重要環(huán)節(jié)。(2) 函數(shù)聲明的位置可

13、以在調(diào)用函數(shù)所在的函數(shù)中,也可以在函數(shù)之外。如果函數(shù)聲明放在函數(shù)的外部,在所有函數(shù)定義之前,則在各個(gè)主調(diào)函數(shù)中不必對(duì)所調(diào)用的函數(shù)再作聲明。例如: char letter(char,char); /本行和以下兩行函數(shù)聲明在所有函數(shù)之前且在函數(shù)外部float f(float,float); /因而作用域是整個(gè)文件 int i(float, float); int main( ) /在main函數(shù)中不必對(duì)它所調(diào)用的函數(shù)作聲明char letter(char c1,char c2) /定義letter函數(shù)float f(float x,float y) /定義f函數(shù) int i(float j,flo

14、at k) /定義i函數(shù)如果一個(gè)函數(shù)被多個(gè)函數(shù)所調(diào)用,用這種方法比較好,不必在每個(gè)主調(diào)函數(shù)中重復(fù)聲明。函數(shù)調(diào)用的一般形式:函數(shù)名(實(shí)際參數(shù)列表) 如果是調(diào)用無(wú)參函數(shù),則“實(shí)參表列”可以沒(méi)有,但括號(hào)不能省略。如果實(shí)參表列包含多個(gè)實(shí)參,則各參數(shù)間用逗號(hào)隔開(kāi)。實(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)用方式:. 函數(shù)語(yǔ)句把函數(shù)調(diào)用單獨(dú)作為一個(gè)語(yǔ)句,并不要求函數(shù)帶回一個(gè)值,只是要求函數(shù)完成一定的操作。如【例3.1】中的p

15、rint_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ù)(formal parameter),簡(jiǎn)稱形參。形參是無(wú)內(nèi)存單元(因而不存在)的任何合法標(biāo)識(shí)符。實(shí)參:在調(diào)用一個(gè)函數(shù)時(shí),調(diào)用語(yǔ)句的函數(shù)名后面括號(hào)中的參數(shù)稱為實(shí)際參數(shù)(actual parameter),簡(jiǎn)稱實(shí)

16、參。實(shí)參是實(shí)際存在(因而有特定值)的常量、變量或表達(dá)式。 【例3.3】 形參和實(shí)參及其數(shù)據(jù)傳遞。#include /*ex3_3.cpp* using namespace std;float volume(float r,float h) /定義有參函數(shù)volume求圓柱體體積,r和h是形參 float v;v=3.14*r*r*h; return (v);void main()float a,b,c;cout a b;c=volume(a,b); /調(diào)用函數(shù)volume,a和b是實(shí)參。函數(shù)值賦給變量ccout The volume is cendl; 運(yùn)行情況如下:please input

17、two float nukbers:2.0 5.0 The volume is 62.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í)參與形參的類

18、型應(yīng)相同或賦值兼容。兩種參數(shù)類型完全一致無(wú)疑是完全合法、正確的。如果實(shí)參為整型而形參為實(shí)型,或者相反,則按不同類型數(shù)值的賦值規(guī)則進(jìn)行轉(zhuǎn)換,原則上不出現(xiàn)語(yǔ)法錯(cuò)誤,但結(jié)果可能帶來(lái)某些非期望的誤差。例如實(shí)參a的值是3.5,而被調(diào)函數(shù)的形參x為整型,則調(diào)用該函數(shù)時(shí)會(huì)將3.5轉(zhuǎn)化為整數(shù)3,然后送到形參x,故x得到的是3,由3計(jì)算出的函數(shù)值與人們期望由3.5計(jì)算出的函數(shù)值一般是有差別的。但字符型與整型可以互相通用。 3.3.2 參數(shù)的值傳遞 值傳遞參數(shù)的實(shí)現(xiàn)是系統(tǒng)將實(shí)參拷貝一個(gè)副本給形參,拷貝后兩者就斷開(kāi)關(guān)系。在被調(diào)函數(shù)中,形參可以被改變,但這只影響副本中的形參值,而不影響調(diào)用函數(shù)的實(shí)參值。所以這類函數(shù)有

19、對(duì)原始數(shù)據(jù)保護(hù)的作用。換一句話說(shuō),這種參數(shù)傳遞機(jī)制是單向影響,即只能由實(shí)參將值傳給形參(實(shí)參影響形參);而形參在函數(shù)中的值如果發(fā)生修改,不會(huì)反過(guò)來(lái)影響與之對(duì)應(yīng)的實(shí)參。 【例3.4】 參數(shù)值傳遞的演示。#include /*ex3_4.cpp* using namespace std;int max(int x,int y) /定義有參函數(shù)max求兩數(shù)最大值,x和y是形參 float m;coutThe initial x,y:x,yy?x:y;x=2*x;y=y+1;coutThe new x,y:x,yendl;return (m);void main()float a,b,c;cout a

20、 b;c=max(a,b); /調(diào)用函數(shù)max,a和b是實(shí)參,函數(shù)值賦給變量c。cout The maxinum is: cendl;cout After calling fuction,a,b:a,bendl;運(yùn)行情況如下:please input two integer numbers:3 8 The initial x,y:3,8The new x,y:6 9The maxinum is:8After calling fuction,a,b:3,83.3.3 參數(shù)的地址傳遞除了3.3.2小節(jié)介紹的值傳遞參數(shù)方式外,函數(shù)調(diào)用還有一種特殊的值傳遞形式,即傳遞的值不是一般的數(shù)值,而是一些內(nèi)存單

21、元地址編號(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)存單元地址(即兩者

22、對(duì)應(yīng)同一個(gè)內(nèi)存單元),稱作形參和實(shí)參地址結(jié)合,兩者合二為一。這樣一來(lái),任何時(shí)候形參的值等于實(shí)參的值;而實(shí)參的值也等于形參的值。因此,形參在函數(shù)中發(fā)生變化后,也會(huì)引起實(shí)參跟著變化(因?yàn)樗鼈兪抢壴谝黄鸬?,一體化的)。這就意味著按地址傳遞的方式,在調(diào)用剛開(kāi)始時(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)值。通常調(diào)用函數(shù)時(shí),要為函數(shù)的每個(gè)形式參數(shù)給定相應(yīng)的值。例如下面的delay( )函數(shù)作用是作時(shí)間延遲,在沒(méi)有使用

23、默認(rèn)值參數(shù)的情況下,是按如下普通方式聲明和定義的: 【例3.5】 延遲函數(shù)的使用。#include /*ex3_5.cpp* void delay(int loop); /函數(shù)聲明void main( ) coutbeginendl; delay(1000); /函數(shù)調(diào)用 coutendendl;void delay(int loop) /函數(shù)定義 if (loop=0) return; for(int i=0;iloop;i+) coutiendl; /輸出i的值為了清楚看到程序執(zhí)行的情況 如果每次調(diào)用延遲時(shí)間基本一樣,可以使用C+中默認(rèn)值參數(shù)函數(shù)形式來(lái)解決問(wèn)題。解決的方法就是在函數(shù)的聲明(

24、或定義)時(shí)給定默認(rèn)值即可。具體做法只要把delay()函數(shù)的聲明改為下列形式: void delay(int loop=1000); /指定參數(shù)默認(rèn)值為1000以后如果需要延遲相同時(shí)間1000,都可以不必指定實(shí)參的值而直接調(diào)用函數(shù):delay(); /不給定實(shí)參,形參將得到默認(rèn)值1000 delay(500); /給定實(shí)參,形參將得到所給的值500 如果有多個(gè)形參,可以使每個(gè)形參有一個(gè)默認(rèn)值;也可以只對(duì)一部分形參指定默認(rèn)值。如前面的求圓柱體體積的函數(shù)volume,可以這樣聲明:float volume(float r,float h=8.5); /只對(duì)形參h指定默認(rèn)值8.5這時(shí)函數(shù)調(diào)用可采用以

25、下形式:volume(6.0); /相當(dāng)于volume(6.0,8.5)volume(6.0,7.2); /r的值為6.0,h的值為7.2 C+中實(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ù)。見(jiàn)圖3.2示意。 圖3.2 在程序中實(shí)現(xiàn)函數(shù)嵌套

26、調(diào)用時(shí),需要注意的是: 在調(diào)用函數(shù)之前,需要對(duì)每一個(gè)被調(diào)用的函數(shù)作聲明(除非定義在前,調(diào)用在后)?!纠?.6】編程求組合,其中求組合的功能要求用函數(shù)完成。分析:根據(jù)組合的計(jì)算公式,知組合函數(shù)有兩個(gè)形參:m和n,可以用自定義函數(shù)comb(int n,int m)表示求組合。而在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 /*ex3_6.cpp*using name

27、space std;long fac(int k) / 定義求階乘的函數(shù)long f=1; int i; for(i=1;i=k;i+) f = f*i; return f;long comb(int n, int m) /定義組合函數(shù)long c; c=fac(m)/(fac(n)*fac(m-n);/ 嵌套調(diào)用階乘函數(shù) return c;void main() int n,m; long c;coutplease input two integer numbers:m,nmn;c=comb(n,m); / 調(diào)用組合函數(shù)combcoutc=c0,可用n*fac(n-1)表示,即fac(n)的

28、函數(shù)體內(nèi)將遞歸調(diào)用fac()本身;但一旦參數(shù)n為0時(shí),則終止調(diào)用函數(shù)自身并給出函數(shù)值1。程序如下: using namespace std;#include /*ex3_7.cpp*long fac(int n)long f; if (n=0) f=1; else f=n*fac(n-1); / 遞歸調(diào)用,求(n-1)! return f;void main( )long y; int n; coutplease input a integer n n; y=fac(n); /調(diào)用fac(n)求n!coutn=n,y=yendl;運(yùn)行時(shí),如果輸入:3, 運(yùn)行結(jié)果如下:n=3, y=6遞歸調(diào)用及

29、返回過(guò)程如圖3.5所示,圖中的數(shù)字序號(hào)表示遞歸調(diào)用和返回的先后順序。 圖3.5 求3!的遞歸過(guò)程 fac(3 )fac( )n=33*fac(2)return 6main( )fac( )n=22*fac(1)return 2n=0fac(0)=1return 1n1*fac(0) return 1fac( )fac( )從求n!的遞歸程序中可以看出,遞歸定義有兩個(gè)要素:(1) 遞歸終止條件。也就是所描述問(wèn)題的最簡(jiǎn)單情況,它本身不再使用遞歸的定義,即程序必須終止。如上例,當(dāng)n=0時(shí),fac(n)=1,不再使用f(n-1)來(lái)定義。(2) 遞歸定義使問(wèn)題向終止條件轉(zhuǎn)化的規(guī)則。遞歸定義必須能使問(wèn)題越

30、來(lái)越簡(jiǎn)單,即參數(shù)越來(lái)越接近終止條件的參數(shù);達(dá)到終止條件參數(shù)時(shí)函數(shù)有確定的值。如上例,f(n)由f(n-1)定義,越來(lái)越靠近f(0),即參數(shù)越來(lái)越接近終止條件參數(shù)0;達(dá)到終止條件參數(shù)時(shí)函數(shù)有確定的值是f(0)=1。 【例3.8】 漢諾塔問(wèn)題 漢諾塔(Tower of Hanoi)問(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í)候不允許大的金片壓在小的金片

31、上面。 圖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ù)原形為

32、:void hanoi(int n,char x,char y,char z)根據(jù)解題步驟,可以寫出求解n個(gè)金片的漢諾塔函數(shù)如下:#include /*ex3_8.cpp*using namespace std;void hanoi(int n,char x,char y,char z) if (n=1) /n=1時(shí),直接將金片從x移動(dòng)到z cout x z 1時(shí) hanoi(n-1,x,z,y); /先將n-1個(gè)金片從借助z移動(dòng)到y(tǒng) cout x z 1時(shí),就遞歸調(diào)用hanoi(),每次n減1。最后當(dāng)n=1時(shí),直接移動(dòng)該金片就可以了。 主函數(shù)如下: void main() int n; co

33、ut input n: n; hanoi(n,a,b,c); / n個(gè)金片從a針借助b針移動(dòng)到c針 雖然遞歸調(diào)用在寫程序時(shí)很簡(jiǎn)單,但執(zhí)行起來(lái)卻很復(fù)雜(時(shí)間、存儲(chǔ)空間都開(kāi)銷大)。對(duì)于漢諾塔問(wèn)題程序的執(zhí)行過(guò)程分析比較復(fù)雜,有興趣的讀者可參閱教材對(duì)3個(gè)盤情景的分析(圖3.7 及其相應(yīng)文字?jǐn)⑹觯?調(diào)用函數(shù)時(shí)需要一定的時(shí)間和空間的開(kāi)銷。下圖表示的是一般函數(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)用的效率。C+提供一種提高效率的方法,即在編譯時(shí)將所調(diào)用函數(shù)的代碼直接嵌入到主調(diào)函數(shù)中,而不是將流程轉(zhuǎn)出去。

34、這種嵌入到主調(diào)函數(shù)中的函數(shù)稱為內(nèi)置函數(shù)(inline function),又稱內(nèi)嵌函數(shù)。在有些書中把它譯成內(nèi)聯(lián)函數(shù)。指定內(nèi)置函數(shù)的方法很簡(jiǎn)單,只需在函數(shù)首行的左端加一個(gè)關(guān)鍵字inline即可?!纠?.9】 判斷用戶從鍵盤輸入的系列字符是數(shù)字字符還是其它字符的函數(shù)is_number()。#include /*ex3_9a.cpp*int is_number(char); /函數(shù)聲明void main( ) char c; while (c=cin.get()!=n) if (is_number(c) /調(diào)用一個(gè)小函數(shù)coutyou enter a digit n;else cout=0& ch=

35、9)?1:0; 程序中不斷到設(shè)備中讀取數(shù)據(jù),頻繁調(diào)用is_number()函數(shù)。為了避免頻繁調(diào)用函數(shù),提高執(zhí)行效率,可以將【例3.9】程序改為:#include /*ex3_9b.cpp*void main() char c; while (c=cin.get()!=n) if (c=0& c=9)?1:0) /修改處:直接計(jì)算表達(dá)式 coutyou enter a digit n; else coutyou enter a non-digit n; 修改后的程序在if語(yǔ)句中用表達(dá)式替換了函數(shù)調(diào)用。在程序運(yùn)行上,提高了一些執(zhí)行效率,因?yàn)槊馊チ舜罅康暮瘮?shù)調(diào)用開(kāi)銷。但是,由于is_number函數(shù)

36、比相應(yīng)的表達(dá)式可讀性好,所以修改后的代碼可讀性降低,尤其若程序中多處出現(xiàn)is_number的替換時(shí),會(huì)大大降低可讀性。我們希望既要用函數(shù)調(diào)用來(lái)體現(xiàn)其結(jié)構(gòu)化和可讀性,又要使效率盡可能地高。為了盡量做到兩全其美,C+中引入內(nèi)置函數(shù)這個(gè)方法。3.5.2 定義和使用內(nèi)置函數(shù)內(nèi)置函數(shù)的定義格式如下: inline 函數(shù)名(形參列表) /函數(shù)體 內(nèi)置函數(shù)的聲明格式如下:inline 函數(shù)名(形參類型表);其實(shí),內(nèi)置函數(shù)只要在開(kāi)頭一次性聲明為inline即可,而后面的函數(shù)定義仍可寫成一般函數(shù)定義的形式,編譯器也會(huì)將函數(shù)視為內(nèi)置函數(shù)。對(duì)【例3.9】使用內(nèi)置函數(shù)來(lái)解決,代碼可以寫成下列形式:#include /

37、*ex3_9c.cpp*inline int is_number(char);/inline函數(shù)聲明void main( ) char c; while (c=cin.get()!=n) if (is_number(c) /調(diào)用一個(gè)小函數(shù)coutyou enter a digit n;else cout=0& ch=9)?1:0; 關(guān)于內(nèi)置函數(shù)的說(shuō)明:(1)內(nèi)置函數(shù)與一般函數(shù)的區(qū)別在于函數(shù)調(diào)用的處理。一般函數(shù)進(jìn)行調(diào)用時(shí),要將程序執(zhí)行到被調(diào)用函數(shù)中,然后返回到主調(diào)函數(shù)中;而內(nèi)置函數(shù)在調(diào)用時(shí),是將調(diào)用部分用內(nèi)置函數(shù)體來(lái)替換。(2)內(nèi)置函數(shù)必須先聲明后調(diào)用。因?yàn)槌绦蚓幾g時(shí)要對(duì)內(nèi)置函數(shù)替換,所以在內(nèi)置

38、函數(shù)調(diào)用之前必須聲明是內(nèi)置的(inline),否則將會(huì)像一般函數(shù)那樣產(chǎn)生調(diào)用而不是進(jìn)行替換操作。(3)在內(nèi)置函數(shù)中,不能含有復(fù)雜的結(jié)構(gòu)控制語(yǔ)句,如switch、for和while。如果內(nèi)置函數(shù)有這些語(yǔ)句,則編譯器將該函數(shù)視同一般函數(shù)那樣產(chǎn)生函數(shù)調(diào)用。(4)遞歸函數(shù)不能用作內(nèi)置函數(shù)。(5)以后講到的類中,所有定義在說(shuō)明內(nèi)部的函數(shù)都是內(nèi)置函數(shù)。3.6.1 變量的作用域 首先將變量按作用域大小分類,可以分為局部變量和全局變量。C+中并不是所有的變量對(duì)任何函數(shù)都是可知的。一些變量在整個(gè)程序或文件中都是可見(jiàn)的,這些變量作用域大,被稱為全局變量。一些變量只能在一個(gè)函數(shù)或塊中可見(jiàn),這些變量作用域小,被稱為局

39、部變量。變量作用域的大小和它們的存儲(chǔ)區(qū)域有關(guān)。全局變量存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū)(也稱為靜態(tài)存儲(chǔ)區(qū)),它在程序運(yùn)行的時(shí)候被分配存儲(chǔ)空間,當(dāng)程序結(jié)束時(shí)釋放存儲(chǔ)空間。局部變量存儲(chǔ)在堆棧數(shù)據(jù)區(qū),當(dāng)程序執(zhí)行到該變量聲明的函數(shù)(或程序塊)時(shí)才開(kāi)辟存儲(chǔ)空間,當(dāng)函數(shù)(或程序塊)執(zhí)行完畢時(shí)釋放存儲(chǔ)空間。而決定變量作用域大小的根源是它的定義位置。3.6 變量和函數(shù)的屬性1局部變量局部變量是指定義在函數(shù)或程序塊內(nèi)的變量,它們的作用域分別在所定義的函數(shù)體或程序塊內(nèi)。下面是一些局部變量的實(shí)例:void main()int x ; /x為函數(shù)級(jí)的局部變量。其作用域?yàn)閙ain()函數(shù)內(nèi) int y ; /y為語(yǔ)句塊級(jí)的局部變量,其

40、作用域?yàn)樵搲K內(nèi) void fun( ) char ch ; /ch為函數(shù)級(jí)局部變量,其作用域?yàn)閒un()函數(shù)內(nèi) 【例3.10】 局部變量的使用。#include /*ex3_10.cpp* double fun1(double a, double b) /fun1函數(shù)中3個(gè)局部變量a、b、c double c; c=a+b; return c; double fun2(double a,double b) /fun2函數(shù)中3個(gè)局部變量a、b、c double c; c=a*b; return c;void main()/main函數(shù)中3個(gè)局部變量a、b、cdouble a,b,c; couta

41、b; c=fun1(a,b); couta+b=cendl; c=fun2(a,b); couta*b=cendl;程序運(yùn)行結(jié)果如下:input two numbers:3.5 4 a+b=7.5 a*b=14注意:不同范圍的局部變量可以同名,但同一范圍內(nèi)不允許同名變量出現(xiàn)(否則有沖突);上例每個(gè)函數(shù)中都定義了相同名稱的局部變量,比如有3個(gè)a;但這個(gè)范圍中定義的a與另一個(gè)范圍中定義的a并不是同一個(gè)對(duì)象,即“此a非彼a”。全局變量是定義在函數(shù)以外的變量(一般的全局變量也稱外部變量,而一類特殊的全局變量則叫靜態(tài)全局變量),它們?cè)瓌t上對(duì)整個(gè)文件的函數(shù)都是可見(jiàn)的,甚至對(duì)本程序的其它文件的函數(shù)也可見(jiàn);但

42、通常條件下的全局變量作用域是從定義變量的位置到該文件的結(jié)束。 2全局變量【例3.11】 全局變量的使用#include /*ex3_11.cpp* int a; /a的作用域?yàn)檎麄€(gè)文件void fun1(); /聲明fun1函數(shù)void main() coutaendl; /main函數(shù)中使用了全局變量afun1(); /調(diào)用fun1函數(shù)coutaendl; /main函數(shù)中再次使用全局變量avoid fun1() a=5; / fun1函數(shù)中使用全局變量a 程序運(yùn)行結(jié)果如下:05 說(shuō)明:(1)上例中,在主函數(shù)中第一次輸出變量a時(shí),a還沒(méi)有賦值,但是執(zhí)行結(jié)果顯示0。 (2)全局變量可以定義在任

43、何位置,但其作用域是從定義的位置開(kāi)始到文件的末尾。而定義在文件中間的全局變量就只能被其下面的函數(shù)所使用,全局變量定義之前的所有函數(shù)不會(huì)知道該變量。 (3)全局變量為函數(shù)間數(shù)據(jù)的傳遞提供了通道。由于全局變量可以被其定義后的函數(shù)所使用,所以可以使用全局變量進(jìn)行函數(shù)間數(shù)據(jù)的傳遞。而且這種傳遞數(shù)據(jù)的方法可以傳遞多個(gè)數(shù)據(jù)的值?!纠?.12】 分別寫兩個(gè)函數(shù)求給定兩個(gè)數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù)。分析:由于求最小公倍數(shù)要依賴于最大公約數(shù),所以應(yīng)先求最大公約數(shù)。故應(yīng)將求最大公約數(shù)的函數(shù)寫在前面,求最小公倍數(shù)的函數(shù)放在后面。#include /*ex3_12.cp

44、p* int greatest_common_divisor(int,int);/聲明求最大公約數(shù)的函數(shù)int lease_common_multiple(int,int); /聲明求最小公倍數(shù)的函數(shù)int max , min; /全局變量分別存放最大公約數(shù)、最小公倍數(shù)void main( ) int a; int b; coutab; greatest_common_divisor(a,b); lease_common_multiple(a,b); cout the greatest common divisor is :maxendl; /使用全局變量max cout the lease

45、common multiple is :minendl; /使用全局變量minint greatest_common_divisor(int x,int y) int t;int r; if (xy) t=x;x=y;y=t; r=x%y; while(r!=0) x=y; y=r; r=x%y; max=y; return max;/使用全局變量maxint lease_common_multiple(int x,int y) min=x*y/max; /使用全局變量max求全局變量min, return min; /返回全局變量min 程序運(yùn)行結(jié)果如下: input a,b:36 15 t

46、he greatest common divisor is :3the lease common multiple is :180本例中利用全局變量max和min存儲(chǔ)最大公約數(shù)和最小公倍數(shù)。最大公約數(shù)是在函數(shù)greatest_common_divisor( )中賦給max的;最小公倍數(shù)是在函數(shù)lease_common_multiple()中賦給min的,而max和min又在main()函數(shù)中使用。本程序的整個(gè)過(guò)程就是利用全局變量max和min由greatest_common_divisor()函數(shù)和lease_common_multiple()函數(shù)向main()函數(shù)傳遞數(shù)據(jù)實(shí)現(xiàn)的。(4)其它文

47、件也可以使用文件外定義的全局變量,但要求該變量是外部變量類型的全局變量,而且要求在使用該變量的文件中要有對(duì)該變量的聲明。外部變量跨文件使用的例子,請(qǐng)參考本章后面的【例3.16】。(5)全局變量降低了函數(shù)的通用性,建議不在必要時(shí)不要使用全局變量。因?yàn)槿绻瘮?shù)在執(zhí)行的時(shí)候使用了全局變量,那么其他程序使用該函數(shù)時(shí)也必須將該全局變量一起移過(guò)去。另外,全局變量在程序執(zhí)行的全部過(guò)程都占用存儲(chǔ)空間,而不是需要時(shí)才開(kāi)辟存儲(chǔ)空間。 3重名局部變量和全局變量作用域規(guī)則在C+中,雖然不允許相同作用域的變量同名,但允許不同作用域的變量同名。那么在一個(gè)特定的位置引用到某個(gè)有重名的變量時(shí),到底是使用哪個(gè)變量呢?這由如下重

48、名變量作用域規(guī)則決定:在某個(gè)作用域范圍內(nèi)定義的變量在該范圍的子范圍內(nèi)可以定義重名變量,這時(shí)原定義的變量在子范圍內(nèi)是不可見(jiàn)的,但是它還存在,只是在子范圍內(nèi)由于出現(xiàn)了重名的變量而被暫時(shí)隱藏起來(lái),過(guò)了子范圍后,它又是可見(jiàn)的。 【例3.13】 函數(shù)中變量和程序塊中變量重名#include /*ex3_13.cpp*void main( ) int a=1,b=2,c=3; couta,b,cendl; int b=4; couta,b,cendl; a=b; int c; c=b; couta,b,cendl; couta,b,cendl; couta,b,cendl; 程序運(yùn)行結(jié)果如下:1,2,31

49、,4,34,4,44,4,34,2,3 【例3.14】 全局變量和局部變量重名#include /*ex3_14.cpp* void fun1( ); float x=3.5; void main( ) float x; coutx; coutx in main is :xendl; fun1( ); coutx in main is :xendl; void fun1() coutx in fun1 is :xendl; 運(yùn)行結(jié)果:input a data:6.6 x in main is :6.6x in fun1 is :3.5x in main is :6.6 從變量的空間屬性考慮變量

50、有作用域的概念。那么,從變量的時(shí)間屬性考慮變量還有存儲(chǔ)期(storage duration,也稱生命期)的概念,存儲(chǔ)期即變量值在內(nèi)存中存在的時(shí)間。而變量的存儲(chǔ)期是由變量的存儲(chǔ)類別決定的,有兩種存儲(chǔ)類別:動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式。 3.6.2 變量的生存期 1短生存期變量動(dòng)態(tài)存儲(chǔ)方式所謂動(dòng)態(tài)存儲(chǔ)方式,是指在程序運(yùn)行期間動(dòng)態(tài)地分配存儲(chǔ)空間給變量的方式。這類變量存儲(chǔ)在動(dòng)態(tài)存儲(chǔ)空間(堆或棧),執(zhí)行其所在函數(shù)或程序塊時(shí)開(kāi)辟存儲(chǔ)空間,函數(shù)或程序塊結(jié)束時(shí)釋放存儲(chǔ)空間,生存期為函數(shù)或程序塊的運(yùn)行期間,主要有:函數(shù)的形參和函數(shù)或程序塊中定義的局部變量(未用static聲明)。使用動(dòng)態(tài)存儲(chǔ)方式的變量有兩種:自動(dòng)

51、變量和寄存器類變量。 (1)自動(dòng)變量:函數(shù)中的局部變量默認(rèn)是自動(dòng)變量,存儲(chǔ)在動(dòng)態(tài)數(shù)據(jù)存儲(chǔ)區(qū)。自動(dòng)變量可以用關(guān)鍵字auto作為存儲(chǔ)類別的聲明。自動(dòng)變量的生存期為函數(shù)或程序塊執(zhí)行期間,作用域也是其所在函數(shù)或程序塊。例如:int fun() auto int a; /a為自動(dòng)類變量 實(shí)際編程過(guò)程中,關(guān)鍵字“auto”可以省略。例如上述自動(dòng)變量也可聲明為下面形式:int fun() int a; (2)寄存器變量:寄存器變量也是動(dòng)態(tài)變量,可以用register作為存儲(chǔ)類別的聲明。寄存器變量存儲(chǔ)在CPU的通用寄存器中,因此訪問(wèn)效率高。寄存器變量的生存期和作用域?yàn)槠涠x所在的函數(shù)或程序塊。一般情況下,將局

52、部最常用到的變量聲明為寄存器變量,如循環(huán)變量。下面main()函數(shù)中的循環(huán)變量i就使用了寄存器變量:#include void main() register int i; int sum=0; for(i=1;i=100;i+) sum+=i; cout1+2+.+100=sumendl;程序運(yùn)行結(jié)果如下:1+2+.+100=5050寄存器變量的使用應(yīng)注意以下問(wèn)題:(1)寄存器變量不宜定義過(guò)多。計(jì)算機(jī)中寄存器數(shù)量是有限的,不能允許所有的變量都為寄存器變量。如果寄存器變量過(guò)多或通用寄存器被其他數(shù)據(jù)使用,那么系統(tǒng)將自動(dòng)把寄存器變量轉(zhuǎn)換成自動(dòng)變量。(2)寄存器變量的數(shù)據(jù)長(zhǎng)度與通用寄存器的長(zhǎng)度相當(dāng)。

53、一般是char型和int型變量。 2長(zhǎng)生存期變量靜態(tài)存儲(chǔ)方式所謂靜態(tài)存儲(chǔ)方式,是指在程序運(yùn)行期間分配固定的存儲(chǔ)空間給變量的方式。這類變量存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),當(dāng)程序運(yùn)行時(shí)開(kāi)辟存儲(chǔ)空間,程序結(jié)束時(shí)釋放存儲(chǔ)空間,生存期為程序運(yùn)行期間。采用靜態(tài)存儲(chǔ)方式的變量有:全局變量(含外部變量、靜態(tài)全局變量)和靜態(tài)局部變量。(1)外部變量:外部變量就是只用數(shù)據(jù)類型關(guān)鍵字而未用static關(guān)鍵字定義的全局變量。存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),生存期為程序執(zhí)行期間。如果不對(duì)外部變量另加聲明,則它的作用域是從定義點(diǎn)到所在文件的末尾。其實(shí),外部變量不管在何處定義,可以通過(guò)用extern關(guān)鍵詞加以聲明后將其作用域擴(kuò)展到整個(gè)程序,聲明語(yǔ)句格

54、式為:extern 外部變量名; 這種擴(kuò)展作用域的聲明語(yǔ)句有兩種情況用到:對(duì)文件內(nèi)容后面位置所定義的外部變量x,將其作用域擴(kuò)展到本文件前面的函數(shù)。這時(shí)只要在該文件的前面用extern對(duì)該變量x聲明即可,這叫做提前引用聲明。對(duì)本程序的另一個(gè)源文件B中定義的外部變量y,要想擴(kuò)展到本文件A中使用,這時(shí)只要在本文件A的前面用extern對(duì)該變量y聲明即可,不妨稱此為跨文件引用聲明。 【例3.15】 對(duì)定義在同一文件中外部變量,作提前引用聲明以擴(kuò)展其使用范圍到文件前面。#include /*ex3_15.cpp* extern x; /提前引用聲明void main() x=4; coutxendl;i

55、nt x; /外部變量x的定義 【例3.16 】對(duì)定義在另一文件中的外部變量,作跨文件引用聲明以擴(kuò)展其作用域到本文件。文件file1.cpp的內(nèi)容:#include /*ex3_16.cpp*extern w; /跨文件引用聲明void main() coutwendl; /使用file2.cpp文件中定義的變量w 文件file2.cpp的內(nèi)容:int w=10; /外部變量w的定義int fun(int x,int y)return (x+y);程序運(yùn)行結(jié)果如下:10 (2)靜態(tài)變量:靜態(tài)變量存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),使用static聲明。靜態(tài)變量有兩種:靜態(tài)局部變量和靜態(tài)全局變量。 靜態(tài)局部變量是

56、在定義局部變量時(shí)開(kāi)頭再添加一個(gè)static關(guān)鍵字所定義的。靜態(tài)局部變量的特點(diǎn)是:程序執(zhí)行時(shí),為其開(kāi)辟存儲(chǔ)空間直到程序結(jié)束,但只能被其定義所在的函數(shù)或程序塊所使用。所以靜態(tài)局部變量的生命周期為程序執(zhí)行期間,作用域?yàn)槠涠x所在的函數(shù)或程序塊內(nèi)。如果沒(méi)有定義靜態(tài)局部變量的初始值,系統(tǒng)將自動(dòng)初始化為0。 【例3.17】 靜態(tài)局部變量的使用#include /*ex3_17.cpp* void fun();void main() int i; for(i=0;i3;i+) fun(); void fun()int a=0; static int b=0; /定義靜態(tài)局部變量 a=a+1; b=b+1;

57、couta,bendl;程序運(yùn)行結(jié)果如下:1,11,21,3 靜態(tài)全局變量是在定義全局變量時(shí)開(kāi)頭再添加一個(gè)static關(guān)鍵字所定義的。靜態(tài)全局變量的特點(diǎn)是:程序執(zhí)行時(shí),為其在全局?jǐn)?shù)據(jù)區(qū)開(kāi)辟存儲(chǔ)空間并初始化為0,直存儲(chǔ)期仍與外部變量一樣一直延續(xù)到程序結(jié)束。但其作用域受限于只能被其定義所在的文件使用,而不能借助前面所講的跨文件引用聲明擴(kuò)展到文件外?!纠?.18】 靜態(tài)全局變量的演示。文件file1.cpp的內(nèi)容:#include /*ex3_18.cpp*static int u=10; /定義靜態(tài)全局變量 void fun() cout”This is file1” 文件file2.cpp的內(nèi)容

58、:#include extern u; /試圖對(duì)u作跨文件引用聲明,此時(shí)行不通void main() coutuendl; /出現(xiàn)“變量u未定義”錯(cuò)誤【例3.18】中,文件file1.cpp中定義的全局變量u加了static關(guān)鍵字,成為靜態(tài)全局變量;因此不能擴(kuò)展作用域到文件file2.cpp。去掉文件file1.cpp中第二句前的static關(guān)鍵字程序就正確。static作用的總結(jié):static關(guān)鍵字加在局部變量前是延長(zhǎng)局部變量的存儲(chǔ)期(但不改變其作用域);static關(guān)鍵字加在全局變量前是限制全局變量的作用域(但不改變其存儲(chǔ)期)。函數(shù)按其存儲(chǔ)類別也可以分為兩類:1、內(nèi)部函數(shù)2、外部函數(shù) 3.

59、6.3 內(nèi)部函數(shù)和外部函數(shù)如果一個(gè)函數(shù)只能被本文件中其他函數(shù)所調(diào)用,它稱為內(nèi)部函數(shù)。在定義內(nèi)部函數(shù)時(shí),在函數(shù)名和函數(shù)類型的前面加static。函數(shù)首部的一般格式為static 類型標(biāo)識(shí)符 函數(shù)名(形參表)如static int fun(int a,int b)內(nèi)部函數(shù)又稱靜態(tài)(static)函數(shù)。使用內(nèi)部函數(shù),可以使函數(shù)只局限于所在文件。如果在不同的文件中有同名的內(nèi)部函數(shù),互不干擾。通常把只能由同一文件使用的函數(shù)和外部變量放在一個(gè)文件中,在它們前面都冠以static使之局部化,其他文件不能引用。1 內(nèi)部函數(shù)【例3.19】 靜態(tài)函數(shù)的例子。文件file1.cpp中的內(nèi)容:#include /*e

60、x3_19.cpp* static void fun( ); void main( ) fun( ); static void fun( ) /文件file1中定義靜態(tài)函數(shù),名稱為fun coutthis in file1 endl; 文件file2.cpp中的內(nèi)容:#include static void fun()/文件file2中定義靜態(tài)函數(shù),名稱也為fun coutthis in file2 endl; 程序運(yùn)行結(jié)果如下: this in file1 2 外部函數(shù)外部函數(shù)是可以被整個(gè)程序各文件調(diào)用的函數(shù)。(1)外部函數(shù)的定義。在函數(shù)類型前加存儲(chǔ)類型關(guān)鍵字extern,或缺省存儲(chǔ)類型關(guān)鍵

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論