C語言程序設(shè)計教程第6章_第1頁
C語言程序設(shè)計教程第6章_第2頁
C語言程序設(shè)計教程第6章_第3頁
C語言程序設(shè)計教程第6章_第4頁
C語言程序設(shè)計教程第6章_第5頁
已閱讀5頁,還剩52頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第六章函數(shù)與編譯預(yù)處理6.1模塊化程序設(shè)計與函數(shù)6.2函數(shù)的定義與調(diào)用6.4變量作用域與存儲方式返回6.3函數(shù)的遞歸調(diào)用6.5編譯預(yù)處理C語言程序設(shè)計教程6.1模塊化程序設(shè)計與函數(shù)

在設(shè)計較復(fù)雜的程序時,我們一般采用的方法是:把問題分成幾個部分,每部分又可分成更細(xì)的若干小部分,逐步細(xì)化,直至分解成很容易求解的小問題。這樣的話,原來問題的解就可以用這些小問題來表示。下一頁第6章函數(shù)與編譯預(yù)處理基本模塊模塊模塊模塊模塊模塊模塊模塊模塊模塊模塊結(jié)構(gòu)圖6.1.1模塊與函數(shù)

C語言程序由基本語句和函數(shù)組成,每個函數(shù)可完成相對獨(dú)立的任務(wù),依一定的規(guī)則調(diào)用這些函數(shù),就組成了解決某個特定問題的程序。下一頁第6章函數(shù)與編譯預(yù)處理把大任務(wù)分解成若干功能模塊,用多個函數(shù)來實現(xiàn)這些功能模塊。通過函數(shù)的調(diào)用來實現(xiàn)完成大任務(wù)的全部功能。任務(wù)、模塊與函數(shù)的關(guān)系:一個大任務(wù)分成多個功能模塊,功能模塊則由一個或多個函數(shù)實現(xiàn)。模塊化的程序設(shè)計是靠設(shè)計函數(shù)和調(diào)用函數(shù)實現(xiàn)的。任務(wù):輸入三個數(shù),從大到小的順序的輸出。如果大于等于85,在該數(shù)后面輸出‘A’,小于85且大于等于70,則輸出‘B’,小于70且大于等于60,輸出‘C’,如果小于60,則輸出‘D’。思路:scanf()輸入分?jǐn)?shù)

另建一個排序函數(shù)

判斷并輸出等級函數(shù)

打印分?jǐn)?shù)及等級的函數(shù)雖然也可以由一個主函數(shù)來完成,但這樣做可讀性及操作性會更好。下一頁第6章函數(shù)與編譯預(yù)處理例如分?jǐn)?shù)排序點(diǎn)擊查看程序請6.1.2模塊設(shè)計的原則模塊獨(dú)立規(guī)模適當(dāng)層次分明功能專一下一頁第6章函數(shù)與編譯預(yù)處理

獨(dú)立性原則表現(xiàn)在模塊完成獨(dú)立的功能,和其它模塊間的關(guān)系簡單,各模塊可以單獨(dú)調(diào)試。修改某一模塊,不會造成整個程序的混亂。要做到模塊的獨(dú)立性要注意以下幾點(diǎn)每個模塊有特定功能每個模塊力求簡單每個模塊應(yīng)用獨(dú)立變量點(diǎn)擊模塊不能太大,但也不能太小。模塊的功能復(fù)雜,可讀性就不好,而且也違背獨(dú)立性原則。但如果做得太小,實際上也會復(fù)雜各個模塊間反復(fù)調(diào)用,可讀性也會降低。這點(diǎn)需要慢慢積累經(jīng)驗,好好把握。下一頁第6章函數(shù)與編譯預(yù)處理分解模塊要注意層次,更多層次的分解任務(wù),要注意對問題進(jìn)行抽象化。開始不要過于注意細(xì)節(jié),要做到逐步細(xì)化求精。6.1.3算法描述簡介什么是算法?

通俗地說,算法是解決一類特定問題的方法和步驟。

算法是一個有限操作的序列。算法的每一步都是確定的。算法的每一步計算機(jī)都能操作。有一個或多個的輸入或輸出。下一頁第6章函數(shù)與編譯預(yù)處理算法描述的任務(wù)是將解題步驟和方法用一定的形式表示出來,要清楚、準(zhǔn)確、嚴(yán)謹(jǐn),還要可讀性好,方便實現(xiàn)。

