第5章 函數(shù)及函數(shù)模板_第1頁
第5章 函數(shù)及函數(shù)模板_第2頁
第5章 函數(shù)及函數(shù)模板_第3頁
第5章 函數(shù)及函數(shù)模板_第4頁
第5章 函數(shù)及函數(shù)模板_第5頁
已閱讀5頁,還剩55頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第第5 5章章 函數(shù)與函數(shù)模板函數(shù)與函數(shù)模板n在以模塊化方式設(shè)計一個較大的程序時,在以模塊化方式設(shè)計一個較大的程序時,需要對復(fù)雜功能進(jìn)行分解,形成若干容易需要對復(fù)雜功能進(jìn)行分解,形成若干容易處理和編碼的相對獨(dú)立的程序塊,而最終處理和編碼的相對獨(dú)立的程序塊,而最終要精心實(shí)現(xiàn)的就是這些小而容易的程序塊,要精心實(shí)現(xiàn)的就是這些小而容易的程序塊,稱為稱為“模塊模塊”,C+中稱之為函數(shù)。中稱之為函數(shù)。 5.1 函數(shù)的定義與聲明函數(shù)的定義與聲明5.1.1 函數(shù)定義函數(shù)定義ntype 函數(shù)名函數(shù)名(形式參數(shù)說明表形式參數(shù)說明表)nn /代碼,稱為函數(shù)體代碼,稱為函數(shù)體nn上述工作的目的是指規(guī)定一個函數(shù)的名字、

2、上述工作的目的是指規(guī)定一個函數(shù)的名字、參數(shù)等信息,并給出實(shí)現(xiàn)它的完整代碼,參數(shù)等信息,并給出實(shí)現(xiàn)它的完整代碼,此過程稱為此過程稱為“函數(shù)定義函數(shù)定義”或或“函數(shù)實(shí)現(xiàn)函數(shù)實(shí)現(xiàn)”。 5.1.1 函數(shù)定義函數(shù)定義n一個程序中可能包含很多個函數(shù),所有函一個程序中可能包含很多個函數(shù),所有函數(shù)無主次之分,單獨(dú)定義,數(shù)無主次之分,單獨(dú)定義,不能在一個函不能在一個函數(shù)的函數(shù)體內(nèi)再定義另一個函數(shù),數(shù)的函數(shù)體內(nèi)再定義另一個函數(shù),這一點(diǎn)這一點(diǎn)稱為函數(shù)的稱為函數(shù)的“外部性外部性”。一個完整的程序。一個完整的程序必須有一個名字為必須有一個名字為main的函數(shù),它起著程的函數(shù),它起著程序入口的作用。即程序從序入口的作用。

3、即程序從main函數(shù)的第一函數(shù)的第一條語句開始執(zhí)行,條語句開始執(zhí)行,main函數(shù)執(zhí)行完畢意味函數(shù)執(zhí)行完畢意味著整個程序運(yùn)行結(jié)束。著整個程序運(yùn)行結(jié)束。 5.1.2 函數(shù)聲明函數(shù)聲明n自定義函數(shù)的聲明自定義函數(shù)的聲明用戶定義的函數(shù)應(yīng)按下述兩種形式之一進(jìn)行聲明,效果用戶定義的函數(shù)應(yīng)按下述兩種形式之一進(jìn)行聲明,效果相同:相同:ntype 函數(shù)名函數(shù)名(形式參數(shù)說明表形式參數(shù)說明表);ntype 函數(shù)名函數(shù)名(形式參數(shù)類型說明表形式參數(shù)類型說明表);例如:例如:ndouble f(double x, double y);double f(double x, double y);ndouble f(dou

4、ble, double);double f(double, double);聲明是為了說明函數(shù)的格式,參數(shù)的名字無關(guān)緊要。聲明是為了說明函數(shù)的格式,參數(shù)的名字無關(guān)緊要。 在函數(shù)定義置于使用之前時也可以不聲明,但一般只在在函數(shù)定義置于使用之前時也可以不聲明,但一般只在簡單程序中采取這種做法。簡單程序中采取這種做法。 5.1.2 函數(shù)聲明函數(shù)聲明n庫函數(shù)的聲明庫函數(shù)的聲明C+語言的庫函數(shù)是預(yù)先設(shè)計的函數(shù),它們的語言的庫函數(shù)是預(yù)先設(shè)計的函數(shù),它們的原型聲明都分類存儲在隨系統(tǒng)攜帶的某個頭文原型聲明都分類存儲在隨系統(tǒng)攜帶的某個頭文件中,需要使用件中,需要使用#include指令指令“包含包含”對應(yīng)的對應(yīng)

