![C語言程序設計教程第6章.ppt_第1頁](http://file.renrendoc.com/FileRoot1/2019-1/13/1d9b7669-ab7a-48fe-aefb-a96283273b91/1d9b7669-ab7a-48fe-aefb-a96283273b911.gif)
![C語言程序設計教程第6章.ppt_第2頁](http://file.renrendoc.com/FileRoot1/2019-1/13/1d9b7669-ab7a-48fe-aefb-a96283273b91/1d9b7669-ab7a-48fe-aefb-a96283273b912.gif)
![C語言程序設計教程第6章.ppt_第3頁](http://file.renrendoc.com/FileRoot1/2019-1/13/1d9b7669-ab7a-48fe-aefb-a96283273b91/1d9b7669-ab7a-48fe-aefb-a96283273b913.gif)
![C語言程序設計教程第6章.ppt_第4頁](http://file.renrendoc.com/FileRoot1/2019-1/13/1d9b7669-ab7a-48fe-aefb-a96283273b91/1d9b7669-ab7a-48fe-aefb-a96283273b914.gif)
![C語言程序設計教程第6章.ppt_第5頁](http://file.renrendoc.com/FileRoot1/2019-1/13/1d9b7669-ab7a-48fe-aefb-a96283273b91/1d9b7669-ab7a-48fe-aefb-a96283273b915.gif)
已閱讀5頁,還剩84頁未讀, 繼續(xù)免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第六章 函數(shù)與編譯預處理,6.1 模塊化程序設計與函數(shù) 6.2 函數(shù)的定義與調用 6.3 函數(shù)的遞歸調用 6.4 變量的作用域與存取方式 6.5 編譯預處理,C語言程序設計教程,2,6.1模塊化程序設計與函數(shù),在設計較復雜的程序時,我們一般采用的方法是:把問題分成幾個部分,每部分又可分成更細的若干小部分,逐步細化,直至分解成很容易求解的小問題。這樣的話,原來問題的解就可以用這些小問題來表示。,2019/7/11,3,基本概念,4,模塊與函數(shù),C語言程序由基本語句和函數(shù)組成,每個函數(shù)可完成相對獨立的任務,依一定的規(guī)則調用這些函數(shù),就組成了解決某個特定問題的程序。,5,模塊與函數(shù),把大任務分解成若干功能模塊, 用多個函數(shù)來實現(xiàn)這些功能模塊。 通過函數(shù)的調用來實現(xiàn)完成大任務的全部功能。,6,模塊與函數(shù),任務、模塊與函數(shù)的關系:一個大任務分成多個功能模塊, 功能模塊則由一個或多函數(shù)實現(xiàn)。 模塊化的程序設計是靠設計函數(shù)和調用函數(shù)實現(xiàn)的。,7,例:分數(shù)排序,任務:輸入三個分數(shù),從大到小的順序的輸出。如果 大于等于85,在該數(shù)后面輸出A,小于85且 大于等于70,則輸出B,小于70且大于等于 60,輸出C,如果小于60,則輸出D。,思路:scanf()輸入分數(shù) 另建一個排序函數(shù) 判斷并輸出等級函數(shù) 打印分數(shù)及等級的函數(shù),雖然也可以由一個主函數(shù)來完成,但這樣做可讀性及操作性會更好。,8,void main() float a,b,c; scanf(“%f,%f,%f“, /* 輸出a,b,c三個數(shù) */ ,9,void sortabc(a,b,c) float a,b,c; float t; if (ab) t=a;a=b;b=t; /* 交換a,和b 的值 */ if (bc) t=b;b=c;c=t; /* 交換b,和c 的值 */ if (ab) t=a;a=b;b=t; /* 交換a,和b 的值 */ ,char grade(x) /*根據(jù)x的值,得到等級標準*/ float x; if (x=85) return(A); else if (x=70) return(B); else if (x=60) return (C); else return (D); ,11,void putabc(a,b,c) float a,b,c; char g; 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); ,12,模塊設計的原則,模塊獨立,規(guī)模適當,層次分明,功能專一,13,獨立性原則表現(xiàn)在模塊完成獨立的功能,和其它模塊間的關系簡單,各模塊可以單獨調試。修改某一模塊,不會造成整個程序的混亂。,每個模塊完成一個相對獨立的特定子功能。在對任務逐步分解時,要注意對問題的綜合。例如, 一些模塊的相似的子任務,可以把它們綜合起來考慮,找出它們的共性,把它們做成一個完成特定任務的單獨模塊。,每個模塊有特定功能,模塊獨立,14,15,16,模塊不能太大,但也不能太小。模塊的功能復雜,可讀性就不好,而且也違背獨立性原則。但如果做得太小,實際上也會復雜各個模塊間反復調用,可讀性也會降低。這點需要慢慢積累經驗,好好把握。,模塊規(guī)模適當,17,分解模塊要注意層次,要多層次的分解任務,要注意對問題進行抽象化。開始不要過于注意細節(jié),注意做到逐步細化求精。,18,算 法 簡 介,算 法 簡 介,算 法 簡 介,什么是算法?,通俗地說,算法是解決一類特定問題的方法和步驟。,算法是一個有限操作的序列。,算法的每一步都是確定的。,算法的每一步計算機都能操作。,有一個或多個的輸入或輸出。,19,算法的描述,算法描述的任務是將解題步驟和方法用一定的形式表示出來,要清楚、準確、嚴謹,還要可讀性好,方便實現(xiàn)。 算法兩大要素: 一是操作,用類計算機語句或自然語言描述。 二是控制結構,描述算法一般可以用流程圖描述。,20,例6.2 設計算法:找出a,b兩數(shù)中的較大者,并輸出,分析: 這個問題分三個步驟: 輸入兩個數(shù); 找出其中的大數(shù); 輸出大數(shù)。,2019/7/11,21,開始,輸入a,b,ab,交換a,b,輸出a,結束,非0,0,圖6.3 找出a,b兩數(shù)中的較大者算法流程圖,22,6.2 函數(shù)的定義與調用,在C語言中,函數(shù)(Function)是一個處理過程,可以進行數(shù)值運算、信息處理、控制決策,即一段程序的工作放在函數(shù)中進行,函數(shù)結束時可以攜帶或不帶處理結果。 庫函數(shù)(標準函數(shù)):系統(tǒng)提供 自定義函數(shù):用戶自己寫,23,C語言程序處理過程全部都是以函數(shù)形式出現(xiàn),最簡單的程序至少也有一個main函數(shù)。函數(shù)必須先定義和聲明后才能調用。,24,標準庫函數(shù),C語言有豐富的庫函數(shù),這些函數(shù)的說明在不同的頭文件(*.h)中。,想要調用標準的庫函數(shù),就必須include。,#include main() printf(“%d”,1024*768); ,25,自定義函數(shù),可以把完成一個任務的過程寫成函數(shù)。,int A_to_a(int capital) int small; if (capital=A ,26,“函數(shù)”的主要知識點,函數(shù)的定義 函數(shù)的參數(shù)和返回值 函數(shù)的調用 嵌套和遞歸 變量的作用域,27,函數(shù)舉例,#include main() int a,b,m; /*說明變量*/ int max(int a,int b); /*函數(shù)聲明*/ scanf(“%d,%d“, /*調用庫函數(shù)getch*/ ,28,函數(shù)舉例,int max(int a,int b) /*定義函數(shù)max*/ int y; y=(ab)? a:b; /*條件表達式 */ return y; ,29,自定義函數(shù)的聲明,自定義函數(shù)在調用前應先聲明。使系統(tǒng)知道將要用到某個函數(shù)及它的類型,以便處理。函數(shù)聲明應與該函數(shù)定義時給出的函數(shù)類型與名字、形參的個數(shù)、類型、次序相一致。,30,求1!+2!+3!+10!,算法 i =1; s=0; 當 i = 10 s=s+ i! 定義求 i! 的函數(shù),31,求1!+2!+3!+10! 程序,void main() long mm( int ); /*自定義求階乘函數(shù)應先聲明 */ int i; long s=0; for (i =1; i =10; i +) s+= mm(i ); /*調用求階乘函數(shù),求i的階乘 */ printf(“n%ld”,s); ,32,定義求 n! 的函數(shù),long mm( int n) long t=1; int i; for (i =1; i =n; i +) t *= i ; return t ; ,33,函數(shù)的參數(shù),int max(int a,int b) int y; y=(ab)? a:b; return y; ,調用時: m=max(3,6); m=max(a,b);,34,形式參數(shù)與實際參數(shù)的關系,形式參數(shù)在函數(shù)中是變量名, 在函數(shù)調用時,形參被分配相應的內存 實際參數(shù)是表達式 負責向對應的形參標識的內存單元傳遞數(shù)據(jù) 實參與形參必須個數(shù)相同 對應的形參和實參的類型必須一致 實參給形參傳遞值得時候,按順序傳遞,與形參名無關。所以實參與形參可以不同名。,35,實參與形參,例:主調函數(shù)中有如下語句: scanf(“%d,%d“, 如果輸入 6,2 函數(shù) int max(int a,int b) 形參 a 得到第一個實際參數(shù)a的值 6 形參 b 得到第二個實際參數(shù)b+3的值 5,36,函數(shù)返回值,函數(shù)返回值通過return語句獲得 函數(shù)返回值的類型就是函數(shù)的類型 return y; 將變量y的值返回給調用者 return y+3; 將表達式的值返回給調用者,37,return 的數(shù)據(jù)類型與函數(shù)的類型矛盾時,自動將數(shù)據(jù)轉換成函數(shù)的類型,int funct1() char ch; while (ch=getch( )z) ; return ch; 調用: i=funct1(); /* 返回的是int類型 */,38,函數(shù)沒有返回值, 函數(shù)定義成空類型,void putline() int i; for (i=0;i35;i+) printf(“-“); printf(“n“); ,函數(shù)的功能就是輸出35個- 調用: putline( ); 應該的語句形式 i=putline( ); 是錯的,39,調用函數(shù),a=function(x,y); 或者 function(x,y);,取返回值 只是操作,解決更復雜問題時可以嵌套調用。,long fac(int k) long f=1; int i; for(i=1;i=k;i+) f=f*i; return f; long combination(int n ,int m) long c; int i; c=fac(m)/(fac(n)*fac(m-n) ); return c; 主函數(shù): main( ) int n,m; long c; scanf(“%d,%d”, ,理論上可以a(b(d(e(x),c(f) 般嵌套無數(shù)層。,40,6.3 函數(shù)的遞歸調用,函數(shù)調用它本身,稱為遞歸。直接在函數(shù)內調用自己為直接遞歸,通過別的函數(shù)調用自己為間接遞歸。,void a( ) a( ); ,void a( ) b( ); void b( ) a( ); ,遞歸在解決某些問題中,是一個十分有用的方法。因為其一,有的問題它本身就是遞歸定義的;其二,它可以使某些看起來不易解決的問題變得容易解決,寫出的程序較簡短。,41,遞歸方法求n!,由于 n!= n*(n-1)! 是遞歸定義 所以求n! (n-1)! (n-1)! (n-2)! (n 2)! (n-3)! 0!的問題, 根據(jù)公式有0!=1。 再反過來依次求出1!,2!直到最后求出n!。,42,遞歸方法求n!,long fac( int n) long f; if (n=0) f=1; else f=n* fac(n-1); return f; main( ) long y; int n; scanf(“%d”, ,剛開始的時候,這個n是前面 輸入的需要階乘的n,所以在這里帶入的值是n,而這個函數(shù)里又調用 了本身,不過參數(shù)已經 變成了n-1,所以這里再次調用時 參數(shù)已經變成了n-1 注意:上次調用fac(n) 還沒有完,只是由于遇到 了fac(n-1)而執(zhí)行fac(n-1) 去了.,而在調用fac(n-1)時同樣 遇到了要調用fac(n-2)的 問題,于是一層一層的 包裹下去,每次調用的 時候都會在內部調用一 個結構相同但變量不同 的函數(shù),直到。,直到調用到fac(0)時, 由于內部if判斷,已經 不需要再繼續(xù)調用另一 個fac(n-1),而直接有了f=1,fac(0)已經執(zhí)行完畢,它的 返回值被fac(1)中的f=n*fac(n-1) 語句賦給了f值,同時返回了f。 而這個返回的f又被fac(2)乘上 當前的n值以后繼續(xù)返回f,直到最后的fac(n)都做完了, f的值被返回到了它的調用點: 主函數(shù)中,這樣就是一個遞歸 運算。,43,斐波那契,1170年生于意大利的比薩,在北非的布吉亞,即今阿爾及利亞的貝加亞長大并且接受教育。大約在1200年,他才重新回到比薩。斐波那契無疑在啟蒙教育時期就受到過阿拉伯數(shù)學家的影響或者接受過他們的輔導。他寫過大量的數(shù)學論文,取得了一些重大的數(shù)學發(fā)現(xiàn)。這使他的著作在意大利非常流行,并且引發(fā)了當時羅馬帝國皇帝弗雷德里克二世的注意,他曾邀請斐波那契到他在比薩宮廷覲見。斐波那契于1250年去世。,遞歸舉例:斐波那契 數(shù)列,44,1202年,他在所著的算珠原理中,提出了一個著名而有趣的兔子問題:假定一對小兔子經過一個月后能夠長成一對大兔子,而一對大兔子經過一個月后能夠生了一對小兔子?,F(xiàn)在我們從一對小兔子開始,用 表示第 個月兔子的總對數(shù),顯然, (第1個月只有一對小兔子,第2個月只有一對大兔子), (第3個月一對大兔子生出一對小兔子,總共兩對兔子。于是我們得到一個數(shù)列:1,1,2,3,5,8,13, 仔細觀察這個數(shù)列,從第3項起每一項都是它前相鄰兩項的和,這就是著名的斐波那契數(shù)列,45,問題: 第1個月有1對兔子 過2個月,兔子就可每個月生1對兔子 問第n個月有多少對兔子? 分析: 設第n個月有f(n)對兔子 根據(jù)題意有 f(0)=0, f(1)=1 f(n)= f(n-1) + f(n-2) f(n-1): 前一個月的兔子數(shù) f(n-2): 前2個月的兔子數(shù),46,定義函數(shù)f(n),long f(int n ) switch (n ) case 0: return 0; break ; case 1: return 1; break ; default: return f(n-1) + f(n-2); /*調用函數(shù)f(n) */ ,47,兔子問題主函數(shù),void main() long f(int n ); /*自定義函數(shù)聲明 */ int n; printf(“n input n:”); scanf(“%d”, /*調用函數(shù)f(n) */ ,48,斐波那契數(shù)列有一系列奇妙的性質,現(xiàn)簡列以下幾條,供大家欣賞 1從首項開始,我們依次計算每一項與它的后一項的比值,并精確到小數(shù)是第四位。如果將這一工作不斷地繼續(xù)下去,這個比值將無限趨近于某一個常數(shù),這個常數(shù)位于1.618 0與1.618 1之間,它能準確地用黃金數(shù)表示出黃金分割率。 2在自然界中,斐波那契數(shù)列也常見到,比如:向日葵花冠上的螺旋,如果前一道螺旋直徑為21的話,下一道螺旋直徑則為34,依次形成連續(xù)的斐波那契數(shù)字;松果的外弧為順時針或逆時針方向的螺旋,其相同間隔之間螺旋的直徑也能構成斐波那契數(shù)列;在上等的鸚鵡螺身上,每圈羅紋的直徑與相鄰羅紋直徑之比亦是1:1.618;菠蘿是又一種可以檢驗斐波那契數(shù)的植物;菠蘿表皮方塊形鱗苞形成兩組旋向相反的螺線,它們的條數(shù)必須是這個級數(shù)中緊鄰的兩個數(shù)字(如左旋8行,右旋13行)。,49,3有一種兩人游戲,名叫“尼姆”。游戲方法是由兩個人輪流取一堆粒數(shù)不限的砂子。先取的一方可以取任意粒,但不能把這堆砂子全部取走。后取的一方,取數(shù)也多少不拘,但最多不能超過對方所取砂子數(shù)的一倍。然后又輪到先取的一方來取,但也不能超過對方最后一次所取砂子的一倍。這樣交替地進行下去,直到全部砂子被取光為止,誰能拿到最后一粒砂子,誰就算勝利者。在這個游戲中,若所有砂子的粒數(shù)是個斐波那契數(shù)的話,那么后取的一方穩(wěn)操勝券,但所有的砂子不是一個斐波那契數(shù)的話,那么先取的一方穩(wěn)勝。,50,輾轉相除法求最大公約數(shù),求 m和 n 的公約數(shù)算法 if (m % n) = 0 n 是公約數(shù); else 求 n 和 m % n 的公約數(shù);,51,用歐幾里德算法(輾轉相除法)求兩個數(shù)的最大公約數(shù)的步驟如下: 若 r 是 a b 的余數(shù), 則 gcd(a,b) = gcd(b,r),52,求最大公約數(shù)的遞歸算法,int gcd(int m, int n) if (m % n) = 0 return n ; else return gcd(n, m % n); ,53,求最大公約數(shù)的主函數(shù),void main() int m,n,t; int gcd(int m, int n); scanf(“%d %d”, ,54,漢諾塔(又稱河內塔)問題是印度的一個古老 的傳說。開天辟地的神勃拉瑪在一個廟里留下了 三根金剛石的棒,第一根上面套著64個圓的金片, 最大的一個在底下,其余一個比一個小,依次疊 上去,廟里的眾僧不倦地把它們一個個地從這根 棒搬到另一根棒上,規(guī)定可利用中間的一根棒作 為幫助,但每次只能搬一個,而且大的不能放在 小的上面。面對龐大的數(shù)字(移動圓片的次數(shù))18446744073709551615,看來,眾僧們 耗盡畢生精力也不可能完成金片的移動。,漢諾塔,55,后來,這個傳說就演變?yōu)闈h諾塔游戲: 1.有三根桿子A,B,C。A桿上有若干碟子。 2.每次移動一塊碟子,小的只能疊在大的上面。 3.把所有碟子從A桿全部移到C桿上。 經過研究發(fā)現(xiàn),漢諾塔的破解很簡單,就是按照移動規(guī)則向一個方向移動金片,如3階漢諾塔的移動:AC,AB,CB,AC,BA,BC,AC 此外,漢諾塔問題也是程序設計中的經典遞歸問題。 算法思路: 1.如果只有一個金片,則把該金片從源移動到目標棒,結束。 2.如果有n個金片,則把前n-1個金片移動到輔助的棒,然后把第n個金片移動到目標棒,最后再把前n-1個移動到目標棒,56,漢諾塔是一個很繁雜的游戲,但用遞歸的方法解決起來異常簡單。,規(guī)則:(1) 一次只能移動一個 (2) 大的不能放在小的上面 (3) 只能在三個位置中移動,57,問題可分為三個步驟,對于把n個金片從第一根針a上移到第三根針c的問題可以分解成如下步驟: (1)將n-1個金片從a經過c 移動到b。 (2)將第n個金片移動到c。 (3)再將n-1個盤子從b經過a移動到c。,這樣我們就將移動n個金片的問題變成了移動n-1個金片的問題。這樣做下去的話最后就會變成移動一個金片的問題。,58,遞歸方法解漢諾塔,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,59,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,60,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,主函數(shù)調用hanoi(n,1,2,3); 第一次調用。 第一次調用hanoi(n,a,b,c) (第一層) 即要把三個金片移到c,n=3,61,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,由于n1則執(zhí)行hanoi(n-1,a,c,b) (第二次調用),n=3,62,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,由于仍然n1則執(zhí)行 hanoi(n-1,a,c,b) (第三次調用),n=2,63,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,由于n=1則printf(“%d -%d”,a,c); 即把金片從a移動到c,n=1,64,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,第三層執(zhí)行完畢,返回到第二層,即下去執(zhí)行printf(“%d-%d”,a,c); 把第二個金片擺到第二根針上,n=2,65,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,執(zhí)行下一條語句,又調用第三層hanoi(1,3,1,2),n=2,66,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,n=1, 執(zhí)行結果為32,n=1,67,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,第二層也執(zhí)行完了,返回第一層,執(zhí)行接下來的語句,結果為13。,n=3,68,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,執(zhí)行接下來的語句,再次調用 第二層hanoi(2,2,1,3),n=3,69,遞歸漢諾塔步驟,void hanoi(int n, int a, int b, int c) 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( ) int n; printf(“input n:”); scanf(“%d”, ,2019/7/11,70,6.4 變量的作用域與存儲方式,先看一個例子,錯在那里?: void f1( ) int t=2; a *= t; b /= t; main() int a, b; printf(“ Enter a,b:”); scanf(“%d,%d”, ,編譯程序會提示出錯: Undefined symbol a 和 Undefined symbol b 。為什么?,2019/7/11,71,一.變量的作用域 即變量的有效范圍 1.變量按作用域分為全局變量和局部變量 2.比較: 全局變量(外部變量) 局部變量(內部變量) 定義位置: 函數(shù)體外 函數(shù)體內 作用域 : 從定義處到本源 從定義處到本函數(shù)結束 文件結束 舉例 : 所有函數(shù)體外定義的變量 (1)所有在函數(shù)體內定義 (2)形式參數(shù),注意與局部變量同名的處理 局部變量屏蔽全局變量,不同函數(shù)中同名局部變量互不干擾,2019/7/11,72,#include int a,b; /*a,b為全局變量*/ void f1(int x ) int t1,t2,a; a=t1 = x* 4; t2 = b * 3; b = 10; printf (“f1:t1=%d,t2=%d,a=%d,b=%dn”, t1,t2,a,b); main( ) a=2; b=4; /* 此a,b是全局變量,賦值 */ f1( a); /* 調用函數(shù)f1( ) */ printf (“main: a=%d,b=%d”, a, b); 程序輸出結果為:,f1:t1=8,t2=12,a=8,b=10 main:a=2,b=10,2019/7/11,73,若將程序改為: #include int a=2,b=4; /*a,b為全局變量*/ void f1( ) int t1,t2; t1 = a * 2; t2 = b * 3; b = 100; printf (“t1=%d,t2=%d,b=%dn”, t1, t2,b); main() int b=4; /* 此b是局部變量,賦值 */ f1( ); /* 調用函數(shù)f1( ) */ printf (“a=%d,b=%d”, a, b); ,結論:全局變量與局部變量同名時,局部變量 起作用,全局變量被屏蔽(不影響),應小 心使用,程序輸出結果為: t1=4,t2=12,b=100 a=2,b=4,2019/7/11,74,二.變量的存儲特性 1.變量按存在時間分 靜態(tài)變量 動態(tài)變量,靜態(tài)存儲類型的變量的生存期為程序執(zhí)行的整個過程,在該過程中占有固定的存儲空間,通常稱它們?yōu)橛谰么鎯Α?動態(tài)存儲類型變量只生存在某一段時間內。例如,函數(shù)的形參和函數(shù)體或分程序中定義的變量, 只是在程序進入該函數(shù)或分程序時才分配存儲空間, 當該函數(shù)或分程序執(zhí)行完后,變量對應的存儲空間又被撤銷了。 2.c語言中每一個變量有兩個屬性:數(shù)據(jù)類型,存儲特性 完整的變量定義: 存儲特性 數(shù)據(jù)類型 變量名;,2019/7/11,75,3.變量的存儲特性 自動型 auto 靜態(tài)型 static 寄存器型 register 外部型 extern (1) auto型 每次進入程序是自動分配內存,不長期占用內存例如:形式參數(shù),自動型局部變量 (2)static 型 局部靜態(tài)變量 全局靜態(tài)變量 長期占用內存,2019/7/11,76,例1:分析執(zhí)行結果 f(int a) int b=0; static int c=3; b+;c+; printf(“%5d%5d%5d”,a,b,c); return(a+b+c); main() int a=2,k; for(k=0;k3;k+) printf(“%5dn”,f(a); ,靜態(tài)變量只初始化一次。再次調用定義它的函數(shù)時變量保存了前一次被調用后留下的值。,結果: 2 1 4 (a,b,c) 7 (f(a) 2 1 5 8 2 1 6 9,2019/7/11,77,(3) register型 使用頻率高的變量定義為register型, 可以提高運行速度. 數(shù)據(jù) 內存 運算器 運算器 結果 控制器 數(shù)據(jù),寄存器,寄存器變量只限于整型、字符型、指針型的局部變量。 寄存器變量是動態(tài)變量,而且數(shù)目有限, 一般僅允許說明兩個寄存 器變量。 例如: register int d; register char c;,2019/7/11,78,(4)extern型 引用: extern 類型 變量名; 如果某個模塊文件中要用到另一個模塊 文件中的全局變量,就要用extern說明 例如:程序模塊file1.c中定義了全局變量 int s ; 而在另一個程序模塊file2.c中的函數(shù)fun1( )中需要使用這個變量s,為此,可以在file2.c的函數(shù)fun1( )中加上外部變量說明語句: fun1( ) extern int s;/*表明變量s是在其他文件定義的*/ . 定義時分配內存,其他文件引用時不再分配內存.,2019/7/11,79,6.5編譯預處理,“編譯預處理”是C語言編譯系統(tǒng)的 一個組成部分。是在編譯前由編譯系統(tǒng)中的預處理程序對源程序的預處理命令進行加工。,源程序中的預處理命令均以“#”開頭,結束不加分號,以區(qū)別源程序中的語句,它們可以寫在程序中的任何位置,作用域是自出現(xiàn)點到源程序的末尾。 預處理命令包括執(zhí)行宏定義(宏替換)、包含文件和條件編譯。,2019/7/11,80,一.宏定義 簡單宏定義 1.一般形式為: #define 宏名 串 (宏體) 如: #define PI 3.14159 /*定義后,可以用PI來代替串3.14159*/ 2.宏定義的作用 在宏定義之后, 該程序中宏名就代表了該字符串。 3.說明 可以用 #undef命令終止宏定義的作用域。例如:#undef PI 宏定義的嵌套使用 # define R 3.0 # define PI 3.1415926 # define L 2*PI*R /*宏體是表達式*/ # define S PI*R*R,2019/7/11,81,main ( ) printf (L=%fnS=%fn,L,S); /*2*PI*R替換L, PI*R*R替換S */ 程序運行結果如下: L=18.8
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年立式紅外線治療燈項目投資可行性研究分析報告-20241226-190706
- 廣西師范大學《模式識別》2023-2024學年第二學期期末試卷
- 青島城市學院《電氣制圖與CAD》2023-2024學年第二學期期末試卷
- 上海海洋大學《幼兒認知與學習》2023-2024學年第二學期期末試卷
- 山東外事職業(yè)大學《企業(yè)經營決策模擬》2023-2024學年第二學期期末試卷
- 2025年新高考藝術生數(shù)學突破講義 專題03 等式與不等式的性質
- 貧困學生申請書
- 常州機電職業(yè)技術學院《建筑與室內發(fā)展史》2023-2024學年第二學期期末試卷
- 黑龍江八一農墾大學《工控網絡與通信》2023-2024學年第二學期期末試卷
- 新疆職業(yè)大學《水產養(yǎng)殖及疾病防治》2023-2024學年第二學期期末試卷
- (完整)PEP人教版小學生英語單詞四年級上冊卡片(可直接打印)
- 面神經疾病課件
- 漢代儒學大師董仲舒思想課件
- 普通沖床設備日常點檢標準作業(yè)指導書
- 科技文獻檢索與利用PPT通用課件
- 《紅樓夢講稿》PPT課件
- DB33∕T 628.1-2021 交通建設工程工程量清單計價規(guī)范 第1部分:公路工程
- 吉祥喜金剛現(xiàn)證中品事業(yè)六支妙嚴(節(jié)錄)
- 國民中小學九年一貫課程綱要語文學習領域(國語文)
- 最全的人教初中數(shù)學常用概念、公式和定理
- 橋面結構現(xiàn)澆部分施工方案
評論
0/150
提交評論