函數(shù)和編譯預處理2_第1頁
函數(shù)和編譯預處理2_第2頁
函數(shù)和編譯預處理2_第3頁
函數(shù)和編譯預處理2_第4頁
函數(shù)和編譯預處理2_第5頁
已閱讀5頁,還剩88頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、函數(shù)和編譯預處理2main( )func1()func2()func3()func5()func4()主調函數(shù)、調用被調函數(shù)子函數(shù)、被調用參數(shù)返回值主調函數(shù) 和 被調函數(shù) 的關系: 上下級 關系請問:main( ) 被 誰調用?一個程序中 函數(shù) 調用 的示意圖:#include void main( ) int n; cinn; if (n1) cout“the sum is: sum( n )endl; /調用 sum()函數(shù) int sum( int n) 例3.1 編寫函數(shù)求前 n 個自然數(shù)之和,n 的值從鍵盤輸入。函數(shù)首部、函數(shù)頭函數(shù)首部/函數(shù)頭函數(shù)體 int k,s=0; for (

2、k=1;ky)? x : y ; return z; void main (void ) int a,b,c; cinab; c=max (a , b) ; cout“The max is cy)? x : y ; return z; void main (void ) int a,b,c; cinab; c=max (a , b) ; cout“The max is cendl; ab23調用處表達式中3xy23zc=3不要將函數(shù)名做變量用!不能寫成 max=z;2自定義函數(shù)的聲明函數(shù)類型關鍵字 函數(shù)名( 參數(shù)1 類型 , 參數(shù)1名稱 ,參數(shù)2 類型 , 參數(shù)2名稱 ); 什么時候需要聲明?

3、 聲明的含義、作用? 聲明的格式、位置?1庫函數(shù)的聲明 對庫函數(shù)的聲明已經寫在有關 包含文件頭文件 中了,因此只要在程序文件首部用 include 指令將這些 包含文件 包含到本程序中來,就完成了對庫函數(shù)的聲明。 #include 3.2.2 函數(shù)的聲明補述函數(shù)的聲明形式也叫做函數(shù)原型function prototype) 。 它說明了函數(shù)的類型、函數(shù)名、函數(shù)各形式參數(shù)類型。函數(shù)類型關鍵字 函數(shù)名( 參數(shù)1 類型 ,參數(shù)2 類型 );?修改p68?名稱任意,可省略【例3.2】輸入圓柱體的底面半徑和高,求底面圓面積和體積。設函數(shù) area()和 volum()分別求圓面積和圓柱體體積。#incl

4、ude using namespace std;void main() double volum(float, float); /聲明 double area(float r); /聲明 float r,h; double s,v; coutrh; s= area(r); /調用 v= volum(r,h); /調用 couts=s,v=vab; c=add (a , 3.5) ; cout“The sum is cendl; 2實參 與 形參的類型應一樣或賦值兼容。 值傳遞: 調用函數(shù)時,計算機將函數(shù)調用處的實參值傳給被調函數(shù)的形參,在被調函數(shù)執(zhí)行過程中,形參可以被改變,但不影響函數(shù)調用處的

5、實參值。換一句話說,這種參數(shù)傳遞機制是單向影響。3.3.1 參數(shù)的 值傳遞 (前面已介紹) 除了小節(jié)介紹的值傳遞參數(shù)方式外,函數(shù)調用還有一種特殊的值傳遞形式,即傳遞的值不是一般的數(shù)值,而是一些內存單元地址編號即地址,這時,一般稱之為參數(shù)的地址傳遞。在這種參數(shù)傳遞形式中,無論在函數(shù)的定義中出現(xiàn)的形參還是在調用語句中出現(xiàn)的實參,都是代表一些內存單元地址編號即地址數(shù)值,而不是一般的數(shù)值。 C+中的參數(shù)地址傳遞情況一般有如下幾種:實參可以是一個有確定值的普通變量的地址,或者是一個已經初始化的指針變量;或者是一個初始化的數(shù)組名;或者是一個具體的函數(shù)名。而形參可以是一個任意普通變量的地址,或是一個任意指針