算法兩大要素:

一是操作,用類計算機(jī)語句或自然語言描述。

二是控制結(jié)構(gòu),描述算法一般可以用流程圖描述。設(shè)計算法:找出a,b兩數(shù)中的較大者,并輸出分析:這個問題分三個步驟:輸入兩個數(shù);找出其中的大數(shù);輸出大數(shù)。第6章函數(shù)與編譯預(yù)處理例6.2開始輸入a,ba<b交換a,b輸出a結(jié)束非00算法流程圖見右返回6.2函數(shù)的定義與調(diào)用在C語言中,函數(shù)(Function)是一個處理過程,可以進(jìn)行數(shù)值運(yùn)算、信息處理、控制決策,即一段程序的工作放在函數(shù)中進(jìn)行,函數(shù)結(jié)束時可以攜帶或不帶處理結(jié)果。

庫函數(shù)(標(biāo)準(zhǔn)函數(shù)):系統(tǒng)提供

自定義函數(shù):用戶自己寫下一頁第6章函數(shù)與編譯預(yù)處理

C語言程序處理過程全部都是以函數(shù)形式出現(xiàn),最簡單的程序至少也有一個main函數(shù)。函數(shù)必須先定義和聲明后才能調(diào)用?!昂瘮?shù)”的主要知識點(diǎn)函數(shù)的定義函數(shù)的參數(shù)和返回值函數(shù)的調(diào)用嵌套和遞歸變量的作用域下一頁第6章函數(shù)與編譯預(yù)處理6.2.1標(biāo)準(zhǔn)庫函數(shù)C語言有豐富的庫函數(shù),這些函數(shù)的說明在不同的頭文件(*.h)中。想要調(diào)用標(biāo)準(zhǔn)的庫函數(shù),就必須include。#include<stdio.h>

main()

{printf(“%d”,1024*768);

}調(diào)用printf函數(shù)時,

必須include<stdio.h>下一頁第6章函數(shù)與編譯預(yù)處理6.2.2函數(shù)的定義可以把完成一個任務(wù)的過程寫成函數(shù)。intA_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)試。另外請注意這樣的判斷,如寫成‘A’<capital<‘Z’是不行的下一頁第6章函數(shù)與編譯預(yù)處理如果不需返回則可return0;返回值#include<conio.h>

main()

{inta,b,m;

/*說明變量*/

intmax(inta,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*/

}下一頁第6章函數(shù)與編譯預(yù)處理舉例intmax(inta,intb)

/*定義函數(shù)max*/

{

inty;

y=(a>b)?a:b;/*條件表達(dá)式*/

returny;

}if(a>b)y=a;

elsey=b;自定義函數(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;

}下一頁第6章函數(shù)與編譯預(yù)處理求1!+2!+3!+…+10!算法:i=1;s=0;當(dāng)i<=10s=s+i!定義求i!的函數(shù)下一頁第6章函數(shù)與編譯預(yù)處理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);}舉例longmm(intn){longt=1;inti;for(i=1;i<=n;i++)t*=i;returnt;}定義n!的函數(shù)同樣的,在調(diào)用

m=max(a,b)時,其形參

的值是a和b

而m將會得到y(tǒng)的值函數(shù)的參數(shù)intmax(inta,intb)

{

inty;

y=(a>b)?a:b;

returny;

}調(diào)用時:m=max(3,6);

m=max(a,b);

返回值括號里是實參在這一句調(diào)用時,

形參的值是3和6其返回值y將被賦給

調(diào)用語句中的m下一頁第6章函數(shù)與編譯預(yù)處理括號里是形式參數(shù)形式參數(shù)與實際參數(shù)的關(guān)系形式參數(shù)在函數(shù)中是變量名,在函數(shù)調(diào)用時,形參被分配相應(yīng)的內(nèi)存。實際參數(shù)是表達(dá)式負(fù)責(zé)向?qū)?yīng)的形參標(biāo)識的內(nèi)存單元傳遞數(shù)據(jù)。實參與形參必須個數(shù)相同。對應(yīng)的形參和實參的類型必須一致。

下一頁第6章函數(shù)與編譯預(yù)處理主調(diào)函數(shù)中有如下語句:

