第5章 函數(shù)課件_第1頁
第5章 函數(shù)課件_第2頁
第5章 函數(shù)課件_第3頁
第5章 函數(shù)課件_第4頁
第5章 函數(shù)課件_第5頁
已閱讀5頁,還剩71頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第5章函數(shù)

2012年6月21日星期四

2012-6-21

2012-6-212

結(jié)構(gòu)化程序設(shè)計(jì)方法,從程序?qū)崿F(xiàn)的角度看就是

模塊化程序設(shè)計(jì),就是將程序模塊化,即在程序

設(shè)計(jì)中通常將一個大的程序按功能進(jìn)行分割成一

些模塊,使每個模塊都成為功能單一、結(jié)構(gòu)清晰、

接口簡單、容易理解的小程序。在C語言中是通

過函數(shù)來實(shí)現(xiàn)模塊化程序設(shè)計(jì)的,即將那些較小

的功能單一的程序模塊稱之為函數(shù),通過對函數(shù)

的調(diào)用實(shí)現(xiàn)特定的功能。所以較大的C語言應(yīng)用

程序,往往是由多個函數(shù)組成的,每個函數(shù)分別

對應(yīng)各自的功能模塊,通過函數(shù)的定義把實(shí)現(xiàn)的

細(xì)節(jié)封閉起來,通過函數(shù)調(diào)用組合各種功能。

2012-6-213

c語言提供以下一些功能來支持模塊化軟件開發(fā):

(1)函數(shù)式的程序結(jié)構(gòu)。程序整體由一個或多個

函數(shù)組成。

(2)允許通過使用不同存儲類別的變量,控制模

塊內(nèi)部及外部的信息交換。

(3)具有編譯預(yù)處理功能,為程序的調(diào)試、移植

提供了方便。

2012-6-214

5.1函數(shù)概述

用C語言設(shè)計(jì)程序來求解任何一個問題時,主要任務(wù)

就是編寫函數(shù)。

進(jìn)行C程序設(shè)計(jì)時一般采用自頂向下、逐步細(xì)化的

方法設(shè)計(jì)程序結(jié)構(gòu),即先集中考慮main函數(shù)中的算法。

當(dāng)main函數(shù)中需要使用某一功能時,就先寫上一個調(diào)用

具有該功能的函數(shù)的表達(dá)式。這時只需知道函數(shù)具有什

么功能,如何與程序通信(輸入什么,輸出什么),函

數(shù)的具體實(shí)現(xiàn)先不去處理。設(shè)計(jì)完main()函數(shù)的算法并

檢驗(yàn)無誤后,再開始考慮它所調(diào)用函數(shù)的具體實(shí)現(xiàn)。在

這些被調(diào)用的函數(shù)中,若在庫函數(shù)中可以找到,那就直

接使用,否則就動手設(shè)計(jì)這些函數(shù)。

2012-6-215

【例5.1】分別求兩個長方形的面積。

分析:采用模塊化程序設(shè)計(jì)的思想,將計(jì)算長方形面積的

代碼段提煉出來,寫成函數(shù),當(dāng)需要這段代碼時,就調(diào)

用該函數(shù)。

include<stdio.h>

intmain()/*先設(shè)計(jì)main函數(shù)*/

