2024年-C++函數(shù)遞推遞歸學習課件_第1頁
2024年-C++函數(shù)遞推遞歸學習課件_第2頁
2024年-C++函數(shù)遞推遞歸學習課件_第3頁
2024年-C++函數(shù)遞推遞歸學習課件_第4頁
2024年-C++函數(shù)遞推遞歸學習課件_第5頁
已閱讀5頁,還剩72頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

《C++語言程序設計》第九講

函數(shù)、遞推、遞歸1大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸遞推遞推是計算機數(shù)值計算中的一個重要算法。大2思路:通過數(shù)學推導,將復雜的運算化解為若干重復的簡單運算,以充分發(fā)揮計算機長于重復運算的特點;遞推法特點:從一個已知的事實出發(fā),按一定規(guī)律推出下一個事實,再從這個新的已知事實出發(fā),再向下推出一個新的事實。5/7/2024第九講——函數(shù)、遞推、遞歸遞推舉例(1)大3例:

(猴子吃桃問題)猴子第1天摘下若干桃子,當即吃了一半,還不過癮,

又多吃了一個。第2天早上又將剩下的桃子吃掉一半,

又多吃了一個。以后每天早上都吃了前一天剩下的一

半另加一個。到第10天早上想再吃時,就只剩下一個

桃子了。問第1天猴子共摘了多少桃子?5/7/2024第九講——函數(shù)、遞推、遞歸解題思路:大4假設用

S(i) 表示第

i 天沒吃之前的桃子數(shù)目;則S(1)

即為第

1 天所摘的桃子數(shù);S(10)=S(9)*1/2

– 1 第 10天沒吃之前的桃子數(shù)S(2)=S(1)*1/2–

1第2天沒吃之前的桃子數(shù)S(3)=S(2)*1/2- 1第3天沒吃之前的桃子數(shù)……S(9)=S(8)*1/2-

1第9天沒吃之前的桃子數(shù)5/7/2024第九講——函數(shù)、遞推、遞歸一般形式:S(i)

=

S(i-1)

*

1/2–

1,大5i

=

2,

3,

…,

10;這個公式可用于知第

1

天沒吃之前的桃子數(shù)推算第

2

天沒吃之前的,再推算第

3天沒吃之前的,…….?,F(xiàn)在要求的是第

1

天沒吃之前的。能否倒過來,先知

10

天沒吃之前的的再反推第

9天沒吃之的,……,直到第

1

天沒吃之前的。為此將上式改寫為:S(i-1)=

2*(S(i)+1),

i=

10,9,8,…,25/7/2024第九講——函數(shù)、遞推、遞歸程序:大連理工大學

盤錦校區(qū)基礎教學部 66大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸分析:一般形式:S(i-1)=

2*(S(i)+1),

i=

10,9,8,…,

2;初始:s2=1; //

S(10)=

1大7i

=9s1=2*(s2

+1);s2= s1;s1=2*(s2

+1);s2= s1;s1=2*(s2

+1);s2= s1;//

S(9)=

2*(S(10)+1)// s2=s1=S(9)//

S(8)=

2*(S(9)+1)// s2=s1=S(8)//

S(7)=

2*(S(8)+

1)// s2=s1=S(7)i

=8i

=7i

=6s1=2*(s2

+1);s2= s1;//

S(6)=

2*(S(7)+1)// s2=s1=S(6)5/7/2024第九講——函數(shù)、遞推、遞歸i

=

5大8s1=2*(s2

+1);s2= s1;//

S(5)=

2*(S(6)+1)// s2=s1=S(5)//

S(4)=

2*(S(5)+1)// s2=s1=S(4)//

S(3)=

2*(S(4)+1)// s2=s1=S(3)//

S(2)=

2*(S(3)+

1)// s2=s1=S(2)//

S(1)=

2*(S(2)+1)// s2=s1=

S(1)i