6、變量,或是一個任意的數(shù)組名,或是一個指向函數(shù)的指針變量對應于實參是具體函數(shù)名。 3.3.2 參數(shù)的 地址傳遞4章 實際上,這種參數(shù)傳遞機制就是在函數(shù)調用時把一個內存單元地址傳遞給形參,使形參也具有實參的內存單元地址即兩者對應同一個內存單元,稱作形參和實參地址結合,兩者合二為一。這樣一來,任何時候形參的值等于實參的值;而實參的值也等于形參的值。因此,形參在函數(shù)中發(fā)生變化后,也會引起實參跟著變化因為它們是捆綁在一起的,一體化的。這就意味著按地址傳遞的方式,在調用剛開場時實參的值影響了形參;而在被調函數(shù)執(zhí)行過程中形參值假設發(fā)生了變化,它也會影響實參的值變化。即機制是雙向影響,這與普通值傳遞方式的單向

7、影響機制形成比照?!纠?.5】 延遲函數(shù)的使用。#include void delay(int loop); /聲明void main( ) coutbeginendl; delay( 1000 ); /調用 coutendendl;void delay(int loop) /定義 if (loop=0) return; for(int i=0;iloop;i+) coutiendl; 3.3.3 帶 默認值 的參數(shù) C+ C+語言中,允許在函數(shù)定義或聲明時給一個或多個形參指定默認值。這樣,后面的函數(shù)調用中,可以不給具有默認值的形參設定相應的實參。void delay(int loop=100

8、0); void delay(int x=1000); delay( ); /調用 對于教材【例3.2】的求圓柱體體積的函數(shù)volume( ),如下聲明:float volumefloat r, float h); /只對形參h指定默認值這時函數(shù)調用形式:volume(6.0); /相當于volume(6.0, ),7.2); / r的值為,h的值為7.2 如果函數(shù)有多個形參,可以對每個或局部形參指定默認值。 指定默認值的形參必須放在參數(shù)列表中的 最 右 邊。課堂總結a 函數(shù)b 函數(shù)main 函數(shù)結束(2)(3)(4)(5)(6)(7)(8)(9)C語言不允許對函數(shù)作嵌套定義!3.4.1 嵌套

9、調用:在一個函數(shù)定義中,可以調用另一個函數(shù)。 程序執(zhí)行時,在調用一個函數(shù)的過程中,又調用另一個函數(shù)。 例如:3.4 函數(shù)的 嵌套調用 和 遞歸調用調用 a 函數(shù)調用 b 函數(shù)main( )函數(shù) 直接地 調用了 a函數(shù),main( )函數(shù) 嵌套地 調用了 b函數(shù)(間接調用)。long comb(int n, int m) /定義組合函數(shù)long c; c=fac(m)/(fac(n)*fac(m-n);/ 嵌套調用階乘函數(shù) return c;void main() int n,m; long c;coutplease input two integer numbers:m,nmn;c= comb

10、 (n,m); / 調用組合函數(shù)combcoutc=cendl;main()分析:定義函數(shù)long comb(int n,int m) 求組合數(shù)。定義函數(shù)long fac(int k)求k的階乘。comb()fac()#include using namespace std;long fac(int k) / 定義求階乘的函數(shù)long f=1; int i; for(i=1;i=k;i+) f = f*i; return f;【例3.6】編程求組合數(shù),3.4.2 函數(shù)的 遞歸調用 在調用一個函數(shù)的過程中,被調用函數(shù)又直接或間接地調用 自身,這種調用過程稱為函數(shù)的遞歸(recursive)調用。

11、直接遞歸 調用 函數(shù) 的代碼形式:int f ( ) / 函數(shù)f1的定義 / 函數(shù)其它局部 z=f ( ); / 直接調用自身 / 函數(shù)其它局部 在函數(shù)f ( ) 中,又直接調用了f ( )函數(shù)。間接遞歸 調用 函數(shù) 可以表現(xiàn)為如下:int f1 ( ) / 函數(shù)f1的定義 / f1的其他局部x=f2 ( ); / 調用f2 ( ) / f1的其他局部 int f2 ( ) / 函數(shù)f2的定義 / f2的其他局部y=f1 ( ); / 調用f1 ( ) / f2的其他局部 函數(shù)的直接遞歸調用 函數(shù)的間接遞歸調用 圖中調用過程特點:這兩種遞歸調用都是無終止的自身調用?! 程序中不應出現(xiàn)這種無終止

12、的遞歸調用,而只應出現(xiàn)有限次數(shù)的、有終止的遞歸調用! 解決:用if語句來控制,只有在某一條件成立時才繼續(xù)執(zhí)行遞歸調用,否那么就不再繼續(xù)。包含遞歸調用的函數(shù)稱為遞歸函數(shù)?!纠?.7】 用遞歸計算 n!。求n!,應先求n-1!;而求(n-1)!,又需要先求n-2!,而求(n 2)??;又可以變成求n-3!,如此繼續(xù),直到最后變成求1!的問題,而根據(jù)公式有1!=1(這就是本問題的遞歸終止條件。由終止條件得到1!結果后,再反過來 依次求出2!,3!直到最后求出n!。【例3.7】 用遞歸計算n!。 n!本身就是以遞歸的形式定義的:#include using namespace std;long fac(

13、int n)long f; if (n=1) f=1; else f=n*fac(n-1); / 遞歸調用,求(n-1)! return f;void main( )long y; int n; coutplease input a integer n n; y=fac(n); /調用fac(n)求n!coutn=n,y=y1)long fibonacci(int n)if( n=0|n=1 )return n;elsereturn fibonacci(n-1)+fibonacci(n-2);程序如下所示: ?實驗教程?P19 三 實驗思考 1:求Fibonacci數(shù)列 大于t的最小項 的值。

