




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第2章 函數(shù)的定義 當設計較大程序時,通常需要用若干個模塊來實當設計較大程序時,通常需要用若干個模塊來實現(xiàn)較復雜的功能,而每一個模塊自成結(jié)構(gòu),用來解決現(xiàn)較復雜的功能,而每一個模塊自成結(jié)構(gòu),用來解決一些子問題。一些子問題。這種能完成某一獨立功能的子程序模塊,這種能完成某一獨立功能的子程序模塊,在在C+C+中成為函數(shù)。中成為函數(shù)。 可見,可見,函數(shù)是實現(xiàn)模塊化程序的基本單位。函數(shù)是實現(xiàn)模塊化程序的基本單位。 事實上,函數(shù)還能體現(xiàn)代碼重用的思想,因為一事實上,函數(shù)還能體現(xiàn)代碼重用的思想,因為一個函數(shù)可以在同一個程序中被多次調(diào)用或在多個程序個函數(shù)可以在同一個程序中被多次調(diào)用或在多個程序中被調(diào)用。中被調(diào)
2、用。第第2章章 函數(shù)和作用域函數(shù)和作用域2.1函數(shù)定義和調(diào)用函數(shù)定義和調(diào)用2.2C+函數(shù)特性函數(shù)特性2.3作用域和存儲類型作用域和存儲類型2.4名稱空間名稱空間2.1 函數(shù)定義和調(diào)用函數(shù)定義和調(diào)用2.1.1函數(shù)定義函數(shù)定義C+C+的任何一個程序都可由的任何一個程序都可由一個主函數(shù)一個主函數(shù)和和若干個子函數(shù)若干個子函數(shù)組合而成。主組合而成。主函數(shù)可以調(diào)用子函數(shù),子函數(shù)還可以調(diào)用其他子函數(shù)。函數(shù)可以調(diào)用子函數(shù),子函數(shù)還可以調(diào)用其他子函數(shù)。C+C+規(guī)定主函數(shù)名規(guī)定主函數(shù)名必須是必須是mainmain,而其他函數(shù)可以是,而其他函數(shù)可以是庫函數(shù)庫函數(shù)或或自定義函數(shù)自定義函數(shù)。(1 1)主函數(shù))主函數(shù)ma
3、inmain不僅是程序的入口函數(shù),而且與其他函數(shù)相比較還不僅是程序的入口函數(shù),而且與其他函數(shù)相比較還有許多使用上的限制。例如,它不能被其他函數(shù)調(diào)用,不能用有許多使用上的限制。例如,它不能被其他函數(shù)調(diào)用,不能用inlineinline和和staticstatic來說明等。來說明等。(2 2)庫函數(shù),)庫函數(shù),又稱標準函數(shù),是又稱標準函數(shù),是ANSI/ISO C+ANSI/ISO C+編譯系統(tǒng)已經(jīng)預先定編譯系統(tǒng)已經(jīng)預先定義好的函數(shù),程序設計時可根據(jù)實際需要,直接使用這類函數(shù),而不必義好的函數(shù),程序設計時可根據(jù)實際需要,直接使用這類函數(shù),而不必重新定義。調(diào)用時,必須在程序中包含相應的頭文件,并指明使
4、用名稱重新定義。調(diào)用時,必須在程序中包含相應的頭文件,并指明使用名稱空間空間stdstd。2.1 函數(shù)定義和調(diào)用函數(shù)定義和調(diào)用 (3)自定義函數(shù)自定義函數(shù)是用戶根據(jù)程序的需要,是用戶根據(jù)程序的需要,將某一個功能相將某一個功能相對獨立的程序定義成的一個函數(shù),或?qū)⒔鉀Q某個問題的算法用一對獨立的程序定義成的一個函數(shù),或?qū)⒔鉀Q某個問題的算法用一個函數(shù)來組織。個函數(shù)來組織。 與變量的使用規(guī)則相同,在與變量的使用規(guī)則相同,在C+程序中一定要先說明和定義程序中一定要先說明和定義函數(shù),然后才能調(diào)用函數(shù)。函數(shù),然后才能調(diào)用函數(shù)。 C+中每一個函數(shù)的定義都是由中每一個函數(shù)的定義都是由4個個部分組成的,即部分組成的
5、,即函數(shù)名、函數(shù)類型、形式參數(shù)表和函數(shù)體,函數(shù)名、函數(shù)類型、形式參數(shù)表和函數(shù)體,其定其定義的格式如下:義的格式如下: ( ) 函函數(shù)數(shù)體體2.1.1 函數(shù)定義函數(shù)定義其中,函數(shù)名應是一個合法有效的其中,函數(shù)名應是一個合法有效的C+C+標識符;函數(shù)頭的形式參數(shù)標識符;函數(shù)頭的形式參數(shù)又簡稱為形參。又簡稱為形參。 參數(shù)表中的每一個形參都是由形參的數(shù)據(jù)類型和形參名來構(gòu)成,參數(shù)表中的每一個形參都是由形參的數(shù)據(jù)類型和形參名來構(gòu)成,根據(jù)上述定義格式,可以編寫一個函數(shù)根據(jù)上述定義格式,可以編寫一個函數(shù)sumsum,如圖,如圖2.12.1所示,注意它所示,注意它們的書寫規(guī)范。們的書寫規(guī)范。int sum(in
6、t x, int y)int z = x + y;return z;對齊函數(shù)頭函數(shù)體縮進函數(shù)類型函數(shù)名形參圖圖2.1 定義一個函數(shù)定義一個函數(shù)sum2.1.1 函數(shù)定義函數(shù)定義需要說明的是:需要說明的是:(1)(1) C/C+ C/C+不允許在一個函數(shù)體中再定義函數(shù),不允許在一個函數(shù)體中再定義函數(shù),即禁止嵌套定義,但即禁止嵌套定義,但允許嵌套調(diào)用。允許嵌套調(diào)用。(2)(2) 函數(shù)體也可不含有任何語句,這樣的函數(shù)稱為函數(shù)體也可不含有任何語句,這樣的函數(shù)稱為空函數(shù),它僅為空函數(shù),它僅為程序結(jié)構(gòu)而設定,本身沒有任何操作。程序結(jié)構(gòu)而設定,本身沒有任何操作。(3)(3) 函數(shù)類型決定了函數(shù)所需要的返回值
7、類型,它可以是除數(shù)組類函數(shù)類型決定了函數(shù)所需要的返回值類型,它可以是除數(shù)組類型之外的任何有效的型之外的任何有效的C+C+數(shù)據(jù)類型,包括引用、指針等。數(shù)據(jù)類型,包括引用、指針等。2.1.1 函數(shù)定義函數(shù)定義(4) (4) 若函數(shù)類型為若函數(shù)類型為voidvoid時時,則表示該函數(shù)沒有返回值。則表示該函數(shù)沒有返回值。但仍然可以在但仍然可以在函數(shù)體中使用函數(shù)體中使用returnreturn語句語句“returnreturn ;”;”,此時可將,此時可將“return;”return;”語語句理解為是函數(shù)體花括號句理解為是函數(shù)體花括號“”“”的作用,當流程遇到函數(shù)體的的作用,當流程遇到函數(shù)體的“”“”
8、時,函數(shù)調(diào)用結(jié)束,控制權(quán)返回給主調(diào)函數(shù)。例如:時,函數(shù)調(diào)用結(jié)束,控制權(quán)返回給主調(diào)函數(shù)。例如:void f1( int a)if (a 10) return; / return;一旦執(zhí)行,后面的語句不再一旦執(zhí)行,后面的語句不再 被執(zhí)行被執(zhí)行當當a10條件滿足時,條件滿足時,“return;”語句將控制權(quán)返回給主調(diào)函數(shù)。語句將控制權(quán)返回給主調(diào)函數(shù)。2.1.2 函數(shù)的調(diào)用和聲明函數(shù)的調(diào)用和聲明1. 1. 函數(shù)的實參和形參函數(shù)的實參和形參定義一個函數(shù)就是為了以后的調(diào)用。調(diào)用函數(shù)時,先寫函數(shù)名,然定義一個函數(shù)就是為了以后的調(diào)用。調(diào)用函數(shù)時,先寫函數(shù)名,然后緊跟括號,括號里是后緊跟括號,括號里是實際調(diào)用該
9、函數(shù)時所給定的參數(shù),稱為實際參數(shù),實際調(diào)用該函數(shù)時所給定的參數(shù),稱為實際參數(shù),簡稱實參,簡稱實參,并與形參相對應。要注意形參和實參的區(qū)別:并與形參相對應。要注意形參和實參的區(qū)別:(1) (1) 從模塊概念來說,從模塊概念來說,形參是函數(shù)的接口,是存在于函數(shù)內(nèi)部的變形參是函數(shù)的接口,是存在于函數(shù)內(nèi)部的變量。而實參是存在于函數(shù)外部的變量。量。而實參是存在于函數(shù)外部的變量。它們不是同一個實體,也就是說,它們不是同一個實體,也就是說,形參變量和實參變量所對應的內(nèi)存空間不是同一個內(nèi)存空間。形參變量和實參變量所對應的內(nèi)存空間不是同一個內(nèi)存空間。(2) (2) 按函數(shù)定義時所指定的形參類型,實參除變量外還可
10、以是數(shù)值按函數(shù)定義時所指定的形參類型,實參除變量外還可以是數(shù)值或表達式等,而形參只能是變量?;虮磉_式等,而形參只能是變量。(3) (3) 形參在函數(shù)調(diào)用之前是不存在的,只有在發(fā)生函數(shù)調(diào)用時,函形參在函數(shù)調(diào)用之前是不存在的,只有在發(fā)生函數(shù)調(diào)用時,函數(shù)中的形參才會被分配內(nèi)存空間,然后執(zhí)行函數(shù)體中的語句,而當調(diào)用數(shù)中的形參才會被分配內(nèi)存空間,然后執(zhí)行函數(shù)體中的語句,而當調(diào)用結(jié)束后,形參所占的內(nèi)存空間又會被釋放。結(jié)束后,形參所占的內(nèi)存空間又會被釋放。2.1.2 函數(shù)的調(diào)用和聲明函數(shù)的調(diào)用和聲明2. 2. 函數(shù)的調(diào)用函數(shù)的調(diào)用 函數(shù)調(diào)用的一般格式為:函數(shù)調(diào)用的一般格式為: ( ( ) ); 調(diào)用函數(shù)時要
11、注意:調(diào)用函數(shù)時要注意:實參與形參的個數(shù)應相等,實參與形參的個數(shù)應相等,類型應一致,且按順序?qū)?,一一傳遞數(shù)據(jù)。類型應一致,且按順序?qū)?,一一傳遞數(shù)據(jù)。 例如,下面的示例用來輸出一個三角形的圖案。例如,下面的示例用來輸出一個三角形的圖案。2.1.2 函數(shù)的調(diào)用和聲明函數(shù)的調(diào)用和聲明 例例Ex_Call 函數(shù)的調(diào)用函數(shù)的調(diào)用#include using namespace std;void printline( char ch, int n )for (int i = 0 ; in ; i+)coutch;coutendl ;int main()int row = 5;for (int i =
12、0; irow; i+)printline(*, i+1);/ Areturn 0; 2.1.2 函數(shù)的調(diào)用和聲明函數(shù)的調(diào)用和聲明 程序運行的結(jié)果如下:程序運行的結(jié)果如下: 代碼中,代碼中,main函數(shù)的函數(shù)的for循環(huán)語句共調(diào)用了循環(huán)語句共調(diào)用了5次次printline函數(shù)函數(shù)(A句句),每次調(diào)用時因?qū)崊?,每次調(diào)用時因?qū)崊+1值不斷改變,從而使函數(shù)值不斷改變,從而使函數(shù)printline打印打印出來的星號個數(shù)也隨之改變出來的星號個數(shù)也隨之改變。 2.1.2 函數(shù)的調(diào)用和聲明函數(shù)的調(diào)用和聲明3. 3. 函數(shù)的聲明函數(shù)的聲明 由于前面函數(shù)由于前面函數(shù)printline的定義代碼是放在的定義代碼
13、是放在main函函數(shù)中調(diào)用語句數(shù)中調(diào)用語句A之前,因而之前,因而A語句執(zhí)行不會有問題。語句執(zhí)行不會有問題。 但若將函數(shù)但若將函數(shù)printline的定義代碼放在調(diào)用語句的定義代碼放在調(diào)用語句A之之后,即后,即函數(shù)定義在后,而調(diào)用在前函數(shù)定義在后,而調(diào)用在前,就會產(chǎn)生,就會產(chǎn)生“printline標識符未定義標識符未定義”的編譯錯誤。的編譯錯誤。 此時此時必須在調(diào)用前進行函數(shù)聲明必須在調(diào)用前進行函數(shù)聲明。2.1.2 函數(shù)的聲明函數(shù)的聲明聲明一個函數(shù)按下列格式進行:聲明一個函數(shù)按下列格式進行: ( );可見,可見,函數(shù)聲明的格式是在函數(shù)頭的后面加上分號函數(shù)聲明的格式是在函數(shù)頭的后面加上分號“;”。
14、但要注意,函數(shù)聲明的內(nèi)容應和函數(shù)的定義應相但要注意,函數(shù)聲明的內(nèi)容應和函數(shù)的定義應相同。同。例如,對于前面例如,對于前面sum函數(shù)和最后一個函數(shù)和最后一個printline函數(shù)可有函數(shù)可有如下聲明:如下聲明:int sum(int x, int y);void printline( char ch, int n );2.1.3 值傳遞值傳遞 函數(shù)的調(diào)用實質(zhì)上就是參數(shù)傳遞,函數(shù)的調(diào)用實質(zhì)上就是參數(shù)傳遞, 在在C+中,函數(shù)的參數(shù)傳遞有兩種方式,中,函數(shù)的參數(shù)傳遞有兩種方式,一是按值傳遞,一是按值傳遞,二是地址傳遞或引用傳遞。二是地址傳遞或引用傳遞。 這里先來說明按值傳遞的參數(shù)傳遞方法,地址傳遞或引
15、這里先來說明按值傳遞的參數(shù)傳遞方法,地址傳遞或引用傳遞在以后來討論。用傳遞在以后來討論。 當函數(shù)的形參定義成一般變量時,如前面當函數(shù)的形參定義成一般變量時,如前面printline和和sum函數(shù)的形參都是一般變量,此時函數(shù)的參數(shù)傳遞就是按函數(shù)的形參都是一般變量,此時函數(shù)的參數(shù)傳遞就是按值傳遞方式,簡稱值傳遞方式,簡稱值傳遞值傳遞,是指當一個函數(shù)被調(diào)用時,是指當一個函數(shù)被調(diào)用時,C+根據(jù)實參和形參的對應關(guān)系將實際參數(shù)的值一一傳遞給形參,根據(jù)實參和形參的對應關(guān)系將實際參數(shù)的值一一傳遞給形參,供函數(shù)執(zhí)行時使用。供函數(shù)執(zhí)行時使用。2.1.3 值傳遞值傳遞值傳遞的特點是:值傳遞的特點是:n(1) 若實參
16、指定是若實參指定是一般變量一般變量,則傳遞的是,則傳遞的是實參變量的值實參變量的值而不是實參變量的地址。而不是實參變量的地址。n(2) 在執(zhí)行函數(shù)代碼時,由于對實參數(shù)據(jù)的操作最終是在執(zhí)行函數(shù)代碼時,由于對實參數(shù)據(jù)的操作最終是在形參的內(nèi)存空間中進行,因此形參值的改變只是改在形參的內(nèi)存空間中進行,因此形參值的改變只是改變了形參的內(nèi)存空間存儲的值,而不會改變實參變量變了形參的內(nèi)存空間存儲的值,而不會改變實參變量所對應的內(nèi)存空間的值。所對應的內(nèi)存空間的值。 也就是說,也就是說,即使形參的值在函數(shù)中發(fā)生了變化,函即使形參的值在函數(shù)中發(fā)生了變化,函數(shù)調(diào)用結(jié)束后,實參的值不會受到影響。數(shù)調(diào)用結(jié)束后,實參的值
17、不會受到影響。例如:例如:2.1.3 值傳遞值傳遞例例Ex_SwapValue 交換函數(shù)兩個參數(shù)的值。交換函數(shù)兩個參數(shù)的值。#include using namespace std;void swap(float x, float y);/ 函數(shù)原型說明函數(shù)原型說明int main()float a = 20, b = 40;couta = a, b = bn;swap(a, b);/ 函數(shù)調(diào)用函數(shù)調(diào)用couta = a, b = bn;return 0;void swap(float x, float y)/ 函數(shù)定義函數(shù)定義float temp;temp = x; x = y; y = t
18、emp;coutx = x, y = yn;2.1.3 值傳遞值傳遞程序的運行結(jié)果為:程序的運行結(jié)果為: 可以看出,雖然函數(shù)swap中交換了兩個形參x和y的值,但交換的結(jié)果并不能改變實參的值,所以調(diào)用該函數(shù)后,變量a和b的值仍然為原來的值。2.1.4 函數(shù)的默認形參值函數(shù)的默認形參值在在C+中,中,允許在函數(shù)的聲明或定義時給一個或多個參允許在函數(shù)的聲明或定義時給一個或多個參數(shù)指定默認值。數(shù)指定默認值。這樣在調(diào)用時,可以不給出實際參數(shù),而這樣在調(diào)用時,可以不給出實際參數(shù),而按指定的默認值進行工作。按指定的默認值進行工作。例如:例如:void delay(int loops = 1000) / 函
19、數(shù)定義,函數(shù)定義,1000為形為形 參參loops的默認值的默認值if ( 0 = loops) return;for (int i=0; iloops; i+); / 空循環(huán),起延時作用空循環(huán),起延時作用2.1.4 函數(shù)的默認形參值函數(shù)的默認形參值這樣,當有調(diào)用這樣,當有調(diào)用 delay();/ 和和delay(1000)等效等效 程序就會自動將程序就會自動將loops當作成當作成1000的默認值來進行處理。的默認值來進行處理。當然,也可在當然,也可在函數(shù)調(diào)用時指定相應的實際的參數(shù)值函數(shù)調(diào)用時指定相應的實際的參數(shù)值,例如:例如:delay(2000);/ 形參形參loops的值為的值為200
20、02.1.4 函數(shù)的默認形參值函數(shù)的默認形參值在設置函數(shù)的默認形參值時要注意:在設置函數(shù)的默認形參值時要注意:(1) 當函數(shù)既有原型聲明又有定義時當函數(shù)既有原型聲明又有定義時,默認參數(shù)只能在原型聲明中指,默認參數(shù)只能在原型聲明中指定,而不能在函數(shù)定義中指定。定,而不能在函數(shù)定義中指定。例如:例如:void delay(int loops); / 函數(shù)原型聲明函數(shù)原型聲明/ void delay(int loops = 1000) / 錯誤:此時不能函數(shù)定義中指定默錯誤:此時不能函數(shù)定義中指定默認參數(shù)認參數(shù)/ 2.1.4 函數(shù)的默認形參值函數(shù)的默認形參值(2) 當一個函數(shù)中需要有多個默認參數(shù)時,
21、當一個函數(shù)中需要有多個默認參數(shù)時,則形參分布中,默認參數(shù)應則形參分布中,默認參數(shù)應嚴格從右到左逐次定義和指定,中間不能跳開嚴格從右到左逐次定義和指定,中間不能跳開。例如:例如:void display(int a, int b, int c = 3);/ 合法合法void display(int a, int b = 2, int c = 3); / 合法合法void display(int a = 1, int b = 2, int c = 3); / 合法:可以對所有的參合法:可以對所有的參數(shù)設置默認值數(shù)設置默認值void display(int a, int b = 2, int c);
22、 / 錯誤:默認參數(shù)應從最錯誤:默認參數(shù)應從最右邊開始右邊開始void display(int a = 1, int b = 2, int c);/ 錯誤:默認參數(shù)應從最錯誤:默認參數(shù)應從最右邊開始右邊開始void display(int a = 1, int b, int c = 3); / 錯誤:多個默認參數(shù)錯誤:多個默認參數(shù)中間不能有非默認參數(shù)中間不能有非默認參數(shù)2.1.4 函數(shù)的默認形參值函數(shù)的默認形參值n(3) (3) 當帶有默認參數(shù)的函數(shù)調(diào)用時,當帶有默認參數(shù)的函數(shù)調(diào)用時,系統(tǒng)按從左到右系統(tǒng)按從左到右的順序?qū)崊⑴c形參結(jié)合。的順序?qū)崊⑴c形參結(jié)合。 當實參的數(shù)目不足時,系統(tǒng)將按同樣
23、的順序用聲當實參的數(shù)目不足時,系統(tǒng)將按同樣的順序用聲明或定義中的默認值來補齊所缺少的參數(shù)。明或定義中的默認值來補齊所缺少的參數(shù)。 例如:例如:2.1.4 函數(shù)的默認形參值函數(shù)的默認形參值例例Ex_Default 在函數(shù)定義中設置多個默認參數(shù)在函數(shù)定義中設置多個默認參數(shù)#include using namespace std;void display(int a, int b = 2, int c = 3) / 在函數(shù)定義中設置默認在函數(shù)定義中設置默認參數(shù)參數(shù)couta = a, b = b, c = cn;int main()display(1);display(1, 5);display(1
24、, 7, 9);return 0;程序的運行結(jié)果為:程序的運行結(jié)果為:2.2 C+函數(shù)特性函數(shù)特性 在在C+C+中,函數(shù)還有:中,函數(shù)還有:嵌套調(diào)用、重載、內(nèi)聯(lián)調(diào)用嵌套調(diào)用、重載、內(nèi)聯(lián)調(diào)用以及遞歸調(diào)用以及遞歸調(diào)用等特性,相應的函數(shù)被稱為嵌套函數(shù)、等特性,相應的函數(shù)被稱為嵌套函數(shù)、重載函數(shù)、內(nèi)聯(lián)函數(shù)和遞歸調(diào)用等。重載函數(shù)、內(nèi)聯(lián)函數(shù)和遞歸調(diào)用等。2.2 C+函數(shù)特性函數(shù)特性 函數(shù)重載(函數(shù)重載(overloaded)是是C+對對C的擴展,它允許多的擴展,它允許多個同名的函數(shù)存在,但同名的各個函數(shù)的形參必須有區(qū)別:個同名的函數(shù)存在,但同名的各個函數(shù)的形參必須有區(qū)別:要么形參的個數(shù)不同;要么形參的個數(shù)
25、相同,但參數(shù)類型要么形參的個數(shù)不同;要么形參的個數(shù)相同,但參數(shù)類型有所不同有所不同。 優(yōu)點:代碼中使用函數(shù)的重載,不僅方便函數(shù)名的記優(yōu)點:代碼中使用函數(shù)的重載,不僅方便函數(shù)名的記憶,而且更主要的是完善了同一個函數(shù)的代碼功能,給調(diào)憶,而且更主要的是完善了同一個函數(shù)的代碼功能,給調(diào)用帶來了許多方便。用帶來了許多方便。下例程序中即是各種形式的下例程序中即是各種形式的sum函數(shù)都稱為函數(shù)都稱為sum的重載的重載函數(shù)。函數(shù)。 2.2 C+函數(shù)特性函數(shù)特性【例【例Ex_OverLoad】 編程求兩個或三編程求兩個或三個操作數(shù)之和個操作數(shù)之和 #include int sum(int x, int y);
26、int sum(int x, int y, int z); double sum(double x, double y); double sum(double x, double y, double z); /聲明聲明4個同名的函數(shù)個同名的函數(shù) int main() coutsum(2, 5)endl; / 結(jié)果為結(jié)果為7 coutsum(2, 5, 7)endl; / 結(jié)果為結(jié)果為14 coutsum(1.2, 5.0, 7.5)0當時當時2.2.3 遞歸函數(shù)遞歸函數(shù)例例Ex_Factorial 編程求編程求n的階乘的階乘n! #include using namespace std; lo
27、ng factorial(int n); int main() coutfactorial(4)endl; / 結(jié)果為結(jié)果為24 return 0; long factorial(int n) long result = 0; if (0 = n) result = 1; else result = n*factorial(n-1); / 進行自身調(diào)用進行自身調(diào)用 return result; 1.5.4 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用程序運行結(jié)果如下:程序運行結(jié)果如下:24下面來分析下面來分析main函數(shù)中函數(shù)中“factorial(4);”語句的執(zhí)行過程,這一過程用語句的執(zhí)行過程,這一過程用
28、 圖圖1.8來表示:見書(來表示:見書(p36)2.2.4 內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù) 在程序的執(zhí)行過程中,調(diào)用函數(shù)時首先需要保存主調(diào)函數(shù)的現(xiàn)場和返回地址,然后程序轉(zhuǎn)移到被調(diào)函數(shù)的起始地址繼續(xù)執(zhí)行。被調(diào)函數(shù)執(zhí)行結(jié)束后,先恢復主調(diào)函數(shù)的現(xiàn)場,取出返回地址,并將返回值賦給函數(shù)調(diào)用本身,最后在返回地址處開始繼續(xù)執(zhí)行。當函數(shù)體比較小且執(zhí)行的功能比較簡單時,這種函數(shù)調(diào)用方式的系統(tǒng)開銷相對較大。 2.2.4 內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù) 為了解決這一問題,C+引入了內(nèi)聯(lián)函數(shù)的概念,它把函數(shù)體的代碼直接插入到調(diào)用處,將調(diào)用函數(shù)的方式改為順序執(zhí)行、直接插入的程序代碼,這樣可以減少程序的執(zhí)行時間,但同時增加了代碼的實際長度。 內(nèi)聯(lián)函
29、數(shù)的使用方法與一般函數(shù)相同,只是在內(nèi)聯(lián)函數(shù)定義時,需在函數(shù)的類型前面加上inline關(guān)鍵字關(guān)鍵字。例如:2.2.4 內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)例例Ex_Inline 用內(nèi)聯(lián)函數(shù)實現(xiàn)求兩個實數(shù)的最大值用內(nèi)聯(lián)函數(shù)實現(xiàn)求兩個實數(shù)的最大值 #include using namespace std; inline float fmax(float x, float y) return xy?x:y; int main() float a; a = fmax(5, 10); / A cout最大的數(shù)為:最大的數(shù)為:a10 ? 5 : 10;2.2.4 內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)在使用內(nèi)聯(lián)函數(shù)時,還需要注意的是:在使用內(nèi)聯(lián)函數(shù)
30、時,還需要注意的是:(1) 內(nèi)聯(lián)函數(shù)也要遵循定義在前,調(diào)用在后的原則。形參與實參之間內(nèi)聯(lián)函數(shù)也要遵循定義在前,調(diào)用在后的原則。形參與實參之間的關(guān)系與一般函數(shù)相同。的關(guān)系與一般函數(shù)相同。(2) 關(guān)鍵字關(guān)鍵字inline必須放在函數(shù)定義體前才是內(nèi)聯(lián)函數(shù),僅在函數(shù)聲必須放在函數(shù)定義體前才是內(nèi)聯(lián)函數(shù),僅在函數(shù)聲明時使用明時使用inline,不能定義內(nèi)聯(lián)函數(shù)。,不能定義內(nèi)聯(lián)函數(shù)。(3) 在在C+中,需要定義成的內(nèi)聯(lián)函數(shù)不能含有循環(huán)、中,需要定義成的內(nèi)聯(lián)函數(shù)不能含有循環(huán)、switch和復雜和復雜嵌套的嵌套的if語句。語句。(4) 遞歸函數(shù)不能被用來做內(nèi)聯(lián)函數(shù)。遞歸函數(shù)不能被用來做內(nèi)聯(lián)函數(shù)。 總之,內(nèi)聯(lián)函數(shù)
31、一般是比較小的、經(jīng)常被調(diào)用的、大多可在一總之,內(nèi)聯(lián)函數(shù)一般是比較小的、經(jīng)常被調(diào)用的、大多可在一行寫完的函數(shù)。行寫完的函數(shù)。2.3 作用域和存儲類型作用域和存儲類型2.3.1作用域作用域 作用域又稱作用范圍,是指程序中標識符作用域又稱作用范圍,是指程序中標識符(變量名、函數(shù)名、數(shù)組變量名、函數(shù)名、數(shù)組名、類名、對象名等名、類名、對象名等)的有效范圍。的有效范圍。一個標識符是否可以被引用,稱之一個標識符是否可以被引用,稱之為標識符的可見性。為標識符的可見性。 在一個在一個C+程序項目中,一個標識符只能在聲明或定義它的范圍程序項目中,一個標識符只能在聲明或定義它的范圍內(nèi)可見,在此之外是不可見的。內(nèi)可
32、見,在此之外是不可見的。 根據(jù)標識符的作用范圍,可將其作用域分為根據(jù)標識符的作用范圍,可將其作用域分為5種:種:函數(shù)原型作用域、函數(shù)原型作用域、函數(shù)作用域、塊作用域、類作用域和文件作用域函數(shù)作用域、塊作用域、類作用域和文件作用域。 其中,類作用域?qū)⒃谝院蠼榻B,這里介紹其他幾種。其中,類作用域?qū)⒃谝院蠼榻B,這里介紹其他幾種。2.3 作用域和存儲類型作用域和存儲類型n1. 函數(shù)原型作用域函數(shù)原型作用域 函數(shù)原型作用域指的是函數(shù)原型作用域指的是在聲明函數(shù)原型所指定的參數(shù)標識符在聲明函數(shù)原型所指定的參數(shù)標識符的作用范圍。的作用范圍。 這個這個作用范圍是在函數(shù)原型聲明中的左、右圓括號之間。作用范圍是在函
33、數(shù)原型聲明中的左、右圓括號之間。 正因為如此,在函數(shù)原型中聲明的標識符可以與函數(shù)定義中正因為如此,在函數(shù)原型中聲明的標識符可以與函數(shù)定義中說明的標識符名稱不同。由于所聲明的標識符與該函數(shù)的定義及說明的標識符名稱不同。由于所聲明的標識符與該函數(shù)的定義及調(diào)用無關(guān),所以可以在函數(shù)原型聲明中只作參數(shù)的類型聲明,而調(diào)用無關(guān),所以可以在函數(shù)原型聲明中只作參數(shù)的類型聲明,而省略參數(shù)名。省略參數(shù)名。 例如:例如: double max(double x, double y); 和和 double max(double, double); 是等價的。是等價的。2.3.1 作用域作用域2 塊作用域塊作用域塊語句就
34、是由塊語句就是由“”和和“”組成的組成的(復合語句復合語句)。在塊中聲明的標識符,。在塊中聲明的標識符,其作用域從聲明處開始,一直到結(jié)束塊的花括號為止。其作用域從聲明處開始,一直到結(jié)束塊的花括號為止。塊作用域也稱作塊作用域也稱作局部作用域局部作用域,具有塊作用域的變量是,具有塊作用域的變量是局部變量局部變量。例如:。例如:void fun(void) a的作用域的作用域b的作用域的作用域int a;/ a的作用域起始處的作用域起始處cina;if (a0) a = -a;int b;/ b的作用域起始處的作用域起始處 / b的作用域終止處的作用域終止處 / a的作用域終止處的作用域終止處2.3
35、.1 作用域作用域需要說明的是:需要說明的是:當標識符的作用域完全相同時,不允許出現(xiàn)相同的當標識符的作用域完全相同時,不允許出現(xiàn)相同的標識符名。而當標識符具有不同的作用域時,卻允許標識符同名。標識符名。而當標識符具有不同的作用域時,卻允許標識符同名。例如:例如:void fun(void)塊塊A塊塊B/ 塊塊A開始開始int i;/ 塊塊B開始開始int i;i = 100;/ 塊塊B結(jié)束結(jié)束/ 塊塊A結(jié)束結(jié)束 代碼中,在代碼中,在A和和B塊中都聲明了變量塊中都聲明了變量i,這是允許的,因為塊,這是允許的,因為塊A和塊和塊B不是同一個作用域。不是同一個作用域。塊塊A塊塊B2.3.1 作用域作用
36、域 但同時出現(xiàn)另外一個問題,語句但同時出現(xiàn)另外一個問題,語句“i = 100;”中的中的i是使用是使用A塊塊中的變量中的變量i還是使用還是使用B中的變量中的變量i? C+規(guī)定在這種作用域嵌套的情況下,規(guī)定在這種作用域嵌套的情況下,如果內(nèi)層如果內(nèi)層(塊塊B)和外層和外層(塊塊A)作用域聲明了同名的標識符,那么在外層作用域中聲明的標作用域聲明了同名的標識符,那么在外層作用域中聲明的標識符對于該內(nèi)層作用域是不可見的。識符對于該內(nèi)層作用域是不可見的。 也就是說,在塊也就是說,在塊B聲明的變量聲明的變量i與塊與塊A聲明的變量聲明的變量i無關(guān),當塊無關(guān),當塊B中的中的i=100時,不會影響塊時,不會影響塊
37、A中變量中變量i的值。的值。2.3.1 作用域作用域4. 文件作用域文件作用域 在所有函數(shù)外定義的標識符稱為在所有函數(shù)外定義的標識符稱為全局標識符全局標識符。全局標識符的作用。全局標識符的作用域是文件作用域。域是文件作用域。它從聲明之處開始,直到文件結(jié)束一直是可見的它從聲明之處開始,直到文件結(jié)束一直是可見的。具有文件作用域。具有文件作用域的變量和常量稱為全局變量和全局常量。的變量和常量稱為全局變量和全局常量。例如:例如:const float PI = 3.14;/ 全局常量全局常量PI,其作用域從此開始,其作用域從此開始int a;/ 全局變量全局變量a,其作用域從此開始,其作用域從此開始v
38、oid main( ) / void funA(int x) / 2.3.1 作用域作用域5 函數(shù)作用域函數(shù)作用域若函數(shù)定義在后,調(diào)用在前,必須進行函數(shù)原型聲明。若函數(shù)定義在若函數(shù)定義在后,調(diào)用在前,必須進行函數(shù)原型聲明。若函數(shù)定義在前,調(diào)用在后,函數(shù)定義包含了函數(shù)的原型聲明。前,調(diào)用在后,函數(shù)定義包含了函數(shù)的原型聲明。 一旦聲明了函數(shù)原型,函數(shù)標識符的作用域是從聲明或定義之處開一旦聲明了函數(shù)原型,函數(shù)標識符的作用域是從聲明或定義之處開始到源程序文件結(jié)束。始到源程序文件結(jié)束。例如:例如:void funA(int x ); / 函數(shù)函數(shù)funA的作用域從此開始到文件結(jié)束的作用域從此開始到文件結(jié)
39、束void funB( ) / 函數(shù)函數(shù)funB的作用域從此開始到文件結(jié)束的作用域從此開始到文件結(jié)束/ void main( ) / void funA(int x) / 2.3.3 存儲類型存儲類型 存儲類型是針對變量而言的,它規(guī)定了變量的生存期。無論是全局存儲類型是針對變量而言的,它規(guī)定了變量的生存期。無論是全局變量還是局部變量,編譯系統(tǒng)往往變量還是局部變量,編譯系統(tǒng)往往根據(jù)其存儲方式定義、分配和釋放相根據(jù)其存儲方式定義、分配和釋放相應的內(nèi)存空間。應的內(nèi)存空間。變量的存儲類型變量的存儲類型反映了變量在哪開辟內(nèi)存空間以及占用內(nèi)存空間的反映了變量在哪開辟內(nèi)存空間以及占用內(nèi)存空間的有效期限。有效
40、期限。在在C+中,變量有中,變量有4種存儲類型:種存儲類型:自動類型、靜態(tài)類型、寄存器類自動類型、靜態(tài)類型、寄存器類型和外部類型,型和外部類型,這些存儲類型是在變量定義時來指定的這些存儲類型是在變量定義時來指定的.其一般格式如下:其一般格式如下: ; 2.3.3 存儲類型存儲類型1. 自動存儲類型 一般說來,用自動存儲類型聲明的變量都是限制在某個程序范圍內(nèi)使用,即為局部變量。 從系統(tǒng)角度來說,自動存儲類型變量是采用動態(tài)分配方式在棧區(qū)中來分配內(nèi)存空間。因此,當程序執(zhí)行到超出該變量的作用域時,就釋放它所占用的內(nèi)存空間,其值也隨之消失了。 在C+語言中,聲明一個自動存儲類型的變量是在變量類型前加上關(guān)
41、鍵字auto, 例如: autoint i;2.3.3 存儲類型存儲類型 若自動存儲類型的變量是在函數(shù)內(nèi)或語句塊中聲若自動存儲類型的變量是在函數(shù)內(nèi)或語句塊中聲明的,則可省略關(guān)鍵字明的,則可省略關(guān)鍵字auto,例如:,例如:void fun()int i;/ 省略省略auto/ 2.3.3 存儲類型存儲類型2 寄存器類型寄存器類型使用使用關(guān)鍵字關(guān)鍵字register聲明寄存器類型聲明寄存器類型的變量的目的是將所的變量的目的是將所聲明的變量放入寄存器內(nèi),從而加快程序的運行速度。聲明的變量放入寄存器內(nèi),從而加快程序的運行速度。例如:例如:register int i;/ 聲明寄存器類型變量聲明寄存器
42、類型變量 但有時,在使用但有時,在使用register聲明時,若系統(tǒng)寄存器已經(jīng)被聲明時,若系統(tǒng)寄存器已經(jīng)被其他數(shù)據(jù)占據(jù)時,寄存器類型的變量就會自動當作其他數(shù)據(jù)占據(jù)時,寄存器類型的變量就會自動當作auto變量。變量。2.3.3 存儲類型存儲類型2. 靜態(tài)類型 從變量的生存期來說,一個變量的存儲空間可以是永久的,即在程序運行期間該變量一直存在,如全局變量。 也可以是臨時的,如局部變量,當流程執(zhí)行到它的說明語句時,系統(tǒng)為其在棧區(qū)中動態(tài)分配一個臨時的內(nèi)存空間,并在它的作用域中有效,一旦流程超出該變量的作用域時,就釋放它所占用的內(nèi)存空間,其值也隨之消失。 2.3.3 存儲類型存儲類型 但是,若在聲明局部
43、變量類型前面加上關(guān)鍵字static,則將其定義成了一個靜態(tài)類型的變量。 這樣的變量雖具有局部變量的作用域,但由于它是用靜態(tài)分配方式在靜態(tài)數(shù)據(jù)區(qū)中來分配內(nèi)存空間。 因此,在這種方式下,只要程序還在繼續(xù)執(zhí)行,靜態(tài)類型變量的值就一直有效,不會隨它所在的函數(shù)或語句塊的結(jié)束而消失。 簡單地說,靜態(tài)類型的局部變量雖具有局部變量的作用域,但卻有全局變量的生存期。2.3.3 存儲類型存儲類型例例Ex_Static 使用靜態(tài)類型的局部變量使用靜態(tài)類型的局部變量#include using namespace std;void count()int i = 0;static int j = 0; / 靜態(tài)類型靜態(tài)
44、類型i+;j+;couti = i, j = jn;int main()count();count();return 0; 2.3.3 存儲類型存儲類型 程序中,當?shù)诔绦蛑?,當?shù)?次調(diào)用函數(shù)次調(diào)用函數(shù)count時,由于變量時,由于變量j是靜態(tài)類型,因此其是靜態(tài)類型,因此其初值設為初值設為0后不再進行初始化,執(zhí)行后不再進行初始化,執(zhí)行j+后,后,j值為值為1,并一直有效。第,并一直有效。第2次次調(diào)用函數(shù)調(diào)用函數(shù)count時,由于時,由于j已分配內(nèi)存且進行過初始化,因此語句已分配內(nèi)存且進行過初始化,因此語句“static int j = 0;”被跳過,執(zhí)行被跳過,執(zhí)行j+后,后,j值為值為2。故程
45、序運行結(jié)果為:故程序運行結(jié)果為: 2.3.3 存儲類型存儲類型 需要說明的是,靜態(tài)類型的局部變量只在第一次執(zhí)行時進行初始化,正因為如此,在聲明靜態(tài)類型變量時一定要指定其初值,若沒有指定,編譯器還會將其初值置為0。2.4 名稱空間名稱空間 隨著程序代碼的增多,名稱相互沖突的可能性也將增加。尤其是在程序中使用多家廠商提供的類庫時,標示符名稱的沖突可能性更高。 例如,兩個類庫中可能都定義了名為List、Tree和Node的類,但定義的含義和方式不兼容;或是兩個類庫定義基個程序本相同,但兩個類庫同時包含在一個程序中,會出現(xiàn)標示符重復定義的錯誤。這些問題統(tǒng)稱為名稱空間問題。 解決這些名稱空間問題的方法是
46、使用C+新的名稱空間特性,通過名稱空間的作用域機制來解決。2.4 名稱空間名稱空間2.4.1 名稱空間的定義 在C+中,定義一個名稱空間的格式如下: 其中,namespace是C+關(guān)鍵字,標識符用作名稱空間的名稱,屬于該名稱空間體中的變量、函數(shù)、結(jié)構(gòu)、枚舉、聯(lián)合以及以后要討論的類等都可以認為是該名稱空間的成員。namespace 標識符標識符成員;成員;體體2.4.1 名稱空間的定義名稱空間的定義需要說明的是:需要說明的是:同一個文件中,可以允許定義多個名稱空間。一旦定義名稱空間后,同一個文件中,可以允許定義多個名稱空間。一旦定義名稱空間后,標識符就標識名稱空間體的那個區(qū)域。標識符就標識名稱空
47、間體的那個區(qū)域。例如:例如:using namespace std;namespace DING1char name = this is in DING1 region!;void showname( void )coutnameendl;2.4.1 名稱空間的定義名稱空間的定義namespace DING2char name = this is in DING2 region!;void showname( void )coutnameendl; 盡管名稱空間DIN1和DING2中定義的成員名都相同,但它們由于分屬不同的名稱區(qū)域,因而是合法的。 此后,在引用各自的成員時就可使用域作用運算符來指定DIN1或DING2來標識各自所在的名稱區(qū)域。2.4.1 名稱空間的定義名
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- java線程池原理面試題及答案
- java銀行業(yè)務主要面試題及答案
- 2025年具有獨立功能電氣設備及裝置項目立項申請報告
- 自我意識教育
- 針對2025年新標準的城市污水處理廠深度處理工藝設計優(yōu)化報告
- 環(huán)保產(chǎn)業(yè)園循環(huán)經(jīng)濟模式與能源結(jié)構(gòu)調(diào)整研究報告
- 公司職工舞蹈培訓
- 量子計算在量子搜索算法2025年優(yōu)化與效率研究報告
- 潰瘍性結(jié)腸炎護理診斷
- 中班健康課:小花傘本領(lǐng)大
- 內(nèi)科學《肺結(jié)核》課件
- (完整版)傳熱學期末考試試題
- Python數(shù)據(jù)分析與數(shù)據(jù)挖掘 課件 第6、7章 Pandas基礎(chǔ)與應用、Matplotlib
- 玻璃體手術(shù)并發(fā)癥的預防及處理
- 2023年醫(yī)學高級職稱-中醫(yī)肛腸(醫(yī)學高級)考試歷年高頻考點試題含答案
- 爬架拆除技術(shù)交底
- pergeos軟件教程評價許可介紹
- 密封條范文模板(A4打印版)
- 出租車 專業(yè)部分考核試題 城市客運企業(yè)主要負責人和安全生產(chǎn)管理人員安全考核基礎(chǔ)題庫
- GB/T 9634.3-2002鐵氧體磁心表面缺陷極限導則第3部分:ETD和E形磁心
- GB/T 8478-2008鋁合金門窗
評論
0/150
提交評論