(

inta,b,c,d,s1,s2;

printf("Pleaseinputthewidthandtheheight(two

rectangular):");

nn

scanf(%d%d%d%d,&a5&b,&c,&d);/*調(diào)用輸入庫函數(shù)*

s1=area(a,b);/*調(diào)用自定義函數(shù)area*/

s2=area(c,d);/*再次調(diào)用自定義函數(shù)area*/

printf("theareaofthefirstrectangularis%d\nH,s1);

printf("theareaofthesecondrectangularis%d",s2);

return0;"

-2012-6-216

intarea(intx,inty)/*再設(shè)計(jì)自定義函數(shù)area7

(

intz;

z=x*y;

returnz;

)

由此可以看出,在c程序設(shè)計(jì)中使用函數(shù)可以

減少重復(fù)編寫程序的工作量,使程序便于調(diào)試

和閱讀。

2012-6-217

5.2函數(shù)的分類

C語言中可從不同的角度給函數(shù)分類。

1.從函數(shù)定義的角度

(1)庫函數(shù)

由C系統(tǒng)提供,用戶無須定義,也不必在程序中

作類型說明,只需在程序前包含有該函數(shù)原型的

頭文件即可在程序中直接調(diào)用。在前面章節(jié)中用

至U的printf、scanf>getchar>putchar等函數(shù)均屬

庫函數(shù)。

C語言提供了豐富的庫函數(shù),字符類型函數(shù)、轉(zhuǎn)換

函數(shù)、字符串函數(shù)、數(shù)學(xué)函數(shù)、輸入輸出函數(shù)等

等,詳見附錄IV。

2012-6-218

(2)用戶自定義函數(shù)

系統(tǒng)提供的庫函數(shù)不能完全滿足用戶的特

殊需求時,由用戶按需要自己設(shè)計(jì)的函數(shù)。

用戶可按C語言的函數(shù)規(guī)則定義其函數(shù)名稱、

使用的參數(shù)、完成的功能和運(yùn)行的結(jié)果。

如例5.1中的area函數(shù)是用戶自定義函數(shù)。

2012-6-219

2.從主調(diào)函數(shù)和被調(diào)函數(shù)間數(shù)據(jù)傳送的角度

(1)無參函數(shù)

函數(shù)定義、函數(shù)說明及函數(shù)調(diào)用中均不帶

參數(shù)。主調(diào)函數(shù)和被調(diào)函數(shù)之間不進(jìn)行參

數(shù)傳送。此類函數(shù)通常用來完成一組指定

的功能,可以返回或不返回函數(shù)值。

(2)有參函數(shù)(帶參函數(shù))

在函數(shù)定義及函數(shù)說明時都有參數(shù),稱為

形式參數(shù)(簡稱為形參)。在函數(shù)調(diào)用時也

必須給出參數(shù),稱為實(shí)際參數(shù)(簡稱為實(shí)

參)。進(jìn)行函數(shù)調(diào)用時,主調(diào)函數(shù)將把實(shí)

參的值傳送給形參,供被調(diào)函數(shù)使用。

2012-6-2110

5.3函數(shù)的定義和調(diào)用

?5.3.1函數(shù)的定義

函數(shù)的定義格式為:

類型標(biāo)識符函數(shù)名([形式參數(shù)列表])

類型聲明部分

執(zhí)行語句部分

}

2012-6-2111

說明:

(1)函數(shù)名是由用戶定義的標(biāo)識符,是唯一

標(biāo)識一個函數(shù)的名字,它的命名規(guī)則同變

量的命名規(guī)則完全一樣。同一個程序中不

同的函數(shù)名字不能相同。

(2)類型標(biāo)識符說明了函數(shù)的類型,即函數(shù)

返回值的類型。

(3)若形式參數(shù)列表為空,則該函數(shù)是無參

函數(shù),此時函數(shù)名后面跟一對空圓括號。

2012-6-2112

(4)若有形式參數(shù)列表,則該函數(shù)是有參函

數(shù)。形參表用于調(diào)用函數(shù)和被調(diào)用函數(shù)之

間進(jìn)行數(shù)據(jù)傳遞,形參表中的參數(shù)可以是

各種類型的變量,各參數(shù)之間用逗號間隔。

形參是變量,在形參表中應(yīng)給出形參的類

型說明。

(5)由左、右花括號括起來的部分稱為函數(shù)

體,由類型聲明部分和執(zhí)行語句部分組成。

類型聲明部分用于對函數(shù)內(nèi)所使用的變量

的類型進(jìn)行說明;執(zhí)行語句部分由C語言的

基本語句組成,它是函數(shù)功能的核心部分。

聲明語句須放在執(zhí)行語句之前。

2012-6-2113

(6)允許程序設(shè)計(jì)中使用空函數(shù),該函數(shù)什

么也不做,沒有任何實(shí)際作用,先占一個

位置,在程序需要擴(kuò)充功能時,再用一個

編好的函數(shù)取代它。

空函數(shù)的形式為:

void函數(shù)名()

()

2012-6-2114

【例5.2]定義無參函數(shù)。

include<stdio.h>

voidprint()

(

printfCHello!");

)

intmain()

(

print();/*調(diào)用函數(shù)print*/

return0;

)

運(yùn)行結(jié)果如下:

Hello!

2012-6-2115

【例5.3]定義有參函數(shù)。

include<stdio.h>

intmain()