5、的文件,文件,使編譯器可以查找到所使用函數(shù)的聲明使編譯器可以查找到所使用函數(shù)的聲明。 學(xué)習(xí)時應(yīng)注意了解庫函數(shù)和它所在的頭文件。學(xué)習(xí)時應(yīng)注意了解庫函數(shù)和它所在的頭文件。 5.2 函數(shù)調(diào)用與參數(shù)匹配函數(shù)調(diào)用與參數(shù)匹配n如果僅給出一個函數(shù)的定義和聲明,并不如果僅給出一個函數(shù)的定義和聲明,并不意味著函數(shù)的代碼能夠被執(zhí)行。只有程序意味著函數(shù)的代碼能夠被執(zhí)行。只有程序的其它部分使用該函數(shù)時,系統(tǒng)才會真正的其它部分使用該函數(shù)時,系統(tǒng)才會真正執(zhí)行函數(shù)的代碼,這種使用稱為執(zhí)行函數(shù)的代碼,這種使用稱為“函數(shù)調(diào)函數(shù)調(diào)用用”。 5.2.1 調(diào)用關(guān)系調(diào)用關(guān)系#include using namespace std;do

6、uble sum(double, double);/函數(shù)原型聲明函數(shù)原型聲明void print(double); /函數(shù)原型聲明函數(shù)原型聲明int main( ) print(sum(1.0, 2.0);double sum(double x, double y) return x+y;void print(double x) cout x= x endl;5.2.2 函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式n函數(shù)返回控制函數(shù)返回控制當(dāng)一個函數(shù)的代碼執(zhí)行后,有兩種情況意味著函數(shù)執(zhí)行當(dāng)一個函數(shù)的代碼執(zhí)行后,有兩種情況意味著函數(shù)執(zhí)行完畢并返回到調(diào)用函數(shù)。完畢并返回到調(diào)用函數(shù)。n執(zhí)

7、行完函數(shù)的所有代碼;執(zhí)行完函數(shù)的所有代碼;n執(zhí)行到一個執(zhí)行到一個return語句。語句。 return語句有以下兩種語法形式:語句有以下兩種語法形式:nreturn;nreturn expression;如果函數(shù)中通過如果函數(shù)中通過“return expression;”形式返回,則函數(shù)形式返回,則函數(shù)應(yīng)該是表達(dá)式應(yīng)該是表達(dá)式expression所具有的類型所具有的類型,否則為,否則為void類型。類型。標(biāo)準(zhǔn)標(biāo)準(zhǔn)C+中的中的main函數(shù)函數(shù)有點(diǎn)特殊,盡管被建議是有點(diǎn)特殊,盡管被建議是int類型,類型,但即使但即使沒有沒有return語句帶回值,也不會得到警告錯誤語句帶回值,也不會得到警告錯誤。

8、 5.2.2 函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式n參數(shù)對應(yīng)參數(shù)對應(yīng)n當(dāng)執(zhí)行被調(diào)用函數(shù)的代碼時,形參變量的當(dāng)執(zhí)行被調(diào)用函數(shù)的代碼時,形參變量的值就等于實(shí)參數(shù)的值。應(yīng)保證實(shí)參數(shù)與形值就等于實(shí)參數(shù)的值。應(yīng)保證實(shí)參數(shù)與形式參數(shù)在數(shù)量、類型、順序上的嚴(yán)格匹配。式參數(shù)在數(shù)量、類型、順序上的嚴(yán)格匹配。5.2.2 函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式n函數(shù)調(diào)用表達(dá)式函數(shù)調(diào)用表達(dá)式void類型的函數(shù)類型的函數(shù) 普通數(shù)據(jù)類型的函數(shù)普通數(shù)據(jù)類型的函數(shù) 返回指針或引用的函數(shù)返回指針或引用的函數(shù) 5.2.2 函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式n參數(shù)的默認(rèn)值

9、參數(shù)的默認(rèn)值對于一些常用的實(shí)參數(shù)值,可以說明為默認(rèn)值對于一些常用的實(shí)參數(shù)值,可以說明為默認(rèn)值(缺省值),如果調(diào)用時沒有給出實(shí)參數(shù)則使(缺省值),如果調(diào)用時沒有給出實(shí)參數(shù)則使用聲明或定義中的默認(rèn)值做實(shí)參數(shù)。用聲明或定義中的默認(rèn)值做實(shí)參數(shù)。 nvoid printImage(int r=3, int c=4, char cx=*); nprintImage( );/34的的*圖形圖形nprintImage(4);/44的的*圖形圖形在不能為所有參數(shù)指定默認(rèn)值時,必須按由右在不能為所有參數(shù)指定默認(rèn)值時,必須按由右至左的順序提供默認(rèn)值。同時有定義、聲明時,至左的順序提供默認(rèn)值。同時有定義、聲明時,要要

10、在聲明中指定缺省值而不是在定義中在聲明中指定缺省值而不是在定義中,否則,否則會引起語法錯誤。會引起語法錯誤。 5.2.2 函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式函數(shù)返回控制與函數(shù)調(diào)用表達(dá)式n參數(shù)的計算順序參數(shù)的計算順序?qū)崊?shù)表達(dá)式先按由右至左的順序被計算出值,實(shí)參數(shù)表達(dá)式先按由右至左的順序被計算出值,然后再逐個復(fù)制給形式參數(shù)。然后再逐個復(fù)制給形式參數(shù)。例如:例如:void outdata(int x, int y) cout x , y endl; 注意:注意:實(shí)際參數(shù)的計算次序與數(shù)據(jù)的輸出次序?qū)嶋H參數(shù)的計算次序與數(shù)據(jù)的輸出次序是不同的含義。是不同的含義。 若用語句若用語句int y = 10;outd

