C語言程序設計_07章 函數(shù)_第1頁
C語言程序設計_07章 函數(shù)_第2頁
C語言程序設計_07章 函數(shù)_第3頁
C語言程序設計_07章 函數(shù)_第4頁
C語言程序設計_07章 函數(shù)_第5頁
已閱讀5頁,還剩71頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第七章第七章函函數(shù)數(shù)7.1 概述概述 在在C語言里,語言里,函數(shù)函數(shù)(Function)是指是指實現(xiàn)一個特定功能的程序實現(xiàn)一個特定功能的程序模塊模塊。用戶可以根據(jù)自己程序設計的需要,劃分出不同的功能。用戶可以根據(jù)自己程序設計的需要,劃分出不同的功能模塊,再將這些功能模塊定義為相應的函數(shù),這種由用戶自己模塊,再將這些功能模塊定義為相應的函數(shù),這種由用戶自己所定義的函數(shù),稱為所定義的函數(shù),稱為“用戶自定義函數(shù)用戶自定義函數(shù)”。在集成開發(fā)環(huán)境中,也總是將一些常用的功能模塊編寫成在集成開發(fā)環(huán)境中,也總是將一些常用的功能模塊編寫成函數(shù),放在函數(shù)庫中供公共選用,這些函數(shù)稱為函數(shù),放在函數(shù)庫中供公共選用,這

2、些函數(shù)稱為“庫函數(shù)庫函數(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ù)的調用(演示函數(shù)的調用(演示P143.c)#include “stdlib.h” / VC6.0中使用中使用main ( ) printstar ( ); print_message ( ); printstar ( );printstar ( ) printf(“*n ”);print_message ( )printf(“How do you do!n”);進一步體會進

3、一步體會step over和和step into的區(qū)別。的區(qū)別。說明說明:1) 一個一個C源程序文件源程序文件可以由一個或多個可以由一個或多個函數(shù)函數(shù)組成。一個源程序文件組成。一個源程序文件就是一個編譯單位,而函數(shù)不是編譯單位。就是一個編譯單位,而函數(shù)不是編譯單位。2) 一個一個C程序程序由由一個主函數(shù)一個主函數(shù)和和若干個一般函數(shù)若干個一般函數(shù)構成,其中主函數(shù)是構成,其中主函數(shù)是不可缺省的。每個不可缺省的。每個C程序都是由主函數(shù)去調用其他函數(shù),其他函數(shù)程序都是由主函數(shù)去調用其他函數(shù),其他函數(shù)又可相互調用。又可相互調用。 3) 一個一個C程序程序由由一個或多個源程序文件一個或多個源程序文件組成。

4、對于較大的組成。對于較大的C程序,程序,通常將一些函數(shù)和其他內容分別放在若干源文件中,再由若干源通常將一些函數(shù)和其他內容分別放在若干源文件中,再由若干源文件組成一個文件組成一個C程序。最簡單的情況,一個程序。最簡單的情況,一個C程序由一個源程序文程序由一個源程序文件組成,這個源程序文件中只包含了一個函數(shù)(主函數(shù))。件組成,這個源程序文件中只包含了一個函數(shù)(主函數(shù))。4) C程序的執(zhí)行是程序的執(zhí)行是從從main函數(shù)開始函數(shù)開始,調用其它函數(shù)后流程又回到,調用其它函數(shù)后流程又回到main函數(shù),函數(shù),在在main函數(shù)中結束函數(shù)中結束整個程序的運行。整個程序的運行。main函數(shù)是由系函數(shù)是由系統(tǒng)定義的

5、,是一個特殊的函數(shù)。統(tǒng)定義的,是一個特殊的函數(shù)。5) 所有函數(shù)在定義時是相互獨立的,函數(shù)之間所有函數(shù)在定義時是相互獨立的,函數(shù)之間可以相互調用可以相互調用。函數(shù)的分類函數(shù)的分類:1) 從從用戶使用的角度用戶使用的角度函數(shù)可分為函數(shù)可分為: 標準函數(shù)標準函數(shù),即,即庫函數(shù)庫函數(shù)。由系統(tǒng)提供,用戶不必定義,。由系統(tǒng)提供,用戶不必定義,直接使用直接使用; 用戶自定義函數(shù)用戶自定義函數(shù)。由用戶根據(jù)需要,自行編寫,以解。由用戶根據(jù)需要,自行編寫,以解決專門需要。決專門需要。2) 從從函數(shù)的形式函數(shù)的形式分,函數(shù)可分為:分,函數(shù)可分為: 無參數(shù)函數(shù)無參數(shù)函數(shù)。在調用無參函數(shù)時,主函數(shù)并不將數(shù)據(jù)。在調用無參

6、函數(shù)時,主函數(shù)并不將數(shù)據(jù)傳送給被調用函數(shù),一般用來執(zhí)行指定的一組操作。傳送給被調用函數(shù),一般用來執(zhí)行指定的一組操作。無參函數(shù)可以帶回也可以不帶回函數(shù)值,一般以后者無參函數(shù)可以帶回也可以不帶回函數(shù)值,一般以后者居多;居多; 有參函數(shù)有參函數(shù)。在調用函數(shù)時,在主函數(shù)和被調用函數(shù)之。在調用函數(shù)時,在主函數(shù)和被調用函數(shù)之間有數(shù)據(jù)傳遞。間有數(shù)據(jù)傳遞。7.2 定義一個函數(shù)定義一個函數(shù)1. 無參函數(shù)的定義形式無參函數(shù)的定義形式類型標識符類型標識符函數(shù)名函數(shù)名 ( ) 聲明部分聲明部分語句語句 其中,用其中,用“類型標識符類型標識符”指定函數(shù)值的類型,即函指定函數(shù)值的類型,即函數(shù)返回值的類型。無參函數(shù)一般不需