(

intx,y,z;

printf(Tleaseinputtwointeger:");

HH

scanf(%d%d,&xJ&y);

z=max(x,y);/*調(diào)用函數(shù)max7

printf(Hthemaxis%d.",z);

return0;

)

2012-6-2116

intmax(intm,intn)

/*定義函數(shù)max,求兩個數(shù)的最大值*/

(

ints;/*函數(shù)體的類型聲明部分*/

if(m>n)/*函數(shù)體執(zhí)行語句部分的開始7

s=m;

else

s=n;

returns;/*函數(shù)體執(zhí)行語句部分的結(jié)束*/

)

2012-6-2117

由上述兩個例子可以看出,在C程序中,

一個函數(shù)的定義可以放在任意位置,既可

放在主函數(shù)main之前,也可放在main之后。

在C語言中,所有的函數(shù)定義,包括主函

數(shù)main在內(nèi),都是平行的。也就是說,在

一個函數(shù)的函數(shù)體內(nèi),不能再定義另一個

函數(shù),即函數(shù)不能嵌套定義。

2012-6-2118

5.3.2函數(shù)的調(diào)用

1.函數(shù)的一般調(diào)用形式

函數(shù)名(實(shí)際參數(shù)列表)

說明:

若是調(diào)用無參函數(shù),則“實(shí)際參數(shù)列表”可

以沒有,但圓括號不能省略,如例5.2。若

“實(shí)際參數(shù)列表”包含多個實(shí)參,則各參

數(shù)間用逗號隔開,如例5.3。

2012-6-2119

2.函數(shù)的調(diào)用方式

按函數(shù)在程序中出現(xiàn)的位置來分,有以下三種函數(shù)調(diào)用方式。

(1)函數(shù)語句

把函數(shù)調(diào)用作為一個語句,如例5.2中“print。;”。

(2)函數(shù)表達(dá)式

函數(shù)出現(xiàn)在一個表達(dá)式中,這種表達(dá)式稱為函數(shù)表達(dá)式。

例如:z=max(x,y);

或z=2*max(x,y);

函數(shù)max是表達(dá)式的一部分,它的值乘以2再賦給z。

(3)函數(shù)參數(shù)

函數(shù)調(diào)用作為一個函數(shù)的實(shí)參。

例如:p=max(max(x,y),z);

這里,max(x,y)是一次函藪施用,它的值作為max另一次調(diào)用

的實(shí)參。p的值就是x,y,z三者的最大值。

又如:printf("%d",max(x,y));

這里,函羲調(diào)甫max(x,y)作Rprintf函數(shù)的一個參數(shù)。

2012-6-2120

3.被調(diào)用函數(shù)的使用說明

在程序中調(diào)用另一個函數(shù)時,要滿足以下三個條件。

(1)被調(diào)用函數(shù)可以是已經(jīng)存在的用戶自定義函數(shù)或者

是系統(tǒng)庫函數(shù)。

(2)如果調(diào)用庫函數(shù),應(yīng)該在本程序開頭使用箱的1加6命

令將調(diào)用有關(guān)庫函數(shù)時所需用到的信息“包含”到本程

序中。

例如:

include<stdio.h>/*輸入輸出庫函數(shù)*/

include<math.h>/*數(shù)學(xué)庫函數(shù)*/

2012-6-2121

(3)如果調(diào)用用戶自定義的函數(shù),且該函數(shù)與對該

函數(shù)的調(diào)用函數(shù)在同一個源文件中,特別是函數(shù)中

調(diào)用函數(shù),則在主調(diào)函數(shù)中必須對被調(diào)用函數(shù)作類

型聲明。對被調(diào)用函數(shù)進(jìn)行類型聲明就是告訴系統(tǒng),

在本函數(shù)中將要用到的函數(shù)是什么類型,即函數(shù)的

返回值是什么類型,以便按聲明的類型對函數(shù)值作

相應(yīng)的處理。

函數(shù)聲明的一般格式為:

類型標(biāo)識符函數(shù)名(類型標(biāo)識符形參名,類型標(biāo)識

符形參名,…);

2012-6-2122

說明:

①對被調(diào)用函數(shù)聲明時,可以省略形參名。函數(shù)聲明語句后

面的分號不能省略。

②被調(diào)用函數(shù)的返回值是整型或字符型時,可以不對被調(diào)用

函數(shù)進(jìn)行聲明,而直接調(diào)用。這時系統(tǒng)將自動對被調(diào)用函

數(shù)返回值按整型處理。

如例5.1和例5.3中的被調(diào)函數(shù)area和被調(diào)函數(shù)max的返回值

均為整型,所以在主調(diào)函數(shù)main函數(shù)中均未對被調(diào)函數(shù)作

類型聲明。

③如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必對

被調(diào)用函數(shù)加以聲明。

如例5.2中被調(diào)函數(shù)print在主調(diào)函數(shù)main之前定義,所以在

主調(diào)函數(shù)main中不需要對被調(diào)函數(shù)print作類型聲明。

④如果在程序的開頭(在所有函數(shù)之前),已對本程序中所

調(diào)用的函數(shù)進(jìn)行了聲明,則在各主調(diào)函數(shù)中不必對其所調(diào)

用的函數(shù)再作聲明。

2012-6-2123

【例5.4】計(jì)算n!。

include<stdio.h>

intmain()

longfac(int);/*對被調(diào)函數(shù)fac作類型聲明,省

略了參數(shù)名*/

intn;

longlayer;

print^Tleaseinputn:H);

scanf(”%cT,&n);

layer=fac(n);

printf(,,n=%d,%d!=%ld,,,n,n,layer);

return0;

}________________________________________

2012-6-2124

longfac(intx)

此例是在主調(diào)函數(shù)main中對被調(diào)函數(shù)

longy;fac作類型聲明,聲明語句double

fac(int)也可以放在程序的開頭,即:

inti;

#include<stdio.h>

y=1;doublefac(int);/*對被調(diào)函數(shù)fac

for(i=1;i<=x;i++)作類型聲明*/

intmain()

y=y*i;

returny;

)

)doublefac(intx)/*定義函數(shù)fac*/

)

2012-6-2125

關(guān)于函數(shù)調(diào)用還需要說明的是,在C程序中,

main函數(shù)是主函數(shù),它可以調(diào)用其它函數(shù),而不

允許被其它函數(shù)調(diào)用。因此,C程序的執(zhí)行總是

從main函數(shù)開始,完成對其它函數(shù)的調(diào)用后再返

回到main函數(shù),最后由main函數(shù)結(jié)束整個程序。

一個C源程序必須有,也只能有一個主函數(shù)main。

函數(shù)的使用和變量一樣,一般要求先定義后使用。

