面向?qū)ο蟪绦蛟O(shè)計(jì)教案_第1頁
面向?qū)ο蟪绦蛟O(shè)計(jì)教案_第2頁
面向?qū)ο蟪绦蛟O(shè)計(jì)教案_第3頁
面向?qū)ο蟪绦蛟O(shè)計(jì)教案_第4頁
面向?qū)ο蟪绦蛟O(shè)計(jì)教案_第5頁
已閱讀5頁,還剩15頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、C+面向?qū)ο蟪绦蛟O(shè)計(jì)課程輔導(dǎo)三-函數(shù)的定義與使用 一個(gè)C+語言程序由若干個(gè)程序文件和頭文件所組成,每個(gè)頭文件中通常帶有用戶類型的定義、符號(hào)常量的定義、函數(shù)的聲明等內(nèi)容,每個(gè)程序文件由若干個(gè)函數(shù)定義所組成,其中必有一個(gè)并且只有一個(gè)程序文件中包含有主函數(shù)main,稱此程序文件為主程序文件。函數(shù)是C+程序中的基本功能模塊和執(zhí)行單元,這一章專門討論函數(shù)的定義和調(diào)用,變量的作用域和生存期等內(nèi)容。 一、函數(shù)的定義 1定義格式 <類型名> <函數(shù)名> (<參數(shù)表>) <函數(shù)體> <類型名>為系統(tǒng)或用戶已定義的一種數(shù)據(jù)類型,它是函數(shù)執(zhí)行過程中通過re

2、turn語句要求返回的值的類型,又稱為該函數(shù)的類型。當(dāng)一個(gè)函數(shù)不需要通過return語句返回一個(gè)值時(shí),稱為無返回值函數(shù)或無類型函數(shù),此時(shí)需要使用保留字void作為類型名。當(dāng)類型名為int時(shí),可以省略不寫,但為了清楚起見,還是寫明為好。 <函數(shù)名>是用戶為函數(shù)所起的名字,它是一個(gè)標(biāo)識(shí)符,應(yīng)符合C+標(biāo)識(shí)符的一般命名規(guī)則,用戶通過使用這個(gè)函數(shù)名和實(shí)參表可以調(diào)用該函數(shù)。 <參數(shù)表>又稱形式參數(shù)表,它包含有任意多個(gè)(含0個(gè),即沒有)參數(shù)說明項(xiàng),當(dāng)多于一個(gè)時(shí)其前后兩個(gè)參數(shù)說明項(xiàng)之間必須用逗號(hào)分開。每個(gè)參數(shù)說明項(xiàng)由一種已定義的數(shù)據(jù)類型和一個(gè)變量標(biāo)識(shí)符組成,該變量標(biāo)識(shí)符成為該函數(shù)的形式

3、參數(shù),簡(jiǎn)稱形參,形參前面給出的數(shù)據(jù)類型稱為該形參的類型。一個(gè)函數(shù)定義中的<參數(shù)表>可以被省略,表明該函數(shù)為無參函數(shù),若<參數(shù)表>用void取代,則也表明是無參函數(shù),若<參數(shù)表>不為空,同時(shí)又不是保留字void,則稱為帶參函數(shù)。 <函數(shù)體>是一條復(fù)合語句,它以左花括號(hào)開始,到右花括號(hào)結(jié)束,中間為一條或若干條C+語句。 在一個(gè)函數(shù)的參數(shù)表中,每個(gè)參數(shù)可以為任一種數(shù)據(jù)類型,包括普通類型、指針類型、數(shù)組類型、引用類型等,一個(gè)函數(shù)的返回值可以是除數(shù)組類型之外的任何類型,包括普通類型、指針類型和引用類型等。另外,當(dāng)不需要返回值時(shí),應(yīng)把函數(shù)定義為void類型。

4、 2定義格式舉例 (1) void f1() . (2) void f2(int x) . (3) int f3(int x,int* p) . (4) char* f4(char a). (5) int f5(int& x,double d) . (6) int& f6(int b10, int n) . (7) void f7(float cN, int m, float& max) . (8) bool f8(ElemType*& bt, ElemType& item) . 在第一條函數(shù)定義中,函數(shù)名為f1,函數(shù)類型為void,參數(shù)表為空,此函數(shù)是

5、一個(gè)無參無類型函數(shù)。若在f1后面的圓括號(hào)內(nèi)寫入保留字void,也表示為無參函數(shù)。 在第二條函數(shù)定義中,僅帶有一個(gè)類型為int的形參變量x,該函數(shù)沒有返回值。 在第三條函數(shù)定義中,函數(shù)名為f3,函數(shù)類型為int,函數(shù)參數(shù)為x和p,其中x為int型普通參數(shù),p為int*型指針參數(shù)。 在第四條函數(shù)定義中,函數(shù)名為f4,函數(shù)類型為char*,即字符指針類型,參數(shù)表中包含一個(gè)一維字符數(shù)組參數(shù)。注意:在定義任何類型的一維數(shù)組參數(shù)時(shí),不需要給出維的尺寸,當(dāng)然給出也是允許的,但沒有任何意義。 在第五條函數(shù)定義中,函數(shù)名為f5,返回類型為int,該函數(shù)帶有兩個(gè)形參,一個(gè)為 整型引用變量x,另一個(gè)為雙精度變量d。

6、 在第六條函數(shù)定義中,函數(shù)名為f6,函數(shù)類型為int&,即整型引用,該函數(shù)帶有兩個(gè)形參,一個(gè)是整型數(shù)組b,另一個(gè)是整型變量n。在這里定義形參數(shù)組b所給出的維的尺寸10可以被省略。 在第七條函數(shù)定義中,函數(shù)名為f7,無函數(shù)類型,參數(shù)表中包含三個(gè)參數(shù),一個(gè)為二維單精度型數(shù)組c,第二個(gè)為整型變量m,第三個(gè)為單精度引用變量max。注意:當(dāng)定義一個(gè)二維數(shù)組參數(shù)時(shí),第二維的尺寸必須給出,并且必須是一個(gè)常量表達(dá)式,第一維尺寸可給出也可不給出,其作用相同。 在第八條函數(shù)定義中,函數(shù)名為f8,返回類型為bool,即邏輯類型,該函數(shù)帶有兩個(gè)參數(shù),一個(gè)為形參bt,它為ElemType的指針引用類型,另一個(gè)為

