版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第八章第1頁§8.1概述
一種較大程序可分為若干個程序模塊,每一種模塊用來實現(xiàn)一種特定功能。在高級語言中用子程序?qū)崿F(xiàn)模塊功能。子程序由函數(shù)來完畢。一種C程序可由一種主函數(shù)和若干個其他函數(shù)構(gòu)成。由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。同一種函數(shù)可以被一種或多種函數(shù)調(diào)用任意一再。函數(shù)間調(diào)用關(guān)系第2頁#include<stdio.h>voidmain(){voidprintstar();/*對printstar函數(shù)申明*/
voidprint_message();
/*對print_message函數(shù)申明*/
printstar();
/*調(diào)用printstar函數(shù)*/
print_message();
/*調(diào)用print_message函數(shù)*/
printstar();
/*調(diào)用printstar函數(shù)*/
}例8.1先舉一種函數(shù)調(diào)用簡樸例子第3頁voidprintstar()
/*定義printstar函數(shù)*/{printf("****************\n");}voidprint_message()/*定義print_message函數(shù)*/{printf("Howdoyoudo!\n");}運行狀況如下:****************Howdoyoudo!****************第4頁闡明:(1)一種C程序由一種或多種程序模塊構(gòu)成,每一種程序模塊作為一種源程序文獻。對較大程序,一般不但愿把所有內(nèi)容全放在一種文獻中,而是將他們分別放在若干個源文獻中,再由若干源程序文獻構(gòu)成一種C程序。這樣便于分別編寫、分別編譯,提高調(diào)試效率。一種源程序文獻可認為多種C程序公用。第5頁(2)一種源程序文獻由一種或多種函數(shù)以及其他有關(guān)內(nèi)容(如命令行、數(shù)據(jù)定義等)構(gòu)成。一種源程序文獻是一種編譯單位,在程序編譯時是以源程序文獻為單位進行編譯,而不是以函數(shù)為單位進行編譯。(3)C程序執(zhí)行是從main函數(shù)開始,如是在main函數(shù)中調(diào)用其他函數(shù),在調(diào)用后流程返回到main函數(shù),在main函數(shù)中結(jié)束整個程序運行。第6頁(4)所有函數(shù)都是平行,即在定義函數(shù)時是分別進行,是互相獨立。一種函數(shù)并不從屬于另一函數(shù),即函數(shù)不能嵌套定義。函數(shù)間可以互相調(diào)用,但不能調(diào)用main函數(shù)。main函數(shù)是系統(tǒng)調(diào)用。第7頁(5)從顧客使用角度看,函數(shù)有兩種:①原則函數(shù),即庫函數(shù)。這是由系統(tǒng)提供,顧客不必自己定義這些函數(shù),可以直接使用它們。應(yīng)當闡明,不一樣樣C系統(tǒng)提供庫函數(shù)數(shù)量和功能會有某些不一樣樣,當然許多基本函數(shù)是共同。②顧客自己定義函數(shù)。用以處理顧客專門需要。第8頁(6)從函數(shù)形式看,函數(shù)分兩類:①無參函數(shù)。如例8.1中printstar和print_message就是無參函數(shù)。在調(diào)用無參函數(shù)時,主調(diào)函數(shù)不向被調(diào)用函數(shù)傳遞數(shù)據(jù)。無參函數(shù)一般用來執(zhí)行指定一組操作。例如,例8.1程序中printstar函數(shù)。②有參函數(shù)。在調(diào)用函數(shù)時,主調(diào)函數(shù)在調(diào)用被調(diào)用函數(shù)時,通過參數(shù)向被調(diào)用函數(shù)傳遞數(shù)據(jù),一般狀況下,執(zhí)行被調(diào)用函數(shù)時會得到一種函數(shù)值,供主調(diào)函數(shù)使用。第9頁§8.2函數(shù)定義一般形式§8.2.1.無參函數(shù)定義一般形式定義無參函數(shù)一般形式為:類型標識符函數(shù)名(){申明部分語句部分}在定義函數(shù)時要用“類型標識符”指定函數(shù)值類型,即函數(shù)帶回來值類型。例8.1中printstar和print_message函數(shù)為void類型,表達不需要帶回函數(shù)值。第10頁§8.2.2.有參函數(shù)定義一般形式定義有參函數(shù)一般形式為:類型標識符函數(shù)名(形式參數(shù)表列){申明部分語句部分}例如:intmax(intx,inty){intz;/*函數(shù)體中申明部分*/z=x>y?x∶y;return(z);}第11頁§8.2.3空函數(shù)
定義空函數(shù)一般形式為:類型標識符函數(shù)名(){}例如:dummy(){}調(diào)用此函數(shù)時,什么工作也不做,沒有任何實際作用。在主調(diào)函數(shù)中寫上“dummy();”表明“這里要調(diào)用一種函數(shù)”,而目前這個函數(shù)沒有起作用,等后來擴充函數(shù)功能時補充上。第12頁§8.3函數(shù)參數(shù)和函數(shù)值
§8.3.1形式參數(shù)和實際參數(shù)
在前面提到有參函數(shù)中,在定義函數(shù)時函數(shù)名背面括弧中變量名稱為“形式參數(shù)”(簡稱“形參”),在主調(diào)函數(shù)中調(diào)用一種函數(shù)時,函數(shù)名背面括弧中參數(shù)(可以是一種表達式)稱為“實際參數(shù)”(簡稱“實參”)。return背面括弧中值()作為函數(shù)帶回值(稱函數(shù)返回值)。第13頁在不一樣樣函數(shù)之間傳遞數(shù)據(jù),可以使使用方法:參數(shù):通過形式參數(shù)和實際參數(shù)返回值:用return語句返回計算成果全局變量:外部變量大多數(shù)狀況下,主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞關(guān)系。第14頁#include<stdio.h>voidmain(){intmax(intx,inty);
/*對max函數(shù)申明*/inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf("Maxis%d",c);}
例8.2調(diào)用函數(shù)時數(shù)據(jù)傳遞
第15頁intmax(intx,inty)/*定義有參函數(shù)max*/{intz;z=x>y?x∶y;return(z);}
運行狀況如下:7,8↙Maxis8第16頁通過函數(shù)調(diào)用,使兩個函數(shù)中數(shù)據(jù)發(fā)生聯(lián)絡(luò)第17頁有關(guān)形參與實參闡明:(1)在定義函數(shù)中指定形參,在未出現(xiàn)函數(shù)調(diào)用時,它們并不占內(nèi)存中寄存單元。只有在發(fā)生函數(shù)調(diào)用時,函數(shù)max中形參才被分派內(nèi)存單元。在調(diào)用結(jié)束后,形參所占內(nèi)存單元也被釋放。(2)實參可以是常量、變量或表達式,如:max(3,a+b);但規(guī)定它們有確定值。在調(diào)用時將實參值賦給形參。第18頁(3)在被定義函數(shù)中,必須指定形參類型(見例8.2程序中
“c=max(a,b);”
)。(4)實參與形參類型應(yīng)相似或賦值兼容。例8.2中實參和形參都是整型。假如實參為整型而形參x為實型,或者相反,則按第3章簡介不一樣樣類型數(shù)值賦值規(guī)則進行轉(zhuǎn)換。例如實參值a為3.5,而形參x為整型,則將實數(shù)3.5轉(zhuǎn)換成整數(shù)3,然后送到形參b。字符型與整型可以互相通用。第19頁(5)在C語言中,實參向?qū)π螀?shù)據(jù)傳遞是“值傳遞”,單向傳遞,只由實參傳給形參,而不能由形參傳回來給實參。在內(nèi)存中,實參單元與形參單元是不一樣樣單元。第20頁在調(diào)用函數(shù)時,給形參分派寄存單元,并將實參對應(yīng)值傳遞給形參,調(diào)用結(jié)束后,形參單元被釋放,實參單元仍保留并維持原值。因此,在執(zhí)行一種被調(diào)用函數(shù)時,形參值假如發(fā)生變化,并不會變化主調(diào)函數(shù)實參值。例如,若在執(zhí)行函數(shù)過程中x和y值變?yōu)椋保昂停保担岷停馊詾椋埠停?。?1頁§8.3.2函數(shù)返回值一般,但愿通過函數(shù)調(diào)用使主調(diào)函數(shù)能得到一種確定值,這就是函數(shù)返回值。例如,例8.2中,max(2,3)值是3,max(5,2)值是5。賦值語句將這個函數(shù)值賦給變量c。有關(guān)函數(shù)返回值某些闡明:(1)函數(shù)返回值是通過函數(shù)中return語句獲得。第22頁假如需要從被調(diào)用函數(shù)帶回一種函數(shù)值供主調(diào)函數(shù)使用,被調(diào)用函數(shù)中必須包括return語句。假如不需要從被調(diào)用函數(shù)帶回函數(shù)值可以不要return語句。一種函數(shù)中可以有一種以上return語句,執(zhí)行到哪一種return語句,哪一種語句起作用。return語句背面括弧也可以不要,如:“returnz;”等價于“return(z);”return語句將被調(diào)用函數(shù)中一種確定值帶回主調(diào)函數(shù)中去。見圖8.2中從return語句返回箭頭。第23頁return背面值可以是一種表達式。例如,例8.2中函數(shù)max可以改寫成:max(intx,inty){
return(x>y?x∶y);
}(2)函數(shù)返回值應(yīng)當屬于某一種確定類型,在定義函數(shù)時指定函數(shù)返回值類型。第24頁例如:下面是3個函數(shù)首行:intmax(floatx,floaty)/*函數(shù)值為整型*/charletter(charc1,charc2)/*函數(shù)值為字符型*/doublemin(intx,inty)/*函數(shù)值為雙精度型*/在C語言中,凡不加類型闡明函數(shù),自動按整型處理。例8.2中max函數(shù)首行函數(shù)類型int可以省寫,用TurboC2.0編譯程序時能通過,但用TurboC++3.0編譯程序時不能通過,由于C++規(guī)定所有函數(shù)都必須指定函數(shù)類型。因此,提議在定義時對所有函數(shù)都指定函數(shù)類型。第25頁(3)在定義函數(shù)時指定函數(shù)類型一般應(yīng)當和return語句中表達式類型一致。假如函數(shù)值類型和return語句中表達式值不一致,則以函數(shù)類型為準。對數(shù)值型數(shù)據(jù),可以自動進行類型轉(zhuǎn)換。即函數(shù)類型決定返回值類型。(4)對于不帶回值函數(shù),應(yīng)當用“void”定義函數(shù)為“無類型”(或稱“空類型”)。這樣,系統(tǒng)就保證不使函數(shù)帶回任何值,即嚴禁在調(diào)用函數(shù)中使用被調(diào)用函數(shù)返回值。此時在函數(shù)體中不得出現(xiàn)return語句。第26頁例8.3返回值類型與函數(shù)類型不一樣樣#include<stdio.h>voidmain(){intmax(floatx,floaty);floata,b;intc;scanf("%f,%f,",&a,&b);c=max(a,b);printf("Maxis%d\n",c);}intmax(floatx,floaty){floatz;/*z為實型變量*/z=x>y?x∶y;return(z);}運行狀況如下:1.5,2.5↙Maxis2第27頁§8.4函數(shù)調(diào)用
§8.4.1函數(shù)調(diào)用一般形式函數(shù)調(diào)用一般形式為:函數(shù)名(實參表列)假如實參表列包括多種實參,則各參數(shù)間用逗號隔開。實參與形參個數(shù)應(yīng)相等,類型應(yīng)匹配。實參與形參按次序?qū)?yīng),一一傳遞數(shù)據(jù)。假如是調(diào)用無參函數(shù),則“實參表列”可以沒有,但括弧不能省略。第28頁假如實參表列包括多種實參,對實參求值次序并不是確定,有系統(tǒng)按自左至右次序求實參值,有系統(tǒng)則按自右至左次序。許多C版本是按自右而左次序求值,例如TubroC++。第29頁例8.4實參求值次序#include<stdio.h>voidmain(){intf(inta,intb);/*函數(shù)申明*/inti=2,p;p=f(i,++i);/*函數(shù)調(diào)用*/printf("%d\n",p);}
第30頁intf(inta,intb)/*函數(shù)定義*/{intc;if(a>b)c=1;elseif(a==b)c=0;elsec=-1;return(c);}
第31頁假如按自左至右次序求實參值,則函數(shù)調(diào)用相稱于f(2,3)假如按自左至右次序求實參值,則函數(shù)調(diào)用相稱于f(3,3)
對于函數(shù)調(diào)用inti=2,p;p=f(i,++i);第32頁§8.4.2函數(shù)調(diào)用方式按函數(shù)在程序中出現(xiàn)旳位置來分,可以有如下三種函數(shù)調(diào)用方式:1.函數(shù)語句把函數(shù)調(diào)用作為一種語句。如例8.1中printstar(),這時不規(guī)定函數(shù)帶回值,只規(guī)定函數(shù)完畢一定操作。2.函數(shù)表達式函數(shù)出目前一種表達式中,這種表達式稱為函數(shù)表達式。這時規(guī)定函數(shù)帶回一種確定值以參與表達式運算。例如:c=2*max(a,b);第33頁3.函數(shù)參數(shù)函數(shù)調(diào)用作為一種函數(shù)實參。例如:m=max(a,max(b,c));其中max(b,c)是一次函數(shù)調(diào)用,它值作為max另一次調(diào)用實參。m值是a、b、c三者中最大者。又如:printf("%d",max(a,b));也是把max(a,b)作為printf函數(shù)一種參數(shù)。函數(shù)調(diào)用作為函數(shù)參數(shù),實質(zhì)上也是函數(shù)表達式形式調(diào)用一種,由于函數(shù)參數(shù)本來就規(guī)定是表達式形式。第34頁§8.4.3對被調(diào)用函數(shù)申明和函數(shù)原型在一種函數(shù)中調(diào)用另一函數(shù)(即被調(diào)用函數(shù))需要具有哪些條件呢?(1)首先被調(diào)用函數(shù)必須是已經(jīng)存在函數(shù)(是庫函數(shù)或顧客自己定義函數(shù))。但光有這一條件還不夠?!?.4.3對被調(diào)用函數(shù)申明和函數(shù)原型第35頁(3)假如使用顧客自己定義函數(shù),而該函數(shù)位置在調(diào)用它函數(shù)(即主調(diào)函數(shù))背面(在同一種文獻中),應(yīng)當在主調(diào)函數(shù)中對被調(diào)用函數(shù)作申明。(2)假如使用庫函數(shù),還應(yīng)當在本文獻開頭用#include命令將調(diào)用有關(guān)庫函數(shù)時所需用到信息“包括”到本文獻中來。第36頁函數(shù)原型一般形式為(1)函數(shù)類型函數(shù)名(參數(shù)類型1,參數(shù)類型2……);(2)函數(shù)類型函數(shù)名(參數(shù)類型1,參數(shù)名1,參數(shù)類型2,參數(shù)名2……);第37頁“申明”一詞原文是delaration,過去在許多書中把它譯為“闡明”。申明作用是把函數(shù)名、函數(shù)參數(shù)個數(shù)和參數(shù)類型等信息告知編譯系統(tǒng),以便在碰到函數(shù)調(diào)用時,編譯系統(tǒng)能對旳識別函數(shù)并檢查調(diào)用與否合法。(例如函數(shù)名與否對旳,實參與形參類型和個數(shù)與否一致)。第38頁注意:函數(shù)“定義”和“申明”不是一回事。函數(shù)定義是指對函數(shù)功能確實立,包括指定函數(shù)名,函數(shù)值類型、形參及其類型、函數(shù)體等,它是一種完整、獨立函數(shù)單位。而函數(shù)申明作用則是把函數(shù)名字、函數(shù)類型以及形參類型、個數(shù)和次序告知編譯系統(tǒng),以便在調(diào)用該函數(shù)時系統(tǒng)按此進行對照檢查。第39頁#include<stdio.h>voidmain(){floatadd(floatx,floaty);
/*對被調(diào)用函數(shù)add申明*/floata,b,c;scanf("%f,%f",&a,&b);c=add(a,b);printf("sumis%f\n",c);}floatadd(floatx,floaty)/*函數(shù)首部*/{floatz;/*函數(shù)體*/z=x+y;return(z);}
例8.5對被調(diào)用函數(shù)作申明第40頁假如被調(diào)用函數(shù)定義出目前主調(diào)函數(shù)之前,可以不必加以申明。由于編譯系統(tǒng)已經(jīng)先懂得了已定義函數(shù)有關(guān)狀況,會根據(jù)函數(shù)首部提供信息對函數(shù)調(diào)用作對旳性檢查。假如被調(diào)用函數(shù)定義出目前主調(diào)函數(shù)之前,可以不必加以申明。由于編譯系統(tǒng)已經(jīng)先懂得了已定義函數(shù)有關(guān)狀況,會根據(jù)函數(shù)首部提供信息對函數(shù)調(diào)用作對旳性檢查。第41頁改寫例8.5#include<stdio.h>floatadd(floatx,floaty)/*函數(shù)首部*/{floatz;/*函數(shù)體*/z=x+y;return(z);}voidmain(){floata,b,c;scanf("%f,%f",&a,&b);c=add(a,b);printf("sumis%f\n",c);}第42頁§8.5函數(shù)嵌套調(diào)用嵌套定義就是在定義一種函數(shù)時,其函數(shù)體內(nèi)又包括另一種函數(shù)完整定義。C語言不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),也就是說,在調(diào)用一種函數(shù)過程中,又調(diào)用另一種函數(shù)。第43頁第44頁例8.6用弦截法求方程f(x)=x3-5x2+16x-80=0根
第45頁(1)取兩個不一樣樣點x1,x2,假如f(x1)和f(x2)符號相反,則(x1,x2)區(qū)間內(nèi)必有一種根。假如f(x1)與f(x2)同符號,則應(yīng)變化x1,x2,直到f(x1)、f(x2)異號為止。注意x1、x2值不應(yīng)差太大,以保證(x1,x2)區(qū)間內(nèi)只有一種根。(2)連接(x1,f(x1))和(x2,f(x2))兩點,此線(即弦)交x軸于x。措施:第46頁(3)若f(x)與f(x1)同符號,則根必在(x,x2)區(qū)間內(nèi),此時將x作為新x1。假如f(x)與f(x2)同符號,則表達根在(x1,x)區(qū)間內(nèi),將x作為新x2。(4)反復(fù)環(huán)節(jié)(2)和(3),直到|f(x)|<ε為止,ε為一種很小數(shù),例如10-6\.此時認為f(x)≈0第47頁N-S流程圖
第48頁分別用幾種函數(shù)來實現(xiàn)各部分功能:(1)用函數(shù)f(x)代表x函數(shù):x3-5x2+16x-80.(2)用函數(shù)調(diào)用xpoint(x1,x2)來求(x1,f(x1))和(x2,f(x2))連線與x軸交點x坐標。(3)用函數(shù)調(diào)用root(x1,x2)來求(x1,x2)區(qū)間那個實根。顯然,執(zhí)行root函數(shù)過程中要用到函數(shù)xpoint,而執(zhí)行xpoint函數(shù)過程中要用到f函數(shù)。第49頁#include<stdio.h>#include<math.h>
floatf(floatx)
/*定義f函數(shù),以實現(xiàn)f(x)=x3-5x2+16x-80*/{floaty;y=((x-5.0)*x+16.0)*x-80.0;return(y);}
第50頁floatxpoint(floatx1,floatx2)
/*定義xpoint函數(shù),求出弦與x軸交點*/{floaty;y=(x1*f(x2)-x2*f(x1))/f(x2)-f(x1));return(y);}第51頁floatroot(floatx1,floatx2)
/*定義root函數(shù),求近似根*/{floatx,y,y1;y1=f(x1);
do{x=xpoint(x1,x2);y=f(x);if(y*y1>0)/*f(x)與f(x1)同符號*/{y1=y;x1=x;}elsex2=x;}while(fabs(y)>=0.0001);return(x);}
第52頁
voidmain()
/主函數(shù)/{floatx1,x2,f1,f2,x;
do
{printf("inputx1,x2:\n");scanf("%f,%f",&x1,&x2);f1=f(x1);f2=f(x2);
}while(f1*f2>=0);x=root(x1,x2);printf("Arootofequationis%8.4f\n",x);}運行狀況如下:inputx1,x2:2,6Arootofequationis5.0000第53頁§8.6函數(shù)遞歸調(diào)用
在調(diào)用一種函數(shù)過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)自身,稱為函數(shù)遞歸調(diào)用。C語言特點之一就在于容許函數(shù)遞歸調(diào)用。例如:intf(intx){inty,z;z=f(y);return(2*z);}第54頁第55頁例8.7有5個人坐在一起,問第5個人多少歲?他說比第4個人大2歲。問第4個人歲數(shù),他說比第3個人大2歲。問第3個人,又說比第2個人大2歲。問第2個人,說比第1個人大2歲。最終問第1個人,他說是10歲。請問第5個人多大。
age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10可以用數(shù)學(xué)公式表述如下:age(n)=10(n=1)age(n-1)+2(n>1)第56頁可以用一種函數(shù)來描述上述遞歸過程:intage(intn)/*求年齡遞歸函數(shù)*/{intc;/*c用作寄存函數(shù)返回值變量*/if(n==1)c=10;elsec=age(n-1)+2;return(c);}用一種主函數(shù)調(diào)用age函數(shù),求得第5人年齡。#include<stdio.h>voidmain(){printf(″%d″,age(5));}運行成果如下:18第57頁例8.8用遞歸措施求n!求n!也可以用遞歸措施,即5!等于4!×5,而4?。剑常 粒础保。剑薄?捎孟旅孢f歸公式表達:n?。剑保ǎ睿剑?,1)n·(n-1)?。ǎ睿荆保┑?8頁例8.9Hanoi(漢諾)塔問題。這是一種古典數(shù)學(xué)問題,是一種用遞歸措施解題經(jīng)典例子。問題是這樣:古代有一種梵塔,塔內(nèi)有3個座A、B、C,開始時A座上有64個盤子,盤子大小不等,大在下,小在上(見圖8.13)。有一種老和尚想把這64個盤子從A座移到C座,但每次只容許移動一種盤,且在移動過程中在3個座上都一直保持大盤在下,小盤在上。在移動過程中可以運用B座,規(guī)定編程序打印出移動環(huán)節(jié)。第59頁第60頁為便于理解,我們先分析將A座上3個盤子移到C座上過程:(1)將A座上2個盤子移到B座上(借助C);(2)將A座上1個盤子移到C座上;(3)將B座上2個盤子移到C座上(借助A)。其中第(2)步可以直接實現(xiàn)。第1步又可用遞歸措施分解為:1.1將A上1個盤子從A移到C;1.2將A上1個盤子從A移到B;1.3將C上1個盤子從C移到B。第(3)步可以分解為:3.1將B上1個盤子從B移到A上;3.2將B上1個盤子從B移到C上;3.3將A上1個盤子從A移到C上。將以上綜合起來,可得到移動3個盤子環(huán)節(jié)為A→C,A→B,C→B,A→C,B→A,B→C,A→C。第61頁由上面分析可知:將n個盤子從A座移到C座可以分解為如下3個環(huán)節(jié):(1)將A上n-1個盤借助C座先移到B座上。(2)把A座上剩余一種盤移到C座上。(3)將n-1個盤從B座借助于A座移到C座上。第62頁程序如下:#include<stdio.h>voidmain(){voidhanoi(intn,charone,chartwo,charthree);/*對hanoi函數(shù)申明*/intm;printf("inputthenumberofdiskes:");scanf(“%d”,&m);printf("Thesteptomoveing%ddiskes:\n",m);hanoi(m,'A','B','C');}第63頁voidhanoi(intn,charone,chartwo,charthree)
/*定義hanoi函數(shù),將n個盤從one座借助two座,移到three座*/
{voidmove(charx,chary);/*對move函數(shù)申明*/if(n==1)move(one,three);else{hanoi(n-1,one,three,two);move(one,three);hanoi(n-1,two,one,three);}}voidmove(charx,chary)/*定義move函數(shù)*/{printf(“%c-->%c\n",x,y);}第64頁運行狀況如下:inputthenumberofdiskes:3↙Thestepstonoving3diskes:A-->CA-->BC-->BA-->CB-->AB-->CA-->C第65頁§8.7數(shù)組作為函數(shù)參數(shù)§8.7.1數(shù)組元素作函數(shù)實參由于實參可以是表達式,而數(shù)組元素可以是表達式構(gòu)成部分,因此數(shù)組元素當然可以作為函數(shù)實參,與用變量作實參同樣,是單向傳遞,即“值傳送”方式。例8.10有兩個數(shù)組a和b,各有10個元素,將它們對應(yīng)地逐一相比(即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每次為不一樣樣值),則認為a數(shù)組不小于b數(shù)組,并分別記錄出兩個數(shù)組對應(yīng)元素不小于、等于、不不小于次數(shù)。第66頁#include<stdio.h>voidmain(){intlarge(intx,inty);/*函數(shù)申明*/inta[10],b[10],i,n=0,m=0,k=0;printf(″enterarraya∶\n″);for(i=0;i<10;i++=)scanf(″%d″,&a[i]);
printf(″\n″);
printf(″enterarrayb∶\n″);for(i=0;i<10;i++=)scanf
(″%d″,&b[i]);printf(″\n″);for(i=0;i<10;i++)
{if(large(a[i],b[i])==
1)n=n+1;elseif(large
(a[i],b[i])==0)m=m+1;elsek=k+1;}第67頁printf("a[i]>b[i]%dtimes\na[i]=b[i]%dtimes\na[i]<b[i]%dtimes\n",n,m,k);if(n>k)printf("arrayaislargerthanarrayb\n");elseif(n<k)printf("arrayaissmallerthanarrayb\n");elseprintf("arrayaisequaltoarrayb\n");}large(intx,inty){intflag;if(x>y)flag=1;elseif(x<y)flag=-1;elseflag=0;return(flag);}第68頁運行狀況如下:enterarraya:1357986420↙enterarrayb∶5389–1–35604↙a[i]>b[i]4timesa[i]=b[i]1timesa[i]<b[i]5timesarrayaissmallerthannarrayb第69頁§8.7.2數(shù)組名作函數(shù)參數(shù)
可以用數(shù)組名作函數(shù)參數(shù),此時形參應(yīng)當用數(shù)組名或用指針變量。例8.11有一種一維數(shù)組score,內(nèi)放10個學(xué)生成績,求平均成績。第70頁#include<stdio.h>voidmain(){float
average(floatarray[10]);/*函數(shù)申明*/floatscore[10],aver;inti;printf(″input10scores:\n″);for(i=0;i<10;i++=scanf(″%f″,&score[i]);printf(″\n″);aver=average(score
);printf
(″averagescoreis%5.2f\n″,aver);}第71頁floataverage
(floatarray[10]){inti;floataver,sum=array[0];for(i=1;i<10;i++=)sum=sum+array[i];aver=sum/10;return(aver);}運行狀況如下:input10scores:100567898.576879967.57597↙averagescoreis83.40第72頁例8.12形參數(shù)組不定義長度#include<stdio.h>voidmain(){floataverage(floatarray[],intn)floatscore_1[5]={98.5,97,91.5,60,55};floatscore_2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5};printf(“theaverageofclassAis%6.2f\n”,average(score_1,5));printf(“theaverageofclassBis%6.2f\n”,average(score_2,10));}第73頁floataverage(floatarray[],intn){inti;floataver,sum=array[0];for(i=1;i<n;i++=sum=sum+array[i];aver=sum/n;return(aver);}
運行成果如下:theaverageofclassAis80.40TheaverageofclassBis78.20第74頁例8.13用選擇法對數(shù)組中10個整數(shù)按由小到大排序。所謂選擇法就是先將10個數(shù)中最小數(shù)與a[0]對換;再將a[1]到a[9]中最小數(shù)與a[1]對換……每比較一輪,找出一種未經(jīng)排序數(shù)中最小一種。共比較9輪。第75頁a[0]a[1]a[2]a[3]a[4]36194未排序時狀況16394將5個數(shù)中最小數(shù)1與a[0]對換13694將余下4個數(shù)中最小數(shù)3與a[1]對換13496將余下3個數(shù)中最小數(shù)4與a[2]對換13469將余下2個數(shù)中最小數(shù)6與a[3]對換,至此完畢排序第76頁程序?qū)嵗?include<stdio.h>voidmain(){voidsort(intarray[],intn);inta[10],i;printf(″enterthearray\n″);for(i=0;i<10;i++=scanf(″%d″,&a[i]);
sort(a,10);printf(″thesortedarray∶\n″);for(i=0;i<10;i++=printf(″%d″,a[i]);printf(″\n″);
}
第77頁voidsort(intarray[],intn){inti,j,k,t;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(array[j]<array[k]=k=j;t=array[k];array[k]=array[i];array[i]=t}}第78頁§8.7.3.多維數(shù)組名作函數(shù)參數(shù)程序如下:#include<stdio.h>voidmain(){max_value(intarray[][4]);int[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};printf(″maxvalueis%d\n″,max_value(a));}第79頁max_value
(intarray[][4]){inti,j,k,max;max=array[0][0];for(i=0;i<3;i++)for(j=0;j<4;j++=if(array[i][j]>max)max=array
[i][j];return(max);}
運行成果如下:Maxvalueis34第80頁§8.8局部變量和全局變量§8.8.1局部變量在一種函數(shù)內(nèi)部定義變量是內(nèi)部變量,它只在本函數(shù)范圍內(nèi)有效,也就是說只有在本函數(shù)內(nèi)才能使用它們,在此函數(shù)以外是不能使用這些變量。這稱為“局部變量”。第81頁floatf1(inta)/*函數(shù)f1*/{intb,c;…a、b、c有效}charf2(intx,inty)/*函數(shù)f2*/{inti,j;x、y、i、j有效}voidmain()/*主函數(shù)*/{intm,n;…m、n有效}
第82頁(1)主函數(shù)中定義變量(m,n)也只在主函數(shù)中有效,而不由于在主函數(shù)中定義而在整個文獻或程序中有效。主函數(shù)也不能使用其他函數(shù)中定義變量。(2)不一樣樣函數(shù)中可以使用相似名字變量,它們代表不一樣樣對象,互不干擾。例如,上面在f1函數(shù)中定義了變量b和c,倘若在f2函數(shù)中也定義變量b和c,它們在內(nèi)存中占不一樣樣單元,互不混淆。(3)形式參數(shù)也是局部變量。例如上面f1函數(shù)中形參a,也只在f1函數(shù)中有效。其他函數(shù)可以調(diào)用f1函數(shù),但不能引用f1函數(shù)形參a。(4)在一種函數(shù)內(nèi)部,可以在復(fù)合語句中定義變量,這些變量只在本復(fù)合語句中有效,這種復(fù)合語句也稱為“分程序”或“程序塊”。說明第83頁voidmain(){inta,b;…{intc;c=a+b;c在此范圍內(nèi)有效a,b在此范圍內(nèi)有效…}…}
第84頁§8.8.2全局變量在函數(shù)內(nèi)定義變量是局部變量,而在函數(shù)之外定義變量稱為外部變量,外部變量是全局變量(也稱全程變量)。全局變量可認為本文獻中其他函數(shù)所共用。它有效范圍為從定義變量位置開始到本源文獻結(jié)束。第85頁intp=1,q=5;/*外部變量*/floatf1(inta)/*定義函數(shù)f1*/{intb,c;…}charc1,c2;/*外部變量*/charf2(intx,inty)/*定義函數(shù)f2*/{inti,j;全局變量p,q作用范圍…全局變量c1,c2作用范圍}voidmain()/*主函數(shù)*/{intm,n;…}
第86頁例8.15有一種一維數(shù)組,內(nèi)放10個學(xué)生成績,寫一種函數(shù),求出平均分、最高分和最低分。#include<stdio.h>floatMax=0,Min=0;/*全局變量*/voidmain(){floataverage(floatarray[],intn);floatave,score[10];inti;for(i=0;i<10;i++)scanf(″%f″,&score[i]);ave=
average(score,10);printf(“max=%6.2f\nmin=%6.2f\naverage=%6.2f\n“,Max,Min,ave);}第87頁floataverage(floatarray[],intn)
/*定義函數(shù),形參為數(shù)組*/{inti;floataver,sum=array[0];Max=Min=array[0];for(i=1;i<n;i++){if(array[i]>Max)Max=array[i];elseif(array[i]<Min)Min=array[i];sum=sum+array[i];}aver=sum/n;return(aver);}
運行狀況如下:9945789710067.589926643↙max=100.00min=43.00average=77.65第88頁第89頁提議不在必要時不要使用全局變量,原因如下:①全局變量在程序所有執(zhí)行過程中都占用寄存單元,而不是僅在需要時才開辟單元。②使用全局變量過多,會減少程序清晰性,人們往往難以清晰地判斷出每個瞬時各個外部變量值。在各個函數(shù)執(zhí)行時都也許變化外部變量值,程序輕易出錯。因此,要限制使用全局變量。第90頁③它使函數(shù)通用性減少了,由于函數(shù)在執(zhí)行時要依賴于其所在外部變量。假如將一種函數(shù)移到另一種文獻中,還要將有關(guān)外部變量及其值一起移過去。但若該外部變量與其他文獻變量同名時,就會出現(xiàn)問題,減少了程序可靠性和通用性。一般規(guī)定把C程序中函數(shù)做成一種封閉體,除了可以通過“實參——形參”渠道與外界發(fā)生聯(lián)絡(luò)外,沒有其他渠道。第91頁例8.16外部變量與局部變量同名#include<stdio.h>inta=3,b=5;/*a,b為外部變量*/a,b作用范圍voidmain()
{inta=8;/*a為局部變量*/局部變量a作用范圍printf(″%d″,max(a,b));全局變量b作用范圍}max(inta,intb)/*a,b為局部變量*/
{intc;c=a>b?a∶b;形參a、b作用范圍return(c);
}運行成果為8第92頁§8.9變量寄存類別§8.9.1動態(tài)寄存方式與靜態(tài)寄存方式前面已簡介了從變量作用域(即從空間)角度來分,可以分為全局變量和局部變量。那么從變量值存在時間(即生存期)角度來分,又可以分為靜態(tài)寄存方式和動態(tài)寄存方式。所謂靜態(tài)寄存方式是指在程序運行期間由系統(tǒng)分派固定寄存空間方式。而動態(tài)寄存方式則是在程序運行期間根據(jù)需要進行動態(tài)分派寄存空間方式。這個寄存空間可以分為三部分,1.程序區(qū)2.靜態(tài)寄存區(qū)3.動態(tài)寄存區(qū)第93頁在C語言中每一種變量和函數(shù)有兩個屬性:數(shù)據(jù)類型和數(shù)據(jù)寄存類別。對數(shù)據(jù)類型,讀者已熟悉(如整型、字符型等)。寄存類別指是數(shù)據(jù)在內(nèi)存中寄存方式。寄存方式分為兩大類:靜態(tài)寄存類和動態(tài)寄存類。詳細包括四種:自動(auto),靜態(tài)(static),寄存器(register),外部(extern)。根據(jù)變量寄存類別,可以懂得變量作用域和生存期。第94頁§8.9.2auto變量函數(shù)中局部變量,如不專門申明為static寄存類別,都是動態(tài)地分派寄存空間,數(shù)據(jù)寄存在動態(tài)寄存區(qū)中。函數(shù)中形參和在函數(shù)中定義變量(包括在復(fù)合語句中定義變量),都屬此類,在調(diào)用該函數(shù)時系統(tǒng)會給它們分派寄存空間,在函數(shù)調(diào)用結(jié)束時就自動釋放這些寄存空間。因此此類局部變量稱為自動變量。自動變量用關(guān)鍵字auto作寄存類別申明。例如:intf(inta)/*定義f函數(shù),a為形參*/{autointb,c=3;/*定義b、c為自動變量*/…}第95頁8.9.3用static申明局部變量有時但愿函數(shù)中局部變量值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,即其占用寄存單元不釋放,在下一次該函數(shù)調(diào)用時,該變量已經(jīng)有值,就是上一次函數(shù)調(diào)用結(jié)束時值。這時就應(yīng)當指定該局部變量為“靜態(tài)局部變量”,用關(guān)鍵字static進行申明。通過下面簡樸例子可以理解它特點。第96頁例8.17考察靜態(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;staticc=3;b=b+1;c=c+1;return(a+b+c);}第97頁對靜態(tài)局部變量闡明:(1)靜態(tài)局部變量屬于靜態(tài)寄存類別,在靜態(tài)寄存區(qū)內(nèi)分派寄存單元。在程序整個運行期間都不釋放。而自動變量(即動態(tài)局部變量)屬于動態(tài)寄存類別,占動態(tài)寄存區(qū)空間而不占靜態(tài)寄存區(qū)空間,函數(shù)調(diào)用結(jié)束后即釋放。(2)對靜態(tài)局部變量是在編譯時賦初值,即只賦初值一次,在程序運行時它已經(jīng)有初值。后來每次調(diào)用函數(shù)時不再重新賦初值而只是保留上次函數(shù)調(diào)用結(jié)束時值。而對自動變量賦初值,不是在編譯時進行,而是在函數(shù)調(diào)用時進行,每調(diào)用一次函數(shù)重新給一次初值,相稱于執(zhí)行一次賦值語句。第98頁(3)如在定義局部變量時不賦初值話,則對靜態(tài)局部變量來說,編譯時自動賦初值0(對數(shù)值型變量)或空字符(對字符變量)。而對自動變量來說,假如不賦初值則它值是一種不確定值。這是由于每次函數(shù)調(diào)用結(jié)束后寄存單元已釋放,下次調(diào)用時又重新另分派寄存單元,而所分派單元中值是不確定。(4)雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其他函數(shù)是不能引用它。第99頁例8.18輸出1到5階乘值。#include<stdio.h>voidmain(){intfac(intn);inti;for(i=1;i<=5;i++)printf(″%d!=%d\n″,i,fac(i));}Intfac(intn){staticintf=1;f=f*n;return(f);}第100頁8.9.4register變量
一般狀況下,變量(包括靜態(tài)寄存方式和動態(tài)寄存方式)值是寄存在內(nèi)存中。當程序中用到哪一種變量值時,由控制器發(fā)出指令將內(nèi)存中該變量值送到運算器中。通過運算器進行運算,假如需要存數(shù),再從運算器將數(shù)據(jù)送到內(nèi)存寄存。第101頁假如有某些變量使用頻繁(例如在一種函數(shù)中執(zhí)行10000次循環(huán),每次循環(huán)中都要引用某局部變量),則為存取變量值要花費不少時間。為提高執(zhí)行效率,C語言容許將局部變量值放在CPU中寄存器中,需要用時直接從寄存器取出參與運算,不必再到內(nèi)存中去存取。由于對寄存器存取速度遠高于對內(nèi)存存取速度,因此這樣做可以提高執(zhí)行效率。這種變量叫做寄存器變量,用關(guān)鍵字register作申明。例如,例8.19中程序是輸出1到n階乘值。第102頁例8.19使用寄存器變量#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;return(f);}第103頁8.9.5用extern申明外部變量外部變量是在函數(shù)外部定義全局變量,它作用域是從變量定義處開始,到本程序文獻末尾。在此作用域內(nèi),全局變量可認為程序中各個函數(shù)所引用。編譯時將外部變量分派在靜態(tài)寄存區(qū)。有時需要用extern來申明外部變量,以擴展外部變量作用城。第104頁1.在一種文獻內(nèi)申明外部變量例8.20用extern申明外部變量,擴展它在程序文獻中作用域。#include<stdio.h>voidmain(){intmax(int,int);/*外部變量申明*/externA,B;printf("%d\n",max(A,B));}intA=13,B=-8;/*定義外部變量*/intmax(intx,inty)/*定義max函數(shù)*/{intz;z=x>y?x:y;return(z);}第105頁2.在多文獻程序中申明外部變量例8.21用extern將外部變量作用域擴展到其他文獻。本程序作用是給定b值,輸入a和m,求a×b和am值。文獻file1.c中內(nèi)容為:#include<stdio.h>intA;/*定義外部變量*/voidmain(){intpower(int);/*函數(shù)申明*/intb=3,c,d,m;printf(″enterthenumberaanditspowerm:\n″);scanf(″%d,%d″,&A,&m);c=A*b;printf(″%d*%d=%d\n″,A,b,c);d=power(m);printf(″%d**%d=%d\n″,A,m,d);}第106頁文獻file2.c中內(nèi)容為:externA;/*申明A為一種已定義外部變量*/intpower(intn);{inti,y=1;for(i=1;i<=n;i++)y*=A;return(y);}第107頁8.9.6用static申明外部變量有時在程序設(shè)計中但愿某些外部變量只限于被本文獻引用,而不能被其他文獻引用。這時可以在定義外部變量時加一種static申明。例如:file1.cfile2.cstaticintA;externintA;voidmain()voidfun(intn){{……A=A*n;}第108頁8.9.7有關(guān)變量申明和定義對變量而言,申明與定義關(guān)系稍微復(fù)雜某些。在申明部分出現(xiàn)變量有兩種狀況:一種是需要建立寄存空間(如:inta;),另一種是不需要建立寄存空間(如:externa;)。前者稱為“定義性申明”(definingdeclaration),或簡稱定義(definition)。后者稱為“引用性申明”(referencingdeclaration)。廣義地說,申明包括定義,但并非所有申明都是定義。對“inta;”而言,它既是申明,又是定義。而對“externa;”而言,它是申明而不是定義。第109頁一般為了論述以便,把建立寄存空間申明稱定義,而把不需要建立寄存空間申明稱為申明。顯然這里指申明是狹義,即非定義性申明。例如:voidmain(){externA;/*是申明不是定義。申明A是一個已定義外部變量*/…}intA;第110頁§8.9.8寄存類別小結(jié)下面從不一樣樣角度做些歸納:(1)從作用域角度分,有局部變量和全局變量。它們采用寄存類別如下:局部變量|自動變量,即動態(tài)局部變量
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 液壓彎管機課程設(shè)計
- 2025版電力線路施工臨時道路使用合同3篇
- 二零二五年度標準合同:智能數(shù)據(jù)中心建設(shè)與運營協(xié)議2篇
- 消防工程課程設(shè)計
- 2025版:環(huán)保新材料研發(fā)合作合同標的專利申請與市場推廣3篇
- 紙漿制作物品課程設(shè)計
- 2025版鋼結(jié)構(gòu)廠房施工期食品安全與衛(wèi)生管理合同范本3篇
- 2025版股權(quán)重組與審計服務(wù)合同3篇
- 激光課程設(shè)計封面模板
- 二零二五年度親子娛樂中心經(jīng)營權(quán)轉(zhuǎn)讓合同2篇
- 浙江省金華市金東區(qū)2023-2024學(xué)年九年級上學(xué)期語文期末試卷
- 【7地星球期末】安徽省合肥市包河區(qū)智育聯(lián)盟校2023-2024學(xué)年七年級上學(xué)期期末地理試題(含解析)
- (2021)最高法民申5114號凱某建設(shè)工程合同糾紛案 指導(dǎo)
- 【9物(人)期末】安慶市宿松縣2023-2024學(xué)年九年級上學(xué)期期末考試物理試題
- 導(dǎo)航通信一體化考核試卷
- 尊重學(xué)術(shù)道德遵守學(xué)術(shù)規(guī)范學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 望廬山瀑布李白
- 室內(nèi)質(zhì)控品統(tǒng)一征訂單
- 《論語》誦讀計劃
- 2006年工資標準及套改對應(yīng)表
- 中英文對照財務(wù)報表-模板
評論
0/150
提交評論