C語(yǔ)言程序設(shè)計(jì)課件第11章_第1頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件第11章_第2頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件第11章_第3頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件第11章_第4頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件第11章_第5頁(yè)
已閱讀5頁(yè),還剩39頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第11章C語(yǔ)言的模塊化程序設(shè)計(jì)[Return]本章學(xué)習(xí)目標(biāo)掌握模塊化程序設(shè)計(jì)的基本方法。掌握全局變量和局部變量、動(dòng)態(tài)變量和靜態(tài)變量的概念和使用方法。掌握內(nèi)部函數(shù)和外部函數(shù)的概念和使用方法。掌握由多個(gè)源文件組成的C程序設(shè)計(jì)和編譯運(yùn)行方法。11.1程序設(shè)計(jì)的基本方法11.2C語(yǔ)言對(duì)模塊化編程的支持11.3多個(gè)源程序文件組成的C程序設(shè)計(jì)案例分析11.1程序設(shè)計(jì)的基本方法

結(jié)構(gòu)化程序設(shè)計(jì)方法是隨著結(jié)構(gòu)化程序設(shè)計(jì)語(yǔ)言(如PASCAL、C)的出現(xiàn)和發(fā)展而建立起來(lái)的,已經(jīng)被廣泛應(yīng)用于軟件系統(tǒng)的開(kāi)發(fā)。結(jié)構(gòu)化程序設(shè)計(jì)方法主要包括如下3個(gè)方面:1)自頂向下、逐步求精的設(shè)計(jì)過(guò)程。2)模塊化程序設(shè)計(jì)。3)結(jié)構(gòu)化編程。11.1.1自頂向下、逐步求精的設(shè)計(jì)過(guò)程所謂自頂向下、逐步求精的設(shè)計(jì)過(guò)程就是在進(jìn)行一個(gè)復(fù)雜系統(tǒng)的設(shè)計(jì)時(shí)采取先全局后局部、先整體后細(xì)節(jié)、先抽象后具體的分析設(shè)計(jì)方法,把系統(tǒng)分解為層次分明、結(jié)構(gòu)清晰、容易實(shí)現(xiàn)的若干個(gè)模塊,然后再將每一個(gè)模塊細(xì)化為若干個(gè)處理步驟或算法,直到可用程序設(shè)計(jì)語(yǔ)言的語(yǔ)句來(lái)編程實(shí)現(xiàn)。下面用一個(gè)簡(jiǎn)單例子說(shuō)明這種自頂向下、逐步求精的設(shè)計(jì)過(guò)程。【例11-1】設(shè)計(jì)一個(gè)簡(jiǎn)單的通訊錄管理程序?!舅悸穼?dǎo)航】首先將問(wèn)題分解成以下7個(gè)模塊:(1)主控模塊(2)菜單模塊(3)添加模塊(4)刪除模塊(5)修改模塊(6)顯示模塊

(7)保存模塊

然后,對(duì)這7個(gè)模塊再分別進(jìn)一步細(xì)化。主控模塊可細(xì)化為:(1)初始化;(2)循環(huán)等待用戶選擇菜單項(xiàng);(3)根據(jù)用戶選擇菜單項(xiàng)執(zhí)行相應(yīng)操作: 若是“添加”,則調(diào)用添加模塊; 若是“刪除”。則調(diào)用刪除模塊; 若是“修改”,則調(diào)用修改模塊; 若是“顯示”,則調(diào)用顯示模塊; 若是“保存”,則調(diào)用保存模塊; 若是“退出”,則結(jié)束程序。添加模塊可細(xì)化為:(1)查找(2)根據(jù)查找結(jié)果做出相應(yīng)操作:若該名字已存在,輸出提示信息;若該名字未存在,插入新記錄。刪除模塊可細(xì)化為:(1)查找(2)根據(jù)查找結(jié)果做出相應(yīng)操作:若該名字不存在,輸出提示信息;若該名字存在,刪除該記錄。修改模塊可細(xì)化為:(1)查找(2)根據(jù)查找結(jié)果做出相應(yīng)操作:若該名字不存在,輸出提示信息;若該名字存在,修改該記錄。保存模塊可細(xì)化為:(1)提示輸入文件名;(2)以寫(xiě)方式打開(kāi)該文件;(3)把數(shù)據(jù)寫(xiě)入該文件