2012-6-2126

5.4函數(shù)的返回值

函數(shù)的返回值是指函數(shù)被調(diào)用之后,執(zhí)行函數(shù)體

中的程序段所取得的并返回給主調(diào)函數(shù)的值。函

數(shù)調(diào)用的目的通常是為了得到一個計(jì)算結(jié)果即函

數(shù)值。在C程序中,利用返回語句return將計(jì)算結(jié)

果返回給主調(diào)函數(shù),同時,也使程序的執(zhí)行流程

轉(zhuǎn)到主調(diào)函數(shù)的下一條語句去執(zhí)行。

返回語句的格式為:

return(表達(dá)式);

或者

return表達(dá)式;

2012-6-2127

說明:

(1)函數(shù)的返回值只能通過return語句返回給

主調(diào)函數(shù)。在函數(shù)中允許有多個return語句,

但每次調(diào)用只能有一個return語句被執(zhí)行,因

此只能返回一個函數(shù)值。

(2)返回值的類型和函數(shù)定義中函數(shù)的類型應(yīng)

保持一致。如果兩者不一致,則以函數(shù)類型為

準(zhǔn),自動進(jìn)行類型轉(zhuǎn)換。

(3)系統(tǒng)默認(rèn)的函數(shù)返回值類型為整型,因此

當(dāng)函數(shù)返回值為整型時,在函數(shù)定義時可以省

去返回值類型說明。

2012-6-2128

(4)當(dāng)函數(shù)沒有返回值時,函數(shù)的返回值類型可以

定義為“空類型”,類型說明符為“void”。在調(diào)

用無返回值的函數(shù)時,往往是以單獨(dú)的調(diào)用語句

出現(xiàn)的,即在主調(diào)函數(shù)中就不能使用被調(diào)函數(shù)的

函數(shù)值了。為了使程序有良好的可讀性并減少出

錯,凡不要求返回值的函數(shù)都應(yīng)定義為空類型。

假設(shè)將例5.4中函數(shù)fac定義為void,即:

voidfac(intx)

)

則在主函數(shù)中寫語句:layer二fac(n);就是錯誤的

2012-6-2129

【例5.5】求兩個數(shù)的最大值。

主函數(shù)main()與例5.3的相同,max函數(shù)改寫如下:

max(intm,intn)

(

if(m>n)

returnm;

else

returnn;

)

函數(shù)max的返回值為整型,定義函數(shù)時省略了類

型,所以也未對max函數(shù)作類型聲明。

2012-6-2130

5.5函數(shù)的參數(shù)及參數(shù)的傳遞

5.5.1函數(shù)的參數(shù)

1,形式參數(shù)(簡稱形參)

在定義函數(shù)時函數(shù)名后面括弧中的變量名稱為

形參,即形參出現(xiàn)在函數(shù)定義中。

形參變量只有在被調(diào)用時才為其分配臨時內(nèi)存

單元,在調(diào)用結(jié)束時,即刻釋放所分配的內(nèi)存

單元。因此,形參只在函數(shù)內(nèi)部有效。函數(shù)調(diào)

用結(jié)束返回主調(diào)函數(shù)后則不能再使用該形參變

量。

2012-6-2131

2.實(shí)際參數(shù)(簡稱實(shí)參)

在調(diào)用函數(shù)時,函數(shù)調(diào)用語句中函數(shù)名后面括弧

中的參數(shù)稱為實(shí)參。實(shí)參出現(xiàn)在主調(diào)函數(shù)中。

實(shí)參可以是常量、變量、表達(dá)式、函數(shù)等,無論

實(shí)參是何種類型的量,在進(jìn)行函數(shù)調(diào)用時,它

們都必須具有確定的值,以便把這些值傳送給

形參。因此應(yīng)預(yù)先用賦值、輸入等辦法使實(shí)參

獲得確定值。

實(shí)參和形參在數(shù)量、類型、順序上應(yīng)嚴(yán)格一致,

否則會發(fā)生“類型不匹配”的錯誤。

2012-6-2132

5.5.2參數(shù)的傳遞方式

實(shí)參和形參的功能是作數(shù)據(jù)傳送。在c語言中實(shí)

參和形參之間的數(shù)據(jù)傳遞有兩種方式。

1.傳值

調(diào)用函數(shù)時將實(shí)參的值傳遞給形參,形參值的改

變不會影響實(shí)參。調(diào)用結(jié)束后,形參所占用的內(nèi)

存單元被釋放,實(shí)參仍保持原值不變。該方法只

能由實(shí)參向形參傳遞數(shù)據(jù),即該方式是單向傳遞。

2012-6-2133

【例5.6]傳值方式舉例。

#include<stdio.h>

voidswap(intjnt);/*對被調(diào)函數(shù)的類型聲明*/

intmain()

