




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第六章函數(shù)與編譯預(yù)處理6.1模塊化程序設(shè)計(jì)與函數(shù)6.2函數(shù)的定義與調(diào)用6.4變量作用域與存儲(chǔ)方式返回6.3函數(shù)的遞歸調(diào)用6.5編譯預(yù)處理C語(yǔ)言程序設(shè)計(jì)教程6.1模塊化程序設(shè)計(jì)與函數(shù)
在設(shè)計(jì)較復(fù)雜的程序時(shí),我們一般采用的方法是:把問(wèn)題分成幾個(gè)部分,每部分又可分成更細(xì)的若干小部分,逐步細(xì)化,直至分解成很容易求解的小問(wèn)題。這樣的話,原來(lái)問(wèn)題的解就可以用這些小問(wèn)題來(lái)表示。下一頁(yè)第6章函數(shù)與編譯預(yù)處理基本模塊模塊模塊模塊模塊模塊模塊模塊模塊模塊模塊結(jié)構(gòu)圖6.1.1模塊與函數(shù)
C語(yǔ)言程序由基本語(yǔ)句和函數(shù)組成,每個(gè)函數(shù)可完成相對(duì)獨(dú)立的任務(wù),依一定的規(guī)則調(diào)用這些函數(shù),就組成了解決某個(gè)特定問(wèn)題的程序。下一頁(yè)第6章函數(shù)與編譯預(yù)處理把大任務(wù)分解成若干功能模塊,用多個(gè)函數(shù)來(lái)實(shí)現(xiàn)這些功能模塊。通過(guò)函數(shù)的調(diào)用來(lái)實(shí)現(xiàn)完成大任務(wù)的全部功能。任務(wù)、模塊與函數(shù)的關(guān)系:一個(gè)大任務(wù)分成多個(gè)功能模塊,功能模塊則由一個(gè)或多個(gè)函數(shù)實(shí)現(xiàn)。模塊化的程序設(shè)計(jì)是靠設(shè)計(jì)函數(shù)和調(diào)用函數(shù)實(shí)現(xiàn)的。任務(wù):輸入三個(gè)數(shù),從大到小的順序的輸出。如果大于等于85,在該數(shù)后面輸出‘A’,小于85且大于等于70,則輸出‘B’,小于70且大于等于60,輸出‘C’,如果小于60,則輸出‘D’。思路:scanf()輸入分?jǐn)?shù)
另建一個(gè)排序函數(shù)
判斷并輸出等級(jí)函數(shù)
打印分?jǐn)?shù)及等級(jí)的函數(shù)雖然也可以由一個(gè)主函數(shù)來(lái)完成,但這樣做可讀性及操作性會(huì)更好。下一頁(yè)第6章函數(shù)與編譯預(yù)處理例如分?jǐn)?shù)排序點(diǎn)擊查看程序請(qǐng)6.1.2模塊設(shè)計(jì)的原則模塊獨(dú)立規(guī)模適當(dāng)層次分明功能專一下一頁(yè)第6章函數(shù)與編譯預(yù)處理
獨(dú)立性原則表現(xiàn)在模塊完成獨(dú)立的功能,和其它模塊間的關(guān)系簡(jiǎn)單,各模塊可以單獨(dú)調(diào)試。修改某一模塊,不會(huì)造成整個(gè)程序的混亂。要做到模塊的獨(dú)立性要注意以下幾點(diǎn)每個(gè)模塊有特定功能每個(gè)模塊力求簡(jiǎn)單每個(gè)模塊應(yīng)用獨(dú)立變量點(diǎn)擊模塊不能太大,但也不能太小。模塊的功能復(fù)雜,可讀性就不好,而且也違背獨(dú)立性原則。但如果做得太小,實(shí)際上也會(huì)復(fù)雜各個(gè)模塊間反復(fù)調(diào)用,可讀性也會(huì)降低。這點(diǎn)需要慢慢積累經(jīng)驗(yàn),好好把握。下一頁(yè)第6章函數(shù)與編譯預(yù)處理分解模塊要注意層次,更多層次的分解任務(wù),要注意對(duì)問(wèn)題進(jìn)行抽象化。開(kāi)始不要過(guò)于注意細(xì)節(jié),要做到逐步細(xì)化求精。6.1.3算法描述簡(jiǎn)介什么是算法?
通俗地說(shuō),算法是解決一類特定問(wèn)題的方法和步驟。
算法是一個(gè)有限操作的序列。算法的每一步都是確定的。算法的每一步計(jì)算機(jī)都能操作。有一個(gè)或多個(gè)的輸入或輸出。下一頁(yè)第6章函數(shù)與編譯預(yù)處理算法描述的任務(wù)是將解題步驟和方法用一定的形式表示出來(lái),要清楚、準(zhǔn)確、嚴(yán)謹(jǐn),還要可讀性好,方便實(shí)現(xiàn)。
算法兩大要素:
一是操作,用類計(jì)算機(jī)語(yǔ)句或自然語(yǔ)言描述。
二是控制結(jié)構(gòu),描述算法一般可以用流程圖描述。設(shè)計(jì)算法:找出a,b兩數(shù)中的較大者,并輸出分析:這個(gè)問(wèn)題分三個(gè)步驟:輸入兩個(gè)數(shù);找出其中的大數(shù);輸出大數(shù)。第6章函數(shù)與編譯預(yù)處理例6.2開(kāi)始輸入a,ba<b交換a,b輸出a結(jié)束非00算法流程圖見(jiàn)右返回6.2函數(shù)的定義與調(diào)用在C語(yǔ)言中,函數(shù)(Function)是一個(gè)處理過(guò)程,可以進(jìn)行數(shù)值運(yùn)算、信息處理、控制決策,即一段程序的工作放在函數(shù)中進(jìn)行,函數(shù)結(jié)束時(shí)可以攜帶或不帶處理結(jié)果。
庫(kù)函數(shù)(標(biāo)準(zhǔn)函數(shù)):系統(tǒng)提供
自定義函數(shù):用戶自己寫(xiě)下一頁(yè)第6章函數(shù)與編譯預(yù)處理
C語(yǔ)言程序處理過(guò)程全部都是以函數(shù)形式出現(xiàn),最簡(jiǎn)單的程序至少也有一個(gè)main函數(shù)。函數(shù)必須先定義和聲明后才能調(diào)用?!昂瘮?shù)”的主要知識(shí)點(diǎn)函數(shù)的定義函數(shù)的參數(shù)和返回值函數(shù)的調(diào)用嵌套和遞歸變量的作用域下一頁(yè)第6章函數(shù)與編譯預(yù)處理6.2.1標(biāo)準(zhǔn)庫(kù)函數(shù)C語(yǔ)言有豐富的庫(kù)函數(shù),這些函數(shù)的說(shuō)明在不同的頭文件(*.h)中。想要調(diào)用標(biāo)準(zhǔn)的庫(kù)函數(shù),就必須include。#include<stdio.h>
main()
{printf(“%d”,1024*768);
}調(diào)用printf函數(shù)時(shí),
必須include<stdio.h>下一頁(yè)第6章函數(shù)與編譯預(yù)處理6.2.2函數(shù)的定義可以把完成一個(gè)任務(wù)的過(guò)程寫(xiě)成函數(shù)。intA_to_a(intcapital)
{intsmall;
if(capital>=‘A’&&capital<=‘Z’)
small=capital–(‘A’-’a’);
returnsmall;
}返回值類型名函數(shù)名注意不要與已有庫(kù)函數(shù)重名參數(shù)說(shuō)明和參數(shù)列表調(diào)用函數(shù)時(shí)輸入?yún)?shù)的格式要與之相同定義局部變量最好只使用局部變量,這樣將方便調(diào)試。另外請(qǐng)注意這樣的判斷,如寫(xiě)成‘A’<capital<‘Z’是不行的下一頁(yè)第6章函數(shù)與編譯預(yù)處理如果不需返回則可return0;返回值#include<conio.h>
main()
{inta,b,m;
/*說(shuō)明變量*/
intmax(inta,intb);
/*函數(shù)聲明*/
scanf("%d,%d",&a,&b);
/*調(diào)用庫(kù)函數(shù)scanf*/
m=max(a,b);
/*調(diào)用字定義函數(shù)max*/
printf("max=%d\n",m));
/*調(diào)用庫(kù)函數(shù)printf*/
getch();
/*調(diào)用庫(kù)函數(shù)getch*/
}下一頁(yè)第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)知道將要用到某個(gè)函數(shù)及它的類型,以便處理。函數(shù)聲明應(yīng)與該函數(shù)定義時(shí)給出的函數(shù)類型與名字、形參的個(gè)數(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;
}下一頁(yè)第6章函數(shù)與編譯預(yù)處理求1!+2!+3!+…+10!算法:i=1;s=0;當(dāng)i<=10s=s+i!定義求i!的函數(shù)下一頁(yè)第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)時(shí),其形參
的值是a和b
而m將會(huì)得到y(tǒng)的值函數(shù)的參數(shù)intmax(inta,intb)
{
inty;
y=(a>b)?a:b;
returny;
}調(diào)用時(shí):m=max(3,6);
m=max(a,b);
返回值括號(hào)里是實(shí)參在這一句調(diào)用時(shí),
形參的值是3和6其返回值y將被賦給
調(diào)用語(yǔ)句中的m下一頁(yè)第6章函數(shù)與編譯預(yù)處理括號(hào)里是形式參數(shù)形式參數(shù)與實(shí)際參數(shù)的關(guān)系形式參數(shù)在函數(shù)中是變量名,在函數(shù)調(diào)用時(shí),形參被分配相應(yīng)的內(nèi)存。實(shí)際參數(shù)是表達(dá)式負(fù)責(zé)向?qū)?yīng)的形參標(biāo)識(shí)的內(nèi)存單元傳遞數(shù)據(jù)。實(shí)參與形參必須個(gè)數(shù)相同。對(duì)應(yīng)的形參和實(shí)參的類型必須一致。
下一頁(yè)第6章函數(shù)與編譯預(yù)處理主調(diào)函數(shù)中有如下語(yǔ)句:
scanf("%d,%d",&a,&b);
m=max(a,b+3);如果輸入6,2函數(shù)intmax(inta,intb)形參a得到第一個(gè)實(shí)際參數(shù)a的值6形參b得到第二個(gè)實(shí)際參數(shù)b+3的值5例如函數(shù)返回值函數(shù)返回值通過(guò)return語(yǔ)句獲得函數(shù)返回值的類型就是函數(shù)的類型
returny;
將變量y的值返回給調(diào)用者
returny+3;
將表達(dá)式的值返回給調(diào)用者
return的數(shù)據(jù)類型與函數(shù)的類型矛盾時(shí),自動(dòng)將數(shù)據(jù)轉(zhuǎn)換成函數(shù)的類型下一頁(yè)第6章函數(shù)與編譯預(yù)處理intfunct1(){charch;
while
((ch=getch())<'a'||(ch>'z')
;
returnch;}調(diào)用:i=funct1();返回的是int類型函數(shù)沒(méi)有返回值,函數(shù)定義成空類型voidputline()
{inti;
for(i=0;i<35;i++)
printf("-");
printf("\n");
}函數(shù)的功能就是輸出35個(gè)‘-’調(diào)用:putline();
應(yīng)該的語(yǔ)句形式
i=putline();是錯(cuò)的下一頁(yè)第6章函數(shù)與編譯預(yù)處理調(diào)用函數(shù)a=function(x,y);
或者
function(x,y);取返回值
只是操作解決更復(fù)雜問(wèn)題時(shí)可以嵌套調(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))
般嵌套無(wú)數(shù)層第6章函數(shù)與編譯預(yù)處理返回6.3函數(shù)的遞歸調(diào)用函數(shù)調(diào)用它本身,稱為遞歸。直接在函數(shù)內(nèi)調(diào)用自己為直接遞歸,通過(guò)別的函數(shù)調(diào)用自己為間接遞歸。voida()
{......
a();
......
}voida()
{......
b();......
}
voidb()
{......
a();
......
}遞歸在解決某些問(wèn)題中,是一個(gè)十分有用的方法。因?yàn)槠湟?有的問(wèn)題它本身就是遞歸定義的;其二,它可以使某些看起來(lái)不易解決的問(wèn)題變得容易解決,寫(xiě)出的程序較簡(jiǎn)短。下一頁(yè)第6章函數(shù)與編譯預(yù)處理例:遞歸方法求n!
由于n!=n*(n-1)!是遞歸定義所以求n!(n-1)!
(n-1)!(n-2)!
(n–2)!(n-3)!
……
0!的問(wèn)題,
根據(jù)公式有0!=1。
再反過(guò)來(lái)依次求出1!,2!……直到最后求出n!。下一頁(yè)第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);
}剛開(kāi)始的時(shí)候,這個(gè)n是前面
輸入的需要階乘的n所以在這里帶入的值是n而這個(gè)函數(shù)里又調(diào)用
了本身,不過(guò)參數(shù)已經(jīng)
變成了n-1所以這里再次調(diào)用時(shí)
參數(shù)已經(jīng)變成了n-1注意:上次調(diào)用fac(n)
還沒(méi)有完,只是由于遇到
了fac(n-1)而執(zhí)行fac(n-1)
去了.而在調(diào)用fac(n-1)時(shí)同樣
遇到了要調(diào)用fac(n-2)的問(wèn)題,于是一層一層的
包裹下去,每次調(diào)用的
時(shí)候都會(huì)在內(nèi)部調(diào)用一
個(gè)結(jié)構(gòu)相同但變量不同
的函數(shù),直到。。。直到調(diào)用到fac(0)時(shí),由于內(nèi)部if判斷,已經(jīng)
不需要再繼續(xù)調(diào)用另一
個(gè)fac(n-1),而直接有了f=1fac(0)已經(jīng)執(zhí)行完畢,它的
返回值被fac(1)中的f=n*fac(n-1)
語(yǔ)句賦給了f值,同時(shí)返回了f。而這個(gè)返回的f又被fac(2)乘上
當(dāng)前的n值以后繼續(xù)返回f直到最后的fac(n)都做完了,
f的值被返回到了它的調(diào)用點(diǎn):
主函數(shù)中,這樣就是一個(gè)遞歸
運(yùn)算。下一頁(yè)第6章函數(shù)與編譯預(yù)處理程序
第1個(gè)月有1對(duì)兔子過(guò)2個(gè)月,兔子就可每個(gè)月生1對(duì)兔子問(wèn)第n個(gè)月有多少對(duì)兔子?分析:設(shè)第n個(gè)月有f(n)對(duì)兔子根據(jù)題意有f(0)=0,f(1)=1f(n)=f(n-1)+f(n-2)f(n-1):前一個(gè)月的兔子數(shù)f(n-2):本月生的兔子數(shù)
下一頁(yè)第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)*/}}下一頁(yè)第6章函數(shù)與編譯預(yù)處理下一頁(yè)第6章函數(shù)與編譯預(yù)處理兔子問(wèn)題主函數(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ù);下一頁(yè)第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);}下一頁(yè)第6章函數(shù)與編譯預(yù)處理漢諾塔說(shuō)到遞歸,就不能不提漢諾塔,漢諾塔是一個(gè)很繁雜的游戲,但可以用遞歸的方法異常簡(jiǎn)單的完成。規(guī)則:(1)一次只能移動(dòng)一個(gè)
(2)大的不能放在小的上面
(3)只能在三個(gè)位置中移動(dòng)下一頁(yè)第6章函數(shù)與編譯預(yù)處理例3問(wèn)題可分為三個(gè)步驟對(duì)于把n個(gè)金片從第一根針a上移到第三根針c的問(wèn)題可以分解成如下步驟:(1)將n-1個(gè)金片從a經(jīng)過(guò)c移動(dòng)到b。(2)將第n個(gè)金片移動(dòng)到c。(3)再將n-1個(gè)盤(pán)子從b經(jīng)過(guò)a移動(dòng)到c。這樣我們就將移動(dòng)n個(gè)金片的問(wèn)題變成了移動(dòng)n-1個(gè)金片的問(wèn)題。這樣做下去的話最后就會(huì)變成移動(dòng)一個(gè)金片的問(wèn)題。下一頁(yè)第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時(shí),直接將金片
從a移動(dòng)到cn-1個(gè)金片從a經(jīng)過(guò)
c移動(dòng)到b將第n個(gè)金片
從a移動(dòng)到c再將n-1個(gè)盤(pán)子從
b經(jīng)過(guò)a移動(dòng)到c主函數(shù):main()
{intn;
printf(“inputn:”);
scanf(“%d”,&n);
hanoi(n,1,2,3);
}下一頁(yè)第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下一頁(yè)第6章函數(shù)與編譯預(yù)處理n=3
主函數(shù)調(diào)用hanoi(n,1,2,3);第一次調(diào)用。第一次調(diào)用hanoi(n,a,b,c)(第一層)即要把三個(gè)金片移到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下一頁(yè)第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移動(dòng)到cn=1下一頁(yè)第6章函數(shù)與編譯預(yù)處理第三層執(zhí)行完畢,返回到第二層,即下去執(zhí)行printf(“%d->%d”,a,c);把第二個(gè)金片擺到第二根針上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í)行下一條語(yǔ)句,又調(diào)用第三層hanoi(1,3,1,2)n=2n=1,執(zhí)行結(jié)果為32n=1下一頁(yè)第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í)行接下來(lái)的語(yǔ)句,結(jié)果為13。n=3下一頁(yè)第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í)行接下來(lái)的語(yǔ)句,再次調(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變量的作用域與存儲(chǔ)方式先看一個(gè)例子,錯(cuò)在那里?: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);}編譯程序會(huì)提示出錯(cuò):Undefinedsymbol‘a(chǎn)’和Undefinedsymbol‘b’
。為什么?下一頁(yè)第6章函數(shù)與編譯預(yù)處理變量的作用域即變量的有效范圍1.變量按作用域分為全局變量和局部變量2.比較:全局變量(外部變量)局部變量(內(nèi)部變量)
定義位置:函數(shù)體外函數(shù)體內(nèi)作用域:從定義處到本源從定義處到本函數(shù)結(jié)束文件結(jié)束舉例:所有函數(shù)體外定義(1)所有在函數(shù)體內(nèi)定義的變量(2)形式參數(shù)
與局部變量同名的處理局部變量屏蔽全局變量不同函數(shù)中同名局部變量互不干擾下一頁(yè)第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下一頁(yè)第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);}全局變量與局部變量同名時(shí),局部變量起作用,全局變量被屏蔽(不影響),應(yīng)小心使用下一頁(yè)第6章函數(shù)與編譯預(yù)處理結(jié)果t1=4,t2=12,b=100a=2,b=4結(jié)論變量按存在時(shí)間分靜態(tài)存儲(chǔ)類型的變量的生存期為程序執(zhí)行的整個(gè)過(guò)程,在該過(guò)程中占有固定的存儲(chǔ)空間,通常稱它們?yōu)橛谰么鎯?chǔ)。動(dòng)態(tài)存儲(chǔ)類型變量只生存在某一段時(shí)間內(nèi)。例如,函數(shù)的形參和函數(shù)體或分程序中定義的變量,只是在程序進(jìn)入該函數(shù)或分程序時(shí)才分配存儲(chǔ)空間,當(dāng)該函數(shù)或分程序執(zhí)行完后,變量對(duì)應(yīng)的存儲(chǔ)空間又被撤銷了。下一頁(yè)第6章函數(shù)與編譯預(yù)處理6.4.2變量的存儲(chǔ)方式靜態(tài)變量動(dòng)態(tài)變量
c語(yǔ)言中每一個(gè)變量有兩個(gè)屬性:數(shù)據(jù)類型,存儲(chǔ)特性完整的變量定義:[存儲(chǔ)特性][數(shù)據(jù)類型]變量名;
自動(dòng)型auto靜態(tài)型static寄存器型register外部型extern(1)auto型:每次進(jìn)入程序是自動(dòng)分配內(nèi)存,不長(zhǎng)期占用內(nèi)存例如:形式參數(shù),自動(dòng)型局部變量(2)static型:①局部靜態(tài)變量②全局靜態(tài)變量長(zhǎng)期占用內(nèi)存下一頁(yè)第6章函數(shù)與編譯預(yù)處理變量的存儲(chǔ)特性分析執(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下一頁(yè)第6章函數(shù)與編譯預(yù)處理例如
數(shù)據(jù)內(nèi)存運(yùn)算器運(yùn)算器結(jié)果控制器數(shù)據(jù)寄存器寄存器變量只限于整型、字符型、指針型的局部變量。寄存器變量是動(dòng)態(tài)變量,而且數(shù)目有限,一般僅允許說(shuō)明兩個(gè)寄存器變量。例如:registerintd;registercharc;下一頁(yè)第6章函數(shù)與編譯預(yù)處理(3)register型將使用頻率高的變量定義為register型,可以提高運(yùn)行速度。(4)extern型引用:
extern類型變量名;如果某個(gè)模塊文件中要用到另一個(gè)模塊文件中的全局變量,就要用extern說(shuō)明第6章函數(shù)與編譯預(yù)處理例如:程序模塊file1.c中定義了全局變量
ints;而在另一個(gè)程序模塊file2.c中的函數(shù)fun1()中需要使用這個(gè)變量s。為此,可以在file2.c的函數(shù)fun1()中加上外部變量說(shuō)明語(yǔ)句:fun1(){externints;/*表明變量s是在其他文件定義的*/.......}定義時(shí)分配內(nèi)存,其他文件引用時(shí)不再分配內(nèi)存.返回6.5編譯預(yù)處理“編譯預(yù)處理”是C語(yǔ)言編譯系統(tǒng)的一個(gè)組成部分。是在編譯前由編譯系統(tǒng)中的預(yù)處理程序?qū)υ闯绦虻念A(yù)處理命令進(jìn)行加工。源程序中的預(yù)處理命令均以“#”開(kāi)頭,結(jié)束不加分號(hào),以區(qū)別源程序中的語(yǔ)句,它們可以寫(xiě)在程序中的任何位置,作用域是自出現(xiàn)點(diǎn)到源程序的末尾。預(yù)處理命令包括執(zhí)行宏定義(宏替換)、包含文件和條件編譯。下一頁(yè)第6章函數(shù)與編譯預(yù)處理1.一般形式為:#define宏名串(宏體)如:#definePI3.14159/*定義后,可以用PI來(lái)代替串3.14159*/2.宏定義的作用:在宏定義之后,該程序中宏名就代表了該字符串。3.說(shuō)明①可以用#undef命令終止宏定義的作用域。例如:#undefPI②宏定義的嵌套使用#defineR3.0#definePI3.1415926#defineL2*PI*R/*宏體是表達(dá)式*/#defineSPI*R*R下一頁(yè)第6章函數(shù)與編譯預(yù)處理6.5.1宏定義無(wú)參宏定義例如:main(){printf("L=%f\nS=%f\n",L,S);/*2*PI*R替換L,PI*R*R替換S*/}程序運(yùn)行結(jié)果:L=18.849556③雙引號(hào)內(nèi)與宏同名的字母不作宏展開(kāi).(見(jiàn)上例)帶參數(shù)的宏定義1.帶參數(shù)的宏定義的一般形式為#define宏名(參數(shù)表)字符串如:#defineS(a,b)a*b#definePR(x)printf("s=%f\n”,x)下一頁(yè)第6章函數(shù)與編譯預(yù)處理2.帶實(shí)參的宏名被展開(kāi)下一頁(yè)第6章函數(shù)與編譯預(yù)處理宏定義與函數(shù)的區(qū)別
(1)引用宏只占編譯時(shí)間,不占運(yùn)行時(shí)間。(2)引用宏沒(méi)有返回值
宏名被所定義的宏體替換,宏體中的形參按從左到右的順序被實(shí)參替換。例如:area=S(3,2);PR(area);展開(kāi)為:area=3*2;PR(area)展開(kāi)的結(jié)果是:printf("s=%f\n”,area);#definesqu(n)n*nvoidmain(void){printf("%f\n",27.0/squ(3.0));}注意,展開(kāi)為27.0/3.0*3.0不是27.0/(3.0*3.0)程序輸出結(jié)果為:27.000000例如下一頁(yè)第6章函數(shù)與編譯預(yù)處理(3)宏替換的形參無(wú)類型(4)實(shí)參為表達(dá)式的情況函數(shù)調(diào)用是先計(jì)算出實(shí)參的值,再將值傳遞給形參;宏的引用是用表達(dá)式替換形參.
例如:
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟裝設(shè)計(jì)合同合同范本
- 新疆2025年新疆科技職業(yè)技術(shù)學(xué)院招聘166人筆試歷年參考題庫(kù)附帶答案詳解-1
- 2025至2030年中國(guó)花生梳打夾心餅數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025年迷彩彈性短裙項(xiàng)目可行性研究報(bào)告
- 2025至2030年五金接插件項(xiàng)目投資價(jià)值分析報(bào)告
- 工程保護(hù)合同范本
- 的小學(xué)語(yǔ)文教研工作計(jì)劃
- 2025至2030年中國(guó)鋼琴漆面地板數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025年短信監(jiān)控器項(xiàng)目可行性研究報(bào)告
- 2025至2030年中國(guó)讀寫(xiě)磁頭數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 數(shù)據(jù)結(jié)構(gòu)英文教學(xué)課件:chapter10 Hashing
- 藍(lán)色卡通風(fēng)學(xué)生班干部競(jìng)選介紹PPT模板課件
- 人教新目標(biāo)英語(yǔ)九年級(jí)上冊(cè)單詞中文Units
- 機(jī)動(dòng)車牌證申請(qǐng)表格模板(完整版)
- 部編版小學(xué)語(yǔ)文三年級(jí)(下冊(cè))學(xué)期課程綱要
- 道路交通事故責(zé)任認(rèn)定行政復(fù)議申請(qǐng)書(shū)范例
- 高效液相含量測(cè)定計(jì)算公式
- 六宮格數(shù)獨(dú)解題技巧
- 公安機(jī)關(guān)通用告知書(shū)模板
- 工程款支付審批流程圖
- 人教版七年級(jí)歷史下冊(cè)第一單元填空題
評(píng)論
0/150
提交評(píng)論