函數(shù)與編譯預處理_第1頁
函數(shù)與編譯預處理_第2頁
函數(shù)與編譯預處理_第3頁
函數(shù)與編譯預處理_第4頁
函數(shù)與編譯預處理_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第六章函數(shù)與編譯預處理

6.1模塊化程序設(shè)計與函數(shù)6.2函數(shù)的定義與調(diào)用6.3函數(shù)的遞歸調(diào)用6.4變量作用域與存儲方式

6.5編譯預處理6.6函數(shù)設(shè)計舉例

C語言程序設(shè)計

函數(shù)與編譯預處理

C語言程序設(shè)計

函數(shù)與編譯預處理

模塊化程序設(shè)計求解較小問題的算法和程序稱作“功能模塊”?;舅枷耄簩⒁粋€大的程序按功能分割成一些小模塊特點:各模塊相對獨立、功能單一、結(jié)構(gòu)清晰、接口簡單控制了程序設(shè)計的復雜性提高元件的可靠性縮短開發(fā)周期避免程序開發(fā)的重復勞動易于維護和功能擴充開發(fā)方法:自上向下,逐步分解,分而治之6.1模塊化程序設(shè)計與函數(shù)

C語言程序設(shè)計

函數(shù)與編譯預處理模塊與函數(shù)

C語言程序由基本語句和函數(shù)組成,每個函數(shù)可完成相對獨立的任務,依一定的規(guī)則調(diào)用這些函數(shù),就組成了解決某個特定問題的程序。把大任務分解成若干功能模塊,用多個函數(shù)來實現(xiàn)這些功能模塊。通過函數(shù)的調(diào)用來實現(xiàn)完成大任務的全部功能。任務、模塊與函數(shù)的關(guān)系:

一個大任務分成多個功能模塊,功能模塊則由一個或多函數(shù)實現(xiàn)。模塊化的程序設(shè)計是靠設(shè)計函數(shù)和調(diào)用函數(shù)實現(xiàn)的。

C語言程序設(shè)計

函數(shù)與編譯預處理例ex1.c:分數(shù)排序任務:輸入三個數(shù),從大到小的順序的輸出。如果大于等于85,在該數(shù)后面輸出‘A’,

小于85且大于等于70,則輸出‘B’,

小于70且大于等于60,輸出‘C’,

如果小于60,則輸出‘D’。思路:輸入分數(shù)

排序

判斷并輸出等級

C語言程序設(shè)計

函數(shù)與編譯預處理

voidsortabc(floata,floatb,floatc){floatt;

if(a<b){t=a;a=b;b=t;}/*交換a,和b的值*/

if(b<c){t=b;b=c;c=t;}/*交換b,和c的值*/

if(a<b){t=a;a=b;b=t;}/*交換a,和b的值*/}

scanf("%f,%f,%f",&a,&b,&c);

C語言程序設(shè)計

函數(shù)與編譯預處理(1)/*輸入*/(2)/*排序*/

chargrade(floatx){if(x>=85)

return('A');

elseif(x>=70)

return('B');else

if(x>=60)

return('C');else

return('D');

}(3)/*判斷并輸出等級*/

C語言程序設(shè)計

函數(shù)與編譯預處理/*根據(jù)x的值,得到等級標準*//*判別等級并輸出*/

voidputabc(floata,floatb,floatc){charg;g=grade(a);

printf("%6.1f:%c",a,g);g=grade(b);

printf("%6.1f:%c",b,g);g=grade(c);

printf("%6.1f:%c",c,g);}

voidmain(){floata,b,c;

scanf("%f,%f,%f",&a,&b,&c);/*輸入*/

sortabc(a,b,c);/*排序*/

putabc(a,b,c);/*分等級并輸出a,b,c三個數(shù)*/}

C語言程序設(shè)計

函數(shù)與編譯預處理/*主函數(shù)*/模塊設(shè)計的原則模塊獨立規(guī)模適當層次分明功能專一

C語言程序設(shè)計

函數(shù)與編譯預處理獨立性原則表現(xiàn)在模塊完成獨立的功能,和其它模塊間的關(guān)系簡單,各模塊可以單獨調(diào)試。修改某一模塊,不會造成整個程序的混亂。每個模塊完成一個相對獨立的特定子功能。在對任務逐步分解時,要注意對問題的綜合。例如,一些模塊的相似的子任務,可以把它們綜合起來考慮,找出它們的共性,把它們做成一個完成特定任務的單獨模塊。每個模塊有特定功能1、模塊獨立

C語言程序設(shè)計

函數(shù)與編譯預處理模塊之間最好只通過數(shù)據(jù)傳遞發(fā)生聯(lián)系,而不發(fā)生控制聯(lián)系。例如,C語言禁止goto語句作用到另一個函數(shù),就是為了保證函數(shù)的獨立性。每個模塊力求簡單模塊內(nèi)使用的數(shù)據(jù),對于不需要這些數(shù)據(jù)的其它模塊來說,應該不允許使用;在一個模塊內(nèi)的變量的修改不會影響其它模塊的數(shù)據(jù)。即模塊的私有數(shù)據(jù)只屬于這個模塊。C語言的局部變量,就是滿足模塊獨立的的需要。每個模塊應用獨立變量