最后,把各個(gè)子模塊再細(xì)化為具體的C語(yǔ)言語(yǔ)句。請(qǐng)看書(shū)中/*exam11_1*/。程序編譯運(yùn)行后的用戶界面如圖11-1所示。

[演示]圖11-111.1.2模塊化程序設(shè)計(jì)

1.什么是程序模塊?在軟件設(shè)計(jì)過(guò)程中,往往將一個(gè)大規(guī)模的程序劃分成若干個(gè)大小適當(dāng)?shù)某绦蚨稳ゾ帉?xiě),或者是將那些重復(fù)使用的程序段進(jìn)行獨(dú)立設(shè)計(jì),以達(dá)到計(jì)算機(jī)可以重復(fù)執(zhí)行,而設(shè)計(jì)人員又不必重復(fù)去編寫(xiě)的目的。這樣劃分的程序段被稱(chēng)為程序模塊。2.什么是模塊化程序設(shè)計(jì)?模塊化程序設(shè)計(jì)就是遵循一定的模塊分解和組織原則,把一個(gè)大程序分解為多個(gè)容易理解和實(shí)現(xiàn)的大小適當(dāng)、功能明確、具有一定獨(dú)立性的程序模塊的過(guò)程。(1)模塊分解原則在進(jìn)行模塊分解時(shí),要求各模塊功能盡可能專(zhuān)一,各模塊之間的聯(lián)系盡可能簡(jiǎn)單。模塊之間的聯(lián)系越簡(jiǎn)單,獨(dú)立性就越強(qiáng),就越容易獨(dú)立地進(jìn)行設(shè)計(jì)、維護(hù)和修改,程序的可維護(hù)性和可擴(kuò)展性就越好,程序設(shè)計(jì)的效率和質(zhì)量也就越高。(2)模塊組織原則結(jié)構(gòu)化程序設(shè)計(jì)方法要求按層次結(jié)構(gòu)組織各模塊。“自頂向下”地將一個(gè)大程序逐層分解,得到程序的模塊層次結(jié)構(gòu),而后再進(jìn)一步把每個(gè)模塊分解為具體的執(zhí)行模塊或執(zhí)行步驟。按層次組織模塊時(shí),一般較上層的模塊描述“做什么”,最底層的模塊才描述“如何做”。3.C語(yǔ)言的模塊化技術(shù)(1)C語(yǔ)言的模塊化粒度在C語(yǔ)言中,函數(shù)是實(shí)現(xiàn)程序模塊化的有力工具。一般地,一個(gè)函數(shù)實(shí)現(xiàn)一個(gè)模塊功能,一個(gè)模塊(或一個(gè)源程序文件)可以由多個(gè)函數(shù)組成。C語(yǔ)言的模塊粒度從小到大依次為:函數(shù)——源程序文件——程序,如圖11-1所示。C程序源程序文件1源程序文件2源程序文件n函數(shù)1函數(shù)2函數(shù)n……圖11-1(2)C語(yǔ)言編譯系統(tǒng)對(duì)模塊化的技術(shù)支持

C語(yǔ)言編譯系統(tǒng)提供了宏定義、文件包含、條件編譯等編譯預(yù)處理命令來(lái)實(shí)現(xiàn)編譯預(yù)處理,并且提供了豐富的庫(kù)函數(shù),為實(shí)現(xiàn)模塊化編程提供了極大的方便。(3)C語(yǔ)言對(duì)模塊化的技術(shù)支持

