C語言第8章 函數_第1頁
C語言第8章 函數_第2頁
C語言第8章 函數_第3頁
C語言第8章 函數_第4頁
C語言第8章 函數_第5頁
已閱讀5頁,還剩109頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

1、 8.1 8.1 概述概述 8. 8.函數定義的一般形式函數定義的一般形式 8. 8.函數參數和函數的值函數參數和函數的值 8. 8. 函數的調用函數的調用 8. 8. 函數的嵌套調用函數的嵌套調用 8. 8.函數的遞歸調用函數的遞歸調用 8. 8.數組作為函數參數數組作為函數參數 8.8 8.8 局部變量和全局變量局部變量和全局變量 8. 8.變量的存儲類別變量的存儲類別 8.10 8.10 內部函數和外部函數內部函數和外部函數 一個程序可由一個主函數和若干個其他函數構成。一個較大的程序可分為若干個程序模塊,每一個模塊用來實現一個特定的功能。在高級語言中用子程序實現模塊的功能。子程序由函數來

2、完成。 函數間的調用關系:由主函數調用其他函數,其他函數也可以互相調用。同一個函數可以被一個或多個函數調用任意多次。例例8.18.1先舉一個函數調用的簡單例子先舉一個函數調用的簡單例子# include void main() void printstar(); /*對對printstar函數聲明函數聲明*/ void print_message(); /*對對print_message函數聲明函數聲明*/ printstar(); *調用調用printstar函數函數* print_message(); /*調用調用print_message函數函數*/ printstar(); *調用調用

3、printstar函數函數*/ void printstar() *定義定義printstar函數函數* printf(* * * * * * * * * * * * * * * *n);void print_message() *定義定義print_message函數函數* printf(How do you do!n); 運行情況如下:運行情況如下:* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *How do you do!How do you do!* * * * * * * * * * * * * * * *

4、 * * * * * * * * * * * * * * * *說明:說明: (1)一個程序由一個或多個程序模塊組成,每一個程序模塊作為一個源程序文件。對于較大的程序,通常將程序內容分別放在若干個源文件中,再由若干源程序文件組成一個C程序。這樣便于分別編寫、分別編譯,提高調試效率。一個源程序文件可以為多個C程序公用。(2) 一個源程序文件由一個或多個函數以及其他有關內容(如命令行、數據定義等)組成。一個源程序文件是一個編譯單位,在程序編譯時是以源程序文件為單位進行編譯的,而不是以函數為單位進行編譯的。(3) 程序的執行是從main函數開始的,如果在main函數中調用其他函數,在調用后流程返回到

5、main函數,在main函數中結束整個程序的運行。(4)所有函數都是平行的,即在定義函數時是分別進行的,是互相獨立的。一個函數并不從屬于另一函數,即函數不能嵌套定義。函數間可以互相調用,但不能調用main函數。main函數是系統調用的。(5)從用戶使用的角度看,函數有兩種: 標準函數,即庫函數。這是由系統提供的,用戶不必自己定義這些函數,可以直接使用它們。不同的C系統提供的庫函數的數量和功能會有一些不同,但許多基本的函數是共同的。 用戶自己定義的函數。用以解決用戶的專門需要。 (6) 從函數的形式看,函數分兩類: 無參函數。無參函數一般用來執行指定的一組操作。在調用無參函數時,主調函數不向被調

6、用函數傳遞數據。有參函數。主調函數在調用被調用函數時,通過參數向被調用函數傳遞數據。 8.8.函數定義的一般形式函數定義的一般形式8.2.1 8.2.1 無參函數的定義一般形式無參函數的定義一般形式定義無參函數的一般形式為定義無參函數的一般形式為:類型標識符類型標識符函數名函數名()() 聲明部分聲明部分 語句部分語句部分 8.2.2 8.2.2 有參函數定義的一般形式有參函數定義的一般形式定義有參函數的一般形式為定義有參函數的一般形式為:類型標識符類型標識符函數名函數名(形式參數表列)(形式參數表列) 聲明部分聲明部分 語句部分語句部分 例如:例如: (int ,int ) ;/ *函數體中