C語言程序設(shè)計

函數(shù)與編譯預處理

模塊不能太大,但也不能太小。模塊的功能復雜,可讀性就不好,而且也違背獨立性原則。但如果做得太小,實際上也會復雜各個模塊間反復調(diào)用,可讀性也會降低。這點需要慢慢積累經(jīng)驗,好好把握。2、規(guī)模適當3、層次分明要多層次的分解任務,注意對問題進行抽象化

C語言程序設(shè)計

函數(shù)與編譯預處理算法簡介什么是算法?通俗地說,算法是解決一類特定問題的方法和步驟。算法是一個有限操作的序列。算法的每一步都是確定的。算法的每一步計算機都能操作。有一個或多個的輸入或輸出。

C語言程序設(shè)計

函數(shù)與編譯預處理6.2函數(shù)的定義與調(diào)用

在C語言中,函數(shù)(Function)是一個處理過程,可以進行數(shù)值運算、信息處理、控制決策,即一段程序的工作放在函數(shù)中進行,函數(shù)結(jié)束時可以攜帶或不帶處理結(jié)果。從用戶使用函數(shù)的角度,函數(shù)有兩種:

庫函數(shù)(標準函數(shù)):系統(tǒng)提供

自定義函數(shù):用戶自己寫

從函數(shù)的形式看,函數(shù)分兩類:

無參函數(shù)、有參函數(shù)

注:C語言程序處理過程全部都是以函數(shù)形式出現(xiàn),最簡單的程序至少也有一個main函數(shù)。函數(shù)必須先定義和聲明后才能調(diào)用。

C語言程序設(shè)計

函數(shù)與編譯預處理標準庫函數(shù)

C語言有豐富的庫函數(shù),按功能分為:類型轉(zhuǎn)換函數(shù)、字符判別與轉(zhuǎn)換函數(shù)、字符串處理函數(shù)、標準I/O函數(shù)、文件管理函數(shù)、數(shù)學運算函數(shù),這些函數(shù)的說明在不同的頭文件(*.h)中。想要調(diào)用標準的庫函數(shù),就必須include。

main()

{{putchar(‘a(chǎn)’);}

}

C語言程序設(shè)計

函數(shù)與編譯預處理調(diào)用putchar函數(shù)時,

必須include<stdio.h>#include<stdio.h>

C語言程序設(shè)計

函數(shù)與編譯預處理一般格式合法標識符函數(shù)類型函數(shù)名(形參類型說明表){

說明部分 語句部分}函數(shù)的定義把完成一個子任務程序?qū)懗梢粋€函數(shù)函數(shù)返回值類型缺省int型無返回值void函數(shù)體

C語言程序設(shè)計

函數(shù)與編譯預處理intmax(intx1,intx2,intx3)/*定義函數(shù)的返回值類型,函數(shù)名,形參*/{intmax;if(x1>x2)max=x1;elsemax=x2;if(max<x3)max=x3;/*通過比較得到三個數(shù)的最大值放到max中*/

return(max);/*返回運算結(jié)果*/} 【例】編寫函數(shù),求三個整型參數(shù)的最大值。

函數(shù)分為兩大部分:1.函數(shù)的說明部分(函數(shù)首部)。2.函數(shù)體部分。

C語言程序設(shè)計

函數(shù)與編譯預處理1.函數(shù)的說明部分

函數(shù)的說明部分包括函數(shù)的類型、函數(shù)名、參數(shù)表及參數(shù)類型的說明。(1)函數(shù)的類型。函數(shù)的類型即函數(shù)的返回值類型。說明函數(shù)將給調(diào)用者提供什么類型的返回值。如果函數(shù)不提供返回值,可以定義函數(shù)類型為空??疹愋偷臉俗R符:void

例:voidputdata(inta)函數(shù)的返回值可以是任何一種數(shù)據(jù)類型,但不能是數(shù)組型。當返回值類型被省略時,默認為int型。函數(shù)的返回值將由return(表達式)語句返回給調(diào)用者(即調(diào)用這個函數(shù)的另一個函數(shù)),表達式的值即是函數(shù)的返回值。(2)函數(shù)名函數(shù)又稱為函數(shù)標識符。對自定義函數(shù),其命名遵循C語言標識符的規(guī)定。(3)參數(shù)表參數(shù)表寫在函數(shù)后的括號“()”內(nèi),參數(shù)表由一個或多個變量標識符及類型標識符組成。參數(shù)表中的變量也稱為形式參數(shù),簡稱為形參。如果沒有形參,稱作無參數(shù)函數(shù),無參數(shù)函數(shù)的括號“()”不能省略。例有參函數(shù)

intmax(intx,inty){intz;z=x>y?x:y;return(z);}例有參函數(shù)

intmax(intx,y){intz;z=x>y?x:y;return(z);}例無參函數(shù)