(

intn,m;

printf(nPleaseinputnumber:");

scanf("%d%d"5&n,&m);

printf(,,n=%d,m=%d\n,,,n,m);

swap(n,m);

printf("n=%d,m=%d\n",n,m);

return0;

)

2012-6-2134

voidswap(intx,inty)

/*函數(shù)swap的定義,該函數(shù)無返回值7

(

intt;

t=x;

x=y;

y=t;

printf("x=%d,y=%d\n,,,x,y);

)

假定輸入n和m的值分別為5和7,運(yùn)行結(jié)果如下:

Pleaseinputnumber:57/

n=5,m=7

x=7,y=5

n=5,m=7

2012-6-2135

?本例中函數(shù)swap的功能是交換兩個參數(shù)的

值。但從運(yùn)行結(jié)果可以看出,調(diào)用swap函

數(shù)只交換了兩個形參的值,而實(shí)參的值并

沒有交換。

5K!75Kg7

5E77?5

(a)調(diào)用swap時,形參分別得到對應(yīng)實(shí)參的(b)執(zhí)行sw叩,交換了形參的

值圖5.1傳值方式疆列

2012-6-2136

【例5.7】利用數(shù)組元素、表達(dá)式作為實(shí)參進(jìn)行參數(shù)傳遞。

#include<stdio.h>

intsum(intjnt);

intmain()

intx=10,y=20,a,bc;

J運(yùn)行結(jié)果如下:

intaa[3]={1,2,3};

x+y=30

a=sum(x,y);

(x+10)=y=40

b=sum(x+10,y);

aa[0]+aa[1]+aa[2]=6

c=sum(sum(aa[0],aa[1]),aa[2]);

printf("x+y=%d\n",a);

printf("(x+10)+y=%d\n",b);

printf("aa[0]+aa[1]+aa[2]=%d\n",c);本例在主調(diào)函數(shù)main函數(shù)中,分別

return0;用零量:x,V、表達(dá)式:x+10、數(shù)

}組元素:aa[O],aa[1],aa[2]>函

intsum(intm,intn)數(shù)值sum(aa[0],aa[1])作為實(shí)參單向

給形參傳遞值。

intp;

p=m+n;

returnp;

Joi2-6-21

37

由此可見,在普通變量或數(shù)組元素作為函數(shù)

參數(shù)時,形參變量和實(shí)參變量是在程序運(yùn)

行時分配的兩個不同的內(nèi)存單元,所進(jìn)行

的值傳遞是單向的,即只能從實(shí)參傳向形

參,不能從形參傳回實(shí)參。形參的初值和

實(shí)參相同,而形參的值發(fā)生改變后,實(shí)參

的值并不變化,兩者的最終值是不同的。

2012-6-2138

2,傳地址

在實(shí)際應(yīng)用中,往往需要將形參的值返回給

實(shí)參,所以需要雙向傳遞,這時可以使用

傳地址方式。

當(dāng)用表示地址的數(shù)組名或者用指針變量(詳

見第6章)作為函數(shù)參數(shù)進(jìn)行參數(shù)傳遞時就

不是傳值,實(shí)際上傳送的是地址,即把實(shí)

參所存放的地址賦予形參。由于形參在調(diào)

用時所得到的是實(shí)參所指的地址,因而形

參和實(shí)參將占用同一片內(nèi)存空間,即兩者

指向同一個對象,因此在被調(diào)函數(shù)中對形

參所做的操作都會影響到實(shí)參。

2012-6-2139

【例5.8】采用插入排序法將數(shù)組中元素升序排列。

#include<stdio.h>

#defineN10

voidsort(inta[],intn);

intmain()

(

ints[N],i;

printf("Pleaseinputdata:");

for(i=0;i<N;i++)

scanf("%d",&s[i]);

sort(s,N);

printf("Thelistis(inmain()):");

for(i=0;i<N;i++)

printf("%4d",s[i]);

return0;

2012-6-2140

voidsort(inta[],intn)

int本例中,排序函數(shù)sort(inta[],intn)

for(i=0;i<n-1;i++)的兩個形參中,a表示數(shù)組"n

指定數(shù)組的長度。

k=i;

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

if(a[j]<a[k])k=j;

if(k!=i)

t=a[k];a[k]=a[i];a[i]=t;

}

}

printf("\nThelistis(insort()):");

for(i=0;i<n;i++)

printf("%4d",a[i]);

2012-6-2141

注意:

用數(shù)組名作為函數(shù)參數(shù)時,必須在被調(diào)函數(shù)與主

調(diào)函數(shù)中分別定義數(shù)組。在對形參數(shù)組定義時不

指定數(shù)組的長度,而僅給出類型、數(shù)組名和一對

方括號,以便允許同一個函數(shù)可根據(jù)需要來處理

不同長度的數(shù)組;但是為了能使程序了解當(dāng)前處

理數(shù)組的實(shí)際長度,往往用另一個參數(shù)來表示數(shù)

組的長度。當(dāng)多維數(shù)組名作為函數(shù)參數(shù)時,除第

一維可以不指定長度外,其余各維都必須指定數(shù)

組長度。形參數(shù)組與實(shí)參數(shù)組在類型上應(yīng)該一致,

否則會出錯。

2012-6-2142

5.6函數(shù)的嵌套與遞歸調(diào)用

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

C語言中不允許作嵌套的函數(shù)定義。因此各

函數(shù)之間是平行的,不存在上一級函數(shù)和

下一級函數(shù)的問題。但是C語言允許在一

個函數(shù)的定義中出現(xiàn)對另一個函數(shù)的調(diào)用。

這樣就出現(xiàn)了函數(shù)的嵌套調(diào)用,即在被調(diào)

函數(shù)中又調(diào)用其它函數(shù)。

2012-6-2143

?函數(shù)的嵌套調(diào)用可以用圖5.2表示,這是一

個二層調(diào)用的示意圖。

main函數(shù)fl函數(shù)f2函數(shù)

①②③

調(diào)用fl函數(shù)調(diào)用f2函數(shù)

⑨⑦

結(jié)束返回main函數(shù)返回fl函數(shù)

圖5.2函數(shù)嵌套調(diào)用示意圖

2012-6-2144

【例5.9]計(jì)算1!+2!+3!+…+10!

#include<stdio.h>longsum(intn)longfac(intx)

longfac(int);

longsum(int);inti;longy;

intmain()longm=0;inti;

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

longs;m+=fac(i);for(i=1;i<=x;i++)

s=sum(10);returnm;y=y*i;

printf("1!+2!+..+10!=%ld",s);}returny;

return0;}

)

2012-6-2145

5.6.2函數(shù)的遞歸調(diào)用

在調(diào)用函數(shù)的過程中又出現(xiàn)直接或間接的調(diào)用該函數(shù)自身,稱為

函數(shù)的遞歸調(diào)用。這種函數(shù)稱為遞歸函數(shù)。C語言允許函數(shù)的

遞歸調(diào)用,但是程序中不應(yīng)出現(xiàn)無終止的遞歸調(diào)用,只應(yīng)出現(xiàn)

有限次數(shù)的。

例如有函數(shù)fun如下:

intfun(intm)

intn;

t=fun(n);

returnt;

這個函數(shù)是一個遞歸函數(shù)。但是運(yùn)行該函數(shù)時將無休止地調(diào)用其

自身,這顯然是不正確的。為了防止遞歸調(diào)用無終止地進(jìn)行,

必須在函數(shù)內(nèi)有終止遞歸調(diào)用的語句。常用的辦法是加條件判

斷,滿足某種條件后就不再作遞歸調(diào)用,然后逐層返回。

2012-6-2146

【例5.10】用遞歸算法計(jì)算n!

用遞歸法計(jì)算n!可用下述公式表示:

n!=1(n=0,1)

nX(n-1)!(n>1)intmain()

include<stdio.h>intn;

longfac(intn)longm;

printf(H\nPleaseinputainteger:");

scanf(”%cT,&n);

longf;

m=fac(n);

if(n==0||n==1)f=1;printf(,,%d!=%ld,,,n,m);

elsef=n*fac(n-1);return0;}

returnf;

)

2012-6-2147

57變量的作用域和存儲類型

前面介紹了變量的一些屬性及使用方法,本節(jié)將從

空間和時間兩個不同的角度來描述變量,介紹變

量的作用域和生存期。兩者既有聯(lián)系,又有區(qū)別

變量的作用域指一個變量能夠起作用(被引用)的

程序范圍,即一個變量定義之后,在何處可以使

用該變量。

變量的生存期指程序在執(zhí)行期間,變量存在的時間

間隔,即從給變量分配內(nèi)存,至所分配內(nèi)存被釋

放的那段時間。

2012-6-2148

5.7.1變量的作用域

c語言中所有的變量都有自己的作用域。變量

定義的位置,其作用域?qū)⒉煌?。C語言中的變

量,按作用域范圍可分為兩種,即局部變量和

全局變量。

1.局部變量

局部變量也稱為內(nèi)部變量。局部變量是在函數(shù)

內(nèi)作定義說明的。其作用域僅限于函數(shù)內(nèi),離

開該函數(shù)后再使用這種變量是非法的。

2012-6-2149

例如:

intf1(inta)/*函數(shù)f1*/

{/*a,b,c在該花括號范圍內(nèi)有效*/

intb,c;

)

intf2(intx)/*函數(shù)f2*/

{/*x,y,z在該花括號范圍內(nèi)有效*/

inty,z;

)

intmain()

{/*在該花括號范圍內(nèi)有效*/

2012-6-2150

說明:

(1)主函數(shù)中定義的變量也只能在主函數(shù)中使用,

不能在其它函數(shù)中使用。同時,主函數(shù)中也不能

使用其它函數(shù)中定義的變量。因?yàn)橹骱瘮?shù)也是一