C語(yǔ)言提供函數(shù)和局部變量以實(shí)現(xiàn)模塊的包裝和獨(dú)立性(在第7章已介紹),提供全局變量以實(shí)現(xiàn)多個(gè)模塊之間的數(shù)據(jù)共享,提供extern聲明的全局變量和外部函數(shù)以擴(kuò)展其作用域從而提高模塊之間的函數(shù)和數(shù)據(jù)的共享性,提供static聲明的全局變量和內(nèi)部函數(shù)以限制其作用域從而提高模塊的相對(duì)獨(dú)立性。本章11.2節(jié)將重點(diǎn)討論這些技術(shù)的使用。11.1.3結(jié)構(gòu)化編程

結(jié)構(gòu)化編程是把任何程序的結(jié)構(gòu)都限制為順序、選擇和循環(huán)三種基本結(jié)構(gòu),以提高程序的可讀性和可靠性。一個(gè)結(jié)構(gòu)化程序應(yīng)當(dāng)具有以下特點(diǎn):(1)有一個(gè)入口、一個(gè)出口;(2)沒(méi)有死語(yǔ)句(永遠(yuǎn)執(zhí)行不到的語(yǔ)句),每一個(gè)語(yǔ)句應(yīng)當(dāng)至少有一條從入口到出口的路徑通過(guò)它;(3)沒(méi)有死循環(huán)(無(wú)限制的循環(huán))。在本書(shū)前面的章節(jié)已經(jīng)詳細(xì)介紹了順序結(jié)構(gòu)、選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)的程序設(shè)計(jì),這里就不再重復(fù)。11.2C語(yǔ)言對(duì)模塊化編程的支持11.2.1局部變量與全局變量1.定義變量的位置C語(yǔ)言中定義變量的位置基本上有三種:在函數(shù)體內(nèi)、函數(shù)體外和函數(shù)形式參數(shù)。在函數(shù)體內(nèi)定義的變量以及函數(shù)的形式參數(shù)都稱(chēng)作局部變量,在所有函數(shù)體外定義的變量稱(chēng)作全局變量。2.局部變量

局部變量只在定義它們的函數(shù)內(nèi)有效,在此函數(shù)之外不能使用它們。局部變量還可以在函數(shù)內(nèi)的復(fù)合語(yǔ)句中定義,此時(shí)局部變量只在定義它們的復(fù)合語(yǔ)句中有效。常常把起于左大括號(hào)“{”,止于右大括號(hào)“}”內(nèi)的語(yǔ)句塊統(tǒng)稱(chēng)為代碼塊,所以可以說(shuō),局部變量?jī)H在定義它們的代碼塊中有效。例如:fun1(){intz;/*z在函數(shù)fun1內(nèi)有效*/z=10;}fun2(intx,inty){intz;/*x,y,z在函數(shù)fun2內(nèi)有效*/z=x+y;returnz;}fun3(){intflag;/*flag在函數(shù)fun3內(nèi)有效*/scan(“%d”,flag);if(flag){chars[30];/*s僅在if語(yǔ)句塊中有效*/printf(“pleaseenterinformation:”);gets(s);…}}※注意:在C語(yǔ)言中,代碼塊中的局部變量必須在代碼塊開(kāi)始處定義,即變量的定義必須出現(xiàn)在其它非變量定義語(yǔ)句之前。而在c++中則不存在此限制,可以在任意地方定義變量。例如:fun(){inti;i=10;

intj;j=20;} j變量的定義出現(xiàn)在給i的賦值語(yǔ)句之后,在多數(shù)C編譯系統(tǒng)中會(huì)報(bào)告語(yǔ)法錯(cuò)誤。應(yīng)改為:fun(){inti;intj;i=10;j=20;}3.全局變量與局部變量不同,全局變量可以自定義位置起被本源文件中的其他所有函數(shù)使用,也可以用extern聲明后,在由多個(gè)文件組成的程序中被其它源文件使用(關(guān)于extern的作用在下一節(jié)關(guān)于變量存儲(chǔ)類(lèi)型中再詳細(xì)討論)?!纠?1-2】全局變量的作用范圍。代碼如下:/*exam11_2*/#include<stdio.h>intcount;/*定義全局變量count*/fun1(){inttemp;/*定義局部變量temp*/temp=count;/*引用全局變量count*/fun2();printf(“\ncountis%d,tempis%d”,count,temp);}inttemp;/*定義全局變量temp*/fun2(){intcount;/*局部變量count屏蔽了全局變量count*/for(count=1;count<=temp;count++)/*引用全局變量temp*/putchar(‘*’);}intmain(void){temp=10;/*對(duì)全局變量temp賦值*/count=100;/*對(duì)全局變量count賦值*/fun1();return0;}全局變量count的作用范圍全局變量temp的作用范圍[演示]