11、ata(y+1, y+);調(diào)用。調(diào)用。5.3 參數(shù)的傳遞方式參數(shù)的傳遞方式nC+的函數(shù)參數(shù)有的函數(shù)參數(shù)有2種傳遞方式種傳遞方式傳值和引用,傳值又可以細(xì)分為傳遞普通數(shù)據(jù)傳值和引用,傳值又可以細(xì)分為傳遞普通數(shù)據(jù)和指針。和指針。 5.3.1 普通傳值方式普通傳值方式n以傳值規(guī)則處理參數(shù)會導(dǎo)致一個明顯的結(jié)以傳值規(guī)則處理參數(shù)會導(dǎo)致一個明顯的結(jié)論:論:形式參數(shù)的改變與實(shí)際參數(shù)無關(guān),即形式參數(shù)的改變與實(shí)際參數(shù)無關(guān),即形參的變化不會影響實(shí)參變量的值。形參的變化不會影響實(shí)參變量的值。 5.3.2 傳遞指針方式傳遞指針方式n使用指針做函數(shù)參數(shù)的特殊作用使用指針做函數(shù)參數(shù)的特殊作用利用指針做函數(shù)參數(shù)主要有二個目的:

12、利用指針做函數(shù)參數(shù)主要有二個目的:n在調(diào)用函數(shù)中定義變量(準(zhǔn)備存儲空間)。在調(diào)用函數(shù)中定義變量(準(zhǔn)備存儲空間)。被調(diào)用被調(diào)用函數(shù)使用參數(shù)接收此變量的地址(指針),再以間函數(shù)使用參數(shù)接收此變量的地址(指針),再以間接引用方式將一個值寫入該地址空間。接引用方式將一個值寫入該地址空間。n提高效率。提高效率。在有連續(xù)存放的多個數(shù)據(jù)或一個復(fù)雜的在有連續(xù)存放的多個數(shù)據(jù)或一個復(fù)雜的數(shù)據(jù)(如對象)需要傳遞給函數(shù)時,可以傳遞數(shù)據(jù)數(shù)據(jù)(如對象)需要傳遞給函數(shù)時,可以傳遞數(shù)據(jù)區(qū)的首地址。區(qū)的首地址。 int calcSum(int* x, int count) int sum = 0, k; for(k=0; kc

13、ount; k+) sum += xk; return sum;int a100 = .; /一個已賦值的數(shù)組一個已賦值的數(shù)組cout calcSum(a, 100); /所有所有100個元素的和個元素的和cout calcSum(a+30, 20);/下標(biāo)下標(biāo)30開始的開始的20個元素的和個元素的和5.3.2 傳遞指針方式傳遞指針方式nmain函數(shù)中的參數(shù)函數(shù)中的參數(shù)C+的的main函數(shù)可以使用包含二個參數(shù)(甚至函數(shù)可以使用包含二個參數(shù)(甚至更多)的擴(kuò)展形式:更多)的擴(kuò)展形式:nint main(int argc, char* argv);n其中其中argv是一個指針數(shù)組(字符串?dāng)?shù)組),是一

14、個指針數(shù)組(字符串?dāng)?shù)組),argc是是數(shù)組數(shù)組argv的長度,即元素個數(shù)。的長度,即元素個數(shù)。 main函數(shù)的實(shí)參數(shù)來自于命令行(在函數(shù)的實(shí)參數(shù)來自于命令行(在DOS窗口窗口下以字符方式執(zhí)行程序的形式)而不是程序運(yùn)下以字符方式執(zhí)行程序的形式)而不是程序運(yùn)行時的輸入。行時的輸入。見例見例test_maintest_main。 5.3.3 傳遞引用方式傳遞引用方式n以引用做函數(shù)參數(shù)是引用的主要作用之一。以引用做函數(shù)參數(shù)是引用的主要作用之一。如果采用引用作函數(shù)參數(shù),如果采用引用作函數(shù)參數(shù),C+不建立形參不建立形參副本副本,即形式參數(shù)是對實(shí)參數(shù)的引用,沒,即形式參數(shù)是對實(shí)參數(shù)的引用,沒有自己的存儲空間