7、要帶回函數(shù)值,因數(shù)返回值的類型。無參函數(shù)一般不需要帶回函數(shù)值,因此可以不寫類型標識符。此可以不寫類型標識符。2. 有參函數(shù)的定義形式有參函數(shù)的定義形式類型標識符類型標識符函數(shù)名函數(shù)名 ( 形式參數(shù)表列形式參數(shù)表列 ) 聲明部分聲明部分語句語句例如例如:int max(int x, int y) int z; z=xy?x:y; return(z);說明:說明:1)return(z)的作用是將的作用是將z的值作為函數(shù)值返回到主函數(shù)中,的值作為函數(shù)值返回到主函數(shù)中,這個值稱為這個值稱為“函數(shù)返回值函數(shù)返回值”。注意返回值的類型要和。注意返回值的類型要和定義函數(shù)的定義函數(shù)的“類型標識符類型標識符”一

8、致。一致。2)如果在定義函數(shù)時)如果在定義函數(shù)時不指定函數(shù)類型不指定函數(shù)類型,系統(tǒng)會隱含指定,系統(tǒng)會隱含指定函數(shù)類型為函數(shù)類型為int 型型。3. 空函數(shù)空函數(shù)的定義形式的定義形式類型說明符類型說明符 函數(shù)名函數(shù)名( ) 例如例如: dummy( ) 說明:說明:1)調用此函數(shù)時,什么工作也不做,沒有任何實際作用。)調用此函數(shù)時,什么工作也不做,沒有任何實際作用。2)空函數(shù)的使用一般用于程序設計的模塊設計階段。表示)空函數(shù)的使用一般用于程序設計的模塊設計階段。表示這是一個待完成的函數(shù),但不影響當前程序的運行。這是一個待完成的函數(shù),但不影響當前程序的運行。4. 對形參進行聲明的方式(在對形參進行

9、聲明的方式(在1.3節(jié)中已講)節(jié)中已講) C語言傳統(tǒng)聲明方式為:對形參類型的聲明放在函數(shù)語言傳統(tǒng)聲明方式為:對形參類型的聲明放在函數(shù)定義的第定義的第2行,在函數(shù)括號外單獨指定。行,在函數(shù)括號外單獨指定。傳統(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ù)名后面括號中的

10、變量名稱為在定義函數(shù)時,函數(shù)名后面括號中的變量名稱為“形式參形式參數(shù)數(shù)” (簡稱(簡稱“形參形參”)。在主調函數(shù)中調用一個函數(shù)時,函數(shù))。在主調函數(shù)中調用一個函數(shù)時,函數(shù)名后面括弧中的參數(shù)(也可是一個表達式)稱為名后面括弧中的參數(shù)(也可是一個表達式)稱為“實際參數(shù)實際參數(shù)”(簡稱(簡稱“實參實參”)。)。例例7.2(P176)調用函數(shù)時的數(shù)據(jù)傳遞)調用函數(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);運行情況如下運行情況如下:7,8Max is 8實參實參a,b形參形參x,y關于形參和實參的說明關于形參和實參的說明1) 在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調用時,它們并在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調用時,它們并不占據(jù)內存單元。只有在發(fā)生函數(shù)調用時,不占據(jù)內存單元。只有在發(fā)生函數(shù)調用時, max函數(shù)中的函數(shù)中的形參才被分配內存單元。在調用結束后,形參所占的內存形參才被分配內存單元。在調用結束后,形參所占的內存單元也被釋放。單元也被釋放。2) 實參可以是常量、變量、表達式、函數(shù)。如:實參可以是常量、變量、表達式、函數(shù)。如:max(3,a+b)但要

12、求它要有一個但要求它要有一個確定的值確定的值。在調用時將實參的值賦給形。在調用時將實參的值賦給形參(如果實參是一個表達式或函數(shù),則需要參(如果實參是一個表達式或函數(shù),則需要先求解出實參先求解出實參的值的值)。)。3) 在被定義的函數(shù)中,必須指定形參的類型。在被定義的函數(shù)中,必須指定形參的類型。4) 實參和形參的類型應實參和形參的類型應相同相同或或賦值兼容賦值兼容,否則會出錯。,否則會出錯。5) C語言規(guī)定,實參與形參之間的數(shù)據(jù)傳遞遵守語言規(guī)定,實參與形參之間的數(shù)據(jù)傳遞遵守“單向值傳單向值傳遞遞”的原則,即只能由實參傳給形參,而不能由形參反過的原則,即只能由實參傳給形參,而不能由形參反過來傳給實

13、參。來傳給實參。說明說明: 1) 如果需要從被調函數(shù)帶回一個函數(shù)值,供主調函數(shù)使用,如果需要從被調函數(shù)帶回一個函數(shù)值,供主調函數(shù)使用,則被調函數(shù)中必須包含則被調函數(shù)中必須包含return語句語句。 2) 一個函數(shù)中可以有一個函數(shù)中可以有一個以上一個以上的的return語句,但只有一個語句,但只有一個return語句被執(zhí)行。語句被執(zhí)行。 3) return語句后的括弧可以不要。例如:語句后的括弧可以不要。例如: return z; 和和 return(z); 是等效的。是等效的。 4) 函數(shù)的返回值類型由函數(shù)定義時的說明類型決定,函數(shù)的返回值類型由函數(shù)定義時的說明類型決定,return語句中的表

14、達式類型一般應與之一致。如果不一致,對數(shù)語句中的表達式類型一般應與之一致。如果不一致,對數(shù)值型數(shù)據(jù),系統(tǒng)會自動進行類型轉換。值型數(shù)據(jù),系統(tǒng)會自動進行類型轉換。7.3.2 函數(shù)的返回值函數(shù)的返回值 通過函數(shù)調用使主調函數(shù)得到一個確定的值,這個值就是通過函數(shù)調用使主調函數(shù)得到一個確定的值,這個值就是函數(shù)的返回值。例如例函數(shù)的返回值。例如例8.2。 5) 如果不需要返回值,則被調函數(shù)中可以不要如果不需要返回值,則被調函數(shù)中可以不要return語句,但此語句,但此時并不是沒有返回值,而是返回了時并不是沒有返回值,而是返回了一個不確定的值一個不確定的值,C語言也語言也允許用戶把該值賦給一個變量。允許用戶

