版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第七章第七章函函數(shù)數(shù)7.1 概述概述 在在C語(yǔ)言里,語(yǔ)言里,函數(shù)函數(shù)(Function)是指是指實(shí)現(xiàn)一個(gè)特定功能的程序?qū)崿F(xiàn)一個(gè)特定功能的程序模塊模塊。用戶(hù)可以根據(jù)自己程序設(shè)計(jì)的需要,劃分出不同的功能。用戶(hù)可以根據(jù)自己程序設(shè)計(jì)的需要,劃分出不同的功能模塊,再將這些功能模塊定義為相應(yīng)的函數(shù),這種由用戶(hù)自己模塊,再將這些功能模塊定義為相應(yīng)的函數(shù),這種由用戶(hù)自己所定義的函數(shù),稱(chēng)為所定義的函數(shù),稱(chēng)為“用戶(hù)自定義函數(shù)用戶(hù)自定義函數(shù)”。在集成開(kāi)發(fā)環(huán)境中,也總是將一些常用的功能模塊編寫(xiě)成在集成開(kāi)發(fā)環(huán)境中,也總是將一些常用的功能模塊編寫(xiě)成函數(shù),放在函數(shù)庫(kù)中供公共選用,這些函數(shù)稱(chēng)為函數(shù),放在函數(shù)庫(kù)中供公共選用,這
2、些函數(shù)稱(chēng)為“庫(kù)函數(shù)庫(kù)函數(shù)”。main函數(shù)函數(shù)a函數(shù)函數(shù)e函數(shù)函數(shù)f 函數(shù)函數(shù)g . . .函數(shù)函數(shù)b函數(shù)函數(shù)h函數(shù)函數(shù)I函數(shù)函數(shù)J . . .函數(shù)函數(shù)c函數(shù)函數(shù)K 函數(shù)函數(shù)L 函數(shù)函數(shù)M . . .例例7.1(P170)函數(shù)的調(diào)用(演示函數(shù)的調(diào)用(演示P143.c)#include “stdlib.h” / VC6.0中使用中使用main ( ) printstar ( ); print_message ( ); printstar ( );printstar ( ) printf(“*n ”);print_message ( )printf(“How do you do!n”);進(jìn)一步體會(huì)進(jìn)
3、一步體會(huì)step over和和step into的區(qū)別。的區(qū)別。說(shuō)明說(shuō)明:1) 一個(gè)一個(gè)C源程序文件源程序文件可以由一個(gè)或多個(gè)可以由一個(gè)或多個(gè)函數(shù)函數(shù)組成。一個(gè)源程序文件組成。一個(gè)源程序文件就是一個(gè)編譯單位,而函數(shù)不是編譯單位。就是一個(gè)編譯單位,而函數(shù)不是編譯單位。2) 一個(gè)一個(gè)C程序程序由由一個(gè)主函數(shù)一個(gè)主函數(shù)和和若干個(gè)一般函數(shù)若干個(gè)一般函數(shù)構(gòu)成,其中主函數(shù)是構(gòu)成,其中主函數(shù)是不可缺省的。每個(gè)不可缺省的。每個(gè)C程序都是由主函數(shù)去調(diào)用其他函數(shù),其他函數(shù)程序都是由主函數(shù)去調(diào)用其他函數(shù),其他函數(shù)又可相互調(diào)用。又可相互調(diào)用。 3) 一個(gè)一個(gè)C程序程序由由一個(gè)或多個(gè)源程序文件一個(gè)或多個(gè)源程序文件組成。
4、對(duì)于較大的組成。對(duì)于較大的C程序,程序,通常將一些函數(shù)和其他內(nèi)容分別放在若干源文件中,再由若干源通常將一些函數(shù)和其他內(nèi)容分別放在若干源文件中,再由若干源文件組成一個(gè)文件組成一個(gè)C程序。最簡(jiǎn)單的情況,一個(gè)程序。最簡(jiǎn)單的情況,一個(gè)C程序由一個(gè)源程序文程序由一個(gè)源程序文件組成,這個(gè)源程序文件中只包含了一個(gè)函數(shù)(主函數(shù))。件組成,這個(gè)源程序文件中只包含了一個(gè)函數(shù)(主函數(shù))。4) C程序的執(zhí)行是程序的執(zhí)行是從從main函數(shù)開(kāi)始函數(shù)開(kāi)始,調(diào)用其它函數(shù)后流程又回到,調(diào)用其它函數(shù)后流程又回到main函數(shù),函數(shù),在在main函數(shù)中結(jié)束函數(shù)中結(jié)束整個(gè)程序的運(yùn)行。整個(gè)程序的運(yùn)行。main函數(shù)是由系函數(shù)是由系統(tǒng)定義的
5、,是一個(gè)特殊的函數(shù)。統(tǒng)定義的,是一個(gè)特殊的函數(shù)。5) 所有函數(shù)在定義時(shí)是相互獨(dú)立的,函數(shù)之間所有函數(shù)在定義時(shí)是相互獨(dú)立的,函數(shù)之間可以相互調(diào)用可以相互調(diào)用。函數(shù)的分類(lèi)函數(shù)的分類(lèi):1) 從從用戶(hù)使用的角度用戶(hù)使用的角度函數(shù)可分為函數(shù)可分為: 標(biāo)準(zhǔn)函數(shù)標(biāo)準(zhǔn)函數(shù),即,即庫(kù)函數(shù)庫(kù)函數(shù)。由系統(tǒng)提供,用戶(hù)不必定義,。由系統(tǒng)提供,用戶(hù)不必定義,直接使用直接使用; 用戶(hù)自定義函數(shù)用戶(hù)自定義函數(shù)。由用戶(hù)根據(jù)需要,自行編寫(xiě),以解。由用戶(hù)根據(jù)需要,自行編寫(xiě),以解決專(zhuān)門(mén)需要。決專(zhuān)門(mén)需要。2) 從從函數(shù)的形式函數(shù)的形式分,函數(shù)可分為:分,函數(shù)可分為: 無(wú)參數(shù)函數(shù)無(wú)參數(shù)函數(shù)。在調(diào)用無(wú)參函數(shù)時(shí),主函數(shù)并不將數(shù)據(jù)。在調(diào)用無(wú)參
6、函數(shù)時(shí),主函數(shù)并不將數(shù)據(jù)傳送給被調(diào)用函數(shù),一般用來(lái)執(zhí)行指定的一組操作。傳送給被調(diào)用函數(shù),一般用來(lái)執(zhí)行指定的一組操作。無(wú)參函數(shù)可以帶回也可以不帶回函數(shù)值,一般以后者無(wú)參函數(shù)可以帶回也可以不帶回函數(shù)值,一般以后者居多;居多; 有參函數(shù)有參函數(shù)。在調(diào)用函數(shù)時(shí),在主函數(shù)和被調(diào)用函數(shù)之。在調(diào)用函數(shù)時(shí),在主函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞。間有數(shù)據(jù)傳遞。7.2 定義一個(gè)函數(shù)定義一個(gè)函數(shù)1. 無(wú)參函數(shù)的定義形式無(wú)參函數(shù)的定義形式類(lèi)型標(biāo)識(shí)符類(lèi)型標(biāo)識(shí)符函數(shù)名函數(shù)名 ( ) 聲明部分聲明部分語(yǔ)句語(yǔ)句 其中,用其中,用“類(lèi)型標(biāo)識(shí)符類(lèi)型標(biāo)識(shí)符”指定函數(shù)值的類(lèi)型,即函指定函數(shù)值的類(lèi)型,即函數(shù)返回值的類(lèi)型。無(wú)參函數(shù)一般不需
7、要帶回函數(shù)值,因數(shù)返回值的類(lèi)型。無(wú)參函數(shù)一般不需要帶回函數(shù)值,因此可以不寫(xiě)類(lèi)型標(biāo)識(shí)符。此可以不寫(xiě)類(lèi)型標(biāo)識(shí)符。2. 有參函數(shù)的定義形式有參函數(shù)的定義形式類(lèi)型標(biāo)識(shí)符類(lèi)型標(biāo)識(shí)符函數(shù)名函數(shù)名 ( 形式參數(shù)表列形式參數(shù)表列 ) 聲明部分聲明部分語(yǔ)句語(yǔ)句例如例如:int max(int x, int y) int z; z=xy?x:y; return(z);說(shuō)明:說(shuō)明:1)return(z)的作用是將的作用是將z的值作為函數(shù)值返回到主函數(shù)中,的值作為函數(shù)值返回到主函數(shù)中,這個(gè)值稱(chēng)為這個(gè)值稱(chēng)為“函數(shù)返回值函數(shù)返回值”。注意返回值的類(lèi)型要和。注意返回值的類(lèi)型要和定義函數(shù)的定義函數(shù)的“類(lèi)型標(biāo)識(shí)符類(lèi)型標(biāo)識(shí)符”一
8、致。一致。2)如果在定義函數(shù)時(shí))如果在定義函數(shù)時(shí)不指定函數(shù)類(lèi)型不指定函數(shù)類(lèi)型,系統(tǒng)會(huì)隱含指定,系統(tǒng)會(huì)隱含指定函數(shù)類(lèi)型為函數(shù)類(lèi)型為int 型型。3. 空函數(shù)空函數(shù)的定義形式的定義形式類(lèi)型說(shuō)明符類(lèi)型說(shuō)明符 函數(shù)名函數(shù)名( ) 例如例如: dummy( ) 說(shuō)明:說(shuō)明:1)調(diào)用此函數(shù)時(shí),什么工作也不做,沒(méi)有任何實(shí)際作用。)調(diào)用此函數(shù)時(shí),什么工作也不做,沒(méi)有任何實(shí)際作用。2)空函數(shù)的使用一般用于程序設(shè)計(jì)的模塊設(shè)計(jì)階段。表示)空函數(shù)的使用一般用于程序設(shè)計(jì)的模塊設(shè)計(jì)階段。表示這是一個(gè)待完成的函數(shù),但不影響當(dāng)前程序的運(yùn)行。這是一個(gè)待完成的函數(shù),但不影響當(dāng)前程序的運(yùn)行。4. 對(duì)形參進(jìn)行聲明的方式(在對(duì)形參進(jìn)行
9、聲明的方式(在1.3節(jié)中已講)節(jié)中已講) C語(yǔ)言傳統(tǒng)聲明方式為:對(duì)形參類(lèi)型的聲明放在函數(shù)語(yǔ)言傳統(tǒng)聲明方式為:對(duì)形參類(lèi)型的聲明放在函數(shù)定義的第定義的第2行,在函數(shù)括號(hào)外單獨(dú)指定。行,在函數(shù)括號(hào)外單獨(dú)指定。傳統(tǒng)聲明方式傳統(tǒng)聲明方式: int max(x, y) int x, y; int z; z=xy?x:y; return(z); 現(xiàn)代聲明方式現(xiàn)代聲明方式: int max(int x,int y) int z; z=xy?x:y; return(z); 7.3 函數(shù)參數(shù)和函數(shù)的值(函數(shù)參數(shù)和函數(shù)的值(P174)7.3.1 形式參數(shù)和實(shí)際參數(shù)形式參數(shù)和實(shí)際參數(shù) 在定義函數(shù)時(shí),函數(shù)名后面括號(hào)中的
10、變量名稱(chēng)為在定義函數(shù)時(shí),函數(shù)名后面括號(hào)中的變量名稱(chēng)為“形式參形式參數(shù)數(shù)” (簡(jiǎn)稱(chēng)(簡(jiǎn)稱(chēng)“形參形參”)。在主調(diào)函數(shù)中調(diào)用一個(gè)函數(shù)時(shí),函數(shù))。在主調(diào)函數(shù)中調(diào)用一個(gè)函數(shù)時(shí),函數(shù)名后面括弧中的參數(shù)(也可是一個(gè)表達(dá)式)稱(chēng)為名后面括弧中的參數(shù)(也可是一個(gè)表達(dá)式)稱(chēng)為“實(shí)際參數(shù)實(shí)際參數(shù)”(簡(jiǎn)稱(chēng)(簡(jiǎn)稱(chēng)“實(shí)參實(shí)參”)。)。例例7.2(P176)調(diào)用函數(shù)時(shí)的數(shù)據(jù)傳遞)調(diào)用函數(shù)時(shí)的數(shù)據(jù)傳遞main ( ) int a,b,c; scanf(“%d,%d”,&a,&b); c=max(a, b); printf(“Max is %d”,c) int max( int x, int y) int z;
11、z=xy?x:y; return(z);運(yùn)行情況如下運(yùn)行情況如下:7,8Max is 8實(shí)參實(shí)參a,b形參形參x,y關(guān)于形參和實(shí)參的說(shuō)明關(guān)于形參和實(shí)參的說(shuō)明1) 在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調(diào)用時(shí),它們并在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調(diào)用時(shí),它們并不占據(jù)內(nèi)存單元。只有在發(fā)生函數(shù)調(diào)用時(shí),不占據(jù)內(nèi)存單元。只有在發(fā)生函數(shù)調(diào)用時(shí), max函數(shù)中的函數(shù)中的形參才被分配內(nèi)存單元。在調(diào)用結(jié)束后,形參所占的內(nèi)存形參才被分配內(nèi)存單元。在調(diào)用結(jié)束后,形參所占的內(nèi)存單元也被釋放。單元也被釋放。2) 實(shí)參可以是常量、變量、表達(dá)式、函數(shù)。如:實(shí)參可以是常量、變量、表達(dá)式、函數(shù)。如:max(3,a+b)但要
12、求它要有一個(gè)但要求它要有一個(gè)確定的值確定的值。在調(diào)用時(shí)將實(shí)參的值賦給形。在調(diào)用時(shí)將實(shí)參的值賦給形參(如果實(shí)參是一個(gè)表達(dá)式或函數(shù),則需要參(如果實(shí)參是一個(gè)表達(dá)式或函數(shù),則需要先求解出實(shí)參先求解出實(shí)參的值的值)。)。3) 在被定義的函數(shù)中,必須指定形參的類(lèi)型。在被定義的函數(shù)中,必須指定形參的類(lèi)型。4) 實(shí)參和形參的類(lèi)型應(yīng)實(shí)參和形參的類(lèi)型應(yīng)相同相同或或賦值兼容賦值兼容,否則會(huì)出錯(cuò)。,否則會(huì)出錯(cuò)。5) C語(yǔ)言規(guī)定,實(shí)參與形參之間的數(shù)據(jù)傳遞遵守語(yǔ)言規(guī)定,實(shí)參與形參之間的數(shù)據(jù)傳遞遵守“單向值傳單向值傳遞遞”的原則,即只能由實(shí)參傳給形參,而不能由形參反過(guò)的原則,即只能由實(shí)參傳給形參,而不能由形參反過(guò)來(lái)傳給實(shí)
13、參。來(lái)傳給實(shí)參。說(shuō)明說(shuō)明: 1) 如果需要從被調(diào)函數(shù)帶回一個(gè)函數(shù)值,供主調(diào)函數(shù)使用,如果需要從被調(diào)函數(shù)帶回一個(gè)函數(shù)值,供主調(diào)函數(shù)使用,則被調(diào)函數(shù)中必須包含則被調(diào)函數(shù)中必須包含return語(yǔ)句語(yǔ)句。 2) 一個(gè)函數(shù)中可以有一個(gè)函數(shù)中可以有一個(gè)以上一個(gè)以上的的return語(yǔ)句,但只有一個(gè)語(yǔ)句,但只有一個(gè)return語(yǔ)句被執(zhí)行。語(yǔ)句被執(zhí)行。 3) return語(yǔ)句后的括弧可以不要。例如:語(yǔ)句后的括弧可以不要。例如: return z; 和和 return(z); 是等效的。是等效的。 4) 函數(shù)的返回值類(lèi)型由函數(shù)定義時(shí)的說(shuō)明類(lèi)型決定,函數(shù)的返回值類(lèi)型由函數(shù)定義時(shí)的說(shuō)明類(lèi)型決定,return語(yǔ)句中的表
14、達(dá)式類(lèi)型一般應(yīng)與之一致。如果不一致,對(duì)數(shù)語(yǔ)句中的表達(dá)式類(lèi)型一般應(yīng)與之一致。如果不一致,對(duì)數(shù)值型數(shù)據(jù),系統(tǒng)會(huì)自動(dòng)進(jìn)行類(lèi)型轉(zhuǎn)換。值型數(shù)據(jù),系統(tǒng)會(huì)自動(dòng)進(jìn)行類(lèi)型轉(zhuǎn)換。7.3.2 函數(shù)的返回值函數(shù)的返回值 通過(guò)函數(shù)調(diào)用使主調(diào)函數(shù)得到一個(gè)確定的值,這個(gè)值就是通過(guò)函數(shù)調(diào)用使主調(diào)函數(shù)得到一個(gè)確定的值,這個(gè)值就是函數(shù)的返回值。例如例函數(shù)的返回值。例如例8.2。 5) 如果不需要返回值,則被調(diào)函數(shù)中可以不要如果不需要返回值,則被調(diào)函數(shù)中可以不要return語(yǔ)句,但此語(yǔ)句,但此時(shí)并不是沒(méi)有返回值,而是返回了時(shí)并不是沒(méi)有返回值,而是返回了一個(gè)不確定的值一個(gè)不確定的值,C語(yǔ)言也語(yǔ)言也允許用戶(hù)把該值賦給一個(gè)變量。允許用戶(hù)
15、把該值賦給一個(gè)變量。 6) 如果用戶(hù)要明確表示如果用戶(hù)要明確表示“不要返回值不要返回值”,則可定義被調(diào)函數(shù)類(lèi)型,則可定義被調(diào)函數(shù)類(lèi)型為為void(空類(lèi)型)(空類(lèi)型)。 例如:例例如:例8.1中的定義可以改為中的定義可以改為: void printstar( ) void print_message( ) 這樣,被調(diào)函數(shù)就不會(huì)返回任何值,系統(tǒng)會(huì)禁止在主調(diào)函數(shù)這樣,被調(diào)函數(shù)就不會(huì)返回任何值,系統(tǒng)會(huì)禁止在主調(diào)函數(shù)中使用被調(diào)函數(shù)的返回值。中使用被調(diào)函數(shù)的返回值。 例如:例如: a=printfstar( ); b=print_message( ); 是不合法的。是不合法的。7.4 函數(shù)的調(diào)用函數(shù)的調(diào)用
16、7.4.1 函數(shù)調(diào)用的一般形式函數(shù)調(diào)用的一般形式 函數(shù)調(diào)用的一般形式為函數(shù)調(diào)用的一般形式為: 函數(shù)名函數(shù)名 ( 實(shí)參表列實(shí)參表列 ) 說(shuō)明說(shuō)明: 1) 如果是調(diào)用無(wú)參函數(shù),則如果是調(diào)用無(wú)參函數(shù),則“實(shí)參表列實(shí)參表列”可以沒(méi)有,可以沒(méi)有,但括弧不能省略。但括弧不能省略。 2) 如果有多個(gè)實(shí)參,則各參數(shù)間用如果有多個(gè)實(shí)參,則各參數(shù)間用逗號(hào)隔開(kāi)逗號(hào)隔開(kāi),實(shí)參與,實(shí)參與形參的形參的個(gè)數(shù)應(yīng)相等個(gè)數(shù)應(yīng)相等,類(lèi)型應(yīng)一致類(lèi)型應(yīng)一致。在。在Turbo C中,中,對(duì)對(duì)實(shí)參求值的順序?qū)崊⑶笾档捻樞蚴前词前醋杂抑磷笞杂抑磷蟮捻樞?。的順序?7.4.2 函數(shù)調(diào)用的方式(函數(shù)調(diào)用的方式(P174) 按函數(shù)在程序中出現(xiàn)的位
17、置來(lái)分,可以有以下三種函數(shù)調(diào)用按函數(shù)在程序中出現(xiàn)的位置來(lái)分,可以有以下三種函數(shù)調(diào)用方式:方式:1. 函數(shù)語(yǔ)句:函數(shù)語(yǔ)句:把函數(shù)調(diào)用作為一個(gè)語(yǔ)句。如例把函數(shù)調(diào)用作為一個(gè)語(yǔ)句。如例8.1中的中的printstar( ); 這種調(diào)用方式不要求函數(shù)帶回值,只要求函數(shù)這種調(diào)用方式不要求函數(shù)帶回值,只要求函數(shù)完成一定的操作完成一定的操作;2. 函數(shù)表達(dá)式:函數(shù)表達(dá)式:函數(shù)出現(xiàn)在一個(gè)表達(dá)式中,這種表達(dá)式稱(chēng)為函數(shù)出現(xiàn)在一個(gè)表達(dá)式中,這種表達(dá)式稱(chēng)為函數(shù)表達(dá)式函數(shù)表達(dá)式,這時(shí)要求函數(shù)這時(shí)要求函數(shù)帶回一個(gè)確定的值帶回一個(gè)確定的值參加表達(dá)式的運(yùn)算。參加表達(dá)式的運(yùn)算。 例如例如:c=2*max(a,b);3. 函數(shù)參數(shù)
18、:函數(shù)參數(shù):函數(shù)調(diào)用函數(shù)調(diào)用作為一個(gè)函數(shù)的實(shí)參作為一個(gè)函數(shù)的實(shí)參。這種調(diào)用的實(shí)質(zhì)也是函數(shù)。這種調(diào)用的實(shí)質(zhì)也是函數(shù)表達(dá)式調(diào)用的一種特例。表達(dá)式調(diào)用的一種特例。.例如例如:m=max(a,max(b,c);其中其中max(b,c)是一次函數(shù)調(diào)用,它的值作為是一次函數(shù)調(diào)用,它的值作為max第二次調(diào)用的實(shí)參。第二次調(diào)用的實(shí)參。7.4.3 對(duì)被調(diào)用函數(shù)的聲明和函數(shù)原型(對(duì)被調(diào)用函數(shù)的聲明和函數(shù)原型(P179) 在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)需要具備的條件:在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)需要具備的條件:1)首先被調(diào)用的函數(shù)首先被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù)必須是已經(jīng)存在的函數(shù)(庫(kù)函數(shù)或用(庫(kù)函數(shù)或用戶(hù)自己定義的
19、函數(shù))。此條件必要而不充分。戶(hù)自己定義的函數(shù))。此條件必要而不充分。2)如果使用庫(kù)函數(shù),一般還應(yīng)在本文件開(kāi)頭用如果使用庫(kù)函數(shù),一般還應(yīng)在本文件開(kāi)頭用#include命命令將相關(guān)的令將相關(guān)的 “頭文件頭文件”(含有所用庫(kù)函數(shù)的相關(guān)信息)(含有所用庫(kù)函數(shù)的相關(guān)信息)“包含包含”到本文件中來(lái)。例如:到本文件中來(lái)。例如: #include #include 3)如果使用的是用戶(hù)自定義函數(shù),且被調(diào)函數(shù)的定義位于主調(diào)函數(shù)如果使用的是用戶(hù)自定義函數(shù),且被調(diào)函數(shù)的定義位于主調(diào)函數(shù)之后(如下例),則之后(如下例),則在主調(diào)函數(shù)的可執(zhí)行語(yǔ)句之前在主調(diào)函數(shù)的可執(zhí)行語(yǔ)句之前應(yīng)對(duì)被調(diào)函數(shù)應(yīng)對(duì)被調(diào)函數(shù)進(jìn)行聲明。進(jìn)行聲明。
20、函數(shù)聲明函數(shù)聲明也稱(chēng)為也稱(chēng)為函數(shù)原型函數(shù)原型,其作用主要是,其作用主要是提前告訴編提前告訴編譯系統(tǒng)所要調(diào)用函數(shù)的原型,具體的函數(shù)定義在后面,便于編譯譯系統(tǒng)所要調(diào)用函數(shù)的原型,具體的函數(shù)定義在后面,便于編譯系統(tǒng)在程序的編譯階段對(duì)函數(shù)調(diào)用的合法性進(jìn)行全面檢查系統(tǒng)在程序的編譯階段對(duì)函數(shù)調(diào)用的合法性進(jìn)行全面檢查。例例 7.5(P180) main( ) float add (float x,float y); float a,b,c; scanf(“%f,%f”,&a,&b); c=add(a,b); printf(“sum is %f”,c);float add(float x,fl
21、oat y) float z; z=x+y; return(z); 聲明聲明定義:包括函數(shù)首定義:包括函數(shù)首部、函數(shù)體部分。部、函數(shù)體部分。調(diào)用調(diào)用關(guān)于函數(shù)聲明的幾點(diǎn)說(shuō)明:關(guān)于函數(shù)聲明的幾點(diǎn)說(shuō)明: 1.函數(shù)原型。函數(shù)原型。函數(shù)原型的一般形式為:函數(shù)原型的一般形式為:1)函數(shù)類(lèi)型函數(shù)類(lèi)型 函數(shù)名(形參類(lèi)型函數(shù)名(形參類(lèi)型1 形參名形參名1, 形參類(lèi)型形參類(lèi)型2 形參名形參名2, )2)函數(shù)類(lèi)型函數(shù)類(lèi)型 函數(shù)名(形參類(lèi)型函數(shù)名(形參類(lèi)型1, 形參類(lèi)型形參類(lèi)型2, ) 第一種便于閱讀,第二種為基本形式。實(shí)際上,第一種便于閱讀,第二種為基本形式。實(shí)際上,編譯系統(tǒng)不對(duì)編譯系統(tǒng)不對(duì)形參名做檢查形參名做檢查
22、。因此上例程序中的函數(shù)聲明可以寫(xiě)成:。因此上例程序中的函數(shù)聲明可以寫(xiě)成: float add( float, float );2. 應(yīng)當(dāng)保證應(yīng)當(dāng)保證函數(shù)原型與函數(shù)首部寫(xiě)法上的一致函數(shù)原型與函數(shù)首部寫(xiě)法上的一致,即,即函數(shù)函數(shù)類(lèi)型類(lèi)型、函數(shù)名函數(shù)名,參數(shù)類(lèi)型參數(shù)類(lèi)型,參數(shù)個(gè)數(shù)參數(shù)個(gè)數(shù)和和參數(shù)順序參數(shù)順序必須必須相同。函數(shù)調(diào)用時(shí)實(shí)參類(lèi)型必須與函數(shù)原型中的形參相同。函數(shù)調(diào)用時(shí)實(shí)參類(lèi)型必須與函數(shù)原型中的形參類(lèi)型賦值兼容。類(lèi)型賦值兼容。3. 如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,則主調(diào)函如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,則主調(diào)函數(shù)中可以不對(duì)被調(diào)函數(shù)進(jìn)行聲明。數(shù)中可以不對(duì)被調(diào)函數(shù)進(jìn)行聲明。4. 如
23、果已在所有函數(shù)定義之前,在函數(shù)的外部已做了函如果已在所有函數(shù)定義之前,在函數(shù)的外部已做了函數(shù)聲明,則在各個(gè)主調(diào)函數(shù)中不必對(duì)所調(diào)用的函數(shù)再數(shù)聲明,則在各個(gè)主調(diào)函數(shù)中不必對(duì)所調(diào)用的函數(shù)再作聲明。作聲明。5. 如果在函數(shù)調(diào)用之前,沒(méi)有對(duì)函數(shù)作聲明,則編譯系如果在函數(shù)調(diào)用之前,沒(méi)有對(duì)函數(shù)作聲明,則編譯系統(tǒng)會(huì)把第一次遇到的該函數(shù)形式(函數(shù)定義或函數(shù)調(diào)統(tǒng)會(huì)把第一次遇到的該函數(shù)形式(函數(shù)定義或函數(shù)調(diào)用)作為函數(shù)的聲明,并用)作為函數(shù)的聲明,并將函數(shù)類(lèi)型默認(rèn)為將函數(shù)類(lèi)型默認(rèn)為int 型型。 推薦作法:為了程序清晰和安全,建議都加以聲明!推薦作法:為了程序清晰和安全,建議都加以聲明!7.5 函數(shù)的嵌套調(diào)用函數(shù)的
24、嵌套調(diào)用C語(yǔ)言的函數(shù)定義都是互相平行、獨(dú)立的,即不允許嵌套定義。語(yǔ)言的函數(shù)定義都是互相平行、獨(dú)立的,即不允許嵌套定義。嵌套定義嵌套定義是指在定義函數(shù)時(shí),一個(gè)函數(shù)內(nèi)又包含了另一個(gè)函數(shù),是指在定義函數(shù)時(shí),一個(gè)函數(shù)內(nèi)又包含了另一個(gè)函數(shù),這個(gè)內(nèi)嵌的函數(shù)只能被包含它的函數(shù)所調(diào)用,其它函數(shù)不能調(diào)用它。這個(gè)內(nèi)嵌的函數(shù)只能被包含它的函數(shù)所調(diào)用,其它函數(shù)不能調(diào)用它。這在這在PASCAL中是允許的。中是允許的。例如:例如:main() fun1( ); /* 函數(shù)調(diào)用語(yǔ)句函數(shù)調(diào)用語(yǔ)句 */ fun1( ) fun2( ); /* 函數(shù)嵌套調(diào)用函數(shù)嵌套調(diào)用 */ fun2( ) main() fun1( ); /*
25、 函數(shù)調(diào)用語(yǔ)句函數(shù)調(diào)用語(yǔ)句 */ fun1( ) fun2( ) /* 函數(shù)嵌套定義函數(shù)嵌套定義 */ C語(yǔ)句不能嵌套定義函數(shù),但可以語(yǔ)句不能嵌套定義函數(shù),但可以嵌套調(diào)用嵌套調(diào)用函數(shù),即在調(diào)用函數(shù),即在調(diào)用一個(gè)函數(shù)的過(guò)程中,又調(diào)用另一個(gè)函數(shù)。一個(gè)函數(shù)的過(guò)程中,又調(diào)用另一個(gè)函數(shù)。下圖是兩次嵌套調(diào)用(連下圖是兩次嵌套調(diào)用(連main函數(shù)共函數(shù)共3層函數(shù))的執(zhí)行過(guò)程:層函數(shù))的執(zhí)行過(guò)程:main函數(shù)函數(shù)調(diào)用調(diào)用a函數(shù)函數(shù)結(jié)束結(jié)束a函數(shù)函數(shù)調(diào)用調(diào)用b函數(shù)函數(shù)b函數(shù)函數(shù) 關(guān)于函數(shù)嵌套的概念比較簡(jiǎn)單,請(qǐng)大家自學(xué)例關(guān)于函數(shù)嵌套的概念比較簡(jiǎn)單,請(qǐng)大家自學(xué)例8.6,下,下面給大家詳細(xì)講述一種特殊的函數(shù)嵌套面給大
26、家詳細(xì)講述一種特殊的函數(shù)嵌套函數(shù)的遞歸。函數(shù)的遞歸。 所謂遞歸調(diào)用,是指在函數(shù)體內(nèi)部直接或間接地自己調(diào)所謂遞歸調(diào)用,是指在函數(shù)體內(nèi)部直接或間接地自己調(diào)用自己,即函數(shù)嵌套調(diào)用該函數(shù)本身。用自己,即函數(shù)嵌套調(diào)用該函數(shù)本身。 一一、遞歸調(diào)用的形式遞歸調(diào)用的形式 1 1、直接調(diào)用、直接調(diào)用例例: age ( int n ) int c ; if ( n = = 1 ) c = 10 ; else c = age ( n 1) + 2 ; return ( c ) ; f ( ) 函數(shù)函數(shù) 調(diào)用調(diào)用f ( )函數(shù)函數(shù) 7.6 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用 2 2、 間接調(diào)用間接調(diào)用 f1( ) f2(
27、) 調(diào)用調(diào)用f2( ) 調(diào)用調(diào)用f1( ) 如如: int f1( int x ) int f2 ( int t ) int y , z ; int a , c ; z = f2(y) ; c = f1(a) ; return ( 2*z ) ; return ( 3 + c ) ; 例例7.7 用遞歸方法求用遞歸方法求n!。例。例7.8 古典的漢諾塔問(wèn)題,不作要求。古典的漢諾塔問(wèn)題,不作要求。 例例7.6(P185)有有5 5個(gè)人坐在一起,問(wèn)第個(gè)人坐在一起,問(wèn)第5 5個(gè)人多少歲?他說(shuō)比個(gè)人多少歲?他說(shuō)比第第4 4個(gè)人大個(gè)人大2 2歲。問(wèn)第歲。問(wèn)第4 4個(gè)人歲數(shù),他說(shuō)比第個(gè)人歲數(shù),他說(shuō)比第3
28、3個(gè)人大個(gè)人大2 2歲。問(wèn)第歲。問(wèn)第3 3個(gè)人,又說(shuō)比第個(gè)人,又說(shuō)比第2 2個(gè)人大個(gè)人大2 2歲。問(wèn)第歲。問(wèn)第2 2個(gè)人,說(shuō)比第個(gè)人,說(shuō)比第1 1個(gè)人大個(gè)人大2 2歲。歲。最后問(wèn)第最后問(wèn)第1 1個(gè)人,他說(shuō)是個(gè)人,他說(shuō)是1010歲。請(qǐng)問(wèn)第歲。請(qǐng)問(wèn)第5 5個(gè)人多大?個(gè)人多大?根據(jù)題意有:根據(jù)題意有:age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10用數(shù)學(xué)通式表述為:用數(shù)學(xué)通式表述為:age(n)=10 (n=1)age(n)=10 (n=1)age(n)=age(n-1)+2 (n1)age(n)=age(n-
29、1)+2 (n1)圖示:age(5)age(4)age(3)age(2)age(1)=10age(1)+2age(2)+2age(3)+2age(4)+2age(5)age(4)age(3)age(2)=12=14=16=18第一階段:回推第二階段:遞推 age ( int n ) int c ; if ( n = = 1 ) c = 10 ; else c = age ( n 1) + 2 ; return ( c ) ; main ( ) printf ( “ %d ”, age(5) ) ; 源程序,源程序,演示:演示:P158.c進(jìn)一步熟悉進(jìn)一步熟悉VC6.0中幾個(gè)基本的調(diào)試工具:中幾
30、個(gè)基本的調(diào)試工具: step into,Step over,Watch,Variables,Call stack。 main age(5)=18 age(4)=16 age(3)=14 age(2)=12 age(1)=10 結(jié)果: 18 age(5) age(4)+2 c =10 age(1)+2 age(2)+2 age(3)+2二、實(shí)現(xiàn)遞歸的條件二、實(shí)現(xiàn)遞歸的條件 1 1)要有完成函數(shù)任務(wù)的語(yǔ)句;)要有完成函數(shù)任務(wù)的語(yǔ)句; 2 2)要有能避免遞歸調(diào)用的判斷(即遞歸)要有能避免遞歸調(diào)用的判斷(即遞歸“終止條件終止條件”);); 3 3)在遞歸調(diào)用的過(guò)程中,要能不斷逼近遞歸終止條件,以至)在
31、遞歸調(diào)用的過(guò)程中,要能不斷逼近遞歸終止條件,以至最后結(jié)束遞歸;最后結(jié)束遞歸; 4 4)先先進(jìn)行遞歸終止條件的判斷,進(jìn)行遞歸終止條件的判斷,后后進(jìn)行遞歸調(diào)用。進(jìn)行遞歸調(diào)用。n=5n=4n=3n=2n=1 age ( int n ) int c ; if ( n = = 1 ) c = 10 ; else c = age ( n 1) + 2 ; return ( c ) ; main ( ) printf ( “ %d ”, age(5) ) ; 分析遞歸的條件分析遞歸的條件完成任務(wù)遞歸終止條件遞歸調(diào)用先判斷后遞歸調(diào)用三、對(duì)遞歸的評(píng)價(jià)三、對(duì)遞歸的評(píng)價(jià) 遞歸的目的是要簡(jiǎn)化程序設(shè)計(jì),使程序遞歸的目的
32、是要簡(jiǎn)化程序設(shè)計(jì),使程序易讀易讀。 但遞歸但遞歸增加了系統(tǒng)開(kāi)銷(xiāo)增加了系統(tǒng)開(kāi)銷(xiāo)。時(shí)間上,執(zhí)行函數(shù)調(diào)用和函數(shù)。時(shí)間上,執(zhí)行函數(shù)調(diào)用和函數(shù)返回屬于額外工作,要占用返回屬于額外工作,要占用CPUCPU時(shí)間??臻g上,每遞歸一次,時(shí)間??臻g上,每遞歸一次,棧內(nèi)存就要多占用一部分。棧內(nèi)存就要多占用一部分。 相應(yīng)的非遞歸函數(shù)雖然效率高,但卻比較難編程,而且相應(yīng)的非遞歸函數(shù)雖然效率高,但卻比較難編程,而且相對(duì)來(lái)說(shuō)可讀性較差。實(shí)際上,大多數(shù)遞歸函數(shù)都是可以用相對(duì)來(lái)說(shuō)可讀性較差。實(shí)際上,大多數(shù)遞歸函數(shù)都是可以用非遞歸函數(shù)來(lái)代替的。關(guān)于非遞歸函數(shù)來(lái)代替的。關(guān)于“遞歸的消去遞歸的消去”不再探討。不再探討。 現(xiàn)代程序設(shè)計(jì)
33、的目標(biāo)主要是可讀性好。隨著計(jì)算機(jī)硬件現(xiàn)代程序設(shè)計(jì)的目標(biāo)主要是可讀性好。隨著計(jì)算機(jī)硬件性能的不斷提高,程序在更多的場(chǎng)合優(yōu)先考慮的是可讀性,性能的不斷提高,程序在更多的場(chǎng)合優(yōu)先考慮的是可讀性,而不是高效性,所以我們而不是高效性,所以我們鼓勵(lì)使用遞歸的思想實(shí)現(xiàn)程序設(shè)計(jì)鼓勵(lì)使用遞歸的思想實(shí)現(xiàn)程序設(shè)計(jì)。1. 數(shù)組元素作為函數(shù)實(shí)參數(shù)組元素作為函數(shù)實(shí)參 數(shù)組元素可以作為函數(shù)實(shí)參,數(shù)組元素可以作為函數(shù)實(shí)參, 用法與變量實(shí)參相同,依然遵用法與變量實(shí)參相同,依然遵循的是循的是“單向值傳遞單向值傳遞”原則。原則。例例7.9(P193)從鍵盤(pán)上輸入)從鍵盤(pán)上輸入10個(gè)整數(shù),并輸出其中最大的元素和個(gè)整數(shù),并輸出其中最大
34、的元素和該元素是第幾個(gè)數(shù)。該元素是第幾個(gè)數(shù)。7.7 數(shù)組作為函數(shù)參數(shù)數(shù)組作為函數(shù)參數(shù)#include int main( ) int max( int x, int y); int a10,m,n,i; printf(“enter 10 integer numbers:”); for( i=0; i10; i+) scanf(“%d”,&ai); printf(“n”); for (i=1,m=a0,n=0; i m) m=max(m,ai); n=i; printf(“max=%d, No. %d”,m,n+1);int max( int x, int y) return (xy?
35、x: y);例例8.10 有兩個(gè)數(shù)組有兩個(gè)數(shù)組a,b,各有,各有10個(gè)元素,將它們個(gè)元素,將它們對(duì)應(yīng)元素逐一比對(duì)應(yīng)元素逐一比較較。如果。如果a數(shù)組中的元素大于數(shù)組中的元素大于b數(shù)組中相應(yīng)元素的個(gè)數(shù)數(shù)組中相應(yīng)元素的個(gè)數(shù)多于多于b數(shù)組數(shù)組中的元素大于中的元素大于a數(shù)組中相應(yīng)元素的個(gè)數(shù),則認(rèn)為數(shù)組中相應(yīng)元素的個(gè)數(shù),則認(rèn)為a數(shù)組數(shù)組大于大于b數(shù)組,數(shù)組,并分別使用并分別使用n、m、k三個(gè)標(biāo)記變量來(lái)記錄兩個(gè)數(shù)組相應(yīng)元素大于、三個(gè)標(biāo)記變量來(lái)記錄兩個(gè)數(shù)組相應(yīng)元素大于、等于、小于的次數(shù)。要求是用等于、小于的次數(shù)。要求是用large函數(shù)來(lái)實(shí)現(xiàn)對(duì)應(yīng)元素的比較。函數(shù)來(lái)實(shí)現(xiàn)對(duì)應(yīng)元素的比較。abmain ( )int
36、large(int x,int y);int a10,b10,i,n=0,m=0,k=0;printf(“enter array a:n”); for(i=0; i10; i+) scanf(“%d”,&ai);printf(“n”);printf(“enter array b:n”); for(i=0; i10; i+)scanf(“%d”,&bi);printf(“n”);for(i=0;ibi%d imesn ai=bi%d imesn aik)printf(“array a is larger than array bn”);else if(ny) flag=1; el
37、se if (xy) flag=-1; else flag=0; return(flag);2. 數(shù)組名可作函數(shù)參數(shù)數(shù)組名可作函數(shù)參數(shù)數(shù)組名可作函數(shù)參數(shù),此時(shí)實(shí)參與形參都應(yīng)用數(shù)組名。數(shù)組名可作函數(shù)參數(shù),此時(shí)實(shí)參與形參都應(yīng)用數(shù)組名。例例7.10(P194) 在一維數(shù)組在一維數(shù)組score中存放了中存放了10個(gè)成績(jī),求平均成績(jī)。個(gè)成績(jī),求平均成績(jī)。float average(float array10) int i;float aver,sum=array0;for(i=1;i10;i+)sum=sum+arrayi;aver=sum/10;return(aver);main( )float sc
38、ore10,aver;int i;printf(“input 10 scores:n”);for(i=0;i10;i+)scanf(“%f”,&scorei);printf(“n”);aver=average(score);printf(“average score is %5.2f”,aver);說(shuō)明:說(shuō)明: 1)用數(shù)組名作函數(shù)參數(shù),用數(shù)組名作函數(shù)參數(shù),應(yīng)該在主調(diào)函數(shù)和被調(diào)用函數(shù)分別定應(yīng)該在主調(diào)函數(shù)和被調(diào)用函數(shù)分別定義數(shù)組義數(shù)組,不能只在一方定義(在未講指針前是這樣的)。,不能只在一方定義(在未講指針前是這樣的)。 2)實(shí)參數(shù)組與形參數(shù)組類(lèi)型應(yīng)一致,否則出錯(cuò);實(shí)參數(shù)組與形參數(shù)組類(lèi)型應(yīng)
39、一致,否則出錯(cuò); 3)實(shí)參數(shù)組與形參數(shù)組大小可以一致也可以不一致,實(shí)參數(shù)組與形參數(shù)組大小可以一致也可以不一致,C編譯對(duì)編譯對(duì)形參數(shù)組大小不作檢查,只是將實(shí)參數(shù)組的首地址傳給形參形參數(shù)組大小不作檢查,只是將實(shí)參數(shù)組的首地址傳給形參數(shù)組。因此,上例的被調(diào)函數(shù)首部也可寫(xiě)成:數(shù)組。因此,上例的被調(diào)函數(shù)首部也可寫(xiě)成:float average( float array ) 4)為了能在被調(diào)用函數(shù)中知道主調(diào)函數(shù)所傳遞的數(shù)組大小,我為了能在被調(diào)用函數(shù)中知道主調(diào)函數(shù)所傳遞的數(shù)組大小,我們通常另設(shè)一個(gè)參數(shù)(們通常另設(shè)一個(gè)參數(shù)(int 變量),傳遞數(shù)組元素的個(gè)數(shù)。變量),傳遞數(shù)組元素的個(gè)數(shù)。 參見(jiàn)參見(jiàn)P166 例
40、例8.12 。 5)實(shí)參和形參數(shù)組將共占同一段內(nèi)存單元,如果形參數(shù)組中的實(shí)參和形參數(shù)組將共占同一段內(nèi)存單元,如果形參數(shù)組中的元素發(fā)生變化會(huì)使實(shí)參數(shù)組中的元素發(fā)生相同的變化。元素發(fā)生變化會(huì)使實(shí)參數(shù)組中的元素發(fā)生相同的變化。例例7.12(P196)用選擇法對(duì)數(shù)組中用選擇法對(duì)數(shù)組中10個(gè)整數(shù)按由小到大排序。個(gè)整數(shù)按由小到大排序。選擇法介紹:選擇法介紹:1)將)將10個(gè)數(shù)進(jìn)行相互比較,找出最小數(shù),將之與個(gè)數(shù)進(jìn)行相互比較,找出最小數(shù),將之與a0對(duì)換;對(duì)換;2)再將)再將a1到到a9的數(shù)進(jìn)行比較,找出最小數(shù),將之與的數(shù)進(jìn)行比較,找出最小數(shù),將之與a1對(duì)對(duì)換;換;3),共比較,共比較9輪,最后得到排序后的結(jié)
41、果;輪,最后得到排序后的結(jié)果;以以5個(gè)數(shù)為例說(shuō)明:個(gè)數(shù)為例說(shuō)明:a0 a1 a2 a3 a4 3 6 1 9 4 未排序時(shí)的情況未排序時(shí)的情況 1 6 3 9 4 將將5個(gè)數(shù)中最小數(shù)個(gè)數(shù)中最小數(shù)1與與a0對(duì)換對(duì)換 1 3 6 9 4 將余下的將余下的4個(gè)數(shù)中最小數(shù)個(gè)數(shù)中最小數(shù)3與與a1對(duì)換對(duì)換 1 3 4 9 6 將余下的將余下的3個(gè)數(shù)中最小數(shù)個(gè)數(shù)中最小數(shù)4與與a2對(duì)換對(duì)換 1 3 4 6 9 將余下的將余下的2個(gè)數(shù)中最小數(shù)個(gè)數(shù)中最小數(shù)6與與a3對(duì)換,對(duì)換,至此完成排序至此完成排序選擇法排序圖示選擇法排序圖示i=00n-1i n-1j=i+1j n 此法共比較此法共比較n-1趟,每趟共比較趟,
42、每趟共比較n-1-i 次,每趟最多次,每趟最多交換交換1 次,總共最多交換次,總共最多交換n-1次。次。標(biāo)記變量標(biāo)記變量k=j:記住每趟中最小的一個(gè)數(shù)的下標(biāo)。:記住每趟中最小的一個(gè)數(shù)的下標(biāo)。源程序(一):不用函數(shù)調(diào)用實(shí)現(xiàn),程序演示源程序(一):不用函數(shù)調(diào)用實(shí)現(xiàn),程序演示P181.c#include main () int a10,n=10,i,j,k,t;printf(enter the arrayn);for(i=0;i10;i+)scanf(%d,&ai);for(i=0;in-1;i+) k=i; for(j=i+1;j aj) k=j; t=ak;ak=ai;ai=t; pri
43、ntf(the sorted array:n);for(i=0;i10;i+) printf(%5d,ai);printf(n);void sort(int array ,int n)int i,j,k,t;for(i=0;in-1;i+) k=i; for(j=i+1;j arrayj) k=j; t=arrayk;arrayk=arrayi;arrayi=t; main () int a10,i; printf(“enter the arrayn”); for(i=0;i10;i+) scanf(“%d”,&ai); sort(a,10); printf(the sorted ar
44、ray:n); for(i=0;i10;i+)printf(“%d”,ai); printf(“n”);源程序(二):用函數(shù)調(diào)用實(shí)現(xiàn)源程序(二):用函數(shù)調(diào)用實(shí)現(xiàn)P182.c標(biāo)記變量標(biāo)記變量k用于記用于記住每趟最小數(shù)的位住每趟最小數(shù)的位置,初始值為每趟置,初始值為每趟的起始位置的起始位置外循環(huán)變量外循環(huán)變量i 用于記住用于記住每趟的起始位置每趟的起始位置,初始,初始值為第一個(gè)數(shù)的位置。值為第一個(gè)數(shù)的位置。冒泡法排序圖示(注意區(qū)別)冒泡法排序圖示(注意區(qū)別)i=00n-1i n-1j=0j n-1-i用外循環(huán)變量用外循環(huán)變量i (0= i n-1 )來(lái)來(lái)控制比較的趟次控制比較的趟次,即第幾趟,即第
45、幾趟(共共n-1趟趟) 。同時(shí),。同時(shí),i 的不斷變化也修改了內(nèi)循環(huán)變量的不斷變化也修改了內(nèi)循環(huán)變量j 的終止條件,即的終止條件,即每趟需要比較的次數(shù)每趟需要比較的次數(shù)(n-1-i), 也是也是每趟最多可能交換的次數(shù)每趟最多可能交換的次數(shù)。注意:注意: P124中是用中是用1= i b?a:b;return(c);main( ) int a=8;printf(“%d”,max(a,b);結(jié)果為:結(jié)果為:8a,b為全局變量a,b為局部變量形參a,b作用范圍全局變量b作用范圍局部變量a作用范圍7.9 變量的存儲(chǔ)類(lèi)別變量的存儲(chǔ)類(lèi)別7.9.1 動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式 前面
46、,我們從變量的作用域角度把變量分為全局變量和前面,我們從變量的作用域角度把變量分為全局變量和局部變量。這里,我們將從變量值存在的時(shí)間(生存期)角局部變量。這里,我們將從變量值存在的時(shí)間(生存期)角度來(lái)分,可分為靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式。度來(lái)分,可分為靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式。 所謂所謂靜態(tài)存儲(chǔ)方式靜態(tài)存儲(chǔ)方式是指是指在程序運(yùn)行期間分配固定的存儲(chǔ)在程序運(yùn)行期間分配固定的存儲(chǔ)空間的方式空間的方式,而,而動(dòng)態(tài)存儲(chǔ)方式動(dòng)態(tài)存儲(chǔ)方式則是則是在程序運(yùn)行期間根據(jù)需要在程序運(yùn)行期間根據(jù)需要進(jìn)行動(dòng)態(tài)分配存儲(chǔ)空間的方式進(jìn)行動(dòng)態(tài)分配存儲(chǔ)空間的方式。 關(guān)于程序內(nèi)存空間的劃分,教材內(nèi)容比較簡(jiǎn)略且陳舊,關(guān)于程序內(nèi)存空
47、間的劃分,教材內(nèi)容比較簡(jiǎn)略且陳舊,下面將作一些補(bǔ)充。下面將作一些補(bǔ)充。補(bǔ)充:關(guān)于程序的內(nèi)存區(qū)域補(bǔ)充:關(guān)于程序的內(nèi)存區(qū)域 我們知道,變量具有全局和局部、靜態(tài)和動(dòng)態(tài)之分,要我們知道,變量具有全局和局部、靜態(tài)和動(dòng)態(tài)之分,要徹底了解變量的這些屬性,我們需要深入地理解程序在內(nèi)存徹底了解變量的這些屬性,我們需要深入地理解程序在內(nèi)存中的分布區(qū)域。一個(gè)用戶(hù)程序?qū)⒉僮飨到y(tǒng)分配給其運(yùn)行的內(nèi)中的分布區(qū)域。一個(gè)用戶(hù)程序?qū)⒉僮飨到y(tǒng)分配給其運(yùn)行的內(nèi)存塊又分為存塊又分為4個(gè)區(qū)域:個(gè)區(qū)域:1)代碼區(qū),存放的是)代碼區(qū),存放的是程序代碼程序代碼,即程序中的各個(gè)函數(shù)代碼塊。即程序中的各個(gè)函數(shù)代碼塊。2)全局?jǐn)?shù)據(jù)區(qū),存放程序的)全
48、局?jǐn)?shù)據(jù)區(qū),存放程序的全局全局?jǐn)?shù)據(jù)數(shù)據(jù)、靜態(tài)數(shù)據(jù)靜態(tài)數(shù)據(jù)和和常量常量。3)堆區(qū),存放程序的動(dòng)態(tài)數(shù)據(jù)。)堆區(qū),存放程序的動(dòng)態(tài)數(shù)據(jù)。4)棧區(qū),存放程序的局部數(shù)據(jù),)棧區(qū),存放程序的局部數(shù)據(jù),即即各個(gè)函數(shù)中的數(shù)據(jù)各個(gè)函數(shù)中的數(shù)據(jù)。代碼區(qū)代碼區(qū)(code area)全局?jǐn)?shù)據(jù)區(qū)全局?jǐn)?shù)據(jù)區(qū)(data area)堆區(qū)堆區(qū)(heap area)程序內(nèi)存空間程序內(nèi)存空間棧區(qū)棧區(qū)(stack area)低高對(duì)用戶(hù)程序數(shù)據(jù)區(qū)的具體說(shuō)明:對(duì)用戶(hù)程序數(shù)據(jù)區(qū)的具體說(shuō)明:1)全局?jǐn)?shù)據(jù)區(qū)全局?jǐn)?shù)據(jù)區(qū)(教材中稱(chēng)靜態(tài)存儲(chǔ)區(qū))(教材中稱(chēng)靜態(tài)存儲(chǔ)區(qū))中的數(shù)據(jù),是在程序中的數(shù)據(jù),是在程序開(kāi)始執(zhí)行時(shí)就分配存儲(chǔ)空間,直到程序執(zhí)行完畢才釋放空開(kāi)
49、始執(zhí)行時(shí)就分配存儲(chǔ)空間,直到程序執(zhí)行完畢才釋放空間。在程序的執(zhí)行過(guò)程中,它們始終占據(jù)固定的存儲(chǔ)單元。間。在程序的執(zhí)行過(guò)程中,它們始終占據(jù)固定的存儲(chǔ)單元。2)棧區(qū)棧區(qū)中存放的數(shù)據(jù)有以下三種:中存放的數(shù)據(jù)有以下三種: 函數(shù)的形參函數(shù)的形參; 函數(shù)中函數(shù)中定義的自動(dòng)變量定義的自動(dòng)變量(未加(未加static聲明的局部變量);聲明的局部變量); 函數(shù)調(diào)函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)保用時(shí)的現(xiàn)場(chǎng)保 護(hù)和返回地址護(hù)和返回地址等。等。 對(duì)于以上數(shù)據(jù),都是在函數(shù)調(diào)用開(kāi)始時(shí)才分配相應(yīng)的對(duì)于以上數(shù)據(jù),都是在函數(shù)調(diào)用開(kāi)始時(shí)才分配相應(yīng)的存儲(chǔ)空間,當(dāng)函數(shù)結(jié)束時(shí)便釋放這些空間。在程序執(zhí)行過(guò)存儲(chǔ)空間,當(dāng)函數(shù)結(jié)束時(shí)便釋放這些空間。在程序執(zhí)
50、行過(guò)程中,這種分配和釋放是動(dòng)態(tài)的。程中,這種分配和釋放是動(dòng)態(tài)的。3)堆區(qū)堆區(qū)中的數(shù)據(jù),是在程序運(yùn)行過(guò)程由用戶(hù)臨時(shí)開(kāi)辟或收回中的數(shù)據(jù),是在程序運(yùn)行過(guò)程由用戶(hù)臨時(shí)開(kāi)辟或收回的。的。C語(yǔ)言提供語(yǔ)言提供void * malloc(size_t)和和void free(void *)兩個(gè)兩個(gè)函數(shù)函數(shù)來(lái)完成此任務(wù);來(lái)完成此任務(wù);C+中還提供中還提供new 和和delete 兩個(gè)操作符兩個(gè)操作符來(lái)實(shí)現(xiàn)。來(lái)實(shí)現(xiàn)。 (棧區(qū)和堆區(qū)對(duì)應(yīng)教材中的動(dòng)態(tài)存儲(chǔ)區(qū))(棧區(qū)和堆區(qū)對(duì)應(yīng)教材中的動(dòng)態(tài)存儲(chǔ)區(qū))在在C語(yǔ)言中,定義一個(gè)語(yǔ)言中,定義一個(gè)變量變量時(shí),需要考慮兩個(gè)基本屬性:時(shí),需要考慮兩個(gè)基本屬性:數(shù)據(jù)類(lèi)型數(shù)據(jù)類(lèi)型和和數(shù)據(jù)存儲(chǔ)
51、類(lèi)別數(shù)據(jù)存儲(chǔ)類(lèi)別。存儲(chǔ)類(lèi)別指明了數(shù)據(jù)在內(nèi)存中。存儲(chǔ)類(lèi)別指明了數(shù)據(jù)在內(nèi)存中存儲(chǔ)的地方存儲(chǔ)的地方(哪個(gè)區(qū)哪個(gè)區(qū))。對(duì)于變量,我們可以根據(jù)它的存儲(chǔ)。對(duì)于變量,我們可以根據(jù)它的存儲(chǔ)類(lèi)別知道它的類(lèi)別知道它的生存期生存期。至此,我們?cè)诔绦蛟O(shè)計(jì)中使用一個(gè)。至此,我們?cè)诔绦蛟O(shè)計(jì)中使用一個(gè)變量時(shí),必須還要清楚該變量的如下三點(diǎn)信息:變量時(shí),必須還要清楚該變量的如下三點(diǎn)信息:以上三點(diǎn)信息以上三點(diǎn)信息都是在定義該變量時(shí)明確指定的都是在定義該變量時(shí)明確指定的。變量變量數(shù)據(jù)類(lèi)型數(shù)據(jù)類(lèi)型作用域作用域存儲(chǔ)類(lèi)別具體包含以下四種存儲(chǔ)類(lèi)別:存儲(chǔ)類(lèi)別具體包含以下四種存儲(chǔ)類(lèi)別:1. auto變量變量 函數(shù)中的局部變量,如不專(zhuān)門(mén)聲明為函
52、數(shù)中的局部變量,如不專(zhuān)門(mén)聲明為static存儲(chǔ)類(lèi)別,都存儲(chǔ)類(lèi)別,都是動(dòng)態(tài)分配存儲(chǔ)空間的,是動(dòng)態(tài)分配存儲(chǔ)空間的, 數(shù)據(jù)存儲(chǔ)在棧區(qū)中,在函數(shù)調(diào)用結(jié)數(shù)據(jù)存儲(chǔ)在棧區(qū)中,在函數(shù)調(diào)用結(jié)束時(shí)就自動(dòng)釋放這些存儲(chǔ)空間,因此束時(shí)就自動(dòng)釋放這些存儲(chǔ)空間,因此這類(lèi)局部變量稱(chēng)為這類(lèi)局部變量稱(chēng)為自動(dòng)變自動(dòng)變量量。自動(dòng)變量用關(guān)鍵字。自動(dòng)變量用關(guān)鍵字auto作存儲(chǔ)類(lèi)別的聲明。例如:作存儲(chǔ)類(lèi)別的聲明。例如: int f (int a) /* 定義定義f 函數(shù),函數(shù),a為形參為形參*/ auto int b,c=3 /* 定義定義b,c為自動(dòng)變量為自動(dòng)變量 */ 實(shí)際上,關(guān)鍵字實(shí)際上,關(guān)鍵字“auto”可以省略,可以省略,aut
53、o不寫(xiě)則隱含確定不寫(xiě)則隱含確定為為“自動(dòng)存儲(chǔ)類(lèi)別自動(dòng)存儲(chǔ)類(lèi)別” 。程序中大多數(shù)變量屬于自動(dòng)變量。我。程序中大多數(shù)變量屬于自動(dòng)變量。我們前面介紹的函數(shù)中定義的變量都沒(méi)有聲明為們前面介紹的函數(shù)中定義的變量都沒(méi)有聲明為auto,其實(shí)都隱,其實(shí)都隱含指自動(dòng)變量。含指自動(dòng)變量。7.9.2 局部變量的存儲(chǔ)類(lèi)別局部變量的存儲(chǔ)類(lèi)別 有時(shí)希望函數(shù)中的局部變量的值在有時(shí)希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保函數(shù)調(diào)用結(jié)束后不消失而保留原值留原值,即其占用的存儲(chǔ)單元不釋放,在下一次該函數(shù)調(diào)用時(shí),該,即其占用的存儲(chǔ)單元不釋放,在下一次該函數(shù)調(diào)用時(shí),該變量已有值,就是上一次函數(shù)調(diào)用結(jié)束時(shí)的值。這時(shí)就應(yīng)該指定該
54、變量已有值,就是上一次函數(shù)調(diào)用結(jié)束時(shí)的值。這時(shí)就應(yīng)該指定該局部變量為局部變量為“靜態(tài)局部變量靜態(tài)局部變量”,用關(guān)鍵字,用關(guān)鍵字static進(jìn)行存儲(chǔ)類(lèi)別的聲明。進(jìn)行存儲(chǔ)類(lèi)別的聲明。例例7.16(P205)f (int a) auto b=0; static c=3; /* 在以上兩條定義語(yǔ)句中僅在以上兩條定義語(yǔ)句中僅int型可以省略型可以省略*/ b=b+1; /* 每次調(diào)用每次調(diào)用f 函數(shù)執(zhí)行此語(yǔ)句,函數(shù)執(zhí)行此語(yǔ)句,b均為均為1 */ c=c+1; /* 第一次調(diào)用后第一次調(diào)用后c 等于等于4,第二次后為,第二次后為5 */ return(a+b+c);main ( ) int a=2,i;
55、for(i=0;i3;i+) printf(“%d ”,f(a);2. static局部變量局部變量運(yùn)行結(jié)果為:運(yùn)行結(jié)果為:7 8 9等價(jià)于:等價(jià)于:auto b; b=0;不等于:不等于:static c; c=3;說(shuō)明:說(shuō)明:1)靜態(tài)局部變量屬于靜態(tài)存儲(chǔ)類(lèi)別,在全局?jǐn)?shù)據(jù)區(qū)內(nèi)分配存靜態(tài)局部變量屬于靜態(tài)存儲(chǔ)類(lèi)別,在全局?jǐn)?shù)據(jù)區(qū)內(nèi)分配存儲(chǔ)單元,在程序整個(gè)運(yùn)行期間都不釋放。儲(chǔ)單元,在程序整個(gè)運(yùn)行期間都不釋放。2)對(duì)對(duì)靜態(tài)局部變量靜態(tài)局部變量是在是在編譯時(shí)進(jìn)行初始化編譯時(shí)進(jìn)行初始化的,在程序運(yùn)行時(shí)的,在程序運(yùn)行時(shí)它已有初值,以后每次調(diào)用函數(shù)時(shí)不再重新初始化而只它已有初值,以后每次調(diào)用函數(shù)時(shí)不再重新初始
56、化而只是保留上次函數(shù)調(diào)用結(jié)束時(shí)的值。而對(duì)是保留上次函數(shù)調(diào)用結(jié)束時(shí)的值。而對(duì)自動(dòng)變量的初始自動(dòng)變量的初始化化,不是在編譯時(shí)進(jìn)行,而是,不是在編譯時(shí)進(jìn)行,而是在函數(shù)調(diào)用時(shí)進(jìn)行在函數(shù)調(diào)用時(shí)進(jìn)行,每調(diào),每調(diào)用一次函數(shù)就重新賦一次初值,相當(dāng)于執(zhí)行一次賦值語(yǔ)用一次函數(shù)就重新賦一次初值,相當(dāng)于執(zhí)行一次賦值語(yǔ)句。因此,自動(dòng)變量的句。因此,自動(dòng)變量的初始化初始化與與賦初值賦初值是相同的。是相同的。3)如在定義局部變量時(shí)不進(jìn)行初始化,對(duì)如在定義局部變量時(shí)不進(jìn)行初始化,對(duì)靜態(tài)局部變量靜態(tài)局部變量,編,編譯時(shí)會(huì)自動(dòng)初始化為譯時(shí)會(huì)自動(dòng)初始化為0(對(duì)數(shù)值型變量對(duì)數(shù)值型變量)或或空字符空字符(對(duì)字符變對(duì)字符變量量)。而對(duì)。
57、而對(duì)自動(dòng)變量自動(dòng)變量來(lái)說(shuō),如果不進(jìn)行初始化則它的值是來(lái)說(shuō),如果不進(jìn)行初始化則它的值是一個(gè)一個(gè)不確定的值不確定的值。4)雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其它函雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其它函數(shù)是不能引用它的,即其它函數(shù)不在其作用域內(nèi),稱(chēng)為數(shù)是不能引用它的,即其它函數(shù)不在其作用域內(nèi),稱(chēng)為“不可見(jiàn)不可見(jiàn)”。一般在以下情況下使用局部靜態(tài)變量:。一般在以下情況下使用局部靜態(tài)變量: (1)需要保留函數(shù)上一次調(diào)用結(jié)束時(shí)的值。需要保留函數(shù)上一次調(diào)用結(jié)束時(shí)的值。 (2)如果初始化后,變量只被引用而不改變其值,則這如果初始化后,變量只被引用而不改變其值,則這時(shí)用靜態(tài)局部變量比較方便,
58、以免每次調(diào)用時(shí)重新賦值。時(shí)用靜態(tài)局部變量比較方便,以免每次調(diào)用時(shí)重新賦值。 但是應(yīng)該看到,用靜態(tài)存儲(chǔ)但是應(yīng)該看到,用靜態(tài)存儲(chǔ)要多占內(nèi)存要多占內(nèi)存(長(zhǎng)期占用不(長(zhǎng)期占用不釋放,而不能像動(dòng)態(tài)存儲(chǔ)那樣一個(gè)存儲(chǔ)單元可供多個(gè)變量釋放,而不能像動(dòng)態(tài)存儲(chǔ)那樣一個(gè)存儲(chǔ)單元可供多個(gè)變量使用,節(jié)約內(nèi)存空間),而且使用,節(jié)約內(nèi)存空間),而且降低了程序的可讀性降低了程序的可讀性,當(dāng)調(diào),當(dāng)調(diào)用次數(shù)多時(shí)往往弄不清靜態(tài)局部變量的當(dāng)前值是什么。因用次數(shù)多時(shí)往往弄不清靜態(tài)局部變量的當(dāng)前值是什么。因此,此,如不十分必要,就不要采用靜態(tài)局部變量如不十分必要,就不要采用靜態(tài)局部變量。3. register變量變量 一般情況下,一般情
59、況下,變量變量(包括靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式)(包括靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式)的值是的值是存放在內(nèi)存中的存放在內(nèi)存中的,當(dāng)程,當(dāng)程 序中用到哪一個(gè)變量的值時(shí),序中用到哪一個(gè)變量的值時(shí),由控制器發(fā)出指令將內(nèi)存中該變量的值送到運(yùn)算器中。經(jīng)過(guò)運(yùn)由控制器發(fā)出指令將內(nèi)存中該變量的值送到運(yùn)算器中。經(jīng)過(guò)運(yùn)算器進(jìn)行運(yùn)算,如果需要保存數(shù)據(jù),再?gòu)倪\(yùn)算器將數(shù)據(jù)送到內(nèi)算器進(jìn)行運(yùn)算,如果需要保存數(shù)據(jù),再?gòu)倪\(yùn)算器將數(shù)據(jù)送到內(nèi)存中存放。存中存放。 如果有一些變量使用十分頻繁,則從內(nèi)存中存取數(shù)據(jù)將花如果有一些變量使用十分頻繁,則從內(nèi)存中存取數(shù)據(jù)將花費(fèi)較多時(shí)間。為了提高執(zhí)行效率,費(fèi)較多時(shí)間。為了提高執(zhí)行效率,C語(yǔ)言允許將局
60、部變量的值語(yǔ)言允許將局部變量的值放在放在CPU中的寄存器中中的寄存器中。由于對(duì)寄存器的存取速度遠(yuǎn)高于對(duì)。由于對(duì)寄存器的存取速度遠(yuǎn)高于對(duì)內(nèi)存的存取速度,因此這樣就可以提高執(zhí)行效率。這種變量叫內(nèi)存的存取速度,因此這樣就可以提高執(zhí)行效率。這種變量叫做做“寄存器變量寄存器變量”,用關(guān)鍵字,用關(guān)鍵字register作聲明。作聲明。內(nèi)存內(nèi)存CPU總總線(xiàn)線(xiàn)運(yùn)算器運(yùn)算器控制器控制器寄存器寄存器例例7.17(P207)輸出)輸出1到到5的階乘。書(shū)上使用靜態(tài)變量實(shí)現(xiàn)的。的階乘。書(shū)上使用靜態(tài)變量實(shí)現(xiàn)的。下面,使用寄存器變量實(shí)現(xiàn)。下面,使用寄存器變量實(shí)現(xiàn)。int fac(int n)register int i,f=1;for(i=1;i=n;i+)f=f*i;return(f);main ( )int
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 城市綠化帶道路施工方案
- 農(nóng)業(yè)監(jiān)控視頻系統(tǒng)方案
- 隧道施工消防安全演練方案
- 采礦權(quán)轉(zhuǎn)讓合同的談判技巧
- 村莊土培房拆除合同(2篇)
- 電力管道工程竣工驗(yàn)收方案
- 建筑工程施工設(shè)計(jì)方案及安全措施方案
- 醫(yī)院急救藥品采購(gòu)管理制度
- 工程施工合同(2篇)
- 運(yùn)動(dòng)中心塑膠跑道施工流程方案
- 北京市道德與法治初一上學(xué)期期中試卷及答案指導(dǎo)(2024年)
- 高校實(shí)驗(yàn)室安全基礎(chǔ)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 四川省綿陽(yáng)市高中2025屆高三一診考試物理試卷含解析
- 第五章 種內(nèi)與種間關(guān)系
- 飛利浦16排螺旋CT機(jī)操作規(guī)程(1)
- 油菜品種田間記載項(xiàng)目與標(biāo)準(zhǔn)
- 渣土車(chē)輛駕駛員管理制度
- 德力西系列變頻器說(shuō)明書(shū)
- 后疫情時(shí)代探索家校共育新模式維護(hù)學(xué)生心理健康
- 小學(xué)美術(shù)11-身邊的伙伴ppt課件
- 鐵合金生產(chǎn)工藝
評(píng)論
0/150
提交評(píng)論