個函數(shù),它與其它函數(shù)是平行關(guān)系。

(2)形參變量是屬于被調(diào)函數(shù)的局部變量,實(shí)參變

量是屬于主調(diào)函數(shù)的局部變量。

(3)允許在不同的函數(shù)中使用相同的變量名,它們

代表不同的對象,分配不同的單元,互不干擾,

也不會發(fā)生混淆。如在例5.10中,形參和實(shí)參的

變量名都為n,是完全允許的。

2012-6-2151

(4)在復(fù)合語句中也可定義變量,其作用域只在復(fù)合語句

范隹I內(nèi)。

例如:

main()

{/*s,a在該對花括號范圍內(nèi)有效*/

ints,a;

{/*b在該對花括號范圍內(nèi)有效7

intb;

s=a+b;

}

)

2012-6-2152

【例5.11】局部變量作用域舉例。

#include<stdio.h>

intmain()

inti=1,j=2,k;/*4行,ij,k為main函數(shù)內(nèi)定義的局部變量

k=i+j;

(

intk=5;/*第7行,k為復(fù)合語句內(nèi)定義的局部變量*/

printf(,,k=%d\n,,,k);

)

,,,,

printf(i=%d,j=%d,k=%d\n,i,j,k);運(yùn)行結(jié)果如下:

return0;

k=5

)i=1,j=2,k=3