15、,或者說形參被捆綁到有自己的存儲空間,或者說形參被捆綁到實(shí)參數(shù)的地址上。因此,實(shí)參數(shù)的地址上。因此,函數(shù)中對形式參函數(shù)中對形式參數(shù)的修改就是對實(shí)參數(shù)的修改。數(shù)的修改就是對實(shí)參數(shù)的修改。n見例見例swapswap。 5.4 特殊的函數(shù)返回值特殊的函數(shù)返回值n1 返回指針的函數(shù)返回指針的函數(shù) n2 返回引用的函數(shù)返回引用的函數(shù) 5.4.1 返回指針的函數(shù)返回指針的函數(shù)n語法和作用語法和作用一個函數(shù)可以返回某個數(shù)據(jù)的存儲地址,即指一個函數(shù)可以返回某個數(shù)據(jù)的存儲地址,即指向某個數(shù)據(jù)的指針。此時,函數(shù)一般具有如下向某個數(shù)據(jù)的指針。此時,函數(shù)一般具有如下原型:原型:ntype* 函數(shù)名函數(shù)名(形式參數(shù)說明

16、表形式參數(shù)說明表);函數(shù)返回指針的主要目的是提高效率和靈活性。函數(shù)返回指針的主要目的是提高效率和靈活性。 5.4.1 返回指針的函數(shù)返回指針的函數(shù)例如,將一個字符串中的小寫字母都轉(zhuǎn)換為大寫字母例如,將一個字符串中的小寫字母都轉(zhuǎn)換為大寫字母 #include using namespace std;char* toupper(char* s) for(char* t=s; *t; t+) if(*t=a & *t=z) *t += A - a; return s;int main( ) char s = Hello Tom; cout toupper(s) endl;5.4.1 返回指針的函數(shù)返

17、回指針的函數(shù)n使用使用const的限定的限定如果函數(shù)返回值為指針類型,則函數(shù)調(diào)用表達(dá)式代表如果函數(shù)返回值為指針類型,則函數(shù)調(diào)用表達(dá)式代表一個指針,因此,可以通過該指針進(jìn)行間接引用,如:一個指針,因此,可以通過該指針進(jìn)行間接引用,如:nchar s = Hello Tom;char s = Hello Tom;n* *toupper(s) = A;toupper(s) = A;ncout s endl;cout s endl;這樣的應(yīng)用實(shí)例并不多見,從安全性考慮,有時需要這樣的應(yīng)用實(shí)例并不多見,從安全性考慮,有時需要禁止這種訪問。為此,可以使用禁止這種訪問。為此,可以使用const進(jìn)行限定,如:

18、進(jìn)行限定,如:nconst char* toupper(char* s); 5.4.1 返回指針的函數(shù)返回指針的函數(shù)n字符串操作函數(shù)字符串操作函數(shù)char *strcpy(char *dest, const char *src);/將將src復(fù)制到復(fù)制到dest,返回返回destchar *strcat(char *dest, const char *src);/將將src連接到連接到dest之后,返回之后,返回destchar *strstr(const char *s1, const char *s2);/在在s1中查找中查找s2是否存在,若存在,返回第一次出現(xiàn)的位置,否則是否存在,若存在

19、,返回第一次出現(xiàn)的位置,否則返回返回0(空指針)(空指針)n此外,還有一些以字符串指針為參數(shù)的函數(shù),如:此外,還有一些以字符串指針為參數(shù)的函數(shù),如:int strlen(const char *s);/計算字符串計算字符串s的實(shí)際長度的實(shí)際長度int strcmp(const char* s1, const char* s2);/比較字符串比較字符串s1和和s2的大小。相等時返回的大小。相等時返回0,s1大時返回正數(shù),大時返回正數(shù),s1小小時返回負(fù)數(shù)時返回負(fù)數(shù)n使用上述函數(shù)時應(yīng)添加使用上述函數(shù)時應(yīng)添加“#include”指令。指令。 5.4.1 返回指針的函數(shù)返回指針的函數(shù)n例:從鍵盤輸入兩個

20、字符串例:從鍵盤輸入兩個字符串s和和t,并將并將t在在s中的第一次出現(xiàn)中的第一次出現(xiàn)刪除。刪除。 #include #include using namespace std;int main() char s100, t100; cin s t; char* pos = strstr(s, t); if(pos != 0) strcpy(pos, pos + strlen(t); cout s;5.4.1 返回指針的函數(shù)返回指針的函數(shù)n用用strcpy和和strcat時最容易出現(xiàn)的錯誤是未時最容易出現(xiàn)的錯誤是未初始化的指針和空間不足的問題初始化的指針和空間不足的問題 。char *s, t10