雖然main函數(shù)和fun1函數(shù)都沒(méi)有定義count,但由于在兩個(gè)函數(shù)之前定義了全局變量count,所以main和fun1都可以使用count;main和fun2函數(shù)都沒(méi)有定義temp,但由于在兩個(gè)函數(shù)之前定義了全局變量temp,所以main和fun2函數(shù)都可以使用temp;但是temp是在fun1之后才定義的全局變量,所以如果在fun1函數(shù)中企圖引用全局變量temp,則會(huì)報(bào)告出錯(cuò)。

fun2函數(shù)定義了與全局變量同名的局部變量count,所以全局變量count在fun2中被屏蔽,即不起作用,而只使用局部變量count。fun1函數(shù)定義了與全局變量同名的局部變量temp,全局變量temp在本函數(shù)無(wú)效,并且就算fun1函數(shù)內(nèi)沒(méi)有定義同名的局部變量temp,也不能引用全局變量temp,因?yàn)槿肿兞縯emp在fun1函數(shù)之后才定義(若使用extern聲明后擴(kuò)展了有效范圍則可以引用,參考下節(jié)關(guān)于變量的存儲(chǔ)類(lèi)型討論)。說(shuō)明:(1)使用全局變量的好處全局變量可以起到在不同函數(shù)間進(jìn)行數(shù)據(jù)傳遞的作用,尤其當(dāng)需要從一個(gè)函數(shù)返回多于一個(gè)的返回值時(shí)可以利用全局變量來(lái)實(shí)現(xiàn)。這是因?yàn)樵谝粋€(gè)函數(shù)中改變了全局變量的值,則會(huì)影響到所有使用該全局變量的函數(shù)。(2)使用全局變量的壞處①使用全局變量會(huì)使函數(shù)的通用性變。C語(yǔ)言的一大特點(diǎn)就是支持模塊化編程,通過(guò)函數(shù)和局部變量實(shí)現(xiàn)對(duì)代碼數(shù)據(jù)的包裝,函數(shù)之間除了通過(guò)參數(shù)傳遞數(shù)據(jù)外盡量不要有其它任何依賴關(guān)系,使得程序的移植性好,可讀性強(qiáng)。使用全局變量則使函數(shù)之間的依賴變強(qiáng),降低程序的通用性。②在程序中大量使用全局變量容易引起程序錯(cuò)誤,因?yàn)楦鱾€(gè)函數(shù)執(zhí)行時(shí)都可能改變?nèi)肿兞康闹担菀桩a(chǎn)生副作用。③全局變量在程序的整個(gè)執(zhí)行期間占用存儲(chǔ)單元,而不像局部變量只在需要時(shí)占用存儲(chǔ)空間。鑒于上述原因,建議非不得已時(shí)不使用全局變量?!纠?1-3】通過(guò)全局變量從函數(shù)得到多于一個(gè)的返回值。編寫(xiě)一個(gè)函數(shù),能夠求出一組整數(shù)中的最大值和最小值。【思路導(dǎo)航】因?yàn)橥ㄟ^(guò)函數(shù)的return語(yǔ)句只能返回一個(gè)值,所以把另一個(gè)結(jié)果賦給一個(gè)全局變量,從而達(dá)到返回兩個(gè)結(jié)果的目的。/*exam11_3*/intMax=0; /*定義全局變量*/intminimum(intarray[],intn){intmin,j;Max=min=array[0];for(j=0;j<n;j++){if(min>array[j])min=array[j];elseif(Max<array[j])Max=array[j];}returnmin;}intmain(void){inta[10],k;for(k=0;k<10;k++)scanf(“%d”,a+k);printf(“Max=%d\nmin=%d\n”,Max,minimum(a,10));return0;}[演示]12345678910↙Max=10min=1運(yùn)行情況

