版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第六章函數(shù)與編譯預(yù)處理6.1模塊化程序設(shè)計與函數(shù)6.2函數(shù)的定義與調(diào)用6.3函數(shù)的遞歸調(diào)用6.4變量的作用域與存取方式6.5編譯預(yù)處理C語言程序設(shè)計教程2025/1/1516.1模塊化程序設(shè)計與函數(shù)在設(shè)計較復(fù)雜的程序時,我們一般采用的方法是:把問題分成幾個部分,每部分又可分成更細的若干小部分,逐步細化,直至分解成很容易求解的小問題。這樣的話,原來問題的解就可以用這些小問題來表示。2基本概念基本模塊模塊模塊模塊模塊模塊模塊模塊模塊模塊2025/1/153模塊與函數(shù)C語言程序由基本語句和函數(shù)組成,每個函數(shù)可完成相對獨立的任務(wù),依一定的規(guī)則調(diào)用這些函數(shù),就組成了解決某個特定問題的程序。4模塊與函數(shù)把大任務(wù)分解成若干功能模塊,用多個函數(shù)來實現(xiàn)這些功能模塊。通過函數(shù)的調(diào)用來實現(xiàn)完成大任務(wù)的全部功能。
5模塊與函數(shù)任務(wù)、模塊與函數(shù)的關(guān)系:一個大任務(wù)分成多個功能模塊,
功能模塊則由一個或多函數(shù)實現(xiàn)。
模塊化的程序設(shè)計是靠設(shè)計函數(shù)和調(diào)用函數(shù)實現(xiàn)的。6例:分數(shù)排序任務(wù):輸入三個數(shù),從大到小的順序的輸出。如果大 于等于85,在該數(shù)后面輸出‘A’,小于85且大 于等于70,則輸出‘B’,小于70且大于等于60, 輸出‘C’,如果小于60,則輸出‘D’。思路:scanf()輸入分數(shù)
另建一個排序函數(shù)
判斷并輸出等級函數(shù)
打印分數(shù)及等級的函數(shù)雖然也可以由一個主函數(shù)來完成,但這樣做可讀性及操作性會更好。7
voidmain(){floata,b,c;
scanf("%f,%f,%f",&a,&b,&c);/*輸入*/
sortabc(&a,&b,&c);/*排序*/
putabc(a,b,c);/*輸出a,b,c三個數(shù)*/}8voidsortabc(a,b,c)floata,b,c;{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的值*/}9chargrade(x)/*根據(jù)x的值,得到等級標(biāo)準*/
floatx;{if(x>=85)return('A');elseif(x>=70)return('B');elseif(x>=60)return('C');else
return('D');
}10
voidputabc(a,b,c)floata,b,c;{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);}
11模塊設(shè)計的原則模塊獨立規(guī)模適當(dāng)層次分明功能專一12獨立性原則表現(xiàn)在模塊完成獨立的功能,和其它模塊間的關(guān)系簡單,各模塊可以單獨調(diào)試。修改某一模塊,不會造成整個程序的混亂。每個模塊完成一個相對獨立的特定子功能。在對任務(wù)逐步分解時,要注意對問題的綜合。例如,一些模塊的相似的子任務(wù),可以把它們綜合起來考慮,找出它們的共性,把它們做成一個完成特定任務(wù)的單獨模塊。每個模塊有特定功能13模塊之間最好只通過數(shù)據(jù)傳遞發(fā)生聯(lián)系,而不發(fā)生控制聯(lián)系。例如,C語言禁止goto語句作用到另一個函數(shù),就是為了保證函數(shù)的獨立性。每個模塊力求簡單14模塊內(nèi)使用的數(shù)據(jù),對于不需要這些數(shù)據(jù)的其它模塊來說,應(yīng)該不允許使用;在一個模塊內(nèi)的變量的修改不會影響其它模塊的數(shù)據(jù)。即模塊的私有數(shù)據(jù)只屬于這個模塊。C語言的局部變量,就是滿足模塊獨立的的需要。每個模塊應(yīng)用獨立變量15模塊不能太大,但也不能太小。模塊的功能復(fù)雜,可讀性就不好,而且也違背獨立性原則。但如果做得太小,實際上也會復(fù)雜各個模塊間反復(fù)調(diào)用,可讀性也會降低。這點需要慢慢積累經(jīng)驗,好好把握。16算法簡介算法簡介算法簡介什么是算法?通俗地說,算法是解決一類特定問題的方法和步驟。
算法是一個有限操作的序列。算法的每一步都是確定的。算法的每一步計算機都能操作。有一個或多個的輸入或輸出。17算法的描述算法描述的任務(wù)是將解題步驟和方法用一定的形式表示出來,要清楚、準確、嚴謹,還要可讀性好,方便實現(xiàn)。
算法兩大要素:
一是操作,用類計算機語句或自然語言描述。
二是控制結(jié)構(gòu),描述算法一般可以用流程圖描述。18例6.2
設(shè)計算法:找出a,b兩數(shù)中的較大者,并輸出分析:這個問題分三個步驟:
輸入兩個數(shù);
找出其中的大數(shù);
輸出大數(shù)。19開始輸入a,ba<b交換a,b輸出a結(jié)束非00圖6.3找出a,b兩數(shù)中的較大者算法流程圖
2025/1/15206.2函數(shù)的定義與調(diào)用在C語言中,函數(shù)(Function)是一個處理過程,可以進行數(shù)值運算、信息處理、控制決策,即一段程序的工作放在函數(shù)中進行,函數(shù)結(jié)束時可以攜帶或不帶處理結(jié)果。
庫函數(shù)(標(biāo)準函數(shù)):系統(tǒng)提供
自定義函數(shù):用戶自己寫
21C語言程序處理過程全部都是以函數(shù)形式出現(xiàn),最簡單的程序至少也有一個main函數(shù)。函數(shù)必須先定義和聲明后才能調(diào)用。22標(biāo)準庫函數(shù)C語言有豐富的庫函數(shù),這些函數(shù)的說明在不同的頭文件(*.h)中。想要調(diào)用標(biāo)準的庫函數(shù),就必須include。#include<stdio.h>
main()
{printf(“%d”,1024*768);
}調(diào)用printf函數(shù)時,
必須include<stdio.h>23自定義函數(shù)可以把完成一個任務(wù)的過程寫成函數(shù)。int
A_to_a(intcapital)
{intsmall;
if(capital>=‘A’&&capital<=‘Z’)
small=capital–(‘A’-’a’);
returnsmall;
}返回值類型名函數(shù)名注意不要與已有庫函數(shù)重名參數(shù)說明和參數(shù)列表調(diào)用函數(shù)時輸入?yún)?shù)的格式要與之相同定義局部變量最好只使用局部變量,這樣將方便調(diào)試。返回值如果不需返回則可return0;另外請注意這樣的判斷,如寫成‘A’<capital<‘Z’是不行的24“函數(shù)”的主要知識點
函數(shù)的定義函數(shù)的參數(shù)和返回值
函數(shù)的調(diào)用嵌套和遞歸變量的作用域25函數(shù)舉例#include<conio.h>
main()
{inta,b,m;
/*說明變量*/
int
max(int
a,intb);
/*函數(shù)聲明*/
scanf("%d,%d",&a,&b);
/*調(diào)用庫函數(shù)scanf*/
m=max(a,b);
/*調(diào)用字定義函數(shù)max*/
printf("max=%d\n",m));
/*調(diào)用庫函數(shù)printf*/
getch();
/*調(diào)用庫函數(shù)getch*/
}
26函數(shù)舉例int
max(int
a,intb)
/*定義函數(shù)max*/
{
inty;
y=(a>b)?a:b;/*條件表達式*/
returny;
}if(a>b)y=a;
elsey=b;27自定義函數(shù)的聲明自定義函數(shù)在調(diào)用前應(yīng)先聲明。使系統(tǒng)知道將要用到某個函數(shù)及它的類型,以便處理。函數(shù)聲明應(yīng)與該函數(shù)定義時給出的函數(shù)類型與名字、形參的個數(shù)、類型、次序相一致。#include“stdio.h”
voidmain()
{floatx,y;
intn;
floatpower(floatx,intn);
scanf("%f,%d",&x,&n);
y=power(x,n);printf(“%8.2f”,y);
}floatpower(floatx,intn)
{inti;
floatt=1;
for(i=1;i<=n;i++)
t=t*x;
returnt;
}28求1!+2!+3!+…+10!算法
i=1;s=0;
當(dāng)i<=10s=s+
i!
定義求i!的函數(shù)29求1!+2!+3!+…+10!程序voidmain(){longmm(int);/*自定義求階乘函數(shù)應(yīng)先聲明*/
inti;longs=0;for(i=1;i<=10;i++)s+=mm(i);/*調(diào)用求階乘函數(shù),求I的階乘*/
printf(“\n%ld”,s);}30定義求n!的函數(shù)longmm(intn){longt=1;inti;for(i=1;i<=n;i++)t*=i;returnt;}31同樣的,在調(diào)用
m=max(a,b)時,其形參
的值是a和b
而m將會得到y(tǒng)的值函數(shù)的參數(shù)int
max(int
a,intb)
{
inty;
y=(a>b)?a:b;
returny;
}調(diào)用時:m=max(3,6);
m=max(a,b);
括號里是形式參數(shù)返回值括號里是實參在這一句調(diào)用時,
形參的值是3和6其返回值y將被賦給
調(diào)用語句中的m32形式參數(shù)與實際參數(shù)的關(guān)系形式參數(shù)在函數(shù)中是變量名,
在函數(shù)調(diào)用時,形參被分配相應(yīng)的內(nèi)存實際參數(shù)是表達式
負責(zé)向?qū)?yīng)的形參標(biāo)識的內(nèi)存單元傳遞數(shù)據(jù)實參與形參必須個數(shù)相同對應(yīng)的形參和實參的類型必須一致
實參給形參傳遞值得時候,按順序傳遞,與形參名無關(guān)。所以實參與形參可以不同名。33實參與形參例:主調(diào)函數(shù)中有如下語句:
scanf("%d,%d",&a,&b);
m=max(a,b+3);如果輸入6,2函數(shù)int
max(int
a,intb)形參a得到第一個實際參數(shù)a的值6形參b得到第二個實際參數(shù)b+3的值5
34函數(shù)返回值函數(shù)返回值通過return語句獲得函數(shù)返回值的類型就是函數(shù)的類型
returny;
將變量y的值返回給調(diào)用者
returny+3;
將表達式的值返回給調(diào)用者35return的數(shù)據(jù)類型與函數(shù)的類型矛盾時,自動將數(shù)據(jù)轉(zhuǎn)換成函數(shù)的類型intfunct1(){charch;
while
((ch=getch())<'a'||(ch>'z')
;
returnch;}調(diào)用:i=funct1();/*返回的是int類型*/36函數(shù)沒有返回值,函數(shù)定義成空類型voidputline()
{inti;
for(i=0;i<35;i++)
printf("-");
printf("\n");
}函數(shù)的功能就是輸出35個‘-’
調(diào)用:putline();
應(yīng)該的語句形式
i=putline();是錯的37調(diào)用函數(shù)a=function(x,y);
或者
function(x,y);
取返回值
只是操作解決更復(fù)雜問題時可以嵌套調(diào)用。longfac(intk)
{longf=1;
inti;
for(i=1;i<=k;i++)
f=f*i;
returnf;
}
longcombination(intn,intm)
{longc;
inti;
c=fac(m)/(fac(n)*fac(m-n));
returnc;
}
主函數(shù):
main()
{intn,m;
longc;
scanf(“%d,%d”,&n,&m);
c=combination(n,m);
printf(“%ld”,c);
}理論上可以a(b(d(e(x))),c(f))
般嵌套無數(shù)層。386.3函數(shù)的遞歸調(diào)用函數(shù)調(diào)用它本身,稱為遞歸。直接在函數(shù)內(nèi)調(diào)用自己為直接遞歸,通過別的函數(shù)調(diào)用自己為間接遞歸。voida()
{......
a();
......
}voida()
{......
b();......
}
voidb()
{......
a();
......
}遞歸在解決某些問題中,是一個十分有用的方法。因為其一,有的問題它本身就是遞歸定義的;其二,它可以使某些看起來不易解決的問題變得容易解決,寫出的程序較簡短。39遞歸方法求n!由于n!=n*(n-1)!是遞歸定義所以求n!
(n-1)!
(n-1)!
(n-2)!
(n–2)!
(n-3)!
……
0!的問題,
根據(jù)公式有0!=1。
再反過來依次求出1!,2!……直到最后求出n!。40遞歸方法求n!longfac(intn)
{longf;
if(n==0)
f=1;
else
f=n*fac(n-1);
returnf;
}
main()
{longy;
intn;
scanf(“%d”,&n);
y=fac(n);
printf(“%d!=%ld”,n,y);
}剛開始的時候,這個n是前面
輸入的需要階乘的n所以在這里帶入的值是n而這個函數(shù)里又調(diào)用
了本身,不過參數(shù)已經(jīng)
變成了n-1所以這里再次調(diào)用時
參數(shù)已經(jīng)變成了n-1注意:上次調(diào)用fac(n)
還沒有完,只是由于遇到
了fac(n-1)而執(zhí)行fac(n-1)
去了.而在調(diào)用fac(n-1)時同樣
遇到了要調(diào)用fac(n-2)的問題,于是一層一層的
包裹下去,每次調(diào)用的
時候都會在內(nèi)部調(diào)用一
個結(jié)構(gòu)相同但變量不同
的函數(shù),直到。。。直到調(diào)用到fac(0)時,由于內(nèi)部if判斷,已經(jīng)
不需要再繼續(xù)調(diào)用另一
個fac(n-1),而直接有了f=1fac(0)已經(jīng)執(zhí)行完畢,它的
返回值被fac(1)中的f=n*fac(n-1)
語句賦給了f值,同時返回了f。而這個返回的f又被fac(2)乘上
當(dāng)前的n值以后繼續(xù)返回f直到最后的fac(n)都做完了,
f的值被返回到了它的調(diào)用點:
主函數(shù)中,這樣就是一個遞歸
運算。41遞歸舉例問題:第1個月有1對兔子過2個月,兔子就可每個月生1對兔子問第n個月有多少對兔子?
分析:設(shè)第n個月有f(n)對兔子根據(jù)題意有f(0)=0,f(1)=1f(n)=f(n-1)+f(n-2)f(n-1):前一個月的兔子數(shù)
f(n-2):本月生的兔子數(shù)
42斐波那契其人1170年生于意大利的比薩,在北非的布吉亞,即今阿爾及利亞的貝加亞長大并且接受教育。大約在1200年,他才重新回到比薩。斐波那契無疑在啟蒙教育時期就受到過阿拉伯?dāng)?shù)學(xué)家的影響或者接受過他們的輔導(dǎo)。他寫過大量的數(shù)學(xué)論文,取得了一些重大的數(shù)學(xué)發(fā)現(xiàn)。這使他的著作在意大利非常流行,并且引發(fā)了當(dāng)時羅馬帝國皇帝弗雷德里克二世的注意,他曾邀請斐波那契到他在比薩宮廷覲見。斐波那契于1250年去世。1202年,他在所著的《算珠原理》中,提出了一個著名而有趣的兔子問題:假定一對小兔子經(jīng)過一個月后能夠長成一對大兔子,而一對大兔子經(jīng)過一個月后能夠生了一對小兔子.現(xiàn)在我們從一對小兔子開始,用表示第個月兔子的總對數(shù),顯然,(第1個月只有一對小兔子,第2個月只有一對大兔子),(第3個月一對大兔子生出一對小兔子,總共兩對兔子.
于是我們得到一個數(shù)列:1,1,2,3,5,8,13,…
仔細觀察這個數(shù)列,從第3項起每一項都是它前相鄰兩項的和,這就是著名的斐波那契數(shù)列.43定義函數(shù)f(n)longf(intn)
{
switch(n){case0:return0;break;case1:return1;break;
default:returnf(n-1)+f(n-2);/*調(diào)用函數(shù)f(n)*/}}44兔子問題主函數(shù)voidmain(){longf(intn);/*自定義函數(shù)聲明*/
intn;
printf(“\ninputn:”);
scanf(“%d”,&n);
printf(“\nf(%d)=%ld”,n,f(n));
/*調(diào)用函數(shù)f(n)*/}45斐波那契數(shù)列有一系列奇妙的性質(zhì),現(xiàn)簡列以下幾條,供大家欣賞.
1.從首項開始,我們依次計算每一項與它的后一項的比值,并精確到小數(shù)是第四位.如果將這一工作不斷地繼續(xù)下去,這個比值將無限趨近于某一個常數(shù),這個常數(shù)位于1.6180與1.6181之間,它還能準確地用黃金數(shù)表示出黃金分割率。
2.在自然界中,斐波那契數(shù)列也常見到,比如:向日葵花冠上的螺旋,如果前一道螺旋直徑為21的話,下一道螺旋直徑則為34,依次形成連續(xù)的斐波那契數(shù)字;松果的外弧為順時針或逆時針方向的螺旋,期相同間隔之間螺旋的直徑也能構(gòu)成斐波那契數(shù)列;在上等的鸚鵡螺身上,每圈羅紋的直徑與相鄰羅紋直徑之比亦是1:1.618,菠蘿是又一種可以檢驗斐波那契數(shù)的植物;菠蘿表皮方塊形鱗苞形成兩組旋向相反的螺線,它們的條數(shù)必須是這個級數(shù)中緊鄰的兩個數(shù)字(如左旋8行,右旋13行)。
463.有一種兩人游戲,名叫“尼姆”。游戲方法是由兩個人輪流取一堆粒數(shù)不限的砂子。先取的一方可以取任意粒,但不能把這堆砂子全部取走。后取的一方,取數(shù)也多少不拘,但最多不能超過對方所取砂子數(shù)的一倍。然后又輪到先取的一方來取,但也不能超過對方最后一次所取砂子的一倍。這樣交替地進行下去,直到全部砂子被取光為止,誰能拿到最后一粒砂子,誰就算勝利者。在這個游戲中,若所有砂子的粒數(shù)是個斐波那契數(shù)的話,那么后取的一方穩(wěn)操勝券,但所有的砂子不是一個斐波那契數(shù)的話,那么先取的一方穩(wěn)勝。47輾轉(zhuǎn)相除法求最大公約數(shù)求m和n的公約數(shù)算法if(m%n)==0
n是公約數(shù);
else
求n和m%n的公約數(shù);
48用歐幾里德算法(輾轉(zhuǎn)相除法)求兩個數(shù)的最大公約數(shù)的步驟如下:
1.若r是a÷b的余數(shù),則
gcd(a,b)=gcd(b,r)
2.a和其倍數(shù)之最大公因子為a。
49求最大公約數(shù)的遞歸算法
int
gcd(intm,intn)
{if(m%n)==0
returnn;
else
returngcd(n,
m%n);}50求最大公約數(shù)的主函數(shù)voidmain(){intm,n,t;
int
gcd(intm,intn);
scanf(“%d%d”,&m,&n);
if(m<n)
{t=m;m=n;n=t;}
t=gcd(m,n);/*調(diào)用函數(shù)gcd(m,n);
*/print(“\ngcd=%d”,t);}51漢諾塔(又稱河內(nèi)塔)問題是印度的一個古老的傳說。開天辟地的神勃拉瑪在一個廟里留下了三根金剛石的棒,第一根上面套著64個圓的金片,最大的一個在底下,其余一個比一個小,依次疊上去,廟里的眾僧不倦地把它們一個個地從這根棒搬到另一根棒上,規(guī)定可利用中間的一根棒作為幫助,但每次只能搬一個,而且大的不能放在小的上面。面對龐大的數(shù)字(移動圓片的次數(shù))18446744073709551615,看來,眾僧們耗盡畢生精力也不可能完成金片的移動。漢諾塔52后來,這個傳說就演變?yōu)闈h諾塔游戲:
1.有三根桿子A,B,C。A桿上有若干碟子。
2.每次移動一塊碟子,小的只能疊在大的上面。
3.把所有碟子從A桿全部移到C桿上。經(jīng)過研究發(fā)現(xiàn),漢諾塔的破解很簡單,就是按照移動規(guī)則向一個方向移動金片,如3階漢諾塔的移動:A→C,A→B,C→B,A→C,B→A,B→C,A→C此外,漢諾塔問題也是程序設(shè)計中的經(jīng)典遞歸問題。
算法思路:
1.如果只有一個金片,則把該金片從源移動到目標(biāo)棒,結(jié)束。
2.如果有n個金片,則把前n-1個金片移動到輔助的棒,然后把自己移動到目標(biāo)棒,最后再把前n-1個移動到目標(biāo)棒
53漢諾塔是一個很繁雜的游戲,但用遞歸的方法解決起來異常簡單。規(guī)則:(1)一次只能移動一個
(2)大的不能放在小的上面
(3)只能在三個位置中移動54問題可分為三個步驟對于把n個金片從第一根針a上移到第三根針c的問題可以分解成如下步驟:
(1)將n-1個金片從a經(jīng)過c移動到b。(2)將第n個金片移動到c。(3)再將n-1個盤子從b經(jīng)過a移動到c。這樣我們就將移動n個金片的問題變成了移動n-1個金片的問題。這樣做下去的話最后就會變成移動一個金片的問題。55遞歸方法解漢諾塔voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}n=1時,直接將金片
從a移動到cn-1個金片從a經(jīng)過
c移動到b將第n個金片
從a移動到c再將n-1個金片從
b經(jīng)過a移動到cmain()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}56遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}輸入3。則n=357遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}
主函數(shù)調(diào)用hanoi(n,1,2,3);第一次調(diào)用。第一次調(diào)用hanoi(n,a,b,c)(第一層)即要把三個金片移到cn=358遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}由于n>1則執(zhí)行hanoi(n-1,a,c,b)
(第二次調(diào)用)n=359遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}由于仍然n>1則執(zhí)行
hanoi(n-1,a,c,b)
(第三次調(diào)用)n=260遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}由于n=1則printf(“%d->%d”,a,c);
即把金片從a移動到c
n=161遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}第三層執(zhí)行完畢,返回到第二層,即下去執(zhí)行printf(“%d->%d”,a,c);把第二個金片擺到第二根針上n=262遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}執(zhí)行下一條語句,又調(diào)用第三層hanoi(1,3,1,2)n=263遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}n=1,執(zhí)行結(jié)果為32n=164遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}第二層也執(zhí)行完了,返回第一層,執(zhí)行接下來的語句,結(jié)果為13。n=365遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}執(zhí)行接下來的語句,再次調(diào)用
第二層hanoi(2,2,1,3)n=366遞歸漢諾塔步驟voidhanoi(intn,inta,intb,intc)
{
if(n==1)
printf(“%d->%d”,a,c);
else
{hanoi(n-1,a,c,b);
printf(“%d->%d”,a,c);
hanoi(n-1,b,a,c);
}
}main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}676.4變量的作用域與存儲方式先看一個例子,錯在那里?:voidf1(){intt=2;a*=t;b/=t;}main(){inta,b;
printf(“Entera,b:”);
scanf(“%d,%d”,&a,&b);f1();/*調(diào)用函數(shù)f1()*/
printf(“a=%d,b=%d”,a,b);}編譯程序會提示出錯:Undefinedsymbol‘a(chǎn)’和Undefinedsymbol‘b’
。為什么?2025/1/1568一.變量的作用域
即變量的有效范圍1.變量按作用域分為全局變量和局部變量2.比較:全局變量(外部變量)局部變量(內(nèi)部變量)定義位置:函數(shù)體外函數(shù)體內(nèi)作用域:從定義處到本源從定義處到本函數(shù)結(jié)束文件結(jié)束舉例:所有函數(shù)體外定義的變量(1)所有在函數(shù)體內(nèi)定義(2)形式參數(shù)注意與局部變量同名的處理局部變量屏蔽全局變量不同函數(shù)中同名局部變量互不干擾
2025/1/1569#include<stdio.h>inta,b;/*a,b為全局變量*/voidf1(intx){intt1,t2,a;a=t1=x*4;t2=b*3;b=10;
printf(“f1:t1=%d,t2=%d,a=%d,b=%d\n”,t1,t2,a,b);}main(){a=2;b=4;/*此a,b是全局變量,賦值*/
f1(a);/*調(diào)用函數(shù)f1()*/
printf(“main:a=%d,b=%d”,a,b);}
程序輸出結(jié)果為:
f1:t1=8,t2=12,a=8,b=10main:a=2,b=102025/1/1570若將程序改為:#include<stdio.h>inta=2,b=4;/*a,b為全局變量*/
voidf1(){intt1,t2;t1=a*2;t2=b*3;b=100;
printf(“t1=%d,t2=%d,b=%d\n”,t1,t2,b);}main(){intb=4;/*此b是局部變量,賦值*/
f1();/*調(diào)用函數(shù)f1()*/
printf(“a=%d,b=%d”,a,b);}結(jié)論:全局變量與局部變量同名時,局部變量起作用,全局變量被屏蔽(不影響),應(yīng)小心使用程序輸出結(jié)果為:t1=4,t2=12,b=100a=2,b=42025/1/1571二.變量的存儲特性1.變量按存在時間分
靜態(tài)變量動態(tài)變量靜態(tài)存儲類型的變量的生存期為程序執(zhí)行的整個過程,在該過程中占有固定的存儲空間,通常稱它們?yōu)橛谰么鎯?。動態(tài)存儲類型變量只生存在某一段時間內(nèi)。例如,函數(shù)的形參和函數(shù)體或分程序中定義的變量,只是在程序進入該函數(shù)或分程序時才分配存儲空間,當(dāng)該函數(shù)或分程序執(zhí)行完后,變量對應(yīng)的存儲空間又被撤銷了。2.c語言中每一個變量有兩個屬性:數(shù)據(jù)類型,存儲特性完整的變量定義:[存儲特性][數(shù)據(jù)類型]變量名;2025/1/15723.變量的存儲特性自動型auto
靜態(tài)型static
寄存器型register
外部型extern(1)auto型每次進入程序是自動分配內(nèi)存,不長期占用內(nèi)存例如:形式參數(shù),自動型局部變量(2)static型①局部靜態(tài)變量②全局靜態(tài)變量長期占用內(nèi)存2025/1/1573例1:分析執(zhí)行結(jié)果f(inta){intb=0;staticintc=3;b++;c++;printf(“%5d%5d%5d”,a,b,c);return(a+b+c);}main(){inta=2,k;for(k=0;k<3;k++)printf(“%5d\n”,f(a));}靜態(tài)變量只初始化一次。再次調(diào)用定義它的函數(shù)時變量保存了前一次被調(diào)用后留下的值。結(jié)果:214(a,b,c)7(f(a))215821692025/1/1574(3)register型將使用頻率高的變量定義為register型,可以提高運行速度.數(shù)據(jù)內(nèi)存運算器運算器結(jié)果控制器數(shù)據(jù)寄存器寄存器變量只限于整型、字符型、指針型的局部變量。寄存器變量是動態(tài)變量,而且數(shù)目有限,一般僅允許說明兩個寄存器變量。例如:
registerintd;registercharc;2025/1/1575(4)extern型引用:extern類型變量名;如果某個模塊文件中要用到另一個模塊文件中的全局變量,就要用extern說明例如:程序模塊file1.c中定義了全局變量
ints;而在另一個程序模塊file2.c中的函數(shù)fun1()中需要使用這個變量s。為此,可以在file2.c的函數(shù)fun1()中加上外部變量說明語句:fun1(){externints;/*表明變量s是在其他文件定義的*/.......}定義時分配內(nèi)存,其他文件引用時不再分配內(nèi)存.2025/1/15766.5編譯預(yù)處理
“編譯預(yù)處理”是C語言編譯系統(tǒng)的一個組成部分。是在編譯前由編譯系統(tǒng)中的預(yù)處理程序?qū)υ闯绦虻念A(yù)處理命令進行加工。源程序中的預(yù)處理命令均以“#”開頭,結(jié)束不加分號,以區(qū)別源程序中的語句,它們可以寫在程序中的任何位置,作用域是自出現(xiàn)點到源程序的末尾。預(yù)處理命令包括執(zhí)行宏定義(宏替換)、包含文件和條件編譯。2025/1/1577一.宏定義簡單宏定義1.一般形式為:#define宏名串(宏體)如:#definePI3.14159/*定義后,可以用PI來代替串3.14159*/2.宏定義的作用在宏定義之后,該程序中宏名就代表了該字符串。3.說明①可以用#undef命令終止宏定義的作用域。例如:#undefPI②宏定義的嵌套使用#defineR3.0#definePI3.1415926#defineL2*PI*R/*宏體是表達式*/#defineSPI*R*R2025/1/1578main(){printf("L=%f\nS=%f\n",L,S);/*2*PI*R替換L,PI*R*R替換S*/}程序運行結(jié)果如下:L=18.849556S=28.247333③雙引號內(nèi)與宏同名的字母不作宏展開.(見上例)帶參數(shù)的宏定義1.帶參數(shù)的宏定義的一般形式為#define宏名(參數(shù)表)字符串如:#defineS(a,b)a*b#definePR(x)printf("s=%f\n”,x)2025/1/15792.帶實參的宏名被展開宏名被所定義的宏體替換,宏體中的形參按從左到右的順序被實參替換。例如:#defineL(x)(x*x+2*x+x)宏調(diào)用:y=L(5);調(diào)用時用實參5去代替形參
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年新能源汽車車棚建設(shè)與智能管理系統(tǒng)合同4篇
- 2025年度大學(xué)生父母離婚子女監(jiān)護權(quán)爭議調(diào)解及財產(chǎn)分配合同4篇
- 2025年度民宿軟裝承接合同樣本4篇
- 2024藥店員工聘用合同協(xié)議書范文
- 2025年度門窗行業(yè)綠色建筑評價標(biāo)準制定合同3篇
- 2025年膩子產(chǎn)品出口貿(mào)易及代理銷售合同3篇
- 個人電腦硬件買賣合同2024年2篇
- 二零二五年度瓷磚專賣店品牌戰(zhàn)略規(guī)劃與執(zhí)行合同4篇
- 二零二五版果品出口貿(mào)易代理合同書2篇
- 2025年度建筑工程預(yù)決算審計承包合同規(guī)范4篇
- 農(nóng)民工工資表格
- 【寒假預(yù)習(xí)】專題04 閱讀理解 20篇 集訓(xùn)-2025年人教版(PEP)六年級英語下冊寒假提前學(xué)(含答案)
- 2024年智能監(jiān)獄安防監(jiān)控工程合同3篇
- 幼兒園籃球課培訓(xùn)
- 統(tǒng)編版(2024新版)七年級《道德與法治》上冊第一單元《少年有夢》單元測試卷(含答案)
- 100道20以內(nèi)的口算題共20份
- 高三完形填空專項訓(xùn)練單選(部分答案)
- 護理查房高鉀血癥
- 項目監(jiān)理策劃方案匯報
- 《職業(yè)培訓(xùn)師的培訓(xùn)》課件
- 建筑企業(yè)新年開工儀式方案
評論
0/150
提交評論