7、形參item,它是ElemType的引用類型,其中ElemType為一種用戶定義的類型或是通過typedef語句定義的一個(gè)類型的別名。 3有關(guān)函數(shù)定義的幾點(diǎn)說明 (1) 函數(shù)原型語句 在一個(gè)函數(shù)定義中,函數(shù)體之前的所有部分稱為函數(shù)頭,它給出了該函數(shù)的返回類型、每個(gè)參數(shù)的次序和類型等函數(shù)原型信息,所以當(dāng)沒有專門給出函數(shù)原型說明語句時(shí),系統(tǒng)就從函數(shù)頭中獲取函數(shù)原型信息。 一個(gè)函數(shù)必須先定義或聲明而后才能被調(diào)用,否則編譯程序無法判斷該調(diào)用的正確性。一個(gè)函數(shù)的聲明是通過使用一條函數(shù)原型語句實(shí)現(xiàn)的,當(dāng)然使用多條相同的原型語句聲明同一個(gè)函數(shù)雖然多余但也是允許的,編譯時(shí)不會(huì)出現(xiàn)錯(cuò)誤。 在一個(gè)完整的程序中,函

8、數(shù)的定義和函數(shù)的調(diào)用可以在同一個(gè)程序文件中,也可以處在不同的程序文件中,但必須確保函數(shù)原型語句與函數(shù)調(diào)用表達(dá)式出現(xiàn)在同一個(gè)文件中,并且函數(shù)原型語句出現(xiàn)在前,函數(shù)的調(diào)用出現(xiàn)在后。 通常把一個(gè)程序中用戶定義的所有函數(shù)的原型語句組織在一起,構(gòu)成一個(gè)頭文件,讓該程序中所含的每個(gè)程序文件的開始(即所有函數(shù)定義之前)包含這個(gè)頭文件(通過#include命令實(shí)現(xiàn)),這樣不管每個(gè)函數(shù)的定義在哪里出現(xiàn),都能夠確保函數(shù)先聲明后使用(即調(diào)用)這一原則的實(shí)現(xiàn)。 一個(gè)函數(shù)的原型語句就是其函數(shù)頭的一個(gè)拷貝,當(dāng)然要在最后加上語句接上結(jié)束符分號(hào)。函數(shù)原型語句與函數(shù)頭也有細(xì)微的差別,在函數(shù)原型語句中,其參數(shù)表中的每個(gè)參數(shù)允許只

9、保留參數(shù)類型,而省略參數(shù)名,并且若使用參數(shù)名也允許與函數(shù)頭中對(duì)應(yīng)的參數(shù)名不同。 (2) 常量形參 在定義一個(gè)函數(shù)時(shí),若只允許函數(shù)體訪問一個(gè)形參的值,不允許修改它的值,則應(yīng)把該形參說明為常量,這只要在形參說明的前面加上const保留字進(jìn)行修飾即可。如: void f9(const int& x, const char& y); void f10(const char* p, char key); 在函數(shù)f9的函數(shù)體中只允許使用x和y的值,不允許修改它們的值。在函數(shù)f10的函數(shù)體中只允許使用p所指向的字符對(duì)象或字符數(shù)組對(duì)象的值,不允許修改它們的值,但在函數(shù)體中既允許使用也允許修改形

10、參key的值。 (3) 缺省參數(shù) 在一個(gè)函數(shù)定義中,可根據(jù)需要對(duì)參數(shù)表末尾的一個(gè)或連續(xù)若干個(gè)參數(shù)給出缺省值,當(dāng)調(diào)用這個(gè)函數(shù)時(shí),若實(shí)參表中沒有給出對(duì)應(yīng)的實(shí)參,則形參將采用這個(gè)缺省值。如: void f11(int x, int y=0) . int f12(int a, char op='+', int k=10) . 函數(shù)f11的定義帶有兩個(gè)參數(shù),分別為整型變量x和y,并且y帶有缺省值0,若調(diào)用該函數(shù)的表達(dá)式為f11(a,b),將把a(bǔ)的值賦給x,把b的值賦給y,接著執(zhí)行函數(shù)體;若調(diào)用該函數(shù)的表達(dá)式為f11(a+b),則也是正確的調(diào)用格式,它將把a(bǔ)+b的值賦給x,因y沒有對(duì)應(yīng)的實(shí)

11、參,將采用缺省值0,參數(shù)傳送后接著執(zhí)行函數(shù)體。 函數(shù)f12的定義帶有三個(gè)參數(shù),其中后兩個(gè)帶有缺省值,所以調(diào)用它的函數(shù)格式有三種,一種只帶一個(gè)實(shí)參,用于向形參a傳送數(shù)據(jù),后兩個(gè)形參采用缺省值,第二種帶有兩個(gè)實(shí)參,用于分別向形參a和op傳送數(shù)據(jù),第三個(gè)形參采用缺省值,第三種帶有三個(gè)實(shí)參,分別用于傳送給三個(gè)形參。 若一個(gè)函數(shù)帶有專門的函數(shù)原型語句,則形參的缺省值只能在該函數(shù)原型語句中給出,不允許在函數(shù)頭中給出。如對(duì)于上述的f11和f12函數(shù),其對(duì)應(yīng)的函數(shù)原型語句分別為: void f11(int x, int y=0); int f12(int a, char op='+', int

12、 k=10); 函數(shù)定義應(yīng)分別改寫為: void f11(int x, int y) . int f12(int a, char op, int k) . (4) 數(shù)組參數(shù) 在函數(shù)定義中的每個(gè)數(shù)組參數(shù)實(shí)際上是指向元素類型的指針參數(shù)。對(duì)于一維數(shù)組參數(shù)說明: <數(shù)據(jù)類型> <數(shù)組名> 它與下面的指針參數(shù)說明完全等價(jià): <數(shù)據(jù)類型> *<指針變量名> 其中<指針變量名>就是數(shù)組參數(shù)說明中的<數(shù)組名>。如對(duì)于f12函數(shù)定義中的數(shù)組參數(shù)說明int a,等價(jià)于指針參數(shù)說明int* a。也就是說,數(shù)組參數(shù)說明中的數(shù)組名a是一個(gè)類型為in

13、t*的形參。注意:在變量定義語句中定義的數(shù)組,其數(shù)組名代表的是一個(gè)數(shù)組,它的值是指向第一個(gè)元素的指針常量,這與數(shù)組形參的含義有區(qū)別。 對(duì)于二維數(shù)組參數(shù)說明: <數(shù)據(jù)類型> <參數(shù)名><第二維尺寸> 它與下面的指針參數(shù)說明完全等價(jià): <數(shù)據(jù)類型> (*<參數(shù)名>)<第二維尺寸> 如對(duì)于f7函數(shù)定義中的二維數(shù)組參數(shù)說明float cN,等價(jià)于指針參數(shù)說明float(*c)N。 (5) 函數(shù)類型 當(dāng)調(diào)用一個(gè)函數(shù)時(shí)就執(zhí)行一遍循環(huán)體,對(duì)于類型為非void的函數(shù),函數(shù)體中至少必須帶有一條return語句,并且每條return語句必須帶

14、有一個(gè)表達(dá)式,當(dāng)執(zhí)行到任一條return語句時(shí),將計(jì)算出它的表達(dá)式的值,結(jié)束整個(gè)函數(shù)的調(diào)用過程,把這個(gè)值作為所求的函數(shù)值帶回到調(diào)用位置,參與相應(yīng)的運(yùn)算;對(duì)于類型為void的函數(shù),它不需要返回任何函數(shù)值,所以在函數(shù)體中既可以使用return語句,也可以不使用,對(duì)于使用的每條return語句不允許也不需要帶有表達(dá)式,當(dāng)執(zhí)行到任一條return語句時(shí),或執(zhí)行到函數(shù)體最后結(jié)束位置時(shí),將結(jié)束函數(shù)的調(diào)用過程,返回到調(diào)用位置向下繼續(xù)執(zhí)行。 (6) 內(nèi)聯(lián)函數(shù) 當(dāng)在一個(gè)函數(shù)的定義或聲明前加上關(guān)鍵字inline則就把該函數(shù)聲明為內(nèi)聯(lián)函數(shù)。計(jì)算機(jī)在執(zhí)行一般函數(shù)的調(diào)用時(shí),無論該函數(shù)多么簡(jiǎn)單或復(fù)雜,都要經(jīng)過參數(shù)傳遞、執(zhí)

15、行函數(shù)體和返回等操作。若把一個(gè)函數(shù)聲明為內(nèi)聯(lián)函數(shù)后,在程序編譯階段系統(tǒng)就有可能把所有調(diào)用該函數(shù)的地方都直接替換為該函數(shù)的執(zhí)行代碼,由此省去函數(shù)調(diào)用時(shí)的參數(shù)傳遞和返回操作,從而加快整個(gè)程序的執(zhí)行速度。通??砂岩恍┫鄬?duì)簡(jiǎn)單的函數(shù)聲明為內(nèi)聯(lián)函數(shù),對(duì)于較復(fù)雜的函數(shù)則不應(yīng)聲明為內(nèi)聯(lián)函數(shù)。從用戶的角度看,調(diào)用內(nèi)聯(lián)函數(shù)和一般函數(shù)沒有任何區(qū)別。下面就是一個(gè)內(nèi)聯(lián)函數(shù)定義的例子,它返回形參值的立方。 inline int cube(int n) return n*n*n; 二、函數(shù)的調(diào)用 1調(diào)用格式 調(diào)用一個(gè)已定義或聲明的函數(shù)需要給出相應(yīng)的函數(shù)調(diào)用表達(dá)式,其格式為: <函數(shù)名>(<實(shí)參表>

16、) 若調(diào)用的是一個(gè)無參函數(shù),或全部形參為可選的函數(shù),則<實(shí)參表>被省略,此時(shí)實(shí)參表為空。 <實(shí)參表>為一個(gè)或若干個(gè)用逗號(hào)分開的表達(dá)式,表達(dá)式的個(gè)數(shù)應(yīng)至少等于不帶缺省值的形參的個(gè)數(shù),應(yīng)不大于所有形參的個(gè)數(shù),<實(shí)參表>中每個(gè)表達(dá)式稱為一個(gè)實(shí)參,每個(gè)實(shí)參的類型必須與相應(yīng)的形參類型相同或兼容(即能夠被自動(dòng)轉(zhuǎn)換為形參的類型,如整型與字符型就是兼容類型)。每個(gè)實(shí)參是一個(gè)表達(dá)式,包括是一個(gè)常量、一個(gè)變量、一個(gè)函數(shù)調(diào)用表達(dá)式,或一個(gè)帶運(yùn)算符的一般表達(dá)式。如: (1) g1(25) /實(shí)參是一個(gè)整數(shù) (2) g2(x) /實(shí)參是一個(gè)變量 (3) g3(a,2*b+3) /第一