※注意:上面主函數(shù)中的printf函數(shù)的參數(shù)的前后位置。若把Max放在minimum(a,10)的右邊,則得不到正確結(jié)果,因?yàn)镃函數(shù)的參數(shù)運(yùn)算順序是從右到左,所以應(yīng)把minimum(a,10)放在Max的右邊,這樣才能先調(diào)用minimum函數(shù)從而同時(shí)得到最大值和最小值的結(jié)果。

11.2.2變量的存儲(chǔ)類(lèi)型

在C語(yǔ)言中,每一個(gè)變量有兩個(gè)屬性:數(shù)據(jù)類(lèi)型和數(shù)據(jù)的存儲(chǔ)類(lèi)型。數(shù)據(jù)類(lèi)型是指數(shù)據(jù)被定義為整形、字符型、實(shí)數(shù)型等,前面已詳細(xì)介紹過(guò)。存儲(chǔ)類(lèi)型是指數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方法,分為兩大類(lèi):靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ)。所謂靜態(tài)存儲(chǔ)是指在程序運(yùn)行期間分配固定存儲(chǔ)空間的方式;動(dòng)態(tài)存儲(chǔ)是指根據(jù)需要進(jìn)行存儲(chǔ)空間分配,不需要時(shí)即釋放存儲(chǔ)空間的方式。變量的存儲(chǔ)類(lèi)型具體又分為四種類(lèi)型,四種類(lèi)型說(shuō)明符如下:auto(自動(dòng))register(寄存器)static(靜態(tài))extern(外部)動(dòng)態(tài)存儲(chǔ)靜態(tài)存儲(chǔ)一般以如下形式對(duì)變量進(jìn)行聲明:存儲(chǔ)類(lèi)型說(shuō)明符數(shù)據(jù)類(lèi)型變量名;如:autointa,b;staticintc=1;1.auto變量

函數(shù)的局部變量,如果不作static存儲(chǔ)類(lèi)型聲明,都是動(dòng)態(tài)分配存儲(chǔ)空間的;函數(shù)的形式參數(shù)也是動(dòng)態(tài)分配存儲(chǔ)空間的,兩者都是在函數(shù)調(diào)用時(shí)系統(tǒng)給它們分配存儲(chǔ)空間,在函數(shù)結(jié)束時(shí)系統(tǒng)自動(dòng)釋放這些存儲(chǔ)空間。所以這類(lèi)局部變量和形式參數(shù)都屬于auto(自動(dòng))變量。這類(lèi)局部變量可用auto關(guān)鍵字聲明,例如:intfun(intm){autointj,k;/*定義j,k為自動(dòng)變量,auto可以省略不寫(xiě)*/…}

關(guān)鍵字auto可以省略不寫(xiě),系統(tǒng)把沒(méi)有進(jìn)行static聲明的局部變量和形式參數(shù)默認(rèn)為自動(dòng)型變量。

2.用extern聲明全局變量

全局變量是在所有函數(shù)的外部定義的,它的作用范圍是從定義位置起到本文件結(jié)束處,全局變量是靜態(tài)分配存儲(chǔ)空間的,使用extern可以擴(kuò)展全局變量的作用范圍。