printstar(){printf(“**********\n”);}或

printstar(void){printf(“**********\n”);}

C語言程序設(shè)計

函數(shù)與編譯預處理2.函數(shù)體

函數(shù)定義的花括號“{}”里的部分是函數(shù)體,包括變量定義、執(zhí)行語句序列。函數(shù)所完成的工作在函數(shù)體中由一段程序完成。

例空函數(shù)

dummy(){}函數(shù)體為空如果函數(shù)有返回值,則需要返回語句return.

C語言程序設(shè)計

函數(shù)與編譯預處理函數(shù)的返回值返回語句形式:return(表達式);

或:

return表達式;

或:

return;執(zhí)行時先計算出括號中表達式的值,再將該值返回給主調(diào)函數(shù)中的調(diào)用表達式。功能:使程序控制從被調(diào)用函數(shù)返回到調(diào)用函數(shù)中,同時把返值帶給調(diào)用函數(shù)說明:

函數(shù)中可有多個return語句,執(zhí)行到哪個return語句,那個語句起作用

若無return語句,遇到函數(shù)結(jié)束的“}”時,自動返回調(diào)用函數(shù)

C語言程序設(shè)計

函數(shù)與編譯預處理例:計算表達式的值

x2-x+1(x<0)x3+x+3(x>0)

Y=floaty(floatx){if(x<0)return(x*x-x+1);elsereturn(x*x*x+x+3);}在定義函數(shù)是對函數(shù)值說明的類型一般應該與return語句中的表達式類型一致。若函數(shù)類型與return語句中表達式值的類型不一致,按前者為準,自動轉(zhuǎn)換------函數(shù)調(diào)用轉(zhuǎn)換,即函數(shù)類型決定返回值的類型例如,

intf(){

floatf=7;

f/=2;

returnf;}注意:如果不將函數(shù)調(diào)用賦值給任何變量,它的返回值將被丟棄。函數(shù)返回值為:3,而不是3.5

C語言程序設(shè)計

函數(shù)與編譯預處理如果被調(diào)用函數(shù)中沒有return語句,并不帶回一個確定的、用戶所希望得到的函數(shù)值,但實際上,函數(shù)并不是不帶回值,只是不帶回有用的值,帶回的是一個不確定的值。例:printstar(){printf(“****************\n”);}

盡管沒有要求printstar函數(shù)帶回值,但如果程序中出現(xiàn)下面的語句是合法的:

a=printstar();/*輸出*****************/

printf(“%d”,a);/*輸出16*/

注:a的值不一定有實際意義(printstar函數(shù)輸出16個字符,返回值是16)

C語言程序設(shè)計

函數(shù)與編譯預處理為了明確表示“不帶回值”,可以用“void”定義“無類型”(或稱“空類型”)即void型函數(shù):無返回值的函數(shù)

例:voidprintstar(){printf(“***********”);}

這樣,系統(tǒng)保證不帶回任何值,即禁止在調(diào)用函數(shù)中使用被調(diào)函數(shù)的返回值。此時,若有:

a=printstar();

編譯時會給出錯信息。注:一般,凡不要求帶回函數(shù)值的函數(shù),應定義為void類型例無返回值函數(shù)

voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}

C語言程序設(shè)計

函數(shù)與編譯預處理函數(shù)的調(diào)用

一個c程序有一個主函數(shù)和多個函數(shù)組成。主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可相互調(diào)用。

C語言的函數(shù)調(diào)用遵循先定義,后引用的原則。如果對某函數(shù)的調(diào)用出現(xiàn)在該函數(shù)定義之前,必須用說明語句對函數(shù)進行聲明。

C語言程序設(shè)計

函數(shù)與編譯預處理1.函數(shù)的聲明

在函數(shù)如果要調(diào)用某一已經(jīng)定義了的函數(shù)時,一般還應在主調(diào)函數(shù)中對被調(diào)函數(shù)進行聲明(說明)。作用:告知編譯程序本函數(shù)將要調(diào)用某個函數(shù),并告知相關(guān)信息(函數(shù)類型、函數(shù)名、參數(shù)個數(shù)、參數(shù)類型)函數(shù)聲明語句的形式:

函數(shù)類型名函數(shù)名(參數(shù)類型說明列表)或

函數(shù)類型名函數(shù)名();

C語言程序設(shè)計

函數(shù)與編譯預處理例ex2.c函數(shù)聲明舉例

C語言程序設(shè)計

函數(shù)與編譯預處理main()

{floata,b,c;

scanf("%f,%f",&a,&b);c=add(a,b);

printf("sumis%f",c);}floatadd(floatx,floaty){floatz;z=x+y;return(z);}定義add函數(shù)對被調(diào)用的add函數(shù)作聲明floatadd(floatx,floaty);/*functiondeclaration*/函數(shù)聲明與函數(shù)定義的區(qū)別:

函數(shù)定義是用來建立和實現(xiàn)函數(shù)的功能,包括指定函數(shù)名、函數(shù)值類型、形參及其類型、函數(shù)體等,是一個完整的、獨立的單位。函數(shù)聲明的作用是把函數(shù)的名字、函數(shù)類型、形參的類型、個數(shù)、順序通知編譯系統(tǒng),以便在調(diào)用該函數(shù)時系統(tǒng)按此進行對照檢查,它僅僅給出函數(shù)的類型、函數(shù)名及其參數(shù)的類型。

注:函數(shù)聲明可寫為:函數(shù)首部:

C語言程序設(shè)計

函數(shù)與編譯預處理

C語言程序設(shè)計

函數(shù)與編譯預處理在函數(shù)聲明中也可以不寫形參名,只寫形參的類型,但參數(shù)類型、次序和數(shù)目必須一致floatadd(float,float);下列情況下,可不作函數(shù)聲明被調(diào)用函數(shù)定義出現(xiàn)在主調(diào)函數(shù)之前,即先定義后調(diào)用;floatadd(floatx,floaty){floatz;z=x+y;return(z);}main(){floata,b,c;

scanf("%f,%f",&a,&b);c=add(a,b);

printf("sumis%f",c);}被調(diào)函數(shù)出現(xiàn)在主調(diào)函數(shù)之前,不必函數(shù)聲明Ex3.c已在所有函數(shù)定義之前,在函數(shù)外部作了聲明,則在各個主調(diào)函數(shù)中不必對所調(diào)用的函數(shù)再作聲明)(例ex1.c)

C語言程序設(shè)計

函數(shù)與編譯預處理charletter(char,char);floatf(float,float);intg(float,float);main(){……}charletter(charch1,charch2){……}floatf(floatx,floaty){……}intg(floatj,floatk){……}已在所有函數(shù)定義之前,在函數(shù)外部作了聲明函數(shù)聲明位置:程序的數(shù)據(jù)說明部分(函數(shù)內(nèi)或外);若函數(shù)返值是型或void型事實上,int型函數(shù)定義之前使用也必須作函數(shù)聲明,否則系統(tǒng)不知max(a,b)是函數(shù),形參的值無法傳給實參,結(jié)果出錯

C語言程序設(shè)計

函數(shù)與編譯預處理main(){

floata,b;

intc;scanf("%f,%f",&a,&b);c=max(a,b);printf("Maxis%d\n",c);}max(floatx,floaty){floatz;z=x>y?x:y;return(z);}Ex4.cintmax(floatx,floaty);

C語言程序設(shè)計

函數(shù)與編譯預處理2、函數(shù)的調(diào)用

函數(shù)調(diào)用的一般形式:有參函數(shù)調(diào)用形式:

函數(shù)名(實參表)無參函數(shù)調(diào)用形式:函數(shù)名()函數(shù)調(diào)用的方式:函數(shù)語句:函數(shù)調(diào)用可單獨成為一個語句例output();

printf(“Hello,World!\n”);

函數(shù)表達式:調(diào)用函數(shù)后的返回值可參加表達式的計算,這時要求被調(diào)函數(shù)帶返回值。例sum=add(a,b);c=fac(n)/(fac(k)*fac(n-k));

函數(shù)參數(shù):帶返回值的函數(shù)調(diào)用亦可作為其它函數(shù)的參數(shù)(實際參數(shù))例printf(“%d”,max(a,b));m=max(a,max(b,c));在主調(diào)函數(shù)中調(diào)用一個函數(shù)時,函數(shù)名后面括號中的參數(shù)(可以是常量、變量、表達式)調(diào)用函數(shù)的過程是:

為函數(shù)的所有形參分配內(nèi)存單元。計算各個實參表達式的值,一一對應的賦值給相應形參(若是無參函數(shù),上述過程不執(zhí)行)。

進入函數(shù)體,執(zhí)行函數(shù)中的語句,實現(xiàn)函數(shù)的功能執(zhí)行到return語句時,計算return語句中表達式的值(若是無返回值函數(shù),本項不做),返回到主調(diào)函數(shù)。

釋放形參及本函數(shù)內(nèi)的局部變量所占內(nèi)存,繼續(xù)執(zhí)行主調(diào)函數(shù)中的后繼語句。

C語言程序設(shè)計

函數(shù)與編譯預處理

C語言程序設(shè)計

函數(shù)與編譯預處理C語言中,函數(shù)調(diào)用是值傳遞方式,即函數(shù)的實際參數(shù)和形式參數(shù)之間的數(shù)據(jù)傳遞方向是單向的,只能由實際參數(shù)傳遞給形式參數(shù),而不能由形式參數(shù)傳遞給實際參數(shù),是實際參數(shù)向形式參數(shù)單向賦值的關(guān)系。在內(nèi)存中,形式參數(shù)與實際參數(shù)占用不同的內(nèi)存單元。當調(diào)用函數(shù)時,給形式參數(shù)分配內(nèi)存單元,將實際參數(shù)的值賦值給形式參數(shù),調(diào)用后,形式參數(shù)單元釋放,實際參數(shù)仍保留調(diào)用前的值,形式參數(shù)值的變化不影響實際參數(shù)。函數(shù)參數(shù)及其傳遞方式形式參數(shù):定義函數(shù)時函數(shù)名后面括號中的變量名實際參數(shù):調(diào)用函數(shù)時函數(shù)名后面括號中的表達式