15、把該值賦給一個變量。 6) 如果用戶要明確表示如果用戶要明確表示“不要返回值不要返回值”,則可定義被調函數(shù)類型,則可定義被調函數(shù)類型為為void(空類型)(空類型)。 例如:例例如:例8.1中的定義可以改為中的定義可以改為: void printstar( ) void print_message( ) 這樣,被調函數(shù)就不會返回任何值,系統(tǒng)會禁止在主調函數(shù)這樣,被調函數(shù)就不會返回任何值,系統(tǒng)會禁止在主調函數(shù)中使用被調函數(shù)的返回值。中使用被調函數(shù)的返回值。 例如:例如: a=printfstar( ); b=print_message( ); 是不合法的。是不合法的。7.4 函數(shù)的調用函數(shù)的調用

16、7.4.1 函數(shù)調用的一般形式函數(shù)調用的一般形式 函數(shù)調用的一般形式為函數(shù)調用的一般形式為: 函數(shù)名函數(shù)名 ( 實參表列實參表列 ) 說明說明: 1) 如果是調用無參函數(shù),則如果是調用無參函數(shù),則“實參表列實參表列”可以沒有,可以沒有,但括弧不能省略。但括弧不能省略。 2) 如果有多個實參,則各參數(shù)間用如果有多個實參,則各參數(shù)間用逗號隔開逗號隔開,實參與,實參與形參的形參的個數(shù)應相等個數(shù)應相等,類型應一致類型應一致。在。在Turbo C中,中,對對實參求值的順序實參求值的順序是按是按自右至左自右至左的順序。的順序。 7.4.2 函數(shù)調用的方式(函數(shù)調用的方式(P174) 按函數(shù)在程序中出現(xiàn)的位

17、置來分,可以有以下三種函數(shù)調用按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下三種函數(shù)調用方式:方式:1. 函數(shù)語句:函數(shù)語句:把函數(shù)調用作為一個語句。如例把函數(shù)調用作為一個語句。如例8.1中的中的printstar( ); 這種調用方式不要求函數(shù)帶回值,只要求函數(shù)這種調用方式不要求函數(shù)帶回值,只要求函數(shù)完成一定的操作完成一定的操作;2. 函數(shù)表達式:函數(shù)表達式:函數(shù)出現(xiàn)在一個表達式中,這種表達式稱為函數(shù)出現(xiàn)在一個表達式中,這種表達式稱為函數(shù)表達式函數(shù)表達式,這時要求函數(shù)這時要求函數(shù)帶回一個確定的值帶回一個確定的值參加表達式的運算。參加表達式的運算。 例如例如:c=2*max(a,b);3. 函數(shù)參數(shù)

18、:函數(shù)參數(shù):函數(shù)調用函數(shù)調用作為一個函數(shù)的實參作為一個函數(shù)的實參。這種調用的實質也是函數(shù)。這種調用的實質也是函數(shù)表達式調用的一種特例。表達式調用的一種特例。.例如例如:m=max(a,max(b,c);其中其中max(b,c)是一次函數(shù)調用,它的值作為是一次函數(shù)調用,它的值作為max第二次調用的實參。第二次調用的實參。7.4.3 對被調用函數(shù)的聲明和函數(shù)原型(對被調用函數(shù)的聲明和函數(shù)原型(P179) 在一個函數(shù)中調用另一個函數(shù)需要具備的條件:在一個函數(shù)中調用另一個函數(shù)需要具備的條件:1)首先被調用的函數(shù)首先被調用的函數(shù)必須是已經(jīng)存在的函數(shù)必須是已經(jīng)存在的函數(shù)(庫函數(shù)或用(庫函數(shù)或用戶自己定義的

19、函數(shù))。此條件必要而不充分。戶自己定義的函數(shù))。此條件必要而不充分。2)如果使用庫函數(shù),一般還應在本文件開頭用如果使用庫函數(shù),一般還應在本文件開頭用#include命命令將相關的令將相關的 “頭文件頭文件”(含有所用庫函數(shù)的相關信息)(含有所用庫函數(shù)的相關信息)“包含包含”到本文件中來。例如:到本文件中來。例如: #include #include 3)如果使用的是用戶自定義函數(shù),且被調函數(shù)的定義位于主調函數(shù)如果使用的是用戶自定義函數(shù),且被調函數(shù)的定義位于主調函數(shù)之后(如下例),則之后(如下例),則在主調函數(shù)的可執(zhí)行語句之前在主調函數(shù)的可執(zhí)行語句之前應對被調函數(shù)應對被調函數(shù)進行聲明。進行聲明。

20、函數(shù)聲明函數(shù)聲明也稱為也稱為函數(shù)原型函數(shù)原型,其作用主要是,其作用主要是提前告訴編提前告訴編譯系統(tǒng)所要調用函數(shù)的原型,具體的函數(shù)定義在后面,便于編譯譯系統(tǒng)所要調用函數(shù)的原型,具體的函數(shù)定義在后面,便于編譯系統(tǒng)在程序的編譯階段對函數(shù)調用的合法性進行全面檢查系統(tǒng)在程序的編譯階段對函數(shù)調用的合法性進行全面檢查。例例 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ù)體部分。調用調用關于函數(shù)聲明的幾點說明:關于函數(shù)聲明的幾點說明: 1.函數(shù)原型。函數(shù)原型。函數(shù)原型的一般形式為:函數(shù)原型的一般形式為:1)函數(shù)類型函數(shù)類型 函數(shù)名(形參類型函數(shù)名(形參類型1 形參名形參名1, 形參類型形參類型2 形參名形參名2, )2)函數(shù)類型函數(shù)類型 函數(shù)名(形參類型函數(shù)名(形參類型1, 形參類型形參類型2, ) 第一種便于閱讀,第二種為基本形式。實際上,第一種便于閱讀,第二種為基本形式。實際上,編譯系統(tǒng)不對編譯系統(tǒng)不對形參名做檢查形參名做檢查

22、。因此上例程序中的函數(shù)聲明可以寫成:。因此上例程序中的函數(shù)聲明可以寫成: float add( float, float );2. 應當保證應當保證函數(shù)原型與函數(shù)首部寫法上的一致函數(shù)原型與函數(shù)首部寫法上的一致,即,即函數(shù)函數(shù)類型類型、函數(shù)名函數(shù)名,參數(shù)類型參數(shù)類型,參數(shù)個數(shù)參數(shù)個數(shù)和和參數(shù)順序參數(shù)順序必須必須相同。函數(shù)調用時實參類型必須與函數(shù)原型中的形參相同。函數(shù)調用時實參類型必須與函數(shù)原型中的形參類型賦值兼容。類型賦值兼容。3. 如果被調用函數(shù)的定義出現(xiàn)在主調函數(shù)之前,則主調函如果被調用函數(shù)的定義出現(xiàn)在主調函數(shù)之前,則主調函數(shù)中可以不對被調函數(shù)進行聲明。數(shù)中可以不對被調函數(shù)進行聲明。4. 如

23、果已在所有函數(shù)定義之前,在函數(shù)的外部已做了函如果已在所有函數(shù)定義之前,在函數(shù)的外部已做了函數(shù)聲明,則在各個主調函數(shù)中不必對所調用的函數(shù)再數(shù)聲明,則在各個主調函數(shù)中不必對所調用的函數(shù)再作聲明。作聲明。5. 如果在函數(shù)調用之前,沒有對函數(shù)作聲明,則編譯系如果在函數(shù)調用之前,沒有對函數(shù)作聲明,則編譯系統(tǒng)會把第一次遇到的該函數(shù)形式(函數(shù)定義或函數(shù)調統(tǒng)會把第一次遇到的該函數(shù)形式(函數(shù)定義或函數(shù)調用)作為函數(shù)的聲明,并用)作為函數(shù)的聲明,并將函數(shù)類型默認為將函數(shù)類型默認為int 型型。 推薦作法:為了程序清晰和安全,建議都加以聲明!推薦作法:為了程序清晰和安全,建議都加以聲明!7.5 函數(shù)的嵌套調用函數(shù)的

24、嵌套調用C語言的函數(shù)定義都是互相平行、獨立的,即不允許嵌套定義。語言的函數(shù)定義都是互相平行、獨立的,即不允許嵌套定義。嵌套定義嵌套定義是指在定義函數(shù)時,一個函數(shù)內又包含了另一個函數(shù),是指在定義函數(shù)時,一個函數(shù)內又包含了另一個函數(shù),這個內嵌的函數(shù)只能被包含它的函數(shù)所調用,其它函數(shù)不能調用它。這個內嵌的函數(shù)只能被包含它的函數(shù)所調用,其它函數(shù)不能調用它。這在這在PASCAL中是允許的。中是允許的。例如:例如:main() fun1( ); /* 函數(shù)調用語句函數(shù)調用語句 */ fun1( ) fun2( ); /* 函數(shù)嵌套調用函數(shù)嵌套調用 */ fun2( ) main() fun1( ); /*

25、 函數(shù)調用語句函數(shù)調用語句 */ fun1( ) fun2( ) /* 函數(shù)嵌套定義函數(shù)嵌套定義 */ C語句不能嵌套定義函數(shù),但可以語句不能嵌套定義函數(shù),但可以嵌套調用嵌套調用函數(shù),即在調用函數(shù),即在調用一個函數(shù)的過程中,又調用另一個函數(shù)。一個函數(shù)的過程中,又調用另一個函數(shù)。下圖是兩次嵌套調用(連下圖是兩次嵌套調用(連main函數(shù)共函數(shù)共3層函數(shù))的執(zhí)行過程:層函數(shù))的執(zhí)行過程:main函數(shù)函數(shù)調用調用a函數(shù)函數(shù)結束結束a函數(shù)函數(shù)調用調用b函數(shù)函數(shù)b函數(shù)函數(shù) 關于函數(shù)嵌套的概念比較簡單,請大家自學例關于函數(shù)嵌套的概念比較簡單,請大家自學例8.6,下,下面給大家詳細講述一種特殊的函數(shù)嵌套面給大

26、家詳細講述一種特殊的函數(shù)嵌套函數(shù)的遞歸。函數(shù)的遞歸。 所謂遞歸調用,是指在函數(shù)體內部直接或間接地自己調所謂遞歸調用,是指在函數(shù)體內部直接或間接地自己調用自己,即函數(shù)嵌套調用該函數(shù)本身。用自己,即函數(shù)嵌套調用該函數(shù)本身。 一一、遞歸調用的形式遞歸調用的形式 1 1、直接調用、直接調用例例: age ( int n ) int c ; if ( n = = 1 ) c = 10 ; else c = age ( n 1) + 2 ; return ( c ) ; f ( ) 函數(shù)函數(shù) 調用調用f ( )函數(shù)函數(shù) 7.6 函數(shù)的遞歸調用函數(shù)的遞歸調用 2 2、 間接調用間接調用 f1( ) f2(

27、) 調用調用f2( ) 調用調用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 古典的漢諾塔問題,不作要求。古典的漢諾塔問題,不作要求。 例例7.6(P185)有有5 5個人坐在一起,問第個人坐在一起,問第5 5個人多少歲?他說比個人多少歲?他說比第第4 4個人大個人大2 2歲。問第歲。問第4 4個人歲數(shù),他說比第個人歲數(shù),他說比第3

28、3個人大個人大2 2歲。問第歲。問第3 3個人,又說比第個人,又說比第2 2個人大個人大2 2歲。問第歲。問第2 2個人,說比第個人,說比第1 1個人大個人大2 2歲。歲。最后問第最后問第1 1個人,他說是個人,他說是1010歲。請問第歲。請問第5 5個人多大?個人多大?根據(jù)題意有:根據(jù)題意有:age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10用數(shù)學通式表述為:用數(shù)學通式表述為: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進一步熟悉進一步熟悉VC6.0中幾個基本的調試工具:中幾

30、個基本的調試工具: step into,Step over,Watch,Variables,Call stack。 main age(5)=18 age(4)=16 age(3)=14 age(2)=12 age(1)=10 結果: 18 age(5) age(4)+2 c =10 age(1)+2 age(2)+2 age(3)+2二、實現(xiàn)遞歸的條件二、實現(xiàn)遞歸的條件 1 1)要有完成函數(shù)任務的語句;)要有完成函數(shù)任務的語句; 2 2)要有能避免遞歸調用的判斷(即遞歸)要有能避免遞歸調用的判斷(即遞歸“終止條件終止條件”);); 3 3)在遞歸調用的過程中,要能不斷逼近遞歸終止條件,以至)在

