第七章 用函式實現模組化程式設計

2022-09-23 15:24:10 字數 3577 閱讀 5904

#includevoidmain()

intmax(inta,intb)

v函式宣告中的引數名可以省寫,如上例中的宣告也可以寫成int max(int,int);

v在呼叫函式的過程中呼叫另乙個函式,稱為函式的巢狀呼叫。

v在呼叫乙個函式過程中直接或間接呼叫本函式,稱為函式的遞迴呼叫。

1.在定義函式中指定的形參,在未出現函式呼叫時,它們並不佔記憶體中的儲存單元。在發生函式呼叫時,函式max中的形參被分配到記憶體單元中。

2.將實參對應的值傳遞給形參。

3.在執行max函式期間,由於形參已經有值,就可以進行有關的運算(如把a和b比較)

4.通過return語句將函式的值帶回到主調函式。

5.呼叫結束,形參單元被釋放。注意,實參單元仍保留並維持原值,沒有改變。如果在執行乙個被呼叫函式時,形參的值發生改變,但不會改變主調函式的實參的值。

注意:在c語言中,實參向形參的資料傳遞是「值傳遞」,單向傳遞,只由實參傳給形參,而不能由形參傳給實參。

#include

intmain()

float**erage(floatarray[10])

v由於陣列名代表陣列的首位址,只是將陣列的首元素的位址傳遞給所對應的形參,對應的形參應當是陣列名或指標變數。

v用陣列作為函式引數,在呼叫函式時並不另外開闢乙個存放形引數組的空間,這點是和用變數作函式引數是不同的。

v陣列名代表陣列的首元素的位址,因此,用陣列名作函式實參時,只是將實參陣列的首元素的位址傳給形引數組,形參陣列名獲得了實參陣列的首元素的位址。因此array[0]和score[0]具有同一位址,共佔同一儲存單元,具有相同的值。

v在程式中,定義函式**erage時宣告了形引數組array的大小為10,但在實際應用中,指定其大小並不起任何中,因為c語言編譯對形引數組大小不做檢查,所以形引數組可以不指定大小,在定義陣列時,可以在陣列名後面跟乙個空的方括號,它們效果是相同的。

v形參陣列名實際上是乙個指標變數名。

v形引數組中各元素的值如發生變化會使實參陣列元素的值同時發生變化,這一點是與變臉作函式引數的情況不相同,務請注意。

#include

intmain()

voidsort(intarray,intn)}}

}用變數名或陣列元素作函式引數時,傳遞的是變數的值,用陣列名作函式引數時,傳遞的是陣列首元素的位址。可知,呼叫函式時的虛實結合的方式有兩類:一類是值傳遞方式,一類是位址傳遞方式。

值傳遞方式時,系統為形參另開闢儲存單元,實參與形參不是同一單元,因此形參的值改變不會導致實參值得改變,值傳遞是單向的,只能從實參傳到形參,而不能由形參傳到實參。

位址傳遞方式時,傳遞的是位址,系統不會為形引數組另外開闢一段記憶體單元來存放陣列的值,而是使形引數組與實參陣列共占同一段記憶體單元。由於這個特點,可以利用在函式中改變形引數組的值來改變實參陣列的值。從現象上看,好似傳遞是雙向的,從實參傳遞到形參,又從形參傳遞到實參。但是從嚴格意義上說,傳遞仍然是單向的,僅僅傳遞的是位址而已。由於位址共享,才會出現改變形引數組的值也改變實參陣列的值的現象。這是乙個可以利用的重要技巧。

·二維陣列是由若干個一維陣列組成的,在記憶體中,陣列是按行存放的,因此,在定義二維陣列時,必須指定列數(即一行中包含幾個元素)。

floathighest_score(floatarray[5]);

floathighest_score(floatarray);

floathighest_score(floatarray[4]);

1.在同乙個原始檔中,外部變數和區域性變數同名,則在區域性變數的作用範圍內,外部變數被「遮蔽」,即它不起作用,此時區域性變數是有效的。

2.設定全域性變數的作用是增加函式間資料聯絡的渠道。由於同一源程式檔案的所有函式都能引用全域性變數的值,因此如果在乙個函式中改變了全域性變數的值,就能影響到其他函式,相當於各個函式間有直接的傳遞通道。由於函式的呼叫只能帶回乙個返回值,因此有時可以利用全域性變數增加函式間的聯絡渠道,在呼叫函式時有意改變某個全域性變數的值,這樣,當函式執行結束後,不僅能得到乙個函式返回值,還能使全域性變數獲得乙個新值,從效果上看,相當於通過函式呼叫能得到乙個以上的值。

3.雖然全域性變數有以上優點,但建議不必要時不要使用全域性變數,因為:

