幻燈片-C語言程序設計視頻教程-徐紅波-第8章.ppt

上傳人:xt****7 文檔編號:17681868 上傳時間:2020-11-28 格式:PPT 頁數(shù):71 大?。?05KB
收藏 版權申訴 舉報 下載
幻燈片-C語言程序設計視頻教程-徐紅波-第8章.ppt_第1頁
第1頁 / 共71頁
幻燈片-C語言程序設計視頻教程-徐紅波-第8章.ppt_第2頁
第2頁 / 共71頁
幻燈片-C語言程序設計視頻教程-徐紅波-第8章.ppt_第3頁
第3頁 / 共71頁

下載文檔到電腦,查找使用更方便

14.9 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《幻燈片-C語言程序設計視頻教程-徐紅波-第8章.ppt》由會員分享,可在線閱讀,更多相關《幻燈片-C語言程序設計視頻教程-徐紅波-第8章.ppt(71頁珍藏版)》請在裝配圖網(wǎng)上搜索。

1、C程序設計 講師:徐紅波 Email: x_h_ 第 8章 函數(shù) 8.1 概述 一個較大的程序一般應分為若干個 程序模塊,每一個模塊用來實現(xiàn)一個特 定的功能。所有的高級語句中都有子程 序這個概念,用子程序實現(xiàn)模塊的功能。 在 C語言中,子程序的作用是由函數(shù)來完 成的。一個 C程序可由一個主函數(shù)和若干 個其他函數(shù)構成。由主函數(shù)調用其他函 數(shù),其他函數(shù)也可以相互調用。同一個 函數(shù)可以被一個或多個函數(shù)調用任意多 次。 在程序設計中,常將一些常用的功 能模塊編寫成函數(shù),放在公共函數(shù)庫中 供大家選用。程序設計人員要善于利用 函數(shù),以減少重復編寫程序段的工作量。 例 8.1函

2、數(shù)調用的簡單例子 #include void main() void printstar(); void print_message(); printstar(); print_message(); printstar(); void printstar() printf(“**********n”); void print_message() printf(“How do you do!n”); 說明: (1)一個 C程序由一個或多個程序模塊組成,每一個程序模塊作 為一個源程序文件。對較大的程序,一般不希望把所有內容全 放在一個文件中,而是將它們放在若干個源

3、文件中,再由若干 個源程序文件組成一個 C程序。一個源程序文件可以為多個 C程 序共用。 (2)一個源程序文件由一個或多個函數(shù)以及其他有關內容 (如命令 行、數(shù)據(jù)定義等 )組成。一個源程序是一個編譯單位,在程序編 譯時是以源程序文件為單位進行編譯的,而不是以函數(shù)為單位 進行編譯的。 (3)C程序的執(zhí)行是從 main函數(shù)開始的,如是在 main函數(shù)中調用 其他函數(shù),在調用后流程返回到 main函數(shù),在 main函數(shù)中結束 整個程序的運行。 (4)所有函數(shù)都是平行的,即在定義函數(shù)時是分別進行的,是相 互獨立的。一個函數(shù)并不從屬于另一個函數(shù),即函數(shù)不能嵌套 定義。函數(shù)間可以相互調用,但不能調用

4、 main函數(shù)。 main函數(shù) 是系統(tǒng)調用的。 (5)從用戶使用的角度看,函數(shù)有兩種。 標準函數(shù) 。標準函數(shù)即庫函數(shù),它是由系統(tǒng)提供的,用戶不 必自己定義而直接使用它們。 用戶自己定義的函數(shù) 。它是用以解決用戶專門需要的函數(shù)。 (6)從函數(shù)的形式看,函數(shù)分兩類。 無參函數(shù) 。在調用無參函數(shù)時,主調函數(shù)不向被調用函數(shù)傳 遞數(shù)據(jù)。無參函數(shù)一般用來執(zhí)行指定的一組操作。無參函數(shù) 可以帶回或不帶會函數(shù)值,但一般以不帶回函數(shù)值的居多。 有參函數(shù) 。在調用函數(shù)時,主調函數(shù)在調用被調用函數(shù)時, 通過參數(shù)向被調用函數(shù)傳遞數(shù)據(jù),一般情況下,執(zhí)行被調用 函數(shù)時會得到一個函數(shù)值,供主調函數(shù)使用。