14、void main()int n=0,t;long result,t;cint;result=fibonacci(n);whlie (result=t) n+; result=fibonacci(n); coutresult;方法:1.遞歸函數(shù)?實驗教程: P19 三 實驗思考 1 ?2.用循環(huán)做 ?實驗教程: p90.四,1 ?3. 數(shù)組 ?教材:p140,3?求兩個數(shù)最大公約數(shù)的方法1. 輾轉相除法 (p57)2. 短除法3. 試探法4. 遞歸方法 用 函數(shù)遞歸調用 做用 g(m,n) 表示m、n的最大公約數(shù),請寫出那么其遞歸定義。遞歸邊界終止條件使問題向遞歸邊界終止條件轉化的規(guī)那么類似例

15、題習題:強調:上述問題的遞歸定義具備兩個成分:遞推方法程序描述繁雜,可讀性差;主要采用 循環(huán)構造;逐步執(zhí)行;當前值的求得總建立在前面求解的根底上;遞歸方法描述與原始問題遞歸公式比較接近;書寫簡潔、易讀易寫;易于分析算法的復雜性和證明算法的正確性;在問題轉化時,需要花時間和存儲空間將有關的“現(xiàn)場信息保存起來;當?shù)竭_終止條件時,系統(tǒng)又需要花時間將有關的“現(xiàn)場信息恢復以便處理未曾處理完的函數(shù)調用 。占用存儲空間少,執(zhí)行速度快。遞歸 與 遞推 算法遞歸函數(shù)的適應場合:待求解的問題含有遞歸關系?!纠?.8】 漢諾塔問題abc漢諾塔Tower of Hanoi問題據(jù)說來源于布拉瑪神廟。該問題的裝置如下圖(

16、圖上僅畫三個金片以簡化問題的原理,原問題有64個金片),底座上有三根金鋼石的針,第一根針a上放著從大到小64個金片。解決該問題就是要想法把所有金片從第一根針a上移到第三根針c上,第二根針b作為中間過渡。要求是每次只能移動一個金片,并且任何時候不允許大的金片壓在小的金片上面。 圖3.6 三個金片的漢諾塔問題裝置1. 本問題的遞歸終止條件。如果只有1個盤,顯然問題的解就很明顯是:直接把金片從a移到c。因此終止條件是n = 1;終止條件對應的操作是直接把金片從a移到c,示意ac。2. 本問題的遞歸分析:移動n個金片從a到c,必須先將n-1個金片從a借助c移動到b,移動n-1個金片與原問題一樣,但規(guī)模

17、變小,即向終止條件接近,因此,此問題可以用遞歸過程完成。遞歸過程可以用如下步驟表示:(1)將n-1個金片從a經過c移動到b。(2)將第n個金片從a直接移動到c。(3)再將n-1個金片從b經過a移動到c。 一般地,設將n個金片從x針借助y針移動到z針的函數(shù)原形為:void hanoi(int n,char x,char y,char z)根據(jù)解題步驟,可以寫出求解n個金片的漢諾塔函數(shù)如下:#include /*ex3_8.cpp*using namespace std;void hanoi(int n,char x,char y,char z) if (n=1) /n=1時,直接將金片從x移動到

