版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
C程序設(shè)計(jì)語(yǔ)言第4章函數(shù)與程序結(jié)構(gòu)孫志崗
sun@
2024/5/51FunctionsandProgramStructure第1頁(yè)大話三國(guó)懿問(wèn)曰:“孔明寢食及事之煩簡(jiǎn)若何?”
使者曰:“丞相夙興夜寐,罰二十以上皆親覽焉。所啖之食,日不過(guò)數(shù)升。”
懿顧謂諸將曰:“孔明食少事煩,其能久乎?”第2頁(yè)程序設(shè)計(jì)藝術(shù)算法設(shè)計(jì)藝術(shù)程序靈魂DonaldE.Knuth,"TheArtofComputerProgramming",清華大學(xué)出版社,結(jié)構(gòu)設(shè)計(jì)藝術(shù)程序肉體“..thelargertheproject,themoreessentialthestructuring!”—Dijkstra,1968模塊化(Parnas,1972)結(jié)構(gòu)化(Structural)面向?qū)ο螅∣bject-Oriented)面向組件(Component-Oriented)面向智能體(Agent-Oriented)……第3頁(yè)假如不模塊化讀多少行程序能讓你不頭疼?main()當(dāng)中能放多少行程序?假如printf()函數(shù)由10行代碼替換,那么你見(jiàn)過(guò)程序會(huì)成什么樣子?假如全部代碼都在main()當(dāng)中,怎么團(tuán)體合作?假如代碼都在一個(gè)文件中,怎么團(tuán)體合作?第4頁(yè)模塊化優(yōu)點(diǎn)模塊各司其職每個(gè)模塊只負(fù)責(zé)一件事情,它能夠更專心便于進(jìn)行單個(gè)模塊設(shè)計(jì)、開(kāi)發(fā)、調(diào)試、測(cè)試和維護(hù)等工作一個(gè)模塊一個(gè)模塊地完成,最終再將它們集成開(kāi)發(fā)人員各司其職按模塊分配任務(wù),職責(zé)明確并行開(kāi)發(fā),縮短開(kāi)發(fā)時(shí)間分而治之(Wirth,1971)
信息隱藏(Parnas,1972)第5頁(yè)函數(shù)(function)和模塊(module)函數(shù)是C語(yǔ)言中模塊化編程最小單位能夠把每個(gè)函數(shù)看作一個(gè)模塊若干相關(guān)函數(shù)能夠合并作一個(gè)“模塊”main()printf()scanf()power()putchar()getchar()main()stdio:printf()scanf()putchar()getchar()mymdl:power()第6頁(yè)函數(shù)分類函數(shù)生來(lái)都是平等,沒(méi)有高低貴賤之分,只有main()稍微特殊一點(diǎn)點(diǎn)1、按定義分:標(biāo)準(zhǔn)函數(shù)、自定義函數(shù)2、按調(diào)用分:無(wú)參調(diào)用、有參調(diào)用3、按功效分:無(wú)值返回、有值返回第7頁(yè)庫(kù)函數(shù)ANSIC定義標(biāo)準(zhǔn)庫(kù)函數(shù)符合標(biāo)準(zhǔn)C語(yǔ)言編譯器必須提供這些函數(shù)函數(shù)行為也要符合ANSIC定義第三方庫(kù)函數(shù)由其它廠商自行開(kāi)發(fā)C語(yǔ)言函數(shù)庫(kù)不在標(biāo)準(zhǔn)范圍內(nèi),能擴(kuò)充C語(yǔ)言功效自定義函數(shù)自己編寫函數(shù)包裝后,也可成為函數(shù)庫(kù),供他人使用第8頁(yè)函數(shù)定義兩種形式[類型]函數(shù)名([形式參數(shù)表])形式參數(shù)說(shuō)明{函數(shù)體[return()]}1、傳統(tǒng)格調(diào)(1)有參函數(shù)(傳統(tǒng)格調(diào)、當(dāng)代格調(diào))
intmax(x,y)intx,y;{intz;z=x>y?x:y;return(z);
}
第9頁(yè)[類型]函數(shù)名([類型參數(shù)1,類型參數(shù)2,….]){函數(shù)體;[return表示式;]}2、當(dāng)代格調(diào)(ANSI新標(biāo)準(zhǔn),當(dāng)前慣用)
intmax(intx,inty){intz;z=x>y?x:y;return(z);
}
第10頁(yè)函數(shù)定義(definition)類型函數(shù)名(類型參數(shù)1,類型參數(shù)2,……)
{
函數(shù)體;
return
表示式;
}返回值類型標(biāo)識(shí)符參數(shù)表返回值函數(shù)出口第11頁(yè)類型標(biāo)識(shí)符函數(shù)名(){說(shuō)明部分語(yǔ)句}無(wú)參數(shù)傳遞(2)無(wú)參函數(shù)比如:voidprintstar(){printf(“***”);}第12頁(yè)1、函數(shù)名前面類型實(shí)際上是返回值類型當(dāng)函數(shù)無(wú)返回值時(shí),可用void
定義為“無(wú)類型”或“空類型”。當(dāng)函數(shù)有返回值時(shí),必須定義函數(shù)類型,并一定有return語(yǔ)句說(shuō)明:例:voidprintstar(){printf(“***”);}第13頁(yè)2、若為無(wú)參函數(shù),則形參列表為空,但括號(hào)不能省略。見(jiàn)上例3、若為有參函數(shù),則必須有形參表及形參說(shuō)明。第14頁(yè)4、形參說(shuō)明兩種形式:如:下面對(duì)形式參數(shù)說(shuō)明都是錯(cuò)誤:(1)max(x,y)(2)main(intx,y)intx;intmax(x,y)intx,y;注意兩種形式差異?。?!
intmax(intx,inty)或第15頁(yè)intmax(x,y)intx,y;
{intz;
z=x>y?x:y;return(z);}如:intmax(int
x,inty)
{intz;
z=x>y?x:y;return(z);}5、形參說(shuō)明與函數(shù)體內(nèi)說(shuō)明一定要分別說(shuō)明。第16頁(yè)函數(shù)類型
函數(shù)定義時(shí)應(yīng)該指定函數(shù)類型,應(yīng)該與return語(yǔ)句類型一致。假如函數(shù)類型和return語(yǔ)句類型不一致,以函數(shù)類型為準(zhǔn)。對(duì)數(shù)值型數(shù)據(jù),能夠自動(dòng)進(jìn)行類型轉(zhuǎn)換。既函數(shù)類型決定返回值類型。凡不加類型說(shuō)明函數(shù),一律自動(dòng)按整型處理。假如函數(shù)不返回值,能夠?qū)⒑瘮?shù)定義為“無(wú)類型”void。比如voidprintstar()第17頁(yè)函數(shù)返回值1、函數(shù)返回值是經(jīng)過(guò)函數(shù)中return語(yǔ)句取得,return語(yǔ)句將被調(diào)函數(shù)一個(gè)確定值帶回主調(diào)函數(shù)中去。
若無(wú)值返回可省略return語(yǔ)句或只用return。2、返回值表示式類型應(yīng)與定義函數(shù)類型相一致。語(yǔ)法:return(返回值表示式);第18頁(yè)3、函數(shù)值與返回值類型不一樣,則以函數(shù)類型為準(zhǔn)。4、一個(gè)函數(shù)中允許有多個(gè)return語(yǔ)句,程序執(zhí)行到哪個(gè)return語(yǔ)句,哪個(gè)語(yǔ)句起作用。5、return語(yǔ)句后面括弧能夠不要,比如returnz;6、main()函數(shù)向調(diào)用進(jìn)程(普通是操作系統(tǒng))返回一個(gè)整數(shù)。第19頁(yè)關(guān)于函數(shù)函數(shù)是這么一個(gè)運(yùn)算:函數(shù)名說(shuō)明運(yùn)算規(guī)則參數(shù)是運(yùn)算操作數(shù)返回值是運(yùn)算結(jié)果當(dāng)函數(shù)執(zhí)行到return語(yǔ)句或}時(shí),函數(shù)運(yùn)算停頓。返回到調(diào)用它地方繼續(xù)向下執(zhí)行函數(shù)能夠有多個(gè)return,但最好只有一個(gè)且是最終一行第20頁(yè)
用void定義返回值類型函數(shù)沒(méi)有運(yùn)算結(jié)果,沒(méi)有返回值return語(yǔ)句之后不需要任何表示式
用void定義參數(shù),表示沒(méi)有參數(shù)函數(shù)內(nèi)部能夠定義只能自己使用變量,稱內(nèi)部變量。參數(shù)表里參數(shù)(形式參數(shù))也是函數(shù)語(yǔ)句塊內(nèi)變量關(guān)于函數(shù)第21頁(yè)函數(shù)名命名規(guī)則在Linux/Unix平臺(tái)習(xí)慣用function_name
本書采取Windows格調(diào)函數(shù)名命名用大寫字母開(kāi)頭、大小寫混排單詞組合而成FunctionName
變量名形式“名詞”或者“形容詞+名詞”如變量名oldValue與newValue等函數(shù)名形式“動(dòng)詞”或者“動(dòng)詞+名詞”(動(dòng)賓詞組)如函數(shù)名GetMax()等第22頁(yè)對(duì)函數(shù)接口加以注釋說(shuō)明/*函數(shù)功效:實(shí)現(xiàn)××××功效函數(shù)參數(shù):參數(shù)1,表示×××××參數(shù)2,表示×××××
函數(shù)返回值:×××××*/返回值類型函數(shù)名(參數(shù)表){
函數(shù)體
return
表示式;}第23頁(yè)例:計(jì)算兩個(gè)整數(shù)平均數(shù)/*
函數(shù)功效:計(jì)算平均數(shù)函數(shù)入口參數(shù):整型x,存放第一個(gè)運(yùn)算數(shù)整型y,存放第二個(gè)運(yùn)算數(shù)函數(shù)返回值:平均數(shù)*/intAverage(intx,inty){
intresult; result=(x+y)/2;
returnresult;}第24頁(yè)形式參數(shù)和實(shí)際參數(shù)形式參數(shù):在定義函數(shù)時(shí)函數(shù)名后面括弧中變量名,簡(jiǎn)稱形參。實(shí)際參數(shù):在調(diào)用函數(shù)時(shí)函數(shù)名后面括弧中表示式,簡(jiǎn)稱實(shí)參。函數(shù)參數(shù)第25頁(yè)
例
main()max(intx,inty)
{{intz;inta,b,c;z=x>y?x:y;scanf(“%d,%d”,&a,&b);return(z);
c=max(a,b);
}printf(“Maxis%d”,c);}運(yùn)行結(jié)果:7,8Maxis8
第26頁(yè)參數(shù)傳遞——單向值傳遞值傳遞——函數(shù)參數(shù)為基本數(shù)據(jù)類型時(shí)地址傳遞
——函數(shù)參數(shù)為數(shù)組名、指針類型時(shí)第27頁(yè)單向值傳遞調(diào)用函數(shù)時(shí),必須提供全部參數(shù)printf和scanf是采取變長(zhǎng)變量表定義函數(shù),所以變量個(gè)數(shù)不固定。提供參數(shù)個(gè)數(shù)、類型、次序應(yīng)與定義時(shí)相同第28頁(yè)在函數(shù)調(diào)用前,形參不占內(nèi)存單元,調(diào)用時(shí)占用,調(diào)用后釋放。形參變量和實(shí)參變量占用不一樣內(nèi)存單元(傳值)定義函數(shù)時(shí),必須指定形參類型。實(shí)參必須有確定值,能夠是常量,變量或表示式。在調(diào)用時(shí)將實(shí)參值賦給形參變量。關(guān)于參數(shù)幾點(diǎn)說(shuō)明:形參和實(shí)參區(qū)分——第29頁(yè)實(shí)參加形參應(yīng)匹配(次序、類型、個(gè)數(shù))實(shí)參對(duì)形參數(shù)據(jù)傳遞若是單向傳遞,只由實(shí)參傳遞給形參,調(diào)用結(jié)束后,只有形參單元被釋放,實(shí)參單元中值不變。若是地址傳遞,可了解為實(shí)參加形參共用同一存放單元。(這一點(diǎn)在學(xué)習(xí)數(shù)組、指針時(shí)請(qǐng)注意聽(tīng))。形參和實(shí)參區(qū)分——第30頁(yè)
c=max(a,b);-----------------------max(intx,inty){……returu(z);}
實(shí)參:在運(yùn)行時(shí)把值傳給函數(shù)形參:通知系統(tǒng)要預(yù)留內(nèi)存位置把函數(shù)結(jié)果賦給函數(shù)名形參加實(shí)參、函數(shù)名與返回值之間關(guān)系第31頁(yè)函數(shù)調(diào)用(call)函數(shù)名(表示式1,表示式2,……);調(diào)用一個(gè)函數(shù)之前,先要對(duì)其返回值類型、函數(shù)名和參數(shù)進(jìn)行申明(declare)不對(duì)函數(shù)進(jìn)行申明是非常危險(xiǎn)函數(shù)定義也有申明函數(shù)效果調(diào)用函數(shù)時(shí),提供表示式(叫實(shí)際參數(shù),argument)和該函數(shù)形式參數(shù)必須匹配數(shù)目一致類型一一對(duì)應(yīng)(會(huì)發(fā)生自動(dòng)類型轉(zhuǎn)換)表示式值賦值給對(duì)應(yīng)參數(shù)返回值能夠按需處理realeql.c第32頁(yè)第33頁(yè)函數(shù)調(diào)用普通形式1.函數(shù)調(diào)用普通形式為:
有參函數(shù):函數(shù)名(實(shí)參表列);
無(wú)參函數(shù):函數(shù)名();2.相關(guān)要求:多個(gè)實(shí)參間用逗號(hào)隔開(kāi)實(shí)參加形參間個(gè)數(shù)相等,類型應(yīng)一致實(shí)參加形參按次序?qū)?yīng),一一傳遞數(shù)據(jù)函數(shù)調(diào)用(CALL)第34頁(yè)1.函數(shù)語(yǔ)句:
把函數(shù)調(diào)用作為一個(gè)語(yǔ)句。此時(shí)不要求函數(shù)帶回值,只要求函數(shù)完成一定操作。
比如:printstar();max(a,b)2.函數(shù)表示式:
函數(shù)出現(xiàn)在一個(gè)表示式中,這種表示式稱為函數(shù)表示式。這時(shí)要求函數(shù)帶回一個(gè)確定值以參加表示式運(yùn)算。
比如:c=3+max(a,b);3.函數(shù)參數(shù):(函數(shù)嵌套調(diào)用)函數(shù)調(diào)用作為一個(gè)函數(shù)實(shí)參。比如:m=max(a,max(b,c));函數(shù)調(diào)用方式第35頁(yè)
函數(shù)嵌套調(diào)用
嵌套調(diào)用:在調(diào)用一個(gè)函數(shù)過(guò)程中,又調(diào)用另一個(gè)函數(shù)。函數(shù)是相互平行,C語(yǔ)言要求函數(shù)不能嵌套定義,但能夠嵌套調(diào)用。第36頁(yè)main函數(shù)調(diào)用A函數(shù)結(jié)束A函數(shù)調(diào)用B函數(shù)B函數(shù)192873456兩層嵌套示意圖第37頁(yè)函數(shù)每次執(zhí)行都會(huì)建立一個(gè)全新獨(dú)立環(huán)境為函數(shù)每個(gè)變量(包含形式參數(shù))分配內(nèi)存把實(shí)際參數(shù)值復(fù)制給形式參數(shù)開(kāi)始執(zhí)行函數(shù)內(nèi)第一條語(yǔ)句函數(shù)內(nèi)代碼在這個(gè)獨(dú)立環(huán)境內(nèi)工作函數(shù)退出時(shí)求出返回值,將其存入一個(gè)能夠被調(diào)用者訪問(wèn)地方(x86中通常使用EAX存放器)收回分配給全部變量(包含形式參數(shù))內(nèi)存程序控制權(quán)交給調(diào)用者,調(diào)用者拿到返回值,將其作為函數(shù)調(diào)用表示式結(jié)果函數(shù)調(diào)用過(guò)程第38頁(yè)main()C語(yǔ)言允許不對(duì)函數(shù)參數(shù)和返回值類型進(jìn)行說(shuō)明甚至能夠連函數(shù)名都不申明此時(shí)默認(rèn)該函數(shù)參數(shù)是不定個(gè)數(shù)int型該函數(shù)返回值為int型永遠(yuǎn)不要利用此特征!printf()、scanf()變長(zhǎng)參數(shù)表,<stdarg.h>缺點(diǎn):對(duì)參數(shù)類型和個(gè)數(shù)無(wú)法嚴(yán)格驗(yàn)證,易使用犯錯(cuò)main()、printf()和scanf()特殊嗎?第39頁(yè)使用函數(shù)要注意每個(gè)函數(shù)只完成一個(gè)功效(包含main())對(duì)函數(shù)功效能夠用不含連詞一句話描述函數(shù)不能過(guò)長(zhǎng)1986年IBM研究結(jié)果:大多數(shù)有錯(cuò)誤函數(shù)都大于500行1991年研究表明:小于143行函數(shù)比更長(zhǎng)函數(shù)更輕易維護(hù)函數(shù)一定要對(duì)傳進(jìn)來(lái)非法參數(shù)做點(diǎn)什么向調(diào)用者提供錯(cuò)誤信息assert()safediv.c第40頁(yè)調(diào)用自定義函數(shù)之前,應(yīng)該在主調(diào)函數(shù)中說(shuō)明被調(diào)函數(shù)類型。函數(shù)說(shuō)明(函數(shù)原型說(shuō)明)
在主函數(shù)中對(duì)被調(diào)函數(shù)作類型說(shuō)明,意在告訴編譯系統(tǒng),本函數(shù)中將要用到某函數(shù)是什么類型,方便讓編譯系統(tǒng)作出對(duì)應(yīng)處理。函數(shù)說(shuō)明普通形式為:
類型函數(shù)名();注意:函數(shù)類型說(shuō)明是函數(shù)調(diào)用中一個(gè)非常主要步驟,忽略它將造成程序編譯時(shí)犯錯(cuò)。第41頁(yè)
例7:調(diào)用函數(shù)求n!。main(){intnum;longt;longf();/*函數(shù)類型說(shuō)明*/scanf("%d",&num);t=f(num);/*函數(shù)調(diào)用*/printf("%d!=%1d",num,t);}longf(n)/*定義f函數(shù),其功效是求n!*/intn;{inti;longa=1;/*變量a存放階乘*/for(i=1;i<=n;i++)/*求階乘*/a*=i;return(a);}/*返回a值*/第42頁(yè)函數(shù)定義與函數(shù)說(shuō)明區(qū)分
函數(shù)定義是指函數(shù)功效確實(shí)立,包含指定函數(shù)名、函數(shù)類型、形參及其類型、函數(shù)體等。它是一個(gè)完整、獨(dú)立單位函數(shù)說(shuō)明是對(duì)函數(shù)名、函數(shù)返回值類型、形參類型說(shuō)明,不包含形參和函數(shù)體。函數(shù)說(shuō)明只起到一個(gè)申明作用。第43頁(yè)下面幾個(gè)情況除外,能夠不作函數(shù)說(shuō)明:(1)被調(diào)函數(shù)返回值是int時(shí)(2)被調(diào)函數(shù)定義出現(xiàn)在主調(diào)函數(shù)之前時(shí)如:①被調(diào)函數(shù)在主調(diào)函數(shù)之后,需說(shuō)明
main(){longf();……t=f();…….}longf(intx,inty){…….}第44頁(yè)②被調(diào)函數(shù)在主調(diào)函數(shù)之前已定義,不需說(shuō)明longf(intx,inty){}main(){t=f(a,b);}第45頁(yè)(3)在源程序開(kāi)頭,在全部函數(shù)定義之前已說(shuō)明了函數(shù)類型floata();main(){………a(c,d);……..}floata(intx,inty){……..}如:第46頁(yè)用函數(shù)完成此題編程先由計(jì)算機(jī)“想”一個(gè)1到100之間數(shù)請(qǐng)人猜,假如人猜對(duì)了,則計(jì)算機(jī)給出提醒:“Right!”,不然提醒:“Wrong!”,并告訴人所猜數(shù)是大(Toohigh)還是小(Toolow),最多能夠猜10次。假如猜了10次仍未猜中話,則停頓此次猜數(shù),然后繼續(xù)猜下一個(gè)數(shù)。每次運(yùn)行程序能夠重復(fù)猜多個(gè)數(shù),直到操作者想停頓時(shí)才結(jié)束。第47頁(yè)框架流程開(kāi)始結(jié)束初始化退出主功效為程序運(yùn)行所作準(zhǔn)備工作程序主體功效在退出前要做事情,比如資源釋放第48頁(yè)主功效猜數(shù)字開(kāi)始結(jié)束生成數(shù)字猜數(shù)字是否繼續(xù)?NY開(kāi)始結(jié)束猜得對(duì)嗎?NY提醒大小次數(shù)==10?輸入數(shù)字YN第49頁(yè)§4.2變量作用域和存放類
1、定義語(yǔ)句出現(xiàn)位置——作用域問(wèn)題2、變量值存在時(shí)間長(zhǎng)短(是否保留變量)——生存期問(wèn)題變量必須先定義,后使用。另外,還包括到以下問(wèn)題:第50頁(yè)一、變量作用域
全局變量局部變量變量作用域:在程序中定義變量位置及能被訪問(wèn)范圍。第51頁(yè)局部變量在語(yǔ)句塊內(nèi)定義變量形參也是局部變量特點(diǎn)定義時(shí)不會(huì)自動(dòng)初始化,除非程序員指定初值進(jìn)入語(yǔ)句塊時(shí)取得內(nèi)存,僅能由語(yǔ)句塊內(nèi)語(yǔ)句訪問(wèn),退出語(yǔ)句塊時(shí)釋放內(nèi)存,不再有效并列語(yǔ)句塊各自定義同名變量互不干擾
局部變量第52頁(yè)1、局部變量:在函數(shù)內(nèi)部或復(fù)合語(yǔ)句內(nèi)定義變量稱為~。(離開(kāi)該范圍,其值就不能再引用,即含有局部性)intf1(inta,intb){int
m;m=a*b;return(m);}例:在函數(shù)內(nèi)部m為局部變量,形參a,b也是局部變量,只在函數(shù)f1()中有效。隨函數(shù)f1()建立而建立,并隨其消亡而消亡。第53頁(yè)main(){intx=10;if(x==10){char
s=‘a(chǎn)’;printf(“%c\n",s);}printf(“%d\n",x);}在復(fù)合語(yǔ)句內(nèi)例:
s為局部變量,只在if語(yǔ)句塊中有效局部變量s在if入口處建立,在出口處消亡第54頁(yè)說(shuō)明:①局部變量只在定義它函數(shù)內(nèi)有效,即在此函數(shù)之外是不能使用這些局部變量。(main()一樣)
main(){inta;a=10;f();}f(){intb;b=a*a;/*變量a只在主函數(shù)內(nèi)有效*/
printf(“%d”,b);}第55頁(yè)③能夠在任何復(fù)合語(yǔ)句中定義局部變量。
④
形參也是局部變量如:main(){inta=10;f();printf("main():a=%d\n",a);}f(){inta=20;printf("f():a=%d\n",a);}②不一樣函數(shù)中定義局部變量允許取相同變量名。
運(yùn)行結(jié)果:f():a=20main():a=10第56頁(yè)在全部函數(shù)之外定義變量是全局變量,在定義它位置以后都有效全局變量自動(dòng)初始化為0全局變量使函數(shù)之間數(shù)據(jù)交換更輕易,效率也高一些不過(guò)不推薦使用,甚至禁止使用程序任何部分都能夠改寫全局變量,極難確定在程序哪里改寫了它,程序結(jié)構(gòu)混亂不得不用時(shí)候(這種情況比較少見(jiàn)),要嚴(yán)格控制對(duì)它改寫全局變量(GlobalVariable)第57頁(yè)2、全局變量(/外部變量):在全部函數(shù)之外定義變量有效范圍是:從定義變量位置開(kāi)始到根源程序結(jié)束
比如:inta,b;main(){………}intx,y;f(){……….}全局變量a、b作用范圍全局變量x,y作用范圍第58頁(yè)說(shuō)明:1、同一源文件中全部函數(shù)都能夠引用全局變量值。在一個(gè)函數(shù)中對(duì)全局變量修改會(huì)影響到其它函數(shù)。例:#include<stdio.h>
intn=100;voidde(){n-=10;}main(){for(;n>=60;){de();
n-=10;printf(“n=%d\n”,n);}}運(yùn)行結(jié)果:n=80n=60n=40第59頁(yè)2、若全局變量在文件開(kāi)頭定義,則整個(gè)文件范圍內(nèi)都能夠使用該全局變量而無(wú)須進(jìn)行變量說(shuō)明;(見(jiàn)上例)
假如不在文件開(kāi)頭定義,按要求其作用域只限于定義點(diǎn)到文件終了。若定義點(diǎn)之前函數(shù)想引用該全局變量,則必須在該函數(shù)內(nèi)用關(guān)鍵字extern做“外部變量說(shuō)明”。格式:extern類型名變量名第60頁(yè)
max(intx,inty){intz;z=x>y?x:y;return(z);}main(){extern
inta,b;/*外部變量說(shuō)明*/
printf(“Maxis%d”,max(a,b));}inta=3,b=8;
/*外部變量定義*/
例:第61頁(yè)外部變量定義與外部變量說(shuō)明區(qū)分:1、外部變量定義只能有一次,它位置在全部函數(shù)之外;在同一文件中外部變量說(shuō)明能夠有屢次,它位置在函數(shù)之內(nèi)(即哪個(gè)函數(shù)要用,就在哪個(gè)函數(shù)中說(shuō)明)2、系統(tǒng)依據(jù)外部變量定義(而不是依據(jù)外部變量說(shuō)明)分配存放單元,對(duì)外部變量初始化只能在“定義”時(shí)進(jìn)行,而不能在“說(shuō)明”中進(jìn)行。3、對(duì)外部變量說(shuō)明只是申明該變量是一個(gè)已在外部定義過(guò)變量,僅僅是為了引用該變量而做“申明”第62頁(yè)3、全局變量能夠與局部變量同名。在局部變量作用范圍內(nèi),全局變量不起作用。
例:#include<stdio.h>
intm=10,n=100;voidde(){intn=100;
n-=20;
m-=2;}
main()
{intn=80;
for(;n>=60;){de();
n=n-20;
printf(“%d\n”,n+m);
}}運(yùn)行結(jié)果:6846de()函數(shù)中局部變量n作用域main()中局部變量n作用域全局變量m,n作用域第63頁(yè)例5.7#include<stdio.h>intglobal; /*定義全局變量*/voidGlobalPlusPlus(void);main(){ global=1;
printf("BeforeGlobalPlusPlus(),itis%d\n",global); GlobalPlusPlus();
printf("AfterGlobalPlusPlus(),itis%d\n",global);}/*函數(shù)功效:對(duì)全局變量global加1,并打印加1之前與之后值函數(shù)入口參數(shù):無(wú)函數(shù)返回值:無(wú)*/voidGlobalPlusPlus(void){
printf("Before++,itis%d\n",global); global++;
printf("After++,itis%d\n",global);}BeforeGlobalPlusPlus(),itis1Before++,itis1After++,itis2AfterGlobalPlusPlus(),itis2第64頁(yè)例5.8#include<stdio.h>
voidGlobalPlusPlus(void);main(){
intglobal=1;
printf("BeforeGlobalPlusPlus(),itis%d\n",global); GlobalPlusPlus();
printf("AfterGlobalPlusPlus(),itis%d\n",global);}/*函數(shù)功效:對(duì)局部變量global加1,并打印加1之前與之后值函數(shù)入口參數(shù):無(wú)函數(shù)返回值:無(wú)*/voidGlobalPlusPlus(void){
intglobal=1;
printf("Before++,itis%d\n",global); global++;
printf("After++,itis%d\n",global);}BeforeGlobalPlusPlus(),itis1Before++,itis1After++,itis2AfterGlobalPlusPlus(),itis1第65頁(yè)變量存放類型指數(shù)據(jù)在內(nèi)存中存放方式即編譯器為變量分配內(nèi)存方式,它決定變量生存期動(dòng)態(tài)存放依據(jù)需要暫時(shí)分配存放空間,離開(kāi)即釋放靜態(tài)存放在程序運(yùn)行期間分配固定存放空間不釋放程序區(qū)靜態(tài)存放區(qū)動(dòng)態(tài)存放區(qū)形參、自動(dòng)變量、函數(shù)調(diào)用現(xiàn)場(chǎng)等全局變量、靜態(tài)變量第66頁(yè)二、變量存放類(從生存期角度來(lái)描述變量)C語(yǔ)言中每個(gè)變量和函數(shù)都有兩個(gè)屬性——
數(shù)據(jù)類型和數(shù)據(jù)存放類別數(shù)據(jù)類型:如整型、字符型、浮點(diǎn)型等數(shù)據(jù)存放類別:數(shù)據(jù)在內(nèi)存中存放方式(靜態(tài)存放方式、動(dòng)態(tài)存放方式)存放類型說(shuō)明符數(shù)據(jù)類型說(shuō)明符變量名表;所以,變量說(shuō)明完整形式為:
第67頁(yè)靜態(tài)存放——程序開(kāi)始執(zhí)行時(shí)分配固定存放單元(位于靜態(tài)存放區(qū)),直到程序執(zhí)行完成才釋放所占存放單元。動(dòng)態(tài)存放——程序運(yùn)行期間按照需要暫時(shí)分配存放單元(位于動(dòng)態(tài)存放區(qū)),使用結(jié)束馬上釋放所占存放單元。變量存放方式(變量生存期)分為:第68頁(yè)
auto自動(dòng)變量——?jiǎng)討B(tài)存放區(qū)
register存放器變量——CPU中存放器
extern外部變量——靜態(tài)存放區(qū)
static靜態(tài)變量——靜態(tài)存放區(qū)存放類型程序區(qū)靜態(tài)存放區(qū)動(dòng)態(tài)存放區(qū)形參、自動(dòng)變量、函數(shù)調(diào)用現(xiàn)場(chǎng)等全局變量、靜態(tài)變量存放數(shù)據(jù)第69頁(yè)局部變量存放方式(三種)自動(dòng)變量靜態(tài)局部變量存放器變量第70頁(yè)“自動(dòng)”表達(dá)在進(jìn)入語(yǔ)句塊時(shí)自動(dòng)申請(qǐng)內(nèi)存,退出時(shí)自動(dòng)釋放內(nèi)存對(duì)它們分配和釋放存放空間工作由編譯系統(tǒng)自動(dòng)處理,故稱其為自動(dòng)變量標(biāo)準(zhǔn)定義格式auto類型名變量名;動(dòng)態(tài)局部變量缺省存放類型不初始化時(shí),值是不確定1、自動(dòng)變量(auto)第71頁(yè)例:
intf(inta)/*形參a為自動(dòng)變量,auto省略*/{autointb,c=3;/*定義b,c為自動(dòng)變量*/……}第72頁(yè)2、靜態(tài)局部變量:有時(shí)希望函數(shù)中局部變量值在函數(shù)調(diào)用結(jié)束后不消失(以后一直存在,并總是保持它最新值,即含有記憶性。)即不釋放存放單元。此時(shí)可指定該變量為“靜態(tài)局部變量”,用關(guān)鍵字“static”說(shuō)明。靜態(tài)局部變量系統(tǒng)自動(dòng)初始化為0。存放在靜態(tài)存放區(qū)中第73頁(yè)靜態(tài)變量和全局變量都是靜態(tài)存放類型自動(dòng)初始化為0從靜態(tài)存放區(qū)分配,生存期為整個(gè)程序運(yùn)行期間但作用域不一樣第74頁(yè)例:f(inta){autointb=0;
staticintc=3;/*定義靜態(tài)局部變量c*/b=b+1;c=c+1;return(a+b+c);}main(){inta=2,i;for(i=0;i<3;i++)printf(“%d”,f(a));}運(yùn)行結(jié)果為:789第75頁(yè)例5.9#include<stdio.h>voidFunc(void);main(){
inti;
for(i=0;i<10;i++) { Func(); }}/*函數(shù)功效:打印被調(diào)用次數(shù)
函數(shù)入口參數(shù):無(wú)函數(shù)返回值:無(wú)*/voidFunc(void){
inttimes=1; /*自動(dòng)變量*/
printf("Func()wascalled%dtime(s).\n",times++);}Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).Func()wascalled1time(s).
第76頁(yè)例5.9#include<stdio.h>voidFunc(void);main(){
inti;
for(i=0;i<10;i++) { Func(); }}/*函數(shù)功效:打印被調(diào)用次數(shù)
函數(shù)入口參數(shù):無(wú)函數(shù)返回值:無(wú)*/voidFunc(void){
static
inttimes=1; /*靜態(tài)局部變量*/
printf("Func()wascalled%dtime(s).\n",times++);}Func()wascalled1time(s).Func()wascalled2time(s).Func()wascalled3time(s).Func()wascalled4time(s).Func()wascalled5time(s).Func()wascalled6time(s).Func()wascalled7time(s).Func()wascalled8time(s).Func()wascalled9time(s).Func()wascalled10time(s).
第77頁(yè)對(duì)頻繁使用變量,為降低存取變量花費(fèi)時(shí)間,C語(yǔ)言允許將局部變量值存放在CPU運(yùn)算器存放器中,稱為“存放器變量”,用關(guān)鍵字“register”說(shuō)明。3、存放器變量(register)第78頁(yè)說(shuō)明:存放器變量類型普通只限于整型、字符型或指向整型、字符型指針,且只用于局部變量和形參。所以,全局存放器變量是非法。
不能定義任意多個(gè)存放器變量,因?yàn)橐粋€(gè)計(jì)算機(jī)系統(tǒng)中存放器數(shù)目是有限。不能取存放器變量地址存放器變量(register)第79頁(yè)存放器變量(register)當(dāng)代編譯器有能力自動(dòng)把普通變量?jī)?yōu)化為存放器變量,而且能夠忽略用戶指定,所以普通無(wú)需尤其申明變量為register如:registerstaticinta,b,c;
因?yàn)樽兞縜,b,c不能既放在靜態(tài)存放區(qū)中,又放在存放器中局部靜態(tài)變量不能定義為存放器變量。第80頁(yè)局部變量(按存放方式分)靜態(tài)局部變量(用static申明)動(dòng)態(tài)局部變量含有動(dòng)態(tài)性:隨本過(guò)程建立而建立,隨本過(guò)程結(jié)束而消亡;再次執(zhí)行本過(guò)程時(shí)再重新建立。含有局部性:只在本過(guò)程中有效。即僅能被定義它代碼塊中語(yǔ)句訪問(wèn),在此代碼塊之外是不可知。動(dòng)態(tài)局部變量:(放在動(dòng)態(tài)存放區(qū))含有靜態(tài)性:第一次執(zhí)行本過(guò)程時(shí)建立,以后一直存在,并總是保持它最新值。含有局部性:只在本過(guò)程中有效靜態(tài)局部變量:(放在靜態(tài)存放區(qū))局部變量小結(jié)、存放器變量(register)第81頁(yè)存放器變量:(放在CPU里存放器中)普通只限于整型、字符型或指向整型、字符型指針,不能取存放器變量地址含有動(dòng)態(tài)性:隨本過(guò)程建立而建立,隨本過(guò)程結(jié)束而消亡;再次執(zhí)行本過(guò)程時(shí)再重新建立。含有局部性:只在本過(guò)程中有效。即僅能被定義它代碼塊中語(yǔ)句訪問(wèn),在此代碼塊之外是不可知。第82頁(yè)全局變量存放方式全局變量在編譯時(shí)分配在靜態(tài)存放區(qū)。全局變量能夠:被本文件中函數(shù)引用也能夠被其它文件中函數(shù)引用第83頁(yè)1、允許其它文件中函數(shù)引用。假如在一個(gè)文件中要引用在另一個(gè)文件中定義全局變量,應(yīng)該在需要引用它文件中全部函數(shù)外部用“extern”說(shuō)明。第84頁(yè)文件file1.c內(nèi)容為:
inta;main(){intpower();intb=3,c,d,m;printf(“enteraanditspower:\n”);scanf(“%d,%d”,&a,&b);c=a*b;printf(“%d*%d=%d\n”,a,b,c);d=power(m);printf(“%d^%d”=%d”,a,m,d);文件file2.c內(nèi)容為:
externinta;power(intn){intI,y=1;for(i=1;i<=n;i++)y*=a;return(y);}第85頁(yè)2、只被本文件中函數(shù)引用。
若希望一些全局變量只限于被本文件引用而不能被其它文件引用,能夠在定義外部變量時(shí)前面加一個(gè)static說(shuō)明。靜態(tài)外部變量系統(tǒng)自動(dòng)初始化為0。staticinta;Main(){…..}externinta;fun(intn){…..a=a*n;…….}file1.cfile2.c注:在file1.c中定義了一個(gè)全局變量a,但它有static說(shuō)明,所以只能用于本文件,即使在文件file2.c中用了“externinta”,但文件file2.c無(wú)法使用file1.c中全局變量a。第86頁(yè)存放類別小結(jié)
對(duì)一個(gè)數(shù)據(jù)定義,需要指定兩種屬性:數(shù)據(jù)類型和存放類別,分別用兩個(gè)關(guān)鍵字定義。如:staticinta;(靜態(tài)內(nèi)部變量或靜態(tài)外部變量)
autocharc;(自動(dòng)變量,在函數(shù)內(nèi)部定義)
registerintd;(存放器變量,在函數(shù)內(nèi)部定義)對(duì)外部變量說(shuō)明時(shí),能夠用extern,說(shuō)明為已定義外部變量
externintb;(說(shuō)明b為一個(gè)已定義外部變量)第87頁(yè)從不一樣角度對(duì)存放類別歸納1、從作用域角度分,有局部變量和全局變量,它們采取存放類別是:局部變量
自動(dòng)變量,即動(dòng)態(tài)局部變量(離開(kāi)函數(shù),值就消失)靜態(tài)局部變量(離開(kāi)函數(shù),值仍保留)存放器變量(離開(kāi)函數(shù),值就消失)(形式參數(shù)能夠定義為自動(dòng)變量或存放器變量)全局變量靜態(tài)外部變量(只限本文件使用)
外部變量
(即非靜態(tài)外部變量,允許其它文件引用)第88頁(yè)2、從變量存在時(shí)間來(lái)分,有動(dòng)態(tài)存放和靜態(tài)存放兩種類型。靜態(tài)存放是程序整個(gè)運(yùn)行期間都存在,而動(dòng)態(tài)存放則是在調(diào)用函數(shù)時(shí)暫時(shí)分配存放單元。動(dòng)態(tài)存放
自動(dòng)變量
(本函數(shù)內(nèi)有效)存放器變量(本函數(shù)內(nèi)有效)
形式參數(shù)
靜態(tài)存放靜態(tài)局部變量(函數(shù)內(nèi)有效)
外部變量
(其它文件可引用)靜態(tài)外部變量(本文件內(nèi)有效)第89頁(yè)3、從變量值存放位置來(lái)區(qū)分,可分為:1.內(nèi)存中靜態(tài)存放區(qū)靜態(tài)局部變量(函數(shù)內(nèi)有效)
外部變量(其它文件可引用)靜態(tài)外部變量(本文件內(nèi)有效)2.內(nèi)存中動(dòng)態(tài)存放區(qū):3.CPU中存放器:自動(dòng)變量和形式參數(shù)存放器變量第90頁(yè)對(duì)局部變量來(lái)說(shuō),static使變量由動(dòng)態(tài)存放方式改為靜態(tài)存放方式。對(duì)全局變量來(lái)說(shuō),static使變量局部化(局部于本文件),但仍為靜態(tài)存放方式。從作用域角度看,凡有static說(shuō)明,其作用域都是局限,或者是局限于本函數(shù)內(nèi)(靜態(tài)局部變量),或者局限于本文件內(nèi)(靜態(tài)外部變量)4、static對(duì)局部變量和全局變量作用不一樣。第91頁(yè)全局變量靜態(tài)外部變量
(只限本文件使用)外部變量
(即非靜態(tài)外部變量,允許其它文件引用)局部變量
自動(dòng)變量,(離開(kāi)函數(shù),值就消失)存放器變量(離開(kāi)函數(shù),值就消失)(形式參數(shù)能夠定義為自動(dòng)變量或寄存器變量)定義點(diǎn)之前使用,需用extern申明靜態(tài)局部變量(離開(kāi)函數(shù),值仍保留)動(dòng)態(tài)局部變量第92頁(yè)遞歸(Recursion)函數(shù)直接或間接調(diào)用自己為遞歸unsigned
intfunc(unsigned
intn)
{
if(n==0)
return1;
else
returnn*func(n-1);
}recur.c第93頁(yè)模塊包含兩部分源文件(xxx.c):一系列相關(guān)函數(shù)定義頭文件(xxx.h):這些函數(shù)申明等必要信息函數(shù)申明、外部變量申明、宏定義、類型定義……能夠?qū)⒛K編譯為.obj文件,同.h文件一起供他人使用,從而保護(hù)了源代碼使用模塊過(guò)程建立一個(gè)工程(project)把各模塊都加入到工程中#include模塊頭文件開(kāi)始使用此模塊模塊第94頁(yè)編寫模塊技術(shù)模塊信息隱藏用static定義函數(shù)和全局變量只在此模塊內(nèi)有效(提議采?。┰试S被其它模塊使用全局變量在源文件中定義,不加static修飾在頭文件中進(jìn)行申明,加extern修飾第95頁(yè)*模塊化程序設(shè)計(jì)方法功效分解自頂向下、逐步求精過(guò)程模塊分解標(biāo)準(zhǔn)確保模塊相對(duì)獨(dú)立性高聚合、低耦合模塊實(shí)現(xiàn)細(xì)節(jié)對(duì)外不可見(jiàn)外部:關(guān)心做什么內(nèi)部:關(guān)心怎么做設(shè)計(jì)好模塊接口接口是指羅列出一個(gè)模塊全部與外部打交道變量等定義好后不要輕易改動(dòng)在模塊開(kāi)頭(文件開(kāi)頭)進(jìn)行函數(shù)申明第96頁(yè)*函數(shù)設(shè)計(jì)標(biāo)準(zhǔn)函數(shù)功效要單一,不要設(shè)計(jì)多用途函數(shù)函數(shù)規(guī)模要小,盡可能控制在50行代碼以內(nèi)1986年IBM在OS/360研究結(jié)果:大多數(shù)有錯(cuò)誤函數(shù)都大于500行1991年對(duì)148,000行代碼研究表明:小于143行函數(shù)比更長(zhǎng)函數(shù)更輕易維護(hù)參數(shù)和返回值規(guī)則參數(shù)要書寫完整,不要省略對(duì)函數(shù)入口參數(shù)進(jìn)行有效性檢驗(yàn)沒(méi)有參數(shù)和返回值時(shí),用void填充每個(gè)函數(shù)只有一個(gè)入口和一個(gè)出口,盡可能不使用全局變量盡可能少用靜態(tài)局部變量,以防止使函數(shù)含有“記憶”功效第97頁(yè)模塊和鏈接將一個(gè)程序分解成若干個(gè)模塊,分別放在幾個(gè)源文件中,形成一個(gè)項(xiàng)目文件(.prj)(Project)然后,對(duì)每一個(gè)源文件(.c)分別單獨(dú)進(jìn)行編譯再將它們目標(biāo)代碼(.obj)連同標(biāo)準(zhǔn)函數(shù)庫(kù)中函數(shù)鏈接在一起,形成可執(zhí)行文件(.exe)。模塊之間經(jīng)過(guò)相互調(diào)用函數(shù)聯(lián)絡(luò)起來(lái)頭文件(.h)是聯(lián)絡(luò)紐帶
第98頁(yè)模塊和鏈接優(yōu)點(diǎn):當(dāng)一個(gè)文件代碼被修改后,無(wú)須對(duì)全部程序重新編譯,從而節(jié)約了程序編譯時(shí)間。使程序更宜于維護(hù),給多個(gè)程序員共同編制一個(gè)大型項(xiàng)目標(biāo)代碼提供了方便伎倆。第99頁(yè)模塊和鏈接例5.10能夠不看將習(xí)題5.5修改成1個(gè).h頭文件(X5-5-1.h)2個(gè).c源文件(X5-5-1.c,X5-5.c)1個(gè).prj項(xiàng)目文件(X5-5.prj)由全部源程序文件組成X5-5-1.CX5-5.C參見(jiàn)試驗(yàn)指導(dǎo)書第133頁(yè)第100頁(yè)編譯器在開(kāi)始正式編譯之前處理指令,叫預(yù)編譯指令它們不會(huì)存在于最終生成目標(biāo)代碼中文件包含:#include用#include指定文件內(nèi)容替換#include所在行用<>或者""括上文件名<>表示在編譯器include目錄內(nèi)查找文件""表示在當(dāng)前目錄查找文件文件名中能夠帶有路徑預(yù)
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 機(jī)械行業(yè)促銷計(jì)劃總結(jié)
- 健康行業(yè)采購(gòu)工作總結(jié)
- 重要工程安保工作的系統(tǒng)總結(jié)計(jì)劃
- 科技產(chǎn)品設(shè)計(jì)師的智能體驗(yàn)與科技感
- 水務(wù)文化建設(shè)的探索計(jì)劃
- 中小學(xué)了解學(xué)習(xí)歷史英雄人物故事主題班會(huì):紅色人物1
- 2023年云南省臨滄市公開(kāi)招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 2022年浙江省舟山市公開(kāi)招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 2024年山西省忻州市公開(kāi)招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 2022年浙江省麗水市公開(kāi)招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 裝配式鋼筋混凝土簡(jiǎn)支T梁設(shè)計(jì)
- COMMERCIAL INVOICE 商業(yè)發(fā)票
- 大氣課程設(shè)計(jì)-—袋式除塵器
- 普天超五類檢測(cè)報(bào)告
- 會(huì)計(jì)師事務(wù)所業(yè)務(wù)培訓(xùn)制度
- CMM2-18錨桿機(jī)(新)說(shuō)明書
- 12噸汽車起重機(jī)基本技術(shù)規(guī)格資料
- WEB開(kāi)發(fā)基礎(chǔ)-2021秋本-計(jì)算機(jī)科學(xué)與技術(shù)本復(fù)習(xí)資料-國(guó)家開(kāi)放大學(xué)2022年1月期末考試復(fù)習(xí)資料
- 安徽省政協(xié)機(jī)關(guān)文件材料歸檔范圍
- 本質(zhì)安全理論綜述研究
- 代建項(xiàng)目管理工作大綱
評(píng)論
0/150
提交評(píng)論