7、的聲明部分*?; return(); 8.2.3 8.2.3 空函數空函數定義空函數的一般形式為定義空函數的一般形式為:類型標識符類型標識符函數名函數名()() 例如:例如:()() 主調函數調用空函數時,只表明這里要調用一個函數,但函數本身什么工作也不做等,以后擴充函數功能時補充上。 8.8.函數參數和函數的值函數參數和函數的值8.8. .形式參數和實際參數形式參數和實際參數形式參數:函數名后面括號中的變量名稱為“形式參數”(簡稱“形參形參”)。實際參數:主調函數中調用一個函數時,函數名后面括號中的參數(可以是一個表達式)稱為“實際參數”(簡稱“實參實參”)。函數返回值:return后面的括

8、號中的值作為函數帶回的值(稱函數返回值函數返回值)。 主調函數和被調用函數之間有數據傳遞的關系。在不同的函數之間傳遞數據,可以使用的方法有:參數:通過形式參數和實際參數返回值:用return語句返回計算結果全局變量:外部變量例例8.調用函數時的數據傳遞調用函數時的數據傳遞#include void () int max(int ,int ); /* 對函數的聲明 */ int ,; scanf(,); (,); printf( ,); int max(int ,int )*定義有參函數max * int ; ?; return(); 運行情況如下:運行情況如下:, 通過函數調用,可使兩個函數中

9、的數據發生聯系。關于形參與實參的說明:關于形參與實參的說明:(1 1) 在定義函數中指定的形參,在未出現函數調用時,它們并不占內存中的存儲單元。只有在發生函數調用時,函數max中的形參才被分配內存單元。在調用結束后,形參所占的內存單元也被釋放。(2 2) 實參可以是常量、變量或表達式,例如:例如: max(,);但要求它們有確定的值。在調用時將實參的值賦給形參。(3 3)在被定義的函數中,必須指定形參的類型。(4 4)實參與形參的類型應相同或賦值兼容。(5 5)值傳遞:實參向形參的數據傳遞是單向“值傳遞”,只能由實參傳給形參,而不能由形參傳回來給實參。 在調用函數時,給形參分配存儲單元,并將實

10、參對應的值傳遞給形參,調用結束后,形參單元被釋放,實參單元仍保留并維持原值。 8.3.2 8.3.2 函數的返回值函數的返回值 函數的返回值函數的返回值是通過函數調用使主調函數得到的確定值。例如例如: :例8.中,max(,)的值是,max(,)的值是5。賦值語句將這個函數值賦給變量。 說明:說明: (1)函數的返回值是通過函數中的return語句獲得的。 一個函數中可以有一個以上的return語句,執行到哪一個return語句,哪一個語句起作用。return語句后面的括弧也可以不要例如例如: “return ;” 等價于等價于 “return ();();”return后面的值可以是一個表達

11、式。例如例如: (int ,int ) return(?:);); (2)函數的返回值應當屬于某一個確定的類型,在定義函數時指定函數返回值的類型。例如例如:下面是下面是3個函數的首行:個函數的首行:int max(float ,float ) /* 函數值為整型 */char letter(char c1,char c2) /* 函數值為字符型 */ double min(int ,int ) /* 函數值為雙精度型 */ 注意:注意:凡不加類型說明的函數,自動按整型處理。(3)在定義函數時指定的函數類型一般應該和return語句中的表達式類型一致。 如果函數值的類型和return語句中表達式

12、的值不一致,則以函數類型為準。 對數值型數據,可以自動進行類型轉換。即函數類型決定返回值的類型。(4)對于不帶回值的函數,應當用“void”定義函數為“無類型”(或稱“空類型”)。此時在函數體中不得出現return語句。 例例 8.8. 返回值類型與函數類型不同返回值類型與函數類型不同# include void main() int (float ,float ); float ,; int ; scanf(,); (,); printf( ,); int max(float ,float ) float ; /* z為實型變量 */ ? ; return(); 運行情況如下:, Max i

13、s 8.8. 函數的調用函數的調用 8.8.1 .1 函數調用的一般形式函數調用的一般形式函數調用的一般形式為函數調用的一般形式為: : 函數名(實參表列)函數名(實參表列)說明說明: :(1 1)如果是調用無參函數,則“實參表列”可以沒有,但括弧不能省略。(3 3)如果實參表列包括多個實參,對實參求值的順序并不是確定的,有的系統按自左至右順序求實參的值,有的系統則按自右至左順序。(2 2)如果實參表列包含多個實參,則各參數間用逗號隔開。實參與形參的個數應相等,類型應匹配。實參與形參按順序對應,一一傳遞數據。例例 8.4 8.4 實參求值的順序實參求值的順序#include void main

