版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
函數(shù)的定義和調(diào)用函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的作用域和生存期編譯預(yù)處理多源文件C程序的組織方法第4章函數(shù)與程序結(jié)構(gòu)模塊化程序設(shè)計(jì)技術(shù)就是通過(guò)開(kāi)發(fā)和維護(hù)一些小的程序塊(即模塊)的方法構(gòu)建一個(gè)大型程序,是人類(lèi)解決較大的復(fù)雜問(wèn)題所采用的一種“分而治之”的策略。本章主要討論C語(yǔ)言實(shí)現(xiàn)模塊化程序設(shè)計(jì)技術(shù)的手段以及在模塊化實(shí)現(xiàn)過(guò)程中所遇到的一系列問(wèn)題。第4章函數(shù)與程序結(jié)構(gòu)C程序的一般結(jié)構(gòu)C程序源文件1…源文件i源文件n函數(shù)1預(yù)處理語(yǔ)句函數(shù)m說(shuō)明/定義部分執(zhí)行語(yǔ)句部分圖4.1C程序的一般結(jié)構(gòu)……第4章函數(shù)與程序結(jié)構(gòu)在C語(yǔ)言程序中的若干個(gè)函數(shù)中必須有一個(gè)且只能有一個(gè)函數(shù)成為主函數(shù)。C程序的執(zhí)行從main函數(shù)開(kāi)始,調(diào)用其它函數(shù)后流程回到main函數(shù),在main函數(shù)中結(jié)束整個(gè)程序的運(yùn)行。在一個(gè)函數(shù)中可以使用另一個(gè)函數(shù)的功能,這稱(chēng)為函數(shù)調(diào)用。4.1函數(shù)的定義和調(diào)用
使用函數(shù)首先要對(duì)函數(shù)定義。函數(shù)定義中必須描述出函數(shù)的三個(gè)特征,即函數(shù)的名字、函數(shù)形式的參數(shù)表以及函數(shù)的返回值類(lèi)型。C語(yǔ)言函數(shù)定義的形式如下:
4.1.1函數(shù)的定義和聲明返回值類(lèi)型函數(shù)名(形式參數(shù)列表){函數(shù)體return;}
下面以定義實(shí)現(xiàn)求階乘功能函數(shù)為例了解一個(gè)函數(shù)的具體定義過(guò)程.根據(jù)前面所學(xué)知識(shí)知道,求階乘的C程序如下所示:
#include<stdio.h>voidmain(){ int i,n; longfact=1; printf("Inputn:"); scanf("%d",&n); for(i=1;i<=n;i++) fact*=i;printf("%d!=%ld\n",n,fact);}程序?qū)崿F(xiàn)了計(jì)算從鍵盤(pán)輸入一個(gè)整數(shù)n,并求其階乘的功能。如果在今后的應(yīng)用中,需要將求某數(shù)階乘的功能作為程序中相對(duì)獨(dú)立的一個(gè)部分(功能),則需要將上述功能用自編函數(shù)的方式實(shí)現(xiàn)
4.1.1函數(shù)的定義和聲明(1)函數(shù)的命名函數(shù)的名字在程序設(shè)計(jì)中有兩個(gè)作用:一是使用該名字調(diào)用這個(gè)函數(shù);二是應(yīng)該見(jiàn)名知意,符合c語(yǔ)言的規(guī)則。對(duì)于實(shí)現(xiàn)本功能的函數(shù),命名factorial。
(2)函數(shù)執(zhí)行結(jié)果的返回和返回值類(lèi)型的確定
函數(shù)執(zhí)行的結(jié)果如果是一個(gè)具體的表達(dá)式,當(dāng)函數(shù)執(zhí)行完成時(shí)用關(guān)鍵字return組成形如:return<表達(dá)式>;的C語(yǔ)句將函數(shù)執(zhí)行的結(jié)果返回給調(diào)用函數(shù)者。注意函數(shù)執(zhí)行結(jié)果的數(shù)據(jù)類(lèi)型不是由返回的表達(dá)式數(shù)據(jù)類(lèi)型來(lái)決定的,而是用類(lèi)型名作為關(guān)鍵字在函數(shù)的頭部予以確定?;谏鲜鰞牲c(diǎn),可以寫(xiě)出實(shí)現(xiàn)階乘功能的函數(shù)factorial4.1.1函數(shù)的定義和聲明long為函數(shù)返回值類(lèi)型Return語(yǔ)句將n!返回給調(diào)用函數(shù)花括號(hào)給函數(shù)確定了邊界區(qū)域longfactorial(){ int i,n; longfact=1;
printf("Inputn:"); scanf("%d",&n); for(i=1;i<=n;i++) fact*=i; returnfact;}4.1.1函數(shù)的定義和聲明(3)函數(shù)的參數(shù)表設(shè)計(jì)在上面定義的函數(shù)factorial中,函數(shù)用到的數(shù)據(jù)是從鍵盤(pán)輸入獲取的,如果需要從對(duì)函數(shù)的調(diào)用者(使用者)處獲取所需要的數(shù)據(jù),就必須對(duì)函數(shù)的形式參數(shù)表進(jìn)行設(shè)計(jì)。此時(shí)需要兩個(gè)步驟來(lái)實(shí)現(xiàn):一是將函數(shù)內(nèi)部用于從鍵盤(pán)上接收數(shù)據(jù)的數(shù)據(jù)對(duì)象定義移到函數(shù)的形式參數(shù)表中;二是刪去函數(shù)中從鍵盤(pán)獲取數(shù)據(jù)的語(yǔ)句。函數(shù)factorial可以改造為如下形式:longfactorial(intn){ int i; longfact=1; for(i=1;i<=n;i++) fact*=i; returnfact;}n的值函數(shù)調(diào)用者(使用者)處獲取,不再?gòu)某绦蛑蝎@取。4.1.1函數(shù)的定義和聲明
通過(guò)對(duì)函數(shù)factorial定義過(guò)程的討論,可以理解C函數(shù)定義一般形式中各個(gè)函數(shù)組成成分的確切含義:(1)返回值類(lèi)型說(shuō)明符 用以制定函數(shù)返回值的數(shù)據(jù)類(lèi)型,可以是C語(yǔ)言中任何合法的基本數(shù)據(jù)類(lèi)型和構(gòu)造體數(shù)據(jù)類(lèi)型。如果要表示一個(gè)函數(shù)不需要向調(diào)用者返回值,則函數(shù)的返回值數(shù)據(jù)類(lèi)型應(yīng)該定義為void,如前面章節(jié)的主函數(shù)main。(2)函數(shù)的名字 遵循C語(yǔ)言標(biāo)識(shí)符的命名規(guī)則。盡量做到“見(jiàn)名知意”。(3)形式參數(shù)表 函數(shù)的形式參數(shù)表用圓括號(hào)括起來(lái)的、由零個(gè)到多個(gè)形式參數(shù)的定義組成,兩個(gè)形式參數(shù)定義之間用逗號(hào)分隔。若一個(gè)函數(shù)沒(méi)有形式參數(shù),作為函數(shù)運(yùn)算符使用的圓括號(hào)也不能省略。4.1.1函數(shù)的定義和聲明(4)return<表達(dá)式>;語(yǔ)句如果函數(shù)定義中指定的返回值數(shù)據(jù)類(lèi)型不是void,則函數(shù)定義中必須有用關(guān)鍵字return構(gòu)成的return<表達(dá)式>;語(yǔ)句。當(dāng)函數(shù)執(zhí)行到該C語(yǔ)句時(shí),先計(jì)算該語(yǔ)句中的表達(dá)式的值,然后再將該值強(qiáng)制轉(zhuǎn)化為指定的函數(shù)返回值的數(shù)據(jù)類(lèi)型,返回到主調(diào)函數(shù)中。如果函數(shù)定義時(shí)指定的返回值類(lèi)型是void,則函數(shù)定義中可以沒(méi)有用return構(gòu)成的語(yǔ)句,若函數(shù)定義的執(zhí)行流程需要使用return語(yǔ)句,則其形式只能是:return;。4.1.1函數(shù)的定義和聲明例如:我們定義一個(gè)求兩個(gè)數(shù)中最大值的函數(shù):4.1.1函數(shù)的定義和聲明intmax(intx,inty){inttemp;/*函數(shù)體的局部變量*/
temp=x>y?x:y;/*函數(shù)體的執(zhí)行部分*/
returntemp;/*返回函數(shù)值*/
}
函數(shù)返回類(lèi)型函數(shù)名形式參數(shù)C語(yǔ)言中規(guī)定,函數(shù)不能嵌套定義。這個(gè)規(guī)定保證了每個(gè)函數(shù)都是一個(gè)相對(duì)獨(dú)立的程序模塊。在由多個(gè)函數(shù)組成的C程序中,各個(gè)函數(shù)的定義是并列的并且順序是任意的,函數(shù)在一個(gè)C程序中的定義順序與該C程序運(yùn)行時(shí)函數(shù)的執(zhí)行順序無(wú)關(guān)。函數(shù)定義好后,就可以使用了,稱(chēng)為函數(shù)的調(diào)用。C語(yǔ)言規(guī)定,在調(diào)用函數(shù)之前必須向系統(tǒng)描述所調(diào)用函數(shù)的基本特征,稱(chēng)為函數(shù)的聲明。C語(yǔ)言中的函數(shù)分為標(biāo)準(zhǔn)庫(kù)函數(shù)和用戶(hù)自定義函數(shù)兩大類(lèi)。下面分別介紹他們的聲明方法。
4.1.1函數(shù)的定義和聲明(1)標(biāo)準(zhǔn)庫(kù)函數(shù)的聲明方式#include<頭文件名>當(dāng)使用尖括號(hào)時(shí),指定系統(tǒng)首先查找C編譯系統(tǒng)配置的頭文件路徑(include路徑);#include“頭文件名”當(dāng)使用雙引號(hào)時(shí),指定系統(tǒng)首先查找當(dāng)前目錄。(2)用戶(hù)自定函數(shù)的聲明方式如果被調(diào)用函數(shù)(稱(chēng)為被調(diào)函數(shù))與調(diào)用它的函數(shù)(稱(chēng)為主調(diào)函數(shù))在同一源文件中,需要在函數(shù)調(diào)用之前對(duì)被調(diào)函數(shù)進(jìn)行聲明。形式為:
返回值類(lèi)型函數(shù)名(形式參數(shù)表);4.1.1函數(shù)的定義和聲明/*Name:ex04-01.cpp*/#include<stdio.h>voidmain(){ longfactorial(intn); intnum; printf("Inputthenum:"); scanf("%d",&num); printf("%d!=%ld\n",num,factorial(num));}longfactorial(intn)//函數(shù)factorial的定義,最后沒(méi)有分號(hào){ int i; longfact=1; for(i=1;i<=n;i++) fact*=i; returnfact;}函數(shù)聲明告訴編譯系統(tǒng)factorial是一個(gè)返回值是long,只有一個(gè)int參數(shù)的函數(shù),注意最后分號(hào)不可少!程序演示形式參數(shù)(簡(jiǎn)稱(chēng)形參)實(shí)際參數(shù)(簡(jiǎn)稱(chēng)實(shí)參)在上面程序中,主函數(shù)中的longfactorial(intn);語(yǔ)句就是對(duì)函數(shù)factorial的聲明。C程序中,對(duì)被調(diào)函數(shù)的聲明也可以書(shū)寫(xiě)在主調(diào)函數(shù)定義之前,這種方式下函數(shù)聲明語(yǔ)句之后的所有函數(shù)都能對(duì)被聲明函數(shù)進(jìn)行調(diào)用,如下面的程序段所示:#include<stdio.h>longfactorial(intn);//對(duì)函數(shù)factorial的聲明,該程序中其它函數(shù)均可以調(diào)用它。voidmain(){ … }4.1.1函數(shù)的定義和聲明在函數(shù)的聲明語(yǔ)句中,形參的名字是無(wú)關(guān)緊要的(可以與函數(shù)定義中的不同甚至可以缺?。?,函數(shù)聲明語(yǔ)句的關(guān)鍵是形參的類(lèi)型、個(gè)數(shù)和次序必須與定義對(duì)應(yīng)。例如上面對(duì)函數(shù)factorial的聲明語(yǔ)句還可以寫(xiě)成為如下兩種形式:⑴longfactorial(int);/*對(duì)函數(shù)factorial的聲明中無(wú)形參名,表示默認(rèn)*/⑵longfactorial(intx);/*對(duì)函數(shù)factorial的聲明中形式參數(shù)名與函數(shù)定義不同,但意義一樣*/4.1.1函數(shù)的定義和聲明C語(yǔ)言規(guī)定在下列情況下可以不對(duì)被調(diào)函數(shù)進(jìn)行聲明:1.被調(diào)函數(shù)的返回值數(shù)據(jù)類(lèi)型是整型或字符型在這種情況下,系統(tǒng)自動(dòng)按整型進(jìn)行隱式聲明。但從現(xiàn)代程序設(shè)計(jì)技術(shù)的觀點(diǎn)出發(fā),對(duì)任何類(lèi)型的函數(shù)在調(diào)用之前都必須聲明,所以許多較現(xiàn)代的C編譯系統(tǒng)在這種情況下仍然強(qiáng)制要求對(duì)被調(diào)函數(shù)進(jìn)行聲明。2.被調(diào)函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前在這種情況下,系統(tǒng)在執(zhí)行程序中的函數(shù)調(diào)用語(yǔ)句之前已知道了被調(diào)函數(shù)的所有特征。
4.1.1函數(shù)的定義和聲明/*Name:ex04-02.cpp*/#include<stdio.h>longfactorial(intn)//函數(shù)factorial的定義出現(xiàn)在主調(diào)函數(shù)main的前面{ int i; longfact=1; for(i=1;i<=n;i++) fact*=i; returnfact;}voidmain() //主函數(shù)中沒(méi)有對(duì)函數(shù)factorial進(jìn)行聲明的語(yǔ)句{ intnum;//longfactorial(intn); printf("Inputthenum:"); scanf("%d",&num); printf("%d!=%ld\n",num,factorial(num));}程序演示4.1.1函數(shù)的定義和聲明什么是函數(shù)的調(diào)用?先看下列程序/*計(jì)算S=2!-3!+4!*/
#include<stdio.h>voidmain(){floatqsn(int
x);//函數(shù)的聲明
floats;s=qsn(2)-qsn(3)+qsn(4);/*直接調(diào)用qsn函數(shù)進(jìn)行計(jì)算*/printf(“S=%f\n”,s);}
floatqsn(intn)/*定義函數(shù)qsn為階乘*/{intk;floatqsn;qsn=1;for(k=1;k<=n;k++)qsn*=k;return(qsn);}4.1.2值參數(shù)傳遞的函數(shù)調(diào)用函數(shù)調(diào)用的一般形式為:
函數(shù)名(實(shí)際參數(shù)列表)C程序中對(duì)函數(shù)的調(diào)用方式有三種:
⑴函數(shù)語(yǔ)句方式 把函數(shù)調(diào)用作為一個(gè)語(yǔ)句來(lái)使用。例如:for(k=0;k<5);k++)printline();//函數(shù)調(diào)用部分,無(wú)參函數(shù)
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用
⑵函數(shù)表達(dá)式方式 在函數(shù)調(diào)用的這種方式下,函數(shù)調(diào)用出現(xiàn)在一個(gè)表達(dá)式中,這個(gè)表達(dá)式亦稱(chēng)為函數(shù)表達(dá)式。此時(shí)要求函數(shù)被調(diào)用后必須要返回一個(gè)確定的值以參加表達(dá)式運(yùn)算。例如:
s=qsn(2)-qsn(3)+qsn(4);
⑶函數(shù)參數(shù)方式在函數(shù)調(diào)用的這種方式下,函數(shù)調(diào)用作為另外一個(gè)函數(shù)調(diào)用的實(shí)際參數(shù)出現(xiàn)。此時(shí)要求函數(shù)被調(diào)用后必須要返回一個(gè)確定的值以作為其外層函數(shù)調(diào)用的實(shí)際參數(shù)。例如:
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用
/*函數(shù)參數(shù).cpp*/
#include<stdio.h>
intmax(intx,inty)/*函數(shù)定義*/{return(x>y?x:y);}main(){inta,b,c;/*定義3個(gè)整型變量,保存需要保存的三個(gè)數(shù)*/
intMAX;/*保存最大值*/
printf(“請(qǐng)輸入三個(gè)數(shù)\n”);
scanf(“%d,%d,%d”,&a,&b,&c);
MAX=max(a,max(b,c));/*求三個(gè)數(shù)的最大值,函數(shù)max作為實(shí)參*/
printf(“3個(gè)數(shù)中的最大值是:%d\n”,MAX);
}//n個(gè)數(shù)的最大值可以?xún)蓛上嗲螅?個(gè)數(shù)中的最大值max(max(a,b),max(c,d)4.1.2值參數(shù)傳遞的函數(shù)調(diào)用當(dāng)被調(diào)函數(shù)是有參函數(shù)時(shí),函數(shù)的調(diào)用必然伴隨著參數(shù)傳遞。在C程序函數(shù)調(diào)用的數(shù)據(jù)傳遞中,傳遞的是實(shí)際參數(shù)所具有的值。當(dāng)實(shí)際參數(shù)是常量、變量或函數(shù)調(diào)用時(shí),傳遞的數(shù)據(jù)就是這些數(shù)據(jù)對(duì)象所具有的內(nèi)容,這種方式亦稱(chēng)為傳數(shù)據(jù)值方式。如果函數(shù)調(diào)用時(shí)所傳遞的實(shí)際參數(shù)是數(shù)據(jù)對(duì)象在內(nèi)存中存儲(chǔ)的首地址值,則稱(chēng)之為傳地址值方式,對(duì)于指針參數(shù)和數(shù)組參數(shù)就是使用的傳地址值調(diào)用方式,將分別在本章的4.1.3和4.1.4小節(jié)中予以討論。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用無(wú)論函數(shù)調(diào)用時(shí)的傳遞是數(shù)值值還是地址值,函數(shù)調(diào)用的執(zhí)行過(guò)程都可以分為下面四個(gè)步驟:(1)系統(tǒng)為被調(diào)函數(shù)中的局部變量分配存儲(chǔ);(2)如果是有參函數(shù)調(diào)用則進(jìn)行參數(shù)傳遞,主調(diào)函數(shù)將實(shí)參值傳遞給被調(diào)函數(shù)的形參,傳遞時(shí)要保證參數(shù)的個(gè)數(shù)、類(lèi)型、位置等一一對(duì)應(yīng);(3)程序執(zhí)行的控制流程轉(zhuǎn)移到被調(diào)函數(shù)執(zhí)行;(4)執(zhí)行完被調(diào)函數(shù)后,程序執(zhí)行的控制流程以及被調(diào)函數(shù)的執(zhí)行結(jié)果返回到主調(diào)函數(shù)中的調(diào)用點(diǎn)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用例4.3的程序討論函數(shù)調(diào)用的執(zhí)行過(guò)程,為了討論方便為程序加上行號(hào)。1 /*ex04-03.cpp*/2 #include<stdio.h>3 voidmain()4 { voidswap(intx,inty);5 inta=3,b=5;6 printf("swap調(diào)用前:a=%d,b=%d\n",a,b);7 swap(a,b);8 printf("swap調(diào)用后:a=%d,b=%d\n",a,b);9 }10 voidswap(intx,inty)11 { intt;12 t=x,x=y,y=t;13 printf("swap調(diào)用中:x=%d,y=%d\n",x,y);14 }4.1.2值參數(shù)傳遞的函數(shù)調(diào)用C程序執(zhí)行時(shí),函數(shù)在被調(diào)用之前其形參和函數(shù)體中定義的普通變量在系統(tǒng)中都是不存在的,它們?cè)谙到y(tǒng)中出現(xiàn)或消失與函數(shù)調(diào)用的過(guò)程有著密切的關(guān)系,在例4.3程序執(zhí)行到第7行之前,函數(shù)swap中的形參x和y以及函數(shù)體中定義的變量t在系統(tǒng)中均不存在,參見(jiàn)圖4.2a)。
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用函數(shù)swap傳數(shù)據(jù)值調(diào)用的過(guò)程如下:(1)系統(tǒng)為被調(diào)函數(shù)中的局部變量分配存儲(chǔ)。如在例4.3程序中,程序執(zhí)行到第7行時(shí)系統(tǒng)才會(huì)創(chuàng)建變量x、y和t(即為這些變量分配存儲(chǔ)),參見(jiàn)圖4.2b)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用(2)參數(shù)傳遞。傳遞參數(shù)值實(shí)質(zhì)上是將實(shí)參的內(nèi)容拷貝給形參,一旦拷貝完成則實(shí)參與形參就沒(méi)有任何關(guān)系。在例4.3程序中,傳遞參數(shù)時(shí)將實(shí)參a的值拷貝給形參x,實(shí)參b的值拷貝給形參y,拷貝完成后實(shí)參變量a、b與形參變量x、y就斷開(kāi)聯(lián)系,參見(jiàn)圖4.2c)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用(3)控制流程轉(zhuǎn)移到被調(diào)函數(shù)執(zhí)行。在例4.3程序中,參數(shù)調(diào)用完成后程序的控制流程(執(zhí)行順序)就從第7行轉(zhuǎn)移到第12行開(kāi)始執(zhí)行函數(shù)swap,參見(jiàn)圖4.2c)d)e)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用(4)控制流程返回主調(diào)函數(shù)。在例4.3程序中,程序執(zhí)行到第14行時(shí)將控制流程返回到第7行的函數(shù)調(diào)用點(diǎn)后。與此同時(shí),調(diào)用swap函數(shù)時(shí)創(chuàng)建的變量x、y和t都自動(dòng)被系統(tǒng)撤消。程序控制流程執(zhí)行到被調(diào)函數(shù)中的return語(yǔ)句或函數(shù)體的函數(shù)的最后一個(gè)右花括號(hào)“}”時(shí),將程序執(zhí)行的控制流程以及被調(diào)函數(shù)的執(zhí)行結(jié)果返回到主調(diào)函數(shù)中的調(diào)用點(diǎn)。特別需要注意的是,隨著程序控制流程的返回,系統(tǒng)會(huì)自動(dòng)收回為被調(diào)函數(shù)的形式參數(shù)和局部變量分配的存儲(chǔ)單元,即在函數(shù)被調(diào)用時(shí)創(chuàng)建的形式參數(shù)和局部變量會(huì)自動(dòng)撤銷(xiāo)。
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用程序執(zhí)行的結(jié)果如下所示:swap調(diào)用前:a=3,b=5swap調(diào)用中:x=5,y=3swap調(diào)用后:a=3,b=5從輸出結(jié)果看到main中a和b的值并沒(méi)有交換,原因就是在調(diào)用函數(shù)時(shí),只是把參數(shù)a和b的值拷貝給了x和y。在swap中,只是對(duì)局部變量x、y的值進(jìn)行了交換,并不影響主調(diào)函數(shù)中作為參數(shù)變量a和b。如果需要在被調(diào)函數(shù)中對(duì)主調(diào)函數(shù)中實(shí)際參數(shù)進(jìn)行操作,則需要將主調(diào)函數(shù)中實(shí)際參數(shù)在內(nèi)存中存放的地址起始值傳遞給被調(diào)函數(shù)對(duì)應(yīng)的形式參數(shù),這就是“傳地址調(diào)用”的方法。通過(guò)這種方法可以做到“函數(shù)中對(duì)參數(shù)的修改將影響主調(diào)函數(shù)中參數(shù)值”。這就好比在兩個(gè)函數(shù)間開(kāi)了一個(gè)通道,讓一個(gè)函數(shù)可以操作另外一個(gè)函數(shù)的局部變量。程序演示4.1.2值參數(shù)傳遞的函數(shù)調(diào)用本小節(jié)主要討論指針變量的基本用法和實(shí)際參數(shù)值是地址值時(shí)的函數(shù)調(diào)用問(wèn)題1)指針和指針變量的概念程序中的任何數(shù)據(jù)對(duì)象在運(yùn)行過(guò)程中一旦被使用,就會(huì)對(duì)應(yīng)計(jì)算機(jī)系統(tǒng)內(nèi)存中的一個(gè)地址。由于系統(tǒng)內(nèi)存儲(chǔ)器是按字節(jié)編址的,一個(gè)數(shù)據(jù)對(duì)象有可能占用一至若干個(gè)字節(jié)的存儲(chǔ)單元,在程序設(shè)計(jì)語(yǔ)言中一般將數(shù)據(jù)對(duì)象的名字與其所占用的存儲(chǔ)單元的首地址相對(duì)應(yīng)。在計(jì)算機(jī)系統(tǒng)中,內(nèi)存單元的地址是用有序整型數(shù)進(jìn)行編址的,所以存儲(chǔ)系統(tǒng)的地址序號(hào)本質(zhì)上就是無(wú)符號(hào)的整型數(shù)據(jù)。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用什么是指針?我們知道存放在內(nèi)存中的數(shù)據(jù)有些占4字節(jié)(整型),有些占8字節(jié),也就是說(shuō)只要知道數(shù)據(jù)的起始位置和數(shù)據(jù)類(lèi)型,計(jì)算機(jī)就可以準(zhǔn)確的訪(fǎng)問(wèn)這個(gè)數(shù)據(jù)。把起始地址記為數(shù)據(jù)的“地址”,如圖:
4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用A19233.141596.02e+23101……105地址內(nèi)存空間10010110510911720502046char型,占1字節(jié)bint型,占4字節(jié)cfloat型,占4字節(jié)ddouble型,占8字節(jié)pq2046存放的是整數(shù)1923的地址p,2050存放的是浮點(diǎn)數(shù)3.14159的地址q,這就需要我們用一種新的數(shù)據(jù)表示存儲(chǔ)的數(shù)據(jù)是地址而不是其他的數(shù)值。在C中,除了在前面介紹的各種普通數(shù)據(jù)類(lèi)型之外,還有另外一種特殊性質(zhì)的變量,即指針變量,簡(jiǎn)稱(chēng)指針。
指針是存放一個(gè)數(shù)據(jù)或變量地址的變量。它和普通變量一樣占用一定的存儲(chǔ)空間,不同之處在于:指針存儲(chǔ)的不是普通數(shù)據(jù),而是一個(gè)數(shù)據(jù)或變量的地址。怎么能知道一個(gè)變量的地址呢?
使用運(yùn)算符&!假設(shè)定義一個(gè)整型指針變量,名字是p,定義x為普通整型變量,對(duì)x取地址,&x的值就是變量x的地址。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用intx;int*p;/*變量前加*,表示該變量是指針變量*/p=&x;4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用變量x的地址被裝入指針p的存儲(chǔ)區(qū)域,即p的內(nèi)容就是變量x的地址。如圖示:變量x應(yīng)當(dāng)和指針變量p的類(lèi)型保持一致。101指針p地址101變量x(a)將x的地址裝入p(b)指針p指向變量x指針p地址101變量xp=&x稱(chēng)*p為指針p的目標(biāo)變量,也就是變量x,指針除了可以指向變量外,還可以指向內(nèi)存中其它任何一種數(shù)據(jù)結(jié)構(gòu),如數(shù)組、結(jié)構(gòu)體類(lèi)型和函數(shù)等。指針的定義:例如: int*p,*y; 定義了兩個(gè)整型的指針變量p和y,注意指針變量是p和y,而不是*p和*y 如果有需要,指針變量也可以和同類(lèi)型的普通變量混合定義。 例如: charch1,ch2,*p; 定義了兩個(gè)字符變量ch1、ch2以及一個(gè)指針變量4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用類(lèi)型標(biāo)識(shí)符*指針名指針變量賦值的方法有兩種:一種是;(1)使用賦值號(hào)的一般形式為:
指針變量名=地址值;(2)另外一種是指針變量在定義時(shí)進(jìn)行初始化,一般形式為:
數(shù)據(jù)類(lèi)型符*指針變量名=初始化地址值;
4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用
例如:intx,*y=&x;
/*定義了變量x和指針變量y,并將x的首地址賦值給y*/或
intx,*y; /*定義變量x和指針變量y*/ y=&x;/*將變量x的首地址賦值給指針變量y*/(假設(shè)x的值為100,X對(duì)應(yīng)的存儲(chǔ)單元的首地址是25000,則指針變量y和它指向的變量x之間的關(guān)系如圖)2500025000100xy10025000xya)b)圖4.3指針變量y與變量x的存儲(chǔ)關(guān)系圖4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用深入理解指針運(yùn)算符*和地址運(yùn)算符&如前例:*y是y所指向的變量,即x,*是一個(gè)指針運(yùn)算符,y是運(yùn)算對(duì)象,下列賦值語(yǔ)句結(jié)果一樣:
對(duì)整型變量x取地址,下列操作等同*(&x)表示的含義呢?表示x本身4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用x=8;或*y=8;&x或&(*y)在C程序設(shè)計(jì)中,對(duì)于指針變量的理解和使用時(shí)還應(yīng)該特別注意以下幾點(diǎn):⑴在指針變量的定義形式中,星號(hào)(*)只是一個(gè)標(biāo)志,表示其后面的變量是指針變量。例如,在指針變量定義語(yǔ)句intx,*y;中,y是指針變量。⑵一個(gè)指針變量只能指向與它同類(lèi)型的普通變量,即只有數(shù)據(jù)類(lèi)型相同時(shí)普通變量才能將自己存儲(chǔ)單元的首地址賦值給指針變量,其原因是不同類(lèi)型的變量所占存儲(chǔ)單元的字節(jié)數(shù)是不同的。intx;float*ptr;ptr=&x;/*錯(cuò)誤,指針變量沒(méi)有指向合適的數(shù)據(jù)對(duì)象*/但在這種情況下有一個(gè)特例,可以將任何數(shù)據(jù)類(lèi)型對(duì)象的存儲(chǔ)首地址賦值給void類(lèi)型(空類(lèi)型)的指針變量,例如:intx; void*p=&x; /*將整型變量x的存儲(chǔ)首地址賦值給空類(lèi)型指針變量p*/4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用⑶指針變量只能在有確定的指向后才能正常使用,也就是說(shuō)指針變量中必須要有確定的地址。沒(méi)有確定指向的指針?lè)Q為“空指針”或稱(chēng)為“懸掛指針”,使用這種指針變量有可能引起不可預(yù)知的錯(cuò)誤。⑷指針變量中只能存放地址值,不能把除NULL外的整型常數(shù)直接賦給指針變量。例如,下面的指針變量的賦值是錯(cuò)誤的:int*ptr;ptr=100;/*錯(cuò)誤,整型常數(shù)值直接賦給指針變量*/
以下是正確的:
float*p=NULL;/*定義實(shí)型指針變量p并將其初始化為常量NULL*/ 或者float*p;
/*定義實(shí)型指針變量p*/
p=NULL;
/*將符號(hào)常量NULL賦值給指針變量p*/4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用3.指針變量的引用怎樣用指針運(yùn)算符來(lái)處理數(shù)據(jù)呢?設(shè)變量x、y同類(lèi)型,把x復(fù)制到y(tǒng)中,可采取下列方法:直接賦值: y=x;使用指針:設(shè)指針變量p用于保存x的地址: p=&x;再執(zhí)行語(yǔ)句 y=*p;例如下列程序段
intx=20,y,*ptr;ptr=&x;y=*ptr;該程序段的意思為:定義整型變量x(初值為20),y和指針*ptr,將變量x的地址賦給指針變量ptr,然后以指針變量ptr的值為內(nèi)存單元地址,將該單元的數(shù)據(jù)取出賦給變量y,相當(dāng)于語(yǔ)句y=x;例如有語(yǔ)句序列為:
intx,*y;y=&x;此時(shí)&x等價(jià)于y,而*y則等價(jià)于變量x。在這種情況下,有下面的等價(jià)關(guān)系的:scanf("%d",&x);等價(jià)于scanf("%d",y);printf(“%d\n”,x);等價(jià)于printf("%d\n",*y);在編寫(xiě)程序過(guò)程,注意的幾個(gè)概念:設(shè)有指針變量pP指針變量,它的內(nèi)容是地址值。*p指針的目標(biāo)變量,它的內(nèi)容是數(shù)據(jù)(p地址的數(shù)據(jù))。&p指針變量的地址,即“地址的地址”。NULL空指針,表示指針內(nèi)容為0p=NULL;/*等價(jià)于p=0*/4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用例4.4取地址運(yùn)算符(&)和指針運(yùn)算符(*)的使用示例。/*Name:ex04-04.cpp*/#include<stdio.h>voidmain(){ intx=200,*y; y=&x; *y=300; printf("%x:%d,%d\n",y,x,*y);}程序執(zhí)行的結(jié)果為:13ff7c:300,300(注意變量y的十六進(jìn)制值在不同的機(jī)器上可能是不同的)。程序演示4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用以16進(jìn)制形式輸出無(wú)符號(hào)整數(shù)4.地址值參數(shù)傳遞調(diào)用
函數(shù)調(diào)用時(shí)如果被調(diào)函數(shù)的形參用指針型參數(shù)(即某種數(shù)據(jù)類(lèi)型的指針變量作為函數(shù)的形式參數(shù)),則主調(diào)函數(shù)中的實(shí)參就必須是指針值(地址)。這種在函數(shù)調(diào)用過(guò)程中傳遞主調(diào)函數(shù)實(shí)際參數(shù)的指針(即實(shí)際參數(shù)存儲(chǔ)單元的首地址)的方式提供了在被調(diào)函數(shù)中操作主調(diào)函數(shù)中實(shí)際參數(shù)的可能性。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用例4.5地址值參數(shù)傳遞函數(shù)調(diào)用示例。/*Name:ex04-05.cpp*/#include<stdio.h>voidmain(){ voidswap(int*x,int*y);/*函數(shù)聲明中形參是指針變量*/ inta=3,b=5; printf("swap函數(shù)調(diào)用前:a=%d,b=%d\n",a,b);
swap(&a,&b);/*實(shí)參也必須為地址*/ printf("swap函數(shù)調(diào)用后:a=%d,b=%d\n",a,b);}voidswap(int*x,int*y)/*函數(shù)定義中形參是指針變量*/{ intt;/*注意t不是指針變量,是被指針指向的變量*/ t=*x; *x=*y; *y=t;}4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用執(zhí)行過(guò)程如圖:3510002000xyabta)參數(shù)傳遞過(guò)程中3510002000xyabtb)參數(shù)傳遞完成后35100020003xyabtc)t=*x執(zhí)行后55100020003xyabtd)*x=*y執(zhí)行后53100020003xyabte)*y=t執(zhí)行后圖4.4地址值傳遞函數(shù)調(diào)用時(shí)參數(shù)的變化情況4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用程序執(zhí)行后的輸出結(jié)果為:swap函數(shù)調(diào)用前:a=3,b=5swap函數(shù)調(diào)用后:a=5,b=3從上面程序執(zhí)行的過(guò)程可以得出使用地址傳送方式在函數(shù)之間傳遞數(shù)據(jù)的特點(diǎn)是:數(shù)據(jù)在主調(diào)函數(shù)和被調(diào)函數(shù)中均使用同一存儲(chǔ)單元,所以在被調(diào)函數(shù)中對(duì)形參數(shù)據(jù)任何的變動(dòng)必然會(huì)反映到主調(diào)函數(shù)中來(lái)。5.指針變量與被指針指向變量的區(qū)別從上面程序執(zhí)行的過(guò)程t=*x;*x=*y;*y=t;可以看出在操作的對(duì)象是被指針指向變量。而下面這個(gè)例子是交換的對(duì)象是指針變量本身,體會(huì)它們的不同之處。程序演示4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用例4.6地址值參數(shù)傳遞函數(shù)調(diào)用示例。/*Name:ex04-06.cpp*/#include<stdio.h>voidmain(){ voidswap(int*x,int*y); inta=3,b=5; printf("swap函數(shù)調(diào)用前:a=%d,b=%d\n",a,b); swap(&a,&b); printf("swap函數(shù)調(diào)用后:a=%d,b=%d\n",a,b);}voidswap(int*x,int*y){ int*t;/*t是指針變量*/ t=x; x=y; y=t;}4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用執(zhí)行過(guò)程如圖:3510002000xyabta)參數(shù)傳遞過(guò)程中3510002000xyabtb)參數(shù)傳遞完成后35100020001000xyabtc)t=x執(zhí)行后35200020001000xyabtd)x=y執(zhí)行后35200010001000xyabte)y=t執(zhí)行后圖4.5地址值傳遞函數(shù)調(diào)用時(shí)參數(shù)的變化情況4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用程序執(zhí)行的結(jié)果并沒(méi)使得主函數(shù)中的實(shí)參變量a和b交換內(nèi)容。程序執(zhí)行的結(jié)果為:swap函數(shù)調(diào)用前:a=3,b=5swap函數(shù)調(diào)用后:a=3,b=5程序演示4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用雖然在被調(diào)用函數(shù)中使用指針型參數(shù)就提供了在被調(diào)函數(shù)中操作主調(diào)函數(shù)中實(shí)際參數(shù)的可能性。但并不是用了指針變量作函數(shù)的形式參數(shù)就一定可以在被調(diào)函數(shù)中操作或修改主調(diào)函數(shù)中的實(shí)參。在被調(diào)函數(shù)中是否能夠操作或修改主調(diào)函數(shù)中實(shí)參值還要取決于在被調(diào)函數(shù)中對(duì)指針形參的操作方式,操作指針形參變量指向的對(duì)象(即實(shí)參本身)則可以達(dá)到在被調(diào)函數(shù)中操作或修改主調(diào)函數(shù)實(shí)參的目的;但若操作的是指針形參變量本身則不能實(shí)現(xiàn)在被調(diào)函數(shù)中操作或修改主調(diào)函數(shù)實(shí)際參數(shù)的目的。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用
在C程序設(shè)計(jì)中,既可以用數(shù)組的元素作為函數(shù)的參數(shù),也可以將數(shù)組看成一個(gè)整體作為函數(shù)的參數(shù)。
使用數(shù)組元素作為參數(shù)傳遞,其用法都與普通變量用法一樣,實(shí)現(xiàn)的是函數(shù)間的傳值調(diào)用。而用數(shù)組名作為實(shí)參,是傳遞的是數(shù)組地址。
例如4.7程序在執(zhí)行中,對(duì)于主函數(shù)中傳遞過(guò)來(lái)的一維數(shù)組a和二維數(shù)組b的每一個(gè)數(shù)組元素,利用自定義函數(shù)myprint進(jìn)行輸出。4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用程序演示/*Name:ex04-07.cpp*/#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5voidmain(){ voidmyprint(intx); inta[N],b[N][N],i,j; srand(time(NULL)); printf("下面是數(shù)組a的數(shù)據(jù)...\n"); for(i=0;i<N;i++) { a[i]=rand()%100;
myprint(a[i]); }printf("\n下面是數(shù)組b的數(shù)據(jù)...\n");for(i=0;i<N;i++){for(j=0;j<N;j++){b[i][j]=rand()%100;
myprint(b[i][j]);}printf("\n");
}}voidmyprint(intx){ printf("%4d",x);}4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用將數(shù)組看成一個(gè)整體作為函數(shù)參數(shù)時(shí),用數(shù)組名作為函數(shù)的形式參數(shù)或?qū)嶋H參數(shù),實(shí)現(xiàn)的是函數(shù)間的傳地址值調(diào)用。先認(rèn)識(shí)指針與數(shù)組的關(guān)系:intarray[9],*ptr;ptr=array;或者intarray[9],*ptr;ptr=&array[0]/*表示指針ptr指向了數(shù)組array的首地址*/補(bǔ)充:為何數(shù)組名是一個(gè)(首)地址ptrarrayarray[0]*ptrarray[i]array[1]array[2]array[3]*(ptr+1)*(ptr+2)*(ptr+3)*(ptr+i)如圖:數(shù)組與指針的關(guān)系,當(dāng)數(shù)組名傳給函數(shù)時(shí),傳送的是數(shù)組的起始位置
1.一維數(shù)組名作為函數(shù)參數(shù)實(shí)現(xiàn)的是“傳地址值調(diào)用”,其本質(zhì)是將它的全部存儲(chǔ)區(qū)域或者部分存儲(chǔ)區(qū)域提供給形式參數(shù)數(shù)組共享,即形參數(shù)組與實(shí)參數(shù)組是同一存儲(chǔ)區(qū)域或者形參數(shù)組是實(shí)參數(shù)組存儲(chǔ)區(qū)域的一部分。存儲(chǔ)關(guān)系如下圖:實(shí)參數(shù)組a…形參數(shù)組b[]注:形參數(shù)組b本質(zhì)上是指針變量圖4.6數(shù)組存儲(chǔ)區(qū)域全部共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用需要把實(shí)參數(shù)組中從某個(gè)元素值后的部分傳遞給被調(diào)函數(shù)中的形參數(shù)組,則使用實(shí)參數(shù)組某個(gè)元素的地址(參見(jiàn)圖4.7)。
實(shí)參數(shù)組&a[2]…形參數(shù)組b[]注:形參數(shù)組b本質(zhì)上是指針變量圖4.7數(shù)組存儲(chǔ)區(qū)域部分共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用例4.8編制求和函數(shù)并通過(guò)該函數(shù)求數(shù)組的元素值和。intsum(intv[],intn){ inti,s=0; for(i=0;i<n;i++) s+=v[i]; returns;}/*Name:ex04-08.cpp*/#include<stdio.h>#defineN10voidmain(){intsum(intv[],intn);/*v表示一維數(shù)組,n表示其長(zhǎng)度*/inta[N]={1,2,3,4,5,6,7,8,9,10},total;total=sum(a,N);/*調(diào)用時(shí)將數(shù)組名a作為實(shí)參傳遞給形參v,首地址默認(rèn)為0,也可以寫(xiě)作&a[0]*/printf("total=%ld\n",total);}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用例4.9編制求和函數(shù)并通過(guò)該函數(shù)求數(shù)組自某一元素后的所有元素值和,起始點(diǎn)元素序號(hào)從鍵盤(pán)上輸入。/*Name:ex04-09.cpp*/#include<stdio.h>#defineN10voidmain(){intsum(intv[],intn);inta[N]={1,2,3,4,5,6,7,8,9,10},total,pos;printf("請(qǐng)輸入求和起始元素序號(hào):");scanf("%d",&pos);
total=sum(&a[pos],N-pos);/*調(diào)用時(shí)將數(shù)組a[pos]作為實(shí)參首地址傳遞給形參v,*/printf("total=%ld\n",total);}intsum(intv[],intn){ inti,s=0; for(i=0;i<n;i++) s+=v[i]; returns;}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用比較例4.8和例4.9的程序,可以發(fā)現(xiàn)函數(shù)sum沒(méi)有任何改變,程序中有所改變的是主調(diào)函數(shù)中的調(diào)用表達(dá)式:sum(&a[pos],N-pos),其中,參數(shù)&a[pos]表示將數(shù)組a自a[pos]元素以后的元素全部提供給形參數(shù)組共享,N-pos是傳遞到函數(shù)total中共享的數(shù)組元素個(gè)數(shù)。4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用2.二維數(shù)組作函數(shù)的參數(shù)
數(shù)組a的起始地址數(shù)組的起始地址表示方法a 表示平面的起始地址(二級(jí)地址)&a[0][0]表示線(xiàn)性的起始地址(一級(jí)地址)a[0]表示線(xiàn)性的起始地址(一級(jí)地址)*a表示線(xiàn)性的起始地址(一級(jí)地址)圖4.8二維數(shù)組起始地址的表示方法示意
二維數(shù)組在存儲(chǔ)時(shí)也是有序地占用一片連續(xù)的內(nèi)存區(qū)域,數(shù)組的名字表示這段存儲(chǔ)區(qū)域的首地址。需要特別注意的是,二維數(shù)組起始地址有多種表示方法,而且這些表示方法在物理含義上還有表示平面起始地址和表示線(xiàn)性起始地址之分,所以在使用二維數(shù)組的起始地址使必須注意區(qū)分需要用哪一種起始地址。
4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用(1)用二維數(shù)組名字作為實(shí)際參數(shù)實(shí)參用a,形參用b[][5]圖4.9實(shí)際參數(shù)為二維數(shù)組名字,用二維數(shù)組名作為函數(shù)參數(shù)實(shí)現(xiàn)的是“傳地址值調(diào)用”,其本質(zhì)仍然是在函數(shù)調(diào)用期間實(shí)際參數(shù)數(shù)組將它的全部存儲(chǔ)區(qū)域提供給形式參數(shù)數(shù)組共享,即形參數(shù)組與實(shí)參數(shù)組是同一存儲(chǔ)區(qū)域。實(shí)參用a形參用b[][5]圖4.9實(shí)際參數(shù)為二維數(shù)組名字4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用用二維數(shù)組名字作為實(shí)際參數(shù)傳地址調(diào)用例4.10編制求二維矩陣最大元素的函數(shù)(假定矩陣為3行4列),用相應(yīng)主函數(shù)進(jìn)行測(cè)試。/*Name:ex04-10.cpp*/#include<stdio.h>#defineM3#defineN4voidmain(){ intmax(intv[][N]); inta[M][N]={38,23,56,9,56,2,789,45,76,7,45,34}; printf("Maxvalueis:%d\n",max(a));}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用intmax(intv[][N]) //注意數(shù)組參數(shù)只能省略最高維的長(zhǎng)度指定{ inti,j,maxv; maxv=v[0][0]; for(i=0;i<M;i++) for(j=0;j<N;j++) if(v[i][j]>maxv) maxv=v[i][j]; returnmaxv;}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用例4.10程序的函數(shù)max中使用了二維數(shù)組樣式的形式參數(shù)接收從主調(diào)函數(shù)中傳遞過(guò)來(lái)的二維數(shù)組首地址,使得形參數(shù)組v共享實(shí)參數(shù)組a的存儲(chǔ)區(qū)域;然后通過(guò)對(duì)形參數(shù)組v的操作達(dá)到操作是參數(shù)a的目的,即在形參數(shù)數(shù)組v中尋找最大值實(shí)質(zhì)上是在實(shí)參數(shù)組a中尋找最大值,程序執(zhí)行的結(jié)果為:Maxvalueis:789。該函數(shù)雖然能求出矩陣的最大元素,但有一個(gè)致命弱點(diǎn),它只能求出3行4列矩陣的最大元素。其根本原因是:使用高維數(shù)組名作函數(shù)的形參時(shí),必須要制定除最高維以外的所有維的長(zhǎng)度。為編制較通用的函數(shù),可以使用一維數(shù)組名作形參,此時(shí),可以不制定長(zhǎng)度,但仍然要注意一下2點(diǎn):(1)調(diào)用時(shí)的實(shí)參必須是一維數(shù)組的地址(指針)形式。如圖4.8的一級(jí)地址。(2)在函數(shù)中每一行的長(zhǎng)度由程序員自己控制,應(yīng)該從主調(diào)函數(shù)中傳遞過(guò)來(lái)。4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用(2)用二維數(shù)組起始地址的一級(jí)地址形式作為實(shí)際參數(shù)使用一維數(shù)組樣式的形式參數(shù)接收二維數(shù)組實(shí)參,數(shù)組存儲(chǔ)區(qū)域全部共享或部分共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系如圖4.10所示。
4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用實(shí)參數(shù)組a…形參數(shù)組b[]注:形參數(shù)組b本質(zhì)上是指針變量圖4.6數(shù)組存儲(chǔ)區(qū)域全部共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系例4.11重新編制例4.10中的函數(shù)max,使其能夠處理任意行列的二維數(shù)組。/*Name:ex04-11.cpp*/#include<stdio.h>#defineM3#defineN4voidmain(){ intmax(intv[],intm,intn); inta[M][N]={38,23,56,9,56,2,789,45,76,7,45,34}; printf("Maxvalueis:%d\n",max(a[0],M,N));}4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用intmax(intv[],intm,intn){ inti,j,maxv; maxv=v[0]; for(i=0;i<m;i++) for(j=0;j<n;j++) if(v[i*n+j]>maxv) maxv=v[i*n+j]; returnmaxv;}程序中函數(shù)max用一維數(shù)組形參v來(lái)接收從主調(diào)函數(shù)中傳遞過(guò)來(lái)的二維數(shù)組首地址,注意到二維數(shù)組的名字表示的是二級(jí)地址,所以被傳遞的二維數(shù)組的首地址不能直接用二維數(shù)組名表示而應(yīng)該使用3種一級(jí)地址形式,本示例中使用的是a[0],還可以使用&a[0][0]和*a形式。在被調(diào)函數(shù)中將傳遞過(guò)來(lái)的二維數(shù)組當(dāng)作一維數(shù)組處理,其元素對(duì)應(yīng)關(guān)系應(yīng)該是:a[i][j]→v[i*n+j]。程序執(zhí)行的結(jié)果為:Maxvalueis:789。程序演示函數(shù)的定義和調(diào)用函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的作用域和生存期編譯預(yù)處理多源文件C程序的組織方法第4章函數(shù)與程序結(jié)構(gòu)4.2.1函數(shù)的嵌套調(diào)用在C程序中函數(shù)不能嵌套定義。但C語(yǔ)言允許函數(shù)嵌套調(diào)用,所謂函數(shù)的嵌套調(diào)用就是一個(gè)函數(shù)在自己被調(diào)用的過(guò)程中又調(diào)用了另外的函數(shù)。一個(gè)兩層嵌套函數(shù)調(diào)用的過(guò)程如圖4.10。主函數(shù)函數(shù)fun1函數(shù)fun2程序運(yùn)行結(jié)束調(diào)用函數(shù)fun1調(diào)用函數(shù)fun2fun1執(zhí)行結(jié)束fun2執(zhí)行結(jié)束圖4.10兩層函數(shù)嵌套調(diào)用示意圖4.2函數(shù)的嵌套調(diào)用和遞歸調(diào)用例4.12編程序計(jì)算要求對(duì)n項(xiàng)的求和以及每一項(xiàng)ik的計(jì)算都用獨(dú)立的函數(shù)實(shí)現(xiàn),k和n的值在主函數(shù)中從鍵盤(pán)輸入。程序設(shè)計(jì)思路:可以把問(wèn)題分解為兩個(gè)模塊:求冪次方模塊和求和模塊,在求和模塊中要包含求冪模塊。f1()函數(shù)的參數(shù)為n和k,其返回值是n的k次方。f2()函數(shù)的參數(shù)為n和k,返回值是冪次方的累加和。4.2.1函數(shù)的嵌套調(diào)用#include<stdio.h>longf1(intn,intk)
{longpower=n;inti;for(i=1;i<k;i++)power*=n;returnpower;}longf2(intn,intk) {longsum=0;inti;for(i=1;i<=n;i++)sum+=f1(i,k);returnsum;}voidmain(){intn,k;
scanf(“%d,%d”,&n,&k);printf("Sumof%dpowersofintegersfrom1to%d=",k,n);printf("%d\n",f2(n,k));}輸入:4,5結(jié)果:Sumof5powersofintegersfrom1to4=1300該程序中,main()中調(diào)用了f2()函數(shù),而f2()函數(shù)中又調(diào)用了f1()函數(shù),這就是函數(shù)的嵌套調(diào)用。程序演示4.2.1函數(shù)的嵌套調(diào)用
一個(gè)函數(shù)直接地或間接地自己調(diào)用自己,稱(chēng)為函數(shù)的遞歸調(diào)用。特點(diǎn)為:(1)遞歸調(diào)用中每次嵌套調(diào)用的函數(shù)都是該函數(shù)本身;(2)遞歸調(diào)用不會(huì)無(wú)限制進(jìn)行下去,即這種特殊的自己對(duì)自己的嵌套調(diào)用總會(huì)在某種條件下結(jié)束。(3)遵從”先進(jìn)后出“規(guī)則。遞歸調(diào)用的實(shí)現(xiàn)依靠系統(tǒng)提供一個(gè)特殊部件(堆棧)存放未完成的操作。計(jì)算機(jī)系統(tǒng)的堆棧是一段先進(jìn)后出(FILO)的存儲(chǔ)區(qū)域,系統(tǒng)在遞歸調(diào)用時(shí)將在遞歸過(guò)程中應(yīng)該執(zhí)行而未執(zhí)行的操作依次從堆棧棧底開(kāi)始存放,當(dāng)遞歸結(jié)束回溯時(shí)再依存放時(shí)相反的順序?qū)⑺鼈儚亩褩V腥〕鰜?lái)執(zhí)行,在壓棧和出棧操作中,系統(tǒng)使用堆棧指針指示出應(yīng)該存入和取出數(shù)據(jù)的位置。4.2.2函數(shù)的遞歸調(diào)用例4.13函數(shù)遞歸調(diào)用示例(使用遞歸調(diào)的方法反向輸出字符串)。1 /*Name:ex04-13.cpp*/2 #include<stdio.h>3 voidmain()4 { voidreverse();5 printf("輸入一個(gè)字符串,以'#'作為結(jié)束字符:");6 reverse();7 printf("\n");8 }9 voidreverse()10 { charch;11 ch=getchar();12 if(ch=='#')13 putchar(ch);14 else15 { reverse();16 putchar(ch);17 }18 }執(zhí)行如下圖4.2.2函數(shù)的遞歸調(diào)用所以程序執(zhí)行時(shí)輸入數(shù)據(jù)為字符串:abc#,則輸出數(shù)據(jù)為字符串:#cba。topa)空棧topputchar(‘a(chǎn)’)topc)putchar(‘a(chǎn)’)putchar(‘b’)topd)
putchar(‘a(chǎn)’)putchar(‘b’)putchar(‘c’)tope)
putchar(‘a(chǎn)’)putchar(‘b’)topputchar(‘a(chǎn)’)b)
f)
topg)空棧圖4.11遞歸調(diào)用時(shí)系統(tǒng)堆棧數(shù)據(jù)的變化示意圖程序演示4.2.2函數(shù)的遞歸調(diào)用例4.14編程序使用遞歸方式求n!。/*Name:ex04-14.cpp*/#include<stdio.h>voidmain(){ longfac(longn); longn,result; printf("Inputthen:"); scanf("%ld",&n);
result=fac(n); printf("%ld!=%ld\n",n,result);}longfac(longn){ if(n<=1) return1; else returnfac(n-1)*n;}4.2.2函數(shù)的遞歸調(diào)用fac(5)等于120執(zhí)行如下:程序演示4.2.2函數(shù)的遞歸調(diào)用fac(4)*5fac(3)*4*5fac(2)*3*4*5fac(1)*2*3*4*5調(diào)用返回fac(5)fac(5)等于120fac(5)→fac(4)*5fac(4)→fac(3)*4fac(3)→fac(2)*3fac(2)→fac(1)*2fac(1)→1遞歸壓棧方向fac(2)→fac(1)*2→1*2→2fac(3)→fac(2)*3→2*3→6fac(4)→fac(3)*4→6*4→24fac(5)→fac(4)*5→24*5→120遞歸回溯方向圖4.12函數(shù)遞歸調(diào)用過(guò)程示意圖執(zhí)行如下:程序演示4.2.2函數(shù)的遞歸調(diào)用
遞歸是程序設(shè)計(jì)中一種非常重要的技術(shù),與程序設(shè)計(jì)中其它控制方法策略相比較,遞歸程序設(shè)計(jì)的難度在于遞歸在人類(lèi)社會(huì)的現(xiàn)實(shí)生活中沒(méi)有直接對(duì)應(yīng)的概念存在,而必須通過(guò)推理分析才能理解遞歸思想進(jìn)而實(shí)現(xiàn)遞歸程序設(shè)計(jì)。在實(shí)際設(shè)計(jì)遞歸函數(shù)程序時(shí),我們可以將重點(diǎn)放在分析遞推公式和遞歸終止條件上,可以忽略系統(tǒng)的具體執(zhí)行過(guò)程,只要算法和遞推公式正確,結(jié)論一定是正確的。4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)遞歸的實(shí)質(zhì)是一種簡(jiǎn)化復(fù)雜問(wèn)題求解的方法,它將問(wèn)題逐步簡(jiǎn)化直至趨于已知條件。在簡(jiǎn)化的過(guò)程中必須保證問(wèn)題的性質(zhì)不發(fā)生變化,即在簡(jiǎn)化的過(guò)程中必須保證兩點(diǎn):一是問(wèn)題簡(jiǎn)化后具有同樣的形式;二是問(wèn)題簡(jiǎn)化后必須趨于比原問(wèn)題簡(jiǎn)單一些。具體使用遞歸技術(shù)時(shí),必須能夠?qū)?wèn)題簡(jiǎn)化分解為遞歸方程(即問(wèn)題的形式)和遞歸結(jié)束條件(即最簡(jiǎn)單的解)兩個(gè)部分。如例4.14求n的階乘,可以分解得到遞歸方程:n*(n-1)!和遞歸結(jié)束條件:n<=1時(shí)階乘為1。4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)例4.15求菲波拉契數(shù)列。已知一對(duì)小兔出生一個(gè)月后變成一對(duì)成兔,兩個(gè)月后這對(duì)成兔就會(huì)生出一對(duì)小兔,三個(gè)月后這對(duì)成兔將生出第二對(duì)小兔,而第一對(duì)小兔又長(zhǎng)大變成一對(duì)成兔,即一月成熟,二月生育,如此類(lèi)推。請(qǐng)用計(jì)算機(jī)求解一對(duì)小兔經(jīng)n月后將繁衍成多少對(duì)兔子?4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)可以分析出如下遞歸關(guān)系:按照上面分析得到的遞歸方程和結(jié)束條件,求菲波拉契數(shù)列的遞歸算法可以設(shè)計(jì)為如圖4.13所示。n=0或者n=1fib(n)retuan1returnfib(n-1)+fib(n-2)TF圖4.13菲波拉契數(shù)列的遞歸算法4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)/*Name:ex04-15.cpp*/#include<stdio.h>voidmain(){ intm; floatfib(intn); printf("請(qǐng)輸入月份數(shù)"); scanf("%d",&m); printf("經(jīng)過(guò)%d個(gè)月后,兔子有%.0f對(duì)。\n",m,fib(m));}floatfib(intn){ if(n==0||n==1) return1; else returnfib(n-1)+fib(n-2);}程序演示4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)
例4.16編程序用遞歸方法求兩個(gè)正整數(shù)的最大公約數(shù)。 可以分析得出如下遞歸關(guān)系:r=m%n=0gcd(n)retuannreturn
gcd(n,r)TF圖4.14最大公約數(shù)的遞歸算法4.2.2函數(shù)的遞歸調(diào)4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)/*Name:ex04-16.cpp*/#include<stdio.h>voidmain(){ intGcd(intm,intn); intnum1,num2; printf("請(qǐng)輸入兩個(gè)正整數(shù):"); scanf("%d,%d",&num1,&num2); if(num1<num2) num1=num1+num2,num2=num1-num2,num1=num1-num2; printf("%d與%d的最大公約數(shù)是:%d\n",num1,num2,Gcd(num1,num2));}intGcd(intm,intn){ intr; if((r=m%n)==0) returnn; else returnGcd(n,r);}程序演示4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)通過(guò)上面兩個(gè)示例的分析,遞歸方式的實(shí)現(xiàn)也是基于語(yǔ)言的條件控制結(jié)構(gòu)。遞歸函數(shù)設(shè)計(jì)的基本框架是相對(duì)固定的,其一般形式可以描述如下:if遞歸結(jié)束條件成立Return已知結(jié)果else將問(wèn)題轉(zhuǎn)化為同性質(zhì)的較簡(jiǎn)單子問(wèn)題;以遞歸方式求解子問(wèn)題(遞歸方程);4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)例4.17漢諾塔(TowerofHanoi)問(wèn)題。有A、B、C三根桿,最左邊桿上自下而上、由大到小順序串有64個(gè)金盤(pán)呈一塔形?,F(xiàn)要把左邊A桿上的金盤(pán)全部移到右邊C桿上,條件是一次只能移動(dòng)一個(gè)盤(pán),且不允許大盤(pán)壓在小盤(pán)的上面。可以將漢諾塔問(wèn)題分解為下面三步遞歸求解:第一步:把a(bǔ)桿上的n-1個(gè)盤(pán)子設(shè)法借助b桿放到c桿,記做hanoi(n-1,a,c,b);第二步:把第n個(gè)盤(pán)子從a桿移動(dòng)到b桿;第三步:把c桿上的n-1個(gè)盤(pán)子借助a桿移動(dòng)到b桿,記做hanoi(n-1,c,b,a);4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)/*Name:ex04-17.cpp*/#include<stdio.h>voidmain(){intn; voidhanoi(intn,chara,charb,charc); printf("\nPleaseinputthenumberofdiskstobemoved:"); scanf("%d",&n); hanoi(n,'a','b','c');}voidhanoi(intn,chara,charb,charc){ if(n==1) printf("\nMovedisc%dfrompile%cto%c",n,a,b); else { hanoi(n-1,a,c,b); printf("\nMovedisc%dfrompile%cto%c",n,a,b); hanoi(n-1,c,b,a); }}程序演示4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)函數(shù)的定義和調(diào)用函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的作用域和生存期編譯預(yù)處理多源文件C程序的組織方法第4章函數(shù)與程序結(jié)構(gòu)
變量的作用域是指其有效范圍。變量的生存期是指變量存在的時(shí)間。⑴一個(gè)變量在某個(gè)函數(shù)、某個(gè)源程序文件或某幾個(gè)源程序文件范圍內(nèi)是有效的,則稱(chēng)其有效的范圍為該變量的作用域,在此范圍內(nèi)可以訪(fǎng)問(wèn)或引用該變量。如果從變量的作用域角度來(lái)考慮,變量可分為全局變量和局部變量。⑵一個(gè)變量的值在某一時(shí)刻是存在的,則認(rèn)為這一時(shí)刻屬于該變量的“生存期”,或稱(chēng)其在此時(shí)刻“存在”。如果從變量的生存期來(lái)考慮,變量可分為靜態(tài)存儲(chǔ)變量和動(dòng)態(tài)存儲(chǔ)變量。4.3變量的作用域和生存期從變量作用域概念上將變量分為“全局變量”和“局部變量”兩類(lèi)。C語(yǔ)言使用extern和auto來(lái)表示變量的作用域?qū)傩浴?.全局變量指在所有函數(shù)之外定義的變量,全局變量也稱(chēng)為外部變量。其作用域(作用范圍)是從定義位置開(kāi)始直到本源文件結(jié)束為止。定義的一般形式如下:
[extern]<數(shù)據(jù)類(lèi)型符>變量表;定義全局變量時(shí)一般將extern省略。使用extern,目的是對(duì)程序中定義的全局變量進(jìn)行重新聲明,這種聲明方法的意義和使用方法牽涉到多源程序文件,將在4.5節(jié)中予以討論。在定義全局變量時(shí),也可以對(duì)其進(jìn)行初始化工作。如果在定義全局變量時(shí)沒(méi)有顯式初始化,C的編譯系統(tǒng)會(huì)自動(dòng)將其初始化為0(若是字符類(lèi)數(shù)據(jù)則初始化為’\0’)。4.3.1變量的作用域例4.18全局變量的作用域示例 /*Name:ex04-18.cpp*/2 #include<stdio.h>3 voidincrea();4 voidincreb();5 intx;6 voidmain()7 { x++;8 increa();9 increb();10 printf("x=%d\n",x); 11 }12 voidincrea()13 {14 x+=5;15 }16 voidincreb()17 {18 x-=2;19 }
程序在第5行定義了整型變量,由于變量x定義在所有函數(shù)的外面,所以變量x是全局變量,其作用范圍(作用域)從第5行開(kāi)始至第19行結(jié)束。同時(shí)由于在定義全局變量x時(shí)沒(méi)有對(duì)其顯式初始化。該程序運(yùn)行的結(jié)果為:x=4。
程序演示4.3.1變量的作用域
全局變量X的作用范圍例全局變量的作用域示例 #include<stdio.h>charc1,c2;/*全局變量*/charf1(inta,intb)/*定義函數(shù)f1*/{inti,j;……}inta=5,b=10;/*全局變量*/intf2(intp)/*定義函數(shù)f2*/{intx=a,y=b;……}main()/*主函數(shù)*/{floata,b;/*ab為主函數(shù)內(nèi)的局部變量*/……}
c1、c2、a、b、雖然都是全局變量,但作用的范圍不一樣。c1、c2在開(kāi)始定義,所以在f1(),f2(),主函數(shù)內(nèi)都有效,而a、僅僅在f2(),主函數(shù)內(nèi)都有效。在主函數(shù)中又定義了2個(gè)局部變量a、b。這時(shí)全局變量不起作用。即當(dāng)全局變量和局部變量同名時(shí),在局部變量作用范圍內(nèi),全局變量不起作用。4.3.1變量的作用域全局變量ab的作用范圍全局變量c1c2的作用范圍例全局變量的使用實(shí)例 #include<stdio.h>intx=3,y=5;intmax(inta,intb){return(a>b?a:b);}main(){intx=8;printf(“max(%d,%d)=%d\n”,x,y,max(x,y));}輸出結(jié)果:max(8,5)=8思考:主函數(shù)中如果沒(méi)有intx=8,結(jié)果是多少?如果全局變量x=-3,結(jié)果又是多少?如果要將全局變量作用域擴(kuò)展到其他源文件,在變量定義前加exterm。例如extermintx=3,y=5;4.3.1變量的作用域2.局部變量指定義在函數(shù)內(nèi)部的變量,也稱(chēng)為自動(dòng)變量。局部變量的作用域有三個(gè),它們是:①函數(shù)形式參數(shù)表部分;②函數(shù)體內(nèi)部;③復(fù)合語(yǔ)句內(nèi)部{}。一般形式:[auto]<數(shù)據(jù)類(lèi)型符>變量表;auto類(lèi)型符是局部變量默認(rèn)的存儲(chǔ)類(lèi)型,一般省略。如果局部變量在定義時(shí)沒(méi)有對(duì)其進(jìn)行顯式的初始化則其初始值是隨機(jī)的數(shù)值。局部變量的建立和撤消都是系統(tǒng)自動(dòng)進(jìn)行的,如在某個(gè)函數(shù)中定義了自動(dòng)變量,只有當(dāng)這個(gè)函數(shù)被調(diào)用時(shí)系統(tǒng)才會(huì)為這些局部變量分配存儲(chǔ)單元;當(dāng)函數(shù)執(zhí)行完畢,程序控制流程離開(kāi)這個(gè)函數(shù)時(shí),自動(dòng)變量被系統(tǒng)自動(dòng)撤銷(xiāo),其所占據(jù)的存儲(chǔ)單元被系統(tǒng)自動(dòng)收回。4.3.1變量的作用域例4.19局部變量在函數(shù)調(diào)用時(shí)的特征示例。/*Name:ex04-19.cpp*/#include<stdio.h>voidmain(){ intincre(); printf("x=%d\n",incre()); printf("x=%d\n",incre());}intincre(){intx=20; x+=5; returnx;}函數(shù)incre在第一次被調(diào)用時(shí),會(huì)創(chuàng)建局部變量x并賦初值為20,然后對(duì)其進(jìn)行加5的操作并將結(jié)果25返回到主函數(shù)中輸出(注意:隨著函數(shù)執(zhí)行完成后控制流程的返回,函數(shù)中定義的局部變量(自動(dòng)變量)x被系統(tǒng)自動(dòng)撤銷(xiāo))。當(dāng)函數(shù)incre第二次被調(diào)用時(shí),會(huì)重新創(chuàng)建局部變量x并賦初值為20,然后對(duì)其進(jìn)行加5的操作并將結(jié)果25返回到主函數(shù)中輸出,所以程序執(zhí)行的結(jié)果為:x=25x=25⑴函數(shù)的每次調(diào)用都是使用不同局部變量組。程序演示4.3.1變量的作用域⑵局部變量即使名字相同,互相也無(wú)關(guān)系。例4.20編制程序輸出如下所示的字符圖形(每行15個(gè)星號(hào),共輸出5行)。***************************************************************************圖4.15字符圖形/*Name:ex04-20.cpp*/#include<stdio.h>voidmain(){ voidmyprint(); inti; for(i=0;i<5;i++) myprint();}voidmyprint(){ inti; for(i=0;i<15;i++) putchar('*'); printf("\n");}程序演示4.3.1變量的作用域局部變量i的作用范圍局部變量i的作用范圍局部變量只在本函數(shù)或本復(fù)合語(yǔ)句內(nèi)才能使用,main()函數(shù)也不例外,主函數(shù)main定義了變量a,b,只在主函數(shù)有效,c在復(fù)合語(yǔ)句內(nèi)有效,在主函數(shù)其他地方無(wú)效?!?main(){floata,b;
……{floatc;c=a*b;
……}}4.3.1變量的作用域局部變量C的作用范圍局部變量a、b的作用范圍3.同名全局變量與局部變量作用域重疊問(wèn)題在某些特定的情況下,可能會(huì)出現(xiàn)全局變量和局部變量同名,C規(guī)定按“定義就近原則”來(lái)使用的變量。⑴在函數(shù)中如果定義有與全局變量同名的局部變量,則當(dāng)程序的控制流程進(jìn)入到函數(shù)的作用范圍時(shí),程序使用在函數(shù)內(nèi)部(包括形式參數(shù)表和函數(shù)體)定義的局部同名變量。⑵在程序的一個(gè)更小局部范圍(復(fù)合語(yǔ)句)中如果定義有與較大范圍(函數(shù)局部或全局)變量同名的變量,則當(dāng)程序的控制流程進(jìn)入到這個(gè)小的(復(fù)合語(yǔ)句)局部范圍時(shí),使用在該小局部范圍內(nèi)所定義的局部同名變量;4.3.1變量的作用域intx;voidmain(){ x++; …}voidf1(){intx=1;{intx=2;x++;}x++;}voidf2(){x++;…}全局變量x的作用域圖4.16全局變量與局部變量作用域重疊示意圖復(fù)合語(yǔ)句內(nèi)部定義的局部變量x的作用域①函數(shù)內(nèi)部定義的局部變量x的作用域②③4.3.1變量的作用域例3-26程序的執(zhí)行結(jié)果為(注意輸出順序): 復(fù)合語(yǔ)句中:x=20主函數(shù)中:x=10函數(shù)f1中:x=0 /*全局變量x沒(méi)有顯式初始化,默認(rèn)的初始化值為0*/程序演示4.3.1變量的作用域
變量的生存期即是指變量存在的時(shí)間。從變量的生存期來(lái)看,變量可以分為靜態(tài)存儲(chǔ)變量和動(dòng)態(tài)存儲(chǔ)變量。數(shù)據(jù)的這種存儲(chǔ)方法稱(chēng)之為變量的存儲(chǔ)類(lèi)型。靜態(tài)存儲(chǔ)變量:程序運(yùn)行時(shí)分配固定存儲(chǔ)空間的變量;動(dòng)態(tài)存儲(chǔ)變量:在程序運(yùn)行期間,根據(jù)需要進(jìn)行動(dòng)態(tài)的分配存儲(chǔ)空間的變量。動(dòng)態(tài)存儲(chǔ)變量能夠提高內(nèi)存的使用效率。4.3.2變量的生存期用戶(hù)區(qū)程序區(qū)靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)存儲(chǔ)區(qū)變量的存儲(chǔ)區(qū)存放全局變量、局部變量函數(shù)形參變量、局部變量等一個(gè)完整的變量定義格
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 7948-2024滑動(dòng)軸承塑料軸套極限PV試驗(yàn)方法
- 受眾定向技術(shù)行業(yè)經(jīng)營(yíng)分析報(bào)告
- 芯片讀卡器產(chǎn)品供應(yīng)鏈分析
- 電壓力鍋高壓鍋市場(chǎng)發(fā)展前景分析及供需格局研究預(yù)測(cè)報(bào)告
- 手機(jī)游戲開(kāi)發(fā)行業(yè)經(jīng)營(yíng)分析報(bào)告
- 皮制錢(qián)包項(xiàng)目運(yùn)營(yíng)指導(dǎo)方案
- 室內(nèi)裝潢的消毒行業(yè)市場(chǎng)調(diào)研分析報(bào)告
- 玻璃鋼軸流風(fēng)機(jī)項(xiàng)目營(yíng)銷(xiāo)計(jì)劃書(shū)
- 坐便器產(chǎn)業(yè)鏈招商引資的調(diào)研報(bào)告
- 斷布機(jī)產(chǎn)品供應(yīng)鏈分析
- 4.4.1 對(duì)數(shù)函數(shù)的概念 課時(shí)教學(xué)設(shè)計(jì)
- 2023屆高考寫(xiě)作指導(dǎo):漫畫(huà)作文 課件24張
- YS/T 1022-2015偏釩酸銨
- GB/T 9574-2001橡膠和塑料軟管及軟管組合件試驗(yàn)壓力、爆破壓力與設(shè)計(jì)工作壓力的比率
- 馬工程《刑法學(xué)(下冊(cè))》教學(xué)課件 第19章 破壞社會(huì)主義市場(chǎng)經(jīng)濟(jì)秩序罪
- GB/T 1740-2007漆膜耐濕熱測(cè)定法
- 校園突發(fā)事件及危機(jī)應(yīng)對(duì)
- 《必修上第六單元》教案【高中語(yǔ)文必修上冊(cè)】
- 立體構(gòu)成的基本要素及形式美法則備課講稿課件
- 廣東省房屋建筑工程概算定額說(shuō)明及計(jì)算規(guī)則樣本
- 汽車(chē)文化知識(shí)考試參考題庫(kù)400題(含答案)
評(píng)論
0/150
提交評(píng)論