scanf("%d,%d",&a,&b);

m=max(a,b+3);如果輸入6,2函數(shù)intmax(inta,intb)形參a得到第一個實際參數(shù)a的值6形參b得到第二個實際參數(shù)b+3的值5例如函數(shù)返回值函數(shù)返回值通過return語句獲得函數(shù)返回值的類型就是函數(shù)的類型

returny;

將變量y的值返回給調(diào)用者

returny+3;

將表達(dá)式的值返回給調(diào)用者

return的數(shù)據(jù)類型與函數(shù)的類型矛盾時,自動將數(shù)據(jù)轉(zhuǎn)換成函數(shù)的類型下一頁第6章函數(shù)與編譯預(yù)處理intfunct1(){charch;

while

((ch=getch())<'a'||(ch>'z')

;

returnch;}調(diào)用:i=funct1();返回的是int類型函數(shù)沒有返回值,函數(shù)定義成空類型voidputline()

{inti;

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

printf("-");

printf("\n");

}函數(shù)的功能就是輸出35個‘-’調(diào)用:putline();

應(yīng)該的語句形式

i=putline();是錯的下一頁第6章函數(shù)與編譯預(yù)處理調(diào)用函數(shù)a=function(x,y);

或者

function(x,y);取返回值

只是操作解決更復(fù)雜問題時可以嵌套調(diào)用longfac(intk)

{longf=1;

inti;

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

f=f*i;

retrunf;

}

longcombination(intn,intm)

{longc;

inti;

c=fac(m)/(fac(n)*fac(m-n));

retrunc;

}

主函數(shù):

main()

{intn,m;

longc;

scanf(“%d,%d”,&n,&m);

c=combination(n,m);

prnit(“%ld”,c);

}理論上可以a(b(d(e(x))),c(f))

般嵌套無數(shù)層第6章函數(shù)與編譯預(yù)處理返回6.3函數(shù)的遞歸調(diào)用函數(shù)調(diào)用它本身,稱為遞歸。直接在函數(shù)內(nèi)調(diào)用自己為直接遞歸,通過別的函數(shù)調(diào)用自己為間接遞歸。voida()

{......

a();

......

}voida()

{......

b();......

}

voidb()

{......

a();

......

}遞歸在解決某些問題中,是一個十分有用的方法。因為其一,有的問題它本身就是遞歸定義的;其二,它可以使某些看起來不易解決的問題變得容易解決,寫出的程序較簡短。下一頁第6章函數(shù)與編譯預(yù)處理例:遞歸方法求n!

由于n!=n*(n-1)!是遞歸定義所以求n?。╪-1)!

(n-1)!(n-2)!

(n–2)!(n-3)!

……

0!的問題,

根據(jù)公式有0!=1。

再反過來依次求出1!,2!……直到最后求出n!。下一頁第6章函數(shù)與編譯預(yù)處理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)用點(diǎn):

主函數(shù)中,這樣就是一個遞歸

運(yùn)算。下一頁第6章函數(shù)與編譯預(yù)處理程序

第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ù)

下一頁第6章函數(shù)與編譯預(yù)處理遞歸舉例例1定義函數(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)*/}}下一頁第6章函數(shù)與編譯預(yù)處理下一頁第6章函數(shù)與編譯預(yù)處理兔子問題主函數(shù)voidmain(){longf(intn);/*自定義函數(shù)聲明*/intn;

printf(“\ninputn:”);

scanf(“%d”,&n);printf(“\nf(%d)=%ld”,n,f(n));

/*調(diào)用函數(shù)f(n)*/}輾轉(zhuǎn)相除法求最大公約數(shù)

求m和n的公約數(shù)算法if(m%n)==0

n是公約數(shù);else

求n和m%n的公約數(shù);下一頁第6章函數(shù)與編譯預(yù)處理例2求最大公約數(shù)的遞歸算法

intgcd(intm,intn)