17、個(gè)為變量,第二個(gè)運(yùn)算表達(dá)式 (4) g4(sin(x),) /第一個(gè)為函數(shù)調(diào)用表達(dá)式,第二個(gè)為字符常量 (5) g5(&d,*p,x/y-1) /分別為取地址運(yùn)算、間接訪問和一般運(yùn)算表達(dá)式 任一個(gè)函數(shù)調(diào)用表達(dá)式都可以單獨(dú)作為一條表達(dá)式語句使用,但當(dāng)該函數(shù)調(diào)用帶有返回值時(shí),這個(gè)值被自動(dòng)丟失。對(duì)于具有返回值的函數(shù),調(diào)用它的函數(shù)表達(dá)式通常是作為一個(gè)數(shù)據(jù)項(xiàng)使用,用返回值參與相應(yīng)的運(yùn)算,如把它賦值給一個(gè)變量,把它輸出到屏幕上顯示出來等。如: (1) f1(); /作為單獨(dú)的語句,若有返回值則被丟失 (2) y=f3(x,a); /返回值被賦給y保存 (3) cout<<f6(c,10

18、)<<endl; /返回值被輸出到屏幕上 (4) f2(f5(x1,d1)+1); /f2調(diào)用作為單獨(dú)的語句, /f5調(diào)用是f2實(shí)參表達(dá)式中的一個(gè)數(shù)據(jù)項(xiàng) (5) f6(b,5)=3*w-2; /f6函數(shù)調(diào)用的返回值當(dāng)作一個(gè)左值 (6) if(f8(ct,x) cout<<”true”<<endl; / f6函數(shù)調(diào)用作為一個(gè)判斷條件, /若返回值不為0則執(zhí)行后面的輸出語句,否則不執(zhí)行任何操作 2. 調(diào)用過程 當(dāng)調(diào)用一個(gè)函數(shù)時(shí),整個(gè)調(diào)用過程分為三步進(jìn)行,第一步是參數(shù)傳遞,第二步是函數(shù)體執(zhí)行,第三步是返回,即返回到函數(shù)調(diào)用表達(dá)式的位置。 參數(shù)傳遞稱為實(shí)虛結(jié)合,即實(shí)

19、參向形參傳遞信息,使形參具有確切地含義(即具有對(duì)應(yīng)的存儲(chǔ)空間和初值)。這種傳遞又分為兩種不同情況,一種是向非引用參數(shù)傳遞,另一種是向引用參數(shù)傳遞。 形參表中的非引用參數(shù)包括普通類型的參數(shù)、指針類型的參數(shù)和數(shù)組類型的參數(shù)三種。實(shí)際上可以把數(shù)組類型的參數(shù)歸為指針類型的參數(shù)。 當(dāng)形參為非引用參數(shù)時(shí),實(shí)虛結(jié)合的過程為:首先計(jì)算出實(shí)參表達(dá)式的值,接著給對(duì)應(yīng)的形參變量分配一個(gè)存儲(chǔ)空間,該空間的大小等于該形參類型的長(zhǎng)度,然后把已求出的實(shí)參表達(dá)式的值存入到為形參變量分配的存儲(chǔ)空間中,成為形參變量的初值。這種傳遞是把實(shí)參表達(dá)式的值傳送給對(duì)應(yīng)的形參變量,稱這種傳遞方式為“按值傳遞”。 假定有下面的函數(shù)原型: (1

20、) void h1(int x, int y); (2) bool h2(char*p); (3) void h3(int a, int n); (4) char* h4(char bN, int m); 若采用如下的函數(shù)調(diào)用: (1) h1(a,25); /假定a為int型(2) bool bb=h2(sp); /假定sp為char*型(3) h3(b,10); /假定b為int*型(4) char* s=h4(c,n+1); /假定c為int(*)N型,n為int型 當(dāng)執(zhí)行第一條語句中的h1(a,25)調(diào)用時(shí),把第一個(gè)實(shí)參a的值傳送給對(duì)應(yīng)形參x的存儲(chǔ)空間,成為x的初值,把常數(shù)25傳送給形參

21、y的存儲(chǔ)空間,成為y的初值。 當(dāng)執(zhí)行第二條語句中的h2(sp)調(diào)用時(shí),將把sp的值,即一個(gè)字符對(duì)象的存儲(chǔ)地址傳送給對(duì)應(yīng)的指針形參p的存儲(chǔ)空間中,使p指向的對(duì)象就是實(shí)參sp所指向的對(duì)象,即*p和*sp指的是同一個(gè)對(duì)象,若在函數(shù)體中對(duì)*p進(jìn)行了修改,則待調(diào)用結(jié)束返回后通過訪問*sp就得到了這個(gè)修改。 當(dāng)執(zhí)行第三條語句中的h3(b,10)調(diào)用時(shí),將把b的值(通常為元素類型為 int的一維數(shù)組的首地址)傳送給對(duì)應(yīng)數(shù)組變量(實(shí)際為指針變量)a的存儲(chǔ)空間中,使得形參a指向?qū)崊所指向的數(shù)組空間,因此,在函數(shù)體中對(duì)數(shù)組a的存取元素的操作就是對(duì)實(shí)參數(shù)組b的操作。也就是說,采用數(shù)組傳送能夠在函數(shù)體中使用形參數(shù)組

