譚浩強(qiáng)C語言課件第4章.ppt_第1頁
譚浩強(qiáng)C語言課件第4章.ppt_第2頁
譚浩強(qiáng)C語言課件第4章.ppt_第3頁
譚浩強(qiáng)C語言課件第4章.ppt_第4頁
譚浩強(qiáng)C語言課件第4章.ppt_第5頁
已閱讀5頁,還剩127頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第4章 函數(shù)與預(yù)處理,4.1 概述 4.2 定義函數(shù)的一般形式 4.3 函數(shù)參數(shù)和函數(shù)的值 4.4 函數(shù)的調(diào)用 *4.5 內(nèi)置函數(shù) *4.6 函數(shù)的重載 *4.7 函數(shù)模板 *4.8 有默認(rèn)參數(shù)的函數(shù) 4.9 函數(shù)的嵌套調(diào)用 4.10 函數(shù)的遞歸調(diào)用 4.11 局部變量和全局變量 4.12 變量的存儲類別 4.13 變量屬性小結(jié) 4.14 關(guān)于變量的聲明和定義 4.15 內(nèi)部函數(shù)和外部函數(shù) 4.16 預(yù)處理命令,一個(gè)較大的程序不可能完全由一個(gè)人從頭至尾地完成,更不可能把所有的內(nèi)容都放在一個(gè)主函數(shù)中。為了便于規(guī)劃、組織、編程和調(diào)試,一般的做法是把一個(gè)大的程序劃分為若干個(gè)程序模塊(即程序文件),每一個(gè)模塊實(shí)現(xiàn)一部分功能。不同的程序模塊可以由不同的人來完成。在程序進(jìn)行編譯時(shí),以程序模塊為編譯單位,即分別對每一個(gè)編譯單位進(jìn)行編譯。如果發(fā)現(xiàn)錯(cuò)誤,可以在本程序模塊范圍內(nèi)查錯(cuò)并改正。在分別通過編譯后,才進(jìn)行連接,把各模塊的目標(biāo)文件以及系統(tǒng)文件連接在一起形成可執(zhí)行文件。,4.1 概述,在一個(gè)程序文件中可以包含若干個(gè)函數(shù)。無論把一個(gè)程序劃分為多少個(gè)程序模塊,只能有一個(gè)main函數(shù)。程序總是從main函數(shù)開始執(zhí)行的。在程序運(yùn)行過程中,由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。在C語言中沒有類和對象,在程序模塊中直接定義函數(shù)??梢哉J(rèn)為,一個(gè)C程序是由若干個(gè)函數(shù)組成的,C語言被認(rèn)為是面向函數(shù)的語言。C+面向過程的程序設(shè)計(jì)沿用了C語言使用函數(shù)的方法。在C+面向?qū)ο蟮某绦蛟O(shè)計(jì)中,主函數(shù)以外的函數(shù)大多是被封裝在類中的。主函數(shù)或其他函數(shù)可以通過類對象調(diào)用類中的函數(shù)。無論是C還是C+,程序中的各項(xiàng)操作基本上都是由函數(shù)來實(shí)現(xiàn)的,程序編寫者要根據(jù)需要編寫一個(gè)個(gè)函數(shù),每個(gè)函數(shù)用來實(shí)現(xiàn)某一功能。因此,讀者必須掌握函數(shù)的概念以及學(xué)會設(shè)計(jì)和使用函數(shù)。,“函數(shù)”這個(gè)名詞是從英文function翻譯過來的,其實(shí)function的原意是“功能”。顧名思義,一個(gè)函數(shù)就是一個(gè)功能。 在實(shí)際應(yīng)用的程序中,主函數(shù)寫得很簡單,它的作用就是調(diào)用各個(gè)函數(shù),程序各部分的功能全部都是由各函數(shù)實(shí)現(xiàn)的。主函數(shù)相當(dāng)于總調(diào)度,調(diào)動(dòng)各函數(shù)依次實(shí)現(xiàn)各項(xiàng)功能。 開發(fā)商和軟件開發(fā)人員將一些常用的功能模塊編寫成函數(shù),放在函數(shù)庫中供公共選用。程序開發(fā)人員要善于利用庫函數(shù),以減少重復(fù)編寫程序段的工作量。,圖4.是一個(gè)程序中函數(shù)調(diào)用的示意圖。 圖4.,例41 在主函數(shù)中調(diào)用其他函數(shù)。 #include using namespace std; void printstar(void) /定義printstar函數(shù) cout* endl; /輸出30個(gè)“*” void print_message(void) /定義print_message函數(shù) cout Welcome to C+!endl; /輸出一行文字 int main(void) printstar( ); /調(diào)用printstar 函數(shù) print_message( ); /調(diào)用print_message函數(shù) printstar( ); /調(diào)用printstar 函數(shù) return 0; ,運(yùn)行情況如下: * Welcome to C+! * 從用戶使用的角度看,函數(shù)有兩種: (1) 系統(tǒng)函數(shù),即庫函數(shù)。這是由編譯系統(tǒng)提供的,用戶不必自己定義這些函數(shù),可以直接使用它們。 (2) 用戶自己定義的函數(shù)。用以解決用戶的專門需要。 從函數(shù)的形式看,函數(shù)分兩類: (1) 無參函數(shù)。調(diào)用函數(shù)時(shí)不必給出參數(shù)。 (2) 有參函數(shù)。在調(diào)用函數(shù)時(shí),要給出參數(shù)。在主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞。,定義無參函數(shù)的一般形式為 類型標(biāo)識符 函數(shù)名(void) 聲明部分 語句 例4.1中的printstar和print_message函數(shù)都是無參函數(shù)。用類型標(biāo)識符指定函數(shù)的類型,即函數(shù)帶回來的值的類型。,4.2 定義函數(shù)的一般形式 4.2.1 定義無參函數(shù)的一般形式,定義有參函數(shù)的一般形式為 類型標(biāo)識符 函數(shù)名(形式參數(shù)表列) 聲明部分 語句 例如: int max(int x,int y) /函數(shù)首部,函數(shù)值為整型,有兩個(gè)整型形參 int z; /函數(shù)體中的聲明部分 z=xy?x:y; /將x和y中的大者的值賦給整型變量z return (z); /將z的值作為函數(shù)值返回調(diào)用點(diǎn) C+要求在定義函數(shù)時(shí)必須指定函數(shù)的類型。,4.2.2 定義有參函數(shù)的一般形式,在調(diào)用函數(shù)時(shí),大多數(shù)情況下,函數(shù)是帶參數(shù)的。主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞關(guān)系。前面已提到:在定義函數(shù)時(shí)函數(shù)名后面括號中的變量名稱為形式參數(shù)(formal parameter,簡稱形參),在主調(diào)函數(shù)中調(diào)用一個(gè)函數(shù)時(shí),函數(shù)名后面括號中的參數(shù)(可以是一個(gè)表達(dá)式)稱為實(shí)際參數(shù)(actual parameter,簡稱實(shí)參)。,4.3 函數(shù)參數(shù)和函數(shù)的值 4.3.1 形式參數(shù)和實(shí)際參數(shù),例4.2 調(diào)用函數(shù)時(shí)的數(shù)據(jù)傳遞。 #include using namespace std; int max(int x,int y) /定義有參函數(shù)max int z; z=xy?x:y; return(z); int main( ) int a,b,c; coutab; c=max(a,b); /調(diào)用max函數(shù),給定實(shí)參為a,b。函數(shù)值賦給c coutmax=cendl; return 0; ,運(yùn)行情況如下: please enter two integer numbers:2 3 max=3 圖4.2,有關(guān)形參與實(shí)參的說明: (1) 在定義函數(shù)時(shí)指定的形參,在未出現(xiàn)函數(shù)調(diào)用時(shí),它們并不占內(nèi)存中的存儲單元,因此稱它們是形式參數(shù)或虛擬參數(shù),表示它們并不是實(shí)際存在的數(shù)據(jù),只有在發(fā)生函數(shù)調(diào)用時(shí),函數(shù)max中的形參才被分配內(nèi)存單元,以便接收從實(shí)參傳來的數(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.2程序第3行)。,(4) 實(shí)參與形參的類型應(yīng)相同或賦值兼容。例4.2中實(shí)參和形參都是整型,這是合法的、正確的。如果實(shí)參為整型而形參為實(shí)型,或者相反,則按不同類型數(shù)值的賦值規(guī)則進(jìn)行轉(zhuǎn)換。例如實(shí)參a的值為3.5,而形參x為整型,則將3.5轉(zhuǎn)換成整數(shù)3,然后送到形參b。字符型與整型可以互相通用。 (5) 實(shí)參變量對形參變量的數(shù)據(jù)傳遞是“值傳遞”,即單向傳遞,只由實(shí)參傳給形參,而不能由形參傳回來給實(shí)參。在調(diào)用函數(shù)時(shí),編譯系統(tǒng)臨時(shí)給形參分配存儲單元。請注意: 實(shí)參單元與形參單元是不同的單元。圖4.3表示將實(shí)參和的值2和3傳遞給對應(yīng)的形參和。,圖4.3 圖4.4 調(diào)用結(jié)束后,形參單元被釋放,實(shí)參單元仍保留并維持原值。因此,在執(zhí)行一個(gè)被調(diào)用函數(shù)時(shí),形參的值如果發(fā)生改變,并不會改變主調(diào)函數(shù)中實(shí)參的值。例如,若在執(zhí)行max函數(shù)過程中形參和的值變?yōu)?0和15,調(diào)用結(jié)束后,實(shí)參和仍為2和3,見圖4.4。,(1) 函數(shù)的返回值是通過函數(shù)中的return語句獲得的。return語句將被調(diào)用函數(shù)中的一個(gè)確定值帶回主調(diào)函數(shù)中去。 return語句后面的括號可以要,也可以不要。return后面的值可以是一個(gè)表達(dá)式。 (2) 函數(shù)值的類型。既然函數(shù)有返回值,這個(gè)值當(dāng)然應(yīng)屬于某一個(gè)確定的類型,應(yīng)當(dāng)在定義函數(shù)時(shí)指定函數(shù)值的類型。 (3) 如果函數(shù)值的類型和return語句中表達(dá)式的值不一致,則以函數(shù)類型為準(zhǔn),即函數(shù)類型決定返回值的類型。對數(shù)值型數(shù)據(jù),可以自動(dòng)進(jìn)行類型轉(zhuǎn)換。,4.3.2 函數(shù)的返回值,函數(shù)名(實(shí)參表列) 如果是調(diào)用無參函數(shù),則“實(shí)參表列”可以沒有,但括號不能省略。如果實(shí)參表列包含多個(gè)實(shí)參,則各參數(shù)間用逗號隔開。實(shí)參與形參的個(gè)數(shù)應(yīng)相等,類型應(yīng)匹配(相同或賦值兼容)。實(shí)參與形參按順序?qū)?yīng),一對一地傳遞數(shù)據(jù)。但應(yīng)說明,如果實(shí)參表列包括多個(gè)實(shí)參,對實(shí)參求值的順序并不是確定的。,4.4 函數(shù)的調(diào)用 4.4.1 函數(shù)調(diào)用的一般形式,按函數(shù)在語句中的作用來分,可以有以下3種函數(shù)調(diào)用方式: . 函數(shù)語句 把函數(shù)調(diào)用單獨(dú)作為一個(gè)語句,并不要求函數(shù)帶回一個(gè)值,只是要求函數(shù)完成一定的操作。如例4.1中的printstar( ); 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í)參,4.4.2 函數(shù)調(diào)用的方式,在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)(即被調(diào)用函數(shù))需要具備哪些條件呢? (1) 首先被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù)。 (2) 如果使用庫函數(shù),一般還應(yīng)該在本文件開頭用include命令將有關(guān)頭文件“包含”到本文件中來。 (3) 如果使用用戶自己定義的函數(shù),而該函數(shù)與調(diào)用它的函數(shù)(即主調(diào)函數(shù))在同一個(gè)程序單位中,且位置在主調(diào)函數(shù)之后,則必須在調(diào)用此函數(shù)之前對被調(diào)用的函數(shù)作聲明。 所謂函數(shù)聲明(declare),就是在函數(shù)尚在未定義的情況下,事先將該函數(shù)的有關(guān)信息通知編譯系統(tǒng),以便使編譯能正常進(jìn)行。,4.4.3 對被調(diào)用函數(shù)的聲明和函數(shù)原型,例4.3 對被調(diào)用的函數(shù)作聲明。 #include using namespace std; int main( ) float add(float x,float y); /對add函數(shù)作聲明 float a,b,c; coutab; c=add(a,b); coutsum=cendl; return 0; float add(float x,float y) /定義add函數(shù) float z; z=x+y; return (z); ,運(yùn)行情況如下: please enter a,b:123.68 456.45 sum=580.13 注意:對函數(shù)的定義和聲明不是同一件事情。定義是指對函數(shù)功能的確立,包括指定函數(shù)名、函數(shù)類型、形參及其類型、函數(shù)體等,它是一個(gè)完整的、獨(dú)立的函數(shù)單位。而聲明的作用則是把函數(shù)的名字、函數(shù)類型以及形參的個(gè)數(shù)、類型和順序(注意,不包括函數(shù)體)通知編譯系統(tǒng),以便在對包含函數(shù)調(diào)用的語句進(jìn)行編譯時(shí),據(jù)此對其進(jìn)行對照檢查(例如函數(shù)名是否正確,實(shí)參與形參的類型和個(gè)數(shù)是否一致)。 其實(shí),在函數(shù)聲明中也可以不寫形參名,而只寫形參的類型,如,float add(float,float); 這種函數(shù)聲明稱為函數(shù)原型(function prototype)。使用函數(shù)原型是C和C+的一個(gè)重要特點(diǎn)。它的作用主要是: 根據(jù)函數(shù)原型在程序編譯階段對調(diào)用函數(shù)的合法性進(jìn)行全面檢查。如果發(fā)現(xiàn)與函數(shù)原型不匹配的函數(shù)調(diào)用就報(bào)告編譯出錯(cuò)。它屬于語法錯(cuò)誤。用戶根據(jù)屏幕顯示的出錯(cuò)信息很容易發(fā)現(xiàn)和糾正錯(cuò)誤。 函數(shù)原型的一般形式為 (1) 函數(shù)類型 函數(shù)名(參數(shù)類型1,參數(shù)類型2); (2) 函數(shù)類型 函數(shù)名(參數(shù)類型1 參數(shù)名1,參數(shù)類型2 參數(shù)名2);,第(1)種形式是基本的形式。為了便于閱讀程序,也允許在函數(shù)原型中加上參數(shù)名,就成了第(2)種形式。但編譯系統(tǒng)并不檢查參數(shù)名。因此參數(shù)名是什么都無所謂。上面程序中的聲明也可以寫成 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í)參個(gè)數(shù)應(yīng)與函數(shù)原型一致。,說明: (1) 前面已說明,如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必加以聲明。因?yàn)榫幾g系統(tǒng)已經(jīng)事先知道了已定義的函數(shù)類型,會根據(jù)函數(shù)首部提供的信息對函數(shù)的調(diào)用作正確性檢查。 有經(jīng)驗(yàn)的程序編制人員一般都把main函數(shù)寫在最前面,這樣對整個(gè)程序的結(jié)構(gòu)和作用一目了然,統(tǒng)覽全局,然后再具體了解各函數(shù)的細(xì)節(jié)。此外,用函數(shù)原型來聲明函數(shù),還能減少編寫程序時(shí)可能出現(xiàn)的錯(cuò)誤。由于函數(shù)聲明的位置與函數(shù)調(diào)用語句的位置比較近,因此在寫程序時(shí)便于就近參照函數(shù)原型來書寫函數(shù)調(diào)用,不易出錯(cuò)。所以應(yīng)養(yǎng)成對所有用到的函數(shù)作聲明的習(xí)慣。這是保證程序正確性和可讀性的重要環(huán)節(jié)。,(2) 函數(shù)聲明的位置可以在調(diào)用函數(shù)所在的函數(shù)中,也可以在函數(shù)之外。如果函數(shù)聲明放在函數(shù)的外部,在所有函數(shù)定義之前,則在各個(gè)主調(diào)函數(shù)中不必對所調(diào)用的函數(shù)再作聲明。例如: char letter(char,char); /本行和以下兩行函數(shù)聲明在所有函數(shù)之前且在函數(shù)外部 float f(float,float); /因而作用域是整個(gè)文件 int i(float, float); int main( ) /在main函數(shù)中不必對它所調(diào)用的函數(shù)作聲明 char letter(char c1,char c2) /定義letter函數(shù) float f(float x,float y) /定義f函數(shù) int i(float j,float k) /定義i函數(shù) 如果一個(gè)函數(shù)被多個(gè)函數(shù)所調(diào)用,用這種方法比較好,不必在每個(gè)主調(diào)函數(shù)中重復(fù)聲明。,調(diào)用函數(shù)時(shí)需要一定的時(shí)間和空間的開銷。圖4.5表示函數(shù)調(diào)用的過程: 圖4.5,*4.5 內(nèi)置函數(shù),C+提供一種提高效率的方法,即在編譯時(shí)將所調(diào)用函數(shù)的代碼直接嵌入到主調(diào)函數(shù)中,而不是將流程轉(zhuǎn)出去。這種嵌入到主調(diào)函數(shù)中的函數(shù)稱為內(nèi)置函數(shù)(inline function),又稱內(nèi)嵌函數(shù)。在有些書中把它譯成內(nèi)聯(lián)函數(shù)。 指定內(nèi)置函數(shù)的方法很簡單,只需在函數(shù)首行的左端加一個(gè)關(guān)鍵字inline即可。,例4.4 函數(shù)指定為內(nèi)置函數(shù)。 #include using namespace std; inline int max(int,int, int); /聲明函數(shù),注意左端有inline int main( ) int i=10,j=20,k=30,m; m=max(i,j,k); couta) a=b; /求a,b,c中的最大者 if(ca) a=c; return a; ,由于在定義函數(shù)時(shí)指定它為內(nèi)置函數(shù),因此編譯系統(tǒng)在遇到函數(shù)調(diào)用“max(i,j,k)”時(shí),就用max函數(shù)體的代碼代替“max(i,j,k)”,同時(shí)將實(shí)參代替形參。這樣,程序第6行 “m=max(i,j,k);”就被置換成 if (ji) i=j; if(ki) i=k; m=i; 注意: 可以在聲明函數(shù)和定義函數(shù)時(shí)同時(shí)寫inline,也可以只在其中一處聲明inline,效果相同,都能按內(nèi)置函數(shù)處理。 使用內(nèi)置函數(shù)可以節(jié)省運(yùn)行時(shí)間,但卻增加了目標(biāo)程序的長度。因此一般只將規(guī)模很小(一般為5個(gè)語句以下)而使用頻繁的函數(shù)(如定時(shí)采集數(shù)據(jù)的函數(shù))聲明為內(nèi)置函數(shù)。,內(nèi)置函數(shù)中不能包括復(fù)雜的控制語句,如循環(huán)語句和switch語句。 應(yīng)當(dāng)說明: 對函數(shù)作inline聲明,只是程序設(shè)計(jì)者對編譯系統(tǒng)提出的一個(gè)建議,也就是說它是建議性的,而不是指令性的。并非一經(jīng)指定為inline,編譯系統(tǒng)就必須這樣做。編譯系統(tǒng)會根據(jù)具體情況決定是否這樣做。 歸納起來,只有那些規(guī)模較小而又被頻繁調(diào)用的簡單函數(shù),才適合于聲明為inline函數(shù)。,在編程時(shí),有時(shí)我們要實(shí)現(xiàn)的是同一類的功能,只是有些細(xì)節(jié)不同。例如希望從3個(gè)數(shù)中找出其中的最大者,而每次求最大數(shù)時(shí)數(shù)據(jù)的類型不同,可能是3個(gè)整數(shù)、3個(gè)雙精度數(shù)或3個(gè)長整數(shù)。程序設(shè)計(jì)者往往會分別設(shè)計(jì)出3個(gè)不同名的函數(shù),其函數(shù)原型為: int max1(int a,int b, int c); /求3個(gè)整數(shù)中的最大者 double max2(double a,double b,double c); /求3個(gè)雙精度數(shù)中最大者 long max3(long a,long b,long c); /求3個(gè)長整數(shù)中的最大者 C+允許用同一函數(shù)名定義多個(gè)函數(shù),這些函數(shù)的參數(shù)個(gè)數(shù)和參數(shù)類型不同。這就是函數(shù)的重載(function overloading)。即對一個(gè)函數(shù)名重新賦予它新的含義,使一個(gè)函數(shù)名可以多用。,*4.6 函數(shù)的重載,對上面求最大數(shù)的問題可以編寫如下的C+程序。 例4.5 求3個(gè)數(shù)中最大的數(shù)(分別考慮整數(shù)、雙精度數(shù)、長整數(shù)的情況)。 #include using namespace std; int main( ) int max(int a,int b,int c); /函數(shù)聲明 double max(double a,double b,double c); /函數(shù)聲明 long max(long a,long b,long c); /函數(shù)聲明 int i1,i2,i3,i; cini1i2i3; /輸入3個(gè)整數(shù) i=max(i1,i2,i3); /求3個(gè)整數(shù)中的最大者 coutd1d2d3; /輸入3個(gè)雙精度數(shù) d=max(d1,d2,d3); /求3個(gè)雙精度數(shù)中的最大者 coutg1g2g3; /輸入3個(gè)長整數(shù),g=max(g1,g2,g3); /求3個(gè)長整數(shù)中的最大者 couta) a=b; if(ca) a=c; return a; double max(double a,double b,double c) /定義求3個(gè)雙精度數(shù)中的最大者的函數(shù) if(ba) a=b; if(ca) a=c; return a; long max(long a,long b,long c) /定義求3個(gè)長整數(shù)中的最大者的函數(shù) if(ba) a=b; if(ca) a=c; return a; ,運(yùn)行情況如下: 185 -76 567 (輸入3個(gè)整數(shù)) 56.87 90.23 -3214.78 (輸入3個(gè)實(shí)數(shù)) 67854 -912456 673456 (輸入3個(gè)長整數(shù)) i_max=567 (輸出3個(gè)整數(shù)的最大值) d_max=90.23 (輸出3個(gè)雙精度數(shù)的最大值) g_max=673456 (輸出3個(gè)長整數(shù)的最大值) 上例3個(gè)max函數(shù)的函數(shù)體是相同的,其實(shí)重載函數(shù)并不要求函數(shù)體相同。重載函數(shù)除了允許參數(shù)類型不同以外,還允許參數(shù)的個(gè)數(shù)不同。,例4.6 編寫一個(gè)程序,用來求兩個(gè)整數(shù)或3個(gè)整數(shù)中的最大數(shù)。如果輸入兩個(gè)整數(shù),程序就輸出這兩個(gè)整數(shù)中的最大數(shù),如果輸入3個(gè)整數(shù),程序就輸出這3個(gè)整數(shù)中的最大數(shù)。 #include using namespace std; int main( ) int max(int a,int b,int c); /函數(shù)聲明 int max(int a,int b); /函數(shù)聲明 int a=8,b=-12,c=27; couta) a=b;,if(ca) a=c; return a; int max(int a,int b) /此max函數(shù)的作用是求兩個(gè)整數(shù)中的最大者 if(ab) return a; else return b; 運(yùn)行情況如下: max(a,b,c)=27 max(a,b)=8 兩次調(diào)用max函數(shù)的參數(shù)個(gè)數(shù)不同,系統(tǒng)就根據(jù)參數(shù)的個(gè)數(shù)找到與之匹配的函數(shù)并調(diào)用它。 參數(shù)的個(gè)數(shù)和類型可以都不同。但不能只有函數(shù)的類型不同而參數(shù)的個(gè)數(shù)和類型相同。例如:,int f(int); /函數(shù)返回值為整型 long f(int); /函數(shù)返回值為長整型 void f(int); /函數(shù)無返回值 在函數(shù)調(diào)用時(shí)都是同一形式,如“f(10)”。編譯系統(tǒng)無法判別應(yīng)該調(diào)用哪一個(gè)函數(shù)。重載函數(shù)的參數(shù)個(gè)數(shù)、參數(shù)類型或參數(shù)順序3者中必須至少有一種不同,函數(shù)返回值類型可以相同也可以不同。 在使用重載函數(shù)時(shí),同名函數(shù)的功能應(yīng)當(dāng)相同或相近,不要用同一函數(shù)名去實(shí)現(xiàn)完全不相干的功能,雖然程序也能運(yùn)行,但可讀性不好,使人莫名其妙。,C+提供了函數(shù)模板(function template)。所謂函數(shù)模板,實(shí)際上是建立一個(gè)通用函數(shù),其函數(shù)類型和形參類型不具體指定,用一個(gè)虛擬的類型來代表。這個(gè)通用函數(shù)就稱為函數(shù)模板。凡是函數(shù)體相同的函數(shù)都可以用這個(gè)模板來代替,不必定義多個(gè)函數(shù),只需在模板中定義一次即可。在調(diào)用函數(shù)時(shí)系統(tǒng)會根據(jù)實(shí)參的類型來取代模板中的虛擬類型,從而實(shí)現(xiàn)了不同函數(shù)的功能??聪旅娴睦泳颓宄恕?例4.7 將例4.6程序改為通過函數(shù)模板來實(shí)現(xiàn)。,*4.7 函數(shù)模板,#include using namespace std; template /模板聲明,其中T為類型參數(shù) T max(T a,T b,T c) /定義一個(gè)通用函數(shù),用T作虛擬的類型名 if(ba) a=b; if(ca) a=c; return a; int main( ) int i1=185,i2=-76,i3=567,i; double d1=56.87,d2=90.23,d3=-3214.78,d; long g1=67854,g2=-912456,g3=673456,g; i=max(i1,i2,i3); /調(diào)用模板函數(shù),此時(shí)T被int取代 d=max(d1,d2,d3); /調(diào)用模板函數(shù),此時(shí)T被double取代 g=max(g1,g2,g3); /調(diào)用模板函數(shù),此時(shí)T被long取代 couti_max=iendl; coutf_max=fendl; coutg_max=gendl; return 0; ,運(yùn)行結(jié)果與例4.5相同。為了節(jié)省篇幅,數(shù)據(jù)不用cin語句輸入,而在變量定義時(shí)初始化。 程序第38行是定義模板。定義函數(shù)模板的一般形式為 template 或 template 通用函數(shù)定義 通用函數(shù)定義 在建立函數(shù)模板時(shí),只要將例4.5程序中定義的第一個(gè)函數(shù)首部的int改為T即可。即用虛擬的類型名T代替具體的數(shù)據(jù)類型。在對程序進(jìn)行編譯時(shí),遇到第13行調(diào)用函數(shù)max(i1,i2,i3),編譯系統(tǒng)會將函數(shù)名max與模板max相匹配,將實(shí)參的類型取代了函數(shù)模板中的虛擬類型T。此時(shí)相當(dāng)于已定義了一個(gè)函數(shù):,int max(int a,int b,int c) if(ba) a=b; if(ca) a=c; return a; 然后調(diào)用它。后面兩行(14,15行)的情況類似。 類型參數(shù)可以不只一個(gè),可以根據(jù)需要確定個(gè)數(shù)。如 template 可以看到,用函數(shù)模板比函數(shù)重載更方便,程序更簡潔。但應(yīng)注意它只適用于函數(shù)的參數(shù)個(gè)數(shù)相同而類型不同,且函數(shù)體相同的情況,如果參數(shù)的個(gè)數(shù)不同,則不能用函數(shù)模板。,一般情況下,在函數(shù)調(diào)用時(shí)形參從實(shí)參那里取得值,因此實(shí)參的個(gè)數(shù)應(yīng)與形參相同。有時(shí)多次調(diào)用同一函數(shù)時(shí)用同樣的實(shí)參,C+提供簡單的處理辦法,給形參一個(gè)默認(rèn)值,這樣形參就不必一定要從實(shí)參取值了。如有一函數(shù)聲明 float area(float r=6.5); 指定r的默認(rèn)值為6.5,如果在調(diào)用此函數(shù)時(shí),確認(rèn)r的值為6.5,則可以不必給出實(shí)參的值,如 area( ); /相當(dāng)于area(6.5); 如果不想使形參取此默認(rèn)值,則通過實(shí)參另行給出。如,*4.8 有默認(rèn)參數(shù)的函數(shù),area(7.5); /形參得到的值為7.5,而不是6.5 這種方法比較靈活,可以簡化編程,提高運(yùn)行效率。 如果有多個(gè)形參,可以使每個(gè)形參有一個(gè)默認(rèn)值,也可以只對一部分形參指定默認(rèn)值,另一部分形參不指定默認(rèn)值。如有一個(gè)求圓柱體體積的函數(shù),形參h代表圓柱體的高,r為圓柱體半徑。函數(shù)原型如下: float volume(float h,float r=12.5); /只對形參r指定默認(rèn)值12.5 函數(shù)調(diào)用可以采用以下形式: volume(45.6); /相當(dāng)于volume(45.6,12.5) volume(34.2,10.4) /h的值為34.2,r的值為10.4 實(shí)參與形參的結(jié)合是從左至右順序進(jìn)行的。因此指定默認(rèn)值的參數(shù)必須放在形參表列中的最右端,否則出錯(cuò)。例如:,void f1(float a,int b=0,int c,char d=a); /不正確 void f2(float a,int c,int b=0, char d=a); /正確 如果調(diào)用上面的f2函數(shù),可以采取下面的形式: f2(3.5, 5, 3, x) /形參的值全部從實(shí)參得到 f2(3.5, 5, 3) /最后一個(gè)形參的值取默認(rèn)值a f2(3.5, 5) /最后兩個(gè)形參的值取默認(rèn)值,b=0,d=a 可以看到,在調(diào)用有默認(rèn)參數(shù)的函數(shù)時(shí),實(shí)參的個(gè)數(shù)可以與形參的個(gè)數(shù)不同,實(shí)參未給定的,從形參的默認(rèn)值得到值。利用這一特性,可以使函數(shù)的使用更加靈活。例如例4.7求2個(gè)數(shù)或3個(gè)數(shù)中的最大數(shù)。也可以不用重載函數(shù),而改用帶有默認(rèn)參數(shù)的函數(shù)。,例4.8 求2個(gè)或3個(gè)正整數(shù)中的最大數(shù),用帶有默認(rèn)參數(shù)的函數(shù)實(shí)現(xiàn)。 #include using namespace std; int main( ) int max(int a, int b, int c=0);/函數(shù)聲明,形參c有默認(rèn)值 int a,b,c; cinabc; couta) a=b; if(ca) a=c; return a; ,運(yùn)行情況如下: 14 -56 135 max(a,b,c)=135 max(a,b)=14 在使用帶有默認(rèn)參數(shù)的函數(shù)時(shí)有兩點(diǎn)要注意: (1) 如果函數(shù)的定義在函數(shù)調(diào)用之前,則應(yīng)在函數(shù)定義中給出默認(rèn)值。如果函數(shù)的定義在函數(shù)調(diào)用之后,則在函數(shù)調(diào)用之前需要有函數(shù)聲明,此時(shí)必須在函數(shù)聲明中給出默認(rèn)值,在函數(shù)定義時(shí)可以不給出默認(rèn)值(如例4.8)。 (2) 一個(gè)函數(shù)不能既作為重載函數(shù),又作為有默認(rèn)參數(shù)的函數(shù)。因?yàn)楫?dāng)調(diào)用函數(shù)時(shí)如果少寫一個(gè)參數(shù),系統(tǒng)無法判定是利用重載函數(shù)還是利用默認(rèn)參數(shù)的函數(shù),出現(xiàn)二義性,系統(tǒng)無法執(zhí)行。,C+不允許對函數(shù)作嵌套定義,也就是說在一個(gè)函數(shù)中不能完整地包含另一個(gè)函數(shù)。在一個(gè)程序中每一個(gè)函數(shù)的定義都是互相平行和獨(dú)立的。 雖然C+不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),也就是說,在調(diào)用一個(gè)函數(shù)的過程中,又調(diào)用另一個(gè)函數(shù)。見圖4.6。 圖4.6,4.9 函數(shù)的嵌套調(diào)用,在程序中實(shí)現(xiàn)函數(shù)嵌套調(diào)用時(shí),需要注意的是: 在調(diào)用函數(shù)之前,需要對每一個(gè)被調(diào)用的函數(shù)作聲明(除非定義在前,調(diào)用在后)。 例4.9 用弦截法求方程f(x)=x3-5x2+16x-80=0的根。 這是一個(gè)數(shù)值求解問題,需要先分析用弦截法求根的算法。根據(jù)數(shù)學(xué)知識,可以列出以下的解題步驟: (1) 取兩個(gè)不同點(diǎn)x1,x2,如果f(x1)和f(x2)符號相反,則(x1,x2)區(qū)間內(nèi)必有一個(gè)根。如果f(x1)與f(x2)同符號,則應(yīng)改變x1,x2,直到f(x1), f(x2)異號為止。注意x1、x2的值不應(yīng)差太大,以保證(x1,x2)區(qū)間內(nèi)只有一個(gè)根。 (2) 連接(x1, f(x1))和(x2, f(x2))兩點(diǎn),此線(即弦)交x軸于x,見圖4.7。,圖4.7,x點(diǎn)坐標(biāo)可用下式求出: x=x1f(x2)-x2f(x1) f(x2)-f(x1) 再從x求出f(x)。 (3) 若f(x)與f(x1)同符號,則根必在(x, x2)區(qū)間內(nèi),此時(shí)將x作為新的x1。如果f(x)與f(x2)同符號,則表示根在( x1,x)區(qū)間內(nèi),將x作為新的x2。 (4) 重復(fù)步驟 (2) 和 (3), 直到 f(x)為止, 為一個(gè)很小的正數(shù), 例如10-6。此時(shí)認(rèn)為 f(x)0。 這就是弦截法的算法,在程序中分別用以下幾個(gè)函數(shù)來實(shí)現(xiàn)以上有關(guān)部分功能: (1) 用函數(shù)f(x)代表x的函數(shù):x3-5x2+16x-80。,(2) 用函數(shù)xpoint (x1,x2)來求(x1,f(x1)和(x2,f(x2)的連線與x軸的交點(diǎn)x的坐標(biāo)。 (3) 用函數(shù)root(x1,x2)來求(x1,x2)區(qū)間的那個(gè)實(shí)根。顯然,執(zhí)行root函數(shù)的過程中要用到xpoint函數(shù),而執(zhí)行xpoint函數(shù)的過程中要用到f函數(shù)。 根據(jù)以上算法,可以編寫出下面的程序: #include #include #include using namespace std; double f(double); /函數(shù)聲明 double xpoint(double, double); /函數(shù)聲明 double root(double, double); /函數(shù)聲明 int main( ) double x1,x2,f1,f2,x;,do coutx1x2; f1=f(x1); f2=f(x2); while(f1*f2=0); x=root(x1,x2); coutsetiosflags(iosfixed)setprecision(7); /指定輸出7位小數(shù) coutA root of equation is xendl; return 0; double f(double x) /定義f函數(shù),以實(shí)現(xiàn)f(x) double y; y=x*x*x-5*x*x+16*x-80; return y; ,double xpoint(double x1, double x2) /定義xpoint函數(shù),求出弦與軸交點(diǎn) double y; y=(x1*f(x2)-x2*f(x1)/(f(x2)-f(x1); /在xpoint函數(shù)中調(diào)用f函數(shù) return y; double root(double x1, double x2) /定義root函數(shù),求近似根 double x,y,y1; y1=f(x1); do x=xpoint(x1,x2); /在root函數(shù)中調(diào)用xpoint函數(shù) y=f(x); /在root函數(shù)中調(diào)用f函數(shù) if (y*y10) y1=y; x1=x; else x2=x; while(fabs(y)=0.00001); return x; ,運(yùn)行情況如下: input x1,x2:2.5 6.7 A root of equation is 5.0000000 對程序的說明: (1) 在定義函數(shù)時(shí),函數(shù)名為f,xpoint和root的3個(gè)函數(shù)是互相獨(dú)立的,并不互相從屬。這3個(gè)函數(shù)均定為雙精度型。 (2) 3個(gè)函數(shù)的定義均出現(xiàn)在main函數(shù)之后,因此在main函數(shù)的前面對這3個(gè)函數(shù)作聲明。 習(xí)慣上把本程序中用到的所有函數(shù)集中放在最前面聲明。 (3) 程序從main函數(shù)開始執(zhí)行。函數(shù)的嵌套調(diào)用見圖4.8。,圖4.8 (4) 在root函數(shù)中要用到求絕對值的函數(shù)fabs,它是對雙精度數(shù)求絕對值的系統(tǒng)函數(shù)。它屬于數(shù)學(xué)函數(shù)庫,故在文件開頭用#include 把有關(guān)的頭文件包含進(jìn)來。,在調(diào)用一個(gè)函數(shù)的過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸(recursive)調(diào)用。C+允許函數(shù)的遞歸調(diào)用。例如: int f(int x) int y,z; z=f(y); /在調(diào)用函數(shù)f的過程中,又要調(diào)用f函數(shù) return (2*); 以上是直接調(diào)用本函數(shù),見圖4.9。 圖4.10表示的是間接調(diào)用本函數(shù)。在調(diào)用f1函數(shù)過程中要調(diào)用f2函數(shù),而在調(diào)用f2函數(shù)過程中又要調(diào)用f1函數(shù)。,4.10 函數(shù)的遞歸調(diào)用,圖4.9 圖4.10 從圖上可以看到,這兩種遞歸調(diào)用都是無終止的自身調(diào)用。顯然,程序中不應(yīng)出現(xiàn)這種無終止的遞歸調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的、有終止的遞歸調(diào)用,這可以用if語句來控制,只有在某一條件成立時(shí)才繼續(xù)執(zhí)行遞歸調(diào)用,否則就不再繼續(xù)。 包含遞歸調(diào)用的函數(shù)稱為遞歸函數(shù)。,例4.10 有5個(gè)人坐在一起,問第5個(gè)人多少歲?他說比第4個(gè)人大兩歲。問第4個(gè)人歲數(shù),他說比第3個(gè)人大兩歲。問第3個(gè)人,又說比第2個(gè)人大兩歲。問第2個(gè)人,說比第1個(gè)人大兩歲。最后問第1個(gè)人,他說是10歲。請問第5個(gè)人多大? 每一個(gè)人的年齡都比其前1個(gè)人的年齡大兩歲。即 age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10 可以用式子表述如下: age(n)=10 (n=1) age(n)=age(n-1)+2 (n1),可以看到,當(dāng)n1時(shí),求第n個(gè)人的年齡的公式是相同的。因此可以用一個(gè)函數(shù)表示上述關(guān)系。圖4.11表示求第5個(gè)人年齡的過程。 圖4.11,可以寫出以下C+程序,其中的age函數(shù)用來實(shí)現(xiàn)上述遞歸過程。 #include using namespace std; int age(int); /函數(shù)聲明 int main( ) /主函數(shù) coutage(5)endl; return 0; int age(int n) /求年齡的遞歸函數(shù) int c; /用c作為存放年齡的變量 if(n=1) c=10; /當(dāng)n=1時(shí),年齡為10 else c=age(n-1)+2; /當(dāng)n1時(shí),此人年齡是他前一個(gè)人的年齡加2 return c; /將年齡值帶回主函數(shù) ,運(yùn)行結(jié)果如下: 18 函數(shù)調(diào)用過程如圖4.12所示。 圖4.12,例4.11 用遞歸方法求!。 求n!可以用遞推方法,即從1開始,乘2,再乘3一直乘到n。 求n!也可以用遞歸方法,即5!=4!5,而4!3!4,1!=??捎孟旅娴倪f歸公式表示: n!= 1 (n=0,1) n(n-1)! (n1) 有了例4.10的基礎(chǔ),很容易寫出本題的程序: #include using namespace std; long fac(int); /函數(shù)聲明 int main( ) int n; /n為需要求階乘的整數(shù) long y; /y為存放n!的變量,coutn; /輸入n y=fac(n); /調(diào)用fac函數(shù)以求n! cout1時(shí),進(jìn)行遞歸調(diào)用 return f; /將f的值作為函數(shù)值返回 ,運(yùn)行情況如下: please input an integer:10 10!=3628800 許多問題既可以用遞歸方法來處理,也可以用非遞歸方法來處理。在實(shí)現(xiàn)遞歸時(shí),在時(shí)間和空間上的開銷比較大,但符合人們的思路,程序容易理解。,在一個(gè)函數(shù)內(nèi)部定義的變量是內(nèi)部變量,它只在本函數(shù)范圍內(nèi)有效,也就是說只有在本函數(shù)內(nèi)才能使用它們,在此函數(shù)以外是不能使用這些變量的。同樣,在復(fù)合語句中定義的變量只在本復(fù)合語句范圍內(nèi)有效。這稱為局部變量(local variable)。如,4.11 局部變量和全局變量 4.11.1 局部變量,float f1(int a) /函數(shù)f1 int b,c; b、c有效 a有效 char f2(int x, int y) /函數(shù)f2 int i,j; i、j有效 x、y有效 int main( ) /主函數(shù) int m,n; int p,q; p、q在復(fù)合語句中有效 m、n有效 ,說明: (1) 主函數(shù)main中定義的變量(m,n)也只在主函數(shù)中有效,不會因?yàn)樵谥骱瘮?shù)中定義而在整個(gè)文件或程序中有效。主函數(shù)也不能使用其他函數(shù)中定義的變量。 (2) 不同函數(shù)中可以使用同名的變量,它們代表不同的對象,互不干擾。例如,在f1函數(shù)中定義了變量b和c,倘若在f2函數(shù)中也定義變量b和c,它們在內(nèi)存中占不同的單元,不會混淆。 (3) 可以在一個(gè)函數(shù)內(nèi)的復(fù)合語句中定義變量,這些變量只在本復(fù)合語句中有效,這種復(fù)合語句也稱為分程序或程序塊。 (4) 形式參數(shù)也是局部變量。例如f1函數(shù)中的形參a也只在f1函數(shù)中有效。其他函數(shù)不能調(diào)用。,(5) 在函數(shù)聲明中出現(xiàn)的參數(shù)名,其作用范圍只在本行的括號內(nèi)。實(shí)際上,編譯系統(tǒng)對函數(shù)聲明中的變量名是忽略的,即使在調(diào)用函數(shù)時(shí)也沒有為它們分配存儲單元。例如 int max(int a,int b); /函數(shù)聲明中出現(xiàn)a、b int max(int x,int y) /函數(shù)定義,形參是x、y coutxyendl; /合法,x、y在函數(shù)體中有效 coutabendl; /非法,a、b在函數(shù)體中無效 編譯時(shí)認(rèn)為max函數(shù)體中的a和b未經(jīng)定義。,前面已介紹,程序的編譯單位是源程序文件,一個(gè)源文件可以包含一個(gè)或若干個(gè)函數(shù)。在函數(shù)內(nèi)定義的變量是局部變量,而在函數(shù)之外定義的變量是外部變量,稱為全局變量(global variable,也稱全程變量)。全局變量的有效范圍為從定義變量的位置開始到本源文件結(jié)束。如,4.11.2 全局變量,int p=1,q=5;/全局變量 全局變量c1、c2的作用范圍 float f1(a)/定義函數(shù)f1 int a; int b,c; char c1,c2; /全局變量 全局變量p、q的作用范圍 char f2 (int x, int y) /定義函數(shù)f2 int i,j; main ( )/主函數(shù) int m,n; ,p、q、c1、c2都是全局變量,但它們的作用范圍不同,在main函數(shù)和f2函數(shù)中可以使用全局變量p、q、c1、c2,但在函數(shù)f1中只能使用全局變量p、q,而不能使用c1和c2。 在一個(gè)函數(shù)中既可以使用本函數(shù)中的局部變量,又可以使用有效的全局變量。 說明: (1) 設(shè)全局變量的作用是增加函數(shù)間數(shù)據(jù)聯(lián)系的渠道。 (2) 建議不在必要時(shí)不要使用全局變量,因?yàn)椋?全局變量在程序的全部執(zhí)行過程中都占用存儲單元,而不是僅在需要時(shí)才開辟單元。, 它使函數(shù)的通用性降低了,因?yàn)樵趫?zhí)行函數(shù)時(shí)要受到外部變量的影響。如果將一個(gè)函數(shù)移到另一個(gè)文件中,還要將有關(guān)的外部變量及其值一起移過去。但若該外部變量與其他文件的變量同名,就會出現(xiàn)問題,降低了程序的可靠性和通用性。在程序設(shè)計(jì)中,在劃分模塊時(shí)要求模塊的內(nèi)聚性強(qiáng)、與其他模塊的耦合性弱。即模塊的功能要單一(不要把許多互不相干的功能放到一個(gè)模塊中),與其他模塊的相互影響要盡量少,而用全局變量是不符合這個(gè)原則的。 一般要求把程序中的函數(shù)做成一個(gè)封閉體,除了可以通過“實(shí)參形參”的渠道與外界發(fā)生聯(lián)系外,沒有其他渠道。這樣的程序移植性好,可讀性強(qiáng)。, 使用全局變量過多,會降低程序的清晰性。在各個(gè)函數(shù)執(zhí)行時(shí)都可能改變?nèi)肿兞康闹担绦蛉菀壮鲥e(cuò)。因此,要限制使用全局變量。 (3) 如果在同一個(gè)源文件中,全局變量與局部變量同名,則在局部變量的作用范圍內(nèi),全局變量被屏蔽,即它不起作用。 變量的有效范圍稱為變量的作用域(scope)。歸納起來,變量有4種不同的作用域、文件作用域(file scope)、函數(shù)作用域(function scope)、塊作用域(block scope)和函數(shù)原型作用域(function prototype scope)。文件作用域是全局的,其他三者是局部的。 除了變量之外,任何以標(biāo)識符代表的實(shí)體都有作用域,概念與變量的作用域相似。,上一節(jié)已介紹了變量的一種屬性作用域,作用域是從空間的角度來分析的,分為全局變量和局部變量。 變量還有另一種屬性存儲期(storage duration,也稱生命期)。存儲期是指變量在內(nèi)存中的存在期間。這是從變量值存在的時(shí)間角度來分析的。存儲期可以分為靜態(tài)存儲期(static storage duration)和動(dòng)態(tài)存儲期(dynamic storage duration)。這是由變量的靜態(tài)存儲方式和動(dòng)態(tài)存儲方式?jīng)Q定的。,4.12 變量的存儲類別 4.12.1 動(dòng)態(tài)存儲方式與靜態(tài)存儲方式,所謂靜態(tài)存儲方式是指在程序運(yùn)行期間,系統(tǒng)對變量分配固定的存儲空間。而動(dòng)態(tài)存儲方式則是在程序運(yùn)行期間,系統(tǒng)對變量動(dòng)態(tài)地分配存儲空間。 先看一下內(nèi)存中的供用戶使用的存儲空間的情況。這個(gè)存儲空間可以分為三部分,即: (1) 程序區(qū) (2) 靜態(tài)存儲區(qū) (3) 動(dòng)態(tài)存儲區(qū) 圖4.13,數(shù)據(jù)分別存放在靜態(tài)存儲區(qū)和動(dòng)態(tài)存儲區(qū)中。全局變量全部存放在靜態(tài)存儲區(qū)中,在程序開始執(zhí)行時(shí)給全局變量分配存儲單元,程序執(zhí)行完畢就釋放這些空間。在程序執(zhí)行過程中它們占據(jù)固定的存儲單元,而不是動(dòng)態(tài)地進(jìn)行分配和釋放。 在動(dòng)態(tài)存儲區(qū)中存放以下數(shù)據(jù): 函數(shù)形式參數(shù)。在調(diào)用函數(shù)時(shí)給形參分配存儲空間。函數(shù)中的自動(dòng)變量(未加static聲明的局部變量,詳見后面的介紹)。函數(shù)調(diào)用時(shí)的現(xiàn)場保護(hù)和返回地址等。 對以上這些數(shù)據(jù),在函數(shù)調(diào)用開始時(shí)分配動(dòng)態(tài)存儲空間,函數(shù)結(jié)束時(shí)釋放這些空間。在程序執(zhí)行過程中,這種分配和釋放是動(dòng)態(tài)的,如果在一個(gè)程序中兩次調(diào)用同一函數(shù),則要進(jìn)行兩次分配和釋放,而兩次分配給此函數(shù)中局部變量的存儲空間地址可能是不相同的。,如果在一個(gè)程序中包含若干個(gè)函數(shù),每個(gè)函數(shù)中的局部變量的存儲期并不等于整個(gè)程序的執(zhí)行周期,它只是整個(gè)程序執(zhí)行周期的一部分。根據(jù)函數(shù)調(diào)用的情況,系統(tǒng)對局部變量動(dòng)態(tài)地分配和釋放存儲空間。 在C+中變量除了有數(shù)據(jù)類型的屬性之外,還有存儲類別(storage class) 的屬性。存儲類別指的是數(shù)據(jù)在內(nèi)存中存儲的方法。存儲方法分為靜態(tài)存儲和動(dòng)態(tài)存儲兩大類。具體包含4種:自動(dòng)的(auto)、靜態(tài)的(static)、寄存器的(register)和外部的(extern)。根據(jù)變量的存儲類別,可以知道變量的作用域和存儲期。,函數(shù)中的局部變量,如果不用關(guān)鍵字static加以聲明,編譯系統(tǒng)對它們是動(dòng)態(tài)地分配存儲空間的。函數(shù)的形參和在函數(shù)中定

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論