幻燈片C語(yǔ)言程序設(shè)計(jì)視頻教程第8章ppt課件
《幻燈片C語(yǔ)言程序設(shè)計(jì)視頻教程第8章ppt課件》由會(huì)員分享,可在線閱讀,更多相關(guān)《幻燈片C語(yǔ)言程序設(shè)計(jì)視頻教程第8章ppt課件(72頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、C程序設(shè)計(jì),講師:徐紅波 Email:,第8章 函數(shù)8.1 概述,一個(gè)較大的程序一般應(yīng)分為若干個(gè)程序模塊,每一個(gè)模塊用來(lái)實(shí)現(xiàn)一個(gè)特定的功能。所有的高級(jí)語(yǔ)句中都有子程序這個(gè)概念,用子程序?qū)崿F(xiàn)模塊的功能。在C語(yǔ)言中,子程序的作用是由函數(shù)來(lái)完成的。一個(gè)C程序可由一個(gè)主函數(shù)和若干個(gè)其他函數(shù)構(gòu)成。由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以相互調(diào)用。同一個(gè)函數(shù)可以被一個(gè)或多個(gè)函數(shù)調(diào)用任意多次。 在程序設(shè)計(jì)中,常將一些常用的功能模塊編寫(xiě)成函數(shù),放在公共函數(shù)庫(kù)中供大家選用。程序設(shè)計(jì)人員要善于利用函數(shù),以減少重復(fù)編寫(xiě)程序段的工作量。,例8.1函數(shù)調(diào)用的簡(jiǎn)單例子,#include void main() void p
2、rintstar(); void print_message(); printstar(); print_message(); printstar(); ,void printstar() printf(“**********n”); void print_message() printf(“How do you do!n”); ,說(shuō)明:,(1)一個(gè)C程序由一個(gè)或多個(gè)程序模塊組成,每一個(gè)程序模塊作為一個(gè)源程序文件。對(duì)較大的程序,一般不希望把所有內(nèi)容全放在一個(gè)文件中,而是將它們放在若干個(gè)源文件中,再由若干個(gè)源程序文件組成一個(gè)C程序。一個(gè)源程序文件可以為多個(gè)C程序共用。 (2)一個(gè)源程序文件由一個(gè)
3、或多個(gè)函數(shù)以及其他有關(guān)內(nèi)容(如命令行、數(shù)據(jù)定義等)組成。一個(gè)源程序是一個(gè)編譯單位,在程序編譯時(shí)是以源程序文件為單位進(jìn)行編譯的,而不是以函數(shù)為單位進(jìn)行編譯的。 (3)C程序的執(zhí)行是從main函數(shù)開(kāi)始的,如是在main函數(shù)中調(diào)用其他函數(shù),在調(diào)用后流程返回到main函數(shù),在main函數(shù)中結(jié)束整個(gè)程序的運(yùn)行。 (4)所有函數(shù)都是平行的,即在定義函數(shù)時(shí)是分別進(jìn)行的,是相互獨(dú)立的。一個(gè)函數(shù)并不從屬于另一個(gè)函數(shù),即函數(shù)不能嵌套定義。函數(shù)間可以相互調(diào)用,但不能調(diào)用main函數(shù)。main函數(shù)是系統(tǒng)調(diào)用的。,,(5)從用戶使用的角度看,函數(shù)有兩種。 標(biāo)準(zhǔn)函數(shù)。標(biāo)準(zhǔn)函數(shù)即庫(kù)函數(shù),它是由系統(tǒng)提供的,用戶不必自己定義而
4、直接使用它們。 用戶自己定義的函數(shù)。它是用以解決用戶專門(mén)需要的函數(shù)。 (6)從函數(shù)的形式看,函數(shù)分兩類。 無(wú)參函數(shù)。在調(diào)用無(wú)參函數(shù)時(shí),主調(diào)函數(shù)不向被調(diào)用函數(shù)傳遞數(shù)據(jù)。無(wú)參函數(shù)一般用來(lái)執(zhí)行指定的一組操作。無(wú)參函數(shù)可以帶回或不帶會(huì)函數(shù)值,但一般以不帶回函數(shù)值的居多。 有參函數(shù)。在調(diào)用函數(shù)時(shí),主調(diào)函數(shù)在調(diào)用被調(diào)用函數(shù)時(shí),通過(guò)參數(shù)向被調(diào)用函數(shù)傳遞數(shù)據(jù),一般情況下,執(zhí)行被調(diào)用函數(shù)時(shí)會(huì)得到一個(gè)函數(shù)值,供主調(diào)函數(shù)使用。,8.2 函數(shù)定義的一般形式8.2.1 無(wú)參函數(shù)定義的一般形式,定義無(wú)參函數(shù)的一般形式為: 類型標(biāo)識(shí)符 函數(shù)名() 聲明部分 語(yǔ)句部分 在定義函數(shù)時(shí)要用“類型標(biāo)識(shí)符”指定函數(shù)值的類型,即函數(shù)帶
5、回來(lái)的值的類型。,8.2.2 有參函數(shù)定義的一般形式,定義有參函數(shù)的一般形式為: 類型標(biāo)識(shí)符 函數(shù)名(形式參數(shù)表列) 聲明部分 語(yǔ)句部分 ,例如: int max(int x, int y) int z; z = xy ? x : y; return z; ,8.2.3 空函數(shù),在程序設(shè)計(jì)中有時(shí)會(huì)用到空函數(shù),它的形式為: 類型說(shuō)明符 函數(shù)名() ,8.3 函數(shù)參數(shù)和函數(shù)的值8.3.1 形式參數(shù)和實(shí)際參數(shù),在調(diào)用函數(shù)時(shí),大多數(shù)情況下,主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞關(guān)系。在定義函數(shù)時(shí)函數(shù)名后面括號(hào)中的變量名稱為“形式參數(shù)”(簡(jiǎn)稱“形參”),在主調(diào)函數(shù)中調(diào)用一個(gè)函數(shù)時(shí),函數(shù)名后面括號(hào)中的參數(shù)(可
6、以是一個(gè)表達(dá)式)稱為“實(shí)際參數(shù)”(簡(jiǎn)稱“實(shí)參”)。,例8.2調(diào)用函數(shù)時(shí)的數(shù)據(jù)傳遞,#include void main() int max(int x, int y); int a, b, c; scanf(“%d,%d”, ,int max(int x, int y) int z; z = x y ? x : y; return z; ,關(guān)于形參與實(shí)參的說(shuō)明:,(1)在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調(diào)用時(shí),它們并不占內(nèi)存中的存儲(chǔ)單元。只有在發(fā)生函數(shù)調(diào)用時(shí),函數(shù)max中的形參才被分配內(nèi)存單元。在調(diào)用結(jié)束后,形參所占的內(nèi)存單元也被釋放。 (2)實(shí)參可以是常量、變量或表達(dá)式。但要求它們有確定的
7、值。在調(diào)用時(shí)將實(shí)參的值賦給形參。 (3)在被定義的函數(shù)中,必須指定形參的類型。 (4)實(shí)參與形參的類型應(yīng)相同或賦值兼容。 (5)實(shí)參向形參的數(shù)據(jù)傳遞是“值傳遞”,單向傳遞,只由實(shí)參傳給形參,而不能由形參傳回來(lái)給實(shí)參。在內(nèi)存中,實(shí)參單元與形參單元是不同的單元。在調(diào)用函數(shù)時(shí),給形參分配存儲(chǔ)單元,并將實(shí)參對(duì)應(yīng)的值傳遞給形參,調(diào)用結(jié)束后,形參單元被釋放,實(shí)參單元仍保留并維持原值。因此,在執(zhí)行一個(gè)被調(diào)用函數(shù)時(shí),形參的值如果發(fā)生改變,并不會(huì)改變主調(diào)函數(shù)的實(shí)參的值。,8.3.2 函數(shù)的返回值,通過(guò)函數(shù)調(diào)用使主調(diào)函數(shù)能得到一個(gè)確定的值,這就是函數(shù)的返回值。 (1)函數(shù)的返回值是通過(guò)函數(shù)中的return語(yǔ)句獲得
8、的。return語(yǔ)句將被調(diào)用函數(shù)中的一個(gè)確定值帶回主調(diào)函數(shù)中去。 (2)函數(shù)值的類型。既然函數(shù)有返回值,這個(gè)值當(dāng)然應(yīng)屬于某一個(gè)確定的類型,應(yīng)當(dāng)在定義函數(shù)時(shí)指定函數(shù)值的類型。 (3)在定義函數(shù)時(shí)指定的函數(shù)類型一般應(yīng)該和return語(yǔ)句中的表達(dá)式類型一致。如果函數(shù)值的類型和return語(yǔ)句中表達(dá)式的值不一致,則以函數(shù)類型為準(zhǔn)。對(duì)數(shù)值型數(shù)據(jù),可以自動(dòng)進(jìn)行類型轉(zhuǎn)換。即函數(shù)類型決定返回值的類型。,例8.3返回值類型與函數(shù)類型不同,#include void main() int max(flaot x, float y); float a, b; int c; scanf(“%f,%f”, ,int m
9、ax(float x, float y) float z; z = x y ? x : y; return z; ,,(4)對(duì)于不帶回值的函數(shù),應(yīng)當(dāng)用“void”定義函數(shù)為“無(wú)類型”(或稱“空類型”)。這樣,系統(tǒng)就保證不使函數(shù)帶回任何值,即禁止調(diào)用函數(shù)中使用被調(diào)用函數(shù)的返回值。此時(shí)在函數(shù)體中不得出現(xiàn)return語(yǔ)句。,8.4 函數(shù)的調(diào)用8.4.1 函數(shù)調(diào)用的一般形式,函數(shù)調(diào)用的一般形式為 函數(shù)名(實(shí)參表列); 如果是調(diào)用無(wú)參函數(shù),則“實(shí)參表列”可以沒(méi)有,但括號(hào)不能省略。如果實(shí)參表列包含多個(gè)實(shí)參,則各參數(shù)間用逗號(hào)隔開(kāi)。實(shí)參與形參的個(gè)數(shù)應(yīng)相等,類型應(yīng)匹配。實(shí)參與形參按順序?qū)?yīng),一一傳遞數(shù)據(jù)。但應(yīng)說(shuō)
10、明,如果實(shí)參表列包括多個(gè)實(shí)參,對(duì)實(shí)參求值的順序并不是確定的,有的系統(tǒng)按自左至右順序求實(shí)參的值,有的系統(tǒng)則按自右至左順序。,例8.4實(shí)參求值的順序,#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ù)調(diào)用的方式,按函數(shù)在程序中出現(xiàn)的位置來(lái)分,可以有以下3種函數(shù)調(diào)用方式。 1. 函數(shù)語(yǔ)句 把函數(shù)調(diào)用作為一個(gè)
11、語(yǔ)句。這時(shí)不要求函數(shù)帶回值,只要求函數(shù)完成一定的操作。 2. 函數(shù)表達(dá)式 函數(shù)出現(xiàn)在一個(gè)表達(dá)式中,這種表達(dá)式稱為函數(shù)表達(dá)式。這時(shí)要求函數(shù)帶回一個(gè)確定的值以參加表達(dá)式的運(yùn)算。 3. 函數(shù)參數(shù) 函數(shù)調(diào)用作為一個(gè)函數(shù)的實(shí)參。,8.4.3 對(duì)被調(diào)用函數(shù)的聲明和函數(shù)原型,在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)需要具備的條件如下 。 (1)首先被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù)(是庫(kù)函數(shù)或用戶自己定義的函數(shù))。但光有這一條件還不夠。 (2)如果使用庫(kù)函數(shù),還應(yīng)該在本文件開(kāi)頭用#include命令將調(diào)用有關(guān)庫(kù)函數(shù)時(shí)所需用到的信息“包含”到本文件中去。 (3)如果使用用戶自己定義的函數(shù),而該函數(shù)的位置在調(diào)用它的函數(shù)(即主調(diào)
12、函數(shù))的后面(在同一個(gè)文件中),應(yīng)該在主調(diào)函數(shù)中對(duì)被調(diào)用的函數(shù)作聲明。,例8.5對(duì)被調(diào)用的函數(shù)作聲明,#include void main() float add(float x, float y); float a, b, c; scanf(“%f,%f”, ,float add(float x, float y) float z; z=x+y; return z; ,,在函數(shù)調(diào)用之前用函數(shù)原型做了函數(shù)聲明。因此編譯系統(tǒng)記下了所需調(diào)用的函數(shù)的有關(guān)信息。編譯系統(tǒng)根據(jù)函數(shù)的原型對(duì)函數(shù)的調(diào)用的合法性進(jìn)行全面的檢查。與函數(shù)原型不匹配的函數(shù)調(diào)用會(huì)導(dǎo)致編譯出錯(cuò),它屬于語(yǔ)法錯(cuò)誤。用戶根據(jù)屏幕顯示的出錯(cuò)信息
13、很容易發(fā)現(xiàn)和糾正錯(cuò)誤。,,函數(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);,說(shuō)明:,(1)如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必加以聲明。 (2)如果已在文件的開(kāi)頭(在所有函數(shù)之前),已對(duì)本文件中所調(diào)用的函數(shù)進(jìn)行了聲明,則在各函數(shù)中不必對(duì)其所調(diào)用的函數(shù)再作聲明。,8.5 函數(shù)的嵌套調(diào)用,C語(yǔ)言的函數(shù)定義是相互平行、獨(dú)立的。在定義函數(shù)時(shí),一個(gè)函數(shù)內(nèi)不能包含另一個(gè)函數(shù)。 C語(yǔ)言不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),在調(diào)用一個(gè)函數(shù)的過(guò)
14、程中,又調(diào)用另一個(gè)函數(shù)。,例8.6函數(shù)嵌套調(diào)用的應(yīng)用,8.6 函數(shù)的遞歸調(diào)用,在調(diào)用一個(gè)函數(shù)的過(guò)程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。,例8.7有5個(gè)人坐在一起,問(wèn)第5個(gè)人多少歲?他說(shuō)比第4個(gè)人大2歲。問(wèn)第4個(gè)人歲數(shù),他說(shuō)比第3個(gè)人大2歲。問(wèn)第3個(gè)人,又說(shuō)比第2個(gè)人大2歲。問(wèn)第2個(gè)人,說(shuō)比第1個(gè)人大2歲。最后問(wèn)第1個(gè)人,他說(shuō)是10歲。請(qǐng)問(wèn)第5個(gè)人多大,例8.8用遞歸方法求n!,8.9Hanoi塔問(wèn)題。古代有一個(gè)梵塔,塔內(nèi)有3個(gè)座A、B、C,開(kāi)始時(shí)A座上有64個(gè)盤(pán)子,盤(pán)子大小不等,大的在下,小的在上。有一個(gè)老和尚想把這64個(gè)盤(pán)子從A座移到C座,但每次只允許移動(dòng)一個(gè)盤(pán),且在移動(dòng)
15、過(guò)程中在3個(gè)座上都始終保持大盤(pán)在下,小盤(pán)在上。在移動(dòng)過(guò)程中可以利用B座,要求編程序輸出移動(dòng)的步驟,8.7 數(shù)組作為函數(shù)參數(shù),前面已經(jīng)介紹了可以用變量作函數(shù)參數(shù),顯然,數(shù)組元素也可以作函數(shù)參數(shù),其用法與變量相同。此外,數(shù)組名也可以作實(shí)參和形參,傳遞的是數(shù)組首元素的地址。,8.7.1 數(shù)組元素作函數(shù)實(shí)參,由于實(shí)參可以是表達(dá)式,而數(shù)組元素可以是表達(dá)式的組成部分,因此數(shù)組元素當(dāng)然可以作為函數(shù)的實(shí)參,與用變量作實(shí)參一樣,是單向傳遞,即“值傳送”方式。 例8.10有兩個(gè)數(shù)組a和b,各有10個(gè)元素,將它們對(duì)應(yīng)地逐個(gè)比較(即a0與b0比,a1與b1比)。如果a數(shù)組中的元素大于b數(shù)組中的相應(yīng)元素的數(shù)目多于b數(shù)組
16、中元素大于a數(shù)組中相應(yīng)元素的數(shù)目(例如,aibi6次,biai3次,其中i每次為不同的值),則認(rèn)為a數(shù)組大于b數(shù)組,并分別統(tǒng)計(jì)出兩個(gè)數(shù)組相應(yīng)元素大于、等于、小于的次數(shù)。,8.7.2 數(shù)組名作函數(shù)參數(shù),可以用數(shù)組名作函數(shù)參數(shù),此時(shí)形參應(yīng)當(dāng)用數(shù)組名或用指針變量。 例8.11有一個(gè)一維數(shù)組score,內(nèi)放10個(gè)學(xué)生成績(jī),求平均成績(jī),說(shuō)明:,(1)用數(shù)組名作函數(shù)參數(shù),應(yīng)該在主調(diào)函數(shù)和被調(diào)函數(shù)分別定義數(shù)組。 (2)實(shí)參數(shù)組與形參數(shù)組類型應(yīng)一致,如不一致,結(jié)果將出錯(cuò)。 (3)在被調(diào)用函數(shù)中聲明了形參數(shù)組的大小為10,但在實(shí)際上,指定其大小是不起任何作用的,因?yàn)镃語(yǔ)言編譯對(duì)形參數(shù)組大小不做檢查,只是將實(shí)參數(shù)
17、組的首元素的地址傳給形參數(shù)組。因此,形參數(shù)組名獲得了實(shí)參數(shù)組的首元素的地址。 (4)形參數(shù)組可以不指定大小,在定義數(shù)組時(shí)在數(shù)組名后面跟一個(gè)空的方括號(hào)。有時(shí)為了在被調(diào)用函數(shù)中處理數(shù)組元素的需要,可以另設(shè)一個(gè)形參,傳遞需要處理的數(shù)組元素的個(gè)數(shù)。 例8.12形參數(shù)組不定義長(zhǎng)度,,(5)用數(shù)組名作函數(shù)實(shí)參時(shí),不是把數(shù)組元素的值傳遞給形參,而是把實(shí)參數(shù)組的首元素的地址傳遞給形參數(shù)組,這樣兩個(gè)數(shù)組就共占同一段內(nèi)存單元。形參數(shù)組中各元素的值如發(fā)生變化會(huì)使實(shí)參數(shù)組元素的值同時(shí)發(fā)生變化。,例8.13用選擇法對(duì)數(shù)組中10個(gè)整數(shù)按由小到大排序。所謂選擇法就是先將10個(gè)數(shù)中最小的數(shù)與a0對(duì)換;再將a1到a9中最小的數(shù)
18、與a1對(duì)換每比較一輪,找出一個(gè)未經(jīng)排序的數(shù)中最小的一個(gè)。共比較9輪,,8.7.3 多維數(shù)組名作函數(shù)參數(shù),多維數(shù)組元素可以作函數(shù)參數(shù)。 用多維數(shù)組名作為函數(shù)的實(shí)參和形參,在被調(diào)用函數(shù)中對(duì)形參數(shù)組定義時(shí)可以指定每一維的大小,也可以省略第一維的大小說(shuō)明。但是不能把第二維以及其他高維的大小說(shuō)明省略。,例8.14有一個(gè)34矩陣,求所有元素最大值,先使變量max的初值為矩陣中第一個(gè)元素的值,然后將矩陣中各個(gè)元素的值與max相比,每次比較后都把“大者”存放在max中,全部元素比較完后,max的值就是所有元素的最大值。,8.8 局部變量和全局變量8.8.1 局部變量,在一個(gè)函數(shù)內(nèi)部定義的變量是內(nèi)部變量,它只在
19、本函數(shù)范圍內(nèi)有效,也就是說(shuō)只有在本函數(shù)內(nèi)才能使用它們,在此函數(shù)以外是不能使用這些變量的。這稱為“局部變量”。例如: float f1(int a) int b, c; char f2(int x, int y) int i, j; void main() int m, n; ,說(shuō)明:,(1)主函數(shù)中定義的變量也只在主函數(shù)中有效,而不因?yàn)樵谥骱瘮?shù)中定義而在整個(gè)文件或程序中有效。主函數(shù)也不能使用其他函數(shù)中定義的變量。 (2)不同函數(shù)中可以使用相同名字的變量,它們代表不同的對(duì)象,互不干擾。 (3)形式參數(shù)也是局部變量。 (4)在一個(gè)函數(shù)內(nèi)部,可以在復(fù)合語(yǔ)句中定義變量,這些
20、變量只在本復(fù)合語(yǔ)句中有效,這種復(fù)合語(yǔ)句也稱為“分程序”或“程序塊”。,8.8.2 全局變量,程序的編譯單位是源程序文件,一個(gè)源文件可以包含一個(gè)或若干個(gè)函數(shù)。在函數(shù)內(nèi)定義的變量是局部變量,而在函數(shù)之外定義的變量稱為外部變量,外部變量是全局變量。全局變量可以為本文件中其他函數(shù)所共用。它的有效范圍為從定義變量的位置開(kāi)始到本源文件結(jié)束。,例如:,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; ,說(shuō)明:,(1)設(shè)置全局變量的作用是增加了
21、函數(shù)間數(shù)據(jù)聯(lián)系的渠道。 例8.15有一個(gè)一維數(shù)組,內(nèi)放10個(gè)學(xué)生成績(jī),寫(xiě)一個(gè)函數(shù),求出平均分、最高分和最低分 (2)建議不在必要時(shí)不要使用全局變量,原因如下: 全局變量在程序的全部執(zhí)行過(guò)程中都占用存儲(chǔ)單元,而不是僅在需要時(shí)才開(kāi)辟單元。 它使函數(shù)的通用性降低了,因?yàn)楹瘮?shù)在執(zhí)行時(shí)要依賴于其所在的外部變量。 使用全局變量過(guò)多,會(huì)降低程序的清晰性,難以清除地判斷出每個(gè)瞬時(shí)各個(gè)外部變量的值。 (3)如果在同一個(gè)源文件中,外部變量與局部變量同名,則在局部變量的作用范圍內(nèi),外部變量被“屏蔽”,即它不起作用。 例8.16外部變量與局部變量同名,8.9 變量的存儲(chǔ)類別8.9.1 動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式,從變
22、量的作用域(即從空間)角度來(lái)分,可以分為全局變量和局部變量。 從變量值存在的時(shí)間(即生存期)角度來(lái)分,可以分為靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式。 所謂靜態(tài)存儲(chǔ)方式是指在程序運(yùn)行期間由系統(tǒng)分配固定的存儲(chǔ)空間的方式。而動(dòng)態(tài)存儲(chǔ)方式則是在程序運(yùn)行期間根據(jù)需要進(jìn)行動(dòng)態(tài)的分配存儲(chǔ)空間的方式。,,程序的存儲(chǔ)空間可以分為三部分: 程序區(qū) 靜態(tài)存儲(chǔ)區(qū) 動(dòng)態(tài)存儲(chǔ)區(qū) 數(shù)據(jù)分別存放在靜態(tài)存儲(chǔ)區(qū)和動(dòng)態(tài)存儲(chǔ)區(qū)中。全局變量全部存放在靜態(tài)存儲(chǔ)區(qū)中,在程序開(kāi)始執(zhí)行時(shí)給全局變量分配存儲(chǔ)區(qū),程序執(zhí)行完畢就釋放。在程序執(zhí)行過(guò)程中它們占據(jù)固定的存儲(chǔ)單元,而不是動(dòng)態(tài)地進(jìn)行分配和釋放。,,在動(dòng)態(tài)存儲(chǔ)區(qū)中存放以下數(shù)據(jù): 函數(shù)形式參數(shù)。在調(diào)用函數(shù)
23、時(shí)給形參分配存儲(chǔ)空間。 自動(dòng)變量(未加static聲明的局部變量) 函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)保護(hù)和返回地址等。 對(duì)以上這些數(shù)據(jù),在函數(shù)調(diào)用開(kāi)始時(shí)分配動(dòng)態(tài)存儲(chǔ)空間,函數(shù)結(jié)束時(shí)釋放這些空間。在程序執(zhí)行過(guò)程中,這種分配和釋放是動(dòng)態(tài)的,如果在一個(gè)程序中兩次調(diào)用同一函數(shù),分配給此函數(shù)中局部變量的存儲(chǔ)空間地址可能是不同的。如果一個(gè)程序包含若干個(gè)函數(shù),每個(gè)函數(shù)中的局部變量的生存期并不等于整個(gè)程序的執(zhí)行周期,它只是程序執(zhí)行周期的一部分。根據(jù)函數(shù)調(diào)用的需要,動(dòng)態(tài)地分配和釋放存儲(chǔ)空間。,,在C語(yǔ)言中,每一個(gè)變量和函數(shù)有兩個(gè)屬性:數(shù)據(jù)類型和數(shù)據(jù)的存儲(chǔ)類別。存儲(chǔ)類別指的是數(shù)據(jù)在內(nèi)存中存儲(chǔ)的方式。存儲(chǔ)方式分為兩大類:靜態(tài)存儲(chǔ)類
24、和動(dòng)態(tài)存儲(chǔ)類。具體包含4種:自動(dòng)的(auto)、靜態(tài)的(static)、寄存器的(register)、外部的(extern)。根據(jù)變量的存儲(chǔ)類別,可以知道變量的作用域和生存期。,8.9.2 auto變量,函數(shù)中的局部變量,如果不專門(mén)聲明為static存儲(chǔ)類別,都是動(dòng)態(tài)地分配存儲(chǔ)空間的,數(shù)據(jù)存儲(chǔ)在動(dòng)態(tài)存儲(chǔ)區(qū)中。函數(shù)中的形參和在函數(shù)中定義的變量(包括在復(fù)合語(yǔ)句中定義的變量),都屬此類,在調(diào)用該函數(shù)時(shí)系統(tǒng)會(huì)給它們分配存儲(chǔ)空間,在函數(shù)調(diào)用結(jié)束時(shí)就自動(dòng)釋放這些存儲(chǔ)空間。因此這類局部變量稱為自動(dòng)變量。自動(dòng)變量用關(guān)鍵字auto作存儲(chǔ)類別的聲明。,,例如: int f(int a) auto int b, c
25、=3; ,8.9.3 用static聲明局部變量,有時(shí)希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,即其占用的存儲(chǔ)單元不釋放,在下一次該函數(shù)調(diào)用時(shí),該變量已有值,就是上一次函數(shù)調(diào)用結(jié)束時(shí)的值。這時(shí)就應(yīng)該指定該局部變量為“靜態(tài)局部變量”,用關(guān)鍵字static進(jìn)行聲明。,例8.17考察靜態(tài)局部變量的值,#include void main() int f(int); int a=2, i; 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; re
26、turn (a+b+c); ,對(duì)靜態(tài)局部變量的說(shuō)明,(1)靜態(tài)局部變量屬于靜態(tài)存儲(chǔ)類別,在靜態(tài)存儲(chǔ)區(qū)內(nèi)分配存儲(chǔ)單元。在程序整個(gè)運(yùn)行期間都不釋放。而自動(dòng)變量(即動(dòng)態(tài)局部變量)屬于動(dòng)態(tài)存儲(chǔ)類別,占動(dòng)態(tài)存儲(chǔ)區(qū)空間而不占靜態(tài)存儲(chǔ)區(qū)空間,函數(shù)調(diào)用結(jié)束后即釋放。 (2)對(duì)靜態(tài)局部變量是在編譯時(shí)賦初值的,即只賦初值一次,在程序運(yùn)行時(shí)它已有初值。以后每次調(diào)用函數(shù)時(shí)不再重新賦初值而只是保留上次函數(shù)調(diào)用結(jié)束時(shí)的值。而對(duì)自動(dòng)變量賦初值,不是在編譯時(shí)進(jìn)行的,而是在函數(shù)調(diào)用時(shí)進(jìn)行,每調(diào)用一次函數(shù)重新給一次初值,相當(dāng)于執(zhí)行一次賦值語(yǔ)句。 (3)如在定義局部變量時(shí)不賦初值的話,則對(duì)靜態(tài)局部變量來(lái)說(shuō),編譯時(shí)自動(dòng)賦初值0(對(duì)數(shù)
27、值型變量)或空字符(對(duì)字符變量)。而對(duì)自動(dòng)變量而說(shuō),如果不賦初值則它的值是一個(gè)不確定的值。這是由于每次函數(shù)調(diào)用結(jié)束后存儲(chǔ)單元已釋放,下次調(diào)用時(shí)又重新另分配存儲(chǔ)單元,而所分配的單元中的值是不確定的。 (4)雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其他函數(shù)是不能引用它的。,,需要用靜態(tài)局部變量的情況如下。 (1)需要保留函數(shù)上一次調(diào)用結(jié)束時(shí)的值。 例8.18輸出1到5的階乘值 (2)如果初始化后,變量只被引用而不改變其值,則這時(shí)用靜態(tài)局部變量比較方便,以免每次調(diào)用時(shí)重新賦值。 但是應(yīng)該看到,用靜態(tài)存儲(chǔ)要多占內(nèi)存(長(zhǎng)期占用不釋放,而不能像動(dòng)態(tài)存儲(chǔ)那樣一個(gè)存儲(chǔ)單元可供多個(gè)變量使用,節(jié)約內(nèi)存),而且
28、降低了程序的可讀性,當(dāng)調(diào)用次數(shù)多時(shí)往往弄不清靜態(tài)局部變量的當(dāng)前值是什么。因此,若非必要,不要多用靜態(tài)局部變量。,8.9.4 register變量,一般情況下,變量(包括靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式)的值是存放在內(nèi)存中的。當(dāng)程序中用到哪一個(gè)變量的值時(shí),由控制器發(fā)出指令將內(nèi)存中該變量的值送到運(yùn)算器中。經(jīng)過(guò)運(yùn)算器進(jìn)行運(yùn)算,如果需要存數(shù),再?gòu)倪\(yùn)算器將數(shù)據(jù)送到內(nèi)存存放。 如果有一些變量使用頻繁(例如,在一個(gè)函數(shù)中執(zhí)行10000次循環(huán),每次循環(huán)中都要引用某局部變量),則為存取變量的值要花費(fèi)不少時(shí)間。為提高執(zhí)行效率,C語(yǔ)言允許將局部變量的值放在CPU中的寄存器中,需要用時(shí)直接從寄存器取出參加運(yùn)算,不必再到內(nèi)存
29、中去存取。由于對(duì)寄存器的存取速度遠(yuǎn)高于對(duì)內(nèi)存的存取速度,因此這樣做可以提高執(zhí)行效率。這種變量叫做寄存器變量,用關(guān)鍵字register作聲明。,例8.19使用寄存器變量,#include void main() long fac(long); long i, n; scanf(“%ld”, ,long fac(long n) register long i, f=1; for(i=1; i<=n; i++) f=f*i; return f; ,說(shuō)明:,(1)只有局部自動(dòng)變量和形式參數(shù)可以作為寄存器變量,其他(如全局變量)不行,在調(diào)用一個(gè)函數(shù)時(shí)占用一些寄存器以存放寄存器變量的值,函數(shù)調(diào)用結(jié)束釋放寄
30、存器。此后,在調(diào)用另一個(gè)函數(shù)時(shí)又可以利用它來(lái)存放該函數(shù)的寄存器變量。 (2)一個(gè)計(jì)算機(jī)系統(tǒng)中的寄存器數(shù)目是有限的,不能定義任意多個(gè)寄存器變量。不同的系統(tǒng)允許使用的寄存器數(shù)目是有限的,而且對(duì)register變量的處理方法也是不同的,有的系統(tǒng)對(duì)register變量當(dāng)作自動(dòng)變量處理,分配內(nèi)存單元,并不真正把它們存放在寄存器中,有的系統(tǒng)只允許將int、char和指針型變量定義為寄存器變量。 (3)局部靜態(tài)變量不能定義為寄存器變量。,8.9.5 用extern聲明外部變量,外部變量是在函數(shù)的外部定義的全局變量,它的作用域是從變量的定義處開(kāi)始,到本程序文件的末尾。在此作用域內(nèi),全局變量可以為程序中各個(gè)函數(shù)
31、所引用。編譯時(shí)將外部變量分配在靜態(tài)存儲(chǔ)區(qū)。 有時(shí)需要用extern來(lái)聲明外部變量,以擴(kuò)展外部變量的作用域。,1、在一個(gè)文件內(nèi)聲明外部變量,如果外部變量不在文件的開(kāi)頭定義,其有效的作用范圍只限于定義處到文件結(jié)束。如果在定義點(diǎn)之前的函數(shù)想引用該外部變量,則應(yīng)該在引用之前用關(guān)鍵字extern對(duì)該變量作“外部變量聲明”,表示該變量是一個(gè)已經(jīng)定義的外部變量。有了此聲明,就可以從“聲明”處起,合法地使用該外部變量。,例8.20用extern聲明外部變量,擴(kuò)展它在程序文件中的作用域,#include void main() int max(int, int); extern A, B; printf(“%d
32、n”, max(A, B)); int A=13, B=-8; int max(int x, int y) int z; z=xy ? x : y; return z; ,2、在多文件的程序中聲明外部變量,如果一個(gè)程序包含兩個(gè)文件,在兩個(gè)文件中都要用到同一個(gè)外部變量Num,不能分別在兩個(gè)文件中各自定義一個(gè)外部變量Num,否則在進(jìn)行程序的連接時(shí)會(huì)出現(xiàn)“重復(fù)定義”的錯(cuò)誤。正確的做法是:在任一個(gè)文件中定義外部變量Num,而在另一個(gè)文件中用extern對(duì)Num作“外部變量聲明”。即“extern Num;”。在編譯和連接時(shí),系統(tǒng)會(huì)由此知道Num是一個(gè)已在別處定義的外部變量,并將在另一文件中定義的外部變
33、量的作用域擴(kuò)展到本文件,在本文件中可以合法地引用外部變量Num。,例8.21用extern將外部變量的作用域擴(kuò)展到其他文件,#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”, ,extern A; int power(int n) int i, y=1; for(i=1; i<=n; i++) y*=A; return y; ,8.9.6 用static聲明外部變量,有時(shí)在程序設(shè)計(jì)中希望某些外部變
34、量只限于被本文件引用,而不能被其他文件引用。這時(shí)可以在定義外部變量時(shí)加一個(gè)static聲明。 例如: static int A;extern int A; void main()void fun(int n) A=A*n; ,8.9.7 關(guān)于變量的聲明和定義,對(duì)變量而言,聲明與定義的關(guān)系稍微復(fù)雜一些。在聲明部分出現(xiàn)的變量有兩種情況:一種是需要建立存儲(chǔ)空間的(如:int a;),另一種是不需要建立存儲(chǔ)空間(如:extern a;)。前者稱為“定義性聲明”,或簡(jiǎn)稱定義。后者稱為“引用性聲明”。廣義地說(shuō),聲明包括定義,但并非所有的聲明都是定義。對(duì)“int a;”而言,它既是聲明,又是定義。而對(duì)“e
35、xtern a;”而言,它是聲明而不是定義。一般為了敘述方便,把建立存儲(chǔ)空間的聲明稱定義,而把不需要建立存儲(chǔ)空間的聲明稱為聲明。顯然這里指的聲明是狹義的,即非定義性聲明。例如: void main() extern A; int A;,8.9.8 存儲(chǔ)類別小結(jié),從上可知,對(duì)一個(gè)數(shù)據(jù)的定義,需要指定兩種屬性:數(shù)據(jù)類型和存儲(chǔ)類別,分別使用兩個(gè)關(guān)鍵字。例如: static int a; auto char c; register int d; 此外,可以用extern聲明變量為已定義的外部變量,例如: extern b;,下面從不同角度做些歸納:,(1)從作用域角度分,有局部變量和全局變量。它們采
36、用的存儲(chǔ)類別如下: 局部變量: 自動(dòng)變量,即動(dòng)態(tài)局部變量(離開(kāi)函數(shù),值就消失) 靜態(tài)局部變量(離開(kāi)函數(shù),值仍保留) 寄存器變量(離開(kāi)函數(shù),值就消失) (形式參數(shù)可以定義為自動(dòng)變量和寄存器變量) 全局變量: 靜態(tài)外部變量(只限本文件引用) 外部變量(即非靜態(tài)的外部變量,允許其他文件引用),,(2)從變量存在的時(shí)間(生存期)來(lái)區(qū)分,有動(dòng)態(tài)存儲(chǔ)和靜態(tài)存儲(chǔ)兩種類型。靜態(tài)存儲(chǔ)是程序整個(gè)運(yùn)行時(shí)間都存在,而動(dòng)態(tài)存儲(chǔ)則是在調(diào)用函數(shù)時(shí)臨時(shí)分配單元。 動(dòng)態(tài)存儲(chǔ): 自動(dòng)變量(本函數(shù)內(nèi)有效) 寄存器變量(本函數(shù)內(nèi)有效) 形式參數(shù)(本函數(shù)內(nèi)有效) 靜態(tài)存儲(chǔ): 靜態(tài)局部變量(函數(shù)內(nèi)有效) 靜態(tài)外部變量(本文件內(nèi)有效) 外
37、部變量(其他文件可引用),,(3)從變量值存放的位置來(lái)區(qū)分,可分為: 內(nèi)存中靜態(tài)存儲(chǔ)區(qū): 靜態(tài)局部變量 靜態(tài)外部變量(函數(shù)外部靜態(tài)變量) 外部變量(可為其他文件引用) 內(nèi)存中動(dòng)態(tài)存儲(chǔ)區(qū): 自動(dòng)變量和形式參數(shù) CPU中的寄存器: 寄存器變量,,(4)對(duì)一個(gè)變量的性質(zhì)可以從兩個(gè)方面分析,一是變量的作用域,一是變量值存在時(shí)間的長(zhǎng)短,即生存期。前者是從空間的角度,后者是從時(shí)間的角度。二者有聯(lián)系但不是同一回事。 (5)static對(duì)局部變量和全局變量的作用不同。對(duì)局部變量來(lái)說(shuō),它使變量由動(dòng)態(tài)存儲(chǔ)方式改變?yōu)殪o態(tài)存儲(chǔ)方式。而對(duì)全局變量來(lái)說(shuō),它使變量局部化(局部于本文件),但仍為靜態(tài)存儲(chǔ)方式。從作用域角度看,
38、凡有static聲明的,其作用域都是局限的,或者是局限于本函數(shù)內(nèi)(靜態(tài)局部變量),或者局限于本文件內(nèi)(靜態(tài)外部變量)。,8.10 內(nèi)部函數(shù)和外部函數(shù),函數(shù)本質(zhì)上是全局的,因?yàn)橐粋€(gè)函數(shù)要被另外的函數(shù)調(diào)用,但是,也可以指定函數(shù)不能被其他文件調(diào)用。根據(jù)函數(shù)能否被其他源文件調(diào)用,將函數(shù)區(qū)分為內(nèi)部函數(shù)和外部函數(shù)。,8.10.1 內(nèi)部函數(shù),如果一個(gè)函數(shù)只能被本文件中其他函數(shù)所調(diào)用,它稱為內(nèi)部函數(shù)。在定義內(nèi)部函數(shù)時(shí),在函數(shù)名和函數(shù)類型的前面加static,即: static 類型標(biāo)識(shí)符 函數(shù)名(形參表); 內(nèi)部函數(shù)又稱靜態(tài)函數(shù),因?yàn)樗怯胹tatic聲明的。使用內(nèi)部函數(shù),可以使函數(shù)的作用域只局限于所在文件,
39、在不同的文件中有相同的內(nèi)部函數(shù),互補(bǔ)干擾。這樣不同的人可以分別編寫(xiě)不同的函數(shù),而不必?fù)?dān)心所用函數(shù)是否會(huì)與其他文件中函數(shù)同名。,8.10.2 外部函數(shù),(1)在定義函數(shù)時(shí),如果在函數(shù)首部的最左端加關(guān)鍵字extern,則表示此函數(shù)是外部函數(shù),可供其他文件調(diào)用。 (2)在需要引用此函數(shù)的文件中,用extern對(duì)函數(shù)作聲明,表示該函數(shù)是在其他文件中定義的外部函數(shù)。 例8.22有一個(gè)字符串,內(nèi)有若干個(gè)字符,今輸入一個(gè)字符,要求程序?qū)⒆址性撟址麆h去。用外部函數(shù)實(shí)現(xiàn)。,習(xí)題,8.3 寫(xiě)一個(gè)判素?cái)?shù)的函數(shù),在主函數(shù)輸入一個(gè)整數(shù),輸出是否素?cái)?shù)的信息。 8.4 寫(xiě)一個(gè)函數(shù),使給定的一個(gè)33的二維整型數(shù)組轉(zhuǎn)置,即行列互換。 8.5 寫(xiě)一個(gè)函數(shù),使輸入的一個(gè)字符串按反序存放,在主函數(shù)中輸入和輸出字符串。 8.6 寫(xiě)一個(gè)函數(shù),將兩個(gè)字符串連接。,,8.13 用遞歸方法求n階勒讓德多項(xiàng)式的值,遞歸公式為:,,此課件下載可自行編輯修改,供參考! 感謝您的支持,我們努力做得更好!,
- 溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 川渝旅游日記成都重慶城市介紹推薦景點(diǎn)美食推薦
- XX國(guó)有企業(yè)黨委書(shū)記個(gè)人述責(zé)述廉報(bào)告及2025年重點(diǎn)工作計(jì)劃
- 世界濕地日濕地的含義及價(jià)值
- 20XX年春節(jié)節(jié)后復(fù)工安全生產(chǎn)培訓(xùn)人到場(chǎng)心到崗
- 大唐女子圖鑒唐朝服飾之美器物之美繪畫(huà)之美生活之美
- 節(jié)后開(kāi)工第一課輕松掌握各要點(diǎn)節(jié)后常見(jiàn)的八大危險(xiǎn)
- 廈門(mén)城市旅游介紹廈門(mén)景點(diǎn)介紹廈門(mén)美食展示
- 節(jié)后開(kāi)工第一課復(fù)工復(fù)產(chǎn)十注意節(jié)后復(fù)工十檢查
- 傳統(tǒng)文化百善孝為先孝道培訓(xùn)
- 深圳城市旅游介紹景點(diǎn)推薦美食探索
- 節(jié)后復(fù)工安全生產(chǎn)培訓(xùn)勿忘安全本心人人講安全個(gè)個(gè)會(huì)應(yīng)急
- 預(yù)防性維修管理
- 常見(jiàn)閥門(mén)類型及特點(diǎn)
- 設(shè)備預(yù)防性維修
- 2.乳化液泵工理論考試試題含答案