22、訪問對(duì)應(yīng)的實(shí)參數(shù)組。 當(dāng)執(zhí)行第四條語句中的h4(c,n+1)調(diào)用時(shí),將把c的值(通常為與形參b具有相同元素類型和列數(shù)的二維數(shù)組的首地址)傳送給對(duì)應(yīng)二維數(shù)組參數(shù)(實(shí)際為指針變量)a的存儲(chǔ)空間中,使得形參b指向?qū)崊所指向的二維數(shù)組空間,在函數(shù)體中對(duì)數(shù)組b的存取元素的操作就是對(duì)實(shí)參數(shù)組c的操作;該函數(shù)調(diào)用還要把第二個(gè)實(shí)參表達(dá)式n+1的值傳送給形參m中,在函數(shù)體中對(duì)m的操作與相應(yīng)的實(shí)參無關(guān)。 在函數(shù)定義的形參表中說明一個(gè)數(shù)組參數(shù)時(shí),通常還需要說明一個(gè)整型參數(shù),用它來接收由實(shí)參傳送來的數(shù)組的長(zhǎng)度,這樣才能夠使函數(shù)知道待處理元素的個(gè)數(shù)。 當(dāng)形參為引用參數(shù)時(shí),對(duì)應(yīng)的實(shí)參通常是一個(gè)變量,實(shí)虛結(jié)合的過程為:把