21、;strcpy(s, “string”);/錯誤,錯誤,s是空懸指針是空懸指針strcpy(t, “string”);/正確正確strcpy(t, “this is a string”);/錯誤,錯誤,t的空間長度不夠的空間長度不夠char* s1 = Hello, s2 = Hello;strcat(s1, Tom); /錯誤,錯誤,s1沒有足夠的存儲空間沒有足夠的存儲空間strcat(s2, Tom); /錯誤,錯誤,s2沒有足夠的額外空間沒有足夠的額外空間 5.4.1 返回指針的函數(shù)返回指針的函數(shù)n返回復(fù)雜對象的指針返回復(fù)雜對象的指針一個復(fù)雜對象意味著較大的數(shù)據(jù)量,如果以指一個復(fù)雜對象意

22、味著較大的數(shù)據(jù)量,如果以指針代替普通對象會明顯提高效率,如:針代替普通對象會明顯提高效率,如: string* func(string& s) /string是是C+定義的字符串類型定義的字符串類型 . return &s;/返回對象的地址返回對象的地址 5.4.2 返回引用的函數(shù)返回引用的函數(shù)n語法語法函數(shù)的原型為:函數(shù)的原型為:ntype& 函數(shù)名函數(shù)名(形式參數(shù)說明表形式參數(shù)說明表);返回引用的函數(shù)帶回對某個變量的引用,相當(dāng)返回引用的函數(shù)帶回對某個變量的引用,相當(dāng)于只帶回變量的地址(但不能做地址使用),于只帶回變量的地址(但不能做地址使用),其效率方面的優(yōu)勢是明顯的。其效率方面的優(yōu)勢是明

23、顯的。 5.4.2 返回引用的函數(shù)返回引用的函數(shù)例:下面的函數(shù)例:下面的函數(shù)conv將一個整數(shù)轉(zhuǎn)換成不小于它的偶數(shù)。將一個整數(shù)轉(zhuǎn)換成不小于它的偶數(shù)。#include using namespace std;int& conv(int& a) a = (a%2? a+1: a);/值為奇數(shù)時加值為奇數(shù)時加1 return a;/返回引用返回引用aint main( ) int x = 3; conv(x)+;/x加加1,即,即4加加1 cout x b ? a : b ; 5.6 內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)n如果一個函數(shù)被指定為內(nèi)聯(lián)函數(shù),它將在如果一個函數(shù)被指定為內(nèi)聯(lián)函數(shù),它將在程序中每個調(diào)用點(diǎn)上被內(nèi)聯(lián)地

24、展開。例如:程序中每個調(diào)用點(diǎn)上被內(nèi)聯(lián)地展開。例如:int maxV = max(3+2,7)+max(i, j);n在編譯時被展開為:在編譯時被展開為:int maxV = (5 7 ? 5 : 7)+(i j ? i : j);5.6 內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)n在定義內(nèi)聯(lián)函數(shù)時應(yīng)注意兩方面的問題:在定義內(nèi)聯(lián)函數(shù)時應(yīng)注意兩方面的問題: inline只是對編譯器的只是對編譯器的建議建議而非命令。因此,內(nèi)而非命令。因此,內(nèi)聯(lián)函數(shù)應(yīng)是結(jié)構(gòu)簡單、語句短小的函數(shù),聯(lián)函數(shù)應(yīng)是結(jié)構(gòu)簡單、語句短小的函數(shù),不能不能在內(nèi)聯(lián)函數(shù)中使用流程控制語句,也不能含有在內(nèi)聯(lián)函數(shù)中使用流程控制語句,也不能含有遞歸調(diào)用遞歸調(diào)用。 內(nèi)聯(lián)函

25、數(shù)必須在調(diào)用該函數(shù)的每個文本文件中內(nèi)聯(lián)函數(shù)必須在調(diào)用該函數(shù)的每個文本文件中定義,第一次調(diào)用前必須有冠以定義,第一次調(diào)用前必須有冠以inline的聲明或的聲明或定義。因此,在有定義和聲明時,保險的做法定義。因此,在有定義和聲明時,保險的做法是都加上是都加上inline關(guān)鍵字。關(guān)鍵字。 5.7 函數(shù)重載函數(shù)重載n由于函數(shù)重載使一個名字具有由于函數(shù)重載使一個名字具有“多種功多種功能能”,被認(rèn)為是具有,被認(rèn)為是具有“多種形態(tài)多種形態(tài)”性質(zhì)。性質(zhì)。這是面向?qū)ο蟪绦蛟O(shè)計技術(shù)中的一個十分這是面向?qū)ο蟪绦蛟O(shè)計技術(shù)中的一個十分重要的特征重要的特征多態(tài)性多態(tài)性。 n函數(shù)重載允許多個函數(shù)共享同一個函數(shù)名,函數(shù)重載允