31、遞歸調用的過程中,要能不斷逼近遞歸終止條件,以至最后結束遞歸;最后結束遞歸; 4 4)先先進行遞歸終止條件的判斷,進行遞歸終止條件的判斷,后后進行遞歸調用。進行遞歸調用。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) ) ; 分析遞歸的條件分析遞歸的條件完成任務遞歸終止條件遞歸調用先判斷后遞歸調用三、對遞歸的評價三、對遞歸的評價 遞歸的目的是要簡化程序設計,使程序遞歸的目的

32、是要簡化程序設計,使程序易讀易讀。 但遞歸但遞歸增加了系統(tǒng)開銷增加了系統(tǒng)開銷。時間上,執(zhí)行函數(shù)調用和函數(shù)。時間上,執(zhí)行函數(shù)調用和函數(shù)返回屬于額外工作,要占用返回屬于額外工作,要占用CPUCPU時間??臻g上,每遞歸一次,時間??臻g上,每遞歸一次,棧內存就要多占用一部分。棧內存就要多占用一部分。 相應的非遞歸函數(shù)雖然效率高,但卻比較難編程,而且相應的非遞歸函數(shù)雖然效率高,但卻比較難編程,而且相對來說可讀性較差。實際上,大多數(shù)遞歸函數(shù)都是可以用相對來說可讀性較差。實際上,大多數(shù)遞歸函數(shù)都是可以用非遞歸函數(shù)來代替的。關于非遞歸函數(shù)來代替的。關于“遞歸的消去遞歸的消去”不再探討。不再探討。 現(xiàn)代程序設計