=4s1=2*(s2

+1);s2= s1;s1=2*(s2

+1);s2= s1;s1=2*(s2

+1);s2= s1;s1=2*(s2

+1);s2= s1;i

=3i

=2i

=15/7/2024第九講——函數(shù)、遞推、遞歸遞推舉例(2)大9遞推數(shù)列

一個數(shù)列從某一項起,它的任何一項都可以用它前面的若干項來確定,這樣的數(shù)列稱為遞推數(shù)列,表示某項與其前面的若干項的關系就稱為遞推公式。例如自然數(shù)

1,2,…,n

的階乘就可以形成如下數(shù)列:1!,2!,3!,…,(n-1)!,n!另fact(n)

為n

階乘,依據(jù)后項與前項的關系可以寫出遞推公式: fact(n)

=

n

*

fact(n-1)

(通項公式)fact(1)

=

1

(邊界條件)5/7/2024第九講——函數(shù)、遞推、遞歸遞推算例(3)大10遞推算法程序實現(xiàn):有了通項公式和邊界條件后,采用循環(huán)結構,從邊界條件出發(fā),利用通項公式通過若干步遞推過程就可以求出結果;例:王小二自稱刀工不錯,有人放一張大的煎餅在砧板上,問他:“餅不許離開砧板,切

100

刀最多能分成多少塊?”5/7/2024第九講——函數(shù)、遞推、遞歸分析:切一刀大11切二刀切三刀

切四刀令

q(n)

表示切

n

刀能分成的塊數(shù),由上圖可知q(1)

=1+1=

2q(2)=1+

1+2=

4q(3)=1+

1+2+

3=

7q(4)=

1+1+

2+3+4=

115/7/2024第九講——函數(shù)、遞推、遞歸分析:切一刀大12切二刀切三刀

切四刀在切法上是讓每兩條線都有交點。用歸納法可得出q(n)

=

q(n-1)

+

nq(0)

=

1

(邊界條件)5/7/2024第九講——函數(shù)、遞推、遞歸遞推算例(3)參考程序:大135/7/2024第九講——函數(shù)、遞推、遞歸遞歸遞歸算法在可計算理論中占有重要地位,它是算法設計的有力工具,對于拓展編程思路非常有用。就遞歸算法而言不涉及高深數(shù)學知識,只不過初學者建立起遞歸概念不太容易??匆粋€簡單的例子:大145/7/2024第九講——函數(shù)、遞推、遞歸遞歸有 5個人坐在一起,問第5個人多少歲?他說比第4 個人大兩歲。問第 4個人歲數(shù),他說比第3個人大兩歲。問第3個人,又說比第2 個人大兩歲。問第2 個人,說比第

1 個人大兩歲。最后問第1 個人,他說是10 歲。請問第5個人多大?解題思路:假設用age(i) 表示第i 個人的歲數(shù),則大15借助循環(huán)結構采用遞推方法求解!age(5)=age(4)+2;age(4)age(3)==age(3)age(2)++2;2;age(2)=age(1)+2;age(1)=10;5/7/2024第九講——函數(shù)、遞推、遞歸一般形式:age(n)=10age(n)=age(n-1)+2(n=1)(n>2)大165/7/2024第九講——函數(shù)、遞推、遞歸分析:上述求解是從求解目標出發(fā),即將第

n個人的年齡表示第(n-1)

個人的年齡,再回溯到第

(n-2)個人的年齡

……

直到第1

個人的年齡;(回溯階段)然后,采用遞推方法,從第

1

個人的已知年齡推算第

2

個人的年齡,在推算第

3 個人的年齡,直到推算出第

5 個人的年齡;(遞推階段)這是一個遞歸問題,對它的求解可以分成

回溯

遞推

兩個階段;顯而易見,如果不希望遞歸過程無限制的進行下去,必須有一個結束遞歸過程的條件;如:age(1)=10大175/7/2024第九講——函數(shù)、遞推、遞歸計算年齡函數(shù):int