23、實(shí)參變量的地址傳送給引用形參,成為引用形參的地址,也就是說使得引用形參是實(shí)參變量的一個(gè)引用(別名),引用形參所占用的存儲(chǔ)空間就是實(shí)參變量所占用的存儲(chǔ)空間。因此,在函數(shù)體中對(duì)引用形參的操作實(shí)際上就是對(duì)被引用的實(shí)參變量的操作。這種向引用參數(shù)傳遞信息的方式稱為引用傳送或按址傳送。 引用傳送的好處是不需要為形參分配新的存儲(chǔ)空間,從而節(jié)省存儲(chǔ),另外能夠使對(duì)形參的操作反映到實(shí)參上,函數(shù)被調(diào)用結(jié)束返回后,能夠從實(shí)參中得到函數(shù)對(duì)它的處理結(jié)果。有時(shí),既為了使形參共享實(shí)參的存儲(chǔ)空間,又不希望通過形參改變實(shí)參的值,則應(yīng)當(dāng)把該形參說明為常量引用,如: void f13(const int& A, const

24、Node*& B, char C); 在該函數(shù)執(zhí)行時(shí),只能讀取引用形參A和B的值,不能夠修改它們的值。因?yàn)樗鼈兪菍?duì)應(yīng)實(shí)參的別名,所以,也可以說,只允許該函數(shù)使用A和B對(duì)應(yīng)實(shí)參的值,不允許進(jìn)行修改,從而杜絕了對(duì)實(shí)參進(jìn)行的有意或無意的破壞。 進(jìn)行函數(shù)調(diào)用除了要把實(shí)參傳遞給形參外,系統(tǒng)還將自動(dòng)把函數(shù)調(diào)用表達(dá)式執(zhí)行后的位置(稱為返回地址)傳遞給被調(diào)用的函數(shù),使之保存起來,當(dāng)函數(shù)執(zhí)行結(jié)束后,將按照所保存的返回地址返回到原來位置,繼續(xù)向下執(zhí)行。 函數(shù)調(diào)用的第二步是執(zhí)行函數(shù)體,實(shí)際上就是執(zhí)行函數(shù)頭后面的一條復(fù)合語句,它將按照從上向下、從左向右的次序執(zhí)行函數(shù)體中的每條語句,當(dāng)碰到return語句時(shí)就結(jié)

25、束返回。對(duì)于無類型函數(shù),當(dāng)執(zhí)行到函數(shù)體最后的右花括號(hào)時(shí),與執(zhí)行一條不帶表達(dá)式的return語句相同,也將結(jié)束返回。 函數(shù)調(diào)用的第三步是返回,這實(shí)際上是執(zhí)行一條return語句的過程。當(dāng)return語句不帶有表達(dá)式時(shí),其執(zhí)行過程為:按函數(shù)中所保存的返回地址返回到調(diào)用函數(shù)表達(dá)式的位置接著向下執(zhí)行。當(dāng)return語句帶有表達(dá)式時(shí),又分為兩種情況,一種是函數(shù)類型為非引用類型,則計(jì)算出return表達(dá)式的值,并把它保存起來,以便返回后訪問它參與相應(yīng)的運(yùn)算;另一種情況是函數(shù)的類型為引用類型,則return中的表達(dá)式必須是一個(gè)左值,并且不能是本函數(shù)中的局部變量(關(guān)于局部變量的概念留在下一節(jié)討論),執(zhí)行ret

26、urn語句時(shí)就返回這個(gè)左值,也可以說函數(shù)的返回值是該左值的一個(gè)引用。因此,返回為引用的函數(shù)調(diào)用表達(dá)式既可作為右值又可作為左值使用,但非引用類型的函數(shù)表達(dá)式只能作為右值使用。例如: int& f14(int a, int n) int k=0; for(int i=1;i<n;i+) if(ai>ak) k=i; return ak; 該函數(shù)的功能是從一維整型數(shù)組an中求出具有最大值的元素并引用返回。當(dāng)調(diào)用該函數(shù)時(shí),其函數(shù)表達(dá)式既可以作為右值,從而取出ak的值,又可以作為左值,從而向ak賦予新值。如: #include<iostream.h> int& f

27、14(int a, int n) int k=0; for(int i=1;i<n;i+) if(ai>ak) k=i; return ak; void main() int b8=25,37,18,69,54,73,62,31; cout<<f14(b,8)<<endl; f14(b,5)=86; for(int i=0;i<8;i+) cout<<bi<<' ' cout<<endl; 該程序的運(yùn)行結(jié)果如下,請(qǐng)讀者自行分析。 73 25 37 18 86 54 73 62 31 通常把函數(shù)定義為引

28、用的情況較少出現(xiàn),而定義為非引用(即普通類型和指針類型)的情況則常見。 3. 函數(shù)調(diào)用舉例 程序6-1: #include<iostream.h> int xk1(int n); void main() cout<<"輸入一個(gè)正整數(shù):" int m; cin>>m; int sum=xk1(m)+xk1(2*m+1); cout<<sum<<endl; int xk1(int n) int i,s=0; for(i=1;i<=n;i+) s+=i; return s; 該程序包含一個(gè)主函數(shù)和一個(gè)xk1函數(shù),在