33、的目標主要是可讀性好。隨著計算機硬件現(xiàn)代程序設計的目標主要是可讀性好。隨著計算機硬件性能的不斷提高,程序在更多的場合優(yōu)先考慮的是可讀性,性能的不斷提高,程序在更多的場合優(yōu)先考慮的是可讀性,而不是高效性,所以我們而不是高效性,所以我們鼓勵使用遞歸的思想實現(xiàn)程序設計鼓勵使用遞歸的思想實現(xiàn)程序設計。1. 數(shù)組元素作為函數(shù)實參數(shù)組元素作為函數(shù)實參 數(shù)組元素可以作為函數(shù)實參,數(shù)組元素可以作為函數(shù)實參, 用法與變量實參相同,依然遵用法與變量實參相同,依然遵循的是循的是“單向值傳遞單向值傳遞”原則。原則。例例7.9(P193)從鍵盤上輸入)從鍵盤上輸入10個整數(shù),并輸出其中最大的元素和個整數(shù),并輸出其中最大

34、的元素和該元素是第幾個數(shù)。該元素是第幾個數(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 有兩個數(shù)組有兩個數(shù)組a,b,各有,各有10個元素,將它們個元素,將它們對應元素逐一比對應元素逐一比較較。如果。如果a數(shù)組中的元素大于數(shù)組中的元素大于b數(shù)組中相應元素的個數(shù)數(shù)組中相應元素的個數(shù)多于多于b數(shù)組數(shù)組中的元素大于中的元素大于a數(shù)組中相應元素的個數(shù),則認為數(shù)組中相應元素的個數(shù),則認為a數(shù)組數(shù)組大于大于b數(shù)組,數(shù)組,并分別使用并分別使用n、m、k三個標記變量來記錄兩個數(shù)組相應元素大于、三個標記變量來記錄兩個數(shù)組相應元素大于、等于、小于的次數(shù)。要求是用等于、小于的次數(shù)。要求是用large函數(shù)來實現(xiàn)對應元素的比較。函數(shù)來實現(xiàn)對應元素的比較。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ù)組名可作函數(shù)參數(shù),此時實參與形參都應用數(shù)組名。例例7.10(P194) 在一維數(shù)組在一維數(shù)組score中存放了中存放了10個成績,求平均成績。個成績,求平均成績。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);說明:說明: 1)用數(shù)組名作函數(shù)參數(shù),用數(shù)組名作函數(shù)參數(shù),應該在主調函數(shù)和被調用函數(shù)分別定應該在主調函數(shù)和被調用函數(shù)分別定義數(shù)組義數(shù)組,不能只在一方定義(在未講指針前是這樣的)。,不能只在一方定義(在未講指針前是這樣的)。 2)實參數(shù)組與形參數(shù)組類型應一致,否則出錯;實參數(shù)組與形參數(shù)組類型應

39、一致,否則出錯; 3)實參數(shù)組與形參數(shù)組大小可以一致也可以不一致,實參數(shù)組與形參數(shù)組大小可以一致也可以不一致,C編譯對編譯對形參數(shù)組大小不作檢查,只是將實參數(shù)組的首地址傳給形參形參數(shù)組大小不作檢查,只是將實參數(shù)組的首地址傳給形參數(shù)組。因此,上例的被調函數(shù)首部也可寫成:數(shù)組。因此,上例的被調函數(shù)首部也可寫成:float average( float array ) 4)為了能在被調用函數(shù)中知道主調函數(shù)所傳遞的數(shù)組大小,我為了能在被調用函數(shù)中知道主調函數(shù)所傳遞的數(shù)組大小,我們通常另設一個參數(shù)(們通常另設一個參數(shù)(int 變量),傳遞數(shù)組元素的個數(shù)。變量),傳遞數(shù)組元素的個數(shù)。 參見參見P166 例