5、 8.2 函數(shù)定義的一般形式 8.2.1 無參函數(shù)定義的一般形式 定義無參函數(shù)的一般形式為: 類型標識符 函數(shù)名 () 聲明部分 語句部分 在定義函數(shù)時要用“類型標識符”指定函數(shù)值的類型,即函 數(shù)帶回來的值的類型。 8.2.2 有參函數(shù)定義的一般形式 定義有參函數(shù)的一般形式為: 類型標識符 函數(shù)名 (形式參數(shù)表列 ) 聲明部分 語句部分 例如: int max(int x, int y) int z; z = xy ? x : y; return z; 8.2.3 空函數(shù) 在程序設計中有時會用到空函數(shù),它的形式為: 類型說明符

6、函數(shù)名 () 8.3 函數(shù)參數(shù)和函數(shù)的值 8.3.1 形式參數(shù)和實際參數(shù) 在調用函數(shù)時,大多數(shù)情況下,主調函數(shù)和被調用 函數(shù)之間有數(shù)據(jù)傳遞關系。在定義函數(shù)時函數(shù)名后面括 號中的變量名稱為“形式參數(shù)” (簡稱“形參” ),在主 調函數(shù)中調用一個函數(shù)時,函數(shù)名后面括號中的參數(shù) (可以是一個表達式 )稱為“實際參數(shù)” (簡稱“實參” )。 例 8.2調用函數(shù)時的數(shù)據(jù)傳遞 #include void main() int max(int x, int y); int a, b, c; scanf(“%d,%d”, c=max(a, b); printf(“Max is

7、%d”, c); int max(int x, int y) int z; z = x y ? x : y; return z; 關于形參與實參的說明: (1)在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調用時,它們并不 占內存中的存儲單元。只有在發(fā)生函數(shù)調用時,函數(shù) max中的 形參才被分配內存單元。在調用結束后,形參所占的內存單元 也被釋放。 (2)實參可以是常量、變量或表達式。但要求它們有確定的值。 在調用時將實參的值賦給形參。 (3)在被定義的函數(shù)中,必須指定形參的類型。 (4)實參與形參的類型應相同或賦值兼容。 (5)實參向形參的數(shù)據(jù)傳遞是“值傳遞”,單向傳遞,只由實

8、參 傳給形參,而不能由形參傳回來給實參。在內存中,實參單元 與形參單元是不同的單元。在調用函數(shù)時,給形參分配存儲單 元,并將實參對應的值傳遞給形參,調用結束后,形參單元被 釋放,實參單元仍保留并維持原值。因此,在執(zhí)行一個被調用 函數(shù)時,形參的值如果發(fā)生改變,并不會改變主調函數(shù)的實參 的值。 8.3.2 函數(shù)的返回值 通過函數(shù)調用使主調函數(shù)能得到一個確定的值,這就是函 數(shù)的返回值。 (1)函數(shù)的返回值是通過函數(shù)中的 return語句獲得的。 return語句 將被調用函數(shù)中的一個確定值帶回主調函數(shù)中去。 (2)函數(shù)值的類型。既然函數(shù)有返回值,這個值當然應屬于某一 個確定的類型,應當在定

9、義函數(shù)時指定函數(shù)值的類型。 (3)在定義函數(shù)時指定的函數(shù)類型一般應該和 return語句中的表 達式類型一致。如果函數(shù)值的類型和 return語句中表達式的值不 一致,則以函數(shù)類型為準。對數(shù)值型數(shù)據(jù),可以自動進行類型 轉換。即函數(shù)類型決定返回值的類型。 例 8.3返回值類型與函數(shù)類型不同 #include void main() int max(flaot x, float y); float a, b; int c; scanf(“%f,%f”, c=max(a, b); printf(“Max is %dn”, c); int max(float x, float

10、y) float z; z = x y ? x : y; return z; (4)對于不帶回值的函數(shù),應當用“ void”定義函數(shù)為 “無類型” (或稱“空類型” )。這樣,系統(tǒng)就保證不 使函數(shù)帶回任何值,即禁止調用函數(shù)中使用被調用函 數(shù)的返回值。此時在函數(shù)體中不得出現(xiàn) return語句。 8.4 函數(shù)的調用 8.4.1 函數(shù)調用的一般形式 函數(shù)調用的一般形式為 函數(shù)名 (實參表列 ); 如果是調用無參函數(shù),則“實參表列”可以沒有, 但括號不能省略。如果實參表列包含多個實參,則各參 數(shù)間用逗號隔開。實參與形參的個數(shù)應相等,類型應匹 配。實參與形參按順序對應,一一傳

11、遞數(shù)據(jù)。但應說明, 如果實參表列包括多個實參,對實參求值的順序并不是 確定的,有的系統(tǒng)按自左至右順序求實參的值,有的系 統(tǒng)則按自右至左順序。 例 8.4實參求值的順序 #include void main() int f(int a, int b); int i=2, p; p=f(i, ++i); printf(“%dn”, p); int f(int a, int b) int c; if(ab) c=1; else if(a==b) c=0; else c=-1; return c; 8.4.2 函數(shù)調用的方式 按函數(shù)在程序中出現(xiàn)的位置來分,可以有以