為了解決不同文件可以使用同一個(gè)全局變量的問(wèn)題,常在一個(gè)文件中聲明所有的全局變量,在其他文件中使用extern聲明來(lái)自本文件之外的全局變量。如圖11-2所示。文件2中利用extern聲明x和y為來(lái)自其它文件的全局變量,編譯程序在編譯時(shí)不再為這些變量分配存儲(chǔ)空間,但是鏈接時(shí)會(huì)自動(dòng)從外部模塊中引用這些變量。用extern聲明外部變量時(shí),類(lèi)型名可以不寫(xiě)。在同一個(gè)文件中,當(dāng)全局變量在使用它的函數(shù)之后定義時(shí),也可以在使用它的函數(shù)中利用extern對(duì)該變量做全局變量聲明,如文件1中的全局變量z。3.static變量

用static聲明的變量為靜態(tài)變量,其存儲(chǔ)空間是系統(tǒng)在編譯時(shí)靜態(tài)分配的,生存期為整個(gè)程序的執(zhí)行期。static對(duì)局部變量和全局變量所起作用不同。下面分別介紹(1) static局部變量使用static聲明局部變量時(shí),編譯系統(tǒng)為其分配固定存儲(chǔ)單元,函數(shù)結(jié)束后變量所占空間不會(huì)被系統(tǒng)自動(dòng)釋放,也就是該變量的值可以被該函數(shù)再次使用。這對(duì)于某些需要在函數(shù)調(diào)用之間保持局部變量值的函數(shù)來(lái)說(shuō)是非常重要的?!纠?1-4】數(shù)據(jù)系列產(chǎn)生器。

下面函數(shù)f_series()每次產(chǎn)生一個(gè)新數(shù),這個(gè)新數(shù)比上次值增加3,使用這個(gè)函數(shù)可以產(chǎn)生一個(gè)差為3、第一個(gè)數(shù)為10的等差數(shù)列。/*exam11_4*/#include<stdio.h>f_series(){staticintnumber=10;number+=3;return(number);}intmain(void){intk;for(k=0;k<10;k++)printf(“%d ”,f_series()-3);return0;}[演示]10131619222528313437運(yùn)行結(jié)果

首次進(jìn)入函數(shù)代碼時(shí)給局部變量number賦初值10,以后再次調(diào)用該函數(shù)時(shí)不再賦初值,而且number在整個(gè)程序運(yùn)行期間一直存在,每次調(diào)用函數(shù)f_series()時(shí)新生成的數(shù)number都是在前次調(diào)用結(jié)束時(shí)的number值加上3?!⒁猓涸诤瘮?shù)調(diào)用之間如果需要某些數(shù)值保持可用,可以使用全局變量。但由于全局變量對(duì)所有函數(shù)開(kāi)放,容易引起副作用。所以,如果需要保留函數(shù)上一次調(diào)用結(jié)束時(shí)變量的值,最好是使用static局部變量,因?yàn)殡m然static局部變量在函數(shù)調(diào)用結(jié)束后依然存在,但是只有本函數(shù)可以使用,其它函數(shù)不可使用,從而避免副作用。(2) static全局變量

在全局變量前加上static存儲(chǔ)類(lèi)型說(shuō)明符,限定了該變量只在本文件中有效,只有本文件的所有函數(shù)可以使用它。其它文件的函數(shù)無(wú)法使用它,修改它,從而可以消除副作用?!纠?1-5】改寫(xiě)例11-4?!舅悸穼?dǎo)航】例11-4中函數(shù)f_series()所產(chǎn)生的系列只能是從10開(kāi)始,如果我們需要產(chǎn)生從任意指定數(shù)開(kāi)始的數(shù)據(jù)系列,則需要使用一個(gè)全局變量number和一個(gè)給number賦初值的函數(shù)。為了滿足這個(gè)要求,改寫(xiě)如下:首先用指定起始值調(diào)用f_setstart(),初始化數(shù)據(jù)系列發(fā)生器,然后再連續(xù)調(diào)用f_series()產(chǎn)生等差數(shù)據(jù)系列。代碼如下:/*exam11_5*/#include<stdio.h>staticintnumber;/*定義全局變量number*/