18、z cout x z 1時 hanoi(n-1,x,z,y); /先將n-1個金片從借助z移動到y(tǒng) cout x z 1時,就遞歸調用hanoi(),每次n減1。最后當n=1時,直接移動該金片就可以了。 主函數(shù)如下: void main() int n; cout input n: n; hanoi(n,a,b,c); / n個金片從a針借助b針移動到c針 雖然遞歸調用在寫程序時很簡單,但執(zhí)行起來卻很復雜時間、存儲空間都開銷大。對于漢諾塔問題程序的執(zhí)行過程分析比較復雜,有興趣的讀者可參閱教材對3個盤情景的分析圖3.7 及其相應文字表達。 3.5 內置函數(shù) C+,選講一般函數(shù)調用的過程:調用前:

19、參數(shù)傳遞,保存下條指令地址信息,和CPU狀態(tài)信息,執(zhí)行流程轉入被調函數(shù)。調用完畢:傳回函數(shù)值,執(zhí)行流程回到主調函數(shù)。函數(shù)調用花費額外的時間和空間!如果函數(shù)頻繁地被調用,如調用出現(xiàn)在循環(huán)中,那么開銷大,影響效率缺點。函數(shù)的優(yōu)點之一:便于實現(xiàn)模塊化/構造化程序設計的方法。發(fā)揮其優(yōu)點,抑制其缺點,采用內置函數(shù)3.5 內置函數(shù) C+,選講一般函數(shù)調用的過程:C+編譯時將被調函數(shù)的代碼直接嵌入到主調函數(shù)中,程序執(zhí)行時不必將流程轉出去。這種嵌入到主調函數(shù)中的函數(shù)稱為內置函數(shù)(inline function),又稱內嵌函數(shù) 或 內聯(lián)函數(shù)。3.5.1 內置函數(shù)的作用 提高程序中函數(shù)調用的效率;并保持程序的可讀

20、性。 適應場合:如果函數(shù)頻繁地被調用.指定內置函數(shù)的方法:在函數(shù)定義首行或函數(shù)說明的左端加一個關鍵字inline即可。#include int is_number(char); /函數(shù)聲明void main( ) char c; while (c= cin.get() !=n) if ( is_number(c) ) /調用一個小函數(shù)coutyou enter a digit n;else cout=0& ch=9)?1:0 ; 【例3.9】 判斷用戶從鍵盤輸入的系列字符是數(shù)字字符還是其它字符的函數(shù)is_number()。程序中不斷到設備中讀取數(shù)據(jù),頻繁調用is_number()函數(shù)。為了防止

21、頻繁調用函數(shù),提高執(zhí)行效率,可以將【例3.9】程序改為:#include /*ex3_9b.cpp*void main() char c; while (c=cin.get()!=n) if ( (c=0& c=9)?1:0 ) /修改處:直接計算表達式 coutyou enter a digit n; else coutyou enter a non-digit n; 修改后的程序在if語句中用表達式替換了函數(shù)調用。在程序運行上,提高了一些執(zhí)行效率,因為免去了大量的函數(shù)調用開銷。但是,由于is_number函數(shù)比相應的表達式可讀性好,所以修改后的代碼可讀性降低,尤其假設程序中多處出現(xiàn)is_n

22、umber的替換時,會大大降低可讀性。我們希望既要用函數(shù)調用來表達其構造化和可讀性,又要使效率盡可能地高。為了盡量做到兩全其美,C+中引入內置函數(shù)這個方法。內置函數(shù)的定義格式如下: inline 類型名 函數(shù)名(形參列表) /函數(shù)體 內置函數(shù)的聲明格式如下:inline 類型名 函數(shù)名(形參類型表);其實,內置函數(shù)只要在開頭一次性聲明為inline即可,而后面的函數(shù)定義仍可寫成一般函數(shù)定義的形式,編譯器也會將函數(shù)視為內置函數(shù)。3.5.2 定義 和 使用 內置函數(shù)對【例3.9】使用內置函數(shù)來解決,代碼可以寫成以下形式:#include /*ex3_9c.cpp*inline int is_num