12、下 3種函數(shù)調用 方式。 1. 函數(shù)語句 把函數(shù)調用作為一個語句。這時不要求函數(shù)帶回值,只要 求函數(shù)完成一定的操作。 2. 函數(shù)表達式 函數(shù)出現(xiàn)在一個表達式中,這種表達式稱為函數(shù)表達式。 這時要求函數(shù)帶回一個確定的值以參加表達式的運算。 3. 函數(shù)參數(shù) 函數(shù)調用作為一個函數(shù)的實參。 8.4.3 對被調用函數(shù)的聲明和函數(shù)原型 在一個函數(shù)中調用另一個函數(shù)需要具備的條件如下 。 (1)首先被調用的函數(shù)必須是已經存在的函數(shù) (是庫函數(shù)或用戶自 己定義的函數(shù) )。但光有這一條件還不夠。 (2)如果使用庫函數(shù),還應該在本文件開頭用 #include命令將調 用有關庫函數(shù)時

13、所需用到的信息“包含”到本文件中去。 (3)如果使用用戶自己定義的函數(shù),而該函數(shù)的位置在調用它的 函數(shù) (即主調函數(shù) )的后面 (在同一個文件中 ),應該在主調函數(shù)中 對被調用的函數(shù)作聲明。 例 8.5對被調用的函數(shù)作聲明 #include void main() float add(float x, float y); float a, b, c; scanf(“%f,%f”, c=add(a, b); printf(“sum is %fn”, c); float add(float x, float y) float z; z=x+y; return z;

14、 在函數(shù)調用之前用函數(shù)原型做了函數(shù)聲明。 因此編譯系統(tǒng)記下了所需調用的函數(shù)的有關信息。 編譯系統(tǒng)根據(jù)函數(shù)的原型對函數(shù)的調用的合法性 進行全面的檢查。與函數(shù)原型不匹配的函數(shù)調用 會導致編譯出錯,它屬于語法錯誤。用戶根據(jù)屏 幕顯示的出錯信息很容易發(fā)現(xiàn)和糾正錯誤。 函數(shù)原型的一般形式有兩種,分別為 (1)函數(shù)類型 函數(shù)名 (參數(shù)類型 1, 參數(shù)類型 2, , 參數(shù)類型 n); (2)函數(shù)類型 函數(shù)名 (參數(shù)類型 1 參數(shù)名 1, 參數(shù)類型 2 參數(shù)名 2, , 參數(shù)類型 n 參數(shù)名 n); 說明: (1)如果被調用函數(shù)的定義出現(xiàn)在主調函數(shù)之前,可以 不必加以聲明。 (2)如果已在文件的開

15、頭 (在所有函數(shù)之前 ),已對本文 件中所調用的函數(shù)進行了聲明,則在各函數(shù)中不必對 其所調用的函數(shù)再作聲明。 8.5 函數(shù)的嵌套調用 C語言的函數(shù)定義是相互平行、獨立的。在定義函 數(shù)時,一個函數(shù)內不能包含另一個函數(shù)。 C語言不能嵌套定義函數(shù),但可以嵌套調用函數(shù), 在調用一個函數(shù)的過程中,又調用另一個函數(shù)。 例 8.6函數(shù)嵌套調用的應用 m a i n 函 數(shù) 調 用 a 函 數(shù) 結 束 a 函 數(shù) 調 用 b 函 數(shù) b 函 數(shù) 8.6 函數(shù)的遞歸調用 在調用一個函數(shù)的過程中又出現(xiàn)直接或間接地調用 該函數(shù)本身,稱為函數(shù)的遞歸調用。 f 函 數(shù) 調 用 f 函 數(shù) f 1 函