14、() int f(int a,int b); /* 函數聲明 */ int i=2,p; p=f(i,+i); /* 函數調用 */ printf(%dn,p); int f(int a,int b) /* 函數定義 */ int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return(c); 如果按自左至右順序求實如果按自左至右順序求實參的值,則函數調用相當參的值,則函數調用相當于(,)于(,) 如果按自左至右順序求實如果按自左至右順序求實參的值,則函數調用相當參的值,則函數調用相當于(于(3,),) 對于函數調用對于函數調用 int i=2,p

15、;p=f(i,+i); 8.4.2 8.4.2 函數調用的方式函數調用的方式函數語句函數語句把函數調用作為一個語句。這時不要求函數帶回值,只要求函數完成一定的操作。函數表達式函數表達式函數出現在一個表達式中,這種表達式稱為函數表達函數表達式式。這時要求函數帶回一個確定的值以參加表達式的運算。例如:* *(,);(,); 按函數在程序中出現的位置來分,可以有以按函數在程序中出現的位置來分,可以有以下三種函數調用方式:下三種函數調用方式: 函數參數函數參數函數調用作為一個函數的實參。例如例如: : m = max (a , max ( b , c ) ) ;其中max ( b , c )是一次函數

16、調用,它的值作為max另一次調用的實參。m的值是a、b、c三者中的最大者。8.4.3 8.4.3 對被調用函數的聲明和函數原型對被調用函數的聲明和函數原型1.首先被調用的函數必須是已經存在的函數(是庫函數或用戶自己定義的函數)。但光有這一條件還不夠。3.如果使用用戶自己定義的函數,而該函數的位置在調用它的函數(即主調函數)的后面,應該在主調函數中對被調用的函數作聲明。2.如果使用庫函數,還應該在本文件開頭用#include 命令將調用有關庫函數時所需用到的信息“包含”到本文件中來。 函數原型的一般形式為函數原型的一般形式為: :1. 函數類型 函數名(參數類型1,參數類型2);2. 函數類型

17、函數名(參數類型1,參數名1,參數類型2,參數名2); 聲明的作用是把函數名、函數參數的個數和參數類型等信息通知編譯系統,以便在遇到函數調用時,編譯系統能正確識別函數并檢查調用是否合法。注意:注意: 函數的“定義”和“聲明”的區別:l 函數的定義是指對函數功能的確立,包括指定函數名,函數值類型、形參及其類型、函數體等,它是一個完整的、獨立的函數單位。l 函數的聲明的作用則是把函數的名字、函數類型以及形參的類型、個數和順序通知編譯系統,以便在調用該函數時系統按此進行對照檢查。 例例8. 對被調用的函數作聲明對被調用的函數作聲明# include void main() float add(flo

18、at x, float y); *對被調用函數add的聲明* float a,b,c; scanf(f,f,a,b); cadd(a,b); printf(sum is f n,c);float add(float ,float ) *函數首部* float ; /* 函數體 */ z; return(z); 例例8 8 對被調用的函數作聲對被調用的函數作聲明明# include float add(float ,float ) *函數首部* float ; /* 函數體 */ z; return(z); void main() float a,b,c; scanf(f,f,a,b); cad