age(int

n)大18{int

c;if(n==

1) { c

=

10;

}else{c

=

age(n

-

1)

+2;}return

c;}5/7/2024第九講——函數(shù)、遞推、遞歸遞歸調用大19在調用一個函數(shù)的過程中又出現(xiàn)直接或間接地調用該函數(shù)本身,稱為函數(shù)的遞歸(recursive)調用;C++允許函數(shù)的遞歸調用;例:int

f(int

x){inty,

z;z=

f(y);return

2

*

z;}5/7/2024第九講——函數(shù)、遞推、遞歸遞歸調用直接調用大20間接調用注意:上述兩種情況都是無終止的自身調用;顯然,

程序中不應該出現(xiàn)這種無終止的調用,而只應出現(xiàn)

有限次的,有終止的遞歸調用;可以用if語句控制,

實現(xiàn)遞歸調用結束;5/7/2024第九講——函數(shù)、遞推、遞歸遞歸函數(shù)包含遞歸調用的函數(shù),稱為遞歸函數(shù);計算年齡函數(shù):int

age(int

n){int

c;if(n==

1) { c

=

10;

}else

{c

=

age(n

-

1)

+2;}return

c;}大215/7/2024第九講——函數(shù)、遞推、遞歸遞歸函數(shù)大22計算年齡遞歸函數(shù)執(zhí)行過程:age(5)=age(4)+2//c=

age(4)

+2=age(3)+2+2//c=

age(3)

+2=age(2)+2+2+

2//c

=

age(2)

+2=age(1)+2+2+

2+2;//

c

=

10;5/7/2024第九講——函數(shù)、遞推、遞歸計算年齡程序大235/7/2024第九講——函數(shù)、遞推、遞歸遞歸算例(2)大24用遞歸方法計算

n!算法思路:若n=

10,

則n!

=

10

*

9!定義函數(shù)

fact(n)

表示計算

n!的函數(shù),則有fact(n)=n*

fact(n-1),n>1fact(n)=1,n=0,n=1;5/7/2024第九講——函數(shù)、遞推、遞歸遞歸算例(2)大25階乘計算遞歸函數(shù):iinntt

ffaacctt((iinnttnn)){{intc;if(cn==n=

*0

f||anct=(n=-11));

c

=1;

reelstuern

c;c

=

n

*

fact(n-1);returnc;}}結束遞歸條件5/7/2024第九講——函數(shù)、遞推、遞歸遞歸算例(3)大26用遞歸函數(shù)計算組合數(shù):C(m,n),即從

m

個數(shù)中取

n

個數(shù)的組合數(shù);C(m,n)

=

C(m-1,

n)

+

C(m-1,n-1);C(m,n)

=0,

m

<

0,

n

<

0;C(m,n)

=1,

m

==n;C(m,n)

=

m,

n

=

1;5/7/2024第九講——函數(shù)、遞推、遞歸遞歸算例(3)大275/7/2024第九講——函數(shù)、遞推、遞歸遞歸算例(4)大28例:

(猴子吃桃問題)猴子第1天摘下若干桃子,當即吃了一半,還不過癮,

又多吃了一個。第2天早上又將剩下的桃子吃掉一半,

又多吃了一個。以后每天早上都吃了前一天剩下的一

半另加一個。到第10天早上想再吃時,就只剩下一個

桃子了。問第1天猴子共摘了多少桃子?5/7/2024第九講——函數(shù)、遞推、遞歸解題思路:大29假設用

S(i) 表示第

i 天沒吃之前的桃子數(shù)目;則S(1)

即為第

1 天所摘的桃子數(shù);S(10)=S(9)*1/2

– 1 第 10天沒吃之前的桃子數(shù)S(2)=S(1)*1/2–

1第2天沒吃之前的桃子數(shù)S(3)=S(2)*1/2- 1第3天沒吃之前的桃子數(shù)……S(9)=S(8)*1/2-

1第9天沒吃之前的桃子數(shù)5/7/2024第九講——函數(shù)、遞推、遞歸一般形式:S(i)