16、 數(shù) 調 用 f 2 函 數(shù) f 2 函 數(shù) 調 用 f 1 函 數(shù) ( a ) 直 接 遞 歸 調 用 ( b ) 間 接 遞 歸 調 用 例 8.7有 5個人坐在一起,問第 5個人多少歲?他說比第 4個人大 2歲。問第 4個人歲數(shù),他說比第 3個人大 2歲。 問第 3個人,又說比第 2個人大 2歲。問第 2個人,說比第 1個人大 2歲。最后問第 1個人,他說是 10歲。請問第 5個 人多大 12)1( 110 )( nnage n nage 例 8.8用遞歸方法求 n! 1)!1( 1,01 ! nnn n n 8.9Hanoi塔問題。古代有一個梵塔,塔內有 3個

17、座 A、 B、 C,開始時 A座上有 64個盤子,盤子大小不等,大的在 下,小的在上。有一個老和尚想把這 64個盤子從 A座移 到 C座,但每次只允許移動一個盤,且在移動過程中在 3 個座上都始終保持大盤在下,小盤在上。在移動過程中 可以利用 B座,要求編程序輸出移動的步驟 A B C 8.7 數(shù)組作為函數(shù)參數(shù) 前面已經介紹了可以用變量作函數(shù)參數(shù),顯然,數(shù) 組元素也可以作函數(shù)參數(shù),其用法與變量相同。此外, 數(shù)組名也可以作實參和形參,傳遞的是數(shù)組首元素的地 址。 8.7.1 數(shù)組元素作函數(shù)實參 由于實參可以是表達式,而數(shù)組元素可以是表達式的組成部 分,因此數(shù)組元素當然可以作為函數(shù)的實

18、參,與用變量作實參一 樣,是單向傳遞,即“值傳送”方式。 例 8.10有兩個數(shù)組 a和 b,各有 10個元素,將它們對應地逐個 比較 (即 a0與 b0比, a1與 b1比 ) 。如果 a數(shù)組中的元素大 于 b數(shù)組中的相應元素的數(shù)目多于 b數(shù)組中元素大于 a數(shù)組中相應 元素的數(shù)目 (例如, aibi6次, biai3次,其中 i每次為不同 的值 ),則認為 a數(shù)組大于 b數(shù)組,并分別統(tǒng)計出兩個數(shù)組相應元 素大于、等于、小于的次數(shù)。 8.7.2 數(shù)組名作函數(shù)參數(shù) 可以用數(shù)組名作函數(shù)參數(shù),此時形參應當用數(shù)組名 或用指針變量。 例 8.11有一個一維數(shù)組 score,內放 10個學生成

19、績, 求平均成績 說明: (1)用數(shù)組名作函數(shù)參數(shù),應該在主調函數(shù)和被調函數(shù)分別定義數(shù) 組。 (2)實參數(shù)組與形參數(shù)組類型應一致,如不一致,結果將出錯。 (3)在被調用函數(shù)中聲明了形參數(shù)組的大小為 10,但在實際上,指 定其大小是不起任何作用的,因為 C語言編譯對形參數(shù)組大小不 做檢查,只是將實參數(shù)組的首元素的地址傳給形參數(shù)組。因此, 形參數(shù)組名獲得了實參數(shù)組的首元素的地址。 (4)形參數(shù)組可以不指定大小,在定義數(shù)組時在數(shù)組名后面跟一個 空的方括號。有時為了在被調用函數(shù)中處理數(shù)組元素的需要,可 以另設一個形參,傳遞需要處理的數(shù)組元素的個數(shù)。 例 8.12形參數(shù)組不定義長度 (5)

20、用數(shù)組名作函數(shù)實參時,不是把數(shù)組元素的值傳遞 給形參,而是把實參數(shù)組的首元素的地址傳遞給形參 數(shù)組,這樣兩個數(shù)組就共占同一段內存單元。形參數(shù) 組中各元素的值如發(fā)生變化會使實參數(shù)組元素的值同 時發(fā)生變化。 例 8.13用選擇法對數(shù)組中 10個整數(shù)按由小到大排序。所 謂選擇法就是先將 10個數(shù)中最小的數(shù)與 a0對換;再將 a1到 a9中最小的數(shù)與 a1對換 每比較一輪,找出 一個未經排序的數(shù)中最小的一個。共比較 9輪 8.7.3 多維數(shù)組名作函數(shù)參數(shù) 多維數(shù)組元素可以作函數(shù)參數(shù)。 用多維數(shù)組名作為函數(shù)的實參和形參,在被調用函 數(shù)中對形參數(shù)組定義時可以指定每一維的大小,也可以 省略第

21、一維的大小說明。但是不能把第二維以及其他高 維的大小說明省略。 例 8.14有一個 3 4矩陣,求所有元素最大值 先使變量 max的初值為矩陣中第一個元素的值,然 后將矩陣中各個元素的值與 max相比,每次比較后都把 “大者”存放在 max中,全部元素比較完后, max的值 就是所有元素的最大值。 8.8 局部變量和全局變量 8.8.1 局部變量 在一個函數(shù)內部定義的變量是內部變量,它只在本函數(shù)范圍內有效, 也就是說只有在本函數(shù)內才能使用它們,在此函數(shù)以外是不能使用這些變量 的。這稱為“局部變量”。例如: float f1(int a) int b, c;

22、 char f2(int x, int y) int i, j; void main() int m, n; 說明: (1)主函數(shù)中定義的變量也只在主函數(shù)中有效,而不因 為在主函數(shù)中定義而在整個文件或程序中有效。主函 數(shù)也不能使用其他函數(shù)中定義的變量。 (2)不同函數(shù)中可以使用相同名字的變量,它們代表不 同的對象,互不干擾。 (3)形式參數(shù)也是局部變量。 (4)在一個函數(shù)內部,可以在復合語句中定義變量,這 些變量只在本復合語句中有效,這種復合語句也稱為 “分程序”或“程序塊”。 8.8.2 全局變量 程序

23、的編譯單位是源程序文件,一個源文件可以包 含一個或若干個函數(shù)。在函數(shù)內定義的變量是局部變量, 而在函數(shù)之外定義的變量稱為外部變量,外部變量是全 局變量。全局變量可以為本文件中其他函數(shù)所共用。它 的有效范圍為從定義變量的位置開始到本源文件結束。 例如: int p=1, q=5; float f1(int a) int b, c; char c1, c2; char f2(int x, int y) int i, j; void main() int m, n; 說明: (1)設置全局變量的作用是增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道。 例 8.15有一個一維數(shù)組

24、,內放 10個學生成績,寫一個函數(shù),求 出平均分、最高分和最低分 (2)建議不在必要時不要使用全局變量,原因如下: 全局變量在程序的全部執(zhí)行過程中都占用存儲單元,而不是僅 在需要時才開辟單元。 它使函數(shù)的通用性降低了,因為函數(shù)在執(zhí)行時要依賴于其所在 的外部變量。 使用全局變量過多,會降低程序的清晰性,難以清除地判斷出 每個瞬時各個外部變量的值。 (3)如果在同一個源文件中,外部變量與局部變量同名,則在局部 變量的作用范圍內,外部變量被“屏蔽”,即它不起作用。 例 8.16外部變量與局部變量同名 8.9 變量的存儲類別 8.9.1 動態(tài)存儲方式與靜態(tài)存儲方式 從變量的

25、作用域 (即從空間 )角度來分,可以分為 全 局變量 和 局部變量 。 從變量值存在的時間 (即 生存期 )角度來分,可以分 為 靜態(tài)存儲方式 和 動態(tài)存儲方式 。 所謂靜態(tài)存儲方式是指在程序運行期間由系統(tǒng)分配 固定的存儲空間的方式。而動態(tài)存儲方式則是在程序運 行期間根據(jù)需要進行動態(tài)的分配存儲空間的方式。 程序的存儲空間可以分為三部分: 程序區(qū) 靜態(tài)存儲區(qū) 動態(tài)存儲區(qū) 數(shù)據(jù)分別存放在靜態(tài)存儲區(qū)和動態(tài)存儲區(qū)中。 全局變量全部存放在靜態(tài)存儲區(qū)中,在程序開始 執(zhí)行時給全局變量分配存儲區(qū),程序執(zhí)行完畢就 釋放。在程序執(zhí)行過程中它們占據(jù)固定的存儲單 元,而不是動態(tài)地進行分配和

26、釋放。 在動態(tài)存儲區(qū)中存放以下數(shù)據(jù): 函數(shù)形式參數(shù)。在調用函數(shù)時給形參分配存儲空間。 自動變量 (未加 static聲明的局部變量 ) 函數(shù)調用時的現(xiàn)場保護和返回地址等。 對以上這些數(shù)據(jù),在函數(shù)調用開始時分配動態(tài)存儲空間,函 數(shù)結束時釋放這些空間。在程序執(zhí)行過程中,這種分配和釋放是 動態(tài)的,如果在一個程序中兩次調用同一函數(shù),分配給此函數(shù)中 局部變量的存儲空間地址可能是不同的。如果一個程序包含若干 個函數(shù),每個函數(shù)中的局部變量的生存期并不等于整個程序的執(zhí) 行周期,它只是程序執(zhí)行周期的一部分。根據(jù)函數(shù)調用的需要, 動態(tài)地分配和釋放存儲空間。 在 C語言中,每一個變量和

27、函數(shù)有兩個屬性:數(shù)據(jù) 類型和數(shù)據(jù)的存儲類別。存儲類別指的是數(shù)據(jù)在內存 中存儲的方式。存儲方式分為兩大類:靜態(tài)存儲類和 動態(tài)存儲類。具體包含 4種: 自動的 (auto)、靜態(tài)的 (static)、寄存器的 (register)、外部的 (extern)。根據(jù)變量 的存儲類別,可以知道變量的作用域和生存期。 8.9.2 auto變量 函數(shù)中的局部變量,如果不專門聲明為 static存儲類 別,都是動態(tài)地分配存儲空間的,數(shù)據(jù)存儲在動態(tài)存 儲區(qū)中。函數(shù)中的形參和在函數(shù)中定義的變量 (包括在 復合語句中定義的變量 ),都屬此類,在調用該函數(shù)時 系統(tǒng)會給它們分配存儲空間,在函數(shù)調用結束時就自 動釋

28、放這些存儲空間。因此這類局部變量稱為自動變 量。自動變量用關鍵字 auto作存儲類別的聲明。 例如: int f(int a) auto int b, c=3; 8.9.3 用 static聲明局部變量 有時希望函數(shù)中的局部變量的值在函數(shù)調用結束后 不消失而保留原值,即其占用的存儲單元不釋放,在下 一次該函數(shù)調用時,該變量已有值,就是上一次函數(shù)調 用結束時的值。這時就應該指定該局部變量為“靜態(tài)局 部變量”,用關鍵字 static進行聲明。 例 8.17考察靜態(tài)局部變量的值 #include void main() int f(int); int a=2, i;

29、 for(i=0; i<3; i++) printf(“%d “, f(a)); int f(int a) auto int b=0; static int c=3; b=b+1; c=c+1; return (a+b+c); 對靜態(tài)局部變量的說明 (1)靜態(tài)局部變量屬于靜態(tài)存儲類別,在靜態(tài)存儲區(qū)內分配存儲單元。 在程序整個運行期間都不釋放。而自動變量 (即動態(tài)局部變量 )屬于動 態(tài)存儲類別,占動態(tài)存儲區(qū)空間而不占靜態(tài)存儲區(qū)空間,函數(shù)調用結 束后即釋放。 (2)對靜態(tài)局部變量是在編譯時賦初值的,即只賦初值一次,在程序 運行時它已有初值。以后每次調用函數(shù)時不再重新賦初值而只

30、是保留 上次函數(shù)調用結束時的值。而對自動變量賦初值,不是在編譯時進行 的,而是在函數(shù)調用時進行,每調用一次函數(shù)重新給一次初值,相當 于執(zhí)行一次賦值語句。 (3)如在定義局部變量時不賦初值的話,則對靜態(tài)局部變量來說,編 譯時自動賦初值 0(對數(shù)值型變量 )或空字符 (對字符變量 )。而對自動變 量而說,如果不賦初值則它的值是一個不確定的值。這是由于每次函 數(shù)調用結束后存儲單元已釋放,下次調用時又重新另分配存儲單元, 而所分配的單元中的值是不確定的。 (4)雖然靜態(tài)局部變量在函數(shù)調用結束后仍然存在,但其他函數(shù)是不 能引用它的。 需要用靜態(tài)局部變量的情況如下。 (1)需要保留函數(shù)上一次調用

31、結束時的值。 例 8.18輸出 1到 5的階乘值 (2)如果初始化后,變量只被引用而不改變其值,則這時用靜態(tài)局 部變量比較方便,以免每次調用時重新賦值。 但是應該看到,用靜態(tài)存儲要多占內存 (長期占用不釋放,而 不能像動態(tài)存儲那樣一個存儲單元可供多個變量使用,節(jié)約內 存 ),而且降低了程序的可讀性,當調用次數(shù)多時往往弄不清靜 態(tài)局部變量的當前值是什么。因此,若非必要,不要多用靜態(tài)局 部變量。 8.9.4 register變量 一般情況下,變量 (包括靜態(tài)存儲方式和動態(tài)存儲方式 )的 值是存放在內存中的。當程序中用到哪一個變量的值時,由控 制器發(fā)出指令將內存中該變量的值送到運算器中

32、。經過運算器 進行運算,如果需要存數(shù),再從運算器將數(shù)據(jù)送到內存存放。 如果有一些變量使用頻繁 (例如,在一個函數(shù)中執(zhí)行 10000 次循環(huán),每次循環(huán)中都要引用某局部變量 ),則為存取變量的值 要花費不少時間。為提高執(zhí)行效率, C語言允許將局部變量的 值放在 CPU中的寄存器中,需要用時直接從寄存器取出參加運 算,不必再到內存中去存取。由于對寄存器的存取速度遠高于 對內存的存取速度,因此這樣做可以提高執(zhí)行效率。這種變量 叫做寄存器變量,用關鍵字 register作聲明。 例 8.19使用寄存器變量 #include void main() long fac(long); lon

33、g i, n; scanf(“%ld”, for(i=1; i<=n; i++) printf(“%ld!=%ldn”, i, fac(i)); long fac(long n) register long i, f=1; for(i=1; i<=n; i++) f=f*i; return f; 說明: (1)只有局部自動變量和形式參數(shù)可以作為寄存器變量,其他 (如 全局變量 )不行,在調用一個函數(shù)時占用一些寄存器以存放寄存 器變量的值,函數(shù)調用結束釋放寄存器。此后,在調用另一個 函數(shù)時又可以利用它來存放該函數(shù)的寄存器變量。 (2)一個計算機系統(tǒng)中的寄存器數(shù)目是有限的,

34、不能定義任意多 個寄存器變量。不同的系統(tǒng)允許使用的寄存器數(shù)目是有限的, 而且對 register變量的處理方法也是不同的,有的系統(tǒng)對 register 變量當作自動變量處理,分配內存單元,并不真正把它們存放 在寄存器中,有的系統(tǒng)只允許將 int、 char和指針型變量定義為 寄存器變量。 (3)局部靜態(tài)變量不能定義為寄存器變量。 8.9.5 用 extern聲明外部變量 外部變量是在函數(shù)的外部定義的全局變量,它的作 用域是從變量的定義處開始,到本程序文件的末尾。 在此作用域內,全局變量可以為程序中各個函數(shù)所引 用。編譯時將外部變量分配在靜態(tài)存儲區(qū)。 有時需要用 extern來聲明外

35、部變量,以擴展外部變 量的作用域。 1、在一個文件內聲明外部變量 如果外部變量不在文件的開頭定義,其有效的作用 范圍只限于定義處到文件結束。如果在定義點之前的函 數(shù)想引用該外部變量,則應該在引用之前用關鍵字 extern對該變量作“外部變量聲明”,表示該變量是一 個已經定義的外部變量。有了此聲明,就可以從“聲明” 處起,合法地使用該外部變量。 例 8.20用 extern聲明外部變量,擴展它在程序文 件中的作用域 #include void main() int max(int, int); extern A, B; printf(“%dn”, max(A, B)); i

36、nt A=13, B=-8; int max(int x, int y) int z; z=xy ? x : y; return z; 2、在多文件的程序中聲明外部變量 如果一個程序包含兩個文件,在兩個文件中都要用 到同一個外部變量 Num,不能分別在兩個文件中各自 定義一個外部變量 Num,否則在進行程序的連接時會 出現(xiàn)“重復定義”的錯誤。正確的做法是:在任一個 文件中定義外部變量 Num,而在另一個文件中用 extern 對 Num作“外部變量聲明”。即“ extern Num;”。在編 譯和連接時,系統(tǒng)會由此知道 Num是一個已在別處定 義的外部變量,并將在另一文件中定義的

37、外部變量的 作用域擴展到本文件,在本文件中可以合法地引用外 部變量 Num。 例 8.21用 extern將外部變量的作用域擴展到 其他文件 #include int A; void main() int power(int); int b=3, c, d, m; printf(“enter the number a and its power m:n”); scanf(“%d, %d”, c=A*b; printf(“%d**%d=%dn”, A, m, d); extern A; int power(int n) int i, y=1; for(i=1; i<=

38、n; i++) y*=A; return y; 8.9.6 用 static聲明外部變量 有時在程序設計中希望某些外部變量只限于被本文件引 用,而不能被其他文件引用。這時可以在定義外部變量時加 一個 static聲明。 例如: file1.c file2.c static int A; extern int A; void main() void fun(int n) A=A*n; 8.9.7 關于變量的聲明和定義 對變量而言,聲明與定義的關系稍微復雜一些。在聲明部 分出現(xiàn)的變量有兩種情況:一種是需要建立存儲空間的 (如:

39、int a;),另一種是不需要建立存儲空間 (如: extern a;)。前者稱為 “定義性聲明”,或簡稱定義。后者稱為“引用性聲明”。廣 義地說,聲明包括定義,但并非所有的聲明都是定義。對“ int a;”而言,它既是聲明,又是定義。而對“ extern a;”而言,它是 聲明而不是定義。一般為了敘述方便,把建立存儲空間的聲明 稱定義,而把不需要建立存儲空間的聲明稱為聲明。顯然這里 指的聲明是狹義的,即非定義性聲明。例如: void main() extern A; int A; 8.9.8 存儲類別小結 從上可知,對一個數(shù)據(jù)的定義,需要指定兩種屬 性:數(shù)據(jù)類型

40、和存儲類別,分別使用兩個關鍵字。 例如: static int a; auto char c; register int d; 此外,可以用 extern聲明變量為已定義的外部變 量,例如: extern b; 下面從不同角度做些歸納: (1)從作用域角度分,有局部變量和全局變量。它們采用 的存儲類別如下: 局部變量 : 自動變量,即動態(tài)局部變量 (離開函數(shù),值就消失 ) 靜態(tài)局部變量 (離開函數(shù),值仍保留 ) 寄存器變量 (離開函數(shù),值就消失 ) (形式參數(shù)可以定義為自動變量和寄存器變量 ) 全局變量 : 靜態(tài)外部變量 (只限本文件引用 ) 外部變量 (即

41、非靜態(tài)的外部變量,允許其他文件引用 ) (2)從變量存在的時間 (生存期 )來區(qū)分,有動態(tài)存儲和 靜態(tài)存儲兩種類型。靜態(tài)存儲是程序整個運行時間都 存在,而動態(tài)存儲則是在調用函數(shù)時臨時分配單元。 動態(tài)存儲 : 自動變量 (本函數(shù)內有效 ) 寄存器變量 (本函數(shù)內有效 ) 形式參數(shù) (本函數(shù)內有效 ) 靜態(tài)存儲 : 靜態(tài)局部變量 (函數(shù)內有效 ) 靜態(tài)外部變量 (本文件內有效 ) 外部變量 (其他文件可引用 ) (3)從變量值存放的位置來區(qū)分,可分為: 內存中靜態(tài)存儲區(qū) : 靜態(tài)局部變量 靜態(tài)外部變量 (函數(shù)外部靜態(tài)變量 ) 外部變量 (可為其他文件引用

42、 ) 內存中動態(tài)存儲區(qū) : 自動變量和形式參數(shù) CPU中的寄存器 : 寄存器變量 (4)對一個變量的性質可以從兩個方面分析,一是變量的 作用域,一是變量值存在時間的長短,即生存期。前者 是從空間的角度,后者是從時間的角度。二者有聯(lián)系但 不是同一回事。 (5)static對局部變量和全局變量的作用不同。對局部變 量來說,它使變量由動態(tài)存儲方式改變?yōu)殪o態(tài)存儲方式。 而對全局變量來說,它使變量局部化 (局部于本文件 ), 但仍為靜態(tài)存儲方式。從作用域角度看,凡有 static聲明 的,其作用域都是局限的,或者是局限于本函數(shù)內 (靜 態(tài)局部變量 ),或者局限于本文件內 (靜態(tài)外部變量

43、)。 8.10 內部函數(shù)和外部函數(shù) 函數(shù)本質上是全局的,因為一個函數(shù)要被另 外的函數(shù)調用,但是,也可以指定函數(shù)不能被其 他文件調用。根據(jù)函數(shù)能否被其他源文件調用, 將函數(shù)區(qū)分為 內部函數(shù) 和 外部函數(shù) 。 8.10.1 內部函數(shù) 如果一個函數(shù)只能被本文件中其他函數(shù)所調用,它 稱為內部函數(shù)。在定義內部函數(shù)時,在函數(shù)名和函數(shù)類 型的前面加 static,即: static 類型標識符 函數(shù)名 (形參表 ); 內部函數(shù)又稱靜態(tài)函數(shù),因為它是用 static聲明的。 使用內部函數(shù),可以使函數(shù)的作用域只局限于所在文件, 在不同的文件中有相同的內部函數(shù),互補干擾。這樣不 同的人可以分別編

