




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
為什么要用函數(shù)
VS.使用函數(shù)可使程序清晰、精煉、簡(jiǎn)單、靈活。函數(shù)就是功能。每一個(gè)函數(shù)用來(lái)實(shí)現(xiàn)一個(gè)特定的功能。函數(shù)名應(yīng)反映其代表的功能。在設(shè)計(jì)較大程序時(shí),往往把它分為若干個(gè)程序模塊,每一個(gè)模塊包括一個(gè)或多個(gè)函數(shù),每個(gè)函數(shù)實(shí)現(xiàn)一個(gè)特定的功能。一個(gè)C程序可由一個(gè)主函數(shù)和若干個(gè)其他函數(shù)構(gòu)成。由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。為什么要用函數(shù)【例7.1】想輸出以下的結(jié)果,用函數(shù)調(diào)用實(shí)現(xiàn)。#include<stdio.h>intmain(){ voidprint_star(); //聲明print_star函數(shù)
voidprint_message(); //聲明print_message函數(shù)
print_star(); //調(diào)用print_star函數(shù)
print_message(); //print_message函數(shù)
print_star(); //調(diào)用print_star函數(shù)
return0;}voidprint_star() //定義print_star函數(shù){ printf("******************\n"); //輸出一行*號(hào)}voidprint_message() //定義print_message函數(shù){ printf("Howdoyoudo!\n"); //輸出一行文字信息}print_star和print_message都是用戶定義的函數(shù)名,分別用來(lái)輸出一排“*”號(hào)和一行文字信息。在定義這兩個(gè)函數(shù)時(shí)指定函數(shù)的類型為void,意為函數(shù)無(wú)類型,即無(wú)函數(shù)值,也就是說(shuō),執(zhí)行這兩個(gè)函數(shù)后不會(huì)把任何值帶回main函數(shù)。在程序中,定義print_star函數(shù)和print_message函數(shù)的位置是在main函數(shù)的后面,在這種情況下,應(yīng)當(dāng)在main函數(shù)之前或main函數(shù)中的開(kāi)頭部分,對(duì)以上兩個(gè)函數(shù)進(jìn)行“聲明”。函數(shù)聲明的作用是把有關(guān)函數(shù)的信息(函數(shù)名、函數(shù)類型、函數(shù)參數(shù)的個(gè)數(shù)與類型)通知編譯系統(tǒng),以便在編譯系統(tǒng)對(duì)程序進(jìn)行編譯時(shí),在進(jìn)行到main函數(shù)調(diào)用print_star()和print_message()時(shí)知道它們是函數(shù)而不是變量或其他對(duì)象。此外,還對(duì)調(diào)用函數(shù)的正確性進(jìn)行檢查(如類型、函數(shù)名、參數(shù)個(gè)數(shù)、參數(shù)類型等是否正確)。為什么要用函數(shù)(1)一個(gè)C程序由一個(gè)或多個(gè)程序模塊組成,每一個(gè)程序模塊作為一個(gè)源程序文件。較大的程序,可分別放在若干個(gè)源文件中。這樣便于分別編寫(xiě)和編譯,提高調(diào)試效率。一個(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ù)開(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ù)有兩種。①庫(kù)函數(shù),它是由系統(tǒng)提供的,用戶不必自己定義,可直接使用它們。應(yīng)該說(shuō)明,不同的C語(yǔ)言編譯系統(tǒng)提供的庫(kù)函數(shù)的數(shù)量和功能會(huì)有一些不同,當(dāng)然許多基本的函數(shù)是共同的。②用戶自己定義的函數(shù)。它是用以解決用戶專門(mén)需要的函數(shù)。(6)從函數(shù)的形式看,函數(shù)分兩類。①無(wú)參函數(shù)。在調(diào)用無(wú)參函數(shù)時(shí),主調(diào)函數(shù)不向被調(diào)用函數(shù)傳遞數(shù)據(jù)。②有參函數(shù)。在調(diào)用函數(shù)時(shí),主調(diào)函數(shù)在調(diào)用被調(diào)用函數(shù)時(shí),通過(guò)參數(shù)向被調(diào)用函數(shù)傳遞數(shù)據(jù)。定義函數(shù)為什么定義函數(shù)定義函數(shù)應(yīng)包括以下幾個(gè)內(nèi)容:(1)指定函數(shù)的名字,以便以后按名調(diào)用。(2)指定函數(shù)的類型,即函數(shù)返回值的類型。(3)指定函數(shù)的參數(shù)的名字和類型,以便在調(diào)用函數(shù)時(shí)向它們傳遞數(shù)據(jù)。對(duì)無(wú)參函數(shù)不需要這項(xiàng)。(4)指定函數(shù)應(yīng)當(dāng)完成什么操作,也就是函數(shù)是做什么的,即函數(shù)的功能。這是最重要的,是在函數(shù)體中解決的。C語(yǔ)言要求,在程序中用到的所有函數(shù),必須“先定義,后使用”。定義函數(shù)的方法類型名函數(shù)名(){
函數(shù)體}函數(shù)名后面括號(hào)內(nèi)的void表示“空”,即函數(shù)沒(méi)有參數(shù)。函數(shù)體包括聲明部分和語(yǔ)句部分。在定義函數(shù)時(shí)要用“類型標(biāo)識(shí)符”(即類型名)指定函數(shù)值的類型,即指定函數(shù)帶回來(lái)的值的類型。定義無(wú)參函數(shù)類型名函數(shù)名(void){
函數(shù)體}或類型名函數(shù)名(形式參數(shù)表列){
函數(shù)體}定義有參函數(shù)intmax(intx,inty){ intz; //聲明部分
z=x>y?x:y; //執(zhí)行語(yǔ)句部分
return(z);}類型名函數(shù)名(){}定義空函數(shù)函數(shù)體為空,什么也不做。調(diào)用函數(shù)函數(shù)調(diào)用的形式函數(shù)名(實(shí)參表列)print_star(); //調(diào)用無(wú)參函數(shù)c=max(a,b); //調(diào)用有參函數(shù)1.函數(shù)調(diào)用語(yǔ)句把函數(shù)調(diào)用單獨(dú)作為一個(gè)語(yǔ)句。如printf_star();這時(shí)不要求函數(shù)帶回值,只要求函數(shù)完成一定的操作。2.函數(shù)表達(dá)式函數(shù)調(diào)用出現(xiàn)在另一個(gè)表達(dá)式中,如c=max(a,b);
這時(shí)要求函數(shù)帶回一個(gè)確定的值以參加表達(dá)式的運(yùn)算。3.函數(shù)參數(shù)函數(shù)調(diào)用作為另一個(gè)函數(shù)調(diào)用時(shí)的實(shí)參。如m=max(a,max(b,c));,又如:printf(″%d″,max(a,b));形式參數(shù)和實(shí)際參數(shù)在調(diào)用有參函數(shù)時(shí),主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞關(guān)系。在定義函數(shù)時(shí)函數(shù)名后面括號(hào)中的變量名稱為“形式參數(shù)”(簡(jiǎn)稱“形參”)或“虛擬參數(shù)”。在主調(diào)函數(shù)中調(diào)用一個(gè)函數(shù)時(shí),函數(shù)名后面括號(hào)中的參數(shù)稱為“實(shí)際參數(shù)”(簡(jiǎn)稱“實(shí)參”)。實(shí)際參數(shù)可以是常量、變量或表達(dá)式,但要求它們有確定的值。實(shí)參與形參的類型應(yīng)相同或賦值兼容。賦值兼容是指實(shí)參與形參類型不同時(shí)能按不同類型數(shù)值的賦值規(guī)則進(jìn)行轉(zhuǎn)換。實(shí)參和形參間的數(shù)據(jù)傳遞【例7.2】輸入兩個(gè)整數(shù),要求輸出其中值較大者。要求用函數(shù)來(lái)找到大數(shù)。#include<stdio.h>intmain(){ intmax(intx,inty);
//對(duì)max函數(shù)的聲明
inta,b,c; printf("pleaseentertwointegernumbers:");//提示輸入數(shù)據(jù)
scanf("%d,%d",&a,&b); //輸入兩個(gè)整數(shù)
c=max(a,b);
//調(diào)用max函數(shù),有兩個(gè)實(shí)參。大數(shù)賦給變量c printf("maxis%d\n",c); //輸出大數(shù)c return0;}intmax(intx,inty)
//定義max函數(shù),有兩個(gè)參數(shù){ intz; //定義臨時(shí)變量z z=x>y?x:y; //把x和y中大者賦給z
return(z);
//把z作為max函數(shù)的值帶回main函數(shù)}定義函數(shù),名為max,函數(shù)類型為int。指定兩個(gè)形參x和y,形參的類型為int。主函數(shù)中包含了一個(gè)函數(shù)調(diào)用max(a,b)。max后面括號(hào)內(nèi)的a和b是實(shí)參。a和b是在main函數(shù)中定義的變量,x和y是函數(shù)max的形式參數(shù)。通過(guò)函數(shù)調(diào)用,在兩個(gè)函數(shù)之間發(fā)生數(shù)據(jù)傳遞,實(shí)參a和b的值傳遞給形參x和y,在max函數(shù)中把x和y中的大者賦給變量z,z的值作為函數(shù)值返回main函數(shù),賦給變量c。c=max(a,b); (main函數(shù))intmax(intx,inty) (max函數(shù)){ intz; z=x>y?x:y; return(z);}在調(diào)用函數(shù)過(guò)程中發(fā)生的實(shí)參與形參間的數(shù)據(jù)傳遞稱為“虛實(shí)結(jié)合”。函數(shù)調(diào)用的過(guò)程(1)在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調(diào)用時(shí),它們并不占內(nèi)存中的存儲(chǔ)單元。在發(fā)生函數(shù)調(diào)用時(shí),函數(shù)的形參才被臨時(shí)分配內(nèi)存單元。(2)將實(shí)參的值傳遞給對(duì)應(yīng)形參。(3)在執(zhí)行函數(shù)期間,由于形參已經(jīng)有值,就可以利用形參進(jìn)行有關(guān)的運(yùn)算。(4)通過(guò)return語(yǔ)句將函數(shù)值帶回到主調(diào)函數(shù)。應(yīng)當(dāng)注意返回值的類型與函數(shù)類型一致。如果函數(shù)不需要返回值,則不需要return語(yǔ)句。這時(shí)函數(shù)的類型應(yīng)定義為void類型。(5)調(diào)用結(jié)束,形參單元被釋放。注意:實(shí)參單元仍保留并維持原值,沒(méi)有改變。如果在執(zhí)行一個(gè)被調(diào)用函數(shù)時(shí),形參的值發(fā)生改變,不會(huì)改變主調(diào)函數(shù)的實(shí)參的值。因?yàn)閷?shí)參與形參是兩個(gè)不同的存儲(chǔ)單元。注意實(shí)參向形參的數(shù)據(jù)傳遞是“值傳遞”,單向傳遞,只能由實(shí)參傳給形參,而不能由形參傳給實(shí)參。實(shí)參和形參在內(nèi)存中占有不同的存儲(chǔ)單元,實(shí)參無(wú)法得到形參的值。函數(shù)的返回值(1)函數(shù)的返回值是通過(guò)函數(shù)中的return語(yǔ)句獲得的。一個(gè)函數(shù)中可以有一個(gè)以上的return語(yǔ)句,執(zhí)行到哪一個(gè)return語(yǔ)句,哪一個(gè)return語(yǔ)句就起作用。return語(yǔ)句后面的括號(hào)可以不要,如“returnz;”與“return(z);”等價(jià)。return后面的值可以是一個(gè)表達(dá)式。(2)函數(shù)值的類型。函數(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ù)類型決定返回值的類型。(4)對(duì)于不帶回值的函數(shù),應(yīng)當(dāng)用定義函數(shù)為“void類型”(或稱“空類型”)。這樣,系統(tǒng)就保證不使函數(shù)帶回任何值,即禁止在調(diào)用函數(shù)中使用被調(diào)用函數(shù)的返回值。此時(shí)在函數(shù)體中不得出現(xiàn)return語(yǔ)句。通常,希望通過(guò)函數(shù)調(diào)用使主調(diào)函數(shù)能得到一個(gè)確定的值,這就是函數(shù)值(函數(shù)的返回值)。intmax(floatx,floaty) //函數(shù)值為整型charletter(charc1,charc2) //函數(shù)值為字符型doublemin(intx,inty) //函數(shù)值為雙精度型函數(shù)的返回值【例7.3】將例7.2稍作改動(dòng),將在max函數(shù)中定義的變量z改為float型。函數(shù)返回值的類型與指定的函數(shù)類型不同,分析其處理方法。max函數(shù)的形參是float型,實(shí)參也是float型,在main函數(shù)中輸入給a和b的值是1.5和2.6。在調(diào)用max(a,b)時(shí),把a(bǔ)和b的值1.5和2.6傳遞給形參x和y。執(zhí)行函數(shù)max中的條件表達(dá)式“z=x>y?x:y”,使得變量z得到的值為2.6?,F(xiàn)在出現(xiàn)了矛盾:函數(shù)定義為int型,而return語(yǔ)句中的z為float型,要把z的值作為函數(shù)的返回值,二者不一致。怎樣處理呢?按賦值規(guī)則處理,先將z的值轉(zhuǎn)換為int型,得到2,它就是函數(shù)得到的返回值。如果將main函數(shù)中的c改為float型,用%f格式符輸出,輸出2.000000。因?yàn)檎{(diào)用max函數(shù)得到的是int型,函數(shù)值為整數(shù)2。#include<stdio.h>intmain(){ intmax(floatx,floaty);
floata,b; intc;
scanf("%f,%f",&a,&b);
c=max(a,b); printf("maxis%d\n",c); return0;}intmax(floatx,floaty){ floatz; //z為實(shí)型變量 z=x>y?x:y;
return(z); }對(duì)被調(diào)用函數(shù)的聲明和函數(shù)原型在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)(即被調(diào)用函數(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í)所需用到的信息“包含”到本文件中來(lái)。(3)如果使用用戶自己定義的函數(shù),而該函數(shù)的位置在調(diào)用它的函數(shù)(即主調(diào)函數(shù))的后面(在同一個(gè)文件中),應(yīng)該在主調(diào)函數(shù)中對(duì)被調(diào)用的函數(shù)作聲明(declaration)。聲明的作用是把函數(shù)名、函數(shù)參數(shù)的個(gè)數(shù)和參數(shù)類型等信息通知編譯系統(tǒng),以便在遇到函數(shù)調(diào)用時(shí),編譯系統(tǒng)能正確識(shí)別函數(shù)并檢查調(diào)用是否合法。對(duì)被調(diào)用函數(shù)的聲明和函數(shù)原型【例7.4】輸入兩個(gè)實(shí)數(shù),用一個(gè)函數(shù)求出它們之和。函數(shù)的聲明和函數(shù)定義中的第1行(函數(shù)首部)基本上是相同的,只差一個(gè)分號(hào)(函數(shù)聲明比函數(shù)定義中的首行多一個(gè)分號(hào))。函數(shù)的首行(即函數(shù)首部)稱為函數(shù)原型(functionprototype)。因?yàn)樵诤瘮?shù)的首部包含了檢查調(diào)用函數(shù)是否合法的基本信息(它包括了函數(shù)名、函數(shù)值類型、參數(shù)個(gè)數(shù)、參數(shù)類型和參數(shù)順序),因此,在函數(shù)調(diào)用時(shí)檢查函數(shù)原型是否與函數(shù)聲明一致。這樣就能保證函數(shù)的正確調(diào)用。#include<stdio.h>intmain(){ floatadd(floatx,floaty);
//對(duì)add函數(shù)作聲明
floata,b,c; printf("Pleaseenteraandb:"); //提示輸入
scanf("%f,%f",&a,&b); //輸入兩個(gè)實(shí)數(shù)
c=add(a,b);
//調(diào)用add函數(shù)
printf("sumis%f\n",c); //輸出兩數(shù)之和
return0;}floatadd(floatx,floaty)
//定義add函數(shù){ floatz; z=x+y;
return(z);
//把變量z的值作為函數(shù)值返回}對(duì)被調(diào)用函數(shù)的聲明和函數(shù)原型在函數(shù)聲明中的形參名可以省寫(xiě),而只寫(xiě)形參的類型。如果已在文件的開(kāi)頭(在所有函數(shù)之前),已對(duì)本文件中所調(diào)用的函數(shù)進(jìn)行了聲明,則在各函數(shù)中不必對(duì)其所調(diào)用的函數(shù)再作聲明。floatadd(floatx,floaty);floatadd(float,float); //不寫(xiě)參數(shù)名,只寫(xiě)參數(shù)類型floatadd(floata,
floatb); //參數(shù)名不用x,y,而用a,b。合法函數(shù)類型函數(shù)名(參數(shù)類型1參數(shù)名1,參數(shù)類型2參數(shù)名2,…,參數(shù)類型n參數(shù)名n);函數(shù)類型函數(shù)名(參數(shù)類型1,參數(shù)類型2,
…,參數(shù)類型n);或注意對(duì)函數(shù)的“定義”和“聲明”不是同一回事。函數(shù)的定義是指對(duì)函數(shù)功能的確立,包括指定函數(shù)名、函數(shù)值類型、形參及其類型以及函數(shù)體等,它是一個(gè)完整的、獨(dú)立的函數(shù)單位。而函數(shù)的聲明的作用則是把函數(shù)的名字、函數(shù)類型以及形參的類型、個(gè)數(shù)和順序通知編譯系統(tǒng),以便在調(diào)用該函數(shù)時(shí)系統(tǒng)按此進(jìn)行對(duì)照檢查,它不包含函數(shù)體。charletter(char,char);floatf(float,float);inti(float,float);//所有函數(shù)之前,且在函數(shù)外部進(jìn)行函數(shù)聲明intmain(){…}//在main函數(shù)中要調(diào)用letter,f和i函數(shù),不必再對(duì)所調(diào)用的這3個(gè)函數(shù)進(jìn)行聲明charletter(charc1,charc2){…} //定義letter函數(shù)floatf(floatx,floaty){…} //定義f函數(shù)inti(floatj,floatk){…} //定義i函數(shù)函數(shù)的嵌套調(diào)用①執(zhí)行main函數(shù)的開(kāi)頭部分;②遇函數(shù)調(diào)用語(yǔ)句,調(diào)用函數(shù)a,流程轉(zhuǎn)去a函數(shù);③執(zhí)行a函數(shù)的開(kāi)頭部分;④遇函數(shù)調(diào)用語(yǔ)句,調(diào)用函數(shù)b,流程轉(zhuǎn)去函數(shù)b;⑤執(zhí)行b函數(shù),如果再無(wú)其他嵌套的函數(shù),則完成b函數(shù)的全部操作;⑥返回到a函數(shù)中調(diào)用b函數(shù)的位置;⑦繼續(xù)執(zhí)行a函數(shù)中尚未執(zhí)行的部分,直到a函數(shù)結(jié)束;⑧返回main函數(shù)中調(diào)用a函數(shù)的位置;⑨繼續(xù)執(zhí)行main函數(shù)的剩余部分直到結(jié)束。C語(yǔ)言的函數(shù)定義是互相平行、獨(dú)立的,也就是說(shuō),在定義函數(shù)時(shí),一個(gè)函數(shù)內(nèi)不能再定義另一個(gè)函數(shù),即不能嵌套定義,但可以嵌套調(diào)用函數(shù),即在調(diào)用一個(gè)函數(shù)的過(guò)程中,又調(diào)用另一個(gè)函數(shù)。main函數(shù) a函數(shù) b函數(shù)①
②
③
④調(diào)用a函數(shù)
調(diào)用b函數(shù)
⑤⑨
⑧
⑦
⑥結(jié)束函數(shù)的嵌套調(diào)用【例7.5】輸入4個(gè)整數(shù),找出其中最大的數(shù)。用函數(shù)的嵌套調(diào)用來(lái)處理。#include<stdio.h>intmain(){ intmax4(inta,intb,intc,intd); //對(duì)max4的函數(shù)聲明
inta,b,c,d,max; printf("Pleaseenter4intergernumbers:"); //提示輸入4個(gè)數(shù)
scanf("%d%d%d%d",&a,&b,&c,&d); //輸入4個(gè)數(shù)
max=max4(a,b,c,d);//調(diào)用max4函數(shù),得到4個(gè)數(shù)中的最大者
printf("max=%d\n",max); //輸出4個(gè)數(shù)中的最大者
return0;}intmax4(inta,intb,intc,intd) //定義max4函數(shù){ intmax2(inta,intb); //對(duì)max2的函數(shù)聲明
intm; m=max2(a,b); //調(diào)用max2函數(shù),得到a和b中的大者,放在m中
m=max2(m,c);//調(diào)用max2函數(shù),得到a,b,c中的大者,放在m中
m=max2(m,d);//調(diào)用max2函數(shù),得到a,b,c,d中的大者,放在m中
return(m); //把m作為函數(shù)值帶回main函數(shù)}intmax2(inta,intb) //定義max2函數(shù){ if(a>=b) returna; //若a≥b,將a作為函數(shù)返回值
else returnb; //若a<b,將b作為函數(shù)返回值}在主函數(shù)中要調(diào)用max4函數(shù),因此在主函數(shù)的開(kāi)頭要對(duì)max4函數(shù)作聲明。在max4函數(shù)中3次調(diào)用max2函數(shù),因此在max4函數(shù)的開(kāi)頭要對(duì)max2函數(shù)作聲明。由于在主函數(shù)中沒(méi)有直接調(diào)用max2函數(shù),因此在主函數(shù)中不必對(duì)max2函數(shù)作聲明,只須在max4函數(shù)中作聲明即可。max4函數(shù)執(zhí)行過(guò)程:第1次調(diào)用max2函數(shù)得到的函數(shù)值是a和b中的大者,把它賦給變量m,第2次調(diào)用max2得到m和c中的大者,也就是a,b,c中的最大者,再把它賦給變量m。第3次調(diào)用max2得到m和d中的大者,也就是a,b,c,d中的最大者,再把它賦給變量m。這是一種遞推方法,先求出2個(gè)數(shù)的大者;再以此為基礎(chǔ)求出3個(gè)數(shù)的大者;再以此為基礎(chǔ)求出4個(gè)數(shù)的大者。m的值一次一次地變化,直到實(shí)現(xiàn)最終要求。(1)可以將max2函數(shù)的函數(shù)體改為只用一個(gè)return語(yǔ)句,返回一個(gè)條件表達(dá)式的值:(2)在max4函數(shù)中,3個(gè)調(diào)用max2的語(yǔ)句可以用以下一行代替:甚至可以取消變量m,max4函數(shù)可寫(xiě)成先調(diào)用“max2(a,b)”,得到a和b中的大者。再調(diào)用“max2(max2(a,b),c)”(其中max2(a,b)為已知),得到a,b,c三者中的大者。最后由“max2(max2(max2(a,b),c),d)”求得a,b,c,d四者中的大者。程序改進(jìn)intmax2(inta,intb)
//定義max2函數(shù){return(a>=b?a:b);}
//返回條件表達(dá)式的值,即a和b中的大者m=max2(max2(max2(a,b),c),d);
//把函數(shù)調(diào)用作為函數(shù)參數(shù)intmax4(inta,intb,intc,intd){
intmax2(inta,intb);
//對(duì)max2的函數(shù)聲明
returnmax2(max2(max2(a,b),c),d);}函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用程序中不應(yīng)出現(xiàn)無(wú)終止的遞歸調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的、有終止的遞歸調(diào)用,這可以用if語(yǔ)句來(lái)控制,只有在某一條件成立時(shí)才繼續(xù)執(zhí)行遞歸調(diào)用;否則就不再繼續(xù)。在調(diào)用一個(gè)函數(shù)的過(guò)程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。intf(intx){ inty,z; z=f(y); //在執(zhí)行f函數(shù)的過(guò)程中又要調(diào)用f函數(shù)
return(2*z);}f函數(shù)調(diào)用f函數(shù)直接遞歸f1函數(shù) f2函數(shù)調(diào)用f2函數(shù)
調(diào)用f1函數(shù)間接遞歸函數(shù)的遞歸調(diào)用【例7.6】有5個(gè)學(xué)生坐在一起,問(wèn)第5個(gè)學(xué)生多少歲,他說(shuō)比第4個(gè)學(xué)生大2歲。問(wèn)第4個(gè)學(xué)生歲數(shù),他說(shuō)比第3個(gè)學(xué)生大2歲。問(wèn)第3個(gè)學(xué)生,又說(shuō)比第2個(gè)學(xué)生大2歲。問(wèn)第2個(gè)學(xué)生,說(shuō)比第1個(gè)學(xué)生大2歲。最后問(wèn)第1個(gè)學(xué)生,他說(shuō)是10歲。請(qǐng)問(wèn)第5個(gè)學(xué)生多大。解題思路:age(n)=10 (n=1)age(n)=age(n-1)+2 (n>1)age(5) age(5)=age(4)+2 =18 age(4) age(4) =age(3)+2 =16 age(3) age(3) =age(2)+2 =14 age(2) age(2) =age(1)+2 =12 age(1)=10函數(shù)的遞歸調(diào)用【例7.6】有5個(gè)學(xué)生坐在一起,問(wèn)第5個(gè)學(xué)生多少歲,他說(shuō)比第4個(gè)學(xué)生大2歲。問(wèn)第4個(gè)學(xué)生歲數(shù),他說(shuō)比第3個(gè)學(xué)生大2歲。問(wèn)第3個(gè)學(xué)生,又說(shuō)比第2個(gè)學(xué)生大2歲。問(wèn)第2個(gè)學(xué)生,說(shuō)比第1個(gè)學(xué)生大2歲。最后問(wèn)第1個(gè)學(xué)生,他說(shuō)是10歲。請(qǐng)問(wèn)第5個(gè)學(xué)生多大。#include<stdio.h>intmain(){ intage(intn); //對(duì)age函數(shù)的聲明
printf("NO.5,age:%d\n",age(5)); //輸出第5個(gè)學(xué)生的年齡
return0;}intage(intn) //定義遞歸函數(shù){ intc; //c用作存放函數(shù)的返回值的變量 if(n==1) //如果n等于1 c=10; //年齡為10 else //如果n不等于1 c=age(n-1)+2;
//年齡是前一個(gè)學(xué)生的年齡加2(如第4個(gè)學(xué)生年齡是第3個(gè)學(xué)生年齡加2) return(c); //返回年齡}注意分析遞歸的終止條件。mainage(n)n=5age(n)n=4age(n)n=3age(n)n=2age(n)n=1age(5)輸出age(5)c=age(4)+2c=age(3)+2c=age(2)+2c=age(1)+2c=10age(5)=18age(4)=16age(3)=14age(2)=12age(1)=10函數(shù)的遞歸調(diào)用【例7.7】用遞歸方法求n!。
#include<stdio.h>intmain(){ intfac(intn); //fac函數(shù)聲明
intn; inty; printf("inputanintegernumber:"); scanf("%d",&n); //輸入要求階乘的數(shù)
y=fac(n); printf("%d!=%d\n",n,y); return0;}intfac(intn) //定義fac函數(shù){ intf; if(n<0) //n不能小于0 printf("n<0,dataerror!"); elseif(n==0||n==1) //n=0或,1時(shí)n!=1 f=1; //遞歸終止條件 else f=fac(n-1)*n; //n>1時(shí),n!=n*(n-1) return(f);}mainfac(n)n=5fac(n)n=4fac(n)n=3fac(n)n=2fac(n)n=1fac(5)輸出fac(5)f=fac(4)*5f=fac(3)*4f=fac(2)*3f=fac(1)*2f=1fac(5)=120fac(4)=24fac(3)=6fac(2)=2fac(1)=1注意程序中的變量是int型,如果用VisualC++、GCC以及多數(shù)C編譯系統(tǒng)為int型數(shù)據(jù)分配4個(gè)字節(jié),能表示的最大數(shù)為2147483647,當(dāng)n=12時(shí),運(yùn)行正常,輸出為479001600。如果輸入13,企圖求13!,是得不到預(yù)期結(jié)果的,因?yàn)榍蟪龅慕Y(jié)果超過(guò)了int型數(shù)據(jù)的最大值??蓪,y和fac函數(shù)定義為float或double型。函數(shù)的遞歸調(diào)用【例7.8】Hanoi(漢諾)塔問(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座,但規(guī)定每次只允許移動(dòng)一個(gè)盤(pán),且在移動(dòng)過(guò)程中在3個(gè)座上都始終保持大盤(pán)在下,小盤(pán)在上。在移動(dòng)過(guò)程中可以利用B座。要求編程序輸出移動(dòng)盤(pán)子的步驟。A B C解題思路:老和尚會(huì)這樣想:假如有另外一個(gè)和尚能有辦法將上面63個(gè)盤(pán)子從一個(gè)座移到另一座。那么,問(wèn)題就解決了。此時(shí)老和尚只須這樣做:①命令第2個(gè)和尚將63個(gè)盤(pán)子從A座移到B座;②自己將1個(gè)盤(pán)子(最底下的、最大的盤(pán)子)從A座移到C座;③再命令第2個(gè)和尚將63個(gè)盤(pán)子從B座移到C座。第2個(gè)和尚又想:如果有人能將62個(gè)盤(pán)子從一個(gè)座移到另一座,我就能將63個(gè)盤(pán)子從A座移到B座,他是這樣做的:①命令第3個(gè)和尚將62個(gè)盤(pán)子從A座移到C座;②自己將1個(gè)盤(pán)子從A座移到B座;③再命令第3個(gè)和尚將62個(gè)盤(pán)子從C座移到B座。……A B C63個(gè)盤(pán)子①③②A B C移動(dòng)前解題思路:為便于理解,先分析將A座上3個(gè)盤(pán)子移到C座上的過(guò)程:①將A座上2個(gè)盤(pán)子移到B座上(借助C座)。②將A座上1個(gè)盤(pán)子移到C座上。③將B座上2個(gè)盤(pán)子移到C座上(借助A座)。其中第②步可以直接實(shí)現(xiàn)。第①步又可用遞歸方法分解為:
將A座上1個(gè)盤(pán)子從A座移到C座;將A座上1個(gè)盤(pán)子從A座移到B座;將C座上1個(gè)盤(pán)子從C座移到B座。第③步可以分解為:
將B座上1個(gè)盤(pán)子從B座移到A座上;將B座上1個(gè)盤(pán)子從B座移到C座上;將A座上1個(gè)盤(pán)子從A座移到C座上。將以上綜合起來(lái),可得到移動(dòng)3個(gè)盤(pán)子的步驟為:A→C,A→B,C→B,A→C,B→A,B→C,A→C。共經(jīng)歷7步。由此可推出:移動(dòng)n個(gè)盤(pán)子要經(jīng)歷(2n-1)步。A B C①A B C②A B C③解題思路:由上面的分析可知:將n個(gè)盤(pán)子從A座移到C座可以分解為以下3個(gè)步驟:①將A座上n-1個(gè)盤(pán)借助C座先移到B座上;②把A座上剩下的一個(gè)盤(pán)移到C座上;③將n-1個(gè)盤(pán)從B座借助于A座移到C座上。上面第①步和第③步,都是把n-1個(gè)盤(pán)從一個(gè)座移到另一個(gè)座上,采取的辦法是一樣的,只是座的名字不同而已。為使之一般化,可以將第①步和第③步表示為:將one座上n-1個(gè)盤(pán)移到two座(借助three座)。只是在第①步和第③步中,one,two,three和A,B,C的對(duì)應(yīng)關(guān)系不同。對(duì)第①步,對(duì)應(yīng)關(guān)系是one對(duì)應(yīng)A,two對(duì)應(yīng)B,three對(duì)應(yīng)C。對(duì)第③步,是:one對(duì)應(yīng)B,two對(duì)應(yīng)C,three對(duì)應(yīng)A。因此,可以把上面3個(gè)步驟分成兩類操作:①將n-1個(gè)盤(pán)從一個(gè)座移到另一個(gè)座上(n>1)。這就是大和尚讓小和尚做的工作,它是一個(gè)遞歸的過(guò)程,即和尚將任務(wù)層層下放,直到第64個(gè)和尚為止?!猦anoi函數(shù)②將1個(gè)盤(pán)子從一個(gè)座上移到另一座上。這是大和尚自己做的工作?!猰ove函數(shù)在本程序中,調(diào)用遞歸函數(shù)hanoi,其終止條件為hanoi函數(shù)的參數(shù)n的值等于1。顯然,此時(shí)不必再調(diào)用hanoi函數(shù)了,直接執(zhí)行move函數(shù)即可。在本程序中move函數(shù)并未真正移動(dòng)盤(pán)子,而只是輸出移盤(pán)的方案(表示從哪一個(gè)座移到哪一個(gè)座)。#include<stdio.h>intmain(){ voidhanoi(intn,charone,chartwo,charthree);
//對(duì)hanoi函數(shù)的聲明
intm; printf("inputthenumberofdiskes:"); scanf("%d",&m); printf("Thesteptomove%ddiskes:\n",m); hanoi(m,'A','B','C');}voidhanoi(intn,charone,chartwo,charthree) //定義hanoi函數(shù)//將n個(gè)盤(pán)從one座借助two座,移到three座{ voidmove(charx,chary); //對(duì)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);}數(shù)組作為函數(shù)參數(shù)形式參數(shù)實(shí)在參數(shù)變量常量、變量、表達(dá)式、數(shù)組元素?cái)?shù)組數(shù)組數(shù)組元素作為函數(shù)實(shí)參數(shù)組元素可以用作函數(shù)實(shí)參,但是不能用作形參。因?yàn)樾螀⑹窃诤瘮?shù)被調(diào)用時(shí)臨時(shí)分配存儲(chǔ)單元的,不可能為一個(gè)數(shù)組元素單獨(dú)分配存儲(chǔ)單元(數(shù)組是一個(gè)整體,在內(nèi)存中占連續(xù)的一段存儲(chǔ)單元)。在用數(shù)組元素作函數(shù)實(shí)參時(shí),把實(shí)參的值傳給形參,是“值傳遞”方式。數(shù)據(jù)傳遞的方向是從實(shí)參傳到形參,單向傳遞。數(shù)組元素作函數(shù)實(shí)參【例7.9】輸入10個(gè)數(shù),要求輸出其中值最大的元素和該數(shù)是第幾個(gè)數(shù)。從鍵盤(pán)輸入10個(gè)數(shù)給a[0]~a[9]。變量m用來(lái)存放當(dāng)前已比較過(guò)的各數(shù)中的最大者。開(kāi)始時(shí)設(shè)m的值為a[0],然后依次將m與a[i]比,如果a[i]大于m,就以a[i]的值取代m的原值。下一次以m的新值與下一個(gè)a[i]比較。經(jīng)過(guò)9輪循環(huán)的比較,m最后的值就是10個(gè)數(shù)的最大數(shù)。請(qǐng)注意分析怎樣得到最大數(shù)是10個(gè)數(shù)中第幾個(gè)數(shù)。當(dāng)每次出現(xiàn)以max(m,a[i])的值取代m的原值時(shí),就把i的值保存在變量n中。n最后的值就是最大數(shù)的序號(hào)(注意序號(hào)從0開(kāi)始),如果要輸出“最大數(shù)是10個(gè)數(shù)中第幾個(gè)數(shù)”,應(yīng)為n+1。因?yàn)閿?shù)組元素序號(hào)從0開(kāi)始。#include<stdio.h>intmain(){ intmax(intx,inty); //函數(shù)聲明
inta[10],m,n,i; printf("enter10integernumbers:"); for(i=0;i<10;i++) //輸入10個(gè)數(shù)給a[0]~a[9] scanf("%d",&a[i]); printf("\n"); for(i=1,m=a[0],n=0;i<10;i++) { if(max(m,a[i])>m) //若max函數(shù)返回的值大于m { m=max(m,a[i]);
//max函數(shù)返回的值取代m原值
n=i; //把此數(shù)組元素的序號(hào)記下來(lái),放在n中
} } printf("Thelargestnumberis%d\nitisthe%dthnumber.\n",m,n+1);}intmax(intx,inty) //定義max函數(shù){ return(x>y?x:y); //返回x和y中的大者}一維數(shù)組名作函數(shù)參數(shù)【例7.10】有一個(gè)一維數(shù)組score,內(nèi)放10個(gè)學(xué)生成績(jī),求平均成績(jī)。(1)用數(shù)組名作函數(shù)參數(shù),應(yīng)該在主調(diào)函數(shù)和被調(diào)用函數(shù)分別定義數(shù)組。(2)實(shí)參數(shù)組與形參數(shù)組類型必須一致。(3)在定義average函數(shù)時(shí),聲明形參數(shù)組的大小為10,但在實(shí)際上,指定其大小是不起任何作用的,因?yàn)镃語(yǔ)言編譯系統(tǒng)并不檢查形參數(shù)組大小,只是將實(shí)參數(shù)組的首元素的地址傳給形參數(shù)組名。(4)形參數(shù)組可以不指定大小,在定義數(shù)組時(shí)在數(shù)組名后面跟一個(gè)空的方括號(hào)。#include<stdio.h>intmain(){ floataverage(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); //調(diào)用average函數(shù)
printf("averagescoreis%5.2f\n",aver); return0;}floataverage(floatarray[10]) //定義average函數(shù){ inti; floataver,sum=array[0]; for(i=1;i<10;i++) sum=sum+array[i]; //累加學(xué)生成績(jī)
aver=sum/10; return(aver);}floataverage(floatarray[])注意用數(shù)組元素作實(shí)參時(shí),向形參變量傳遞的是數(shù)組元素的值,而用數(shù)組名作函數(shù)實(shí)參時(shí),向形參(數(shù)組名或指針變量)傳遞的是數(shù)組首元素的地址。一維數(shù)組名作函數(shù)參數(shù)【例7.11】有兩個(gè)班級(jí),分別有35和30名學(xué)生,調(diào)用average函數(shù),分別求這兩個(gè)班的學(xué)生的平均成績(jī)。#include<stdio.h>intmain(){ floataverage(floatarray[],intn); floatscore1[5]={98.5,97,91.5,60,55}; //定義長(zhǎng)度為5的數(shù)組
floatscore2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5};
//定義長(zhǎng)度為10的數(shù)組
printf("TheaverageofclassAis%6.2f\n",average(score1,5));
//用數(shù)組名score1和5作實(shí)參
printf("TheaverageofclassBis%6.2f\n",average(score2,10));
//用數(shù)組名score2和10作實(shí)參
return0;}floataverage(floatarray[],intn)//定義average函數(shù),未指定形參數(shù)組長(zhǎng)度{ inti; floataver,sum=array[0]; for(i=1;i<n;i++) sum=sum+array[i]; //累加n個(gè)學(xué)生成績(jī)
aver=sum/n; return(aver);}floataverage(floatarray[])注意用數(shù)組名作函數(shù)實(shí)參時(shí),不是把數(shù)組元素的值傳遞給形參,而是把實(shí)參數(shù)組的首元素的地址傳遞給形參數(shù)組,這樣兩個(gè)數(shù)組就共占同一段內(nèi)存單元。a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]起始地址10002468101214161820b[0]b[1]b[2]b[3]b[4]b[5]b[6]b[7]b[8]b[9]一維數(shù)組名作函數(shù)參數(shù)【例7.12】用選擇法對(duì)數(shù)組中10個(gè)整數(shù)按由小到大排序。解題思路:所謂選擇法就是先將10個(gè)數(shù)中最小的數(shù)與a[0]對(duì)換;再將a[1]~a[9]中最小的數(shù)與a[1]對(duì)換……每比較一輪,找出一個(gè)未經(jīng)排序的數(shù)中最小的一個(gè)。共比較9輪。選擇排序法算法a[0]a[1]a[2]a[3]a[4]36194未排序時(shí)的情況16394將5個(gè)數(shù)中最小的數(shù)1與a[0]對(duì)換13694將余下的后面4個(gè)數(shù)中最小的數(shù)3與a[1]對(duì)換13496將余下的3個(gè)數(shù)中最小的數(shù)4與a[2]對(duì)換13469將余下的2個(gè)數(shù)中最小的數(shù)6與a[3]對(duì)換,至此完成排序可以看到在執(zhí)行函數(shù)調(diào)用語(yǔ)句“sort(a,10);”之前和之后,a數(shù)組中各元素的值是不同的。原來(lái)是無(wú)序的,執(zhí)行“sort(a,10);”后,a數(shù)組已經(jīng)排好序了,這是由于形參數(shù)組array已用選擇法進(jìn)行排序了,形參數(shù)組改變也使實(shí)參數(shù)組隨之改變。#include<stdio.h>intmain(){ voidsort(intarray[],intn); inta[10],i; printf("enterarray:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]);
sort(a,10); //調(diào)用sort函數(shù),a為數(shù)組名,大小為10 printf("Thesortedarray:\n"); for(i=0;i<10;i++) printf("%d",a[i]); printf("\n"); return0;}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; }}多維數(shù)組名作函數(shù)參數(shù)可以用多維數(shù)組名作為函數(shù)的實(shí)參和形參,在被調(diào)用函數(shù)中對(duì)形參數(shù)組定義時(shí)可以指定每一維的大小,也可以省略第一維的大小說(shuō)明。在定義二維數(shù)組時(shí),必須指定列數(shù)(即一行中包含幾個(gè)元素),由于形參數(shù)組與實(shí)參數(shù)組類型相同,所以它們是由具有相同長(zhǎng)度的一維數(shù)組所組成的。不能只指定第1維(行數(shù))而省略第2維(列數(shù))。在第2維大小相同的前提下,形參數(shù)組的第1維可以與實(shí)參數(shù)組不同。例如,實(shí)參數(shù)組定義為intscore[5][10];而形參數(shù)組定義為intarray[][10];或intarray[8][10];均可以。這時(shí)形參數(shù)組和實(shí)參數(shù)組都是由相同類型和大小的一維數(shù)組組成的。C語(yǔ)言編譯系統(tǒng)不檢查第一維的大小。intarray[3][10];或intarray[][10]; //二者等價(jià)intarray[][];或intarray[3][]; //必須指定列數(shù)多維數(shù)組名作函數(shù)參數(shù)【例7.13】有一個(gè)3×4的矩陣,求所有元素中的最大值。形參數(shù)組array第1維的大小省略,第2維大小不能省略,而且要和實(shí)參數(shù)組a的第2維的大小相同。在主函數(shù)調(diào)用max_value函數(shù)時(shí),把實(shí)參二維數(shù)組a的第1行的起始地址傳遞給形參數(shù)組array,因此array數(shù)組第1行的起始地址與a數(shù)組的第1行的起始地址相同。由于兩個(gè)數(shù)組的列數(shù)相同,因此array數(shù)組第2行的起始地址與a數(shù)組的第2行的起始地址相同。a[i][j]與array[i][j]同占一個(gè)存儲(chǔ)單元,它們具有同一個(gè)值。實(shí)際上,array[i][j]就是a[i][j],在函數(shù)中對(duì)array[i][j]的操作就是對(duì)a[i][j]的操作。#include<stdio.h>intmain(){ intmax_value(intarray[][4]); //函數(shù)聲明
inta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}}; //對(duì)數(shù)組元素賦初值
printf("Maxvalueis%d\n",max_value(a));
//max_value(a)為函數(shù)調(diào)用
return0;}intmax_value(intarray[][4]) //函數(shù)定義{ inti,j,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]; //把大者放在max中
return(max);}局部變量和全局變量每一個(gè)變量都有一個(gè)作用域問(wèn)題,即它們?cè)谑裁捶秶鷥?nèi)有效。局部變量定義變量可能有3種情況:(1)在函數(shù)的開(kāi)頭定義;(2)在函數(shù)內(nèi)的復(fù)合語(yǔ)句內(nèi)定義;(3)在函數(shù)的外部定義。在一個(gè)函數(shù)內(nèi)部定義的變量只在本函數(shù)范圍內(nèi)有效,也就是說(shuō)只有在本函數(shù)內(nèi)才能引用它們,在此函數(shù)以外是不能使用這些變量的。在復(fù)合語(yǔ)句內(nèi)定義的變量只在本復(fù)合語(yǔ)句范圍內(nèi)有效,只有在本復(fù)合語(yǔ)句內(nèi)才能引用它們。在該復(fù)合語(yǔ)句以外是不能使用這些變量的,以上這些稱為“局部變量”。局部變量
(1)主函數(shù)中定義的變量也只在主函數(shù)中有效。主函數(shù)也不能使用其他函數(shù)中定義的變量。(2)不同函數(shù)中可以使用同名的變量,它們代表不同的對(duì)象,互不干擾。(3)形式參數(shù)也是局部變量。只在定義它的函數(shù)中有效。其他函數(shù)中不能直接引用形參。(4)在一個(gè)函數(shù)內(nèi)部,可以在復(fù)合語(yǔ)句中定義變量,這些變量只在本復(fù)合語(yǔ)句中有效,這種復(fù)合語(yǔ)句也稱為“分程序”或“程序塊”。
全局變量程序的編譯單位是源程序文件,一個(gè)源文件可以包含一個(gè)或若干個(gè)函數(shù)。在函數(shù)內(nèi)定義的變量是局部變量,而在函數(shù)之外定義的變量稱為外部變量,外部變量是全局變量(也稱全程變量)。全局變量可以為本文件中其他函數(shù)所共用。它的有效范圍為從定義變量的位置開(kāi)始到本源文件結(jié)束。注意在函數(shù)內(nèi)定義的變量是局部變量,在函數(shù)外定義的變量是全局變量。全局變量
設(shè)置全局變量的作用是增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道。由于同一文件中的所有函數(shù)都能引用全局變量的值,因此如果在一個(gè)函數(shù)中改變了全局變量的值,就能影響到其他函數(shù)中全局變量的值。相當(dāng)于各個(gè)函數(shù)間有直接的傳遞通道。由于函數(shù)的調(diào)用只能帶回一個(gè)函數(shù)返回值,因此有時(shí)可以利用全局變量來(lái)增加函數(shù)間的聯(lián)系渠道,通過(guò)函數(shù)調(diào)用能得到一個(gè)以上的值。*為了便于區(qū)別全局變量和局部變量,在C程序設(shè)計(jì)人員中有一個(gè)習(xí)慣(但非規(guī)定),將全局變量名的第1個(gè)字母用大寫(xiě)表示。全局變量c1,c2的作用范圍全局變量p,q的作用范圍全局變量【例7.14】有一個(gè)一維數(shù)組,內(nèi)放10個(gè)學(xué)生成績(jī),寫(xiě)一個(gè)函數(shù),當(dāng)主函數(shù)調(diào)用此函數(shù)后,能求出平均分、最高分和最低分。#include<stdio.h>floatMax=0,Min=0;
//定義全局變量Max,Minintmain(){ floataverage(floatarray[],intn); floatave,score[10]; inti; printf("Pleaseenter10scores:"); 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); return0;}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);}全局變量MaxMinavescore10MaxMinmain函數(shù)averarraynMaxMinaverage函數(shù)變量的關(guān)系:全局變量但是,建議不在必要時(shí)不要使用全局變量,原因如下:①全局變量在程序的全部執(zhí)行過(guò)程中都占用存儲(chǔ)單元,而不是僅在需要時(shí)才開(kāi)辟單元。②它使函數(shù)的通用性降低了,因?yàn)槿绻诤瘮?shù)中引用了全局變量,那么執(zhí)行情況會(huì)受到有關(guān)的外部變量的影響,如果將一個(gè)函數(shù)移到另一個(gè)文件中,還要考慮把有關(guān)的外部變量及其值一起移過(guò)去。但是若該外部變量與其他文件的變量同名時(shí),就會(huì)出現(xiàn)問(wèn)題。這就降低了程序的可靠性和通用性。在程序設(shè)計(jì)中,在劃分模塊時(shí)要求模塊的“內(nèi)聚性”強(qiáng)、與其他模塊的“耦合性”弱。即模塊的功能要單一(不要把許多互不相干的功能放到一個(gè)模塊中),與其他模塊的相互影響要盡量少,而用全局變量是不符合這個(gè)原則的。一般要求把C程序中的函數(shù)做成一個(gè)相對(duì)的封閉體,除了可以通過(guò)“實(shí)參—形參”的渠道與外界發(fā)生聯(lián)系外,沒(méi)有其他渠道。這樣的程序移植性好,可讀性強(qiáng)。③使用全局變量過(guò)多,會(huì)降低程序的清晰性,人們往往難以清楚地判斷出每個(gè)瞬時(shí)各個(gè)外部變量的值。由于在各個(gè)函數(shù)執(zhí)行時(shí)都可能改變外部變量的值,程序容易出錯(cuò)。因此,要限制使用全局變量。全局變量【例7.15】若外部變量與局部變量同名,分析結(jié)果。#include<stdio.h>inta=3,b=5; //a,b是全局變量intmain(){ intmax(inta,intb); //函數(shù)聲明。a,b是形參
inta=8; //a是局部變量
printf("max=%d\n",max(a,b)); return0;}intmax(inta,intb) //a,b是函數(shù)形參{ intc; c=a>b?a:b; //把a(bǔ)和b中的大者存放在c中
return(c);}程序第2行定義了全局變量a和b,并對(duì)其初始化。第3行是main函數(shù),在main函數(shù)中(第6行)定義了一個(gè)局部變量a。局部變量a的作用范圍為第6~8行。在此范圍內(nèi)全局變量a被局部變量a屏蔽,相當(dāng)于全局變量a在此范圍內(nèi)不存在(即它不起作用),而全局變量b在此范圍內(nèi)有效。因此第6行中max(a,b)的實(shí)參a應(yīng)是局部變量a,所以max(a,b)相當(dāng)于max(8,5)。它的值為8。第10行起定義max函數(shù),形參a和b是局部變量。全局變量a和b在max函數(shù)范圍內(nèi)不起作用,所以函數(shù)max中的a和b不是全局變量a和b,而是形參a和b,它們的值是由實(shí)參傳給形參的,即8和5。變量的存儲(chǔ)方式和生存期動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式從變量值存在的時(shí)間(即生存期)來(lái)觀察,有的變量在程序運(yùn)行的整個(gè)過(guò)程都是存在的,而有的變量則是在調(diào)用其所在的函數(shù)時(shí)才臨時(shí)分配存儲(chǔ)單元,而在函數(shù)調(diào)用結(jié)束后該存儲(chǔ)單元就馬上釋放了,變量不存在了。也就是說(shuō),變量的存儲(chǔ)有兩種不同的方式:靜態(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ǔ)空間的方式。動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式數(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ù)時(shí)給形參分配存儲(chǔ)空間。②函數(shù)中定義的沒(méi)有用關(guān)鍵字static聲明的變量,即自動(dòng)變量。③函數(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ù)中定義了局部變量,在兩次調(diào)用時(shí)分配給這些局部變量的存儲(chǔ)空間的地址可能是不相同的。如果一個(gè)程序中包含若干個(gè)函數(shù),每個(gè)函數(shù)中的局部變量的生存期并不等于整個(gè)程序的執(zhí)行周期,它只是程序執(zhí)行周期的一部分。在程序執(zhí)行過(guò)程中,先后調(diào)用各個(gè)函數(shù),此時(shí)會(huì)動(dòng)態(tài)地分配和釋放存儲(chǔ)空間。用戶區(qū)程序區(qū)靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)存儲(chǔ)區(qū)存儲(chǔ)類別在C語(yǔ)言中,每一個(gè)變量和函數(shù)都有兩個(gè)屬性:數(shù)據(jù)類型和數(shù)據(jù)的存儲(chǔ)類別。存儲(chǔ)類別指的是數(shù)據(jù)在內(nèi)存中存儲(chǔ)的方式(如靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ))。在定義和聲明變量和函數(shù)時(shí),一般應(yīng)同時(shí)指定其數(shù)據(jù)類型和存儲(chǔ)類別,也可以采用默認(rèn)方式指定(即如果用戶不指定,系統(tǒng)會(huì)隱含地指定為某一種存儲(chǔ)類別)。C的存儲(chǔ)類別包括4種:自動(dòng)的(auto)、靜態(tài)的(statis)、寄存器的(register)、外部的(extern)。根據(jù)變量的存儲(chǔ)類別,可以知道變量的作用域和生存期。局部變量的存儲(chǔ)類別自動(dòng)變量(auto變量)函數(shù)中的局部變量,如果不專門(mén)聲明為static(靜態(tài))存儲(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ǔ)類別的聲明。實(shí)際上,關(guān)鍵字auto可以省略,不寫(xiě)auto則隱含指定為“自動(dòng)存儲(chǔ)類別”,它屬于動(dòng)態(tài)存儲(chǔ)方式。程序中大多數(shù)變量屬于自動(dòng)變量。
autointb,c=3; //等價(jià)于intb,c=3;有時(shí)希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而繼續(xù)保留原值,即其占用的存儲(chǔ)單元不釋放,在下一次再調(diào)用該函數(shù)時(shí),該變量已有值(就是上一次函數(shù)調(diào)用結(jié)束時(shí)的值)。這時(shí)就應(yīng)該指定該局部變量為“靜態(tài)局部變量”,用關(guān)鍵字static進(jìn)行聲明。局部變量的存儲(chǔ)類別靜態(tài)局部變量(static局部變量)【例7.16】考察靜態(tài)局部變量的值。#include<stdio.h>intmain(){ intf(int); //函數(shù)聲明
inta=2,i; //自動(dòng)局部變量
for(i=0;i<3;i++) printf("%d\n",f(a)); //輸出f(a)的值
return0;}intf(inta){ autointb=0; //自動(dòng)局部變量
staticintc=3; //靜態(tài)局部變量
b=b+1; c=c+1; return(a+b+c);}靜態(tài)變量與自動(dòng)變量的值的比較分析第幾次調(diào)用調(diào)用時(shí)初值調(diào)用結(jié)束時(shí)的值bcbca+b+c第1次03147第2次04158第3次05169局部變量的存儲(chǔ)類別靜態(tài)局部變量(static局部變量)(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ù)值型變量)或空字符′\0′(對(duì)字符變量)。而對(duì)自動(dòng)變量來(lái)說(shuō),它的值是一個(gè)不確定的值。這是由于每次函數(shù)調(diào)用結(jié)束后存儲(chǔ)單元已釋放,下次調(diào)用時(shí)又重新另分配存儲(chǔ)單元,而所分配的單元中的內(nèi)容是不可知的。(4)雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其他函數(shù)是不能引用它的。因?yàn)樗蔷植孔兞?,只能被本函?shù)引用,而不能被其他函數(shù)引用。局部變量的存儲(chǔ)類別【例7.17】輸出1到5的階乘值。#include<stdio.h>intmain(){ intfac(intn); inti; for(i=1;i<=5;i++) //先后5次調(diào)用fac函數(shù)
printf("%d!=%d\n",i,fac(i)); //每次計(jì)算并輸出i!的值
return0;}intfac(intn){ staticintf=1;
//f保留了上次調(diào)用結(jié)束時(shí)的值
f=f*n; //在上次的f值的基礎(chǔ)上再乘以n return(f);
//返回值f是n!的值}(1)每次調(diào)用fac(i),輸出一個(gè)i!,同時(shí)保留這個(gè)i!的值以便下次再乘(i+1)。(2)如果函數(shù)中的變量只被引用而不改變值,則定義為靜態(tài)局部變量(同時(shí)初始化)比較方便,以免每次調(diào)用時(shí)重新賦值。注意用靜態(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)前值是什么。因此,若非必要,不要多用靜態(tài)局部變量。局部變量的存儲(chǔ)類別寄存器變量(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í)行效率,允許將局部變量的值放在CPU中的寄存器中,需要用時(shí)直接從寄存器取出參加運(yùn)算,不必再到內(nèi)存中去存取。由于對(duì)寄存器的存取速度遠(yuǎn)高于對(duì)內(nèi)存的存取速度,因此這樣做可以提高執(zhí)行效率。這種變量叫做寄存器變量,用關(guān)鍵字register作聲明。如由于現(xiàn)在的計(jì)算機(jī)的速度愈來(lái)愈快,性能愈來(lái)愈高,優(yōu)化的編譯系統(tǒng)能夠識(shí)別使用頻繁的變量,從而自動(dòng)地將這些變量放在寄存器中,而不需要程序設(shè)計(jì)者指定。因此,現(xiàn)在實(shí)際上用register聲明變量的必要性不大。registerintf; //定義f為寄存器變量注意3種局部變量的存儲(chǔ)位置是不同的:自動(dòng)變量存儲(chǔ)在動(dòng)態(tài)存儲(chǔ)區(qū);靜態(tài)局部變量存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū);寄存器存儲(chǔ)在CPU中的寄存器中。全局變量的存儲(chǔ)類別全局變量都是存放在靜態(tài)存儲(chǔ)區(qū)中的。因此它們的生存期是固定的,存在于程序的整個(gè)運(yùn)行過(guò)程。一般來(lái)說(shuō),外部變量是在函數(shù)的外部定義的全局變量,它的作用域是從變量的定義處開(kāi)始,到本程序文件的末尾。在此作用域內(nèi),全局變量可以為程序中各個(gè)函數(shù)所引用。但有時(shí)程序設(shè)計(jì)人員希望能擴(kuò)展外部變量的作用域。全局變量的存儲(chǔ)類別在一個(gè)文件內(nèi)擴(kuò)展外部變量的作用域如果外部變量不在文件的開(kāi)頭定義,其有效的作用范圍只限于定義處到文件結(jié)束。在定義點(diǎn)之前的函數(shù)不能引用該外部變量。如果由于某種考慮,在定義點(diǎn)之前的函數(shù)需要引用該外部變量,則應(yīng)該在引用之前用關(guān)鍵字extern對(duì)該變量作“外部變量聲明”,表示把該外部變量的作用域擴(kuò)展到此位置。有了此聲明,就可以從“聲明”處起,合法地使用該外部變量?!纠?.18】調(diào)用函數(shù),求3個(gè)整數(shù)中的大者。#include<stdio.h>intmain(){ intmax();
externintA,B,C;
//把外部變量A,B,C的作用域擴(kuò)展到從此處開(kāi)始
printf("Pleaseenterthreeintegernumbers:"); scanf("%d%d%d",&A,&B,&C);
//輸入3個(gè)整數(shù)給A,B,C printf("maxis%d\n",max()); return0;}intA,B,C;
//定義外部變量A,B,Cintmax(){ intm; m=A>B?A:B; //把A和B中的大者放在m中
if(C>m)m=C;
//將A,B,C三者中的大者放在m中
return(m); //返回m的值}注意提倡將外部變量的定義放在引用它的所有函數(shù)之前,這樣可以避免在函數(shù)中多加一個(gè)extern聲明。用extern聲明外部變量時(shí),類型名可以寫(xiě)也可以省寫(xiě)。例如,“externintA,B,C;”也可以寫(xiě)成“externA,B,C;”。因?yàn)樗皇嵌x變量,可以不指定類型,只須寫(xiě)出外部變量名即可。全局變量的存儲(chǔ)類別將外部變量的作用域擴(kuò)展到其他文件如果一個(gè)程序包含兩個(gè)文件,在兩個(gè)文件中都要用到同一個(gè)外部變量Num,不能分別在兩個(gè)文件中各自定義一個(gè)外部變量Num,否則在進(jìn)行程序的連接時(shí)會(huì)出現(xiàn)“重復(fù)定義”的錯(cuò)誤。正確的做法是:在任一個(gè)文件中定義外部變量Num,而在另一文件中用extern對(duì)Num作“外部變量聲明”,即“externNum;”。在編譯和連接時(shí),系統(tǒng)會(huì)由此知道Num有“外部鏈接”,可以從別處找到已定義的外部變量Num,并將在另一文件中定義的外部變量Num的作用域擴(kuò)展到本文件,在本文件中可以合法地引用外部變量Num?!纠?.19】給定b的值,輸入a和m,求a*b和am的值。#include<stdio.h>intA; //定義外部變量intmain(){ 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); return0;}file1.cexternA;//把file1中定義的外部變量的作用域擴(kuò)展到本文件intpower(intn){ inti,y=1; for(i=1;i<=n;i++) y*=A; return(y);}file2.c注意用這種方法擴(kuò)展全局變量的作用域應(yīng)十分慎重,因?yàn)樵趫?zhí)行一個(gè)文件中的操作時(shí),可能會(huì)改變?cè)撊肿兞康闹担瑫?huì)影響到另一文件中全局變量的值,從而影響該文件中函數(shù)的執(zhí)行結(jié)果。全局變量的存儲(chǔ)類別將外部變量的作用域擴(kuò)展到其他文件extern既可以用來(lái)擴(kuò)展外部變量在本文件中的作用域,又可以使外部變量的作用域從一個(gè)文件擴(kuò)展到程序中的其他文件,系統(tǒng)在編譯過(guò)程中遇到extern時(shí),先在本文件中找外部變量的定義,如果找到,就在本文件中擴(kuò)展作用域;如果找不到,就在連接時(shí)從其他文件中找外部變量的定義。如果從其他文件中找到了,就將作用域擴(kuò)展到本文件;如果再找不到,就按出錯(cuò)處理。全局變量的存儲(chǔ)類別將外部變量的作用域限制在本文件中有時(shí)在程序設(shè)計(jì)中希望某些外部變量只限于被本文件引用,而不能被其他文件引用。這時(shí)可以在定義外部變量時(shí)加一個(gè)static聲明。這種加上static聲明、只能用于本文件的外部變量稱為靜態(tài)外部變量。在程序設(shè)計(jì)中,常由若干人分別完成各個(gè)模塊,各人可以獨(dú)立地在其設(shè)計(jì)的文件中使用相同的外部變量名而互不相干。只須在每個(gè)文件中定義外部變量時(shí)加上static即可。這就為程序的模塊化、通用性提供方便。如果已確認(rèn)其他文件不需要引用本文件的外部變量,就可以對(duì)本文件中的外部變量都加上static,成為靜態(tài)外部變量,以免被其他文件誤用。至于在各文件中在函數(shù)內(nèi)定義的局部變量,本來(lái)就不能被函數(shù)外引用,更不能被其他文件引用,因此是安全的。
file1.c
file2.c全局變量的存儲(chǔ)類別將外部變量的作用域限制在本文件中不要誤認(rèn)為對(duì)外部變量加static
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 叉車臺(tái)班合同范本
- 音樂(lè)課程合同范本
- 清運(yùn)泥土合同范本
- 口腔護(hù)士合同范本簡(jiǎn)易
- 醫(yī)院工傷協(xié)作合同范本
- 臺(tái)球俱樂(lè)部合同范本
- 兄弟合作合同范本
- 合同9人合作合同范本
- 買本田新車合同范本
- 產(chǎn)地供應(yīng)合同范本
- 牧童謠課件教學(xué)
- 大學(xué)物理實(shí)驗(yàn)(緒論)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 圖書(shū)出版項(xiàng)目合作協(xié)議
- 《現(xiàn)代家政導(dǎo)論》電子教案 2.2模塊二項(xiàng)目二家庭制度認(rèn)知
- 商務(wù)禮儀課件教學(xué)課件
- 部編版七年級(jí)歷史下冊(cè)全冊(cè)導(dǎo)學(xué)案
- 酒店住宿投標(biāo)方案(技術(shù)標(biāo))
- 2024風(fēng)力發(fā)電葉片維保作業(yè)技術(shù)規(guī)范
- 中建分供方資源管理辦法
- (人教PEP2024版)英語(yǔ)一年級(jí)上冊(cè)Unit 3 教學(xué)課件(新教材)
- 小小演說(shuō)家演講技巧教學(xué)設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論