=

S(i-1)

*

1/2–

1,大30i

=

2,

3,

…,

10;這個公式可用于知第

1

天沒吃之前的桃子數(shù)推算第

2

天沒吃之前的,再推算第

3天沒吃之前的,…….?,F(xiàn)在要求的是第

1

天沒吃之前的。能否倒過來,先知

10

天沒吃之前的的再反推第

9天沒吃之的,……,直到第

1

天沒吃之前的。為此將上式改寫為:5/7/2024第九講——函數(shù)、遞推、遞歸一般形式:大31S(i-1)

=

2

*(S(i)

+

1),

i

=

2,3,4,…,10則S(1)

即為第

1 天所摘的桃子數(shù);S(1)=2

*(S(2)+1)S(2)=2

* (S(3)+1)…S(8)=2

*(S(9)+1)S(10)=15/7/2024第九講——函數(shù)、遞推、遞歸遞歸函數(shù):intcount(int

n)大32{int

c;if(n

==

10)

c

=

1;elsec

=

2

*

(count(n+1)

+

1);return

c;}這樣可以嗎?有沒有問題?如果出現(xiàn)調用語句:count(11)

?5/7/2024第九講——函數(shù)、遞推、遞歸遞歸函數(shù):intcount(int

n){int

c;if(

n

>

10

)

return

-1;

if(n

==

10)

c

=1;elsec

=

2

*(count(n+1)

+

1);return

c;}大335/7/2024第九講——函數(shù)、遞推、遞歸遞歸方法大34遞歸實現(xiàn):在時間和空間上的開銷比較大;但符合人們的思路,程序容易理解;遞歸函數(shù):

只須寫出遞歸公式和遞歸結束條件(即邊界條件),即可很容易寫出遞歸函數(shù);5/7/2024第九講——函數(shù)、遞推、遞歸局部變量和全局變量大35一個程序可以包括若干個源程序文件(文件模塊);

每個源程序文件又包括若干個函數(shù);在每個函數(shù)中和函數(shù)外都可以定義變量。這些在不同地方定義的變量是否都在程序的全部范圍

內有效?如果不是,他們的有效范圍是什么呢?5/7/2024第九講——函數(shù)、遞推、遞歸局部變量和全局變量大36局部變量在一個函數(shù)內部定義的變量是內部變量,它只在

本函數(shù)范圍內有效,換句話說只有在本函數(shù)內才能使

用它們,在此函數(shù)之外是不能使用這些變量的。同樣

的,在復合語句中定義的變量只在復合語句內范圍內

有效。5/7/2024第九講——函數(shù)、遞推、遞歸float

f1(int

a){//函數(shù)f1intb,c;┆}charf2(int{inti,j;┆}intmain(){intm,n;┆{intp,q;┆}}b、c有效a有效x,

inty)i、j有效//函數(shù)f2x、y有效//主函數(shù)p、q在復合語句中有效m、n有效大375/7/2024第九講——函數(shù)、遞推、遞歸a也只在f1函數(shù)中有效。其他函數(shù)不能調用。大連理工大學

盤錦校區(qū)基礎教學部38說明:(1)

主函數(shù)main中定義的變量(m,n)也只在主函數(shù)

中有效,不會因為在主函數(shù)中定義而在整個文件或

程序中有效。主函數(shù)也不能使用其他函數(shù)中定義的

變量。(2)

不同函數(shù)中可以使用同名的變量,它們代表不

同的對象,互不干擾。例如,在f1函數(shù)中定義了變量

b和c,倘若在f2函數(shù)中也定義變量b和c,它們在內存

中占不同的單元,不會混淆。(3)

可以在一個函數(shù)內的復合語句中定義變量,這些變量只在本復合語句中有效,這種復合語句也稱

為分程序或程序塊。(4)

形式參數(shù)也是局部變量。例如f1函數(shù)中的形參大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸大39(5)