全域性變數在程式的全部執行過程中都占用儲存單元,而不是僅在需要時才開闢單元。它使函式的通用性降低了,因為函式在執行時要依賴於其所在的程式檔案中定義的外部變數. 如果將乙個函式移到另乙個檔案中,還要講有關的外部變數及其值一起移過去。但若該外部變數與其他檔案的變數同名時,就會出現衝突,降低程式的可靠性和通用性。、

4.在程式設計中,在劃分模組時要求模組的「內聚性」強、與其他模組的「耦合性」弱,即模組的功能要單一(不要把許多互不相干的功能放到乙個模組中),與其他模組的相互影響要盡量少,而用全域性變數是不符合這個原則的。

5.一般要求把c程式中的函式做成乙個封閉體,除了可以通過「實參-形參」的渠道與外界發生聯絡外,沒有其他渠道。這樣的程式移植性好,可讀性強。

6.使用全域性變數過多,會減低程式的清晰性,人們旺旺難以清楚地判斷出瞬時各個外部變數的值,在各個函式執行時都可能改變外部變數的值,程式容易出錯。因此,要限制使用全域性變數。

v函式的形參

v在函式中定義的變數(包括在復合語句中定義的變數)

1.靜態區域性變數屬於靜態儲存類別,在靜態儲存區內分配儲存單元,在程式整個執行期間都不釋放。

2.而自動變數(即動態區域性變數)屬於動態儲存類別,佔動態儲存區空間而不佔靜態儲存區空間,函式呼叫結束後即釋放。

3.對靜態區域性變數是在編譯時賦初值的,即只賦初值一次,在程式執行時它已有初值,以後每次呼叫函式時不再重新賦初值而只是保留上次函式呼叫結束時的值。

4.而對自動變數賦初值,不是在編譯時進行的,而是在函式呼叫時進行,每呼叫一次函式重新給一次初值,相當於執行一次賦值語句。

5.如在定義區域性變數時不賦初值的話,則對靜態區域性變數來說,編譯時自動賦初值0(對數值型變數)和空字元(對字元變數)。

6.而對自動變數來說,如果不賦初值則它的值是乙個不確定的值。這是由於每次函式呼叫結束後儲存單元已釋放,下次呼叫時又重新另分配儲存單元,而所分配的單元中的值是不可知的。

7.雖然靜態區域性變數在函式呼叫結束後仍然存在,但其他函式是不能引用它的,因為它是區域性變數,只能被本函式引用,而不能被其他函式引用。

8.用靜態儲存會多佔記憶體(長期占用不釋放,而不能像動態儲存那樣,乙個儲存單元可供多個變數使用,節約記憶體),降低程式的可讀性,當呼叫次數多時往往弄不清靜態區域性變數的當前值是什麼。因此,若非必要,不要多動靜態區域性變數。

9.有時在程式設計中希望某些外部變數只限於被本檔案引用,而不能被其他檔案引用。這時可以在定義外部變數時加乙個static宣告。這種加上static宣告,只能用於本檔案的外部變數,稱為靜態外部變數。

vstatic對區域性變數和全域性變數的作用不同。

① 對區域性變數來說,它使變數由動態儲存方式改變為靜態儲存方式。

② 而對全域性變數來說,它使變數區域性化(區域性於本檔案),但仍未靜態儲存方式。

由於現在計算機的執行速度愈來愈快,效能愈來愈好,優化的編譯系統能夠識別使用頻繁的變數,從而自動將這些變數存在暫存器中,而不需要程式設計者指定。

在任乙個檔案中定義外部變數num,而在另一檔案中用extern對num作「外部變數宣告」,即「extern num;」。在編譯和連線時,系統會由此知道num是乙個已在別處定義的外部變數,並將在另一檔案中定義的外部變數的作用域擴充套件到本檔案,在本檔案中可以合法地引用外部變數num。

第七章 用函式實現模組化程式設計

第七章 用函式實現模組化程式設計 7.1 呼叫函式輸出一下結果。7.2 輸入兩個整數,要求輸出其中較大者,用函式早最大者。7.3 對7.2進行修改,將在max函式中定義的變數z改為float型。函式返回值得型別禹之鼎的型別不同。7.4 輸入兩個實數,用函式求和。7.1 呼叫函式輸出一下結果。7.2 ...

第七章 用函式實現模組化程式設計

例7.1輸出以下結果並用函式呼叫實現 include intmain void print star void print message 執行結果如下 例7.2輸入兩個整數要求輸出較大者,用函式來找大數 include intmain intmax int x,int y 執行結果如下 例7.3將...

第七章 用函式實現模組化程式設計

例7.1 想輸出一下結果,用函式呼叫實現。how do you do include intmain void print star void print message 執行結果如下 例7.2 輸入兩個整數,要求輸出其中較大者。要求用函式來找到大數。int max int x,int y incl...