2012-6-2153

2.全局變量

全局變量也稱為外部變量,它是在函數(shù)外部

定義的變量。它不屬于哪一個函數(shù),它屬

于一個源程序文件。其作用域是整個源程

序。在函數(shù)中使用全局變量,一般應(yīng)作全

局變量說明。只有在函數(shù)內(nèi)經(jīng)過說明的全

局變量才能使用。全局變量的說明符為

externo但在一個函數(shù)之前定義的全局變量,

在該函數(shù)內(nèi)使用可不再加以說明。

2012-6-2154

例如:

inta,b;/*a,b為全局變量*/

voidf1()

)

floatx,y;/*x,y為全局變量*/

intf2()

)

intmain()/*主函數(shù)*/

}

2012-6-2155

【例5.12】輸入半徑,求圓的面積和周長。

#include<stdio.h>

#definePI3.14

floatcircle;/*定義全局變量circle,用來獲取周長*/

floatf(floatr)

intmain()

floats;

s=PI*r*r;floatr,area;

printf("\nPleaseinputr:");

circle=2*PI*r;

scanf("%f',&r);

returns;

area=f(r);

)printf("area=%f,len=%f\n",area,circle);

return0;

)

2012-6-2156

關(guān)于全局變量的使用,還需注意:

(1)全局變量可加強(qiáng)函數(shù)模塊之間的數(shù)據(jù)聯(lián)系,

但是又使函數(shù)要依賴這些變量,因而使得

函數(shù)的獨(dú)立性降低。從模塊化程序設(shè)計(jì)的

觀點(diǎn)來看這是不利的,因此在不必要時盡

量不要使用全局變量。

(2)在同一源文件中,允許全局變量和局部變

量同名。在局部變量的作用域內(nèi),全局變

量不起作用。

2012-6-2157

【例5.13】全局變量和局部變量同名舉例。

include<stdio.h>

inta=1,b=2;/*全局變量a,b*/

intsum(intx,inty)

(intmain()

intz;

(

z=x+y;inta=5;/*局部變量a*/

returnz;printf("a+b=%d,,,sum(a,b));

)return0;

}

運(yùn)行結(jié)果如下:

a+b=7

2012-6-2158

5.7,2變量的存儲類型

1.動態(tài)存儲方式與靜態(tài)存儲方式

在C語言中,變量不僅具有確定的數(shù)據(jù)類型要求,

而且還有存儲類型的要求。變量的存儲類型是其

存儲屬性,即變量在內(nèi)存中的存儲方式,不同的

存儲方式,將影響變量值的存在時間(即生存

期)。變量的存儲方式可分為“靜態(tài)存儲”和

“動態(tài)存儲”兩種。

靜態(tài)存儲方式:指在變量定義時就分定存儲單元并

一直保持不變,直至整個程序結(jié)束。

動態(tài)存儲方式:指在程序執(zhí)行過程中,使用它時才

分配存儲單元,使用完畢立即釋放。

2012-6-2159

用戶存儲空間可以分為三個部分:程序區(qū)、靜態(tài)存

儲區(qū)、動態(tài)存儲區(qū)。

全局變量全部放在靜態(tài)存儲區(qū),在程序開始執(zhí)行時

給全局變量分配存儲區(qū),程序執(zhí)行完畢就釋放。

動態(tài)存儲區(qū)存放以下數(shù)據(jù):

(1)函數(shù)的形式參數(shù);

(2)自動變量(未加static聲明的局部變量)

(3)函數(shù)調(diào)用時的現(xiàn)場保護(hù)和返回地址。

這些數(shù)據(jù)在函數(shù)開始調(diào)用時分配動態(tài)存儲空間,函

數(shù)結(jié)束時釋放這些空間。

2012-6-2160

因此,在C語言中,每個變量有兩個屬性:數(shù)據(jù)類型和數(shù)據(jù)

的存儲類型。一個變量說明的完整形式應(yīng)為:

存儲類型標(biāo)識符數(shù)據(jù)類型標(biāo)識符變量名,變量名…;

在c語言中,對變量的存儲類型說明有以下四種:

auto自動變量

register寄存器變量

extern外部變量

static靜態(tài)變量

例如:

staticinta,b;說明a,b為靜態(tài)類型變量

autocharc1,c2;說明c1,c2為自動字符變量

staticinta[5]={123,4,5};說明a為靜態(tài)整型數(shù)組

externintx,y;而明x,y為外部整型變量_

2012-6-2161

2.四種存儲類型

(1)auto變量

函數(shù)中的形參利在函數(shù)內(nèi)定義的未加存儲類型標(biāo)

識符的局部變量(包括在復(fù)合語句中定義的變量)

均視為自動變量,也就是說自動變量反省去說明

符aut。。在調(diào)用函數(shù)時系統(tǒng)將給自動變量分配存

儲空間,函數(shù)調(diào)用結(jié)束時就自動釋放空間。例如:

intf(intx)

inty;

autointz;

)