在函數(shù)聲明中出現(xiàn)的參數(shù)名,其作用范圍只在本

行的括號內。實際上,編譯系統(tǒng)對函數(shù)聲明中的變量

名是忽略的,即使在調用函數(shù)時也沒有為它們分配存儲單元。

例如intmax(inta,intb);┆intmax(intx,int y){cout<<x<<y<<endl;cout<<a<<b<<endl;}//函數(shù)聲明中出現(xiàn)a、b//函數(shù)定義,形參是x、y//合法,x、y在函數(shù)體中有效//非法,a、b在函數(shù)體中無效編譯時認為max函數(shù)體中的a和b未經(jīng)定義。5/7/2024第九講——函數(shù)、遞推、遞歸全局變量大40程序的編譯單位是源程序文件(.cpp),一個源文

件可以包含一個或若干個函數(shù)。在函數(shù)內定義的變量是局部變量,而在函數(shù)之外定

義的變量是外部變量,稱為全局變量(globalvariable,也稱全程變量)。全局變量的有效范圍為從定義變量的位置開始到

本源文件結束。如5/7/2024第九講——函數(shù)、遞推、遞歸intp=1,q=5;//全局變量float

f //定義函數(shù)f11(a)inta;圍全局變量c1、c2的作用范圍(inta)大41{intb,c;┆}charc1,c2;charf2(int

x,inty)//定義函數(shù)f2{inti,j;┆}main(

)//主函數(shù){intm,n;┆}5/7/2024第九講——函數(shù)、遞推、遞歸大42p、q、c1、c2都是全局變量,但它們的作用范圍不

同,在main函數(shù)和f2函數(shù)中可以使用全局變量p、q、c1、c2,但在函數(shù)f1中只能使用全局變量p、q,而

不能使用c1和c2。在一個函數(shù)中既可以使用本函數(shù)中的局部變量,又

可以使用有效的全局變量。說明:(1)

設全局變量的作用是增加函數(shù)間數(shù)據(jù)聯(lián)系的渠

道。(2)

建議不在必要時不要使用全局變量,因為:①

全局變量在程序的全部執(zhí)行過程中都占用存儲單元,而不是僅在需要時才開辟單元。5/7/2024第九講——函數(shù)、遞推、遞歸大43②在程序設計中,在劃分模塊時要求模塊的內聚性強、與其他模塊的耦合性弱。即模塊的功能要單

一(不要把許多互不相干的功能放到一個模塊中),

與其他模塊的相互影響要盡量少,而用全局變量是

不符合這個原則的。一般要求把程序中的函數(shù)做成一個封閉體,除

了可以通過“實參——形參”的渠道與外界發(fā)生聯(lián)

系外,沒有其他渠道。這樣的程序移植性好,可讀性強。5/7/2024第九講——函數(shù)、遞推、遞歸大連理工大學

盤錦校區(qū)基礎教學部 44③使用全局變量過多,會降低程序的清晰性。在各個函數(shù)執(zhí)行時都可能改變全局變量的值,程序容易

出錯。因此,要限制使用全局變量。(3)

如果在同一個源文件中,全局變量與局部變量

同名,則在局部變量的作用范圍內,全局變量被屏

蔽,即它不起作用。變量的有效范圍稱為變量的作用域(scope)。歸納起

來,變量有4種不同的作用域:

文件作用域(filescope)、函數(shù)作用域(function

scope)、塊作用域

(block

scope)和函數(shù)原型作用域(functionprototype

scope)。文件作用域是全局的,其他三者是局部的。44大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸變量的存儲類別大45已介紹了變量的一種屬性——作用域,作用域是從

空間的角度來分析的,分為全局變量和局部變量。變量還有另一種屬性——存儲期(storageduration,也稱生命期)。存儲期是指變量在內存中

的存在時間。這是從變量值存在的時間角度來分析的。存儲期可以分為靜態(tài)存儲期(static

storageduration)和動態(tài)存儲期(dynamic

storageduration)。這是由變量的靜態(tài)存儲方式和動態(tài)存儲