26、許多個函數(shù)共享同一個函數(shù)名,其主要目的是針對不同參數(shù)類型提供相同其主要目的是針對不同參數(shù)類型提供相同的操作。的操作。 5.7 函數(shù)重載函數(shù)重載n1 函數(shù)重載的實(shí)現(xiàn)函數(shù)重載的實(shí)現(xiàn) 利用函數(shù)重載技術(shù),我們可以用相同的函數(shù)名定義出不同的函數(shù):int max(int v1, int v2) return v1v2?v1:v2; int max(int v1, int v2, int v3) int v12 = v1v2?v1:v2; return v12v3?v12:v3;double max(double v1, double v2) return v1v2?v1:v2; const char* m

27、ax(const char* s1, const char* s2) return strcmp(s1, s2)0?s1:s2; 5.7 函數(shù)重載函數(shù)重載n2 重載函數(shù)中的問題重載函數(shù)中的問題在語法上,函數(shù)的形式不同是指重載的函數(shù)必在語法上,函數(shù)的形式不同是指重載的函數(shù)必須具有不同的形式參數(shù)表,即不同的參數(shù)類型、須具有不同的形式參數(shù)表,即不同的參數(shù)類型、數(shù)量或順序。數(shù)量或順序。返回類型不同不能作為區(qū)分函數(shù)的依據(jù),即不返回類型不同不能作為區(qū)分函數(shù)的依據(jù),即不能重載參數(shù)表相同而只有返回值不同的函數(shù)。能重載參數(shù)表相同而只有返回值不同的函數(shù)。void func(int x, int y); int f

28、unc(int a, int b); /錯誤的重載錯誤的重載5.7 函數(shù)重載函數(shù)重載n重載函數(shù)最主要的目的是為了應(yīng)付不同的數(shù)據(jù)類重載函數(shù)最主要的目的是為了應(yīng)付不同的數(shù)據(jù)類型,各重載函數(shù)應(yīng)該執(zhí)行一致的操作。型,各重載函數(shù)應(yīng)該執(zhí)行一致的操作。n如果僅是參數(shù)個數(shù)不同,可以借助參數(shù)的如果僅是參數(shù)個數(shù)不同,可以借助參數(shù)的缺省值缺省值來處理而不是進(jìn)行函數(shù)重載。來處理而不是進(jìn)行函數(shù)重載。n例如,對于如下的重載函數(shù):例如,對于如下的重載函數(shù):int setData(int);int setData(int, int);n可以考慮用如下的一個函數(shù)代替:可以考慮用如下的一個函數(shù)代替:int setData(int

29、, int=0);5.8 指向函數(shù)的指針指向函數(shù)的指針n1 函數(shù)指針函數(shù)指針任何一個函數(shù)在編譯后都對應(yīng)一系列的指令,這些指任何一個函數(shù)在編譯后都對應(yīng)一系列的指令,這些指令在內(nèi)存中占據(jù)一塊連續(xù)的存儲單元,粗略地說,其令在內(nèi)存中占據(jù)一塊連續(xù)的存儲單元,粗略地說,其中第一條指令的地址被稱為函數(shù)的中第一條指令的地址被稱為函數(shù)的“入口地址入口地址”,函,函數(shù)的一次調(diào)用就是通過將函數(shù)的入口地址寫入程序計數(shù)的一次調(diào)用就是通過將函數(shù)的入口地址寫入程序計數(shù)器完成的。數(shù)器完成的。函數(shù)的入口地址被稱為指向函數(shù)的指針。函數(shù)的入口地址被稱為指向函數(shù)的指針。在在C+中,一個函數(shù)的名字代表了函數(shù)的入口地址,即中,一個函數(shù)的

30、名字代表了函數(shù)的入口地址,即函數(shù)名是指向該函數(shù)的指針。例如,若有如下函數(shù)定函數(shù)名是指向該函數(shù)的指針。例如,若有如下函數(shù)定義:義:void func(int x) 則函數(shù)名則函數(shù)名func是指向此函數(shù)代碼的指針,系統(tǒng)的每次是指向此函數(shù)代碼的指針,系統(tǒng)的每次函數(shù)調(diào)用都使用了這一指針。函數(shù)調(diào)用都使用了這一指針。 5.8 指向函數(shù)的指針指向函數(shù)的指針n2 指向函數(shù)的指針變量指向函數(shù)的指針變量指向函數(shù)的指針變量。一般定義形式如下:指向函數(shù)的指針變量。一般定義形式如下:ntype (*變量名變量名)(形參說明表形參說明表);例如,為了存儲函數(shù)指針例如,為了存儲函數(shù)指針func,應(yīng)按如下形式應(yīng)按如下形式定義