23、ber(char);/inline函數(shù)聲明void main( ) char c; while (c=cin.get()!=n) if (is_number(c) /調用一個小函數(shù)coutyou enter a digit n;else cout=0& ch=9)?1:0; 1內置函數(shù)與一般函數(shù)的區(qū)別在于函數(shù)調用的處理。一般函數(shù)進展調用時,要將程序執(zhí)行到被調用函數(shù)中,然后返回到主調函數(shù)中;而內置函數(shù)在調用時,是將調用局部用內置函數(shù)體來替換。2假設函數(shù)定義局部在調用之后,那么內置函數(shù)必須先聲明后調用。因為程序編譯時要對內置函數(shù)替換,所以在內置函數(shù)調用之前必須聲明是內置的inline,否那么將會像

24、一般函數(shù)那樣產生調用而不是進展替換操作。3在內置函數(shù)中,不能含有復雜的構造控制語句,如switch、for和while。如果內置函數(shù)有這些語句,那么編譯器將該函數(shù)視同一般函數(shù)那樣產生函數(shù)調用。4遞歸函數(shù)不能用作內置函數(shù)。5以后講到的類中,所有定義在說明內部的函數(shù)都是內置函數(shù)。關于內置函數(shù)的說明:3.6 變量 和 函數(shù) 的屬性變量的屬性:類型、名稱、作用域、生存期 3.6.1 變量的作用域 作用域:指變量在 空間上 的有效范圍。1局部變量局部變量:在函數(shù)或程序塊復合語句內定義的變量。其作用域:相應的函數(shù)體 或 程序塊,從定義點到相應的函數(shù)體 或 程序塊的尾部。void f( int t ) /

25、t為函數(shù)級的局部變量。 int x1 ; / x1為函數(shù)級的局部變量。 int y1 ; / y1為語句塊級的局部變量, int y2 ; / y2為語句塊級的局部變量, int x2 ; / x2為函數(shù)級的局部變量。 【例3.10】 局部變量的使用。#include double fun1(double a, double b) double c; /fun1函數(shù)中3個局部變量a、b、cc=a+b; return c; void main() /main函數(shù)中3個局部變量a、b、cdouble a,b,c; coutab; c=fun1(a,b); couta+b=cendl; c=fun2

26、(a,b); couta*b=cendl;局部變量同名現(xiàn)象:不同范圍的局部變量可以同名,不同范圍的同名局部變量表示不同的數(shù)據(jù)。但同一范圍內不允許兩變量同名出現(xiàn)。double fun2(double a,double b) double c; /fun2函數(shù)中3個局部變量a、b、cc=a*b; return c;注意: 在函數(shù)聲明中出現(xiàn)的參數(shù)名,其作用范圍只在本行的括號內。例如:int max(int a,int b); /函數(shù)聲明中出現(xiàn)的a、b,它們的作用范圍只在本行有效。 int max(int, int); 定義在函數(shù)以外的變量外部變量,靜態(tài)全局變量。作用域:從變量定義處到該文件結尾處。

27、通過聲明后, 對本程序的其它文件中的函數(shù)也可見。 2全局變量#include int a; /a的作用域為整個文件void fun1( ); /聲明fun1函數(shù)void main( ) coutaendl; /main函數(shù)中使用了全局變量afun1( ); /調用fun1函數(shù)coutaendl; /main函數(shù)中再次使用全局變量avoid fun1( ) a=5; / fun1函數(shù)中使用全局變量a 程序運行結果如下:05沒有設定初始值的全局變量,編譯默認其初值為0?!纠?.11】 全局變量 的使用說明:1沒有人為設定初始值的全局變量,編譯將其初值設為0全局變量默認初始值為0。 2全局變量可以定