C語言程序設(shè)計

函數(shù)與編譯預處理c=max(a,b);(main函數(shù))(max函數(shù))max(intx,inty){intz;z=x>y?x:y;return(z);}例ex4.c比較兩個數(shù)并輸出大者main(){intmax(intx,inty);

inta,b,c;

scanf("%d,%d",&a,&b);c=max(a,b);

printf("Maxis%d",c);}max(intx,inty){intz;z=x>y?x:y;return(z);}形參實參

C語言程序設(shè)計

函數(shù)與編譯預處理

說明:實參必須有確定的值,形參必須指定類型形參與實參類型一致,個數(shù)相同,按順序一一對應

若形參與實參類型不一致,自動按形參類型轉(zhuǎn)換———函數(shù)調(diào)用轉(zhuǎn)換(按不同類型數(shù)據(jù)的賦值規(guī)則進行轉(zhuǎn)換)

形參在函數(shù)被調(diào)用前不占內(nèi)存;函數(shù)調(diào)用時為形參分配內(nèi)存;調(diào)用結(jié)束,內(nèi)存釋放

C語言程序設(shè)計

函數(shù)與編譯預處理例ex5.c計算x的立方#include<stdio.h>floatcube(floatx){return(x*x*x);}main(){floata,product;

printf("Pleaseinputvalueofa:");

scanf("%f",&a);product=cube(a);