31、變量:定義變量:nvoid (*fpx)(int x);nfpx = func;如果需要明確描述出某種類型的函數(shù)指針,可如果需要明確描述出某種類型的函數(shù)指針,可以先用以先用typedef進(jìn)行定義:進(jìn)行定義:ntypedef void (*fpx)(int); nfpx p1, p2, pa5; 5.8 指向函數(shù)的指針指向函數(shù)的指針n3 函數(shù)指針的賦值函數(shù)指針的賦值由于函數(shù)指針的特殊性,所以允許參與的運(yùn)算由于函數(shù)指針的特殊性,所以允許參與的運(yùn)算主要是賦值和調(diào)用函數(shù)。主要是賦值和調(diào)用函數(shù)。 double (*fpx)(double);fpx = sin; void func(double (*fp

32、x)(double); func(sin); /通過參數(shù)傳遞給函數(shù)通過參數(shù)傳遞給函數(shù) 5.8 指向函數(shù)的指針指向函數(shù)的指針n4 通過函數(shù)指針調(diào)用函數(shù)通過函數(shù)指針調(diào)用函數(shù)如果如果p是一個函數(shù)指針,利用是一個函數(shù)指針,利用“*p”或或“p”都都可以表示它指向的函數(shù)(這是指向函數(shù)指針?biāo)梢员硎舅赶虻暮瘮?shù)(這是指向函數(shù)指針?biāo)赜械男再|(zhì))。特有的性質(zhì))。 nx = sin(0.5); /角度應(yīng)采用弧度表示角度應(yīng)采用弧度表示ny = (*sin)(0.35); 5.8 指向函數(shù)的指針指向函數(shù)的指針n一個應(yīng)用范例一個應(yīng)用范例使用函數(shù)指針的主要用途之一是將一個函數(shù)傳遞給另一個函數(shù)。使用函數(shù)指針的主要用途之一

33、是將一個函數(shù)傳遞給另一個函數(shù)。下面的代碼構(gòu)造了一個函數(shù)下面的代碼構(gòu)造了一個函數(shù)calcMax,功能是計算出任何數(shù)學(xué)函數(shù)功能是計算出任何數(shù)學(xué)函數(shù)在指定區(qū)間上的近似最大值。在指定區(qū)間上的近似最大值。 y0 a b x圖 求函數(shù)的近似最大值5.9 函數(shù)模板函數(shù)模板n函數(shù)重載的技術(shù)提供兩個同名函數(shù)定義的目的僅函數(shù)重載的技術(shù)提供兩個同名函數(shù)定義的目的僅是為了使名字是為了使名字func能夠?qū)Σ煌瑪?shù)據(jù)類型有效,但能夠?qū)Σ煌瑪?shù)據(jù)類型有效,但是,要想對于是,要想對于int和和float數(shù)據(jù)的組合都給出重載函數(shù)據(jù)的組合都給出重載函數(shù)的定義是非常麻煩甚至是不現(xiàn)實(shí)的。數(shù)的定義是非常麻煩甚至是不現(xiàn)實(shí)的。n如果能夠使參數(shù)

34、的類型也參數(shù)化,我們可以用一如果能夠使參數(shù)的類型也參數(shù)化,我們可以用一個既包含類型參數(shù)又包含數(shù)據(jù)參數(shù)的更通用的函個既包含類型參數(shù)又包含數(shù)據(jù)參數(shù)的更通用的函數(shù)定義來代替一組重載函數(shù),如:數(shù)定義來代替一組重載函數(shù),如:void func(type x, type y);n其中的類型可以在調(diào)用函數(shù)時指定。這樣的其中的類型可以在調(diào)用函數(shù)時指定。這樣的“函函數(shù)數(shù)”稱為稱為函數(shù)模板函數(shù)模板。 5.9.1 函數(shù)模板定義函數(shù)模板定義n函數(shù)模板的語法函數(shù)模板的語法template / 也可用也可用class Type max(Type v1, Type v2) return v1v2?v1:v2; n如果使用多

35、個模板類型參數(shù)用逗號分隔成列如果使用多個模板類型參數(shù)用逗號分隔成列表形式。如:表形式。如: template void func1(T1 a, T2 b);/必須重新聲明模板參數(shù)必須重新聲明模板參數(shù)template T1 func2(T2 x, T1 y, int z);5.9.1 函數(shù)模板定義函數(shù)模板定義n定義與聲明中均需重新聲明模板類型參數(shù)定義與聲明中均需重新聲明模板類型參數(shù) template Type max(Type v1, Type v2);template Type max(Type v1, Type v2) return v1v2?v1:v2; 5.9.2 模板函數(shù)調(diào)用模板函數(shù)調(diào)

36、用n由編譯器根據(jù)實(shí)參數(shù)進(jìn)行類型推斷由編譯器根據(jù)實(shí)參數(shù)進(jìn)行類型推斷 double x = max(1.0, 3.0); Type max(Type v1, Type v2) n采用顯式指定模板實(shí)參的方式來調(diào)用模板采用顯式指定模板實(shí)參的方式來調(diào)用模板函數(shù),其形式為:函數(shù),其形式為:模板函數(shù)名模板函數(shù)名(實(shí)參數(shù)列表實(shí)參數(shù)列表) int x = max(1, 3);double x = max(1.0, 3.0);func2(2, 1.5, 10); 編譯器利用用戶指定的類型代替函數(shù)中的模板類型參數(shù)生成對應(yīng)編譯器利用用戶指定的類型代替函數(shù)中的模板類型參數(shù)生成對應(yīng)的函數(shù)版本。我們只要將的函數(shù)版本。我們只