方式?jīng)Q定的。5/7/2024第九講——函數(shù)、遞推、遞歸存儲方式大46靜態(tài)存儲方式是指在程序運行期間,系統(tǒng)對變量分配固定的存儲空間。動態(tài)存儲方式則是在程序運行期間,系統(tǒng)對變量動

態(tài)地分配存儲空間。5/7/2024第九講——函數(shù)、遞推、遞歸存儲方式先看一下內存中的供用戶使用的存儲空間的情況。這個存儲空間可以分為三部分,即:(1)

程序區(qū)(2)

靜態(tài)存儲區(qū)(3)

動態(tài)存儲區(qū)大475/7/2024第九講——函數(shù)、遞推、遞歸靜態(tài)存儲區(qū)大48數(shù)據(jù)分別存放在靜態(tài)存儲區(qū)和動態(tài)存儲區(qū)中。全局變量全部存放在靜態(tài)存儲區(qū)中,在程序開始執(zhí)行

時給全局變量分配存儲單元,程序執(zhí)行完畢就釋放這

些空間。在程序執(zhí)行過程中它們占據(jù)固定的存儲單元,而不是

動態(tài)地進行分配和釋放。5/7/2024第九講——函數(shù)、遞推、遞歸動態(tài)存儲區(qū)大49在動態(tài)存儲區(qū)中存放以下數(shù)據(jù):①函數(shù)形式參數(shù)。在調用函數(shù)時給形參分配存儲空間。②函數(shù)中的自動變量(未加static聲明的局部變量,

詳見后面的介紹)。③函數(shù)調用時的現(xiàn)場保護和返回地址等。

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

間,函數(shù)結束時釋放這些空間。在程序執(zhí)行過程中,這種分配和釋放是動態(tài)的,如果在一個程序中兩次調用同一函數(shù),則要進行兩次分配和釋放,而兩次分配給此函數(shù)中局部變量的存儲空間地址可能是不相同的。5/7/2024第九講——函數(shù)、遞推、遞歸50大連理工大學

盤錦校區(qū)基礎教學部如果在一個程序中包含若干個函數(shù),每個函數(shù)中的

局部變量的存儲期并不等于整個程序的執(zhí)行周期,它

只是整個程序執(zhí)行周期的一部分。根據(jù)函數(shù)調用的情況,系統(tǒng)對局部變量動態(tài)地分配和釋放存儲空間。在C++中變量除了有數(shù)據(jù)類型的屬性之外,還有存儲類別(storage

class)

的屬性。存儲類別指的是數(shù)

據(jù)在內存中存儲的方法。存儲方法分為靜態(tài)存儲和動態(tài)存儲兩大類。具體包含4種:自動的(auto)、靜態(tài)的(static)、寄存器的(register)和外部的(extern)。根據(jù)變量的存儲類別,可以知道變量的作用域和存儲期。50大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸自動變量大51函數(shù)中的局部變量,如果不用關鍵字static加以聲明,編譯系統(tǒng)對它們是動態(tài)地分配存儲空間的。函數(shù)的形參和在函數(shù)中定義的變量(包括在復合語

句中定義的變量)都屬此類。在調用該函數(shù)時,系統(tǒng)給形參和函數(shù)中定義的變量

分配存儲空間,數(shù)據(jù)存儲在動態(tài)存儲區(qū)中。在函數(shù)調

用結束時就自動釋放這些空間。如果是在復合語句中

定義的變量,則在變量定義時分配存儲空間,在復合

語句結束時自動釋放空間。因此這類局部變量稱為自

動變量(auto

variable)。5/7/2024第九講——函數(shù)、遞推、遞歸用register聲明寄存器變量一般情況下,變量的值是存放在內存中的。當程序中用到哪一個變量的值時,由控制器發(fā)出指令將內存中

該變量的值送到CPU中的運算器。經(jīng)過運算器進行運算,