printf(”Cubeof%.4fis%.4f\n",a,product);}xaproduct××××28

C語言程序設(shè)計

函數(shù)與編譯預處理參數(shù)傳遞方式

值傳遞方式方式:函數(shù)調(diào)用時,為形參分配單元,并將實參的值復制到形參中;調(diào)用結(jié)束,形參單元被釋放,實參單元仍保留并維持原值特點:

形參與實參占用不同的內(nèi)存單元單向傳遞

地址傳遞方式方式:函數(shù)調(diào)用時,將數(shù)據(jù)的存儲地址作為參數(shù)傳遞給形參,當然此時的行參只能是能存儲地址的變量(指針變量)。

特點:雙向傳遞

C語言程序設(shè)計

函數(shù)與編譯預處理35a:b:調(diào)用前:調(diào)用結(jié)束:35a:b:例ex6.c交換兩個數(shù)#include<stdio.h>main(){inta=3,b=5;

printf(“a=%d,\tb=%d\n",a,b);

printf("swapped:\n");

swap(a,b);

printf(“a=%d,\tb=%d\n",a,b);}swap(intx,inty){inttemp;temp=x;x=y;y=temp;}調(diào)用35x:y:35a:b:swap:temp35a:b:x:35y:

C語言程序設(shè)計

函數(shù)與編譯預處理main(){inti=2,p;p=f(i,++i);

printf("%d",p);}intf(inta,intb){intc;if(a>b)c=1;elseif(a==b)c=0;elsec=-1;return(c);}例ex7.c參數(shù)求值順序main(){inti=2,p;p=f(i,i++);

printf("%d",p);}intf(inta,intb){intc;if(a>b)c=1;elseif(a==b)c=0;elsec=-1;return(c);}運行結(jié)果:0運行結(jié)果:1實參的求值順序不確定,因系統(tǒng)而定(TurboC自右向左)

3.函數(shù)的嵌套調(diào)用

在某函數(shù)體中調(diào)用了另一個函數(shù),則在該函數(shù)被調(diào)用的過程中將發(fā)生另一次函數(shù)調(diào)用。這種調(diào)用現(xiàn)象稱為函數(shù)的嵌套調(diào)用。

intf1(){…

}

intf2(){…f1();

}

voidmain()

{…

f2();}f2()f1()main()f2()f1()

C語言程序設(shè)計

函數(shù)與編譯預處理例ex8.c編程求組合Cnm=m!/n!(m-n)!longfac(intk)

/*定義求階乘的函數(shù)*/{longf=1;

inti;for(i=1;i<=k;i++)f=f*i;returnf;}longcomb(intm,intn)/*定義組合函數(shù)*/{longc;c=fac(m)/(fac(n)*fac(m-n));/*嵌套調(diào)用階乘函數(shù)*/returnc;}main(){intn,m;longc;scanf(“%d,%d”,&m,&n);c=comb(m,n);/*調(diào)用組合函數(shù)*/printf(“%ld”,c);}#include<stdio.h>

longsum(inta,intb);longfactorial(intn);main(){intn1,n2;longa;scanf("%d,%d",&n1,&n2);a=sum(n1,n2);

printf("a=%1d",a);}longsum(inta,intb){longc1,c2;c1=factorial(a);c2=factorial(b);

return(c1+c2);}

longfactorial(intn){longrtn=1;

inti;for(i=1;i<=n;i++)

rtn*=i;

return(rtn);}longsum(inta,intb);longfactorial(intn);文件包含編譯預處理命令函數(shù)類型說明函數(shù)定義函數(shù)調(diào)用函數(shù)調(diào)用函數(shù)返回值形參實參Ex9.c實現(xiàn):任意給定的兩個數(shù)n1,n2,計算:n1!+n2!

C語言程序設(shè)計

函數(shù)與編譯預處理

6.3遞歸調(diào)用定義:函數(shù)直接或間接的調(diào)用自身叫函數(shù)的遞歸調(diào)用f()調(diào)f調(diào)f2調(diào)f1f1()f2()說明C編譯系統(tǒng)對遞歸函數(shù)的自調(diào)用次數(shù)沒有限制每調(diào)用函數(shù)一次,在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù)變量、返回值等信息,所以遞歸次數(shù)過多,可能引起堆棧溢出intf(intx){inty,z;……

z=f(y);…….return(2*z);}intf1(intx){inty,z;……

z=f2(y);…….return(2*z);}intf2(intt){inta,c;……

c=f1(a);…….return(3+c);}

C語言程序設(shè)計

函數(shù)與編譯預處理例ex10.c求n的階乘#include<stdio.h>int

fac(intn){intf;if(n<0)printf("n<0,dataerror!");elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}main(){intn,y;

printf("Inputaintegernumber:");

scanf("%d",&n);

y=fac(n);

printf("%d!=%15d",n,y);}

C語言程序設(shè)計

函數(shù)與編譯預處理

6.4變量的作用域和存儲類別內(nèi)存…….main(){inta;a=10;

printf(“%d”,a);}編譯或函數(shù)調(diào)用時為其分配內(nèi)存單元1020002001程序中使用變量名對內(nèi)存操作

C語言程序設(shè)計

函數(shù)與編譯預處理變量的屬性數(shù)據(jù)類型:變量所持有的數(shù)據(jù)的性質(zhì)(操作屬性)存儲屬性存儲器類型:寄存器、靜態(tài)存儲區(qū)、動態(tài)存儲區(qū)作用域:變量在某區(qū)域內(nèi)有效(空間角度)-------局部變量與全局變量生存期:變量值存在的時間(時間角度)-------靜態(tài)存儲方式與動態(tài)存儲方式變量的存儲類型auto-----自動型register-----寄存器型static------靜態(tài)型extern-----外部型變量定義格式:[存儲類型]數(shù)據(jù)類型變量表;如:intsum;

auto

inta,b,c;

register

inti;

staticfloatx,y;

C語言程序設(shè)計

函數(shù)與編譯預處理內(nèi)部變量---局部變量定義:在函數(shù)內(nèi)定義,只在本函數(shù)內(nèi)有效說明:main中定義的變量只在main中有效不同函數(shù)中同名變量,占不同內(nèi)存單元形參屬于局部變量可定義在復合語句中有效的變量局部變量可用存儲類型:autoregisterstatic(默認為auto)floatf1(inta){intb,c;…….}charf2(intx,inty){inti,j;……}main(){intm,n;…….}a,b,c有效x,y,i,j有效m,n有效

C語言程序設(shè)計

函數(shù)與編譯預處理復合語句中變量#defineN5main(){inti;

inta,b;

scanf(“%d,%d”,&a,&b);if(a<b)

{

inttemp; temp=a; a=b; b=temp;

}

printf("%d,%d",a,b);}例不同函數(shù)中同名變量main(){inta,b;a=3;b=4;

printf("main:a=%d,b=%d\n",a,b);sub();

printf("main:a=%d,b=%d\n",a,b);}sub(){inta,b;a=6;b=7;

printf("sub:a=%d,b=%d\n",a,b);}運行結(jié)果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4

C語言程序設(shè)計

函數(shù)與編譯預處理外部變量(全局變量)定義:在函數(shù)外面定義的變量。外部變量的作用域:對于只有一個源程序文件構(gòu)成的程序,外部變量的作用域是從定義它的位置開始,直至它所在源程序文件的結(jié)束。特點:外部變量的使用增加了函數(shù)之間傳遞數(shù)據(jù)的途徑,在外部變量的作用域內(nèi)的任何函數(shù)都能引用該外部變量,一個函數(shù)對外部變量的修改,能影響到其它引用這個變量的函數(shù);因此對外部變量的使用不當,會產(chǎn)生意外的錯誤。

C語言程序設(shè)計

函數(shù)與編譯預處理floatmax,min;floataverage(intn){inti;floatx;

scanf(“%f”,&x);max=min=x;for(i=2;i<n;i++){scanf(“%f”,&x);if(x>max)max=x;elseif(x<min)min=x;sum+=x;}return(sum/n);}main(){intn;floatave;

scanf(“%d”,&n);

ave=average(n);

printf("max=%6.2f\nmin=%6.2f\naverage=%6.2f\n",max,min,ave);}作用域maxmin

C語言程序設(shè)計

函數(shù)與編譯預處理inta=3,b=5;max(inta,intb){intc;c=a>b?a:b;return(c);}main(){inta=8;

printf(“a=%d\n,b=%d\n,max=%d\n",a,b,max(a,b));}外部變量與局部變量同名時,在內(nèi)部變量的作用域中,外部變量被屏蔽。例:

運行結(jié)果:a=8/*main中的a*/b=5/*全局變量的b*/max=8

C語言程序設(shè)計

函數(shù)與編譯預處理外部變量的作用域是從定義點到本文件結(jié)束。如果定義點之前的函數(shù)需要引用這些外部變量時,需要在函數(shù)內(nèi)對被引用的外部變量進行說明。外部變量說明的一般形式為:extern數(shù)據(jù)類型外部變量[,外部變量2……];注意:外部變量的定義和外部變量的說明是兩回事。外部變量的定義,必須在所有的函數(shù)之外,且只能定義一次。而外部變量的說明,出現(xiàn)在要使用該外部變量的函數(shù)內(nèi),而且可以出現(xiàn)多次。intp=1,q=5;floatf1(inta){intb,c;…….}intf3(){…..}charc1,c2;charf2(intx,inty){inti,j;……}main(){intm,n;…….}c1,c2的作用范圍p,q的作用范圍externcharc1,c2;c1,c2的作用范圍擴展后c1,c2的作用范圍擴展后externcharc1,c2;

C語言程序設(shè)計

函數(shù)與編譯預處理intglobal;/*定義*/externfloatx;

/*說明*/main(){intlocal; . . .}externintglobal;/*說明*/intnumber;/*定義*/func2(){ . . .}floatx;/*定義*/intnumber;/*定義*/func3(){externintglobal;/*說明*/ . . .}file1.cfile2.cfile3.c

對于多文件程序,在一個源文件中定義的外部變量還可以在其它的文件中使用,這時需要在使用它的文件中用extern進行說明,這樣的變量稱為程序級的變量。

C語言程序設(shè)計

函數(shù)與編譯預處理變量的存儲類別------動態(tài)存儲方式與靜態(tài)存儲方式動態(tài)存儲方式:程序運行期間根據(jù)需要進行動態(tài)的分配存儲空間的方式。動態(tài)存儲類別的變量當進入定義它的函數(shù)或復合語句時被分配存儲空間,當離開時所占內(nèi)存空間被釋放。靜態(tài)存儲方式:程序運行期間分配固定的存儲空間的方式。靜態(tài)存儲類別的變量在源程序編譯的時候被分配固定的存儲空間,從程序開始執(zhí)行到程序運行結(jié)束,一直占用該內(nèi)存空間,直至程序運行結(jié)束,才被釋放內(nèi)存空間。程序區(qū)靜態(tài)存儲區(qū)動態(tài)存儲區(qū)全局變量、局部靜態(tài)變量形參變量局部動態(tài)變量(autoregister)函數(shù)調(diào)用現(xiàn)場保護和返回地址等1.靜態(tài)存儲──靜態(tài)內(nèi)部變量(1)定義格式:static數(shù)據(jù)類型內(nèi)部變量表;(2)存儲特點1)靜態(tài)內(nèi)部變量屬于靜態(tài)存儲。在程序執(zhí)行過程中,即使所在函數(shù)調(diào)用結(jié)束也不釋放。換句話說,在程序執(zhí)行期間,靜態(tài)內(nèi)部變量始終存在,但其它函數(shù)是不能引用它們的。2)定義但不初始化,則自動賦以"0"(整型和實型)或'\0'(字符型);且每次調(diào)用它們所在的函數(shù)時,不再重新賦初值,只是保留上次調(diào)用結(jié)束時的值?。?)何時使用靜態(tài)內(nèi)部變量1)需要保留函數(shù)上一次調(diào)用結(jié)束時的值。2)變量只被引用而不改變其值。內(nèi)部變量的存儲類別

