版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第8章函數(shù)(hánshù)
8.1概述 一個(gè)較大的程序一般應(yīng)分為若干個(gè)程序模塊,每一個(gè)模塊用來實(shí)現(xiàn)一個(gè)特定的功能。所有(suǒyǒu)的高級(jí)語(yǔ)句中都有子程序這個(gè)概念,用子程序?qū)崿F(xiàn)模塊的功能。在C語(yǔ)言中,子程序的作用是由函數(shù)來完成的。一個(gè)C程序可由一個(gè)主函數(shù)和若干個(gè)其他函數(shù)構(gòu)成。由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以相互調(diào)用。同一個(gè)函數(shù)可以被一個(gè)或多個(gè)函數(shù)調(diào)用任意多次。 在程序設(shè)計(jì)中,常將一些常用的功能模塊編寫成函數(shù),放在公共函數(shù)庫(kù)中供大家選用。程序設(shè)計(jì)人員要善于利用函數(shù),以減少重復(fù)編寫程序段的工作量。精品資料[例8.1]函數(shù)調(diào)用的簡(jiǎn)單(jiǎndān)例子#include<stdio.h>voidmain(){ voidprintstar(); voidprint_message(); printstar(); print_message(); printstar();}voidprintstar(){ printf(“**********\n”);}voidprint_message(){ printf(“Howdoyoudo!\n”);}精品資料說明(shuōmíng): (1)一個(gè)C程序由一個(gè)或多個(gè)程序模塊組成,每一個(gè)程序模塊作為一個(gè)源程序文件。對(duì)較大的程序,一般不希望把所有內(nèi)容全放在一個(gè)文件中,而是將它們放在若干個(gè)源文件中,再由若干個(gè)源程序文件組成一個(gè)C程序。一個(gè)源程序文件可以為多個(gè)C程序共用。 (2)一個(gè)源程序文件由一個(gè)或多個(gè)函數(shù)以及其他有關(guān)內(nèi)容(如命令行、數(shù)據(jù)定義等)組成。一個(gè)源程序是一個(gè)編譯單位,在程序編譯時(shí)是以源程序文件為單位進(jìn)行編譯的,而不是以函數(shù)為單位進(jìn)行編譯的。 (3)C程序的執(zhí)行是從main函數(shù)開始的,如是在main函數(shù)中調(diào)用其他函數(shù),在調(diào)用后流程返回到main函數(shù),在main函數(shù)中結(jié)束整個(gè)程序的運(yùn)行(yùnxíng)。 (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)提供的,用戶不必自己定義而直接使用它們。②用戶自己定義的函數(shù)。它是用以解決用戶專門需要的函數(shù)。(6)從函數(shù)的形式看,函數(shù)分兩類。①無參函數(shù)。在調(diào)用(diàoyòng)無參函數(shù)時(shí),主調(diào)函數(shù)不向被調(diào)用(diàoyòng)函數(shù)傳遞數(shù)據(jù)。無參函數(shù)一般用來執(zhí)行指定的一組操作。無參函數(shù)可以帶回或不帶會(huì)函數(shù)值,但一般以不帶回函數(shù)值的居多。②有參函數(shù)。在調(diào)用(diàoyòng)函數(shù)時(shí),主調(diào)函數(shù)在調(diào)用(diàoyòng)被調(diào)用(diàoyòng)函數(shù)時(shí),通過參數(shù)向被調(diào)用(diàoyòng)函數(shù)傳遞數(shù)據(jù),一般情況下,執(zhí)行被調(diào)用(diàoyòng)函數(shù)時(shí)會(huì)得到一個(gè)函數(shù)值,供主調(diào)函數(shù)使用。精品資料8.2函數(shù)定義的一般(yībān)形式
8.2.1無參函數(shù)定義的一般(yībān)形式 定義無參函數(shù)(hánshù)的一般形式為: 類型標(biāo)識(shí)符函數(shù)(hánshù)名() { 聲明部分 語(yǔ)句部分 } 在定義函數(shù)(hánshù)時(shí)要用“類型標(biāo)識(shí)符”指定函數(shù)(hánshù)值的類型,即函數(shù)(hánshù)帶回來的值的類型。精品資料8.2.2有參函數(shù)定義的一般(yībān)形式定義有參函數(shù)的一般形式為:類型標(biāo)識(shí)符函數(shù)名(形式參數(shù)表列){ 聲明(shēngmíng)部分 語(yǔ)句部分}例如:intmax(intx,inty){ intz; z=x>y?x:y; returnz;}精品資料8.2.3空函數(shù)(hánshù)在程序設(shè)計(jì)(chénɡxùshèjì)中有時(shí)會(huì)用到空函數(shù),它的形式為: 類型說明符函數(shù)名() { }精品資料8.3函數(shù)(hánshù)參數(shù)和函數(shù)(hánshù)的值
8.3.1形式參數(shù)和實(shí)際參數(shù) 在調(diào)用函數(shù)(hánshù)時(shí),大多數(shù)情況下,主調(diào)函數(shù)(hánshù)和被調(diào)用函數(shù)(hánshù)之間有數(shù)據(jù)傳遞關(guān)系。在定義函數(shù)(hánshù)時(shí)函數(shù)(hánshù)名后面括號(hào)中的變量名稱為“形式參數(shù)”(簡(jiǎn)稱“形參”),在主調(diào)函數(shù)(hánshù)中調(diào)用一個(gè)函數(shù)(hánshù)時(shí),函數(shù)(hánshù)名后面括號(hào)中的參數(shù)(可以是一個(gè)表達(dá)式)稱為“實(shí)際參數(shù)”(簡(jiǎn)稱“實(shí)參”)。精品資料[例8.2]調(diào)用函數(shù)時(shí)的數(shù)據(jù)(shùjù)傳遞#include<stdio.h>voidmain(){ intmax(intx,inty); inta,b,c; scanf(“%d,%d”,&a,&b); c=max(a,b); printf(“Maxis%d”,c);}intmax(intx,inty){ intz; z=x>y?x:y; returnz;}精品資料關(guān)于形參與(cānyù)實(shí)參的說明: (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á)式。但要求它們有確定的值。在調(diào)用時(shí)將實(shí)參的值賦給形參。 (3)在被定義的函數(shù)中,必須指定形參的類型。 (4)實(shí)參與形參的類型應(yīng)相同或賦值兼容。 (5)實(shí)參向形參的數(shù)據(jù)傳遞是“值傳遞”,單向傳遞,只由實(shí)參傳給形參,而不能由形參傳回來給實(shí)參。在內(nèi)存中,實(shí)參單元與形參單元是不同的單元。在調(diào)用函數(shù)時(shí),給形參分配存儲(chǔ)單元,并將實(shí)參對(duì)應(yīng)的值傳遞給形參,調(diào)用結(jié)束后,形參單元被釋放,實(shí)參單元仍保留并維持(wéichí)原值。因此,在執(zhí)行一個(gè)被調(diào)用函數(shù)時(shí),形參的值如果發(fā)生改變,并不會(huì)改變主調(diào)函數(shù)的實(shí)參的值。精品資料8.3.2函數(shù)(hánshù)的返回值 通過函數(shù)調(diào)用使主調(diào)函數(shù)能得到一個(gè)確定的值,這就是函數(shù)的返回值。 (1)函數(shù)的返回值是通過函數(shù)中的return語(yǔ)句獲得的。return語(yǔ)句將被調(diào)用函數(shù)中的一個(gè)確定值帶回主調(diào)函數(shù)中去。 (2)函數(shù)值的類型。既然函數(shù)有返回值,這個(gè)值當(dāng)然應(yīng)屬于某一個(gè)確定的類型,應(yīng)當(dāng)在定義函數(shù)時(shí)指定(zhǐdìng)函數(shù)值的類型。 (3)在定義函數(shù)時(shí)指定(zhǐdìng)的函數(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ù)(hánshù)類型不同#include<stdio.h>voidmain(){ intmax(flaotx,floaty); floata,b; intc; scanf(“%f,%f”,&a,&b); c=max(a,b); printf(“Maxis%d\n”,c);}intmax(floatx,floaty){ floatz; z=x>y?x:y; returnz;}精品資料 (4)對(duì)于不帶回值的函數(shù),應(yīng)當(dāng)用“void”定義函數(shù)為“無類型”(或稱“空類型”)。這樣,系統(tǒng)(xìtǒng)就保證不使函數(shù)帶回任何值,即禁止調(diào)用函數(shù)中使用被調(diào)用函數(shù)的返回值。此時(shí)在函數(shù)體中不得出現(xiàn)return語(yǔ)句。精品資料8.4函數(shù)(hánshù)的調(diào)用
8.4.1函數(shù)(hánshù)調(diào)用的一般形式 函數(shù)調(diào)用的一般形式為 函數(shù)名(實(shí)參表列); 如果是調(diào)用無參函數(shù),則“實(shí)參表列”可以沒有,但括號(hào)不能省略。如果實(shí)參表列包含多個(gè)實(shí)參,則各參數(shù)(cānshù)間用逗號(hào)隔開。實(shí)參與形參的個(gè)數(shù)應(yīng)相等,類型應(yīng)匹配。實(shí)參與形參按順序?qū)?yīng),一一傳遞數(shù)據(jù)。但應(yīng)說明,如果實(shí)參表列包括多個(gè)實(shí)參,對(duì)實(shí)參求值的順序并不是確定的,有的系統(tǒng)按自左至右順序求實(shí)參的值,有的系統(tǒng)則按自右至左順序。精品資料[例8.4]實(shí)參求值的順序(shùnxù)#include<stdio.h>voidmain(){ intf(inta,intb); inti=2,p; p=f(i,++i); printf(“%d\n”,p);}intf(inta,intb){ intc; if(a>b)c=1; elseif(a==b)c=0; elsec=-1; returnc;}精品資料8.4.2函數(shù)調(diào)用的方式(fāngshì) 按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調(diào)用方式。 1.函數(shù)語(yǔ)句(yǔjù) 把函數(shù)調(diào)用作為一個(gè)語(yǔ)句(yǔjù)。這時(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ù)(hánshù)的聲明和函數(shù)(hánshù)原型 在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)需要具備的條件如下。 (1)首先被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù)(是庫(kù)函數(shù)或用戶自己定義的函數(shù))。但光有這一條件還不夠。 (2)如果使用庫(kù)函數(shù),還應(yīng)該在本文件開頭用#include命令(mìnglìng)將調(diào)用有關(guān)庫(kù)函數(shù)時(shí)所需用到的信息“包含”到本文件中去。 (3)如果使用用戶自己定義的函數(shù),而該函數(shù)的位置在調(diào)用它的函數(shù)(即主調(diào)函數(shù))的后面(在同一個(gè)文件中),應(yīng)該在主調(diào)函數(shù)中對(duì)被調(diào)用的函數(shù)作聲明。精品資料[例8.5]對(duì)被調(diào)用的函數(shù)(hánshù)作聲明#include<stdio.h>voidmain(){ floatadd(floatx,floaty); floata,b,c; scanf(“%f,%f”,&a,&b); c=add(a,b); printf(“sumis%f\n”,c);}floatadd(floatx,floaty){ floatz; z=x+y; returnz;}精品資料 在函數(shù)調(diào)用(diàoyòng)之前用函數(shù)原型做了函數(shù)聲明。因此編譯系統(tǒng)記下了所需調(diào)用(diàoyòng)的函數(shù)的有關(guān)信息。編譯系統(tǒng)根據(jù)函數(shù)的原型對(duì)函數(shù)的調(diào)用(diàoyòng)的合法性進(jìn)行全面的檢查。與函數(shù)原型不匹配的函數(shù)調(diào)用(diàoyòng)會(huì)導(dǎo)致編譯出錯(cuò),它屬于語(yǔ)法錯(cuò)誤。用戶根據(jù)屏幕顯示的出錯(cuò)信息很容易發(fā)現(xiàn)和糾正錯(cuò)誤。精品資料 函數(shù)原型的一般形式有兩種,分別(fēnbié)為 (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ōmíng): (1)如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必加以(jiāyǐ)聲明。 (2)如果已在文件的開頭(在所有函數(shù)之前),已對(duì)本文件中所調(diào)用的函數(shù)進(jìn)行了聲明,則在各函數(shù)中不必對(duì)其所調(diào)用的函數(shù)再作聲明。精品資料8.5函數(shù)(hánshù)的嵌套調(diào)用 C語(yǔ)言的函數(shù)定義是相互平行、獨(dú)立(dúlì)的。在定義函數(shù)時(shí),一個(gè)函數(shù)內(nèi)不能包含另一個(gè)函數(shù)。 C語(yǔ)言不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),在調(diào)用一個(gè)函數(shù)的過程中,又調(diào)用另一個(gè)函數(shù)。精品資料[例8.6]函數(shù)(hánshù)嵌套調(diào)用的應(yīng)用精品資料8.6函數(shù)(hánshù)的遞歸調(diào)用 在調(diào)用一個(gè)函數(shù)的過程中又出現(xiàn)直接(zhíjiē)或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。精品資料[例8.7]有5個(gè)人坐在一起,問第5個(gè)人多少歲?他說比第4個(gè)人大2歲。問第4個(gè)人歲數(shù)(suìshu),他說比第3個(gè)人大2歲。問第3個(gè)人,又說比第2個(gè)人大2歲。問第2個(gè)人,說比第1個(gè)人大2歲。最后問第1個(gè)人,他說是10歲。請(qǐng)問第5個(gè)人多大精品資料[例8.8]用遞歸方法(fāngfǎ)求n!精品資料[8.9]Hanoi塔問題。古代有一個(gè)梵塔,塔內(nèi)有3個(gè)座A、B、C,開始(kāishǐ)時(shí)A座上有64個(gè)盤子,盤子大小不等,大的在下,小的在上。有一個(gè)老和尚想把這64個(gè)盤子從A座移到C座,但每次只允許移動(dòng)一個(gè)盤,且在移動(dòng)過程中在3個(gè)座上都始終保持大盤在下,小盤在上。在移動(dòng)過程中可以利用B座,要求編程序輸出移動(dòng)的步驟精品資料8.7數(shù)組作為(zuòwéi)函數(shù)參數(shù) 前面已經(jīng)介紹了可以用變量作函數(shù)參數(shù),顯然,數(shù)組元素也可以作函數(shù)參數(shù),其用法(yònɡfǎ)與變量相同。此外,數(shù)組名也可以作實(shí)參和形參,傳遞的是數(shù)組首元素的地址。精品資料8.7.1數(shù)組元素(yuánsù)作函數(shù)實(shí)參 由于實(shí)參可以是表達(dá)式,而數(shù)組元素可以是表達(dá)式的組成部分,因此數(shù)組元素當(dāng)然可以作為函數(shù)的實(shí)參,與用變量作實(shí)參一樣,是單向傳遞,即“值傳送”方式。 [例8.10]有兩個(gè)數(shù)組a和b,各有10個(gè)元素,將它們對(duì)應(yīng)地逐個(gè)比較(bǐjiào)(即a[0]與b[0]比,a[1]與b[1]比……)。如果a數(shù)組中的元素大于b數(shù)組中的相應(yīng)元素的數(shù)目多于b數(shù)組中元素大于a數(shù)組中相應(yīng)元素的數(shù)目(例如,a[i]>b[i]6次,b[i]>a[i]3次,其中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ù)組名或用指針(zhǐzhēn)變量。 [例8.11]有一個(gè)一維數(shù)組score,內(nèi)放10個(gè)學(xué)生成績(jī),求平均成績(jī)精品資料說明(shuōmíng): (1)用數(shù)組名作函數(shù)參數(shù),應(yīng)該(yīnggāi)在主調(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ù)組的首元素的地址傳給形參數(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)存(nèicún)單元。形參數(shù)組中各元素的值如發(fā)生變化會(huì)使實(shí)參數(shù)組元素的值同時(shí)發(fā)生變化。精品資料[例8.13]用選擇法對(duì)數(shù)組中10個(gè)整數(shù)按由小到大排序。所謂選擇法就是先將10個(gè)數(shù)中最小的數(shù)與a[0]對(duì)換;再將a[1]到a[9]中最小的數(shù)與a[1]對(duì)換……每比較(bǐjiào)一輪,找出一個(gè)未經(jīng)排序的數(shù)中最小的一個(gè)。共比較(bǐjiào)9輪精品資料8.7.3多維數(shù)組名作函數(shù)參數(shù) 多維數(shù)組元素可以作函數(shù)參數(shù)。 用多維數(shù)組名作為函數(shù)的實(shí)參和形參,在被調(diào)用函數(shù)中對(duì)形參數(shù)組定義時(shí)可以指定每一維的大小,也可以省略第一維的大小說明。但是不能把第二維以及(yǐjí)其他高維的大小說明省略。精品資料[例8.14]有一個(gè)3×4矩陣(jǔzhèn),求所有元素最大值 先使變量max的初值為矩陣中第一個(gè)元素的值,然后將矩陣中各個(gè)元素的值與max相比,每次比較后都把“大者”存放(cúnfàng)在max中,全部元素比較完后,max的值就是所有元素的最大值。精品資料8.8局部變量和全局變量
8.8.1局部變量 在一個(gè)函數(shù)內(nèi)部定義的變量是內(nèi)部變量,它只在本函數(shù)范圍內(nèi)有效(yǒuxiào),也就是說只有在本函數(shù)內(nèi)才能使用它們,在此函數(shù)以外是不能使用這些變量的。這稱為“局部變量”。例如: floatf1(inta){ intb,c; …… } charf2(intx,inty){ inti,j; …… } voidmain(){ intm,n; …… }精品資料說明(shuōmíng): (1)主函數(shù)中定義的變量也只在主函數(shù)中有效,而不因?yàn)樵谥骱瘮?shù)中定義而在整個(gè)文件或程序中有效。主函數(shù)也不能使用其他(qítā)函數(shù)中定義的變量。 (2)不同函數(shù)中可以使用相同名字的變量,它們代表不同的對(duì)象,互不干擾。 (3)形式參數(shù)也是局部變量。 (4)在一個(gè)函數(shù)內(nèi)部,可以在復(fù)合語(yǔ)句中定義變量,這些變量只在本復(fù)合語(yǔ)句中有效,這種復(fù)合語(yǔ)句也稱為“分程序”或“程序塊”。精品資料8.8.2全局變量 程序的編譯單位是源程序文件,一個(gè)源文件可以包含一個(gè)或若干個(gè)函數(shù)。在函數(shù)內(nèi)定義的變量是局部變量,而在函數(shù)之外定義的變量稱為外部變量,外部變量是全局變量。全局變量可以為本文件中其他函數(shù)所共用。它的有效(yǒuxiào)范圍為從定義變量的位置開始到本源文件結(jié)束。精品資料例如(lìrú):intp=1,q=5;floatf1(inta){ intb,c; ……}charc1,c2;charf2(intx,inty){ inti,j; ……}voidmain(){ intm,n; ……}精品資料說明(shuōmíng): (1)設(shè)置全局變量的作用是增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道。 [例8.15]有一個(gè)一維數(shù)組,內(nèi)放10個(gè)學(xué)生成績(jī),寫一個(gè)函數(shù),求出平均分、最高分和最低分 (2)建議不在必要時(shí)不要使用全局變量,原因如下: ①全局變量在程序的全部(quánbù)執(zhí)行過程中都占用存儲(chǔ)單元,而不是僅在需要時(shí)才開辟單元。 ②它使函數(shù)的通用性降低了,因?yàn)楹瘮?shù)在執(zhí)行時(shí)要依賴于其所在的外部變量。 ③使用全局變量過多,會(huì)降低程序的清晰性,難以清除地判斷出每個(gè)瞬時(shí)各個(gè)外部變量的值。 (3)如果在同一個(gè)源文件中,外部變量與局部變量同名,則在局部變量的作用范圍內(nèi),外部變量被“屏蔽”,即它不起作用。 [例8.16]外部變量與局部變量同名精品資料8.9變量的存儲(chǔ)類別(lèibié)
8.9.1動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式 從變量(biànliàng)的作用域(即從空間)角度來分,可以分為全局變量(biànliàng)和局部變量(biànliàng)。 從變量(biànliàng)值存在的時(shí)間(即生存期)角度來分,可以分為靜態(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)(dòngtài)存儲(chǔ)區(qū) 數(shù)據(jù)分別存放在靜態(tài)存儲(chǔ)區(qū)和動(dòng)態(tài)(dòngtài)存儲(chǔ)區(qū)中。全局變量全部存放在靜態(tài)存儲(chǔ)區(qū)中,在程序開始執(zhí)行時(shí)給全局變量分配存儲(chǔ)區(qū),程序執(zhí)行完畢就釋放。在程序執(zhí)行過程中它們占據(jù)固定的存儲(chǔ)單元,而不是動(dòng)態(tài)(dòngtài)地進(jìn)行分配和釋放。
精品資料 在動(dòng)態(tài)存儲(chǔ)區(qū)中存放以下數(shù)據(jù): ①函數(shù)形式參數(shù)。在調(diào)用函數(shù)時(shí)給形參分配存儲(chǔ)空間。 ②自動(dòng)變量(未加static聲明的局部變量) ③函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)保護(hù)和返回地址(dìzhǐ)等。 對(duì)以上這些數(shù)據(jù),在函數(shù)調(diào)用開始時(shí)分配動(dòng)態(tài)存儲(chǔ)空間,函數(shù)結(jié)束時(shí)釋放這些空間。在程序執(zhí)行過程中,這種分配和釋放是動(dòng)態(tài)的,如果在一個(gè)程序中兩次調(diào)用同一函數(shù),分配給此函數(shù)中局部變量的存儲(chǔ)空間地址(dìzhǐ)可能是不同的。如果一個(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ǔ)類和動(dòng)態(tài)存儲(chǔ)類。具體包含4種:自動(dòng)的(auto)、靜態(tài)的(static)、寄存器的(register)、外部的(extern)。根據(jù)(gēnjù)變量的存儲(chǔ)類別,可以知道變量的作用域和生存期。精品資料8.9.2auto變量(biànliàng) 函數(shù)中的局部變量,如果不專門聲明為static存儲(chǔ)類別,都是動(dòng)態(tài)地分配存儲(chǔ)空間的,數(shù)據(jù)存儲(chǔ)在動(dòng)態(tài)存儲(chǔ)區(qū)中。函數(shù)中的形參和在函數(shù)中定義的變量(包括(bāokuò)在復(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ǔ)類別的聲明。精品資料例如(lìrú):intf(inta){ autointb,c=3; ……}精品資料8.9.3用static聲明(shēngmíng)局部變量 有時(shí)希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留(bǎoliú)原值,即其占用的存儲(chǔ)單元不釋放,在下一次該函數(shù)調(diào)用時(shí),該變量已有值,就是上一次函數(shù)調(diào)用結(jié)束時(shí)的值。這時(shí)就應(yīng)該指定該局部變量為“靜態(tài)局部變量”,用關(guān)鍵字static進(jìn)行聲明。精品資料[例8.17]考察(kǎochá)靜態(tài)局部變量的值#include<stdio.h>voidmain(){ intf(int); inta=2,i; for(i=0;i<3;i++) printf(“%d“,f(a));}intf(inta){ autointb=0; staticintc=3; b=b+1; c=c+1; return(a+b+c);}精品資料對(duì)靜態(tài)(jìngtài)局部變量的說明 (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é)束(jiéshù)后即釋放。 (2)對(duì)靜態(tài)局部變量是在編譯時(shí)賦初值的,即只賦初值一次,在程序運(yùn)行時(shí)它已有初值。以后每次調(diào)用函數(shù)時(shí)不再重新賦初值而只是保留上次函數(shù)調(diào)用結(jié)束(jiéshù)時(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)局部變量來說,編譯時(shí)自動(dòng)賦初值0(對(duì)數(shù)值型變量)或空字符(對(duì)字符變量)。而對(duì)自動(dòng)變量而說,如果不賦初值則它的值是一個(gè)不確定的值。這是由于每次函數(shù)調(diào)用結(jié)束(jiéshù)后存儲(chǔ)單元已釋放,下次調(diào)用時(shí)又重新另分配存儲(chǔ)單元,而所分配的單元中的值是不確定的。 (4)雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束(jiéshù)后仍然存在,但其他函數(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)存),而且降低了程序的可讀性,當(dāng)調(diào)用次數(shù)多時(shí)往往弄不清靜態(tài)局部變量的當(dāng)前值是什么。因此,若非(ruòfēi)必要,不要多用靜態(tài)局部變量。精品資料8.9.4register變量(biànliàng) 一般情況下,變量(包括靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式)的值是存放在內(nèi)存中的。當(dāng)程序中用到哪一個(gè)變量的值時(shí),由控制器發(fā)出指令將內(nèi)存中該變量的值送到運(yùn)算器中。經(jīng)過運(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í)直接從寄存器取出參加(cānjiā)運(yùn)算,不必再到內(nèi)存中去存取。由于對(duì)寄存器的存取速度遠(yuǎn)高于對(duì)內(nèi)存的存取速度,因此這樣做可以提高執(zhí)行效率。這種變量叫做寄存器變量,用關(guān)鍵字register作聲明。
精品資料[例8.19]使用(shǐyòng)寄存器變量#include<stdio.h>voidmain(){ longfac(long); longi,n; scanf(“%ld”,&n); for(i=1;i<=n;i++) printf(“%ld!=%ld\n”,i,fac(i));}longfac(longn){ registerlongi,f=1; for(i=1;i<=n;i++) f=f*i; returnf;}精品資料說明(shuōmíng): (1)只有局部自動(dòng)變量和形式參數(shù)可以(kěyǐ)作為寄存器變量,其他(如全局變量)不行,在調(diào)用一個(gè)函數(shù)時(shí)占用一些寄存器以存放寄存器變量的值,函數(shù)調(diào)用結(jié)束釋放寄存器。此后,在調(diào)用另一個(gè)函數(shù)時(shí)又可以(kěyǐ)利用它來存放該函數(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ēngmíng)外部變量 外部變量是在函數(shù)的外部定義的全局變量,它的作用域是從變量的定義處開始,到本程序文件的末尾。在此作用域內(nèi),全局變量可以(kěyǐ)為程序中各個(gè)函數(shù)所引用。編譯時(shí)將外部變量分配在靜態(tài)存儲(chǔ)區(qū)。 有時(shí)需要用extern來聲明外部變量,以擴(kuò)展外部變量的作用域。精品資料1、在一個(gè)文件內(nèi)聲明外部(wàibù)變量 如果外部變量不在文件的開頭定義,其有效的作用范圍只限于定義處到文件結(jié)束。如果在定義點(diǎn)之前的函數(shù)想引用該外部變量,則應(yīng)該在引用之前用關(guān)鍵字extern對(duì)該變量作“外部變量聲明”,表示該變量是一個(gè)已經(jīng)(yǐjing)定義的外部變量。有了此聲明,就可以從“聲明”處起,合法地使用該外部變量。精品資料[例8.20]用extern聲明(shēngmíng)外部變量,擴(kuò)展它在程序文件中的作用域#include<stdio.h>voidmain(){ intmax(int,int); externA,B; printf(“%d\n”,max(A,B));}intA=13,B=-8;intmax(intx,inty){ intz; z=x>y?x:y; returnz;}精品資料2、在多文件的程序(chéngxù)中聲明外部變量 如果一個(gè)程序包含兩個(gè)文件,在兩個(gè)文件中都要用到同一個(gè)外部變量Num,不能分別在兩個(gè)文件中各自定義(dìngyì)一個(gè)外部變量Num,否則在進(jìn)行程序的連接時(shí)會(huì)出現(xiàn)“重復(fù)定義(dìngyì)”的錯(cuò)誤。正確的做法是:在任一個(gè)文件中定義(dìngyì)外部變量Num,而在另一個(gè)文件中用extern對(duì)Num作“外部變量聲明”。即“externNum;”。在編譯和連接時(shí),系統(tǒng)會(huì)由此知道Num是一個(gè)已在別處定義(dìngyì)的外部變量,并將在另一文件中定義(dìngyì)的外部變量的作用域擴(kuò)展到本文件,在本文件中可以合法地引用外部變量Num。精品資料[例8.21]用extern將外部(wàibù)變量的作用域擴(kuò)展到其他文件#include<stdio.h>intA;voidmain(){ intpower(int); intb=3,c,d,m; printf(“enterthenumberaanditspowerm:\n”); scanf(“%d,%d”,&A,&m); c=A*b; printf(“%d**%d=%d\n”,A,m,d);}externA;intpower(intn){ inti,y=1; for(i=1;i<=n;i++) y*=A; returny;}精品資料8.9.6用static聲明(shēngmíng)外部變量 有時(shí)在程序設(shè)計(jì)中希望(xīwàng)某些外部變量只限于被本文件引用,而不能被其他文件引用。這時(shí)可以在定義外部變量時(shí)加一個(gè)static聲明。 例如: file1.c file2.c staticintA; externintA; voidmain() voidfun(intn) { { …… …… } A=A*n; …… }精品資料8.9.7關(guān)于(guānyú)變量的聲明和定義 對(duì)變量而言,聲明與定義的關(guān)系稍微復(fù)雜一些。在聲明部分出現(xiàn)的變量有兩種情況:一種是需要建立存儲(chǔ)空間的(如:inta;),另一種是不需要建立存儲(chǔ)空間(如:externa;)。前者稱為“定義性聲明”,或簡(jiǎn)稱定義。后者稱為“引用(yǐnyòng)性聲明”。廣義地說,聲明包括定義,但并非所有的聲明都是定義。對(duì)“inta;”而言,它既是聲明,又是定義。而對(duì)“externa;”而言,它是聲明而不是定義。一般為了敘述方便,把建立存儲(chǔ)空間的聲明稱定義,而把不需要建立存儲(chǔ)空間的聲明稱為聲明。顯然這里指的聲明是狹義的,即非定義性聲明。例如: voidmain() { externA; …… } intA;精品資料8.9.8存儲(chǔ)類別(lèibié)小結(jié) 從上可知,對(duì)一個(gè)數(shù)據(jù)的定義,需要指定兩種屬性:數(shù)據(jù)類型和存儲(chǔ)類別,分別使用兩個(gè)關(guān)鍵字。例如: staticinta; autocharc; registerintd; 此外,可以(kěyǐ)用extern聲明變量為已定義的外部變量,例如: externb;精品資料下面(xiàmian)從不同角度做些歸納: (1)從作用域角度分,有局部變量和全局變量。它們采用(cǎiyòng)的存儲(chǔ)類別如下: 局部變量: 自動(dòng)變量,即動(dòng)態(tài)局部變量(離開函數(shù),值就消失) 靜態(tài)局部變量(離開函數(shù),值仍保留) 寄存器變量(離開函數(shù),值就消失) (形式參數(shù)可以定義為自動(dòng)變量和寄存器變量) 全局變量: 靜態(tài)外部變量(只限本文件引用) 外部變量(即非靜
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025合同違約賠償協(xié)議書10篇
- 公司股份轉(zhuǎn)讓協(xié)議書七篇
- 公司盤活閑置資產(chǎn)和清收清欠工作專題會(huì)講話
- 單位租車協(xié)議書標(biāo)準(zhǔn)范本7篇
- 自發(fā)性細(xì)菌性腹膜炎病因介紹
- (立項(xiàng)備案申請(qǐng)模板)低溫預(yù)浸纖維項(xiàng)目可行性研究報(bào)告參考范文
- 1.1《沁園春·長(zhǎng)沙》【中職專用】高一語(yǔ)文(高教版2023基礎(chǔ)模塊上冊(cè))
- (2024)旅游集散中心建設(shè)項(xiàng)目申請(qǐng)報(bào)告可行性研究報(bào)告(一)
- 房屋構(gòu)造識(shí)圖與建模- 趙靖 任務(wù)三 基礎(chǔ)類型與 構(gòu)61課件講解
- 2023年浸漬、涂布或包覆處理紡織物項(xiàng)目融資計(jì)劃書
- 污水廠電氣安全培訓(xùn)課件
- 應(yīng)對(duì)突發(fā)事件技巧
- 2024中國(guó)遠(yuǎn)洋海運(yùn)集團(tuán)校園招聘995人高頻考題難、易錯(cuò)點(diǎn)模擬試題(共500題)附帶答案詳解
- 廣告學(xué)專業(yè)大學(xué)生職業(yè)規(guī)劃
- 二年級(jí)道法無紙化測(cè)評(píng)方案
- 施工合同范本W(wǎng)ord模板下載(多篇)
- (打印版)小學(xué)二年級(jí)上-連加連減加減混合帶小括號(hào)-練習(xí)題
- 小組合作學(xué)習(xí)在初中道德與法治程中的應(yīng)用研究
- 《無償獻(xiàn)血招募》課件
- 《學(xué)術(shù)論文撰寫》課件
- 接納他人的主題班會(huì)
評(píng)論
0/150
提交評(píng)論