{if(m%n)==0

returnn;else

returngcd(n,m%n);}求最大公約數(shù)的主函數(shù)voidmain(){intm,n,t;

intgcd(intm,intn);

scanf(“%d%d”,&m,&n);

if(m<n)

{t=a;a=b;b=t;}

t=gcd(m,n);/*調(diào)用函數(shù)gcd(m,n);

*/print(“\ngcd=%d”,t);}下一頁第6章函數(shù)與編譯預(yù)處理漢諾塔說到遞歸,就不能不提漢諾塔,漢諾塔是一個很繁雜的游戲,但可以用遞歸的方法異常簡單的完成。規(guī)則:(1)一次只能移動一個

(2)大的不能放在小的上面

(3)只能在三個位置中移動下一頁第6章函數(shù)與編譯預(yù)處理例3問題可分為三個步驟對于把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個金片的問題。這樣做下去的話最后就會變成移動一個金片的問題。下一頁第6章函數(shù)與編譯預(yù)處理遞歸方法解漢諾塔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移動到c主函數(shù):main()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}下一頁第6章函數(shù)與編譯預(yù)處理遞歸漢諾塔步驟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=3下一頁第6章函數(shù)與編譯預(yù)處理n=3

主函數(shù)調(diào)用hanoi(n,1,2,3);第一次調(diào)用。第一次調(diào)用hanoi(n,a,b,c)(第一層)即要把三個金片移到c由于n>1則執(zhí)行hanoi(n-1,a,c,b)

(第二次調(diào)用)n=3由于仍然n>1則執(zhí)行

hanoi(n-1,a,c,b)

(第三次調(diào)用)n=2下一頁第6章函數(shù)與編譯預(yù)處理遞歸漢諾塔步驟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移動到cn=1下一頁第6章函數(shù)與編譯預(yù)處理第三層執(zhí)行完畢,返回到第二層,即下去執(zhí)行printf(“%d->%d”,a,c);把第二個金片擺到第二根針上n=2遞歸漢諾塔步驟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=2n=1,執(zhí)行結(jié)果為32n=1下一頁第6章函數(shù)與編譯預(yù)處理

遞歸漢諾塔步驟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=3下一頁第6章函數(shù)與編譯預(yù)處理遞歸漢諾塔步驟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=3第6章函數(shù)與編譯預(yù)處理遞歸漢諾塔步驟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);

}

返回6.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’

。為什么?下一頁第6章函數(shù)與編譯預(yù)處理變量的作用域即變量的有效范圍1.變量按作用域分為全局變量和局部變量2.比較:全局變量(外部變量)局部變量(內(nèi)部變量)

定義位置:函數(shù)體外函數(shù)體內(nèi)作用域:從定義處到本源從定義處到本函數(shù)結(jié)束文件結(jié)束舉例:所有函數(shù)體外定義(1)所有在函數(shù)體內(nèi)定義的變量(2)形式參數(shù)

與局部變量同名的處理局部變量屏蔽全局變量不同函數(shù)中同名局部變量互不干擾下一頁第6章函數(shù)與編譯預(yù)處理6.4.1變量的作用域注意#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);}f1:t1=8,t2=12,a=8,b=10main:a=2,b=10下一頁第6章函數(shù)與編譯預(yù)處理舉例結(jié)果若將程序改為:#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);}全局變量與局部變量同名時,局部變量起作用,全局變量被屏蔽(不影響),應(yīng)小心使用下一頁第6章函數(shù)與編譯預(yù)處理結(jié)果t1=4,t2=12,b=100a=2,b=4結(jié)論變量按存在時間分靜態(tài)存儲類型的變量的生存期為程序執(zhí)行的整個過程,在該過程中占有固定的存儲空間,通常稱它們?yōu)橛谰么鎯?。動態(tài)存儲類型變量只生存在某一段時間內(nèi)。例如,函數(shù)的形參和函數(shù)體或分程序中定義的變量,只是在程序進(jìn)入該函數(shù)或分程序時才分配存儲空間,當(dāng)該函數(shù)或分程序執(zhí)行完后,變量對應(yīng)的存儲空間又被撤銷了。下一頁第6章函數(shù)與編譯預(yù)處理6.4.2變量的存儲方式靜態(tài)變量動態(tài)變量

c語言中每一個變量有兩個屬性:數(shù)據(jù)類型,存儲特性完整的變量定義:[存儲特性][數(shù)據(jù)類型]變量名;