28、義在任何位置,但其作用域是從定義的位置開場到文件的末尾。 而定義在文件中間的全局變量就只能被其下面的函數(shù)所使用,全局變量定義之前的所有函數(shù)不會知道該變量。 3全局變量 為函數(shù)之間 數(shù)據(jù)的傳遞 提供了通道。由于全局變量可以被其定義后的函數(shù)所使用,所以可以使用全局變量進展函數(shù)間數(shù)據(jù)的傳遞。而且這種傳遞數(shù)據(jù)的方法可以傳遞多個數(shù)據(jù)的值。gcd(a, b) maxlcm(a, b)main( ) min分析:由于求最小公倍數(shù)要依賴于最大公約數(shù),所以應先求最大公約數(shù)。故應將求最大公約數(shù)的函數(shù)寫在前面,求最小公倍數(shù)的函數(shù)放在后面。int gcd(int, int);/聲明求最大公約數(shù)的函數(shù)int lcm(i

29、nt, int); /聲明求最小公倍數(shù)的函數(shù)int max , min; /全局變量分別存放 最大公約數(shù)、最小公倍數(shù)void main( )【例3.12】 分別寫兩個函數(shù)求給定兩個數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù)。分析:由于求最小公倍數(shù)要依賴于最大公約數(shù),所以應先求最大公約數(shù)。故應將求最大公約數(shù)的函數(shù)寫在前面,求最小公倍數(shù)的函數(shù)放在后面。#include int gcd(int, int);/聲明求最大公約數(shù)的函數(shù)int lcm(int, int); /聲明求最小公倍數(shù)的函數(shù)int max , min; /全局變量分別存放最大公約數(shù)、最小公倍數(shù)void

30、 main( ) int a; int b; coutab; gcd (a,b); lcm(a,b); cout the greatest common divisor is :maxendl; /使用全局變量 max cout the lease common multiple is :minendl; /使用全局變量 min【例3.12】 分別寫兩個函數(shù)求給定兩個數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù)。int gcd(int x,int y) int t;int r; if (xy) t=x;x=y;y=t; r=x%y; while(r!=0) x=y

31、; y=r; r=x%y; max=y; return max;/使用全局變量maxint lcm(int x,int y) min=x*y/max; /使用全局變量max求全局變量min, return min; /返回全局變量min void gcd(int x,int y) int t;int r; if (xy) t=x;x=y;y=t; r=x%y; while(r!=0) x=y; y=r; r=x%y; max=y;(4) 全局變量降低了函數(shù)的通用性,建議不在必要時不要使用全局變量缺點。因為如果函數(shù)在執(zhí)行的時候使用了全局變量,那么其他程序使用該函數(shù)時也必須將該全局變量一起移過去。

32、另外,全局變量在程序執(zhí)行的全部過程都占用存儲空間,而不是需要時才開辟存儲空間。 3不同作用域的同名變量引用規(guī)那么 程序運行結果是:1,2,3,5 【例3】不同作用域的同名變量引用規(guī)那么例如。int a=5; /全局變量aint fun(); /聲明一個函數(shù)main() int a; /函數(shù)級局部變量a a=1; /引用是函數(shù)級局部變量a couta,; /此處引用的是函數(shù)級局部變量a int a; /程序塊級局部變量a a=2; /此處引用是程序塊級局部變量a couta,; /此處引用的是程序塊級局部變量a a=3; /此處引用的a是函數(shù)級局部變量a couta,; /此處引用的a是函數(shù)級局

33、部變量a coutfun()endl;int fun() return a; /全局變量a 重名變量作用域規(guī)那么:在某個作用域范圍內定義的變量,在該范圍的子范圍內可以定義重名變量,這時原定義的變量在子范圍內是不可見的,但是它還存在,只是在子范圍內由于出現(xiàn)了重名的變量而被暫時隱藏起來,過了子范圍后,它又是可見的。3.6.2 變量的生存期較難變量存儲期(生命期) :變量(值)在內存中存在的時間。動態(tài)存儲區(qū)(堆棧)靜態(tài)(全局)存儲區(qū)寄存器(CPU中)數(shù)據(jù)存儲區(qū)變量存儲區(qū)1短生存期變量動態(tài)存儲方式2長生存期變量靜態(tài)存儲方式變量存儲期長短 由變量的 存儲方式 決定。動態(tài)存儲方式:在程序運行期間動態(tài)地分配

34、存儲空間給變量的方式。 包括:函數(shù)的形參,函數(shù)或程序塊中定義的局部變量未用static聲明。 具體有兩種:自動變量、存放器類變量。靜態(tài)存儲方式:在程序運行期間分配固定的存儲空間給變量的方式。 存儲位置:靜態(tài)(全局)存儲區(qū),生存期:為程序運行期間。包括:全局變量含外部變量、靜態(tài)全局變量、靜態(tài)局部變量。存儲位置:在動態(tài)存儲空間堆或棧或存放器中。存儲期:為函數(shù)或程序塊的運行期間。 存儲位置:在動態(tài)數(shù)據(jù)存儲區(qū);生存期:函數(shù) 或 程序塊 執(zhí)行期間;作用域:其所在函數(shù)或程序塊。用關鍵字auto作為存儲類別的聲明。例如:int fun() auto int a; /a為自動類變量 關鍵字“auto可以省略。