29、程序開始給出了一條xk1函數(shù)的原型語句,使得xk1函數(shù)無論在什么地方定義,在此程序文件中的所有函數(shù)都能夠合法地調(diào)用它。注意:主函數(shù)不需要使用相應(yīng)的函數(shù)原型語句加以聲明,因?yàn)镃+規(guī)定不允許任何函數(shù)調(diào)用它,它只由操作系統(tǒng)調(diào)用并返回操作系統(tǒng)。 函數(shù)xk1的功能是求出自然數(shù)1至n之和,這個(gè)和就是s的最后值,由return語句把它返回。在主函數(shù)中首先為m輸入一個(gè)自然數(shù),接著用m去調(diào)用xk1函數(shù)返回1至m之間的所有自然數(shù)之和,再用2*m+1去調(diào)用xk1函數(shù)返回1至2*m+1之間的所有自然數(shù)之和,把這兩個(gè)和加起來賦給變量sum,最后輸出sum的值。 假定從鍵盤上為m輸入的正整數(shù)為5,則進(jìn)行xk1(m)調(diào)用時(shí)

30、把m的值5傳送給n,接著執(zhí)行函數(shù)體后返回s的值為15,進(jìn)行xk1(2*m+1)調(diào)用時(shí)把2*m+1的值11傳送給n,接著執(zhí)行函數(shù)體后返回s的值為66,它們的和81被作為初值賦給sum,最后輸出的sum值為81。 程序6-2: #include<iostream.h> void xk2(int& a, int b); void main() int x=12,y=18; cout<<"x="<<x<<' '<<"y="<<y<<endl; xk2(x,

31、y); cout<<"x="<<x<<' '<<"y="<<y<<endl; void xk2(int& a, int b) cout<<"a="<<a<<' '<<"b="<<b<<endl; a=a+b; b=a+b; cout<<"a="<<a<<' '&l

32、t;<"b="<<b<<endl; 該程序包含一個(gè)主函數(shù)和一個(gè)xk2函數(shù),xk2函數(shù)使用了兩個(gè)形參,一個(gè)是整型引用變量a,另一個(gè)是整型變量b。在主函數(shù)中使用xk1(x,y)調(diào)用時(shí),將使形參a成為實(shí)參x的別名,在函數(shù)體中對(duì)a的訪問就是對(duì)主函數(shù)中x的訪問,此調(diào)用同時(shí)把y的值傳送給形參b,在函數(shù)體中對(duì)形參b的操作是與對(duì)應(yīng)的實(shí)參y無關(guān)的,因?yàn)樗鼈兪褂酶髯缘拇鎯?chǔ)空間。該程序的運(yùn)行結(jié)果為: x=12 y=18 a=12 b=18 a=30 b=48 x=30 y=18 程序6-3: #include<iostream.h> void xk3(i

33、nt* a, int* b); void xk4(int& a, int& b); void main() int x=5,y=10; cout<<"x="<<x<<' '<<"y="<<y<<endl; xk3(&x, &y); cout<<"x="<<x<<' '<<"y="<<y<<endl; xk4(x

34、, y); cout<<"x="<<x<<' '<<"y="<<y<<endl; void xk3(int* a, int* b) int c=*a; *a=*b; *b=c; void xk4(int& a, int& b) int c=a; a=b; b=c; 該程序中的xk3函數(shù)用于交換a和b分別指向的兩個(gè)對(duì)象的值,主函數(shù)使用xk3(&x, &y)調(diào)用時(shí),分別把x和y的地址賦給形參a和b,所以實(shí)際交換的是主函數(shù)中x和y的值; xk

35、4函數(shù)用于直接交換a和b的值,由于a和b都是引用參數(shù),所以在主函數(shù)使用xk4(x,y)調(diào)用時(shí),執(zhí)行xk4函數(shù)實(shí)際交換的是相應(yīng)實(shí)參變量x和y的值。 此程序的運(yùn)行結(jié)果為: x=5 y=10 x=10 y=5 x=5 y=10 上述的xk3和xk4具有完全相同的功能,但由于在xk3中使用的是指針參數(shù),傳送給它的實(shí)參也必須是對(duì)象的地址,在函數(shù)體中訪問指針?biāo)赶虻膶?duì)象必須進(jìn)行間接訪問運(yùn)算,所以,定義和調(diào)用xk3不如定義和調(diào)用xk4直觀和簡(jiǎn)便。 程序6-4: #include<iostream.h> const int N=8; int xk5(int a, int n); void main

36、() int bN=1,7,2,6,4,5,3,-2; int m1=xk5(b,8); int m2=xk5(&b2,5); int m3=xk5(b+3,3); cout<<m1<<' '<<m2<<' '<<m3<<endl; int xk5(int a, int n) int i,f=1; for(i=0;i<n;i+) f*=ai; /或?qū)懗蒮*=*a+; return f; 該函數(shù)包含一個(gè)主函數(shù)和一個(gè)xk5函數(shù),xk5函數(shù)的功能是求出一維整型數(shù)組an中所有元素之積并

37、返回。在主函數(shù)中第一次調(diào)用xk5函數(shù)時(shí),把數(shù)組b的首地址傳送給a,把數(shù)組b的長(zhǎng)度8傳送給n,執(zhí)行函數(shù)體對(duì)數(shù)組a的操作實(shí)際上就是對(duì)主函數(shù)中數(shù)組b的操作,因?yàn)樗鼈兺瑫r(shí)指向數(shù)組b的存儲(chǔ)空間;第二次調(diào)用xk5函數(shù)是把數(shù)組b中b2元素的地址傳送給a,把整數(shù)5傳送給n,執(zhí)行函數(shù)體對(duì)數(shù)組an的操作實(shí)際上是對(duì)數(shù)組b中b2至b6之間元素的操作;第三次調(diào)用xk5函數(shù)是把數(shù)組b中b3元素的地址傳送給a,把整數(shù)3傳送給n,執(zhí)行函數(shù)體對(duì)數(shù)組an的操作實(shí)際上是對(duì)數(shù)組b中b3至b5之間元素的操作。該程序的運(yùn)行結(jié)果為: -10080 720 120 程序6-5: #include<iostream.H> char