如果需要存數(shù),再從運算器將數(shù)據(jù)送到內存存放。如圖

所示。為提高執(zhí)行效率,C++允許將局部變量的放在CPU中的寄存器中,需要用時直接從寄

存器取出參加運算,不必再到內存中去存

取。這種變量叫做寄存器變量,用關鍵字register作聲明。但是,是建議性的;值大525/7/2024第九講——函數(shù)、遞推、遞歸用static聲明靜態(tài)局部變量大53有時希望函數(shù)中的局部變量的值在函數(shù)調用結束后不

消失而保留原值,即其占用的存儲單元不釋放,在下

一次該函數(shù)調用時,該變量保留上一次函數(shù)調用結束

時的值。這時就應該指定該局部變量為靜態(tài)局部變量

(static

local

variable)。5/7/2024第九講——函數(shù)、遞推、遞歸大545/7/2024第九講——函數(shù)、遞推、遞歸先后3次調用f函數(shù)時,b和c的值如書中表所示。大555/7/2024第九講——函數(shù)、遞推、遞歸靜態(tài)局部變量說明(1)

靜態(tài)局部變量在靜態(tài)存儲區(qū)內分配存儲單元。

在程序整個運行期間都不釋放。而自動變量(即動態(tài)局部變量)屬于動態(tài)存儲類別,存儲在動態(tài)存儲

區(qū)空間(而不是靜態(tài)存儲區(qū)空間),函數(shù)調用結束后

即釋放。(2)

為靜態(tài)局部變量賦初值是在編譯時進行值的,

即只賦初值一次,在程序運行時它已有初值。以后

每次調用函數(shù)時不再重新賦初值而只是保留上次函

數(shù)調用結束時的值。而為自動變量賦初值,不是在

編譯時進行的,而是在函數(shù)調用時進行,每調用一

次函數(shù)重新給一次初值大連,理工相大學當盤錦校于區(qū)基執(zhí)礎教行學部一次賦值語句。

5656大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸(3)

如果在定義局部變量時不賦初值的話,對靜態(tài)局部變量來說,編譯時自動賦初值0(對數(shù)值型變量)或空字符(對字符型變量)。而對自動變量來說,如

果不賦初值,則它的值是一個不確定的值。這是由于每次函數(shù)調用結束后存儲單元已釋放,下次調用時又重新另分配存儲單元,而所分配的單元中的值

是不確定的。大57(4)

雖然靜態(tài)局部變量在函數(shù)調用結束后仍然存在,但其他函數(shù)是不能引用它的,也就是說,在其他函數(shù)中它是“不可見”的。5/7/2024第九講——函數(shù)、遞推、遞歸靜態(tài)局部變量使用大58在什么情況下需要用局部靜態(tài)變量呢?1.

需要保留函數(shù)上一次調用結束時的值。例如可以用下例中的方法求n!。如:int