44、寫不同的函數(shù),而不必擔心所用函數(shù) 是否會與其他文件中函數(shù)同名。 8.10.2 外部函數(shù) (1)在定義函數(shù)時,如果在函數(shù)首部的最左端加關鍵字 extern,則表示此函數(shù)是外部函數(shù),可供其他文件調用。 (2)在需要引用此函數(shù)的文件中,用 extern對函數(shù)作聲 明,表示該函數(shù)是在其他文件中定義的外部函數(shù)。 例 8.22有一個字符串,內有若干個字符,今輸入一個 字符,要求程序將字符串中該字符刪去。用外部函數(shù) 實現(xiàn)。 習題 8.3 寫一個判素數(shù)的函數(shù),在主函數(shù)輸入一個整數(shù),輸 出是否素數(shù)的信息。 8.4 寫一個函數(shù),使給定的一個 3 3的二維整型數(shù)組轉 置,即行列互換。 8.5 寫一個函數(shù),使輸入的一個字符串按反序存放,在 主函數(shù)中輸入和輸出字符串。 8.6 寫一個函數(shù),將兩個字符串連接。 8.13 用遞歸方法求 n階勒讓德多項式的值,遞歸公式為: 1/))(*)1()(*)12(( 1 01 )( 21 nnxpnxpxn nx n xp nn n

展開閱讀全文
溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

相關資源

更多
正為您匹配相似的精品文檔
關于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對上載內容本身不做任何修改或編輯。若文檔所含內容侵犯了您的版權或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!