38、* xk6(char* sp, char* dp); void main() char a15="abcadecaxybcw" char b15; char* c1=xk6(a,b); cout<<c1<<' '<<a<<' '<<b<<endl; char* c2=xk6(a+4,b); cout<<c1<<' '<<a<<' '<<b<<endl; char* xk

39、6(char* sp, char* dp) if(*sp='0') *dp='0' return dp; int i=0,j; for(char* p=sp; *p; p+) /掃描sp所指字符串中的每個(gè)字符位置 for(j=0;j<i;j+) if(*p=dpj) break; /當(dāng)*p與dp0至dpi-1之間的 /任一元素相同則比較過程結(jié)束 if(j>=i) dpi+=*p; /若dp數(shù)組的前i個(gè)元素均不等于*p,則把*p寫入dpi元素中 dpi='0' /寫入字符串結(jié)束符 return dp; xk6函數(shù)的功能是把sp所指向的字

40、符串,去掉重復(fù)字符后拷貝到dp所指向的字符數(shù)組中,并返回dp指針。在主函數(shù)中第一次調(diào)用xk6函數(shù)時(shí),分別以a和b作為實(shí)參,第二次調(diào)用時(shí)分別以a+4(即a4的地址)和b作為實(shí)參。該程序運(yùn)行后的輸出結(jié)果為: abcdexyw abcadecaxybcw abcdexyw decaxybw abcadecaxybcw decaxybw 程序6-6: #include<iostream.H> int* xk7(int*& a1, int* a2); int* xk7(int*& a1, int* a2) cout<<"when enter xk7: *

41、a1,*a2="<<*a1<<", "<<*a2<<endl; a1=new int(2*a1+4); a2=new int(2*a2-1); cout<<"when leave xk7: *a1,*a2="<<*a1<<", "<<*a2<<endl; return a2; void main() int x=10, y=25; int *xp=&x, *yp=&y; cout<<&quo

42、t;before call xk7: *xp,*yp="<<*xp<<", "<<*yp<<endl; int* ip=xk7(xp,yp); cout<<"after call xk7: *xp,*yp="<<*xp<<", "<<*yp<<endl; cout<<"*ip="<<*ip<<endl; delete xp; /xp指向的是在執(zhí)行xk7函數(shù)時(shí)動(dòng)態(tài)分

43、配的對(duì)象*a1 delete ip; /ip指向的是在執(zhí)行xk7函數(shù)時(shí)動(dòng)態(tài)分配的對(duì)象*a2 在xk7函數(shù)的定義中,把形參a1定義為整型指針的引用,把a(bǔ)2定義為整型指針,當(dāng)在主函數(shù)中利用xk7(xp,yp)表達(dá)式調(diào)用該函數(shù)時(shí),a1就成為xp的別名,訪問a1就等于訪問主函數(shù)中的xp,而a2同yp具有各自獨(dú)立的存儲(chǔ)空間,a2的初值為yp的值,在xk7函數(shù)中對(duì)a2的訪問(指直接訪問)與yp無關(guān)。此程序運(yùn)行結(jié)果為: before call xk7: *xp,*yp=10, 25 when enter xk7: *a1,*a2=10, 25 when leave xk7: *a1,*a2=24, 49 a

44、fter call xk7: *xp,*yp=24, 25 *ip=49 三、變量的作用域 在一個(gè)C+程序中,對(duì)于每個(gè)變量必須遵循先定義后使用的原則。根據(jù)變量定義的位置不同將使它具有不同的作用域。一個(gè)變量離開了它的作用域,在定義時(shí)為它分配的存儲(chǔ)空間就被系統(tǒng)自動(dòng)回收了,因此該變量也就不存在了。 1作用域分類 變量的作用域具有四種類別:全局作用域、文件作用域、函數(shù)作用域和塊作用域。具有全局作用域的變量稱為全局變量,具有塊作用域的變量稱為局部變量。 (1) 全局作用域 當(dāng)一個(gè)變量在一個(gè)程序文件的所有函數(shù)定義之外(并且通常在所有函數(shù)定義之前)定義時(shí),則該變量具有全局作用域,即該變量在整個(gè)程序包括的所有

45、文件中都有效,都是可見的,都是可以訪問的。當(dāng)一個(gè)全局變量不是在本程序文件中定義時(shí),若要在本程序文件中使用,則必須在本文件開始進(jìn)行聲明,聲明格式為: extern <類型名> <變量名>, <變量名>,.; 它與變量定義語句格式類似,其區(qū)別是:不能對(duì)變量進(jìn)行初始化,并且要在整個(gè)語句前加上extern保留字。 當(dāng)用戶定義一個(gè)全局變量時(shí),若沒有對(duì)其初始化,則編譯時(shí)會(huì)自動(dòng)把它初始化為0。 (2) 文件作用域 當(dāng)一個(gè)變量定義語句出現(xiàn)在一個(gè)程序文件中的所有函數(shù)定義之外,并且該語句前帶有static保留字時(shí),則該語句定義的所有變量都具有文件作用域,即在整個(gè)程序文件中有效,

46、但在其他文件中是無效的,不可見的。 若在定義文件作用域變量時(shí)沒有初始化,則編譯時(shí)會(huì)自動(dòng)把它初始化為0。 (3) 函數(shù)作用域 在每個(gè)函數(shù)中使用的語句標(biāo)號(hào)具有函數(shù)作用域,即它在本函數(shù)中有效,供本函數(shù)中的goto語句跳轉(zhuǎn)使用。由于語句標(biāo)號(hào)不是變量,應(yīng)該說函數(shù)作用域不屬于變量的一種作用域。 (4) 塊作用域 當(dāng)一個(gè)變量是在一個(gè)函數(shù)體內(nèi)定義時(shí),則稱它具有塊作用域,其作用域范圍是從定義點(diǎn)開始,直到該塊結(jié)束(即所在復(fù)合語句的右花括號(hào))為止。 具有塊作用域的變量稱為局部變量,若局部變量沒有被初始化,則系統(tǒng)也不會(huì)對(duì)它初始化,它的初值是不確定的。對(duì)于在函數(shù)體中使用的變量定義語句,若在其前面加上static保留字,

