版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
關(guān)于函數(shù)和編譯預(yù)處理第一頁,共九十七頁,編輯于2023年,星期日3.1概述函數(shù):
function,功能。執(zhí)行或承擔某一功能的程序段,解答某問題的一段程序。它有特定的組織格式和使用方式。
函數(shù)與程序的關(guān)系:一個復(fù)雜的C語言程序包含多個函數(shù)。(主函數(shù)main)它們可存放在多個文件中。模塊化程序設(shè)計思想:
劃分程序功能,每個子功能用子函數(shù)(主函數(shù)之外的函數(shù))來承擔,而讓主函數(shù)去調(diào)用(使用)這些子函數(shù)從而實現(xiàn)程序的所有功能。每個函數(shù)單獨設(shè)計調(diào)試,而且可以重復(fù)使用。第二頁,共九十七頁,編輯于2023年,星期日main()func1()func2()func3()func5()func4()主調(diào)函數(shù)、調(diào)用被調(diào)函數(shù)(子函數(shù))、被調(diào)用參數(shù)返回值主調(diào)函數(shù)和被調(diào)函數(shù)的關(guān)系:上下級關(guān)系請問:main()被誰調(diào)用?一個程序中函數(shù)調(diào)用的示意圖:第三頁,共九十七頁,編輯于2023年,星期日#include<iostream>
voidmain(){intn;cin>>n;if(n>1)cout<<“thesumis:”<<sum(n)<<endl;//調(diào)用sum()函數(shù)}intsum(intn)例3.1編寫函數(shù)求前n個自然數(shù)之和,n的值從鍵盤輸入。函數(shù)首部、函數(shù)頭函數(shù)首部/函數(shù)頭函數(shù)體{intk,s=0;for(k=1;k<=n;k++)s=s+k;
return
s;}第四頁,共九十七頁,編輯于2023年,星期日第五頁,共九十七頁,編輯于2023年,星期日int
sum(
intn)//s()函數(shù)的首部doublef(intx,floaty)函數(shù)類型:函數(shù)返回值的數(shù)據(jù)類型,由返回值類型標識符決定
。前面【例3.1】的main函數(shù)是無參函數(shù),其頭部也可以寫成:voidmain()voidmain(void)無返回值的函數(shù),叫空值類型函數(shù)。第六頁,共九十七頁,編輯于2023年,星期日函數(shù)分類:從用戶使用的角度看,函數(shù)有兩種:(1)系統(tǒng)函數(shù),即庫函數(shù),由編譯系統(tǒng)提供,用戶不必自己定義這些函數(shù),可以直接使用它們。(2)用戶自己定義的函數(shù),用以解決用戶的特殊問題。從函數(shù)的形式看,函數(shù)分兩類:(1)無參函數(shù)。定義、調(diào)用函數(shù)時不必給出參數(shù)。(2)有參函數(shù)。定義、調(diào)用函數(shù)時,要給出參數(shù)。在主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞。第七頁,共九十七頁,編輯于2023年,星期日3.2.2函數(shù)的聲明(3.2.4后再學(xué))第八頁,共九十七頁,編輯于2023年,星期日3.2.3函數(shù)的返回值(接續(xù)函數(shù)定義一節(jié))函數(shù)的返回值(函數(shù)值):函數(shù)運行后得到的數(shù)據(jù)值。通過被調(diào)用函數(shù)中的return語句獲得的。(1)return語句
在有返回值的被調(diào)用函數(shù)中:return結(jié)束函數(shù)的運行并將其后表達式的值帶回主調(diào)函數(shù)中。
return表達式;…無………。(此時函數(shù)最后的return;可省略)一個函數(shù)中可有多條return語句!但其中只有一條被執(zhí)行。(2)函數(shù)的類型/函數(shù)值的類型
由函數(shù)首部的返回值類型標識符決定
。(3)如果return語句中表達式值的類型和函數(shù)的類型不一致,則以函數(shù)類型為準,即函數(shù)類型決定返回值的類型。對數(shù)值型數(shù)據(jù),可以自動進行類型轉(zhuǎn)換。intf(intx){doublez;…
return
z;}第九頁,共九十七頁,編輯于2023年,星期日3.2.4函數(shù)的調(diào)用使用函數(shù)。兩層含義:一層含義指在設(shè)計、編寫源程序時使用一個函數(shù)(靜態(tài))。
注意:如果實參列表包括多個實參,實參中出現(xiàn)表達式時,多個實參因共用某些變量而聯(lián)系時,實參值可能與實參求值的順序有關(guān)。如:fun(n,
++n);設(shè)法避免!調(diào)用形式:函數(shù)名([實際參數(shù)列表])實參與形參的個數(shù)應(yīng)相等,類型應(yīng)匹配(相同或賦值兼容)。實參與形參按順序?qū)?yīng),運行時一對一地傳遞數(shù)據(jù)。實參可以是常量、變量或表達式。另一層含義指在程序運行過程中執(zhí)行函數(shù)中的語句(動態(tài))。第十頁,共九十七頁,編輯于2023年,星期日函數(shù)調(diào)用的具體方式:3種函數(shù)調(diào)用方式1.函數(shù)語句print_word();把函數(shù)調(diào)用單獨作為一個語句,并不要求函數(shù)帶回一個值,只是要求函數(shù)完成一定的操作。2.函數(shù)表達式c=2*max(a,b);函數(shù)出現(xiàn)在一個表達式中,這時要求函數(shù)帶回一個確定的值以參加表達式的運算。3.函數(shù)參數(shù)函數(shù)調(diào)用作為一個函數(shù)的實參。m=max(a,max(b,c));//max(b,c)是函數(shù)調(diào)用,其值作為外層 //max函數(shù)調(diào)用的一個實參第十一頁,共九十七頁,編輯于2023年,星期日
(1)主調(diào)函數(shù)和被調(diào)函數(shù)中語句的執(zhí)行順序。(執(zhí)行流程改變、CPU控制權(quán)傳遞)(2)參數(shù)值傳遞方向:實參值形參(3)函數(shù)值的返回:調(diào)用處調(diào)用函數(shù)過程(動態(tài)含義)中的問題:第十二頁,共九十七頁,編輯于2023年,星期日intmax(intx,inty){intz;z=(x>y)?x:y;
returnz;}voidmain(void){inta,b,c;cin>>a>>b;c=max(a,b);cout<<“Themaxis”<<c<<endl;}主調(diào)函數(shù)函數(shù)調(diào)用函數(shù)類型函數(shù)名函數(shù)體形參列表說明函數(shù)值實際參數(shù)將實參a,b的值傳給被調(diào)函數(shù)max的形參x,y,計算后將z的值作為函數(shù)值返回。第十三頁,共九十七頁,編輯于2023年,星期日intmax(intx,inty){intz;z=(x>y)?x:y;returnz;}voidmain(void){inta,b,c;cin>>a>>b;c=max(a,b);cout<<“Themaxis”<<c<<endl;}ab23調(diào)用處(表達式中)3xy23zc=3不要將函數(shù)名做變量用!不能寫成max=z;第十四頁,共九十七頁,編輯于2023年,星期日(2)自定義函數(shù)的聲明函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型,參數(shù)1名稱][,參數(shù)2類型,參數(shù)2名稱][…]);
什么時候需要聲明?聲明的含義、作用?聲明的格式、位置?(1)庫函數(shù)的聲明對庫函數(shù)的聲明已經(jīng)寫在有關(guān)包含文件(頭文件)中了,因此只要在程序文件首部用
include
指令將這些包含文件包含到本程序中來,就完成了對庫函數(shù)的聲明。#include<cmath>
3.2.2函數(shù)的聲明(補述)函數(shù)的聲明形式也叫做函數(shù)原型(functionprototype)。它說明了函數(shù)的類型、函數(shù)名、函數(shù)各形式參數(shù)類型。函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型][,參數(shù)2類型
][…]);《修改p68》名稱任意,可省略第十五頁,共九十七頁,編輯于2023年,星期日【例3.2】輸入圓柱體的底面半徑和高,求底面圓面積和體積。設(shè)函數(shù)area()和volum()分別求圓面積和圓柱體體積。#include<iostream>usingnamespacestd;voidmain(){doublevolum(float,float);//聲明
doublearea(floatr);//聲明
floatr,h;
doubles,v;cout<<"pleaseinputr,h:";cin>>r>>h;s=area(r);//調(diào)用
v=volum(r,h);//調(diào)用
cout<<"s="<<s<<","<<"v="<<v<<endl;}
doublevolum(floatx,floaty)//定義{doublearea(floatr);//聲明
doublez1,z2;z1=area(x);z2=z1*y;return(z2);
}doublearea(floatx)//定義{doublez;z=3.14*x*x;return(z);}第十六頁,共九十七頁,編輯于2023年,星期日3.2.2函數(shù)的聲明(補述)說明:(1)函數(shù)定義和函數(shù)聲明是兩回事,不要混淆。(2)之所以函數(shù)原型中可以省略形式參數(shù)的名稱,是因為形式參數(shù)的名稱是無關(guān)緊要的,且在調(diào)用前形參并不存在。(3)函數(shù)聲明的位置。函數(shù)聲明可以放在主調(diào)函數(shù)中,也可放在函數(shù)外面,只要出現(xiàn)在函數(shù)調(diào)用之前即可。第十七頁,共九十七頁,編輯于2023年,星期日(1)在定義函數(shù)時指定的形參,在未出現(xiàn)函數(shù)調(diào)用時,它們并不占內(nèi)存中的存儲單元,因此稱它們是形式參數(shù)或虛擬參數(shù),表示它們并不是實際存在的數(shù)據(jù);只有在程序運行并發(fā)生函數(shù)調(diào)用時,函數(shù)中的形參才被分配內(nèi)存單元,以便接收從實參傳來的數(shù)據(jù)。在調(diào)用結(jié)束后,形參所占的內(nèi)存單元也被釋放。3.3函數(shù)的參數(shù)傳遞(再次說明)intadd(intx,inty){intz;z=x+y;returnz;}voidmain(void){doublea,b,c;cin>>a>>b;c=add(a,3.5);cout<<“Thesumis”<<c<<endl;}(2)實參與形參的類型應(yīng)相同或賦值兼容。第十八頁,共九十七頁,編輯于2023年,星期日
值傳遞:調(diào)用函數(shù)時,計算機將函數(shù)調(diào)用處的實參值傳給被調(diào)函數(shù)的形參,在被調(diào)函數(shù)執(zhí)行過程中,形參可以被改變,但不影響函數(shù)調(diào)用處的實參值。換一句話說,這種參數(shù)傳遞機制是單向影響。3.3.1參數(shù)的值傳遞(前面已介紹)第十九頁,共九十七頁,編輯于2023年,星期日除了3.3.2小節(jié)介紹的值傳遞參數(shù)方式外,函數(shù)調(diào)用還有一種特殊的值傳遞形式,即傳遞的值不是一般的數(shù)值,而是一些內(nèi)存單元地址編號(即地址),這時,一般稱之為參數(shù)的地址傳遞。在這種參數(shù)傳遞形式中,無論在函數(shù)的定義中出現(xiàn)的形參還是在調(diào)用語句中出現(xiàn)的實參,都是代表一些內(nèi)存單元地址編號(即地址數(shù)值),而不是一般的數(shù)值。C++中的參數(shù)地址傳遞情況一般有如下幾種:實參可以是一個有確定值的普通變量的地址,或者是一個已經(jīng)初始化的指針變量;或者是一個初始化的數(shù)組名;或者是一個具體的函數(shù)名。而形參可以是一個任意普通變量的地址,或是一個任意指針變量,或是一個任意的數(shù)組名,或是一個指向函數(shù)的指針變量(對應(yīng)于實參是具體函數(shù)名)。3.3.2參數(shù)的地址傳遞(4章)第二十頁,共九十七頁,編輯于2023年,星期日實際上,這種參數(shù)傳遞機制就是在函數(shù)調(diào)用時把一個內(nèi)存單元地址傳遞給形參,使形參也具有實參的內(nèi)存單元地址(即兩者對應(yīng)同一個內(nèi)存單元),稱作形參和實參地址結(jié)合,兩者合二為一。這樣一來,任何時候形參的值等于實參的值;而實參的值也等于形參的值。因此,形參在函數(shù)中發(fā)生變化后,也會引起實參跟著變化(因為它們是捆綁在一起的,一體化的)。這就意味著按地址傳遞的方式,在調(diào)用剛開始時實參的值影響了形參;而在被調(diào)函數(shù)執(zhí)行過程中形參值若發(fā)生了變化,它也會影響實參的值變化。即機制是雙向影響,這與普通值傳遞方式的單向影響機制形成對比。第二十一頁,共九十七頁,編輯于2023年,星期日【例3.5】延遲函數(shù)的使用。#include<iostream.h>voiddelay(intloop);//聲明voidmain(){cout<<"begin"<<endl;delay(1000);//調(diào)用cout<<"end"<<endl;}voiddelay(intloop)//定義{if(loop==0)return;for(inti=0;i<loop;i++)cout<<i<<endl;}3.3.3帶默認值的參數(shù)(C++)C++語言中,允許在函數(shù)定義或聲明時給一個或多個形參指定默認值。這樣,后面的函數(shù)調(diào)用中,可以不給具有默認值的形參設(shè)定相應(yīng)的實參。voiddelay(intloop=1000);voiddelay(intx=1000);delay();//調(diào)用
第二十二頁,共九十七頁,編輯于2023年,星期日
對于教材【例3.2】的求圓柱體體積的函數(shù)volume(),如下聲明:floatvolume(floatr,floath=8.5);//只對形參h指定默認值8.5這時函數(shù)調(diào)用形式:volume(6.0);//相當于volume(6.0,8.5)volume(6.0,7.2);//r的值為6.0,h的值為7.2
如果函數(shù)有多個形參,可以對每個或部分形參指定默認值。指定默認值的形參必須放在參數(shù)列表中的
最右邊。第二十三頁,共九十七頁,編輯于2023年,星期日課堂總結(jié)第二十四頁,共九十七頁,編輯于2023年,星期日……a函數(shù)……b函數(shù)………………⑴main函數(shù)…………結(jié)束(2)(3)(4)(5)(6)(7)(8)(9)
C語言不允許對函數(shù)作嵌套定義!3.4.1嵌套調(diào)用:在一個函數(shù)定義中,可以調(diào)用另一個函數(shù)。
程序執(zhí)行時,在調(diào)用一個函數(shù)的過程中,又調(diào)用另一個函數(shù)。例如:3.4函數(shù)的嵌套調(diào)用和遞歸調(diào)用調(diào)用a函數(shù)調(diào)用b函數(shù)main()函數(shù)直接地調(diào)用了a函數(shù),main()函數(shù)嵌套地調(diào)用了b函數(shù)(間接調(diào)用)。第二十五頁,共九十七頁,編輯于2023年,星期日longcomb(intn,intm)//定義組合函數(shù){longc;c=fac(m)/(fac(n)*fac(m-n));//嵌套調(diào)用階乘函數(shù)
returnc;}voidmain(){intn,m;longc;cout<<"pleaseinputtwointegernumbers:m,n"<<endl;cin>>m>>n;c=comb(n,m);//調(diào)用組合函數(shù)combcout<<"c="<<c<<endl;}main()分析:定義函數(shù)longcomb(intn,intm)求組合數(shù)。定義函數(shù)longfac(intk)求k的階乘。comb()fac()#include<iostream>usingnamespacestd;longfac(intk)//定義求階乘的函數(shù){longf=1;inti;for(i=1;i<=k;i++)f=f*i;returnf;}【例3.6】編程求組合數(shù),第二十六頁,共九十七頁,編輯于2023年,星期日3.4.2函數(shù)的遞歸調(diào)用在調(diào)用一個函數(shù)的過程中,被調(diào)用函數(shù)又直接或間接地調(diào)用自身,這種調(diào)用過程稱為函數(shù)的遞歸(recursive)調(diào)用。直接遞歸調(diào)用函數(shù)的代碼形式:intf()//函數(shù)f1的定義{……//函數(shù)其它部分
z=f();//直接調(diào)用自身
……//函數(shù)其它部分}在函數(shù)f()中,又直接調(diào)用了f()函數(shù)。第二十七頁,共九十七頁,編輯于2023年,星期日間接遞歸調(diào)用函數(shù)可以表現(xiàn)為如下:intf1()//函數(shù)f1的定義{……//f1的其他部分x=f2();//調(diào)用f2()……//f1的其他部分}intf2()//函數(shù)f2的定義{……//f2的其他部分y=f1
();//調(diào)用f1()……//f2的其他部分
}第二十八頁,共九十七頁,編輯于2023年,星期日函數(shù)的直接遞歸調(diào)用函數(shù)的間接遞歸調(diào)用
圖中調(diào)用過程特點:這兩種遞歸調(diào)用都是無終止的自身調(diào)用?!程序中不應(yīng)出現(xiàn)這種無終止的遞歸調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的、有終止的遞歸調(diào)用!解決:用if語句來控制,只有在某一條件成立時才繼續(xù)執(zhí)行遞歸調(diào)用,否則就不再繼續(xù)。包含遞歸調(diào)用的函數(shù)稱為遞歸函數(shù)。第二十九頁,共九十七頁,編輯于2023年,星期日【例3.7】用遞歸計算n!。求n!,應(yīng)先求(n-1)?。欢?n-1)!,又需要先求(n-2)!,而求(n–2)??;又可以變成求(n-3)!,如此繼續(xù),直到最后變成求1!的問題,而根據(jù)公式有1!=1(這就是本問題的遞歸終止條件)。由終止條件得到1!結(jié)果后,再反過來依次求出2!,3!……直到最后求出n!。第三十頁,共九十七頁,編輯于2023年,星期日【例3.7】用遞歸計算n!。n!本身就是以遞歸的形式定義的:#include<iostream>usingnamespacestd;longfac(intn){longf;if(n==1)f=1;elsef=n*fac(n-1);//遞歸調(diào)用,求(n-1)!returnf;}voidmain(){longy;intn;cout<<"pleaseinputaintegern"<<endl;cin>>n;y=fac(n);//調(diào)用fac(n)求n!cout<<"n="<<n<<","<<"y="<<y<<endl;}調(diào)用fac(3)求3!時,fac()遞歸調(diào)用及調(diào)用返回過程:fac(3)fac()n=33*fac(2)return6main()fac()n=22*fac(1)return2n=1fac(1)return1fac()⑤②①③⑥④第三十一頁,共九十七頁,編輯于2023年,星期日問題的遞歸定義(遞歸求解方法)含有兩個要素:(1)遞歸終止條件。也就是所描述問題的最簡單情況,它本身不再使用遞歸的定義,即程序必須終止。如上例,當n=1時,fac(n)=1,不再使用f(n-1)來定義。(2)使問題向終止條件轉(zhuǎn)化的規(guī)則。
遞歸定義必須能使問題越來越簡單,即參數(shù)越來越接近終止條件的參數(shù);達到終止條件參數(shù)時函數(shù)有確定的值。如上例,f(n)由f(n-1)定義,越來越靠近f(1),即參數(shù)n越來越接近終止條件參數(shù)1;達到終止條件參數(shù)時函數(shù)有確定的值是f(1)=1。
第三十二頁,共九十七頁,編輯于2023年,星期日方法一:用循環(huán)做方法二:用遞歸函數(shù)做(n=0)(n≥1)Sn=n+Sn-10(遞歸定義)類似的問題:已知n,求sn=1+2+3+......+n 第三十三頁,共九十七頁,編輯于2023年,星期日Fibonacci數(shù)列:0,1,1,2,3,5,8,13,21,…其數(shù)學(xué)表達式(遞歸定義)為:
fibonacci(0)=0n==0fibonacci(1)=1n==1fibonacci(n)=fibonacci(n-1)+fibonacci(n-2)(n>1)longfibonacci(intn){ if(n==0||n==1) returnn; else returnfibonacci(n-1)+fibonacci(n-2);}程序如下所示:
《實驗教程》P19三實驗思考1:求Fibonacci數(shù)列大于t的最小項的值。第三十四頁,共九十七頁,編輯于2023年,星期日voidmain(){ intn=0,t; longresult,t; cin>>t; result=fibonacci(n); whlie(result<=t){n++; result=fibonacci(n);}cout<<result; }方法:1.遞歸函數(shù)《實驗教程:P19三實驗思考1》2.用循環(huán)做《實驗教程:
p90.四,1》3.數(shù)組《教材:p140,3》第三十五頁,共九十七頁,編輯于2023年,星期日求兩個數(shù)最大公約數(shù)的方法1.輾轉(zhuǎn)相除法(p57)2.短除法3.試探法4.遞歸方法(用函數(shù)遞歸調(diào)用做)用g(m,n)表示m、n的最大公約數(shù),請寫出則其遞歸定義。第三十六頁,共九十七頁,編輯于2023年,星期日遞歸邊界(終止)條件使問題向遞歸邊界(終止)條件轉(zhuǎn)化的規(guī)則類似例題習(xí)題:強調(diào):上述問題的遞歸定義具備兩個成分:第三十七頁,共九十七頁,編輯于2023年,星期日遞推方法程序描述繁雜,可讀性差;主要采用循環(huán)結(jié)構(gòu);逐步執(zhí)行;當前值的求得總建立在前面求解的基礎(chǔ)上;遞歸方法描述與原始問題(遞歸公式)比較接近;書寫簡潔、易讀易寫;易于分析算法的復(fù)雜性和證明算法的正確性;在問題轉(zhuǎn)化時,需要花時間和存儲空間將有關(guān)的“現(xiàn)場信息”保存起來;當達到終止條件時,系統(tǒng)又需要花時間將有關(guān)的“現(xiàn)場信息”恢復(fù)以便處理未曾處理完的函數(shù)調(diào)用。占用存儲空間少,執(zhí)行速度快。遞歸與遞推算法遞歸函數(shù)的適應(yīng)場合:待求解的問題含有遞歸關(guān)系。第三十八頁,共九十七頁,編輯于2023年,星期日【例3.8】漢諾塔問題abc漢諾塔(TowerofHanoi)問題據(jù)說來源于布拉瑪神廟。該問題的裝置如圖3.6所示(圖上僅畫三個金片以簡化問題的原理,原問題有64個金片),底座上有三根金鋼石的針,第一根針a上放著從大到小64個金片。解決該問題就是要想法把所有金片從第一根針a上移到第三根針c上,第二根針b作為中間過渡。要求是每次只能移動一個金片,并且任何時候不允許大的金片壓在小的金片上面。圖3.6三個金片的漢諾塔問題裝置第三十九頁,共九十七頁,編輯于2023年,星期日1.本問題的遞歸終止條件。如果只有1個盤,顯然問題的解就很明顯是:直接把金片從a移到c。因此終止條件是n=1;終止條件對應(yīng)的操作是直接把金片從a移到c,示意ac。2.本問題的遞歸分析:移動n個金片從a到c,必須先將n-1個金片從a借助c移動到b,移動n-1個金片與原問題相同,但規(guī)模變小,即向終止條件接近,因此,此問題可以用遞歸過程完成。遞歸過程可以用如下步驟表示:(1)將n-1個金片從a經(jīng)過c移動到b。(2)將第n個金片從a直接移動到c。(3)再將n-1個金片從b經(jīng)過a移動到c。
第四十頁,共九十七頁,編輯于2023年,星期日一般地,設(shè)將n個金片從x針借助y針移動到z針的函數(shù)原形為:voidhanoi(intn,charx,chary,charz)根據(jù)解題步驟,可以寫出求解n個金片的漢諾塔函數(shù)如下:#include<iostream>//*****ex3_8.cpp*****usingnamespacestd;voidhanoi(intn,charx,chary,charz){if(n==1)//n=1時,直接將金片從x移動到zcout<<x<<"->"<<z<<endl;else//n>1時{hanoi(n-1,x,z,y);//先將n-1個金片從借助z移動到y(tǒng)cout<<x<<"->"<<z<<endl;//然后將第n個金片從x移到zhanoi(n-1,y,x,z);//再將n-1個金片從y借助x移動到z}}第四十一頁,共九十七頁,編輯于2023年,星期日當n>1時,就遞歸調(diào)用hanoi(),每次n減1。最后當n=1時,直接移動該金片就可以了。主函數(shù)如下:
voidmain(){intn;cout<<"inputn:"<<endl;cin>>n;hanoi(n,'a','b','c');//n個金片從a針借助b針移動到c針}雖然遞歸調(diào)用在寫程序時很簡單,但執(zhí)行起來卻很復(fù)雜(時間、存儲空間都開銷大)。對于漢諾塔問題程序的執(zhí)行過程分析比較復(fù)雜,有興趣的讀者可參閱教材對3個盤情景的分析(圖3.7及其相應(yīng)文字敘述)。第四十二頁,共九十七頁,編輯于2023年,星期日3.5內(nèi)置函數(shù)(C++,選講)一般函數(shù)調(diào)用的過程:調(diào)用前:參數(shù)傳遞,保存下條指令地址信息,和CPU狀態(tài)信息,執(zhí)行流程轉(zhuǎn)入被調(diào)函數(shù)。調(diào)用完畢:傳回函數(shù)值,執(zhí)行流程回到主調(diào)函數(shù)。函數(shù)調(diào)用花費額外的時間和空間!如果函數(shù)頻繁地被調(diào)用,如調(diào)用出現(xiàn)在循環(huán)中,則開銷大,影響效率(缺點)。函數(shù)的優(yōu)點之一:便于實現(xiàn)模塊化/結(jié)構(gòu)化程序設(shè)計的方法。發(fā)揮其優(yōu)點,克服其缺點,采用內(nèi)置函數(shù)第四十三頁,共九十七頁,編輯于2023年,星期日3.5內(nèi)置函數(shù)(C++,選講)一般函數(shù)調(diào)用的過程:C++編譯時將被調(diào)函數(shù)的代碼直接嵌入到主調(diào)函數(shù)中,程序執(zhí)行時不必將流程轉(zhuǎn)出去。這種嵌入到主調(diào)函數(shù)中的函數(shù)稱為內(nèi)置函數(shù)(inlinefunction),又稱內(nèi)嵌函數(shù)或內(nèi)聯(lián)函數(shù)。第四十四頁,共九十七頁,編輯于2023年,星期日3.5.1內(nèi)置函數(shù)的作用提高程序中函數(shù)調(diào)用的效率;并保持程序的可讀性。
適應(yīng)場合:如果函數(shù)頻繁地被調(diào)用.指定內(nèi)置函數(shù)的方法:在函數(shù)定義首行(或函數(shù)說明)的左端加一個關(guān)鍵字inline即可。第四十五頁,共九十七頁,編輯于2023年,星期日#include<iostream.h>intis_number(char);//函數(shù)聲明voidmain(){charc;while((c=cin.get())!='\n'){if(is_number(c))//調(diào)用一個小函數(shù)cout<<"youenteradigit\n";elsecout<<"youenteranon-digit\n";}}intis_number(charch)//函數(shù)定義{return(ch>='0'&&ch<='9')?1:0;}【例3.9】判斷用戶從鍵盤輸入的系列字符是數(shù)字字符還是其它字符的函數(shù)is_number()。第四十六頁,共九十七頁,編輯于2023年,星期日程序中不斷到設(shè)備中讀取數(shù)據(jù),頻繁調(diào)用is_number()函數(shù)。為了避免頻繁調(diào)用函數(shù),提高執(zhí)行效率,可以將【例3.9】程序改為:#include<iostream.h>//*****ex3_9b.cpp*****voidmain(){charc;while((c=cin.get())!='\n'){if((c>='0'&&c<='9')?1:0)//修改處:直接計算表達式
cout<<"youenteradigit\n";elsecout<<"youenteranon-digit\n";}}第四十七頁,共九十七頁,編輯于2023年,星期日修改后的程序在if語句中用表達式替換了函數(shù)調(diào)用。在程序運行上,提高了一些執(zhí)行效率,因為免去了大量的函數(shù)調(diào)用開銷。但是,由于is_number函數(shù)比相應(yīng)的表達式可讀性好,所以修改后的代碼可讀性降低,尤其若程序中多處出現(xiàn)is_number的替換時,會大大降低可讀性。我們希望既要用函數(shù)調(diào)用來體現(xiàn)其結(jié)構(gòu)化和可讀性,又要使效率盡可能地高。為了盡量做到兩全其美,C++中引入內(nèi)置函數(shù)這個方法。第四十八頁,共九十七頁,編輯于2023年,星期日內(nèi)置函數(shù)的定義格式如下:inline
類型名函數(shù)名(形參列表){……//函數(shù)體}內(nèi)置函數(shù)的聲明格式如下:inline類型名函數(shù)名(形參類型表);其實,內(nèi)置函數(shù)只要在開頭一次性聲明為inline即可,而后面的函數(shù)定義仍可寫成一般函數(shù)定義的形式,編譯器也會將函數(shù)視為內(nèi)置函數(shù)。3.5.2定義和使用內(nèi)置函數(shù)第四十九頁,共九十七頁,編輯于2023年,星期日對【例3.9】使用內(nèi)置函數(shù)來解決,代碼可以寫成下列形式:#include<iostream.h>//*****ex3_9c.cpp*****inlineintis_number(char);//inline函數(shù)聲明voidmain(){charc;while((c=cin.get())!='\n'){if(is_number(c))//調(diào)用一個小函數(shù)cout<<"youenteradigit\n";elsecout<<"youenteranon-digit\n";}}intis_number(charch)//此處可省掉inline,卻被本程序視為inline{return(ch>='0'&&ch<='9')?1:0;}第五十頁,共九十七頁,編輯于2023年,星期日(1)內(nèi)置函數(shù)與一般函數(shù)的區(qū)別在于函數(shù)調(diào)用的處理。一般函數(shù)進行調(diào)用時,要將程序執(zhí)行到被調(diào)用函數(shù)中,然后返回到主調(diào)函數(shù)中;而內(nèi)置函數(shù)在調(diào)用時,是將調(diào)用部分用內(nèi)置函數(shù)體來替換。(2)若函數(shù)定義部分在調(diào)用之后,則內(nèi)置函數(shù)必須先聲明后調(diào)用。因為程序編譯時要對內(nèi)置函數(shù)替換,所以在內(nèi)置函數(shù)調(diào)用之前必須聲明是內(nèi)置的(inline),否則將會像一般函數(shù)那樣產(chǎn)生調(diào)用而不是進行替換操作。(3)在內(nèi)置函數(shù)中,不能含有復(fù)雜的結(jié)構(gòu)控制語句,如switch、for和while。如果內(nèi)置函數(shù)有這些語句,則編譯器將該函數(shù)視同一般函數(shù)那樣產(chǎn)生函數(shù)調(diào)用。(4)遞歸函數(shù)不能用作內(nèi)置函數(shù)。(5)以后講到的類中,所有定義在說明內(nèi)部的函數(shù)都是內(nèi)置函數(shù)。關(guān)于內(nèi)置函數(shù)的說明:第五十一頁,共九十七頁,編輯于2023年,星期日3.6變量和函數(shù)的屬性變量的屬性:類型、名稱、作用域、生存期
3.6.1變量的作用域
作用域:指變量在空間上的有效范圍。1.局部變量局部變量:在函數(shù)或程序塊(復(fù)合語句)內(nèi)定義的變量。其作用域:相應(yīng)的函數(shù)體或程序塊,從定義點到相應(yīng)的函數(shù)體或程序塊的尾部。voidf(intt)//t為函數(shù)級的局部變量。{intx1;//x1為函數(shù)級的局部變量。
……{inty1;//y1為語句塊級的局部變量,
……inty2;//y2為語句塊級的局部變量,
……
}……intx2;//x2為函數(shù)級的局部變量。……}第五十二頁,共九十七頁,編輯于2023年,星期日【例3.10】局部變量的使用。#include<iostream.h>doublefun1(doublea,doubleb){doublec;//fun1函數(shù)中3個局部變量a、b、cc=a+b;returnc;}voidmain()//main函數(shù)中3個局部變量a、b、c{doublea,b,c;cout<<"inputtwonumbers:";cin>>a>>b;c=fun1(a,b);cout<<"a+b="<<c<<endl;c=fun2(a,b);cout<<"a*b="<<c<<endl;}局部變量同名現(xiàn)象:不同范圍的局部變量可以同名,不同范圍的同名局部變量表示不同的數(shù)據(jù)。但同一范圍內(nèi)不允許兩變量同名出現(xiàn)。doublefun2(doublea,doubleb){doublec;//fun2函數(shù)中3個局部變量a、b、cc=a*b;returnc;}第五十三頁,共九十七頁,編輯于2023年,星期日注意:在函數(shù)聲明中出現(xiàn)的參數(shù)名,其作用范圍只在本行的括號內(nèi)。例如:intmax(inta,intb);
//函數(shù)聲明中出現(xiàn)的a、b,它們的作用范圍只在本行有效。
intmax(int,int);
第五十四頁,共九十七頁,編輯于2023年,星期日定義在函數(shù)以外的變量(外部變量,靜態(tài)全局變量)。作用域:從變量定義處到該文件結(jié)尾處。通過聲明后,對本程序的其它文件中的函數(shù)也可見。2.全局變量第五十五頁,共九十七頁,編輯于2023年,星期日#include<iostream.h>inta;//a的作用域為整個文件voidfun1();//聲明fun1函數(shù)voidmain(){cout<<a<<endl;//main函數(shù)中使用了全局變量afun1();//調(diào)用fun1函數(shù)cout<<a<<endl;//main函數(shù)中再次使用全局變量a}voidfun1(){a=5;}//fun1函數(shù)中使用全局變量a程序運行結(jié)果如下:05沒有設(shè)定初始值的全局變量,編譯默認其初值為0?!纠?.11】全局變量的使用第五十六頁,共九十七頁,編輯于2023年,星期日說明:(1)沒有人為設(shè)定初始值的全局變量,編譯將其初值設(shè)為0(全局變量默認初始值為0)。(2)全局變量可以定義在任何位置,但其作用域是從定義的位置開始到文件的末尾。
而定義在文件中間的全局變量就只能被其下面的函數(shù)所使用,全局變量定義之前的所有函數(shù)不會知道該變量。
(3)全局變量為函數(shù)之間數(shù)據(jù)的傳遞提供了通道。由于全局變量可以被其定義后的函數(shù)所使用,所以可以使用全局變量進行函數(shù)間數(shù)據(jù)的傳遞。而且這種傳遞數(shù)據(jù)的方法可以傳遞多個數(shù)據(jù)的值。第五十七頁,共九十七頁,編輯于2023年,星期日gcd(a,b)
maxlcm(a,b)main()
min分析:由于求最小公倍數(shù)要依賴于最大公約數(shù),所以應(yīng)先求最大公約數(shù)。故應(yīng)將求最大公約數(shù)的函數(shù)寫在前面,求最小公倍數(shù)的函數(shù)放在后面。intgcd(int,int);//聲明求最大公約數(shù)的函數(shù)intlcm(int,int);//聲明求最小公倍數(shù)的函數(shù)intmax,min;//全局變量分別存放最大公約數(shù)、最小公倍數(shù)voidmain()【例3.12】分別寫兩個函數(shù)求給定兩個數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù)。第五十八頁,共九十七頁,編輯于2023年,星期日分析:由于求最小公倍數(shù)要依賴于最大公約數(shù),所以應(yīng)先求最大公約數(shù)。故應(yīng)將求最大公約數(shù)的函數(shù)寫在前面,求最小公倍數(shù)的函數(shù)放在后面。#include<iostream>intgcd(int,int);//聲明求最大公約數(shù)的函數(shù)intlcm(int,int);//聲明求最小公倍數(shù)的函數(shù)intmax,min;//全局變量分別存放最大公約數(shù)、最小公倍數(shù)voidmain(){inta;intb;cout<<"inputa,b:";cin>>a>>b;gcd(a,b);lcm(a,b);cout<<"thegreatestcommondivisoris:"<<max<<endl;//使用全局變量max
cout<<"theleasecommonmultipleis:"<<min<<endl;//使用全局變量min}【例3.12】分別寫兩個函數(shù)求給定兩個數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù)。第五十九頁,共九十七頁,編輯于2023年,星期日intgcd(intx,inty){intt;intr;if(x<y){t=x;x=y;y=t;}r=x%y;while(r!=0){x=y;y=r;r=x%y;}
max=y;returnmax;//使用全局變量max}intlcm(intx,inty){
min=x*y/max;//使用全局變量max求全局變量min,returnmin;//返回全局變量min}void
gcd(intx,inty){intt;intr;if(x<y){t=x;x=y;y=t;}r=x%y;while(r!=0){x=y;y=r;r=x%y;}
max=y;}第六十頁,共九十七頁,編輯于2023年,星期日(4)全局變量降低了函數(shù)的通用性,建議不在必要時不要使用全局變量(缺點)。因為如果函數(shù)在執(zhí)行的時候使用了全局變量,那么其他程序使用該函數(shù)時也必須將該全局變量一起移過去。另外,全局變量在程序執(zhí)行的全部過程都占用存儲空間,而不是需要時才開辟存儲空間。第六十一頁,共九十七頁,編輯于2023年,星期日3.不同作用域的同名變量引用規(guī)則
程序運行結(jié)果是:1,2,3,5
【例3.13】不同作用域的同名變量引用規(guī)則示例?!璱nta=5;
//全局變量aintfun();//聲明一個函數(shù)main()
{inta;
//函數(shù)級局部變量a
a=1;//引用是函數(shù)級局部變量acout<<a<<”,”;
//此處引用的是函數(shù)級局部變量a{inta;
//程序塊級局部變量a
a=2;
//此處引用是程序塊級局部變量acout<<a<<”,”;//此處引用的是程序塊級局部變量a}
a=3;
//此處引用的a是函數(shù)級局部變量acout<<a<<”,”;//此處引用的a是函數(shù)級局部變量acout<<fun()<<endl;}intfun(){returna;}//全局變量a
重名變量作用域規(guī)則:在某個作用域范圍內(nèi)定義的變量,在該范圍的子范圍內(nèi)可以定義重名變量,這時原定義的變量在子范圍內(nèi)是不可見的,但是它還存在,只是在子范圍內(nèi)由于出現(xiàn)了重名的變量而被暫時隱藏起來,過了子范圍后,它又是可見的。第六十二頁,共九十七頁,編輯于2023年,星期日3.6.2變量的生存期(較難)變量存儲期(生命期):變量(值)在內(nèi)存中存在的時間。動態(tài)存儲區(qū)(堆棧)靜態(tài)(全局)存儲區(qū)寄存器(CPU中)數(shù)據(jù)存儲區(qū)(變量存儲區(qū))1.短生存期變量――動態(tài)存儲方式2.長生存期變量――靜態(tài)存儲方式變量存儲期長短由變量的存儲方式?jīng)Q定。動態(tài)存儲方式:在程序運行期間動態(tài)地分配存儲空間給變量的方式。包括:函數(shù)的形參,函數(shù)或程序塊中定義的局部變量(未用static聲明)。具體有兩種:自動變量、寄存器類變量。靜態(tài)存儲方式:在程序運行期間分配固定的存儲空間給變量的方式。存儲位置:靜態(tài)(全局)存儲區(qū),生存期:為程序運行期間。包括:全局變量(含外部變量、靜態(tài)全局變量)、靜態(tài)局部變量。存儲位置:在動態(tài)存儲空間(堆或棧)或寄存器中。存儲期:為函數(shù)或程序塊的運行期間。
第六十三頁,共九十七頁,編輯于2023年,星期日存儲位置:在動態(tài)數(shù)據(jù)存儲區(qū);生存期:函數(shù)或程序塊執(zhí)行期間;作用域:其所在函數(shù)或程序塊。用關(guān)鍵字auto作為存儲類別的聲明。例如:intfun(){autointa;//a為自動類變量}
關(guān)鍵字“auto”可以省略。上述自動變量也可聲明為inta;(1)自動變量:函數(shù)中的局部變量默認是自動變量。(2)寄存器變量:局部變量。存儲位置:在CPU的通用寄存器中;生存期:作用域:特點:訪問效率高,數(shù)量較少;用關(guān)鍵字register作為存儲類別的聲明。例如:voidmain(){registerinti;…}第六十四頁,共九十七頁,編輯于2023年,星期日1)寄存器變量不宜定義過多。計算機中寄存器數(shù)量是有限的,不能允許所有的變量都為寄存器變量。如果寄存器變量過多或通用寄存器被其他數(shù)據(jù)使用,那么系統(tǒng)將自動把寄存器變量轉(zhuǎn)換成自動變量。2)寄存器變量的數(shù)據(jù)長度與通用寄存器的長度相當。一般是char型和int型變量。寄存器變量的使用應(yīng)注意以下問題:第六十五頁,共九十七頁,編輯于2023年,星期日2.長生存期變量――靜態(tài)存儲方式全局變量(含外部變量、靜態(tài)全局變量)和靜態(tài)局部變量。(1)外部變量:未用static關(guān)鍵字定義的全局變量。如果不對外部變量另加聲明,則它的作用域是從定義點到所在文件的末尾。第六十六頁,共九十七頁,編輯于2023年,星期日用extern關(guān)鍵詞加以聲明后將外部變量作用域擴展到聲明位置,聲明語句格式為extern
類型符
外部變量名;//int類型符可省改具體方式:①提前引用聲明。擴展外部變量作用域的方式【例3.14】對定義在同一文件中外部變量,作提前引用聲明可以擴展其使用范圍到文件前面的聲明位置。#include<iostream.h>voidmain(){x=4;cout<<x<<endl;}intx;//外部變量x的定義……externintx;//提前引用聲明第六十七頁,共九十七頁,編輯于2023年,星期日②跨文件引用聲明。
擴展外部變量作用域的方式【例3.15】對定義在另一文件中的外部變量,作跨文件引用聲明以擴展其作用域到本文件。文件file1.cpp的內(nèi)容:#include<iostream.h>voidmain(){cout<<w<<endl;//使用file2.cpp文件中定義的變量w}文件file2.cpp的內(nèi)容:intw=10;//外部變量w的定義程序運行結(jié)果如下:10externintw;//跨文件引用聲明用途:用于多個文件中的函數(shù)共享數(shù)據(jù)!兩個文件中不能出現(xiàn)同名的外部變量!
第六十八頁,共九十七頁,編輯于2023年,星期日(2)靜態(tài)變量:靜態(tài)全局變量、靜態(tài)局部變量
①靜態(tài)全局變量:在定義全局變量時開頭再添加一個static關(guān)鍵字所定義的全局變量。作用域:定義點至定義所在文件的末尾;可以通過提前引用聲明擴展其作用域;不能通過跨文件引用聲明擴展其作用域(只對本文件有效)。一個文件中定義的靜態(tài)全局變量與別的文件中定義的同名靜態(tài)全局變量或同名外部變量沒有牽連,互不影響!默認初值:0。第六十九頁,共九十七頁,編輯于2023年,星期日【例3.17】靜態(tài)全局變量的演示。文件file1.cpp的內(nèi)容:#include<iostream.h>staticintu=10;//定義靜態(tài)全局變量voidfun(){cout<<”Thisisfile1”}文件file2.cpp的內(nèi)容:#include<iostream.h>externintu;//試圖對u作跨文件引用聲明,此時行不通voidmain(){cout<<u<<endl;//出現(xiàn)“變量u未定義”錯誤}第七十頁,共九十七頁,編輯于2023年,星期日(2)靜態(tài)變量:靜態(tài)全局變量、靜態(tài)局部變量
②靜態(tài)局部變量:在定義局部變量時開頭再添加一個static關(guān)鍵字所定義的局部變量。生命周期:作用域:默認初值:0。第七十一頁,共九十七頁,編輯于2023年,星期日【例3.16】使用靜態(tài)局部變量的例子。#include<iostream.h>voidfun();voidmain(){inti;for(i=0;i<3;i++)fun();}voidfun(){inta=0;//定義局部變量
staticintb=0;//定義靜態(tài)局部變量
a=a+1;b=b+1;cout<<a<<","<<b<<endl;}程序運行結(jié)果如下:1,11,21,3第七十二頁,共九十七頁,編輯于2023年,星期日變量屬性總結(jié)根據(jù)需要設(shè)置變量的屬性!第七十三頁,共九十七頁,編輯于2023年,星期日3.6.3內(nèi)部函數(shù)和外部函數(shù)(選講)存儲屬性(作用域)分別類似靜態(tài)全局變量、外部變量1內(nèi)部函數(shù)(存儲屬性類似靜態(tài)全局變量)如果一個函數(shù)只能被本文件中其他函數(shù)所調(diào)用,它稱為內(nèi)部函數(shù)。在定義內(nèi)部函數(shù)時,在函數(shù)名和函數(shù)類型的前面加static。函數(shù)首部的一般格式為static類型標識符函數(shù)名(形參表)如staticintfun(inta,intb)內(nèi)部函數(shù)又稱靜態(tài)(static)函數(shù)。使用內(nèi)部函數(shù),可以使函數(shù)只局限于所在文件。不同文件中的同名內(nèi)部函數(shù)互不干擾。第七十四頁,共九十七頁,編輯于2023年,星期日【例3.18】靜態(tài)函數(shù)的例子。文件file1.cpp中的內(nèi)容:#include<iostream.h>staticvoidfun();voidmain(){fun();}staticvoidfun()//文件file1中定義靜態(tài)函數(shù),名稱為fun{cout<<"thisinfile1"<<endl;}文件file2.cpp中的內(nèi)容:#include<iostream.h>staticvoidfun()//文件file2中定義靜態(tài)函數(shù),名稱也為fun{cout<<"thisinfile2"<<endl;}程序運行結(jié)果如下:thisinfile1第七十五頁,共九十七頁,編輯于2023年,星期日2外部函數(shù)(存儲屬性類似外部變量)外部函數(shù)是可以被整個程序各文件中函數(shù)調(diào)用的函數(shù)。(1)外部函數(shù)的定義。在函數(shù)類型前加存儲類型關(guān)鍵字extern,或缺省存儲類型關(guān)鍵字,定義格式如下:[extern]函數(shù)類型函數(shù)名([參數(shù)列表]){
函數(shù)體}extern可缺省,即系統(tǒng)默認為extern型。(2)外部函數(shù)的(跨文件引用)聲明。文件A在需要調(diào)用文件B中所定義的外部函數(shù)時,需要在文件A中用關(guān)鍵字extern對被調(diào)函數(shù)提出聲明,聲明格式如下:extern
函數(shù)類型函數(shù)名(參數(shù)類型列表)第七十六頁,共九十七頁,編輯于2023年,星期日【例3.19】文件file1.cpp利用別的文件(file2.cpp)中的外部函數(shù)實現(xiàn)求階乘。文件file1.cpp中的內(nèi)容:#include<iostream>usingnamespacestd;voidmain(){externdoublefac(int);//聲明其他文件中定義的外部函數(shù)intn;cout<<"pleaseinputaintegerton:"<<endl;cin>>n;cout<<n<<"!="<<fac(n)<<endl;}文件file2.cpp中的內(nèi)容:#include<iostream>usingnamespacestd;externdoublefac(intm)//定義fac函數(shù)extern可以省略{intn;doubles;s=1;for(n=1;n<=m;n++)s=s*n;returns;}程序運行結(jié)果如下:pleaseinputaintegerton:5↙5!=120第七十七頁,共九十七頁,編輯于2023年,星期日什么叫編譯預(yù)處理?指編譯前對源程序中的
特殊命令(預(yù)處理命令)進行的一些預(yù)處理加工的過程。預(yù)處理由編譯系統(tǒng)中的預(yù)處理程序按源程序中的預(yù)處理命令進行。功能:編譯預(yù)處理命令不是C語句,但它擴展了C++程序的設(shè)計環(huán)境,提高編程效率。
源程序目標程序可執(zhí)行程序中間結(jié)果編譯預(yù)處理編譯連接編譯
C/C++程序提供的編譯預(yù)處理命令有三種:
1.宏定義
2.文件包含3.條件編譯3.7編譯預(yù)處理第七十八頁,共九十七頁,編輯于2023年,星期日1不帶參數(shù)的宏定義用一個指定的標識符來代表一個字符串,它的一般定義形式為
#define
標識符字符串
這種方法使用戶能以一個簡單的名字代替一個長的字符串,因此把這個標識符稱為“宏名
”。
#define
宏名
字符串
;
在預(yù)編譯時將宏名替換成字符串的過程稱為“宏展開”。3.7.1宏定義第七十九頁,共九十七頁,編輯于2023年,星期日#define
PI3.1415926 /*PI是宏名,3.1415926用來替換宏名的常數(shù)main(){floatradius,length,area,volume;cin>>radius;length=2*PI*radius; /*引用無參宏名求周長*/
area=PI*radius*radius;/*引用無參宏名求面積*/
cout<<length<<area;}length=2*3.1415926
*radius;例3.20輸入圓的半徑,求圓的周長、面積。要求使用無參宏定義圓周率。第八十頁,共九十七頁,編輯于2023年,星期日(1)可提高源程序的可維護性(2)可提高源程序的可移植性
(3)減少源程序中重復(fù)書寫字符串的工作量使用宏定義的優(yōu)點第八十一頁,共九十七頁,編輯于2023年,星期日說明:(1)在定義宏時,“宏名”和“字符串”之間要用空格分開。而“字符串”中的內(nèi)容不要有空格。(2)宏名通常用大寫字母定義。(3)宏定義是在編譯前對宏進行替換的,但對程序中用雙引號括起來的字符串內(nèi)容,如果其中有與宏名相同的部分,是不進行文本替換的。例如:#include<iostream.h>#definePI3.14159
voidmain(){cout<<"PI="<<PI<<endl;}程序運行結(jié)果如下:PI=3.14159第八十二頁,共九十七頁,編輯于2023年,星期日(4)宏定義后,可以在本文件各個函數(shù)中使用。也可以使用#undef取消宏的定義。(5)宏定義可以嵌套,已被定義的宏可以用來定義新的宏。例如:#include<iostream>#defineM3#defineNM+2//用已定義的宏M來定義新的宏N#defineL4*N+6//用已定義的宏N來定義新的宏Lvoidmain(){cout<<L<<endl;}
程序運行結(jié)果如下:20與常變量的區(qū)別
const
double
PI3.14159第八十三頁,共九十七頁,編輯于2023年,星期日2.有參數(shù)宏定義
帶參數(shù)宏定義的一般格式
#define宏名(形參表)字符串
宏展開:不只是簡單地將宏名用字符串替換,還要進行參數(shù)替換。#definePI3.1415926#defineS(r)PI*r*rmain(){floata,area;a=3.6;area=S(a);cout<<a<<area;}area=PI*a*aarea=3.1415926*a*a第八十四頁,共九十七頁,編輯于2023年,星期日(1)定義有參宏時,宏名與左圓括號之間不能留有空格。否則,C編譯系統(tǒng)將空格以后的所有字符均作為替代字符串,而將該宏視為無參宏。(2)有參宏的展開,只是將宏名和參數(shù)進行字符串替換。為了保證宏的展開結(jié)果正確,在定義有參宏時,在所有形參外和整個字符串外,均加一對圓括號。
area=S(a+5);預(yù)期的替換的結(jié)果:area=3.1415926*(a+5)*(a+5)宏展開(字符串替換)的實際結(jié)果:area=3.1415926*a+5*a+5d=1/S(a+5);預(yù)期的替換的結(jié)果:d=1/(3.1415926*(a+5)*(a+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)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)療診斷、監(jiān)護及治療設(shè)備制造考核試卷
- 二零二五年度跨境電子商務(wù)平臺運營承包合同2篇
- 合同簽訂授權(quán)委托書
- 2025年滬教版七年級歷史下冊月考試卷含答案
- 2025年北師大新版八年級地理上冊月考試卷含答案
- 2025年外研版三年級起點選擇性必修3歷史下冊階段測試試卷
- 2025年度暖通工程綠色建材采購合同4篇
- 二零二五版景區(qū)導(dǎo)覽門牌定制服務(wù)合同4篇
- 2025版南京市房產(chǎn)局推廣的房屋抵押權(quán)設(shè)立合同模板4篇
- 二零二五年度農(nóng)膜行業(yè)人才培養(yǎng)與交流合同3篇
- DB32-T 4444-2023 單位消防安全管理規(guī)范
- 臨床三基考試題庫(附答案)
- 合同簽訂執(zhí)行風(fēng)險管控培訓(xùn)
- DB43-T 3022-2024黃柏栽培技術(shù)規(guī)程
- 九宮數(shù)獨200題(附答案全)
- 人員密集場所消防安全管理培訓(xùn)
- 《聚焦客戶創(chuàng)造價值》課件
- PTW-UNIDOS-E-放射劑量儀中文說明書
- JCT587-2012 玻璃纖維纏繞增強熱固性樹脂耐腐蝕立式貯罐
- 典范英語2b課文電子書
- 員工信息登記表(標準版)
評論
0/150
提交評論