19、d(a,b); printf(sum is f n,c);8.8. 函數的嵌套調用函數的嵌套調用嵌套定義就是在定義一個函數時,其函數體內又包含另一個函數的完整定義 。例 8. 用弦截法求方程 f(x)=x3-5x2+16x-80=0 的根 1.1. 取兩個不同點x1,x2,如果f(x1)和f(x2)符號相反,則(x1,x2)區間內必有一個根。如果f(x1)與f(x2)同符號,則應改變x1,x2,直到f(x1)、f(x2)異號為止。注意x1、x2的值不應差太大,以保證(x1,x2)區間內只有一個根。 2.2. 連接(x1,f(x1)和(x2,f(x2)兩點,此線(即弦)交x軸于x。方法:方法:3

20、.3. 若f(x)與f(x1)同符號,則根必在(x,x2)區間內,此時將x作為新的x1。如果f(x)與f(x2)同符號,則表示根在(x1,x)區間內,將x作為新的x2。4.4. 重復步驟 (2) 和 (3) , 直到 f(x) 為止, 為一個很小的數, 例如 10-6. 此時認為 f(x)0 。N-S流程圖流程圖 實現各部分功能的幾個函數實現各部分功能的幾個函數:1. 用函數f(x)代表x的函數:x3-5x2+16x-80。2. 用函數調用xpoint (x1,x2)來求(x1,f(x1)和 (x2,f(x2)的連線與x軸的交點x的坐標。3. 用函數調用root (x1,x2)來求(x1,x2

21、)區間的 那個實根。顯然,執行root函數過程中要用到函 數xpoint,而執行xpoint函數過程中要用 到f函數。include include float f(float x) * 定義函數,以實現f(x) x3-5x2+16x-80 * float ; =(-.)*+.)*-.; return(); float xpoint (float x1,float x2) *定義xpoint函數,求出弦與x軸交點 */ float ; =(*()-*() ()-(); return (); float root(float ,float ) /* 定義root函數,求近似根 */float ,

22、; (); do xpoint(,); (); if(*) /*()與()同符號 */ ; ; ; while(fabs()0.0001); return( void main() *主函數 */float ,; do printf( ,:); scanf(,); (); (); while(*); (,); printf( root of equation is .n,); 運行情況如下:input ,:, root of equation is 5.0000 8.6 8.6 函數的遞歸調用函數的遞歸調用 在調用一個函數的過程中又出現直接或間接地調用該函數本身,稱為函數的遞歸調用。語言的特點

23、之一就在于允許函數的遞歸調用。例如:例如: int f ( int ) ,; (); return(*); 例例 8.7:8.7: 有個人坐在一起,問第個人多少歲?他說比第個人大歲。問第個人歲數,他說比第個人大歲。問第個人,又說比第個人大歲。問第個人,說比第個人大歲。最后問第個人,他說是歲。請問第個人多大。 age(5)= age (4)+2age(4)= age (3)+2age(3)= age (2)+2age(2)= age (1)+2age(1)= 10用數學公式表述如下:age(n)= 10 ()age(n-1)+2 ()可以用一個函數來描述上述遞歸過程:可以用一個函數來描述上述遞歸

24、過程:int age(int ) *求年齡的遞歸函數* int ; * 用作存放函數的返回值的變量 * if() ; else (); return();運行結果如下:運行結果如下: 用一個主函數調用age函數,求得第5人的年齡。#include void main() printf(,age(); 例例8.8.用遞歸方法求!用遞歸方法求! 求!也可以用遞歸方法,即!等于!,而!。可用下面的遞歸公式表示: ! (,) ()! ()例例8.9 Hanoi(漢諾塔)問題(漢諾塔)問題:由上面的分析可知:將個盤子從座移到座可以分解為以下3個步驟:1.將上個盤借助座先移到座上。2.把座上剩下的一個盤移

25、到座上。3.將個盤從座借助于座移到座上。程序如下:程序如下:#include void main()void hanoi(int n,char one,char two,char three); /* 對hanoi函數的聲明 */ int m; printf(input the number of diskes:); scanf(“%d”,&m); printf(The step to moveing %d diskes:n,m); hanoi(m,A,B,C); void hanoi(int n,char one,char two,char three) /* 定義hanoi函數,將

26、個盤從one座借助two座,移到three座 */ void move(char x,char y); /* 對move函數的聲明 */ if(n=1) move(one,three); else hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); void move(char x,char y) /* 定義move函數 */ printf(“%c-%cn,x,y); 運行情況如下:運行情況如下:input the number of diskes:3 The steps to noving 3 diskes

27、: 8.8.數組作為函數參數數組作為函數參數8.7.1 8.7.1 數組元素作函數實參數組元素作函數實參 由于實參可以是表達式,而數組元素可以是表達式的組成部分,因此數組元素可以作為函數的實參,與用變量作實參一樣,是單向傳遞,即“值傳送”方式。 例例 8.108.10 有兩個數組和,各有個元素,將它們對應地逐個相比(即與比,與比)。如果數組中的元素大于數組中的相應元素的數目多于b數組中元素大于a數組中相應元素的數目(例如,aibi6次,biai3次,其中i每次為不同的值),則認為a數組大于b數組,并分別統計出兩個數組相應元素大于、等于、小于的次數。 #include void main() i

28、nt large(int x,int y); /* 函數聲明 */ int 10,10,,; printf(enter array a ); for(;) scanf(,); printf(); printf( enter array ); for(;) scanf (,); printf(); for(;) if(large (i,i )= ) ; else if( large (i,i )=) =+; else ;printf(aibi %d timesnai=bi %d timesnaik) printf(array a is larger than array bn); else if

29、 (nk) printf(array a is smaller than array bn); else printf(array is equal to array bn);large(int ,int ) int ; if();else if()flag;else flag; return(flag);運行情況如下:運行情況如下: enter array a: 5 3 8 9 1 3 5 6 0 4 array a is smaller thann array b 8.7.2 8.7.2 數組名作函數參數數組名作函數參數 用數組名作函數參數時,此時形參應當用數組名或用指針變量 。例例8.1

30、1 有一個一維數組score,內放10個學生成績,求平均成績。#include void main() float average(float array10); /* 函數聲明 */ float score10 , aver; int ; printf(input scores:); for(; scanf(,score); printf(); averaverage( score ); printf ( average score is .n, aver);float average (float array10) int ; float aver,; for (;);return(ave

31、r);運行情況如下:運行情況如下:input scores: .5 .5 average score is 83.40 例例 8.8.形參數組不定義長度形參數組不定義長度#include void main() float average(float ,int ) float score_15 , .,; float score_210= 67.5,89.5,99,6.5, 77,89.5,76.5,54,60,99.5; printf(“the average of class A is %6.2fn”, average(score_1,5); printf(“the average of

32、class B is %6.2fn”, average(score_2,10); float average(float ,int ) int ; float aver,; for(; sumsumarray; aversum; return(); 運行結果如下:運行結果如下:the average of class A is 80.40The average of class is 78.20例例 8.13 用選擇法對數組中10個整數按由小到大排序。 所謂選擇法就是先將10個數中最小的數與a0對換;再將a1到a9中最小的數與a1對換每比較一輪,找出一個未經排序的數中最小的一個。共比較9輪。未

33、排序時的情況:a0 a1 a2 a3 a4 3 6 1 9 4 將5個數中最小的數1與a0對換: 1 6 3 9 4 將余下的4個數中最小的數3與a1對換 1 3 6 9 4 將余下的3個數中最小的數4與a2對換 1 3 4 9 6 將余下的2個數中最小的數6與a3對換 1 3 4 6 9 程序:程序:#include void main() void sort(int ,int ); int ,; printf(enter the array); for(; scanf(,); sort(,); printf(the sorted array ); for(; printf(,); prin

34、tf(); void sort(int array,int )/*排序函數*/ int ,; for(;) ; for(;) if(array array=; =arrayk; arrayk=arrayi;arrayi=t 8.7.3. 8.7.3. 多維數組名作函數參數多維數組名作函數參數程序:程序:#include void main() max_value ( int 4); int 34=1,3,5,7,2,4,6,8,15,17,34,12; printf(max value is , max_value(a) ); 用多維數組名作為函數實參和形參。在被調函數中對形參數組定義時可以指

35、定每一維的大小 。max_value ( int array 4) int ,max; max=; for(=;) for(;if(array) max= array ; return(max); 運行結果如下:運行結果如下:Max value is 348.88.8局部變量和全局變量局部變量和全局變量8.8.18.8.1局部變量局部變量內部變量:在一個函數內部定義的變量稱內部變量。它只在本函數范圍內有效,即:只有在本函數內才能使用這些變量,故稱為“局部變量” 。例:float f1( int a) /*函數f1 */int b,c; /* a、b、c有效*/ char f2(int x,in

36、t y) /*函數f2 */int i,j; /* x、y、i、j有效*/ void main( ) /*主函數*/int m,n; /* m、n有效*/ 主函數中定義的變量只在主函數中有效,而不因為在主函數中定義而在整個文件或程序中有效。主函數也不能使用其他函數中定義的變量。(2) 不同函數中可以使用相同名字的變量,它們代表不同的對象,互不干擾。(3) 形式參數也是局部變量。(4) 在一個函數內部,可以在復合語句中定義變量,這些變量只在本復合語句中有效,這種復合語句也稱為“分程序”或“程序塊”。void main ( )int a,b;int c; c=a+b; c在此范圍內有效 a,b在此

37、范圍內有效 外部變量:函數之外定義的變量稱為外部變量。外部變量可以為本文件中其他函數所共用。它的有效范圍為從定義變量的位置開始到本源文件結束。所以也稱全程變量。int p=1,q=5; /* 外部變量 */float f1(int a) /* 定義函數f1 */int b,c;char c1,c2; /* 外部變量*/char f2 (int x, int y) /* 定義函數f2 */int i,j; 全局變量p,q的作用范圍 全局變量c1,c2的作用范圍void main ( ) /*主函數*/int m,n; 例8.15 有一個一維數組,內放個學生成績,寫一個函數,求出平均分、最高分和最

38、低分。#include float Max,Min; *全局變量*void main() float average(float array ,int n); float ave,score10; int ; for(;) scanf(,); ave= average(,); printf(“max=%6.2fnmin=%6.2fn average=%6.2fn“,Max,Min,ave); float average(float array ,int n) * 定義函數,形參為數組 */ int ; float aver,sum=array; Max=Min=array; for(=;) i

39、f(arrayMax)Maxarray; else if(arrayMin)Min array; sum=sum+array; aver; return(); 運行情況如下:運行情況如下: 建議:不必要時不要使用全局變量,原因如下: 全局變量在程序的全部執行過程中都占用存儲單元,而不是僅在需要時才開辟單元。 使用全局變量過多,會降低程序的清晰性。在各個函數執行時都可能改變外部變量的值,程序容易出錯。因此,要限制使用全局變量。降低函數的通用性。因為函數在執行時要依賴于其所在的外部變量。如果將一個函數移到另一個文件中,還要將有關的外部變量及其值一起移過去。但若該外部變量與其他文件的變量同名時,就會

40、出現問題,降低了程序的可靠性和通用性。一般要求把程序中的函數做成一個封閉體,除了可以通過“實參形參”的渠道與外界發生聯系外,沒有其他渠道。例例 8.8.6 6 外部變量與局部變量同名外部變量與局部變量同名#include int a=3,b=5; /* a,b為外部變量*/ a,b作用范圍void main ( ) int a=8; /*a為局部變量 */ 局部變量a作用范圍 printf (%d, max (a,b); 全局變量b的作用范圍 max (int a, int b) /*a,b為局部變量 */ int c; c=ab?a b; 形參a、b作用范圍 return (c); 運行結果

41、為運行結果為 8 8.8. 變量的存儲類別變量的存儲類別 8.9.1 8.9.1 動態存儲方式與靜態存儲方式動態存儲方式與靜態存儲方式 從變量的作用域(即從空間)角度來分,可以分為全局變量和局部變量。從變量值存在的時間角度來分,又可以分為靜態存儲方式和動態存儲方式。靜態存儲方式:指在程序運行期間由系統分配固定的存儲空間的方式。動態存儲方式:則是在程序運行期間根據需要進行動態的分配存儲空間的方式。這個存儲空間可以分為三部分:1.1.程序區程序區 2.2.靜態存儲區靜態存儲區 3.3.動態存儲區動態存儲區 變量和函數有兩個屬性:數據類型數據類型和數據的存儲數據的存儲類別類別。存儲類別指的是數據在內

42、存中存儲的方式。存儲方式分為兩大類:靜態存儲類和動態存儲類。包含:自動的(自動的(auto););靜態的(靜態的(static););寄存器的(寄存器的(register););外部的(外部的(extern)。 根據變量的存儲類別,可以知道變量的作用域和生存期。 8.9.2 auto8.9.2 auto變量變量自動變量auto:不專門聲明為static存儲類別的局部變量都是動態分配存儲空間,在調用該函數時系統會給它們分配存儲空間,在函數調用結束時就自動釋放這些存儲空間。因此這類局部變量稱為自動變量。函數中的形參和在函數中定義的變量(包括在復合語句中定義的變量),都屬此類。自動變量用關鍵字aut

43、o作存儲類別的聲明。例如:例如:int (int ) *定義f函數,為形參 *auto int ,;/*定義、為自動變量 * 8.9.3 8.9.3 用用staticstatic聲明局部變量聲明局部變量 當函數中的局部變量的值在函數調用結束后不消失而保留原值時,該變量稱為靜態局部變量。用關鍵字static進行聲明。例例87 考察靜態局部變量的值#include void main()int (int); int ,; for(; printf( ,(); int (int )auto int ; static ; ; return(); 對靜態局部變量的說明:對靜態局部變量的說明:(1) 靜態

44、局部變量屬于靜態存儲類別,在靜態存儲區內分配存儲單元。在程序整個運行期間都不釋放。而自動變量(即動態局部變量)屬于動態存儲類別,占動態存儲區空間而不占靜態存儲區空間,函數調用結束后即釋放。(2)對靜態局部變量是在編譯時賦初值的,即只賦初值一次,在程序運行時它已有初值。以后每次調用函數時不再重新賦初值而只是保留上次函數調用結束時的值。(3)如在定義局部變量時不賦初值的話,則對靜態局部變量來說,編譯時自動賦初值(對數值型變量)或空字符(對字符變量)。而對自動變量來說,如果不賦初值則它的值是一個不確定的值。(4)雖然靜態局部變量在函數調用結束后仍然存在,但其他函數不能引用它。例例88 輸出到的階乘值

45、#include void main()int fac(int ); int ; for(;) printf(%!=,fac();Int fac(int )static int ; *; return(); 8.9.4 register8.9.4 register變量變量 變量的值是存放在內存中的。當程序中用到哪一個變量的值時,由控制器發出指令將內存中該變量的值送到運算器中。 經過運算器進行運算,如果需要存數,再從運算器將數據送到內存存放。 如果有一些變量使用頻繁,則為存取變量的值要花費不少時間。為提高執行效率,語言允許將局部變量的值放在CPU中的寄存器中,需要用時直接從寄存器取出參加運算,不

46、必再到內存中去存取。由于對寄存器的存取速度遠高于對內存的存取速度,因此這樣做可以提高執行效率。這種變量叫做寄存寄存器變量器變量,用關鍵字registerregister作聲明。例819使用寄存器變量#include void main ( )long fac(long); long i,n; scanf(%ld,&n); for(i=1;i=n;i+) printf(%ld!=%ldn,i,fac(i);long fac(long n)register long i,f=1; /*定義寄存器變量*/ for (i=1;i=n;i+) f=f*i; return (f);8.9.5 8.

47、9.5 用用externextern聲明外部變量聲明外部變量 外部變量是在函數的外部定義的全局變量,它的作用域是從變量的定義處開始,到本程序文件的末尾。在此作用域內,全局變量可以為程序中各個函數所引用。編譯時將外部變量分配在靜態存儲區。用extern來聲明外部變量,以擴展外部變量的作用城。1. 在一個文件內聲明外部變量在一個文件內聲明外部變量例例820 用用extern聲明外部變量,擴展它在程聲明外部變量,擴展它在程序文件中的作用域序文件中的作用域#include void main() int max(int,int); *外部變量聲明* extern A,B; printf(%dn,max

48、(A,B); int A=13,B=-8; *定義外部變量* int max(int x,int y) *定義函數 * int z; z=xy?x:y; return(z); 2. 在多文件的程序中聲明外部變量在多文件的程序中聲明外部變量#include int A; /*定義外部變量*/void main() int (int); /*函數聲明*/ int ,; printf(enter the number a and its power m:n); scanf(,A,); A*; printf(*,A,); (); printf(*n,A,); 例例8.8. 用extern將外部變量的作

49、用域擴展到其他文件。本程序的作用是給定的值,輸入和,求和am的值。文件file.中的內容為:文件file中的內容為:extern A; /*聲明A為一個已定義的外部變量*/ int powre(int );int ,; for(;) *A; return(); 8.9.6 8.9.6 用用staticstatic聲明外部變量聲明外部變量在程序設計中,某些外部變量只限于被本文件引用,而不能被其他文件引用。這時可以在定義外部變量時加一個staitic聲明。例如:例如:file1.c file2.cstatic int A; extern int A;void main ( ) void fun (int n) A=A*n; 8.9.7 8.9.7 關于變量的聲明和定義關于變量的聲明和定義定義性

溫馨提示

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

評論

0/150

提交評論