37、要將max、max、func2看作是一個完整的函數(shù)名就可以了??醋魇且粋€完整的函數(shù)名就可以了。 5.9.2 模板函數(shù)調(diào)用模板函數(shù)調(diào)用n在模板類型參數(shù)的聲明中除了類型外,還可以包在模板類型參數(shù)的聲明中除了類型外,還可以包含常量。例如:含常量。例如:template bool isBetween(AnyType x) return (x=begin & x=end ? true : false);n這里的這里的begin和和end都應(yīng)以常量作為實(shí)參提供在模都應(yīng)以常量作為實(shí)參提供在模板類型參數(shù)列表中,如:板類型參數(shù)列表中,如:cout isBetween(35)endl;5.9.3 模板函數(shù)重載模板

38、函數(shù)重載n模板函數(shù)可以像普通函數(shù)一樣重載。例如:模板函數(shù)可以像普通函數(shù)一樣重載。例如:template Type max(Type v1, Type v2) return v1v2?v1:v2; template Type max(Type v1, Type v2, Type v3) Type v12 = (v1v2?v1:v2); return (v12v3?v12:v3);char* max(char* v1, char* v2) return strcmp(v1, v2)0? v1 : v2;cout max(1.2, 3.0) max(hello, heLLo) max(3,1,2);

39、 5.10 變量的存儲屬性變量的存儲屬性nC+將程序使用的內(nèi)存劃分為將程序使用的內(nèi)存劃分為4個區(qū)域:個區(qū)域:代代碼區(qū)、靜態(tài)區(qū)、棧區(qū)和堆區(qū)。碼區(qū)、靜態(tài)區(qū)、棧區(qū)和堆區(qū)。n一個變量定義可以包含一個變量定義可以包含4種存儲屬性中的一種存儲屬性中的一種:種:extern(外部)、外部)、static(靜態(tài))、靜態(tài))、auto(自動)和自動)和register(寄存器)。寄存器)。n具有不同存儲屬性的變量定義位置也有差具有不同存儲屬性的變量定義位置也有差異。異。 5.10 變量的存儲屬性(續(xù))變量的存儲屬性(續(xù))n外部變量和靜態(tài)變量存儲在外部變量和靜態(tài)變量存儲在靜態(tài)區(qū)靜態(tài)區(qū),其特,其特點(diǎn)有:點(diǎn)有:生存期長

40、。在變量構(gòu)建后,一直存在,在整個生存期長。在變量構(gòu)建后,一直存在,在整個程序運(yùn)行結(jié)束后才拆除,屬于永久性變量;程序運(yùn)行結(jié)束后才拆除,屬于永久性變量;初始化只在第一次執(zhí)行到變量定義語句時進(jìn)行初始化只在第一次執(zhí)行到變量定義語句時進(jìn)行一次。一次。在沒有明確提供初始化值時,由系統(tǒng)賦予在沒有明確提供初始化值時,由系統(tǒng)賦予0值值。5.10 變量的存儲屬性(續(xù))變量的存儲屬性(續(xù))n自動變量存儲在自動變量存儲在棧區(qū)棧區(qū),其特點(diǎn)是:,其特點(diǎn)是:生存期短。自動變量在一個局部的塊內(nèi)定義,生存期短。自動變量在一個局部的塊內(nèi)定義,在程序運(yùn)行離開塊時被拆除,屬于臨時性變量;在程序運(yùn)行離開塊時被拆除,屬于臨時性變量;每次進(jìn)入塊時重新構(gòu)建自動變量并進(jìn)行初始化;每次進(jìn)入塊時重新構(gòu)建自動變量并進(jìn)行初始化;在沒有明確提供初始化值時,值不可預(yù)測。在沒有明確提供初始化值時,值不可預(yù)測。 5.10 變量的存儲屬性(續(xù))變量的存儲屬性(續(xù))n動態(tài)分配的變量存儲在動態(tài)分配的變量存儲在堆區(qū)堆區(qū),在使用,在使用delete釋放或程序運(yùn)行結(jié)束時拆除。釋放或程序運(yùn)行結(jié)束時拆除。n寄存器變量寄存器變量保存在寄存器而不是內(nèi)存中,保存在寄存器而不是內(nèi)存中,特點(diǎn)是處理速度較快,通常作為循環(huán)的控特點(diǎn)是處理速度較快,通常作為循環(huán)的控制變量,但由于制變量,但由于C+本身能夠?qū)Υa進(jìn)行優(yōu)本身能夠?qū)Υa進(jìn)行優(yōu)化而較少使用?;?/p>

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論