版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第5章函數(shù)
2012年6月21日星期四
2012-6-21
2012-6-212
結(jié)構(gòu)化程序設(shè)計方法,從程序?qū)崿F(xiàn)的角度看就是
模塊化程序設(shè)計,就是將程序模塊化,即在程序
設(shè)計中通常將一個大的程序按功能進(jìn)行分割成一
些模塊,使每個模塊都成為功能單一、結(jié)構(gòu)清晰、
接口簡單、容易理解的小程序。在C語言中是通
過函數(shù)來實現(xiàn)模塊化程序設(shè)計的,即將那些較小
的功能單一的程序模塊稱之為函數(shù),通過對函數(shù)
的調(diào)用實現(xiàn)特定的功能。所以較大的C語言應(yīng)用
程序,往往是由多個函數(shù)組成的,每個函數(shù)分別
對應(yīng)各自的功能模塊,通過函數(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è)計程序來求解任何一個問題時,主要任務(wù)
就是編寫函數(shù)。
進(jìn)行C程序設(shè)計時一般采用自頂向下、逐步細(xì)化的
方法設(shè)計程序結(jié)構(gòu),即先集中考慮main函數(shù)中的算法。
當(dāng)main函數(shù)中需要使用某一功能時,就先寫上一個調(diào)用
具有該功能的函數(shù)的表達(dá)式。這時只需知道函數(shù)具有什
么功能,如何與程序通信(輸入什么,輸出什么),函
數(shù)的具體實現(xiàn)先不去處理。設(shè)計完main()函數(shù)的算法并
檢驗無誤后,再開始考慮它所調(diào)用函數(shù)的具體實現(xiàn)。在
這些被調(diào)用的函數(shù)中,若在庫函數(shù)中可以找到,那就直
接使用,否則就動手設(shè)計這些函數(shù)。
2012-6-215
【例5.1】分別求兩個長方形的面積。
分析:采用模塊化程序設(shè)計的思想,將計算長方形面積的
代碼段提煉出來,寫成函數(shù),當(dāng)需要這段代碼時,就調(diào)
用該函數(shù)。
include<stdio.h>
intmain()/*先設(shè)計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è)計自定義函數(shù)area7
(
intz;
z=x*y;
returnz;
)
由此可以看出,在c程序設(shè)計中使用函數(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è)計的函數(shù)。
用戶可按C語言的函數(shù)規(guī)則定義其函數(shù)名稱、
使用的參數(shù)、完成的功能和運行的結(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ù)(簡稱為實
參)。進(jìn)行函數(shù)調(diào)用時,主調(diào)函數(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è)計中使用空函數(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;
)
運行結(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ù)列表)
說明:
若是調(diào)用無參函數(shù),則“實際參數(shù)列表”可
以沒有,但圓括號不能省略,如例5.2。若
“實際參數(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ù)的實參。
例如:p=max(max(x,y),z);
這里,max(x,y)是一次函藪施用,它的值作為max另一次調(diào)用
的實參。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】計算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)用的目的通常是為了得到一個計算結(jié)果即函
數(shù)值。在C程序中,利用返回語句return將計算結(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ù)時,往往是以單獨的調(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ù)(簡稱實參)
在調(diào)用函數(shù)時,函數(shù)調(diào)用語句中函數(shù)名后面括弧
中的參數(shù)稱為實參。實參出現(xiàn)在主調(diào)函數(shù)中。
實參可以是常量、變量、表達(dá)式、函數(shù)等,無論
實參是何種類型的量,在進(jìn)行函數(shù)調(diào)用時,它
們都必須具有確定的值,以便把這些值傳送給
形參。因此應(yīng)預(yù)先用賦值、輸入等辦法使實參
獲得確定值。
實參和形參在數(shù)量、類型、順序上應(yīng)嚴(yán)格一致,
否則會發(fā)生“類型不匹配”的錯誤。
2012-6-2132
5.5.2參數(shù)的傳遞方式
實參和形參的功能是作數(shù)據(jù)傳送。在c語言中實
參和形參之間的數(shù)據(jù)傳遞有兩種方式。
1.傳值
調(diào)用函數(shù)時將實參的值傳遞給形參,形參值的改
變不會影響實參。調(diào)用結(jié)束后,形參所占用的內(nèi)
存單元被釋放,實參仍保持原值不變。該方法只
能由實參向形參傳遞數(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,運行結(jié)果如下:
Pleaseinputnumber:57/
n=5,m=7
x=7,y=5
n=5,m=7
2012-6-2135
?本例中函數(shù)swap的功能是交換兩個參數(shù)的
值。但從運行結(jié)果可以看出,調(diào)用swap函
數(shù)只交換了兩個形參的值,而實參的值并
沒有交換。
5K!75Kg7
5E77?5
(a)調(diào)用swap時,形參分別得到對應(yīng)實參的(b)執(zhí)行sw叩,交換了形參的
值圖5.1傳值方式疆列
2012-6-2136
【例5.7】利用數(shù)組元素、表達(dá)式作為實參進(jìn)行參數(shù)傳遞。
#include<stdio.h>
intsum(intjnt);
intmain()
intx=10,y=20,a,bc;
J運行結(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])作為實參單向
給形參傳遞值。
intp;
p=m+n;
returnp;
Joi2-6-21
37
由此可見,在普通變量或數(shù)組元素作為函數(shù)
參數(shù)時,形參變量和實參變量是在程序運
行時分配的兩個不同的內(nèi)存單元,所進(jìn)行
的值傳遞是單向的,即只能從實參傳向形
參,不能從形參傳回實參。形參的初值和
實參相同,而形參的值發(fā)生改變后,實參
的值并不變化,兩者的最終值是不同的。
2012-6-2138
2,傳地址
在實際應(yīng)用中,往往需要將形參的值返回給
實參,所以需要雙向傳遞,這時可以使用
傳地址方式。
當(dāng)用表示地址的數(shù)組名或者用指針變量(詳
見第6章)作為函數(shù)參數(shù)進(jìn)行參數(shù)傳遞時就
不是傳值,實際上傳送的是地址,即把實
參所存放的地址賦予形參。由于形參在調(diào)
用時所得到的是實參所指的地址,因而形
參和實參將占用同一片內(nèi)存空間,即兩者
指向同一個對象,因此在被調(diào)函數(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ù)
組的長度。當(dāng)多維數(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]計算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ù)。但是運行該函數(shù)時將無休止地調(diào)用其
自身,這顯然是不正確的。為了防止遞歸調(diào)用無終止地進(jìn)行,
必須在函數(shù)內(nèi)有終止遞歸調(diào)用的語句。常用的辦法是加條件判
斷,滿足某種條件后就不再作遞歸調(diào)用,然后逐層返回。
2012-6-2146
【例5.10】用遞歸算法計算n!
用遞歸法計算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ù)中定義的變量。因為主函數(shù)也是一
個函數(shù),它與其它函數(shù)是平行關(guān)系。
(2)形參變量是屬于被調(diào)函數(shù)的局部變量,實參變
量是屬于主調(diào)函數(shù)的局部變量。
(3)允許在不同的函數(shù)中使用相同的變量名,它們
代表不同的對象,分配不同的單元,互不干擾,
也不會發(fā)生混淆。如在例5.10中,形參和實參的
變量名都為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);運行結(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)全局變量可加強函數(shù)模塊之間的數(shù)據(jù)聯(lián)系,
但是又使函數(shù)要依賴這些變量,因而使得
函數(shù)的獨立性降低。從模塊化程序設(shè)計的
觀點來看這是不利的,因此在不必要時盡
量不要使用全局變量。
(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;
}
運行結(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)分配存
儲單元。在程序整個運行期間都不釋放。而自動變量(即
動態(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ī)系統(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ù)的外部定義的,它的作用域為從
變量定義處開始,到本程序文件的末尾。如果全局
變量不在文件的開頭定義,其有效的作用范圍只限
于定義處到文件結(jié)束。如果在定義位置之前的函數(shù)
要引用該全局變量,則應(yīng)該在引用之前用關(guān)鍵字
extern對該變量作“全局變量聲明”。表示該變量
是一個已經(jīng)定義的全局變量。有了此聲明,就可以
從“聲明”處起,合法地使用該外部變量。
2012-6-2167
【例5.16】
#include<stdio.h>
intsum(intx,inty)
intz;
運行結(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綜合實例
【例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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 水樣除油預(yù)處理工藝流程
- 分包合同爭端處理案例分析
- 技術(shù)服務(wù)合同風(fēng)險防范策略
- 焊錫絲采購合同簽訂雙方的合同執(zhí)行
- 學(xué)生個人嚴(yán)于律己勤奮學(xué)習(xí)保證書
- 全新員工忠誠與權(quán)益保證
- 簡化人力資源承包協(xié)議
- 銀行擔(dān)保合作協(xié)議
- 初中生文明行為保證書
- 商品交易合同案例
- 鋼管架搭設(shè)施工方案
- 2021血管壓力治療中國專家共識解讀
- 職業(yè)安全健康知識培訓(xùn)
- 兒童康復(fù)家庭指導(dǎo)培訓(xùn)課件
- 大客戶管理制度(管理經(jīng)驗)
- 學(xué)校領(lǐng)導(dǎo)迎新年詩歌朗誦稿
- 小學(xué)數(shù)學(xué)重量單位克、千克、噸換算練習(xí)100道及答案
- 青海開放大學(xué)招聘考試題庫2024
- 2024年度醫(yī)院病區(qū)發(fā)生火災(zāi)的應(yīng)急預(yù)案
- 國開電大軟件工程形考作業(yè)3參考答案
- 《人體解剖生理學(xué)》全套課件
評論
0/150
提交評論