fac(int

n){

static

int

f=1;//f為靜態(tài)局部變量,函數(shù)結束//

時f的值不釋放//在f原值基礎上乘以nf=f*n;returnf;}5/7/2024第九講——函數(shù)、遞推、遞歸靜態(tài)局部變量使用大592.

如果初始化后,變量只被引用而不改變其值,則這時用靜態(tài)局部變量比較方便,以免每次調用時重新賦值。5/7/2024第九講——函數(shù)、遞推、遞歸用extern聲明外部變量大60全局變量(外部變量)是在函數(shù)的外部定義的,它的作用域為從變量的定義處開始,到本程序文件的末

尾。在此作用域內,全局變量可以為本文件中各個函

數(shù)所引用。編譯時將全局變量分配在靜態(tài)存儲區(qū)。有時需要用extern來聲明全局變量,以擴展全局變量的作用域。5/7/2024第九講——函數(shù)、遞推、遞歸在一個文件內聲明全局變量提前引用聲明大連理工大學

盤錦校區(qū)基礎教學部61大連理工大學

盤錦校區(qū)基礎教學部5/7/2024第九講——函數(shù)、遞推、遞歸在多文件程序中聲明外部變量大62外部變量聲明分析下例:

file1.cppexternint a,b;intmain(

){cout<<a<<″,″<<b<<endl;return 0;}注意:file2.cppint a=3,b=4;┆extern

是用作變量聲明,而不是變量定義。它只是對一個已定義的外部變量作聲明,以擴展其作用域。5/7/2024第九講——函數(shù)、遞推、遞歸用extern擴展全局變量的作用域,雖然能為程序設

計帶來方便,但應十分慎重,因為在執(zhí)行一個文件中的大63函數(shù)時,可能會改變了該全局變量的值,從而會影響到另一文件中的函數(shù)執(zhí)行結果。5/7/2024第九講——函數(shù)、遞推、遞歸用static聲明靜態(tài)外部變量大64有時在程序設計中希望某些外部變量只限于被本文件引用,而不能被其他文件引用。這時可以在定義外部變量時加一個static聲明。例如:file1.cppstatic

int

a=3;int

main

(

){┆file2.cppextern

int

a;int

fun

(int

n){

┆a=a*n;┆}}5/7/2024第九講——函數(shù)、遞推、遞歸這種加上static聲明、只能用于本文件的外部變量(全局變量)稱為靜態(tài)外部變量。這就為程序的模塊化、

通用性提供了方便。如果已知道其他文件不需要引用本

文件的全局變量,可以對本文件中的全局變量都加上static,成為靜態(tài)外部變量,以免被其他文件誤用。大65需要指出,不要誤認為用static聲明的外部變量才采

用靜態(tài)存儲方式(存放在靜態(tài)存儲區(qū)中),而不加static的是動態(tài)存儲(存放在動態(tài)存儲區(qū))。實際上,

兩種形式的外部變量都用靜態(tài)存儲方式,只是作用范圍不同而已,都是在編譯時分配內存的。5/7/2024第九講——函數(shù)、遞推、遞歸存儲期和作用域大665/7/2024第九講——函數(shù)、遞推、遞歸變量的聲明和定義大67關于聲明和定義:針對函數(shù)而言,函數(shù)的聲明是函數(shù)的原型,而函數(shù)的定義是函數(shù)功能的建立;在聲明部分出現(xiàn)的變量有兩種情況:一種是需要建立

存儲空間的(如

int

a

);另一種是不需要建立存儲

空間的(extern

int

a

);前者稱為定義性聲明,或簡稱定義;后者稱為引用性聲明;5/7/2024第九講——函數(shù)、遞推、遞歸為敘述方便,把建立存儲空間的聲明稱為定義;大68如:int

a;而把不需要建立存儲空間的聲明稱為聲明;如:extern

int

a;5/7/2024第九講——函數(shù)、遞推、遞歸外部變量定義和外部變量聲明的含義是不同的。外大69部變量的定義只能有一次,它的位置在所有函數(shù)之外,

而同一文件中的外部變量的聲明可以有多次,它的位置

可以在函數(shù)之內,也可以在函數(shù)之外。系統(tǒng)根據(jù)外部變

量的定義分配存儲單元。對外部變量的初始化只能在定

義時進行,而不能在聲明中進行。所謂聲明,其作用是

向編譯系統(tǒng)發(fā)出一個信息,聲明該變量是一個在后面定

義的外部變量,僅僅是為了提前引用該變量而作的聲明。extern只用作聲明,而不用于定義。5/7/2024第九講——函數(shù)、遞推、遞歸用static來聲明一個變量的作用有二:大70(1)對局部變量用static聲明,使該變量在本函數(shù)調用結束后不釋放,整個程序執(zhí)行期間始終存在,使其存儲期為程序的全過程。(2)全局變量用static聲明,則該變量的作用域只限于本文件模塊(即被聲明的文件中)。5

溫馨提示

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

評論

0/150

提交評論