C語言程序設(shè)計

函數(shù)與編譯預處理2.動態(tài)存儲──自動局部變量(又稱自動變量)(1)定義格式:[auto]數(shù)據(jù)類型變量表;

(2)存儲特點1)自動變量屬于動態(tài)存儲方式。在函數(shù)中定義的自動變量,只在該函數(shù)內(nèi)有效;函數(shù)被調(diào)用時分配存儲空間,調(diào)用結(jié)束就釋放。在復合語句中定義的自動變量,只在該復合語句中有效;退出復合語句后,也不能再使用,否則將引起錯誤。2)定義而不初始化,則其值是不確定的。如果初始化,則賦初值操作是在調(diào)用時進行的,且每次調(diào)用都要重新賦一次初值。3)由于自動變量的作用域和生存期,都局限于定義它的個體內(nèi)(函數(shù)或復合語句),因此不同的個體中允許使用同名的變量而不會混淆。即使在函數(shù)內(nèi)定義的自動變量,也可與該函數(shù)內(nèi)部的復合語句中定義的自動變量同名。建議:系統(tǒng)不會混淆,并不意味著人也不會混淆,所以盡量少用同名自動變量!

C語言程序設(shè)計

函數(shù)與編譯預處理[例]自動變量與靜態(tài)局部變量的存儲特性。