40、例8.12 。 5)實參和形參數(shù)組將共占同一段內存單元,如果形參數(shù)組中的實參和形參數(shù)組將共占同一段內存單元,如果形參數(shù)組中的元素發(fā)生變化會使實參數(shù)組中的元素發(fā)生相同的變化。元素發(fā)生變化會使實參數(shù)組中的元素發(fā)生相同的變化。例例7.12(P196)用選擇法對數(shù)組中用選擇法對數(shù)組中10個整數(shù)按由小到大排序。個整數(shù)按由小到大排序。選擇法介紹:選擇法介紹:1)將)將10個數(shù)進行相互比較,找出最小數(shù),將之與個數(shù)進行相互比較,找出最小數(shù),將之與a0對換;對換;2)再將)再將a1到到a9的數(shù)進行比較,找出最小數(shù),將之與的數(shù)進行比較,找出最小數(shù),將之與a1對對換;換;3),共比較,共比較9輪,最后得到排序后的結

41、果;輪,最后得到排序后的結果;以以5個數(shù)為例說明:個數(shù)為例說明:a0 a1 a2 a3 a4 3 6 1 9 4 未排序時的情況未排序時的情況 1 6 3 9 4 將將5個數(shù)中最小數(shù)個數(shù)中最小數(shù)1與與a0對換對換 1 3 6 9 4 將余下的將余下的4個數(shù)中最小數(shù)個數(shù)中最小數(shù)3與與a1對換對換 1 3 4 9 6 將余下的將余下的3個數(shù)中最小數(shù)個數(shù)中最小數(shù)4與與a2對換對換 1 3 4 6 9 將余下的將余下的2個數(shù)中最小數(shù)個數(shù)中最小數(shù)6與與a3對換,對換,至此完成排序至此完成排序選擇法排序圖示選擇法排序圖示i=00n-1i n-1j=i+1j n 此法共比較此法共比較n-1趟,每趟共比較趟,

42、每趟共比較n-1-i 次,每趟最多次,每趟最多交換交換1 次,總共最多交換次,總共最多交換n-1次。次。標記變量標記變量k=j:記住每趟中最小的一個數(shù)的下標。:記住每趟中最小的一個數(shù)的下標。源程序(一):不用函數(shù)調用實現(xiàn),程序演示源程序(一):不用函數(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ù)調用實現(xiàn)源程序(二):用函數(shù)調用實現(xiàn)P182.c標記變量標記變量k用于記用于記住每趟最小數(shù)的位住每趟最小數(shù)的位置,初始值為每趟置,初始值為每趟的起始位置的起始位置外循環(huán)變量外循環(huán)變量i 用于記住用于記住每趟的起始位置每趟的起始位置,初始,初始值為第一個數(shù)的位置。值為第一個數(shù)的位置。冒泡法排序圖示(注意區(qū)別)冒泡法排序圖示(注意區(qū)別)i=00n-1i n-1j=0j n-1-i用外循環(huán)變量用外循環(huán)變量i (0= i n-1 )來來控制比較的趟次控制比較的趟次,即第幾趟,即第

45、幾趟(共共n-1趟趟) 。同時,。同時,i 的不斷變化也修改了內循環(huán)變量的不斷變化也修改了內循環(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);結果為:結果為:8a,b為全局變量a,b為局部變量形參a,b作用范圍全局變量b作用范圍局部變量a作用范圍7.9 變量的存儲類別變量的存儲類別7.9.1 動態(tài)存儲方式與靜態(tài)存儲方式動態(tài)存儲方式與靜態(tài)存儲方式 前面

46、,我們從變量的作用域角度把變量分為全局變量和前面,我們從變量的作用域角度把變量分為全局變量和局部變量。這里,我們將從變量值存在的時間(生存期)角局部變量。這里,我們將從變量值存在的時間(生存期)角度來分,可分為靜態(tài)存儲方式和動態(tài)存儲方式。度來分,可分為靜態(tài)存儲方式和動態(tài)存儲方式。 所謂所謂靜態(tài)存儲方式靜態(tài)存儲方式是指是指在程序運行期間分配固定的存儲在程序運行期間分配固定的存儲空間的方式空間的方式,而,而動態(tài)存儲方式動態(tài)存儲方式則是則是在程序運行期間根據(jù)需要在程序運行期間根據(jù)需要進行動態(tài)分配存儲空間的方式進行動態(tài)分配存儲空間的方式。 關于程序內存空間的劃分,教材內容比較簡略且陳舊,關于程序內存空

47、間的劃分,教材內容比較簡略且陳舊,下面將作一些補充。下面將作一些補充。補充:關于程序的內存區(qū)域補充:關于程序的內存區(qū)域 我們知道,變量具有全局和局部、靜態(tài)和動態(tài)之分,要我們知道,變量具有全局和局部、靜態(tài)和動態(tài)之分,要徹底了解變量的這些屬性,我們需要深入地理解程序在內存徹底了解變量的這些屬性,我們需要深入地理解程序在內存中的分布區(qū)域。一個用戶程序將操作系統(tǒng)分配給其運行的內中的分布區(qū)域。一個用戶程序將操作系統(tǒng)分配給其運行的內存塊又分為存塊又分為4個區(qū)域:個區(qū)域:1)代碼區(qū),存放的是)代碼區(qū),存放的是程序代碼程序代碼,即程序中的各個函數(shù)代碼塊。即程序中的各個函數(shù)代碼塊。2)全局數(shù)據(jù)區(qū),存放程序的)全