自動型auto靜態(tài)型static寄存器型register外部型extern(1)auto型:每次進(jìn)入程序是自動分配內(nèi)存,不長期占用內(nèi)存例如:形式參數(shù),自動型局部變量(2)static型:①局部靜態(tài)變量②全局靜態(tài)變量長期占用內(nèi)存下一頁第6章函數(shù)與編譯預(yù)處理變量的存儲特性分析執(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)變量只初始化一次結(jié)果:214(a,b,c)7(f(a))21582169下一頁第6章函數(shù)與編譯預(yù)處理例如

數(shù)據(jù)內(nèi)存運(yùn)算器運(yùn)算器結(jié)果控制器數(shù)據(jù)寄存器寄存器變量只限于整型、字符型、指針型的局部變量。寄存器變量是動態(tài)變量,而且數(shù)目有限,一般僅允許說明兩個寄存器變量。例如:registerintd;registercharc;下一頁第6章函數(shù)與編譯預(yù)處理(3)register型將使用頻率高的變量定義為register型,可以提高運(yùn)行速度。(4)extern型引用:

extern類型變量名;如果某個模塊文件中要用到另一個模塊文件中的全局變量,就要用extern說明第6章函數(shù)與編譯預(yù)處理例如:程序模塊file1.c中定義了全局變量

ints;而在另一個程序模塊file2.c中的函數(shù)fun1()中需要使用這個變量s。為此,可以在file2.c的函數(shù)fun1()中加上外部變量說明語句:fun1(){externints;/*表明變量s是在其他文件定義的*/.......}定義時分配內(nèi)存,其他文件引用時不再分配內(nèi)存.返回6.5編譯預(yù)處理“編譯預(yù)處理”是C語言編譯系統(tǒng)的一個組成部分。是在編譯前由編譯系統(tǒng)中的預(yù)處理程序?qū)υ闯绦虻念A(yù)處理命令進(jìn)行加工。源程序中的預(yù)處理命令均以“#”開頭,結(jié)束不加分號,以區(qū)別源程序中的語句,它們可以寫在程序中的任何位置,作用域是自出現(xiàn)點(diǎn)到源程序的末尾。預(yù)處理命令包括執(zhí)行宏定義(宏替換)、包含文件和條件編譯。下一頁第6章函數(shù)與編譯預(yù)處理1.一般形式為:#define宏名串(宏體)如:#definePI3.14159/*定義后,可以用PI來代替串3.14159*/2.宏定義的作用:在宏定義之后,該程序中宏名就代表了該字符串。3.說明①可以用#undef命令終止宏定義的作用域。例如:#undefPI②宏定義的嵌套使用#defineR3.0#definePI3.1415926#defineL2*PI*R/*宏體是表達(dá)式*/#defineSPI*R*R下一頁第6章函數(shù)與編譯預(yù)處理6.5.1宏定義無參宏定義例如:main(){printf("L=%f\nS=%f\n",L,S);/*2*PI*R替換L,PI*R*R替換S*/}程序運(yùn)行結(jié)果:L=18.849556③雙引號內(nèi)與宏同名的字母不作宏展開.(見上例)帶參數(shù)的宏定義1.帶參數(shù)的宏定義的一般形式為#define宏名(參數(shù)表)字符串如:#defineS(a,b)a*b#definePR(x)printf("s=%f\n”,x)下一頁第6章函數(shù)與編譯預(yù)處理2.帶實參的宏名被展開下一頁第6章函數(shù)與編譯預(yù)處理宏定義與函數(shù)的區(qū)別

(1)引用宏只占編譯時間,不占運(yùn)行時間。(2)引用宏沒有返回值

宏名被所定義的宏體替換,宏體中的形參按從左到右的順序被實參替換。例如:area=S(3,2);PR(area);展開為:area=3*2;PR(area)展開的結(jié)果是:printf("s=%f\n”,area);#definesqu(n)n*nvoidmain(void){printf("%f\n",27.0/squ(3.0));}注意,展開為27.0/3.0*3.0不是27.0/(3.0*3.0)程序輸出結(jié)果為:27.000000例如下一頁第6章函數(shù)與編譯預(yù)處理(3)宏替換的形參無類型(4)實參為表達(dá)式的情況函數(shù)調(diào)用是先計算出實參的值,再將值傳遞給形參;宏的引用是用表達(dá)式替換形參.

例如:

溫馨提示

  • 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

提交評論