f_setstart(intstart)/*指定number的起始值*/{number=start;}f_series(){number+=3;returnnumber;}(續(xù))intmain(void){intk,start;printf(“inputthestart:”);scanf(“%d”,&start);start=start-3;f_setstart(start);printf(“%ntheseriesare:”);for(k=0;k<10;k++)printf(“%5d”,f_series());return0;}[演示]inputthestart:5↙theseriesare:581114172023262932運(yùn)行結(jié)果

想一想:為什么主函數(shù)中要使用start=start-3;這條語(yǔ)句?4.register變量

一般情況下,變量的值存放在內(nèi)存單元中。但是有一些使用頻繁的變量,比如循環(huán)控制變量和循環(huán)體內(nèi)反復(fù)引用的局部變量,如果循環(huán)的次數(shù)很多,對(duì)這些變量存取時(shí)要消耗很多的時(shí)間,為了提高程序的執(zhí)行效率,C語(yǔ)言允許將局部變量的值存放在CPU的寄存器中,這樣可以直接從寄存器取出這些變量,從而大大提高存取的速度。

只有局部自動(dòng)變量和形式參數(shù)可以聲明為register變量,對(duì)全局變量和靜態(tài)局部變量不能聲明為register類(lèi)型,也就是說(shuō)寄存器變量是動(dòng)態(tài)存儲(chǔ)類(lèi)型?!⒁猓阂?yàn)閞egister變量可以保存在寄存器中,所以對(duì)這類(lèi)變量不能使用取址操作符&取它的地址。另外,實(shí)際上大多數(shù)系統(tǒng)register只對(duì)整型和字符型變量起作用。當(dāng)今優(yōu)化的編譯系統(tǒng)能夠自動(dòng)識(shí)別使用頻繁的變量,從而將這些變量存放在寄存器中,并不需要編程者指定。

11.2.3內(nèi)部函數(shù)與外部函數(shù)

1.函數(shù)的存儲(chǔ)分類(lèi)

函數(shù)也可以像變量一樣,通過(guò)static和extern聲明改變它的作用范圍。只能被本文件的其它函數(shù)調(diào)用的函數(shù)被稱(chēng)為內(nèi)部函數(shù),能被其它文件中的函數(shù)調(diào)用的函數(shù)稱(chēng)為外部函數(shù)。(1)內(nèi)部函數(shù)

聲明內(nèi)部函數(shù)時(shí),在函數(shù)名和函數(shù)類(lèi)型的前面加static。static類(lèi)型標(biāo)識(shí)符函數(shù)名(形參列表)

例如:staticintfun(intm,intn)

內(nèi)部函數(shù)又叫靜態(tài)函數(shù),和靜態(tài)全局變量一樣,由于在它們的前面使用static聲明,使得其它文件不能引用它們,從而使得在不同的文件可以使用相同的文件名而不會(huì)產(chǎn)生干擾。這也是C語(yǔ)言支持程序模塊化設(shè)計(jì)的一個(gè)特點(diǎn)?!纠?1-7】?jī)?nèi)部函數(shù)舉例。/*exam11_7*//*file1.c*/staticintfun(intx,inty) /*聲明函數(shù)fun為內(nèi)部函數(shù)*/{intz;z=x+y;returnz;}intmain(void){externfun1(int,int);intm,n,s;m=10;n=20;printf(“%d+%d=%d\n”,m,n,fun(m,n));printf(“%d*%d=%d\n”,m,n,fun1(m,n));}/*file2.c*/staticintfun(intx,inty)/*聲明函數(shù)fun為內(nèi)部函數(shù)*/{intz;z=x*y;returnz;}intfun1(intm,intn){returnfun(m,n);}該程序由兩個(gè)文件file1.c和file2.c組成,file1.c中的函數(shù)fun和file2.c中的函數(shù)fun同名,但是fun函數(shù)在兩個(gè)文件中的功能不同,由于在各自文件中作了static聲明,所以互不干擾。file2.c中的函數(shù)fun1沒(méi)有作static聲明,所以可以被file1.c中的main函數(shù)調(diào)用。[演示]10+20=3010*20=200運(yùn)行結(jié)果:

注意要使用Changedir修改為file1和file2所在目錄,同時(shí)輸入“Projectname”為exam11_7.prj。(2)外部函數(shù)

聲明外部函數(shù)時(shí),在函數(shù)名和函數(shù)類(lèi)型的前面加extern。 extern類(lèi)型標(biāo)識(shí)符函數(shù)名(形參列表)

例如:externintfun(intm,intn)

外部函數(shù)可以被其它文件的函數(shù)調(diào)用。C語(yǔ)言規(guī)定,如果在定義函數(shù)時(shí)省略extern,則隱含為外部函數(shù)。雖然在定義外部函數(shù)時(shí)可以省略extern,但是在調(diào)用其它文件的函數(shù)時(shí)要用extern聲明所用函數(shù)為外部函數(shù)或者利用函數(shù)原型進(jìn)行聲明?!纠?1-8】外部函數(shù)舉例。

利用外部函數(shù)實(shí)現(xiàn):輸入一個(gè)字符串,然后把字符串中所有數(shù)字字符刪掉。/*exam11_8*//*file1.c*/voidinput(chars[])/*定義外部函數(shù)input*/{gets(s);/*輸入字符串s*/}voiddelete(chars[])/*定義外部函數(shù)delete*/{intj,k;for(j=k=0;s[j])!=’\0’;j++) if(!(s[j]>=’0’&&s[j]<=’9’))/*不是數(shù)字字符則保留*/ s[k++]=s[j];s[k]=’\0’;/*存放字符串結(jié)束符*/}(續(xù))/*file2.c*/intmain(void){externinput(chars[]);externdelete(chars[]);chars[80];input(s);delete(s);printf(”%s”,s);return0;}/*聲明在本函數(shù)中將要調(diào)用的在其他文件中定義的函數(shù)input()和delete()*/[演示]abcd1276efgh7i4k90lmn65opq8↙abcdefghiklmnopq運(yùn)行結(jié)果:

注意要使用Changedir修改為file1和file2所在目錄,同時(shí)輸入“Projectname”為exam11_8.prj。11.3多個(gè)源程序文件組成的C程序設(shè)計(jì)

在進(jìn)行模塊化程序設(shè)計(jì)過(guò)程中,應(yīng)遵循以下幾個(gè)原則:

1.每個(gè)功能模塊必須只有單一入口和單一出口;

2.盡可能使用形式參數(shù)向函數(shù)傳遞信息,而不使用全局變量;

3.若有一些函數(shù)必須使用全局變量時(shí),最好把這些全局變量和相關(guān)函數(shù)放入單獨(dú)的一個(gè)文件中,并且將全局變量聲明為static;

4.每個(gè)函數(shù)必須能夠?yàn)檎{(diào)用者報(bào)告自己操作的狀態(tài),即報(bào)告調(diào)用是否成功等。

另外,在大型程序設(shè)計(jì)中,往往一個(gè)程序包含的函數(shù)個(gè)數(shù)非常龐大,要查找到所需函數(shù)非常不容易,所以有必要將所有函數(shù)進(jìn)行分類(lèi)存放。一般將在概念或功能上相關(guān)的函數(shù)組織成一個(gè)文件(源文件,也叫一個(gè)模塊)。例如,在一個(gè)通訊錄管理程序中,可以將所有關(guān)于信息輸入的函數(shù)存放在一個(gè)文件中;將所有關(guān)于信息查找的函數(shù)放在一個(gè)文件中;將所有關(guān)于刪除的函數(shù)放在一個(gè)文件中,等等。

下面舉一個(gè)簡(jiǎn)單的例子說(shuō)明如何進(jìn)行多個(gè)源程序組成的C程序設(shè)計(jì)以及編譯運(yùn)行?!纠?1-9】下面是法國(guó)數(shù)學(xué)家加思帕提出來(lái)的一個(gè)趣味問(wèn)題。

溫馨提示

  • 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. 人人文庫(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論