48、局數(shù)據(jù)區(qū),存放程序的全局全局數(shù)據(jù)數(shù)據(jù)、靜態(tài)數(shù)據(jù)靜態(tài)數(shù)據(jù)和和常量常量。3)堆區(qū),存放程序的動態(tài)數(shù)據(jù)。)堆區(qū),存放程序的動態(tài)數(shù)據(jù)。4)棧區(qū),存放程序的局部數(shù)據(jù),)棧區(qū),存放程序的局部數(shù)據(jù),即即各個函數(shù)中的數(shù)據(jù)各個函數(shù)中的數(shù)據(jù)。代碼區(qū)代碼區(qū)(code area)全局數(shù)據(jù)區(qū)全局數(shù)據(jù)區(qū)(data area)堆區(qū)堆區(qū)(heap area)程序內存空間程序內存空間棧區(qū)棧區(qū)(stack area)低高對用戶程序數(shù)據(jù)區(qū)的具體說明:對用戶程序數(shù)據(jù)區(qū)的具體說明:1)全局數(shù)據(jù)區(qū)全局數(shù)據(jù)區(qū)(教材中稱靜態(tài)存儲區(qū))(教材中稱靜態(tài)存儲區(qū))中的數(shù)據(jù),是在程序中的數(shù)據(jù),是在程序開始執(zhí)行時就分配存儲空間,直到程序執(zhí)行完畢才釋放空開

49、始執(zhí)行時就分配存儲空間,直到程序執(zhí)行完畢才釋放空間。在程序的執(zhí)行過程中,它們始終占據(jù)固定的存儲單元。間。在程序的執(zhí)行過程中,它們始終占據(jù)固定的存儲單元。2)棧區(qū)棧區(qū)中存放的數(shù)據(jù)有以下三種:中存放的數(shù)據(jù)有以下三種: 函數(shù)的形參函數(shù)的形參; 函數(shù)中函數(shù)中定義的自動變量定義的自動變量(未加(未加static聲明的局部變量);聲明的局部變量); 函數(shù)調函數(shù)調用時的現(xiàn)場保用時的現(xiàn)場保 護和返回地址護和返回地址等。等。 對于以上數(shù)據(jù),都是在函數(shù)調用開始時才分配相應的對于以上數(shù)據(jù),都是在函數(shù)調用開始時才分配相應的存儲空間,當函數(shù)結束時便釋放這些空間。在程序執(zhí)行過存儲空間,當函數(shù)結束時便釋放這些空間。在程序執(zhí)

50、行過程中,這種分配和釋放是動態(tài)的。程中,這種分配和釋放是動態(tài)的。3)堆區(qū)堆區(qū)中的數(shù)據(jù),是在程序運行過程由用戶臨時開辟或收回中的數(shù)據(jù),是在程序運行過程由用戶臨時開辟或收回的。的。C語言提供語言提供void * malloc(size_t)和和void free(void *)兩個兩個函數(shù)函數(shù)來完成此任務;來完成此任務;C+中還提供中還提供new 和和delete 兩個操作符兩個操作符來實現(xiàn)。來實現(xiàn)。 (棧區(qū)和堆區(qū)對應教材中的動態(tài)存儲區(qū))(棧區(qū)和堆區(qū)對應教材中的動態(tài)存儲區(qū))在在C語言中,定義一個語言中,定義一個變量變量時,需要考慮兩個基本屬性:時,需要考慮兩個基本屬性:數(shù)據(jù)類型數(shù)據(jù)類型和和數(shù)據(jù)存儲

51、類別數(shù)據(jù)存儲類別。存儲類別指明了數(shù)據(jù)在內存中。存儲類別指明了數(shù)據(jù)在內存中存儲的地方存儲的地方(哪個區(qū)哪個區(qū))。對于變量,我們可以根據(jù)它的存儲。對于變量,我們可以根據(jù)它的存儲類別知道它的類別知道它的生存期生存期。至此,我們在程序設計中使用一個。至此,我們在程序設計中使用一個變量時,必須還要清楚該變量的如下三點信息:變量時,必須還要清楚該變量的如下三點信息:以上三點信息以上三點信息都是在定義該變量時明確指定的都是在定義該變量時明確指定的。變量變量數(shù)據(jù)類型數(shù)據(jù)類型作用域作用域存儲類別具體包含以下四種存儲類別:存儲類別具體包含以下四種存儲類別:1. auto變量變量 函數(shù)中的局部變量,如不專門聲明為函

52、數(shù)中的局部變量,如不專門聲明為static存儲類別,都存儲類別,都是動態(tài)分配存儲空間的,是動態(tài)分配存儲空間的, 數(shù)據(jù)存儲在棧區(qū)中,在函數(shù)調用結數(shù)據(jù)存儲在棧區(qū)中,在函數(shù)調用結束時就自動釋放這些存儲空間,因此束時就自動釋放這些存儲空間,因此這類局部變量稱為這類局部變量稱為自動變自動變量量。自動變量用關鍵字。自動變量用關鍵字auto作存儲類別的聲明。例如:作存儲類別的聲明。例如: int f (int a) /* 定義定義f 函數(shù),函數(shù),a為形參為形參*/ auto int b,c=3 /* 定義定義b,c為自動變量為自動變量 */ 實際上,關鍵字實際上,關鍵字“auto”可以省略,可以省略,aut

53、o不寫則隱含確定不寫則隱含確定為為“自動存儲類別自動存儲類別” 。程序中大多數(shù)變量屬于自動變量。我。程序中大多數(shù)變量屬于自動變量。我們前面介紹的函數(shù)中定義的變量都沒有聲明為們前面介紹的函數(shù)中定義的變量都沒有聲明為auto,其實都隱,其實都隱含指自動變量。含指自動變量。7.9.2 局部變量的存儲類別局部變量的存儲類別 有時希望函數(shù)中的局部變量的值在有時希望函數(shù)中的局部變量的值在函數(shù)調用結束后不消失而保函數(shù)調用結束后不消失而保留原值留原值,即其占用的存儲單元不釋放,在下一次該函數(shù)調用時,該,即其占用的存儲單元不釋放,在下一次該函數(shù)調用時,該變量已有值,就是上一次函數(shù)調用結束時的值。這時就應該指定該