形參x和局部變量y、z都是自動變量。

2012-6-2162

(2)用static聲明局部變量

若希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而

保留原值,這時就應(yīng)該指定局部變量為“靜態(tài)局部變量”

用關(guān)鍵字static進(jìn)行聲明。

說明:

①靜態(tài)局部變量屬于靜態(tài)存儲類別,在靜態(tài)存儲區(qū)內(nèi)分配存

儲單元。在程序整個運(yùn)行期間都不釋放。而自動變量(即

動態(tài)局部變量)屬于動態(tài)存儲類別,占動態(tài)存儲空間,函

數(shù)調(diào)用結(jié)束后即釋放。

②靜態(tài)局部變量在編譯時賦初值,即只賦初值一次;而對自

動變量賦初值是在函數(shù)調(diào)用時進(jìn)行,每調(diào)用一次函數(shù)重新

賦一次初值,相當(dāng)于執(zhí)行一次賦值語句。

③如果在定義局部變量時不賦初值的話,則對靜態(tài)局部變量

來說,編譯時自動賦初值0(對數(shù)值型變量)或空字符

(對字符變量)。而對自動變量來說,如果不賦初值則它

的值是一個不確定的值。

2012-6-2163

【例5.14】打印1到4的階乘值。

#include<stdio.h>

intfac(intn)

(

staticintf=1;

f=f*n;

returnf;

}

intmain()

(

inti;

for(i=1;i<=4;i++)

printf("%d!=%d\n",i,fac(i));

return0;

}_.................

2012-6-2164

(3)register變量

為了提高效率,C語言允許將局部變量的值放在

CPU中的寄存器中,這種變量叫“寄存器變量”,

用關(guān)鍵字register作聲明。

說明:

①只有局部自動變量和形式參數(shù)可以作為寄存器變

量;

②一個計(jì)算機(jī)系統(tǒng)中的寄存器數(shù)目有限,不能定義

任意多個寄存器變量;

③局部靜態(tài)變量不能定義為寄存器變量。

2012-6-2165

【例5.15】使用寄存器變量。

intfac(intn)

(

registerinti,f=1;

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

f=f*i

returnf;

)

intmain()

(

inti;

for(i=0;i<=4;i++)

printf("%d!=%d\n",i,fac(i));

return0;

)

2012-6-2166

(4)用extern聲明全局變量

全局變量是在函數(shù)的外部定義的,它的作用域?yàn)閺?/p>

變量定義處開始,到本程序文件的末尾。如果全局

變量不在文件的開頭定義,其有效的作用范圍只限

于定義處到文件結(jié)束。如果在定義位置之前的函數(shù)

要引用該全局變量,則應(yīng)該在引用之前用關(guān)鍵字

extern對該變量作“全局變量聲明”。表示該變量

是一個已經(jīng)定義的全局變量。有了此聲明,就可以

從“聲明”處起,合法地使用該外部變量。

2012-6-2167

【例5.16】

#include<stdio.h>

intsum(intx,inty)

intz;

運(yùn)行結(jié)果如下:

z=x+y;

returnz;30

}

intmain()

externA,B;

printf("%d\n",sum(A,B));

return0;

}

intA=10,B=20;

2012-6-2168

5.8綜合實(shí)例

【例5.17】通過鍵盤輸入10個整數(shù),求最大

值和最小值及平均值。

方法1:將10個整數(shù)放在一個數(shù)組中,作為一個

整體來處理。分別用三個函數(shù)來求最大值、最小

值、平均值。

2012-6-2169

#include<stdio.h>

#defineN10

intmax(inta[],intn);

intmin(inta[],intn);

floatave(inta[],intn);

intmain()

inta[N],i,max_a,min_a;

floatave_a;

printf("Pleaseinput10integer:");

for(i=0;i<10;i++)

scanf("%d",&a[i]);

max_a=max(a,N);

min_a=min(a,N);

ave_a=ave(a,N);

printf("Themaxis:%d\n",max_a);

printf("Theminis:%d\n",min_a);

printf("Theaverageis:%f\nn,ave_a);

2012-6-2170

rn

intmax(inta[],intn)

intmin(inta[],intn)

inti,m;

inti,m;

m=a[0];

m=a[0];

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

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

if(m<a[i])m=a[i];

if(m>a[i])m=a[i];

returnm;

returnm;

)

)

floatave(inta[],intn)

inti;

floatm=0;

for(i=0;i<n;i++)

m+=a

溫馨提示

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

評論

0/150

提交評論