voidauto_static(void){intvar_auto=0;/*自動變量:每次調(diào)用都重新初始化*/

staticintvar_static=0; /*靜態(tài)局部變量:只初始化1次*/

printf(“var_auto=%d,var_static=%d\n”,var_auto,var_static);++var_auto;++var_static;}main(){inti;for(i=0;i<5;i++)auto_static();}

C語言程序設(shè)計

函數(shù)與編譯預處理3.寄存器存儲──寄存器變量一般情況下,變量的值都是存儲在內(nèi)存中的。為提高執(zhí)行效率,C語言允許將局部變量的值存放到寄存器中,這種變量就稱為寄存器變量。定義格式如下:

register

數(shù)據(jù)類型變量表;(1)只有局部變量才能定義成寄存器變量,即全局變量不行。(2)對寄存器變量的實際處理,隨系統(tǒng)而異。例如,微機上的MSC和TC將寄存器變量實際當作自動變量處理。(3)允許使用的寄存器數(shù)目是有限的,不能定義任意多個寄存器變量。

C語言程序設(shè)計

函數(shù)與編譯預處理外部變量的存儲方式外部變量屬于靜態(tài)存儲方式:(1)靜態(tài)外部變量──只允許被本源文件中的函數(shù)引用其定義格式為:static數(shù)據(jù)類型外部變量表;;(2)非靜態(tài)外部變量──允許被其它源文件中的函數(shù)引用定義時缺省static關(guān)鍵字的外部變量,即為非靜態(tài)外部變量。其它源文件中的函數(shù),引用非靜態(tài)外部變量時,需要在引用函數(shù)所在的源文件中進行說明:extern數(shù)據(jù)類型外部變量表;注意:在函數(shù)內(nèi)的extern變量說明,表示引用本源文件中的外部變量!而函數(shù)外(通常在文件開頭)的extern變量說明,表示引用其它文件中的外部變量。

C語言程序設(shè)計

函數(shù)與編譯預處理靜態(tài)局部變量和靜態(tài)外部變量同屬靜態(tài)存儲方式,但兩者區(qū)別較大:(1)定義的位置不同。靜態(tài)局部變量在函數(shù)內(nèi)定義,靜態(tài)外部變量在函數(shù)外定義。(2)作用域不同。靜態(tài)局部變量屬于內(nèi)部變量,其作用域僅限于定義它的函數(shù)內(nèi);雖然生存期為整個源程序,但其它函數(shù)是不能使用它的。靜態(tài)外部變量在函數(shù)外定義,其作用域為定義它的源文件內(nèi);生存期為整個源程序,但其它源文件中的函數(shù)也是不能使用它的。(3)初始化處理不同。靜態(tài)局部變量,僅在第1次調(diào)用它所在的函數(shù)時被初始化,當再次調(diào)用定義它的函數(shù)時,不再初始化,而是保留上1次調(diào)用結(jié)束時的值。而靜態(tài)外部變量是在函數(shù)外定義的,不存在靜態(tài)內(nèi)部變量的“重復”初始化問題,其當前值由最近1次給它賦值的操作決定。

C語言程序設(shè)計

函數(shù)與編譯預處理務必牢記:把局部變量改變?yōu)殪o態(tài)內(nèi)部變量后,改變了它的存儲方式,即改變了它的生存期。把外部變量改變?yōu)殪o態(tài)外部變量后,改變了它的作用域,限制了它的使用范圍。因此,關(guān)鍵字“static”在不同的地方所起的作用是不同的。

C語言程序設(shè)計

函數(shù)與編譯預處理

C語言程序設(shè)計

函數(shù)與編譯預處理6.5編譯預處理作用:對源程序編譯之前做一些處理,生成擴展C

源程序種類宏定義#define文件包含#include條件編譯#if--#else--#endif等格式:“#”開頭占單獨書寫行語句尾不加分號

C語言程序設(shè)計

函數(shù)與編譯預處理如if(x==YES)printf(“correct!\n”);elseif(x==NO)printf(“error!\n”);展開后:if(x==1)printf(“correct!\n”);elseif(x==0)printf(“error!\n”);宏定義不帶參數(shù)宏定義一般形式:#define宏名[宏體]功能:用指定標識符(宏名)表示字符序列(宏體)宏展開:預編譯時,用宏體替換宏名---不作語法檢查如#defineYES1#defineNO0#definePI3.1415926#defineOUTprintf(“Hello,World”);定義位置:函數(shù)外面,通常寫在文件開頭、函數(shù)之前作用域:從定義命令到文件結(jié)束#undef可終止宏名作用域格式:

#undef宏名例#defineYES1main(){……..}#undefYES#defineYES0max(){……..}YES原作用域YES新作用域宏定義可嵌套,不能遞歸例#defineMAXMAX+10()引號中的內(nèi)容與宏名相同也不置換例#definePI3.14159printf(“2*PI=%f\n”,PI*2);宏展開:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論