54、變量已有值,就是上一次函數(shù)調用結束時的值。這時就應該指定該局部變量為局部變量為“靜態(tài)局部變量靜態(tài)局部變量”,用關鍵字,用關鍵字static進行存儲類別的聲明。進行存儲類別的聲明。例例7.16(P205)f (int a) auto b=0; static c=3; /* 在以上兩條定義語句中僅在以上兩條定義語句中僅int型可以省略型可以省略*/ b=b+1; /* 每次調用每次調用f 函數(shù)執(zhí)行此語句,函數(shù)執(zhí)行此語句,b均為均為1 */ c=c+1; /* 第一次調用后第一次調用后c 等于等于4,第二次后為,第二次后為5 */ return(a+b+c);main ( ) int a=2,i;

55、for(i=0;i3;i+) printf(“%d ”,f(a);2. static局部變量局部變量運行結果為:運行結果為:7 8 9等價于:等價于:auto b; b=0;不等于:不等于:static c; c=3;說明:說明:1)靜態(tài)局部變量屬于靜態(tài)存儲類別,在全局數(shù)據(jù)區(qū)內分配存靜態(tài)局部變量屬于靜態(tài)存儲類別,在全局數(shù)據(jù)區(qū)內分配存儲單元,在程序整個運行期間都不釋放。儲單元,在程序整個運行期間都不釋放。2)對對靜態(tài)局部變量靜態(tài)局部變量是在是在編譯時進行初始化編譯時進行初始化的,在程序運行時的,在程序運行時它已有初值,以后每次調用函數(shù)時不再重新初始化而只它已有初值,以后每次調用函數(shù)時不再重新初始

56、化而只是保留上次函數(shù)調用結束時的值。而對是保留上次函數(shù)調用結束時的值。而對自動變量的初始自動變量的初始化化,不是在編譯時進行,而是,不是在編譯時進行,而是在函數(shù)調用時進行在函數(shù)調用時進行,每調,每調用一次函數(shù)就重新賦一次初值,相當于執(zhí)行一次賦值語用一次函數(shù)就重新賦一次初值,相當于執(zhí)行一次賦值語句。因此,自動變量的句。因此,自動變量的初始化初始化與與賦初值賦初值是相同的。是相同的。3)如在定義局部變量時不進行初始化,對如在定義局部變量時不進行初始化,對靜態(tài)局部變量靜態(tài)局部變量,編,編譯時會自動初始化為譯時會自動初始化為0(對數(shù)值型變量對數(shù)值型變量)或或空字符空字符(對字符變對字符變量量)。而對。

57、而對自動變量自動變量來說,如果不進行初始化則它的值是來說,如果不進行初始化則它的值是一個一個不確定的值不確定的值。4)雖然靜態(tài)局部變量在函數(shù)調用結束后仍然存在,但其它函雖然靜態(tài)局部變量在函數(shù)調用結束后仍然存在,但其它函數(shù)是不能引用它的,即其它函數(shù)不在其作用域內,稱為數(shù)是不能引用它的,即其它函數(shù)不在其作用域內,稱為“不可見不可見”。一般在以下情況下使用局部靜態(tài)變量:。一般在以下情況下使用局部靜態(tài)變量: (1)需要保留函數(shù)上一次調用結束時的值。需要保留函數(shù)上一次調用結束時的值。 (2)如果初始化后,變量只被引用而不改變其值,則這如果初始化后,變量只被引用而不改變其值,則這時用靜態(tài)局部變量比較方便,

58、以免每次調用時重新賦值。時用靜態(tài)局部變量比較方便,以免每次調用時重新賦值。 但是應該看到,用靜態(tài)存儲但是應該看到,用靜態(tài)存儲要多占內存要多占內存(長期占用不(長期占用不釋放,而不能像動態(tài)存儲那樣一個存儲單元可供多個變量釋放,而不能像動態(tài)存儲那樣一個存儲單元可供多個變量使用,節(jié)約內存空間),而且使用,節(jié)約內存空間),而且降低了程序的可讀性降低了程序的可讀性,當調,當調用次數(shù)多時往往弄不清靜態(tài)局部變量的當前值是什么。因用次數(shù)多時往往弄不清靜態(tài)局部變量的當前值是什么。因此,此,如不十分必要,就不要采用靜態(tài)局部變量如不十分必要,就不要采用靜態(tài)局部變量。3. register變量變量 一般情況下,一般情

59、況下,變量變量(包括靜態(tài)存儲方式和動態(tài)存儲方式)(包括靜態(tài)存儲方式和動態(tài)存儲方式)的值是的值是存放在內存中的存放在內存中的,當程,當程 序中用到哪一個變量的值時,序中用到哪一個變量的值時,由控制器發(fā)出指令將內存中該變量的值送到運算器中。經(jīng)過運由控制器發(fā)出指令將內存中該變量的值送到運算器中。經(jīng)過運算器進行運算,如果需要保存數(shù)據(jù),再從運算器將數(shù)據(jù)送到內算器進行運算,如果需要保存數(shù)據(jù),再從運算器將數(shù)據(jù)送到內存中存放。存中存放。 如果有一些變量使用十分頻繁,則從內存中存取數(shù)據(jù)將花如果有一些變量使用十分頻繁,則從內存中存取數(shù)據(jù)將花費較多時間。為了提高執(zhí)行效率,費較多時間。為了提高執(zhí)行效率,C語言允許將局

60、部變量的值語言允許將局部變量的值放在放在CPU中的寄存器中中的寄存器中。由于對寄存器的存取速度遠高于對。由于對寄存器的存取速度遠高于對內存的存取速度,因此這樣就可以提高執(zhí)行效率。這種變量叫內存的存取速度,因此這樣就可以提高執(zhí)行效率。這種變量叫做做“寄存器變量寄存器變量”,用關鍵字,用關鍵字register作聲明。作聲明。內存內存CPU總總線線運算器運算器控制器控制器寄存器寄存器例例7.17(P207)輸出)輸出1到到5的階乘。書上使用靜態(tài)變量實現(xiàn)的。的階乘。書上使用靜態(tài)變量實現(xiàn)的。下面,使用寄存器變量實現(xiàn)。下面,使用寄存器變量實現(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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論