47、則稱所定義的變量為靜態(tài)局部變量,若靜態(tài)局部變量沒有被初始化,則編譯時(shí)會(huì)被自動(dòng)初始化為0。 對(duì)于非靜態(tài)局部變量,每次執(zhí)行到它的定義語句時(shí),都會(huì)為它分配對(duì)應(yīng)的存儲(chǔ)空間,并對(duì)帶初值表達(dá)式的變量進(jìn)行初始化;而對(duì)于靜態(tài)局部變量,只是在整個(gè)程序執(zhí)行過程中第一次執(zhí)行到它的定義語句時(shí)為其分配對(duì)應(yīng)的存儲(chǔ)空間,并進(jìn)行初始化,以后再執(zhí)行到它時(shí)什么都不會(huì)做,相當(dāng)于第一次執(zhí)行后就刪除了該語句。 任一函數(shù)定義中的每個(gè)形參也具有塊作用域,這個(gè)塊是作為函數(shù)體的復(fù)合語句,當(dāng)離開函數(shù)體后它就不存在了,函數(shù)調(diào)用時(shí)為它分配的存儲(chǔ)空間也就被系統(tǒng)自動(dòng)回收了,當(dāng)然引用參數(shù)對(duì)應(yīng)的存儲(chǔ)空間不會(huì)被回收。由于每個(gè)形參具有塊作用域,所以它也是局部變

48、量。 在C+程序中定義的符號(hào)常量也同變量一樣具有全局、文件和局部這三種作用域。當(dāng)符號(hào)常量定義語句出現(xiàn)在所有函數(shù)定義之外,并且在前面帶有extern保留字時(shí),則所定義的常量具有全局作用域,若在前面帶有static關(guān)鍵字或什么都沒有,則所定義的常量具有文件作用域。若符號(hào)常量定義語句出現(xiàn)在一個(gè)函數(shù)體內(nèi),則定義的符號(hào)常量具有局部作用域。 一個(gè)C+程序中的所有函數(shù)的函數(shù)名都具有全局作用域,所以在程序中所含的任何文件內(nèi)都可以使用任一函數(shù)名構(gòu)成函數(shù)調(diào)用表達(dá)式,執(zhí)行對(duì)應(yīng)的函數(shù)。 具有同一作用域的任何標(biāo)識(shí)符,不管它表示什么對(duì)象(如常量、變量、函數(shù)、類型等)都不允許重名,若重名系統(tǒng)就無法唯一確定它的含義了。 由于

49、每一個(gè)復(fù)合語句就是一個(gè)塊,所以在不同復(fù)合語句中定義的對(duì)象具有不同的塊作用域,也稱為具有不同的作用域,其對(duì)象名允許重名,因?yàn)橄到y(tǒng)能夠區(qū)分它們。 2. 程序舉例 程序6-7: 程序主文件6-7.cpp #include<iostream.h> int xk8(int n); /函數(shù)xk8的原型聲明 int xk9(int n); /函數(shù)xk9的原型聲明 int AA=5; /定義全局變量AA extern const int BB=8; /定義全局常量BB static int CC=12; /定義文件域變量CC const int DD=23; /定義文件域常量DD void mai

50、n() int x=15; /x的作用域?yàn)橹骱瘮?shù)體 cout<<"x*x="<<xk8(x)<<endl; cout<<"mainFile: AA,BB="<<AA<<','<<BB<<endl; cout<<"mainFile: CC,DD="<<CC<<','<<DD<<endl; cout<<xk9(16)<<endl;

51、 int xk9(int n) /n的作用域?yàn)閤k9函數(shù)體 int x=10; /x的作用域?yàn)閤k9函數(shù)體 cout<<"xk9:x="<<x<<endl; return n*x; 程序次文件6-7-1.cpp #include<iostream.h> int xk8(int n); /函數(shù)xk8的原型聲明 extern int AA; /全局變量AA的聲明 extern const int BB; /全局常量BB的聲明 static int CC=120; /定義文件域變量CC const int DD=230; /定義文件

52、域常量DD int xk8(int n) /n的作用域?yàn)閤k8函數(shù)體 cout<<"attachFile: AA,BB="<<AA<<','<<BB<<endl; cout<<"attachFile: CC,DD="<<CC<<','<<DD<<endl; return n*n; 此程序包含兩個(gè)程序文件,定義有各種類型的變量和常量,其中AA為全局變量,BB為全局常量,CC為各自的文件域變量,DD為各自的文

53、件域常量,主函數(shù)中的x為作用于主函數(shù)的局部變量,xk9函數(shù)中的x為作用于該函數(shù)的局部變量,xk8和xk9函數(shù)的各自參數(shù)表中的形參n是作用于各自函數(shù)的局部變量。為了在程序次文件6-7-1.cpp中能夠使用程序主文件6-7.cpp中定義的全局變量AA和全局常量BB,必須在該文件開始對(duì)他們進(jìn)行聲明。 當(dāng)上機(jī)輸入和運(yùn)行該程序時(shí),可以先建立程序主文件d6-7.cpp并編譯通過,再建立程序次文件d6-7-1.cpp并編譯通過,然后把它們連接起來生成可執(zhí)行文件d6-7.exe。該程序的運(yùn)行結(jié)果為: attachFile: AA,BB=5,8 attachFile: CC,DD=120,230 x*x=225 mainFile: AA,BB=5,8 mainFile: CC,DD=12,23 xk9:x=10 160 請(qǐng)讀者結(jié)合上述程序分析結(jié)果的正確性。 程序6-8: #i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論