版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
C語(yǔ)言程序設(shè)計(jì)(三)8.1概述8.2函數(shù)調(diào)用和返回值8.3函數(shù)調(diào)用時(shí)的參數(shù)傳遞8.4函數(shù)的嵌套調(diào)用和遞歸調(diào)用8.5函數(shù)與指針8.6變量的作用域和存儲(chǔ)屬性8.7編譯預(yù)處理第8章函數(shù)【本章導(dǎo)讀】在C語(yǔ)言中,函數(shù)的含義不是數(shù)學(xué)中的函數(shù)關(guān)系或表達(dá)式,而是一個(gè)程序模塊。本章介紹C語(yǔ)言中函數(shù)的定義與調(diào)用、函數(shù)的參數(shù)和返回值、函數(shù)間的數(shù)據(jù)傳遞方法、函數(shù)的遞歸調(diào)用、函數(shù)與指針的關(guān)系、變量的作用域和存儲(chǔ)屬性、編譯預(yù)處理等。通過(guò)本章的學(xué)習(xí),要求讀者理解函數(shù)的概念,掌握函數(shù)定義和函數(shù)調(diào)用的方法,理解函數(shù)調(diào)用的實(shí)質(zhì),掌握有參函數(shù)的數(shù)據(jù)傳遞方法,區(qū)分“值傳遞〞與“地址傳遞〞的概念。理解函數(shù)遞歸調(diào)用的概念,掌握遞歸函數(shù)設(shè)計(jì)的一般方法。熟悉函數(shù)與指針的關(guān)系,理解變量存儲(chǔ)類別以及作用域和生存期的概念,會(huì)用一般預(yù)編譯命令,掌握模塊化程序設(shè)計(jì)的一般方法與技巧。8.1概述人們?cè)谇蠼庖粋€(gè)問(wèn)題時(shí),通常采用的是逐步分解、分而治之的方法,即把一個(gè)大問(wèn)題分解成假設(shè)干個(gè)比較易解的小問(wèn)題,然后分別求解。一個(gè)模塊化程序就是用高級(jí)語(yǔ)言表示的模塊化算法。這種程序便于編寫、閱讀、修改和維護(hù),提高了程序的可靠性,保證了程序的質(zhì)量。在C語(yǔ)言中,程序的根本單位是函數(shù),函數(shù)就是程序的根本模塊。8.1.1C語(yǔ)言程序的結(jié)構(gòu)
一個(gè)較大的程序通常分為假設(shè)干個(gè)子程序模塊,每個(gè)子程序模塊實(shí)現(xiàn)一個(gè)特定的功能。在C語(yǔ)言中,這些子程序模塊是由函數(shù)來(lái)完成的。一個(gè)C程序可由一個(gè)主函數(shù)和假設(shè)干個(gè)函數(shù)組成。程序執(zhí)行時(shí),從主函數(shù)開(kāi)始,通過(guò)主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以相互調(diào)用。同一個(gè)函數(shù)可以被一個(gè)或多個(gè)函數(shù)調(diào)用。圖8-1是程序中函數(shù)調(diào)用的示意圖。圖8-1C程序函數(shù)調(diào)用示意圖例8-1函數(shù)調(diào)用的例子#include<stdio.h>
main()/*主函數(shù)main*/
{printa();/*調(diào)用printa函數(shù)*/
printb();/*調(diào)用printb函數(shù)*/
printc();/*調(diào)用printc函數(shù)*/
}printa()/*定義printa函數(shù)*/
{printf(“**********\n〞);}printb()/*定義printb函數(shù)*/
{printf(“Cprogram!\n〞);
printa();/*調(diào)用printa函數(shù)*/
}printc()/*定義printc函數(shù)*/
{printf("----------\n");}(1)一個(gè)源程序文件由一個(gè)或多個(gè)函數(shù)構(gòu)成,每個(gè)函數(shù)完成一個(gè)相對(duì)獨(dú)立的任務(wù)。(2)一個(gè)C程序是由一個(gè)或多個(gè)源程序文件組成。一個(gè)C程序是一個(gè)編譯單位,即C語(yǔ)言是以源程序?yàn)閱挝贿M(jìn)行編譯,而不是以函數(shù)為單位進(jìn)行編譯。(3)C程序的執(zhí)行從main函數(shù)開(kāi)始,main函數(shù)調(diào)用其他函數(shù)后流程返回到main函數(shù),在main函數(shù)中結(jié)束整個(gè)程序的運(yùn)行。(4)所有函數(shù)在定義時(shí)都是相互獨(dú)立的,一個(gè)函數(shù)并不附屬于另一個(gè)函數(shù)。也就是說(shuō),在一個(gè)函數(shù)的函數(shù)體內(nèi),不能再定義另一個(gè)函數(shù),即函數(shù)不能嵌套定義。函數(shù)間可以相互調(diào)用,但不能調(diào)用main函數(shù)。說(shuō)明C語(yǔ)言程序結(jié)構(gòu)示意圖:1.從函數(shù)定義的角度,函數(shù)分為兩種:(1)標(biāo)準(zhǔn)函數(shù),即庫(kù)函數(shù)。由系統(tǒng)提供,用戶無(wú)須定義和說(shuō)明,只需在程序前包含有該函數(shù)原型的頭文件,就可在程序中直接使用。如scanf、printf、getchar、putchar、sqrt等都是標(biāo)準(zhǔn)函數(shù)。應(yīng)該說(shuō)明,不同的C系統(tǒng)提供的庫(kù)函數(shù)的數(shù)量和功能不同,當(dāng)然有一些根本的函數(shù)是共同的。(2)用戶自定義函數(shù)。用戶根據(jù)需要,自己定義用以完成某種功能的函數(shù)。如例8-1中printa、printb和printc等都是用戶定義的函數(shù)。8.1.2C語(yǔ)言函數(shù)的分類2.從函數(shù)參數(shù)的角度,函數(shù)分為兩種:(1)無(wú)參函數(shù)。函數(shù)定義、函數(shù)說(shuō)明、函數(shù)調(diào)用均不帶參數(shù)。主調(diào)函數(shù)和被調(diào)函數(shù)之間不進(jìn)行參數(shù)傳遞,如例8-1中printa、printb和printc三個(gè)都是無(wú)參函數(shù)。此類函數(shù)通常用來(lái)完成一組指定的功能,可以返回或不返回函數(shù)值,一般不返回函數(shù)值居多。(2)有參函數(shù)。函數(shù)定義、函數(shù)說(shuō)明時(shí)都有參數(shù),稱為形式參數(shù)(簡(jiǎn)稱形參)。函數(shù)調(diào)用時(shí)必須給出參數(shù),稱為實(shí)際參數(shù)(簡(jiǎn)稱實(shí)參)。進(jìn)行調(diào)用時(shí),主調(diào)函數(shù)單向地把實(shí)參的值傳遞給形參,供被調(diào)函數(shù)使用。被調(diào)函數(shù)可以通過(guò)返回函數(shù)值將結(jié)果帶回供主調(diào)函數(shù)使用。8.1.2C語(yǔ)言函數(shù)的分類
3.函數(shù)分類的其他角度:(1)根據(jù)函數(shù)是否返回值分成有返回值和無(wú)返回值兩種;(2)根據(jù)返回值的類型分成整型函數(shù)、實(shí)型函數(shù)、字符型函數(shù)、指針函數(shù)等等。8.1.3函數(shù)的定義1.無(wú)參函數(shù)定義的一般形式類型說(shuō)明符函數(shù)名(){
說(shuō)明局部語(yǔ)句
執(zhí)行局部語(yǔ)句
}其中類型說(shuō)明符和函數(shù)名()稱為函數(shù)頭。類型說(shuō)明符是指該函數(shù)值的類型,即函數(shù)返回值的類型。函數(shù)名是用戶自己定義的標(biāo)識(shí)符,函數(shù)名后面必須有一對(duì)空括號(hào)()?;ɡㄌ?hào){}中的內(nèi)容稱為函數(shù)體,由說(shuō)明局部和執(zhí)行局部語(yǔ)句序列組成。無(wú)參函數(shù)一般不需要有返回值,因此沒(méi)有函數(shù)值的類型,此時(shí)應(yīng)將函數(shù)值的類型定義為void,即空類型,以確定函數(shù)返回時(shí)不帶回任何值。說(shuō)明【例8-2】包含無(wú)參函數(shù)的C程序例。/*EX8-2.C*/voidmax()/*自定義一個(gè)無(wú)參函數(shù)*/{inta,b,c;scanf("%d,%d",&a,&b);c=a>b?a:b;printf("max=%d\n",c);}main()/*主函數(shù)*/{max();/*函數(shù)調(diào)用*/}【例8-3】包含無(wú)參但有返回值函數(shù)的C程序例。/*EX8-3.C*/intmax1()/*自定義一個(gè)有返回值的無(wú)參函數(shù)*/{inta,b,c;scanf("%d,%d",&a,&b);c=a>b?a:b;return(c);/*函數(shù)返回值*/}main()/*主函數(shù)*/{intm;m=max1();/*函數(shù)調(diào)用*/printf("max=%d\n",m);}2.有參函數(shù)定義的一般形式:類型函數(shù)名(類型形參1,類型形參2,…){說(shuō)明局部語(yǔ)句
執(zhí)行局部語(yǔ)句
}8.1.3函數(shù)的定義與無(wú)參函數(shù)的定義相比,有參函數(shù)的定義在函數(shù)頭局部多了形式參數(shù)和形式參數(shù)類型說(shuō)明的內(nèi)容。形式參數(shù)通常簡(jiǎn)稱為形參。形參可以是任何類型的變量,參數(shù)間用逗號(hào)分隔。在函數(shù)調(diào)用時(shí),主調(diào)函數(shù)將通過(guò)實(shí)際參數(shù)賦予這些形式參數(shù)以實(shí)際值。說(shuō)明【例8-4】包含有參函數(shù)的C程序例如。/*EX8-4.C*/intmax2(intx,inty)/*自定義一個(gè)有參函數(shù)*/{intz;z=x>y?x:y;return(z);/*函數(shù)返回值*/}main()/*主函數(shù)*/{inta,b,m;scanf("%d,%d",&a,&b);m=max2(a,b);/*函數(shù)調(diào)用*/printf("max=%d\n",m);}【例8-5】輸入一個(gè)數(shù)n,打印n個(gè)‘*’。/*EX8-5.C*/voidprintstars(intn)/*定義一個(gè)有參但無(wú)返回值的函數(shù)*/{inti;for(i=1;i<=n;i++)printf("*");printf("\n");}main()/*主函數(shù)*/{intm;scanf("%d",&m);printstars(m);/*函數(shù)調(diào)用*/}【注意】(1)如果在定義函數(shù)時(shí)沒(méi)有指定函數(shù)類型,系統(tǒng)會(huì)隱含指定函數(shù)類型為int型。因此,int型函數(shù)定義時(shí)函數(shù)名左邊的int可以省略不寫。因此,【例8-3】中函數(shù)max1和【例8-4】中函數(shù)max2定義時(shí)左邊的int都可以省略不寫。(2)系統(tǒng)容許有返回值函數(shù)不返回函數(shù)值?!翱蘸瘮?shù)〞定義的一般形式
類型說(shuō)明符函數(shù)名()
{}例如:khs(){}主函數(shù)中也有調(diào)用語(yǔ)句:khs();但沒(méi)有任何作用。“空函數(shù)〞沒(méi)有執(zhí)行作用,僅僅是取一個(gè)名字,一般是為今后程序中增加函數(shù)預(yù)留位置。3.空函數(shù)在老版本C語(yǔ)言中,對(duì)形參類型的聲明是放在函數(shù)定義的第2行,即不在第1行括號(hào)內(nèi)指定形參的類型,而在括號(hào)外單獨(dú)指定。其一般形式:類型說(shuō)明符函數(shù)名(形參1,形參2,…)
形式參數(shù)類型說(shuō)明{
說(shuō)明局部語(yǔ)句
執(zhí)行局部語(yǔ)句
}4.對(duì)形參聲明的傳統(tǒng)方式【例8-4】中max2函數(shù)定義可以寫成:intmax2(x,y)/*函數(shù)有兩個(gè)形參x、y*/intx,y;/*說(shuō)明形參x、y的類型*/{intz;z=x>y?x:y;return(z);}
通常把這種方法稱為傳統(tǒng)的對(duì)形參的聲明方式,而把【例8-4】中定義函數(shù)的方法稱為現(xiàn)代的方式,這兩種用法是等價(jià)的,ANSI新標(biāo)準(zhǔn)推薦使用現(xiàn)代的方式,因?yàn)樗阌诰幾g系統(tǒng)檢查形參的類型?,F(xiàn)代方式與PASCAL語(yǔ)言中所用的方法類似。說(shuō)明8.2函數(shù)調(diào)用和返回值
1.函數(shù)調(diào)用的一般形式及調(diào)用流程(1)函數(shù)調(diào)用的一般形式為:函數(shù)名(實(shí)際參數(shù)表)【說(shuō)明】a、實(shí)際參數(shù)表中有多個(gè)實(shí)參用逗號(hào)分隔;b、實(shí)參與形參的個(gè)數(shù)應(yīng)相同,類型應(yīng)一一對(duì)應(yīng);c、如果調(diào)用無(wú)參函數(shù),那么實(shí)參表為空,但函數(shù)名后的一對(duì)園括號(hào)“()〞不能省略。(2)函數(shù)調(diào)用的流程為:a、為被調(diào)函數(shù)的局部變量(包括定義的變量和形參)開(kāi)辟存儲(chǔ)單元。b、將實(shí)際參數(shù)的值復(fù)制給形式參數(shù)。c、流程從主調(diào)函數(shù)的調(diào)用處轉(zhuǎn)移到被調(diào)函數(shù),執(zhí)行被調(diào)函數(shù)體中的語(yǔ)句序列。d、當(dāng)執(zhí)行到被調(diào)函數(shù)的“return(表達(dá)式);〞語(yǔ)句時(shí),將表達(dá)式的值返回到主調(diào)函數(shù)的調(diào)用處,即以該表達(dá)式的值作為函數(shù)值替換“函數(shù)名(實(shí)際參數(shù)表)〞,結(jié)束被調(diào)函數(shù)的執(zhí)行;如無(wú)return語(yǔ)句,那么遇函數(shù)體的右花括號(hào)“}〞也結(jié)束被調(diào)函數(shù)的執(zhí)行。e、釋放局部變量的存儲(chǔ)單元,流程從被調(diào)函數(shù)轉(zhuǎn)移到主調(diào)函數(shù)的調(diào)用處。f、繼續(xù)從主調(diào)函數(shù)的調(diào)用處向下執(zhí)行。函數(shù)調(diào)用流程如下圖:main(){inta;…fun1(a);…}fun1(int
x){……}調(diào)用返回按函數(shù)調(diào)用出現(xiàn)的位置不同,可分為三種形式:(1)形成單獨(dú)的函數(shù)調(diào)用語(yǔ)句,形式為:函數(shù)名(實(shí)參表達(dá)式1,實(shí)參表達(dá)式2,…);這是無(wú)返回值函數(shù)被調(diào)用的情況,如:printstars(m);(2)出現(xiàn)在表達(dá)式中
這是有返回值函數(shù)被調(diào)用的情況,以函數(shù)的返回值參與表達(dá)式的運(yùn)算。例如:m=5+max2(a,b);(3)函數(shù)調(diào)用作為另一個(gè)函數(shù)調(diào)用的實(shí)際參數(shù)
這種情況是把該函數(shù)的返回值作為實(shí)參進(jìn)行傳遞,因此要求該函數(shù)必須帶值返回。如:printf(“max=%d\n〞,max2(a,b));中的max2(a,b)2.函數(shù)調(diào)用的應(yīng)用形式
函數(shù)調(diào)用實(shí)參一般是表達(dá)式,在有多個(gè)實(shí)參的情況下,C語(yǔ)言中實(shí)參的求值順序是從右到左?!纠?-6】考察函數(shù)調(diào)用時(shí)實(shí)參求值的順序#include<stdio.h>
main()
{intk=1,j;
j=f(k,++k);/*函數(shù)調(diào)用*/printf("%d\n",j);
}intf(inta,intb)
{intc=-1;
if(a>b)c=1;
elseif(a==b)c=0;
return(c);
}3.函數(shù)調(diào)用時(shí)實(shí)參求值的順序?yàn)槭裁催\(yùn)行結(jié)果不是-1呢?這是因?yàn)橄到y(tǒng)(TC和VC相同)對(duì)實(shí)參求值順序是從右到左,即相當(dāng)于f(2,2),所以程序運(yùn)行結(jié)果為0。這種情況在printf函數(shù)中也同樣存在,如:printf("%d,%d\n",k,k++);假設(shè)k的原值為1,那么在TC系統(tǒng)對(duì)實(shí)參求值順序是從右到左,運(yùn)行結(jié)果為2,1;但在VC系統(tǒng)對(duì)實(shí)參求值順序是從左到右,運(yùn)行結(jié)果為1,1。請(qǐng)讀者務(wù)必注意,編程時(shí)應(yīng)防止采用這種容易混淆的用法?!痉治觥?.2.2函數(shù)值的返回
函數(shù)值的返回是通過(guò)被調(diào)函數(shù)中的return語(yǔ)句實(shí)現(xiàn)的。return語(yǔ)句是C語(yǔ)言控制流程轉(zhuǎn)向的語(yǔ)句,它可用在被調(diào)函數(shù)中。return語(yǔ)句的一般形式為:
return(表達(dá)式);或
return表達(dá)式;【功能】計(jì)算表達(dá)式的值,并作為函數(shù)值返回給主調(diào)函數(shù)。在一個(gè)函數(shù)中允許有多個(gè)return語(yǔ)句,例如if語(yǔ)句的每個(gè)分支都有一個(gè)return語(yǔ)句,但每次調(diào)用只執(zhí)行一個(gè)return語(yǔ)句,因此只能返回一個(gè)函數(shù)值。【說(shuō)明】(1)return語(yǔ)句也可以不帶表達(dá)式局部,如:return;它僅實(shí)現(xiàn)程序控制轉(zhuǎn)移而不返回任何值。(2)如果不需要從被調(diào)函數(shù)返回確定的函數(shù)值,被調(diào)函數(shù)可以沒(méi)有return語(yǔ)句,這時(shí)當(dāng)程序執(zhí)行到函數(shù)體的右括號(hào)“}〞時(shí)自動(dòng)返回到主調(diào)函數(shù)中。(3)函數(shù)返回值的類型和函數(shù)定義的類型應(yīng)保持一致。如果兩者不一致,以函數(shù)定義的類型為準(zhǔn),系統(tǒng)將自動(dòng)進(jìn)行類型的轉(zhuǎn)換。(4)如果函數(shù)的返回值是整型,那么在函數(shù)定義時(shí)可省略類型說(shuō)明。(5)為了明確表示“不帶回值〞,可將函數(shù)定義為“空類型〞,類型說(shuō)明符為“void〞。這樣,系統(tǒng)就保證函數(shù)不帶回任何值。8.2.3對(duì)被調(diào)函數(shù)的聲明一個(gè)函數(shù)能被另一個(gè)函數(shù)調(diào)用需要以下幾個(gè)條件:
(1)該函數(shù)必須已經(jīng)存在,無(wú)論是庫(kù)函數(shù)還是用戶自定義函數(shù)(先定義后調(diào)用)。(2)當(dāng)被調(diào)函數(shù)在主調(diào)函數(shù)之后定義時(shí),一般應(yīng)在主調(diào)函數(shù)的開(kāi)始局部對(duì)被調(diào)函數(shù)作聲明。(3)調(diào)用庫(kù)函數(shù)時(shí),不需要對(duì)函數(shù)作聲明,只需在源程序的開(kāi)頭用#include命令將相關(guān)的頭文件包含進(jìn)來(lái)。
對(duì)被調(diào)函數(shù)的聲明對(duì)被調(diào)函數(shù)的聲明有兩種形式:(1)一種為現(xiàn)代形式,其一般形式為:類型說(shuō)明符函數(shù)名(類型形參1,類型形參2,…);即是函數(shù)首部加“;〞形成函數(shù)說(shuō)明語(yǔ)句。也可以只給出形參類型,而不出現(xiàn)形參變量名,如:intmax(int,int);(2)另一種為傳統(tǒng)形式,其一般形式為:類型說(shuō)明符函數(shù)名();【解釋】函數(shù)定義是指對(duì)函數(shù)功能確實(shí)立,包括指定函數(shù)名、函數(shù)值的類型、形參及其類型、函數(shù)體等。它是一個(gè)完整的、獨(dú)立的函數(shù)單位。函數(shù)聲明是指對(duì)已定義函數(shù)的返回值和形參進(jìn)行類型說(shuō)明,它只包括函數(shù)名、函數(shù)類型、形參類型等,不包括函數(shù)體。其作用是告訴編譯系統(tǒng),在本函數(shù)中將要調(diào)用的函數(shù)是何種類型,有何種類型的形參,以便系統(tǒng)作相應(yīng)的檢查和處理。有幾種情況可以省略對(duì)被調(diào)函數(shù)的聲明:
1.如果被調(diào)函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,那么可以省略聲明。2.如果在所有函數(shù)定義之前,在函數(shù)的外部已作了某函數(shù)的聲明,那么在以后的各主調(diào)函數(shù)中,可以不必對(duì)該被調(diào)函數(shù)作聲明。3.如果函數(shù)類型為整型,那么在主調(diào)函數(shù)中可以不要聲明。但使用這種方法時(shí),系統(tǒng)無(wú)法對(duì)參數(shù)的類型做檢查,因此在調(diào)用時(shí)假設(shè)參數(shù)使用不當(dāng),編譯時(shí)也不報(bào)錯(cuò)。為了程序的平安,建議都加以聲明為好。【說(shuō)明】【例8-7】對(duì)被調(diào)函數(shù)的聲明#include<stdio.h>main(){inta,b;floataver(intx,inty);/*對(duì)被調(diào)用函數(shù)的聲明*/floatave;scanf("%d,%d",&a,&b);ave=aver(a,b);/*函數(shù)調(diào)用*/printf("ave=%7.2f\n",ave);}floataver(intx,inty)/*函數(shù)的定義*/{floatz;z=(x+y)/2.0;returnz;}程序運(yùn)行時(shí),假設(shè)輸入50,60↙運(yùn)行結(jié)果如下圖:8.3函數(shù)調(diào)用時(shí)的參數(shù)傳遞
函數(shù)的參數(shù)有形參和實(shí)參兩種。形參出現(xiàn)在函數(shù)定義中的函數(shù)首部,是被調(diào)函數(shù)中的局部變量,只在被調(diào)函數(shù)內(nèi)部起作用,離開(kāi)該函數(shù)那么無(wú)意義。實(shí)參出現(xiàn)在主調(diào)函數(shù)的調(diào)用語(yǔ)句中,其作用是把實(shí)參的值傳遞給被調(diào)函數(shù)的形參,從而實(shí)現(xiàn)主調(diào)函數(shù)向被調(diào)函數(shù)傳遞數(shù)據(jù)的功能。由于是傳遞的數(shù)據(jù),實(shí)參可以是常量、有確定值的變量或表達(dá)式。就參數(shù)傳遞而言,函數(shù)調(diào)用有傳值調(diào)用和傳地址調(diào)用兩種。在函數(shù)調(diào)用的參數(shù)傳遞中應(yīng)注意以下兩點(diǎn):(1)形參和實(shí)參在個(gè)數(shù)、類型及順序上必須保持一致,否那么會(huì)發(fā)生“類型不匹配〞錯(cuò)誤。(2)在函數(shù)調(diào)用時(shí),只能把實(shí)參的值(無(wú)論是數(shù)值還是地址值)傳遞給形參,而不能把形參的值傳遞給實(shí)參。因此,在函數(shù)調(diào)用的過(guò)程中,被調(diào)函數(shù)形參值的改變不會(huì)影響主調(diào)函數(shù)中實(shí)參的值。8.3.1函數(shù)的傳值調(diào)用函數(shù)的傳值調(diào)用是指在函數(shù)調(diào)用時(shí)將實(shí)參的數(shù)值傳遞給形參變量。整個(gè)調(diào)用過(guò)程直至調(diào)用結(jié)束,形參的值都不回傳給實(shí)參。在實(shí)參也是變量的情況下,形參和實(shí)參各自在不同的函數(shù)中占用存儲(chǔ)空間,在被調(diào)函數(shù)內(nèi)部對(duì)形參的任何操作,其結(jié)果只能影響形參變量的值,而不會(huì)影響到實(shí)參變量的值?!纠?-8】分析下面程序的運(yùn)行結(jié)果intswap(inta,intb)
{intt;
printf("a=%d,b=%d\n",a,b);
t=a;a=b;b=t;
printf("a=%d,b=%d\n",a,b);
}#include<stdio.h>
main()
{intx=3,y=5;
swap(x,y);
printf("x=%d,y=%d\n",x,y);
}程序運(yùn)行結(jié)果如下圖swap函數(shù)的功能是交換兩個(gè)參數(shù)的值。從上面運(yùn)行結(jié)果可以看出,交換了兩個(gè)形參變量a和b的值,而main函數(shù)中實(shí)參x和y的值沒(méi)有交換,這是因?yàn)閷?shí)參向形參的數(shù)據(jù)傳遞是單向的,因而形參值的改變不會(huì)影響實(shí)參的值(如下圖)?!痉治觥繑?shù)組元素作實(shí)參的情況:數(shù)組元素的實(shí)質(zhì)與普通變量相同,因此用數(shù)組元素作為函數(shù)的實(shí)參與普通變量作為函數(shù)實(shí)參一樣,都是把值傳遞給形參,即實(shí)現(xiàn)單向的值傳遞?!纠?-9】分析下面程序的運(yùn)行結(jié)果main(){inta[7]={1,2,3,4,5,6,7},i;for(i=0;i<7;i++)printf("%3d",a[i]);printf("\n");for(i=0;i<7;i++)fun(a[i]);/*用數(shù)組元素實(shí)參*/printf("\n");for(i=0;i<7;i++)printf("%3d",a[i]);printf("\n");}fun(inty)/*函數(shù)定義*/{printf("%3d",y*=2);}程序運(yùn)行結(jié)果如下圖。
地址傳遞是將數(shù)據(jù)的存儲(chǔ)地址作為實(shí)參傳遞給形參。按這種方式傳遞時(shí):形參的類型必須是指針變量或數(shù)組(實(shí)質(zhì)也是指針變量);實(shí)參也只能是變量的地址、數(shù)組名(數(shù)組的首地址)或已存放地址值的指針變量。下面分別就指針、一維數(shù)組、二維數(shù)組和字符串指針作函數(shù)參數(shù)的情況進(jìn)行討論。8.3.2函數(shù)的傳地址調(diào)用1.指針作函數(shù)參數(shù)
指針作函數(shù)參數(shù)情況如下:被調(diào)函數(shù)中的形參:指針變量主調(diào)函數(shù)中的實(shí)參:地址表達(dá)式,一般為變量的地址或取得變量地址的指針變量,這里假定為取得變量地址的指針變量。在這種情況下,傳址調(diào)用以后,形參存放地址的改變不會(huì)使得實(shí)參所存地址改變,地址傳遞是單向的。(1)傳址調(diào)用地址傳遞的單向性分析【例8-10】傳址調(diào)用地址傳遞的單向性。voidswap(int*p1,int*p2){int*p;printf("*p1=%d,*p2=%d\n",*p1,*p2);p=p1;p1=p2;p2=p;/*交換指針變量p1、p2的值*/printf("*p1=%d,*p2=%d\n",*p1,*p2);}main(){inti1,i2,*pt1=&i1,*pt2=&i2;printf("輸入兩個(gè)數(shù):\n");scanf("%d%d",&i1,&i2);if(i1<i2)swap(pt1,pt2);/*試圖通過(guò)swap函數(shù)交換指針變量pt1與pt2的指向*/printf("*pt1=%d,*pt2=%d\n",*pt1,*pt2);}程序運(yùn)行結(jié)果如下圖?!痉治觥勘纠齭wap函數(shù)的作用是交換形參指針變量p1和p2的值。先讓主調(diào)函數(shù)指針變量pt1和pt2分別指向整型變量i1和i2,然后當(dāng)i1<i2時(shí)讓pt1和pt2作實(shí)參調(diào)用swap函數(shù),試圖通過(guò)swap函數(shù)交換pt1和pt2存放的地址值,最后按它們的指向輸出。但是,由于傳址調(diào)用地址傳遞的單向性,pt1和pt2存放的地址值并沒(méi)有改變。傳址調(diào)用的過(guò)程如以下圖所示。(2)指針作函數(shù)參數(shù)的作用由于形參指針變量的指向操作可以引起它所指向的主調(diào)函數(shù)變量值的變化,假設(shè)有多個(gè)指針變量形參,它們分別指向主調(diào)函數(shù)中作為存放運(yùn)算結(jié)果的變量,那么可以將被調(diào)函數(shù)中的多個(gè)計(jì)算結(jié)果數(shù)據(jù)傳回主調(diào)函數(shù)(注意以前被調(diào)函數(shù)只能通過(guò)函數(shù)值傳回一個(gè)運(yùn)算結(jié)果)?!纠?-11】分析以下程序的運(yùn)行結(jié)果。intast〔intx,inty,int*cp,int*dp〕{*cp=x+y;*dp=x-y;}main(){inta=4,b=3,c,d;ast(a,b,&c,&d);printf("c=%d,d=%d\n",c,d);}程序的運(yùn)行結(jié)果如下圖。2.數(shù)組作為函數(shù)參數(shù)表8-1數(shù)組指針作為函數(shù)參數(shù)的形式實(shí)際參數(shù)
形式參數(shù)
數(shù)組名數(shù)組(實(shí)質(zhì)仍為指針變量)數(shù)組名指針變量指針變量(已存數(shù)組首地址)
數(shù)組(實(shí)質(zhì)仍為指針變量)指針變量(已存數(shù)組首地址)指針變量數(shù)組指針作為函數(shù)參數(shù)的作用:形參指針變量接受主調(diào)函數(shù)數(shù)組的首地址,就可以通過(guò)指針變量的指向操作改變主調(diào)函數(shù)數(shù)組元素的值?!纠?-12】編一函數(shù)sort,其功能是將一維整型數(shù)組按從小到大的順序排序。主函數(shù)輸入10個(gè)整數(shù),調(diào)用sort函數(shù)對(duì)輸入的數(shù)據(jù)進(jìn)行排序,并在主函數(shù)中輸出?!痉治觥恳幰粋€(gè)函數(shù)對(duì)主函數(shù)中的數(shù)組進(jìn)行排序,還要將排序后的數(shù)據(jù)傳遞到主函數(shù)中。因此形參不能用普通變量,而要使用指針變量;實(shí)參用數(shù)組名。形參指針變量得到主函數(shù)中數(shù)組的首地址,通過(guò)指向操作就可以改變數(shù)組所有元素的值,從而實(shí)現(xiàn)對(duì)主函數(shù)中數(shù)組的排序。程序如下:/*EX8-12.C*/#include<stdio.h>main(){voidsort(int*x,intn);/*函數(shù)聲明*/inti,a[10];for(i=0;i<10;i++)scanf("%d",&a[i]);sort(a,10);/*函數(shù)調(diào)用,數(shù)組名作實(shí)參*/for(i=0;i<10;i++)printf(“%3d〞,a[i]);/*輸出結(jié)果*/printf("\n");}voidsort(int*x,intn)/*函數(shù)定義,x是指針變量*/{inti,j,t;for(i=0;i<n-1;i++)/*數(shù)組排序*/for(j=i+1;j<n;j++)if(*(x+i)>*(x+j))/**(x+i)即a[i],*(x+i)也可寫成x[i]*/{t=*(x+i);*(x+i)=*(x+j);*(x+j)=t;}}程序運(yùn)行時(shí)輸入:2□8□3□5□14□22□19□7□10□1↙運(yùn)行結(jié)果如下圖:可見(jiàn)用形參指針的指向操作,實(shí)現(xiàn)了主函數(shù)中數(shù)組的排序。【說(shuō)明】(1)形參也可以用數(shù)組,即sort函數(shù)的首部可寫成:voidsort(intx[],intn)(2)由于形參x數(shù)組和主函數(shù)的a數(shù)組都是局部數(shù)組,只在各自所在的函數(shù)起作用,因此,形參數(shù)組也可以與主函數(shù)中的數(shù)組同名,sort函數(shù)的首部可寫成:voidsort(inta[],intn),增加了可讀性。其實(shí),這兩個(gè)數(shù)組的類型相同、首地址相同,從存儲(chǔ)的角度說(shuō),實(shí)質(zhì)是同一個(gè)數(shù)組,共同擁有一段存儲(chǔ)空間。(3)x數(shù)組的元素個(gè)數(shù)沒(méi)有寫(當(dāng)然可以寫),因?yàn)樾螀?shù)組的實(shí)質(zhì)是指針變量,目的是接受實(shí)參數(shù)組名首地址,與元素個(gè)數(shù)無(wú)關(guān),所以一般不寫元素個(gè)數(shù),而由形參n接受實(shí)參的整數(shù)(此例為10)作為元素個(gè)數(shù)。另外一種傳送元素個(gè)數(shù)的方法是將元素個(gè)數(shù)定義成符號(hào)常量,請(qǐng)看【例8-13】?!纠?-13】輸入N(設(shè)為10)個(gè)整數(shù),將其中的全部奇數(shù)輸出。要求輸入、輸出均調(diào)用函數(shù)進(jìn)行,程序如下:
#defineN10voidinput(inta[]){inti;printf("輸入10個(gè)數(shù):\n");for(i=0;i<N;i++)scanf("%d",a+i);}voidoutputodd(int*a){inti;for(i=0;i<N;i++,a++)if(*a%2)printf("%3d",*a);printf("\n");}main(){intarr[N];input(arr);outputodd(arr);}本例程序有三個(gè)函數(shù),操作的都是同一個(gè)數(shù)組,即main函數(shù)的arr數(shù)組。用戶定義的兩個(gè)函數(shù)分別完成數(shù)組的輸入和尋找奇數(shù)元素輸出的任務(wù),main函數(shù)調(diào)用這兩個(gè)函數(shù)。元素個(gè)數(shù)由符號(hào)常量N定義。運(yùn)行程序,假設(shè)輸入1□2□3□4□5□6□7□7□9□10↙,程序運(yùn)行結(jié)果如下圖?!居懻摗吭跀?shù)組作為函數(shù)參數(shù)的情況下,參數(shù)傳遞的單向性是否被破壞?【例8-14】分析下面程序的運(yùn)行結(jié)果。voidfun(inta[2]){intc;c=a[0];a[0]=a[1];a[1]=c;}/*交換了a[0]與a[1]的值*/main(){intx[2]={5,10};printf("x[0]=%d,x[1]=%d\n",x[0],x[1]);fun(x);/*函數(shù)調(diào)用*/printf("x[0]=%d,x[1]=%d\n",x[0],x[1]);}程序運(yùn)行結(jié)果如下圖?!痉治觥亢瘮?shù)fun的功能是交換數(shù)組中兩個(gè)元素的值。程序運(yùn)行結(jié)果實(shí)現(xiàn)了此功能,實(shí)參x數(shù)組發(fā)生了改變。參數(shù)傳遞的單向性是否被破壞?對(duì)這個(gè)問(wèn)題首先要問(wèn):形參和實(shí)參分別是什么?在函數(shù)調(diào)用以后形參和實(shí)參是否發(fā)生了變化?下面的列表答復(fù)這個(gè)問(wèn)題。實(shí)參形參函數(shù)調(diào)用時(shí)數(shù)組名x(地址常量)數(shù)組a(指針變量)獲得數(shù)組x的首地址函數(shù)調(diào)用后數(shù)組名x(地址常量)數(shù)組a(指針變量)仍然存放數(shù)組x的首地址結(jié)果沒(méi)有改變沒(méi)有改變
那么本例中什么發(fā)生了改變呢?其實(shí)發(fā)生改變的是:以形參和實(shí)參為首地址的兩個(gè)整型存儲(chǔ)單元存放的值,而不是形參和實(shí)參本身。由于形參是指針變量,其存放的值是可以改變的,例如【例8-13】中函數(shù)outputodd的形參a通過(guò)a++運(yùn)算存放的地址值發(fā)生了改變,實(shí)參數(shù)組名arr仍然是常量沒(méi)有改變。因此,在數(shù)組作為函數(shù)參數(shù)的情況下,參數(shù)傳遞仍然是單向的,形參的變化不能引起實(shí)參的改變,改變的是:從函數(shù)調(diào)用時(shí)形參和實(shí)參共同擁有的數(shù)組首地址開(kāi)始的數(shù)組元素值,這正是使用數(shù)組作為函數(shù)參數(shù)的目的。3.二維數(shù)組函數(shù)參數(shù)前面討論數(shù)組作為函數(shù)參數(shù),講的都是一維數(shù)組,這樣的討論可以很自然地推廣到多維數(shù)組的情況。多維數(shù)組作函數(shù)的參數(shù),表8-1仍然適用。函數(shù)形參既可以用數(shù)組定義也可以用指針變量,實(shí)質(zhì)都是指針變量,可以用與數(shù)組維數(shù)一致的高級(jí)指針變量,例如二維數(shù)組用指向一維數(shù)組的指針變量作形參;也可以用一級(jí)指針變量作形參,這就是將二維數(shù)組當(dāng)成一維數(shù)組訪問(wèn)?!纠?-15】利用函數(shù)求5×5二維數(shù)組的最小值以及該最小值的位置,結(jié)果在main函數(shù)中輸出。【分析】必須用數(shù)組作為函數(shù)參數(shù)。二維數(shù)組的最小值可以用函數(shù)值返回,最小值的位置用什么返回呢?可以用指針變量形參。數(shù)組的行數(shù)和列數(shù)可以用數(shù)值形參,也可以用符號(hào)常量傳遞,本例采用后者,程序編寫如下。#defineM5main(){inta[M][M]={{2,-3,1,4,6},{-9,0,2,7,7},{4,1,0,4,6},{3,-4,7,9,0},{6,5,3,-7,4}};intamin,mrow,mcol;intmin(int(*p)[],int*pi,int*pj);/*函數(shù)聲明*/amin=min(a,&mrow,&mcol);/*函數(shù)調(diào)用*/printf("min=a[%d][%d]=%d\n",mrow,mcol,amin);}intmin(int(*p)[M],int*pi,int*pj)/*函數(shù)定義*/{inti,j,mn;mn=p[0][0];for(i=0;i<M;i++)for(j=0;j<M;j++)if(p[i][j]<mn){mn=p[i][j];*pi=i;*pj=j;}return(mn);}程序運(yùn)行結(jié)果如下圖:【討論】二維數(shù)組形參也可用數(shù)組定義形式,本例函數(shù)首部可寫作:intmin(inta[5][5],int*pi,int*pj)或intmin(inta[][5],int*pi,int*pj)兩種定義都是合法的,但列數(shù)不能省略,如:intmin(inta[][],int*pi,int*pj)是不合法的。原因是編譯器無(wú)法計(jì)算元素的下標(biāo)值。同樣,函數(shù)首部寫成:intmin(int**a,int*pi,int*pj)也是錯(cuò)誤的,因?yàn)樗補(bǔ)定義成普通的整型二級(jí)指針變量,而不是指向整型一維數(shù)組的指針變量。二維數(shù)組問(wèn)題也可用一維數(shù)組形參,即將二維數(shù)組當(dāng)成一維數(shù)組訪問(wèn),對(duì)應(yīng)的實(shí)參用一級(jí)指針首地址a[0]。本例的程序可改寫如下:
/*EX8-15-1.C*/#defineM5main(){inta[M][M]={{2,-3,1,4,6},{-9,0,2,7,7},{4,1,0,4,6},{3,-4,7,9,0},{6,5,3,-7,4}};intamin,mrow,mcol;intmin(int*p,int*pi,int*pj);/*函數(shù)聲明*/amin=min(a[0],&mrow,&mcol);/*函數(shù)調(diào)用*/printf("min=a[%d][%d]=%d\n",mrow,mcol,amin);}intmin(int*p,int*pi,int*pj)/*函數(shù)定義*/{inti,j,mn;mn=*p;/*p=a[0],*p=a[0][0]*/for(i=0;i<M;i++)for(j=0;j<M;j++)if(*(p+i*M+j)<mn){mn=*(p+i*M+j);*pi=i;*pj=j;}return(mn);}程序運(yùn)行的結(jié)果相同。4.字符串指針作函數(shù)參數(shù)表8-2字符串指針作為函數(shù)參數(shù)的形式
實(shí)際參數(shù)形式參數(shù)字符數(shù)組名字符數(shù)組字符數(shù)組名指針變量指針變量字符數(shù)組指針變量指針變量字符串常量字符數(shù)組字符串常量指針變量【例8-16】編寫函數(shù)cpystr,用指針?lè)椒▽⒆址?復(fù)制到字符串1。主函數(shù)調(diào)用cpystr實(shí)現(xiàn)復(fù)制。#include<stdio.h>voidcpystr(char*s1,char*s2){while((*s1++=*s2++)!='\0');}main(){charstr1[20],str2[20];printf("輸入字符串2:\n");gets(str2);cpystr(str1,str2);printf("字符串1是:%s\n",str1);}程序運(yùn)行結(jié)果如下圖【注意】如果要求將一個(gè)確定的字符串〔例如"CLanguage"〕復(fù)制到字符數(shù)組1中,上面的主函數(shù)可直接調(diào)用cpystr函數(shù),實(shí)參就用該字符串:main(){charstr1[20];cpystr(str1,"CLanguage");puts(str1);}8.4.1函數(shù)的嵌套調(diào)用C語(yǔ)言中函數(shù)的定義都是相互平行、相互獨(dú)立的,也就是說(shuō)在函數(shù)定義時(shí),函數(shù)體內(nèi)不能包含另一個(gè)函數(shù)的定義,即函數(shù)不能嵌套定義,但可以嵌套調(diào)用。【例8-17】定義一個(gè)求階乘的函數(shù)mul實(shí)現(xiàn)1*2*…*n,定義一個(gè)求和函數(shù)sum實(shí)現(xiàn)a1+a2+…+am。調(diào)用這兩個(gè)函數(shù),計(jì)算s=1!+2!+3!+…+10!。程序如下:8.4函數(shù)的嵌套與遞歸調(diào)用
main(){doubles,sum();/*此處sum();為sum函數(shù)聲明*/s=sum(10);/*調(diào)用sum函數(shù)*/printf("s=%.0f\n",s);}doublesum(intm)/*time函數(shù)定義*/{doubles=0,mul();/*此處mul()為mul函數(shù)聲明*/inti;for(i=1;i<=m;i++)s=s+mul(i);/*mul函數(shù)調(diào)用*/returns;}doublemul(intn)/*mul函數(shù)定義*/{doublet=1,j;for(j=1;j<=n;j++)t=t*j;returnt;}該程序中,主函數(shù)調(diào)用了sum函數(shù),而在sum函數(shù)中又調(diào)用了mul函數(shù)。在一個(gè)函數(shù)被調(diào)用的過(guò)程中又調(diào)用另一個(gè)函數(shù),這就是函數(shù)的嵌套調(diào)用。本例函數(shù)嵌套調(diào)用的執(zhí)行過(guò)程如下圖。8.4.2函數(shù)的遞歸調(diào)用
在函數(shù)的調(diào)用過(guò)程中直接或間接地調(diào)用自己,這就是函數(shù)的遞歸調(diào)用。
直接遞歸:函數(shù)不斷直接調(diào)用自己;
間接遞歸:函數(shù)循環(huán)間接調(diào)用自己。由于主函數(shù)不被別的函數(shù)調(diào)用,自己調(diào)用自己的函數(shù)一定是用戶自定義函數(shù)。因此,用遞歸算法設(shè)計(jì)的程序至少有兩個(gè)函數(shù),那就是主函數(shù)加一個(gè)遞歸函數(shù)。在遞歸調(diào)用中,主調(diào)函數(shù)又是被調(diào)函數(shù),整個(gè)遞歸過(guò)程就是遞歸函數(shù)不斷自我調(diào)用的過(guò)程。但是,遞歸過(guò)程不能無(wú)限制進(jìn)行下去,必須有一個(gè)結(jié)束遞歸過(guò)程的條件。總結(jié)以上,要編寫遞歸函數(shù)必須有以下兩個(gè)條件:(1)必須有遞歸調(diào)用的形式,即形式上要能自己調(diào)用自己;(2)必須有終止遞歸調(diào)用的條件。利用函數(shù)的遞歸調(diào)用解決問(wèn)題的優(yōu)點(diǎn):(1)遞歸調(diào)用的算法自然、容易理解;(2)采用遞歸算法的程序簡(jiǎn)單;(3)可以解決用其他方法無(wú)法解決的問(wèn)題(如漢洛塔問(wèn)題)?!纠?-18】用遞歸算法求n!=1×2×3×…×n。【分析】
n!=1×2×3×…×n=[1×2×3×…×(n-1)]×n=n×(n-1)!,
也就是說(shuō),要求n!可先求(n-1)!。同樣,要求(n-1)!先求(n-2)!,...,要求2!先求1!。而1!=1,0!=1??偨Y(jié)起來(lái)可以寫出如下計(jì)算公式:第一行是遞歸的終止條件,第二行是遞歸調(diào)用的形式,據(jù)此可編寫程序如下:longfact(intn)/*定義遞歸函數(shù)*/{if(n==0||n==1)return1;/*遞歸終止條件*/elsereturn(n*fact(n-1));/*實(shí)現(xiàn)遞歸調(diào)用*/}main(){intm;longf;do{printf("輸入m(m>0):");scanf("%d",&m);}while(m<=0);/*保證輸入m>0*/f=fact(m);/*調(diào)用遞歸函數(shù)*/printf("%d!=%ld\n",m,f);}程序運(yùn)行結(jié)果如下圖。該程序中,主函數(shù)調(diào)用了fact函數(shù),而在fact函數(shù)中又調(diào)用了自身fact函數(shù)。程序執(zhí)行流程如下圖:從圖中可以看出,fact函數(shù)每自我調(diào)用一次就進(jìn)入新的一層,遞歸函數(shù)和變量都在內(nèi)存新的空間開(kāi)辟?!纠?-19】用遞歸算法求兩個(gè)自然數(shù)的最大公約數(shù)和最小公倍數(shù)?!痉治觥坷幂氜D(zhuǎn)相除法求自然數(shù)的最大公約數(shù)是迭代算法,顯然可以用遞歸算法求解。其遞歸結(jié)束的條件是:被除數(shù)除以除數(shù)的余數(shù)為0。最小公倍數(shù)等于兩個(gè)自然數(shù)的乘積除以最大公約數(shù),程序編寫如下。main(){intgcd(inta,intb);intx,y,g,lcd;printf(“請(qǐng)輸入兩個(gè)數(shù):〞);scanf(“%d%d〞,&x,&y);g=gcd(x,y);/*調(diào)用遞歸函數(shù)*/lcd=x*y/g;printf(“gcd=%d,lcd=%d\n〞,g,lcd);}intgcd(inta,intb)/*定義遞歸函數(shù)*/{if(a%b==0)return(b);/*遞歸終止條件*/elsereturn(gcd(b,a%b));/*實(shí)現(xiàn)遞歸調(diào)用*/}程序運(yùn)行結(jié)果如下圖?!纠?-20】根據(jù)下式用遞歸算法求π的近似值〔設(shè)n=5000〕?!痉治觥吭O(shè)級(jí)數(shù)和為s(n),根據(jù)上式有:這就包含了遞歸結(jié)束條件和遞歸調(diào)用的形式,程序編寫如下:main(){intm;doubles(intn);printf("請(qǐng)輸入n:");scanf("%d",&m);printf("PI=%lf\n",4.0*s(m));/*調(diào)用遞歸函數(shù)*/}doubles(intn)/*遞歸函數(shù)定義*/{if(n==1)return(2.0/3);elsereturn(1.0/(4*n-3)-1.0/(4*n-1)+s(n-1));}程序運(yùn)行結(jié)果如下圖。8.5函數(shù)與指針
函數(shù)與指針的關(guān)系有以下三個(gè)方面的問(wèn)題:(1)指針作為函數(shù)參數(shù)(傳址調(diào)用,已在節(jié)介紹)(2)指向函數(shù)的指針〔本節(jié)介紹〕(3)返回指針的函數(shù)〔本節(jié)介紹〕8.5.1指向函數(shù)的指針函數(shù)作為程序?qū)嶓w,在程序執(zhí)行以前,其代碼也要進(jìn)入內(nèi)存,占據(jù)內(nèi)存的一段連續(xù)存儲(chǔ)區(qū)域,因此也有內(nèi)存地址。函數(shù)在內(nèi)存一段連續(xù)的存儲(chǔ)區(qū)域的首字節(jié)編號(hào)叫函數(shù)的入口地址,又叫函數(shù)指針。在C語(yǔ)言中,函數(shù)指針用函數(shù)名表示,它是一個(gè)指針常量。C語(yǔ)言可以通過(guò)定義指向函數(shù)的指針變量接受函數(shù)指針,然后通過(guò)指向函數(shù)的指針變量訪問(wèn)該函數(shù)〔間接訪問(wèn)〕。1.用指向函數(shù)的指針變量調(diào)用函數(shù)指向函數(shù)的指針變量的定義形式為:函數(shù)返回值的類型(*指針變量名)();【注意】上面的定義中第一個(gè)園括號(hào)不能少,否那么就會(huì)變成節(jié)將要介紹的返回指針函數(shù)的定義。指向函數(shù)的指針變量在接受某一函數(shù)的入口地址以后,即可用來(lái)調(diào)用該函數(shù)〔無(wú)其他運(yùn)算!〕。用指向函數(shù)的指針變量調(diào)用函數(shù)的方法是:(1)定義指向函數(shù)的指針變量;(2)給指針變量賦函數(shù)入口地址〔函數(shù)名〕;(3)用指向函數(shù)的指針變量調(diào)用該函數(shù),形式為:(*指針變量)〔實(shí)參列表〕【例8-21】用指向函數(shù)的指針變量調(diào)用求兩個(gè)數(shù)中最大值的函數(shù)。程序如下:intmaxnum(inta,intb){return((a>b)?a:b);}main(){intx,y,max;int(*funp)();/*定義指向函數(shù)的指針變量,函數(shù)返回整型值*/funp=maxnum;/*指向函數(shù)的指針變量得到函數(shù)的入口地址*/printf("輸入兩個(gè)數(shù):\n");scanf("%d%d",&x,&y);max=(*funp)(x,y);/*用指向函數(shù)的指針變量調(diào)用函數(shù)*/printf("最大數(shù)是%d.\n",max);}程序運(yùn)行結(jié)果如下圖。指向函數(shù)的指針變量的主要用途:(1)有選擇地執(zhí)行函數(shù)。例如,利用switch語(yǔ)句結(jié)構(gòu),讓指向函數(shù)的指針變量根據(jù)輸入的開(kāi)關(guān)表達(dá)式的值〔如1、2…5之一〕,得到不同函數(shù)(如f1、f2…f5之一)的入口地址,去調(diào)用相應(yīng)的函數(shù),實(shí)現(xiàn)人機(jī)對(duì)話,這就是菜單功能。讀者可按此思路編寫菜單程序,此處從略。(2)屢次調(diào)用同類型的一些函數(shù)做相同的工作。例如求假設(shè)干個(gè)一元函數(shù)的定積分,那就需要用指向函數(shù)的指針變量作函數(shù)參數(shù),請(qǐng)看后面的例子。2.指向函數(shù)的指針變量作函數(shù)參數(shù)
以用梯形法求定積分為例,對(duì)不同的被積函數(shù)來(lái)說(shuō),求定積分的算法都是一樣的。如果設(shè)計(jì)一個(gè)函數(shù)可以求任意函數(shù)的定積分,這就是一個(gè)工作函數(shù),實(shí)現(xiàn)了代碼的重復(fù)使用,提高了編程效率。調(diào)用工作函數(shù)計(jì)算不同的被積函數(shù)的定積分,就要在工作函數(shù)中設(shè)置一個(gè)指向函數(shù)的指針變量形參,調(diào)用工作函數(shù)時(shí)對(duì)應(yīng)的實(shí)參為要積分的被積函數(shù)名,再加上相應(yīng)的積分上下限參數(shù)即可。在對(duì)多個(gè)被積函數(shù)積分時(shí),工作函數(shù)的首部形式為:
floatintegral(double(*funp)(),floata,floatb)其中funp為指向函數(shù)的指針變量形參,形參a和b為積分的下限和上限。用梯形法計(jì)算定積分的算法如圖8-26所示。其中梯形高h(yuǎn)=(b-a)/n,n為等份數(shù),n越大積分越準(zhǔn)確。積分近似值——曲邊梯形面積和為:
s={[f(a)+f(a+h)]+[f(a+h)+f(a+2h)]+…+[f(a+(n-1)h)+f(a+nh)]}*h/2={[f(a)+f(b)]/2+f(a+h)+f(a+2h)+…+f(a+(n-1)h)}*h【例8-22】利用梯形法計(jì)算定積分sinxdx,cosxdx,#include"math.h"floatintegral(double(*funp)(),floata,floatb){floats,h,y;/*定義工作函數(shù)*/intn,i;s=((*funp)(a)+(*funp)(b))/2.0;/*[f(a)+f(b)]/2作為求和的初值*/n=100;h=(b-a)/n;for(i=1;i<n;i++)s=s+(*funp)(a+i*h);y=s*h;return(y);}doublef(doublex)/*自定義被積函數(shù)*/{return(sqrt(4.0-x*x));}main(){floats1,s2,s3;s1=integral(sin,0.0,3.1415926/2);/*sin為系統(tǒng)庫(kù)函數(shù)sin(x)的入口地址*/s2=integral(cos,0.0,3.1415926/2);s3=integral(f,0.0,2.0);printf("s1=%f,s2=%f,s3=%f\n",s1,s2,s3);}8.5.2返回指針的函數(shù)有時(shí)希望通過(guò)函數(shù)返回一個(gè)地址值,這時(shí)可定義一個(gè)返回指針的函數(shù),其形式為:類型*函數(shù)名(類型形參1,類型形參2,…){/*以下為函數(shù)體*/……}函數(shù)名前面的“*〞表示該函數(shù)是返回指針的函數(shù),“類型〞是函數(shù)返回地址值的基類型,即返回指針?biāo)赶虻臄?shù)據(jù)類型。注意此處的返回指針的函數(shù)與節(jié)定義的指向函數(shù)的指針變量不同:指向函數(shù)的指針變量的定義形式為:類型(*p)();在沒(méi)有形參的情況下,返回指針的函數(shù)定義為:類型*p(){函數(shù)體}區(qū)別:(1)形式不同;(2)實(shí)質(zhì)不同,前者“p〞是指針變量名,后者“p〞是函數(shù)名;(3)后者除了函數(shù)首部外還有函數(shù)體?!咀⒁狻吭谡{(diào)用返回指針的函數(shù)時(shí)必須將返回值給指針變量賦值,該指針變量的基類型必須與該函數(shù)返回地址值的基類型相同?!纠?-23】輸入一個(gè)1~7之間的整數(shù),輸出對(duì)應(yīng)的星期名。函數(shù)確定整數(shù)與星期名的對(duì)應(yīng)關(guān)系,主函數(shù)輸入和輸出。【分析】由函數(shù)確定整數(shù)與星期名的對(duì)應(yīng)關(guān)系,應(yīng)返回星期名單詞。由于單詞是字符串,由首地址確定,因此函數(shù)返回地址值。程序編寫如下:#include<stdio.h>char*day_name(intn){char*name[]={"Illegalday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};return((n<1||n>7)?name[0]:name[n]);/*將指針數(shù)組元素存放的地址值返回*/}main(){inti;printf("InputDayNo.:\n");scanf("%d",&i);if(i<0)exit(1);printf("DayNo.%d->%s\n",i,day_name(i));/*day_name的返回值決定輸出字符串*/}運(yùn)行結(jié)果如下圖:8.5.3帶參數(shù)的主函數(shù)main函數(shù)不被其他函數(shù)調(diào)用,不需要從其他函數(shù)接受數(shù)據(jù),因此main函數(shù)不需要形式參數(shù)。C程序編譯連接形成可執(zhí)行程序(.EXE文件)后,要在DOS提示符的狀態(tài)(即命令行)下運(yùn)行,此時(shí)可以接受命令行傳來(lái)的數(shù)據(jù)。因此,C語(yǔ)言規(guī)定main函數(shù)也可以有形式參數(shù),而實(shí)參就是命令行的字符串。包含形式參數(shù)的main函數(shù)的一般形式為:main〔intargc,char*argv[]〕{/*以下為函數(shù)體*/……}【說(shuō)明】(1)字符型指針數(shù)組argv的元素指向命令行輸入的假設(shè)干字符串,這些字符串以空格隔開(kāi),形如:C:\>可執(zhí)行文件名參數(shù)1參數(shù)2……參數(shù)n↙可執(zhí)行文件名字符串由argv[0]指向,后面假設(shè)干字符串(稱為命令行參數(shù)),分別由argv[1]、argv[2]…指向。通過(guò)這些指針,main函數(shù)可以引用這些字符串。(2)整型變量argc記載命令行字符串的個(gè)數(shù),也就是指針數(shù)組argv的元素個(gè)數(shù)。(3)注意:與一般指針數(shù)組名不同,由于指針數(shù)組argv[]是形參,其名是二級(jí)指針變量而不是常量,可以有argv++、argv--等運(yùn)算。(4)參數(shù)名可以不用“argc〞和“argv〞,但是它們的類型和作用不變,位置也不能顛倒?!纠?-24】編程顯示命令行輸入的,除可執(zhí)行文件名外的全部字符串,每行一個(gè)字符串。程序如下:/*EX8-24.C*/#include<stdio.h>main(intargc,char*argv[]){while(argc-->1)printf("%s\n",*++argv);}設(shè)程序在VC++6.0下編譯連接后形成可執(zhí)行文件EX8-24.EXE(TurboC下編譯連接后形成可執(zhí)行文件名為EX8_24.EXE),然后在命令行(EX8-24.EXE的當(dāng)前目錄下)輸入:EX8-24CLanguageProgram↙,程序運(yùn)行結(jié)果如下圖。【分析】命令行共輸入四個(gè)字符串,因此argc=4,第一次執(zhí)行while循環(huán)體時(shí)argc=3,argv=&argv[0],++argv使得argv=&argv[1],*++argv即argv[1],它指向第二個(gè)字符串,故輸出“C〞。以后每次循環(huán)argc減少1,argv向高端移動(dòng)1。由argc>1的條件共循環(huán)3次,輸出3個(gè)字符串。注意可執(zhí)行文件名不能用DOS的內(nèi)部命令名,否那么DOS執(zhí)行的是內(nèi)部命令,而不是可執(zhí)行文件。例如不能取echo.exe,因?yàn)槿绻钚休斎耄篹choCLanguageProgram↙,屏幕將顯示一行:CLanguageProgram而不是每個(gè)字符串一行,原因是上面的命令行執(zhí)行的是DOS的內(nèi)部命令echo,它的作用就是在下一行顯示命令行輸入的echo之后的全部字符。8.6變量的作用域和存儲(chǔ)屬性
8.6.1變量的作用域
變量的作用域是指變量的有效范圍,在該范圍里,變量是可用的。例如函數(shù)的形參變量只能在該函數(shù)體內(nèi)有效,離開(kāi)該函數(shù)就不能再用了。
C語(yǔ)言中,變量的說(shuō)明方式不同,其作用域也不同,從作用范圍分為局部變量和全局變量?jī)深悺?/p>
在函數(shù)內(nèi)部定義的變量、形參和復(fù)合語(yǔ)句內(nèi)定義的變量稱為局部變量,其作用域僅限于函數(shù)內(nèi)或復(fù)合語(yǔ)句內(nèi),離開(kāi)該函數(shù)或該復(fù)合語(yǔ)句再使用這些變量是非法的。因此在不同的函數(shù)內(nèi)及復(fù)合語(yǔ)句內(nèi)可以定義同名的局部變量,這些變量之間不會(huì)發(fā)生沖突。編譯系統(tǒng)開(kāi)始并不給局部變量分配內(nèi)存,只在程序運(yùn)行過(guò)程中,當(dāng)局部變量所在的函數(shù)被調(diào)用時(shí),才臨時(shí)分配內(nèi)存,調(diào)用結(jié)束立即釋放。1.局部變量【例8-25】局部變量的作用范圍。main(){voidfun();/*函數(shù)聲明*/intx=5;printf("main_1:x=%d\n",x);fun();/*函數(shù)調(diào)用*/printf("main_2:x=%d\n",x);}voidfun()/*函數(shù)定義*/{intx;x=10;printf("fun:x=%d\n",x);}程序運(yùn)行結(jié)果如下圖【分析】函數(shù)fun內(nèi)定義的變量x只在fun里有效,主函數(shù)內(nèi)定義的變量x同樣只在主函數(shù)里有效,他們之間并不相互干擾。因此在調(diào)用fun函數(shù)前主函數(shù)內(nèi)輸出的x值是5,而調(diào)用fun函數(shù)并進(jìn)入fun函數(shù)時(shí),fun函數(shù)里的x起作用,所以在fun函數(shù)體里輸出的x值是10,而調(diào)用結(jié)束返回主函數(shù)時(shí),fun函數(shù)里的變量x無(wú)效,主函數(shù)里的x起作用,因此輸出的x值是5?!纠?-26】復(fù)合語(yǔ)句中的局部變量。/*EX8-26.C*/main(){intt=10;{/*復(fù)合語(yǔ)句開(kāi)始*/intt=20;printf("in:%d\n",t);}/*復(fù)合語(yǔ)句結(jié)束*/printf("out:%d\n",t);}程序運(yùn)行結(jié)果如下圖在所有函數(shù)(包括main函數(shù))之外定義的變量稱為全局變量,又叫外部變量,它不屬于任何函數(shù),而屬于所在的源程序文件,其作用域是從定義的位置開(kāi)始到根源程序文件結(jié)束,并且默認(rèn)初值為0。如果要在定義之前使用該全局變量,要用extern加以說(shuō)明,那么可擴(kuò)展全局變量的作用域(視說(shuō)明語(yǔ)句的位置而定)。2.全局變量【注意】外部變量的定義和說(shuō)明(聲明)不同:(1)外部變量的定義必須在所有函數(shù)之外,且一個(gè)程序只能定義一次。其一般形式為:
類型變量名1[=初值],…,變量名n[=初值];外部變量的說(shuō)明出現(xiàn)在要使用該外部變量的地方(外部變量的作用域達(dá)不到的地方,可以是函數(shù)內(nèi)部,對(duì)一個(gè)外部變量可多處說(shuō)明)。
外部變量說(shuō)明的一般形式為:
extern類型變量名1,…,變量名n;(2)外部變量在編譯時(shí)就分配內(nèi)存空間,在定義的同時(shí)可以賦初值,不賦初值系統(tǒng)自動(dòng)賦給0值;而外部變量的說(shuō)明只是說(shuō)明在該外部變量作用域達(dá)不到的地方要使用外部變量,不能在說(shuō)明語(yǔ)句中賦初值?!菊f(shuō)明】在一個(gè)源程序中,全局變量和局部變量可以同名,在局部變量有效的范圍內(nèi),全局變量不起作用(被屏蔽)?!纠?-27】寫出下面程序運(yùn)行結(jié)果inta=5;/*外部變量定義*/main(){voidfunn();/*函數(shù)聲明*/inta=10;/*局部變量定義*/printf("1:a=%d\n",a);{/*復(fù)合語(yǔ)句開(kāi)始*/externinta;/*外部變量的聲明*/printf("2:a=%d\n",a);/*此時(shí)局部變量a無(wú)效,引用外部變量a*/}/*復(fù)合語(yǔ)句結(jié)束*/funn();/*函數(shù)調(diào)用*/}voidfunn()/*函數(shù)定義*/{printf("3:a=%d\n",a);/*引用外部變量a*/}【思考】1、如果刪除復(fù)合語(yǔ)句中的外部變量說(shuō)明語(yǔ)句externinta;,那么輸出結(jié)果有什么改變?2、如果將復(fù)合語(yǔ)句中的外部變量說(shuō)明語(yǔ)句externinta;改成inta=20;,那么輸出結(jié)果又會(huì)怎樣改變?8.6.2變量的存儲(chǔ)屬性變量的存儲(chǔ)屬性是由它的存儲(chǔ)方式?jīng)Q定的。變量的存儲(chǔ)方式是指變量使用內(nèi)存空間的方式,通常可分為“動(dòng)態(tài)存儲(chǔ)〞和“靜態(tài)存儲(chǔ)〞兩種。內(nèi)存中供用戶使用的存儲(chǔ)空間分為:程序區(qū)、靜態(tài)存儲(chǔ)區(qū)和動(dòng)態(tài)存儲(chǔ)區(qū)。動(dòng)態(tài)存儲(chǔ)是指在程序執(zhí)行過(guò)程中,使用到變量時(shí)才分配存儲(chǔ)單元,使用完畢立即釋放。函數(shù)所有的局部變量都屬于這種存儲(chǔ)方式。靜態(tài)存儲(chǔ)是指在變量編譯時(shí)就分配存儲(chǔ)單元,程序開(kāi)始直至整個(gè)程序結(jié)束一直保持。例如全局變量就屬于這種存儲(chǔ)方式。生存期表示了變量存在的時(shí)間。靜態(tài)存儲(chǔ)變量是一直存在(與程序共存亡)的,而動(dòng)態(tài)存儲(chǔ)變量那么在函數(shù)被調(diào)用的過(guò)程中存在,調(diào)用結(jié)束返回時(shí)即消失。因此他們的生存期不同。生存期和作用域是從時(shí)間和空間兩個(gè)不同的方面描述變量的特性,兩者既有關(guān)聯(lián),又有區(qū)別。變量的存儲(chǔ)類型決定了變量的生存期和作用域。8.6.2變量的存儲(chǔ)屬性C語(yǔ)言中,變量的存儲(chǔ)類型有4種:(1)自動(dòng)類型auto(2)存放器類型register(3)靜態(tài)類型static(4)外部類型extern不同的存儲(chǔ)類型,存放的位置不同:auto類型存儲(chǔ)在內(nèi)存的堆棧區(qū)中;register類型存儲(chǔ)在CPU的通用存放器中;static、extern類型存儲(chǔ)在內(nèi)存數(shù)據(jù)區(qū)中;extern類型用于多個(gè)源文件之間數(shù)據(jù)的傳遞。8.6.2變量的存儲(chǔ)屬性存儲(chǔ)屬性
動(dòng)態(tài)存儲(chǔ)
靜態(tài)存儲(chǔ)
存儲(chǔ)類型
register(寄存器)auto(自動(dòng))static(靜態(tài))
extern(外部)存儲(chǔ)位置
寄存器主內(nèi)存生存期
動(dòng)態(tài)生存期永久生存期作用域局部局部或全局
全局表8-3變量的存儲(chǔ)類及作用域表考慮存儲(chǔ)類,變量定義的形式為:存儲(chǔ)類型數(shù)據(jù)類型變量名[=初值],變量名[=初值],…;8.6.2.1動(dòng)態(tài)存儲(chǔ)變量函數(shù)(含main函數(shù))以及復(fù)合語(yǔ)句中定義的變量、函數(shù)的形參屬于動(dòng)態(tài)存儲(chǔ)的變量,其特性是:①僅當(dāng)定義動(dòng)態(tài)存儲(chǔ)變量的函數(shù)被調(diào)用時(shí),系統(tǒng)才給他們分配存儲(chǔ)單元;②不賦初值其初值是隨機(jī)的;③調(diào)用結(jié)束,空間釋放,自動(dòng)變量消失;④動(dòng)態(tài)存儲(chǔ)變量為局部變量,只在定義的函數(shù)或復(fù)合語(yǔ)句中起作用。動(dòng)態(tài)存儲(chǔ)變量包括自動(dòng)變量和存放器變量?jī)煞N。1.自動(dòng)類型
自動(dòng)變量存放在內(nèi)存的動(dòng)態(tài)區(qū),其定義形式為:[auto]類型變量名[=初值],變量名[=初值],…;其中的auto可以省略。如定義自動(dòng)變量:autointa=2;也可以寫成:inta=2;以前所用的變量,包括函數(shù)和復(fù)合語(yǔ)句中定義的變量以及函數(shù)的形參都是自動(dòng)變量。2.存放器類型存放器類型變量定義的一般形式為:register數(shù)據(jù)類型變量名[=初值],變量名[=初值],…;存放器類型也屬于動(dòng)態(tài)存儲(chǔ)方式,其生存期和作用域與自動(dòng)類型變量相同,只不過(guò)系統(tǒng)把這類變量直接分配在CPU的通用存放器中,因而無(wú)地址〔不能用取地址運(yùn)算符&作用〕。當(dāng)需要使用這些變量時(shí),無(wú)須訪問(wèn)內(nèi)存,直接從存放器中讀寫,提高了效率。一般存放器變量只能是int、char或指針型,當(dāng)CPU無(wú)法分配存放器時(shí),編譯系統(tǒng)會(huì)自動(dòng)地將存放器變量變?yōu)樽詣?dòng)變量。一般把使用頻繁的變量(如循環(huán)變量)設(shè)置成存放器變量?!纠?-28】存放器變量的使用。/*EX8-28.C*/main(){registerintk,s=0;for(k=1;k<=10;k++)s+=k;printf("s=%d\n",s);}程序運(yùn)行結(jié)果如下圖3.動(dòng)態(tài)存儲(chǔ)變量有如下共同的特性:(1)生存期。僅當(dāng)定義動(dòng)態(tài)存儲(chǔ)變量的函數(shù)被調(diào)用時(shí),系統(tǒng)才給動(dòng)態(tài)存儲(chǔ)變量分配內(nèi)存或存放器單元,調(diào)用結(jié)束,動(dòng)態(tài)變量的存儲(chǔ)單元被釋放,其值消失。因此,動(dòng)態(tài)變量無(wú)繼承性,即在函數(shù)兩次被調(diào)用之間,動(dòng)態(tài)變量的值不保存?!纠?-29】動(dòng)態(tài)變量無(wú)繼承性。/*EX8-29.C*/f(inta){intb=0;b++;return(a+b);}main(){inti,a=2;for(i=0;i<3;i++)printf("%3d",f(a));printf("\n");}運(yùn)行結(jié)果如下圖
(2)初始化屬性:程序運(yùn)行到函數(shù)或復(fù)合語(yǔ)句時(shí)才為動(dòng)態(tài)存儲(chǔ)變量分配存儲(chǔ)單元并初始化(賦初值),如未賦初值,存儲(chǔ)值是隨機(jī)的。初值可為任意的有值表達(dá)式,例如:floatmult(floata,floatb){inti=3,j=4;doublex=a*i,y=2*sqrt(b)/j;……}
(3)作用域。動(dòng)態(tài)存儲(chǔ)變量都是局部變量。由于局部變量可屏蔽同名的全局變量,不同函數(shù)或復(fù)合語(yǔ)句中均可定義同名變量而不會(huì)混淆。4.使用動(dòng)態(tài)變量的優(yōu)點(diǎn):(1)由于只在運(yùn)行到定義動(dòng)態(tài)變量的函數(shù)或復(fù)合語(yǔ)句時(shí)才存在,可節(jié)約存儲(chǔ)空間。(2)由于不同局部可定義同名變量而互不相關(guān),局部變量還可以屏蔽全局變量,程序員只需從局部考慮定義適宜的變量,而不用考慮是否與其他局部或全局變量同名,使用方便且便于閱讀和理解程序。靜態(tài)存儲(chǔ)變量靜態(tài)存儲(chǔ)變量包括靜態(tài)(static)變量和外部變量,有如下共同的特征:(1)它們都存儲(chǔ)在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)。(2)生存期。靜態(tài)存儲(chǔ)變量具有永久生存期,即與程序共存亡。(3)初始化屬性:靜態(tài)存儲(chǔ)變量在編譯時(shí)分配存儲(chǔ)單元,只能用常量表達(dá)式賦初值。假設(shè)未賦初值,編譯時(shí)初始化為0〔實(shí)型0.0、字符型‘\0’〕。1.靜態(tài)(static)變量定義的一般形式為:static數(shù)據(jù)類型變量名[=初值],變量名[=初值],…;如:staticinta=1,b=2,c=3;靜態(tài)變量有靜態(tài)局部變量和靜態(tài)外部變量?jī)煞N。1)靜態(tài)局部變量:函數(shù)或復(fù)合語(yǔ)句內(nèi)部定義的靜態(tài)變量。靜態(tài)局部變量的作用域:在其所定義的函數(shù)或復(fù)合語(yǔ)句內(nèi)部,這一點(diǎn)與自動(dòng)變量相同。與自動(dòng)變量的不同在于:①生存期:靜態(tài)局部變量與程序共存亡,當(dāng)其所在函數(shù)被調(diào)用結(jié)束后,其值保存,下次調(diào)用時(shí)原來(lái)保存的數(shù)據(jù)有效,因此具有繼承性。②初始化屬性:靜態(tài)局部變量在編譯時(shí)初始化,它所在函數(shù)被屢次調(diào)用時(shí),其初始化語(yǔ)句只在第一次運(yùn)行時(shí)起作用。【例8-30】靜態(tài)局部變量的繼承性。/*EX8-30.C*/#include<stdio.h>voidfun(){staticinta=0;/*定義變量a為靜態(tài)局部變量*/a+=2;printf("%2d",a);}main(){intn;for(n=1;n<=3;n++)fun();/*函數(shù)調(diào)用*/printf("\n");}程序運(yùn)行結(jié)果如下圖2)靜態(tài)外部變量(靜態(tài)全局變量)在函數(shù)外部定義的static變量叫靜態(tài)外部變量也叫外部靜態(tài)變量或靜態(tài)全局變量。靜態(tài)外部變量是全局變量,但只在根源
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 四川省綿陽(yáng)市梓潼縣2026屆九年級(jí)上學(xué)期1月期末考試語(yǔ)文試卷答案
- 2026年廣東省地理中考自編模擬題(一)適用于廣東省茂名市(含答案)
- 衛(wèi)生面試真題及答案
- 讀后感的作文300字合集7篇2
- 電能質(zhì)量檢測(cè)技術(shù)要點(diǎn)
- 社會(huì)政策學(xué)試題及答案
- 慶云縣體育考試試題及答案
- 遼寧省葫蘆島市2026屆九年級(jí)上學(xué)期期末考試語(yǔ)文試卷(含答案)
- 廣東省深圳市龍華區(qū)2024-2025學(xué)年八年級(jí)上學(xué)期期末生物地理試卷-初中地理(含答案)
- 2026 年初中英語(yǔ)《情景交際》專題練習(xí)與解析 (100 題)
- 被打和解協(xié)議書(shū)范本
- 《糖尿病合并高血壓患者管理指南(2025版)》解讀
- 養(yǎng)老院敬老院流動(dòng)資產(chǎn)管理制度
- 工程施工計(jì)劃與資源配置
- 監(jiān)理掛靠合同協(xié)議
- 機(jī)械密封安裝及維護(hù)培訓(xùn)
- 噴粉廠噴粉施工方案
- 廣東省湛江市雷州市2024-2025學(xué)年七年級(jí)上學(xué)期期末語(yǔ)文試題(原卷版+解析版)
- 電力設(shè)施的綠色設(shè)計(jì)與可持續(xù)發(fā)展
- MB670-1掘錨機(jī)結(jié)構(gòu)原理及操作方法
- 江西省上饒市2023-2024學(xué)年高二上學(xué)期期末教學(xué)質(zhì)量測(cè)試物理試卷(解析版)
評(píng)論
0/150
提交評(píng)論