35、上述自動變量也可聲明為 int a;(1)自動變量:函數(shù)中的局部變量默認是自動變量。(2)存放器變量:局部變量。存儲位置:在CPU的通用存放器中;生存期: 作用域:特點:訪問效率高,數(shù)量較少;用關鍵字register作為存儲類別的聲明。例如:void main() register int i; 1存放器變量不宜定義過多。計算機中存放器數(shù)量是有限的,不能允許所有的變量都為存放器變量。如果存放器變量過多或通用存放器被其他數(shù)據(jù)使用,那么系統(tǒng)將自動把存放器變量轉換成自動變量。2存放器變量的數(shù)據(jù)長度與通用存放器的長度相當。一般是char型和int型變量。 存放器變量 的使用應注意以下問題:2長生存期變

36、量靜態(tài)存儲方式全局變量含外部變量、靜態(tài)全局變量和 靜態(tài)局部變量。1外部變量:未用static關鍵字定義的全局變量。如果不對外部變量另加聲明,那么它的作用域是從定義點到所在文件的末尾。用extern關鍵詞加以聲明后將外部變量作用域擴展到聲明位置,聲明語句格式為extern 類型符 外部變量名; /int 類型符可省 改具體方式: 提前引用聲明。擴展 外部變量 作用域 的方式【例3.14】 對定義在同一文件中外部變量,作提前引用聲明 可以擴展其使用范圍到文件前面的 聲明 位置。#include void main() x=4; coutxendl;int x; /外部變量x的定義 extern i

37、nt x; /提前引用聲明 跨文件引用聲明。 擴展 外部變量 作用域 的方式【例3.15 】對定義在另一文件中的外部變量,作跨文件引用聲明以擴展其作用域到 本文件。文件 的內容:#include void main() coutwendl; /使用文件中定義的變量w 文件 的內容:int w=10; / 外部變量 w 的定義程序運行結果如下:10 extern int w; / 跨文件引用聲明用途:用于多個文件中的函數(shù)共享數(shù)據(jù)! 兩個文件中不能出現(xiàn) 同名的外部變量! 2靜態(tài)變量:靜態(tài)全局變量、靜態(tài)局部變量 靜態(tài)全局變量:在定義全局變量時開頭再添加一個static關鍵字所定義的全局變量。作用域:

38、定義點至定義所在文件的末尾;可以通過提前引用聲明擴展其作用域;不能通過跨文件引用聲明擴展其作用域只對本文件有效。一個文件中定義的靜態(tài)全局變量與別的文件中定義的同名靜態(tài)全局變量或同名外部變量沒有牽連,互不影響!默認初值:0。【例3.17】 靜態(tài)全局變量 的演示。文件的內容:#include static int u=10; /定義靜態(tài)全局變量 void fun() coutThis is file1 文件的內容:#include extern int u; / 試圖對u 作跨文件引用聲明,此時行不通void main() coutuendl; /出現(xiàn)“變量u未定義錯誤2靜態(tài)變量:靜態(tài)全局變量、靜

39、態(tài)局部變量 靜態(tài)局部變量:在定義局部變量時開頭再添加一個static關鍵字所定義的局部變量。生命周期:作用域:默認初值:0?!纠?.16】使用靜態(tài)局部變量的例子。#include void fun();void main() int i; for(i=0;i3;i+) fun( ); void fun() int a=0; /定義局部變量 static int b=0; /定義靜態(tài)局部變量 a=a+1; b=b+1; couta,bendl;程序運行結果如下:1,11,21,3 變量屬性 總結根據(jù)需要設置變量的屬性!3.6.3 內部函數(shù) 和 外部函數(shù) 選講 存儲屬性作用域 分別 類似 靜態(tài)全局

40、變量、外部變量1 內部函數(shù) 存儲屬性 類似靜態(tài)全局變量如果一個函數(shù)只能被 本文件 中 其他函數(shù)所調用,它稱為內部函數(shù)。在定義內部函數(shù)時,在函數(shù)名和函數(shù)類型的前面加static。函數(shù)首部的一般格式為static 類型標識符 函數(shù)名(形參表)如static int fun(int a,int b)內部函數(shù)又稱 靜態(tài)(static)函數(shù)。使用內部函數(shù),可以使函數(shù)只局限于所在文件。不同文件中的同名內部函數(shù)互不干擾?!纠?.18】 靜態(tài)函數(shù)的例子。文件 中的內容:#include static void fun( ); void main( ) fun( ); static void fun( ) /文

41、件file1中定義靜態(tài)函數(shù),名稱為fun coutthis in file1 endl; 文件 中的內容:#include static void fun() /文件file2中定義靜態(tài)函數(shù),名稱也為fun coutthis in file2 endl; 程序運行結果如下: this in file1 2 外部函數(shù)存儲屬性 類似外部變量外部函數(shù)是可以被 整個程序 各文件中函數(shù) 調用的函數(shù)。1外部函數(shù)的定義。在函數(shù)類型前加存儲類型關鍵字extern,或缺省存儲類型關鍵字,定義格式如下:extern 函數(shù)類型 函數(shù)名(參數(shù)列表) 函數(shù)體 extern可缺省,即系統(tǒng)默認為extern型。2外部函數(shù)的

42、跨文件引用聲明。文件A 在需要調用 文件B 中所定義的外部函數(shù)時,需要在文件A中用關鍵字extern對被調函數(shù)提出聲明,聲明格式如下:extern 函數(shù)類型 函數(shù)名(參數(shù)類型列表)【例3.19】 文件利用別的文件中的外部函數(shù)實現(xiàn)求階乘。文件中的內容:#include using namespace std; void main( ) extern double fac(int); / 聲明其他文件中定義的 外部函數(shù)int n;cout please input a integer to n :n;coutn!=fac(n)endl; 文件中的內容:#include using namespac

43、e std; extern double fac(int m) / 定義fac函數(shù) extern 可以省略 int n; double s; s=1; for(n=1;nradius; length=2*PI*radius; /*引用無參宏名求周長*/ area=PI*radius*radius; /*引用無參宏名求面積*/ cout length area; length=2* *radius;例3.20 輸入圓的半徑,求圓的周長、面積。要求使用無參宏定義圓周率。1可提高源程序的可維護性2可提高源程序的可移植性 3減少源程序中重復書寫字符串的工作量使用宏定義的優(yōu)點說明:1在定義宏時,“宏名

44、和 “字符串 之間要用空格分開。而“字符串中的內容不要有空格。2宏名通常用大寫字母定義。3宏定義是在編譯前對宏進展替換的,但對程序中用雙引號括起來的字符串內容,如果其中有與 宏名 一樣的局部,是 不進展 文本替換的。例如:#include #define PI void main( ) coutPI=PIendl; 程序運行結果如下:PI= 3.14159 4宏定義后,可以在本文件各個函數(shù)中使用。也可以使用#undef取消宏的定義。5宏定義可以嵌套,已被定義的宏可以用來定義新的宏。例如:#include #define M 3 #define N M+2 /用已定義的宏M來定義新的宏N#def

45、ine L 4*N +6 /用已定義的宏N來定義新的宏Lvoid main( ) coutLendl; 程序運行結果如下:20 與 常變量 的區(qū)別 const double 2 . 有參數(shù)宏定義 帶參數(shù)宏定義的一般格式 #define 宏名(形參表) 字符串 宏展開:不只是簡單地將宏名用字符串替換,還要進展參數(shù)替換。 #define PI#define S(r) PI*r*rmain()float a,area; a=3.6; area=S(a); coutaarea;area=PI*a*aarea= 3.1415926*a*a1定義有參宏時,宏名與左圓括號之間不能留有空格。否那么,編譯系統(tǒng)將空格以后的所有字符均作為替代字符串,而將該宏視為無參宏。2有參宏的展開,只是將宏名和參數(shù)進展字符串替換。為了保證宏的展開結果正確,在定義有參宏時,在所有 形參外 和 整個字符串 外,均加一對圓括號。 area=S(a+5);預期的替換 的結果:area= 3.1415926*(a+5)*(a+5)宏展開 (字符串替換) 的實際結果:area= 3.1415926*a+5*a+5d=1/S(a+5);預期的替換 的結果:d= 1/

溫馨提示

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

評論

0/150

提交評論