




已閱讀5頁,還剩177頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
7.1 函數(shù)是什么 7.2 函數(shù)的定義和調(diào)用 7.3 函數(shù)的嵌套調(diào)用和遞歸調(diào)用 7.4 數(shù)組作為函數(shù)參數(shù) 7.5 變量的作用域和生存期 7.6 內(nèi)部函數(shù)和外部函數(shù) 7.7 提高部分,第7章 用函數(shù)實現(xiàn)模塊化程序設(shè)計,P168,7.1 函數(shù)是什么,如果程序的功能比較多,規(guī)模比較大,把所有的程序代碼都寫在一個主函數(shù)中,就會使主函數(shù)變得龐雜、頭緒不清,使閱讀和維護程序變得困難。,P168,有時程序中要多次實現(xiàn)某一功能,就需要多次重復(fù)編寫實現(xiàn)此功能的程序代碼。這使程序冗長,不精煉。,7.1 函數(shù)是什么,P168,采用“組裝”的辦法簡化程序設(shè)計過程 事先編好一批函數(shù)實現(xiàn)各種不同的功能 用到什么函數(shù)就直接裝使用就可以 這就是模塊化的程序設(shè)計,7.1 函數(shù)是什么,P168,函數(shù)就是功能(Function) 每一個函數(shù)用來實現(xiàn)一個特定的功能 函數(shù)的名字應(yīng)反映其代表的功能,7.1 函數(shù)是什么,P168,在設(shè)計一個較大的程序時,往往把它分為若干個程序模塊,每一個模塊包括一個或多個函數(shù),每個函數(shù)實現(xiàn)一個特定的功能。,7.1 函數(shù)是什么,P168,一個程序可由一個主函數(shù)和若干個其他函數(shù)構(gòu)成。由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。同一個函數(shù)可以被一個或多個函數(shù)調(diào)用任意多次,7.1 函數(shù)是什么,P168,7.1 函數(shù)是什么,P168,main,a,b,c,f,g,h,d,e,i,e,除了可以使用庫函數(shù)外,還可以編寫一些本領(lǐng)域或本單位常用到一些專用函數(shù),供本領(lǐng)域或本單位的人員使用。、 在程序設(shè)計中要善于利用函數(shù),可以減少各人重復(fù)編寫程序段的工作量,同時可以方便地實現(xiàn)模塊化的程序設(shè)計。,7.1 函數(shù)是什么,P168,7.1 函數(shù)是什么,P168,例7.1 輸出以下的結(jié)果,用函數(shù)調(diào)用實現(xiàn)。 * How do you do! *,7.1 函數(shù)是什么,P168,解題思路: 在輸出的文字上下分別有一行“*”號,顯然不必重復(fù)寫這段代碼,用一個函數(shù)print_star來實現(xiàn)輸出一行“*”號的功能。 再寫一個print_message函數(shù)來輸出中間一行文字信息 用主函數(shù)分別調(diào)用這兩個函數(shù),#include void main() void print_star(); void print_message(); print_star(); print_message(); print_star(); void print_star () printf(*n); void print_message() printf( How do you do!n);,輸出18個*,輸出一行文字,#include void main() void print_star(); void print_message(); print_star(); print_message(); print_star(); void print_star () printf(*n); void print_message() printf( How do you do!n);,聲明函數(shù),定義函數(shù),說明: (1) 一個程序由一個或多個程序模塊組成,每一個程序模塊作為一個源程序文件。對于較大的程序,一般不把所有內(nèi)容全放在一個源程序文件中,而是將它們分別放在若干個源文件中,由若干個源程序文件組成一個C程序。這樣便于分別編寫、分別編譯,提高調(diào)試效率。一個源程序文件可以為多個C程序所調(diào)用。,說明: (2) 一個源程序文件由一個或多個函數(shù)以及其他有關(guān)內(nèi)容組成。一個源程序文件是一個編譯單位,在程序編譯時是以源程序文件為單位進(jìn)行編譯的,而不是以函數(shù)為單位進(jìn)行編譯的。,說明: (3) 不論main函數(shù)出現(xiàn)在什么位置,總是從main函數(shù)開始執(zhí)行。如果在main函數(shù)中調(diào)用其他函數(shù),在調(diào)用后流程返回到main函數(shù),在main函數(shù)中結(jié)束整個程序的運行。,說明: (4) 所有函數(shù)都是平行的,即在定義函數(shù)時是分別進(jìn)行的,是互相獨立的。一個函數(shù)并不從屬于另一個函數(shù),即函數(shù)不能嵌套定義。函數(shù)間可以互相調(diào)用,但不能調(diào)用main函數(shù)。main函數(shù)是由系統(tǒng)調(diào)用的。,說明: (5) 從用戶使用的角度看,函數(shù)有兩種。 庫函數(shù),它是由系統(tǒng)提供的,用戶不必自己定義而直接使用它們。應(yīng)該說明,不同的C語言編譯系統(tǒng)提供的庫函數(shù)的數(shù)量和功能會有一些不同,當(dāng)然許多基本的函數(shù)是共同的。 用戶自己定義的函數(shù)。它是用以解決用戶專門需要的函數(shù)。,說明: (6) 從函數(shù)的形式看,函數(shù)分兩類。 無參函數(shù)。函數(shù)沒有參數(shù),一般用來執(zhí)行固定的一組操作。無參函數(shù)可以帶回或不帶回函數(shù)值,但一般以不帶回函數(shù)值的居多。 有參函數(shù)。在調(diào)用函數(shù)時,要給出實參。主調(diào)函數(shù)在調(diào)用被調(diào)用函數(shù)時,通過參數(shù)向被調(diào)用函數(shù)傳遞數(shù)據(jù),一般情況下,執(zhí)行被調(diào)用函數(shù)時會得到一個函數(shù)值,供主調(diào)函數(shù)使用。,7.2 函數(shù)的定義和調(diào)用,7.2.1 為什么要定義函數(shù) 7.2.2 函數(shù)定義 7.2.3 函數(shù)的調(diào)用 7.2.4 對被調(diào)用函數(shù)的聲明和函數(shù)原型,P170,C語言要求,在程序中用到的所有函數(shù),必須“先定義,后使用” 指定函數(shù)名字、函數(shù)返回值類型、函數(shù)實現(xiàn)的功能以及參數(shù)的個數(shù)與類型,將這些信息通知編譯系統(tǒng)。,7.2.1 為什么要定義函數(shù),P170,指定函數(shù)的名字,以便以后按名調(diào)用 指定函數(shù)類型,即函數(shù)返回值的類型 指定函數(shù)參數(shù)的名字和類型,以便在調(diào)用函數(shù)時向它們傳遞數(shù)據(jù) 指定函數(shù)的功能。這是最重要的,這是在函數(shù)體中解決的,7.2.1 為什么要定義函數(shù),P170,如果程序中要調(diào)用庫函數(shù),只需用#include指令把有關(guān)的頭文件包含到本文件模塊中即可。 如果想使用庫函數(shù)中沒有的函數(shù),需要程序設(shè)計者在程序中自己定義。,7.2.1 為什么要定義函數(shù),P170,7.2.2 函數(shù)定義,1.怎樣定義無參函數(shù) 函數(shù)名后面圓括號中空的,沒有參數(shù) 定義無參函數(shù)的一般形式為: 類型名 函數(shù)名() 函數(shù)體 ,P171,包括聲明部分和語句部分,指定函數(shù)值的類型,7.2.2 函數(shù)定義,1.怎樣定義無參函數(shù) 函數(shù)名后面圓括號中空的,沒有參數(shù) 定義無參函數(shù)的一般形式為: 類型名 函數(shù)名() 函數(shù)體 ,P171,表示不需要帶回函數(shù)值,void,7.2.2 函數(shù)定義,2. 怎樣定義有參函數(shù) 定義有參函數(shù)的一般形式為: 類型標(biāo)識符 函數(shù)名(形式參數(shù)表列) 函數(shù)體 ,P171,7.2.2 函數(shù)定義,2. 怎樣定義有參函數(shù) int max (int x,int y) int z; if(xy) z=x; else z=y; return(z); ,P171,函數(shù)的功能是什么?,求x和y二者中大者,7.2.3 函數(shù)的調(diào)用,1.調(diào)用無參函數(shù)的形式 函數(shù)名() 如print_star() 2. 調(diào)用無參函數(shù)的形式 函數(shù)名(實參表列) 如max(a,b),P172,如果有多個參數(shù),用逗號隔開,例7.2 輸入兩個整數(shù),輸出二者中的大者。要求在主函數(shù)中輸入兩個整數(shù),用一個函數(shù)max求出其中的大者,并在主函數(shù)中輸出此值。,解題思路: 題目要求用一個max函數(shù)實現(xiàn)比較兩個整數(shù),并將得到的大數(shù)帶回主函數(shù)。顯然,二個整數(shù)中的大者也應(yīng)該是整數(shù),因此max函數(shù)應(yīng)當(dāng)是int型。 兩個數(shù)是在主函數(shù)中輸入的,在max函數(shù)中進(jìn)行比較,因此應(yīng)該定義為有參函數(shù),在函數(shù)調(diào)用時進(jìn)行數(shù)據(jù)的傳遞。,#include int max(int x,int y) int z; if (xy) z=x; else z=y; return(z); ,參數(shù)類型,函數(shù)類型,定義函數(shù),定義函數(shù)內(nèi)使用的變量,#include void main() int max(int x,int y); int a,b,c; printf(”please input two number:”); scanf(“%d,%d”, ,調(diào)用函數(shù),c=max(a,b); (main函數(shù)) int max(int x, int y) (max函數(shù)) int z; z=xy?x:y; return(z); ,#include void main() int max(int x,int y); int a,b,c; printf(”please input two number:”); scanf(“%d,%d”, ,if (xy) return(x); else return(y);,#include void main() int max(int x,int y); int a,b,c; printf(”please input two number:”); scanf(“%d,%d”, ,形式參數(shù),實際參數(shù),函數(shù)調(diào)用的過程:,在定義函數(shù)中指定的形參,在未出現(xiàn)函數(shù)調(diào)用時,它們并不占內(nèi)存中的存儲單元。在發(fā)生函數(shù)調(diào)用時,函數(shù)max的形參被臨時分配內(nèi)存單元。,2,a,3,b,x,y,2,3,實參,形參,函數(shù)調(diào)用的過程:,2,a,3,b,x,y,2,3,實參,形參,調(diào)用結(jié)束,形參單元被釋放 實參單元仍保留并維持原值,沒有改變 如果在執(zhí)行一個被調(diào)用函數(shù)時,形參的值發(fā)生改變,不會改變主調(diào)函數(shù)的實參的值,調(diào)用函數(shù)的方式:,按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調(diào)用方式 . 函數(shù)語句 調(diào)用沒有返回值的函數(shù),函數(shù)調(diào)用單獨作為一個語句 如例7.1中的“print_star();”,調(diào)用函數(shù)的方式:,按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調(diào)用方式 . 函數(shù)表達(dá)式 函數(shù)出現(xiàn)在一個表達(dá)式中,這種表達(dá)式稱為函數(shù)表達(dá)式 如例7.2中的“c=max(a,b);”,調(diào)用函數(shù)的方式:,按函數(shù)在程序中出現(xiàn)的位置來分,可以有以下3種函數(shù)調(diào)用方式 . 函數(shù)參數(shù) 函數(shù)調(diào)用作為一個函數(shù)的實參 如printf (%d, max (a,b);,7.2.4 對被調(diào)用函數(shù)的聲明和函數(shù)原型,P175,在一個函數(shù)中調(diào)用另一個函數(shù)需要具備如下條件: (1) 被調(diào)用函數(shù)必須是已經(jīng)定義的函數(shù)(是庫函數(shù)或用戶自己定義的函數(shù))。 (2) 如果使用庫函數(shù),應(yīng)該在本文件開頭加相應(yīng)的#include指令。 (3) 如果使用自己定義的函數(shù),而該函數(shù)的位置在調(diào)用它的函數(shù)后面,應(yīng)該進(jìn)行函數(shù)聲明,7.2.4 對被調(diào)用函數(shù)的聲明和函數(shù)原型,P175,函數(shù)原型的一般形式有兩種: 如 int max(int x,int y); int max(int,int); 原型說明可以放在文件的開頭,這時本文件中所有函數(shù)都可以使用此函數(shù),7.3 函數(shù)的嵌套調(diào)用和遞歸調(diào)用,P177,7.3.1 函數(shù)的嵌套調(diào)用 7.3.2 函數(shù)的遞歸調(diào)用,7.3.1 函數(shù)的嵌套調(diào)用,調(diào)用一個函數(shù)的過程中,又可以調(diào)用另一個函數(shù),P177,7.3.1 函數(shù)的嵌套調(diào)用,P177,main函數(shù),調(diào)用a函數(shù),結(jié)束,a函數(shù),調(diào)用b函數(shù),b函數(shù),例7.3 輸入4個整數(shù),找出其中最大的數(shù)。用一個函數(shù)來實現(xiàn)。 解題思路: 定義max_4函數(shù),找4個數(shù)中最大者 max_4中再多次調(diào)用max,找4個數(shù)中的大者,然后把它作為函數(shù)值返回main函數(shù),#include void main() int max_4(int a,int b,int c,int d); int a,b,c,d,max; printf(“4 interger numbers:“); scanf(“%d%d%d%d“, ,主函數(shù),對max_4 函數(shù)聲明,#include void main() int max_4(int a,int b,int c,int d); int a,b,c,d,max; printf(“4 interger numbers:“); scanf(“%d%d%d%d“, ,主函數(shù),輸入4個整數(shù),#include void main() int max_4(int a,int b,int c,int d); int a,b,c,d,max; printf(“4 interger numbers:“); scanf(“%d%d%d%d“, ,主函數(shù),調(diào)用后肯定是4個數(shù)中最大者,輸出最大者,int max_4(int a,int b,int c,int d) int max(int a,int b); int m; m=max(a,b); m=max(m,c); m=max(m,d); return(m); ,max_4函數(shù),對max 函數(shù)聲明,int max_4(int a,int b,int c,int d) int max(int a,int b); int m; m=max(a,b); m=max(m,c); m=max(m,d); return(m); ,max_4函數(shù),a,b中較大者,a,b,c中較大者,a,b,c,d中最大者,int max_4(int a,int b,int c,int d) int max(int a,int b); int m; m=max(a,b); m=max(m,c); m=max(m,d); return(m); ,max_4函數(shù),int max(int x,int y) if(xy) return x; else return y; ,max函數(shù),找x,y中較大者,int max_4(int a,int b,int c,int d) int max(int a,int b); int m; m=max(a,b); m=max(m,c); m=max(m,d); return(m); ,max_4函數(shù),int max(int x,int y) if(xy) return x; else return y; ,max函數(shù),return(xy?x:y);,int max_4(int a,int b,int c,int d) int max(int a,int b); m=max(a,b);m=max(m,c);m=max(m,d); return(m); ,int max(int x,int y) return(xy?x:y); ,#include void main() max=max_4(a,b,c,d); ,7.3.2 函數(shù)的遞歸調(diào)用,P179,在調(diào)用一個函數(shù)的過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。 語言的特點之一就在于允許函數(shù)的遞歸調(diào)用。,7.3.2 函數(shù)的遞歸調(diào)用,P179,f2函數(shù) 調(diào)用f1函數(shù),int f(int x) int y,z; z=f(y); return (2*z); ,f函數(shù) 調(diào)用f函數(shù),f1函數(shù) 調(diào)用f2函數(shù),應(yīng)使用if語句控制結(jié)束調(diào)用,直接調(diào)用本函數(shù),間接調(diào)用本函數(shù),例7.6 有5個學(xué)生坐在一起 問第5個學(xué)生多少歲?他說比第4個學(xué)生大2歲 問第4個學(xué)生歲數(shù),他說比第3個學(xué)生大2歲 問第3個學(xué)生,又說比第2個學(xué)生大2歲 問第2個學(xué)生,說比第1個學(xué)生大2歲 最后問第1個學(xué)生,他說是10歲 請問第5個學(xué)生多大,解題思路: 要求第個年齡,就必須先知道第個年齡 要求第個年齡必須先知道第個年齡 第個年齡又取決于第個年齡 第個年齡取決于第個年齡 每個學(xué)生年齡都比其前個學(xué)生的年齡大,解題思路: age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10,age(5) =age(4)+2,age(4) =age(3)+2,age(3) =age(2)+2,age(2) =age(1)+2,age(1) =10,age(2) =12,age(3) =14,age(4) =16,age(5) =18,回溯階段,遞推階段,age(5) =age(4)+2,age(4) =age(3)+2,age(3) =age(2)+2,age(2) =age(1)+2,age(1) =10,age(2) =12,age(3) =14,age(4) =16,age(5) =18,回溯階段,遞推階段,結(jié)束遞歸的條件,#include int age(int n) int c; if(n=1) c=10; else c=age(n-1)+2; return(c); void main() printf(“%dn“,age(5); ,age(5) 輸出age(5),main,c=age(4)+2,age函數(shù) n=5,c=age(3)+2,age函數(shù) n=4,c=age(1)+2,age函數(shù) n=2,c=age(2)+2,age函數(shù) n=3,c=10,age函數(shù) n=1,age(1)=10,age(2)=12,age(3)=14,age(4)=16,age(5)=18,18,例7.5 分別用遞推方法和遞歸方法求!,即12 n。 1.用遞推方法求! 解題思路: 從1開始,乘2,再乘3一直乘到n。這種方法容易理解,也容易實現(xiàn)。遞推法的特點是從一個已知的事實出發(fā),按一定規(guī)律推下一個事實,再從這個新的已知的事實出發(fā),再向下推出一個新的事實這是和遞歸不同的。,#include void main() long fac(int n); int n; long fact=0; printf(“input an integer number:”); scanf(“%d”, ,long fac(int n) int i; long fact=1; for(i=1;i=n;i+) fact=fact*i; return fact; ,2.用遞歸方法求! 解題思路: 遞歸的思路和遞推是相反的,并不是先求1 再 求1 2再 3,直到 n,而是直接從目標(biāo)出發(fā)提出問題: !等于!,而!,而1!是已知的,不必再回溯了,#include void main() long fac(int n); int n,y; printf(“input an integer number:“); scanf(“%d“, ,long fac(int n) long f; if(n0) printf(“n0,data error!”); else if(n=0 | n=1) f=1; else f=fac(n-1)*n; return(f); ,fac(5) 輸出fac(5),main,f=fac(4)5,fac函數(shù) n=5,f=fac(3)4,fac函數(shù) n=4,f=fac(1)2,fac函數(shù) n=2,f=fac(2)3,fac函數(shù) n=3,f=1,fac函數(shù) n=1,fac(1)=1,fac(2)=2,fac(3)=6,fac(4)=24,fac(5)=120,120,遞歸調(diào)用的特點: 執(zhí)行“未知未知遞歸邊界條件已知已知已知”的過程。,用遞歸方法解題的條件: (1)所求解的問題能轉(zhuǎn)化為用同一方法解決的子問題。 (2) 子問題的規(guī)模比原問題的規(guī)模小。 (3) 必須要有遞歸結(jié)束條件,停止遞歸,否則形成無窮遞歸,系統(tǒng)無法實現(xiàn)。,7.4 數(shù)組作為函數(shù)參數(shù),7.4.1 數(shù)組元素作函數(shù)實參 7.4.2 數(shù)組名作函數(shù)參數(shù),P184,7.4.1 數(shù)組元素作函數(shù)實參,由于實參可以是表達(dá)式,而數(shù)組元素可以是表達(dá)式的組成部分,因此數(shù)組元素可以作為函數(shù)的實參。,P185,例7.6 有兩個運動隊a和b,各有10個隊員,每個隊員有一個綜合成績。將兩個隊的每個隊員的成績按順序一一對應(yīng)地逐個比較(即a隊第1個隊員與b隊第1個隊員比,)。如果a隊隊員的成績高于b隊相應(yīng)隊員成績的數(shù)目多于b隊隊員成績高于a隊相應(yīng)隊員成績的數(shù)目(例如,a隊蠃6次,b隊蠃4次),則認(rèn)為a隊勝。統(tǒng)計出兩隊隊員比較的結(jié)果(a隊高于、等于和低于b隊的次數(shù))。,解題思路: 設(shè)兩個數(shù)組a和b,各有10個元素,分別存放10個隊員的成績 將兩個數(shù)組的相應(yīng)元素逐個比較,用3個變量n,m,k分別累計a隊隊員高于、等于和低于b隊隊員的次數(shù) 用一個函數(shù)higher來判斷每一次比較的結(jié)果,如果a隊員高于b隊員,結(jié)果為1,二者相等,結(jié)果為0,a隊員低于b隊員,結(jié)果為-1。最后比較n和k即可得到哪隊勝的結(jié)果,#include void main() int higher(int x,int y); int a10,b10,i,n=0,m=0,k=0; printf(“enter array a:n“); for(i=0;i10;i+) scanf(“%d“,輸入a隊隊員成績,輸入b隊隊員成績,for(i=0;i10;i+) if(higher(ai,bi)=1) n+; else if(higher(ai,bi)=0) m+; else k=k+1; printf(“a higher b %d timesn“,n); printf(“a equal to b %d timesn“,m); printf(“b higher a %d timesn“,k);,比較10個隊員,與變量作為實參一樣,if(nk) printf(“a wins!n“); else if (nk) printf(“b wins!n“); else printf(“a is equal to bn“); ,higher(int x,int y) int flag; if(xy) flag=1; else if(xy) flag=-1; else flag=0; return(flag); ,7.4.2 數(shù)組名作函數(shù)參數(shù),P186,希望在函數(shù)中處理整個數(shù)組的元素時,可以用數(shù)組名作為函數(shù)實參 注意,此時只是將數(shù)組的首元素的地址傳遞給所對應(yīng)的形參,因此對應(yīng)的形參應(yīng)當(dāng)是指針變量(見第8章)。,例7.7 有10個學(xué)生成績,用一個函數(shù)求全體學(xué)生的平均成績。 解題思路: 在主函數(shù)中定義一個實型數(shù)組score,將輸入的10個學(xué)生成績存放在數(shù)組中 設(shè)計函數(shù)average,用來求學(xué)生平均成績 需要把數(shù)組有關(guān)信息傳遞給average函數(shù) 采取用數(shù)組名作為實參,把數(shù)組地址傳給average函數(shù),在該函數(shù)中對數(shù)組進(jìn)行處理,#include void main() float average(float array10); float score10,aver; int i; printf(“input 10 scores:n“); for(i=0;i10;i+) scanf(“%f“, ,數(shù)組名作實參,float average(float array10) int i; float aver,sum=array0; for(i=1;i10;i+) sum=sum+arrayi; aver=sum/10; return(aver); ,與score共占同一存儲單元,實參、形參都是float型,相當(dāng)于score0,相當(dāng)于scorei,例7.8 有兩個班,學(xué)生數(shù)不同,編寫一個函數(shù),用來分別求各班的平均成績。,解題思路: 問題的關(guān)鍵是用同一個函數(shù)求不同人數(shù)的班級平均成績 在定義形參時不指定大小,函數(shù)對不同人數(shù)的班級都是適用 由于數(shù)組名傳遞的是數(shù)組首地址,可以利用同一個函數(shù)求人數(shù)不同的班平均成績 在定義average函數(shù)時,增加一個參數(shù)n,用來指定當(dāng)前班級的人數(shù),#include void main() float average(float array ,int n); float score_15=98.5,97,91.5,60,55; float score_210=67.5,89.5,99,69.5, 77,89.5,76.5,54,60,99.5; printf(“%6.2fn”,average(score_1,5); printf(“%6.2fn”,average(score_2,10); ,float average(float array ,int n) int i; float aver,sum=array0; for(i=1;in;i+) sum=sum+arrayi; aver=sum/n; return(aver); ,調(diào)用形式為average(score_1,5)時,相當(dāng)于score_10,相當(dāng)于score_1i,相當(dāng)于5,float average(float array ,int n) int i; float aver,sum=array0; for(i=1;in;i+) sum=sum+arrayi; aver=sum/n; return(aver); ,調(diào)用形式為average(score_2,10)時,相當(dāng)于score_20,相當(dāng)于score_2i,相當(dāng)于10,例7.9 用一個函數(shù)實現(xiàn)用選擇法對10個整數(shù)按升序排列。 解題思路: 所謂選擇法就是先將10個數(shù)中最小的數(shù)與a0對換;再將a1到a9中最小的數(shù)與a1對換每比較一輪,找出一個未經(jīng)排序的數(shù)中最小的一個 共比較9輪,a0 a1 a2 a3 a4,3 6 1 9 4,1 6 3 9 4,1 3 6 9 4,1 3 4 9 6,1 3 4 6 9,小到大排序,#include void main() void sort(int array,int n); int a10,i; printf(“enter the array:n“); for(i=0;i10;i+) scanf(“%d“, ,void sort(int array,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(arrayjarrayk) k=j; t=arrayk; arrayk=arrayi; arrayi=t; ,在sortisort9中,找最小數(shù)下標(biāo),在sortisort9中,最小數(shù)與sorti對換,例7.10 有4個學(xué)生,5門課的成績,設(shè)計一個函數(shù),用來求出其中的最高成績。 解題思路: 先使變量max的初值為二維數(shù)組中第一個元素的值,然后將二維數(shù)組中各個元素的值與max相比,每次比較后都把“大者”存放在max中,取代max的原值。全部元素比較完后,max 的值就是所有元素的最大值。,#include void main() float highest_score(float array45); float score45=61,73,85.5,87,90, 72,84,66,88,78, 75,87,93.5,81,96, 65,85,64,76,71 ; printf(“%6.2fn“,highest_score(score); ,float highest_score(float array45) int i,j; float max; max=array00; for(i=0;imax) max=arrayij; return (max); ,7.5 變量的作用域和生存期,7.5.1 變量的作用域-局部變量和全局變量 7.5.2 變量的存儲方式和生存期 7.5.3 作用域和生存期的小結(jié),P192,7.5.1 變量的作用域 局部變量和全局變量,1 局部變量 在函數(shù)和復(fù)合語句內(nèi)定義的變量,稱為內(nèi)部變量或局部變量 只在本函數(shù)或復(fù)合語句內(nèi)范圍內(nèi)有效(從定義點開始到函數(shù)或復(fù)合語句結(jié)束) 在此函數(shù)或復(fù)合語句以外是不能使用這些變量的,P192,說明: (1) 主函數(shù)中定義的變量也只在主函數(shù)中有效,主函數(shù)也不能使用其他函數(shù)中定義的變量。 (2) 不同函數(shù)中可以使用相同名字的變量,它們代表不同的對象,互不干擾。 (3) 形式參數(shù)也是局部變量。在函數(shù)中可以使用本函數(shù)定義的形參,在函數(shù)外不能引用它。 (4) 在一個函數(shù)內(nèi)部,可以在復(fù)合語句中定義變量,這些變量只在本復(fù)合語句中有效。,2 全局變量 一個程序可以包含一個或若干個源程序文件(即程序模塊),而一個源文件可以包含一個或若干個函數(shù) 在函數(shù)之外定義的變量是外部變量,也稱為全局變量(或全程變量) 全局變量的有效范圍為從定義變量的位置開始到本源文件結(jié)束,在此范圍內(nèi)可以為本文件中所有函數(shù)所共用,2 全局變量 在一個函數(shù)中既可以使用本函數(shù)中的局部變量,又可以使用有效的全局變量。 如果在同一個源文件中,外部變量與局部變量同名,則在局部變量的作用范圍內(nèi),外部變量被“屏蔽”了,即它不起作用,此時局部變量是有效的。,例7.11有4個學(xué)生,5門課的成績,要求輸出其中的最高成績以及它屬于第幾個學(xué)生、第幾門課程。,解題思路: 在例7.10中,通過調(diào)用highest_score函數(shù),得到最高分 除了輸出最高分以外,還要輸出該分?jǐn)?shù)是屬于第幾個學(xué)生、笫幾門課的信息,即需要輸出3個結(jié)果 調(diào)用一個函數(shù)只能得到一個函數(shù)值,因此例7.10程序無法解決這個問題 可以使用全局變量,通過全局變量從函數(shù)中得到所需要的值,#include int Row,Column; void main() float highest_score(float array45); float score45=61,73,85.5,87,90, 72,84,66,88,78,75,87,93.5,81,96, 65,85,64,76,71; printf(“he highest score is %6.2fn“, highest_score(score); printf(“Student No.is %dn Course No. is %dn“,Row,Column); ,定義全局變量,float highest_score(float array45) int i,j; float max; max=array00; for(i=0;imax) max=arrayij; Row=i; Column=j; return (max); ,行的序號賦給全局變量Row,將列的序號賦給全局變量Column,score 函數(shù)調(diào)用 Row Column,array max Row Column,main 函數(shù),highest_score 函數(shù),建議不在必要時不要使用全局變量,全局變量,Row,Column,7.5.2 變量的存儲方式和生存期,變量的生存期:變量值存在的時間 變量的兩種存儲方式:靜態(tài)存儲方式和動態(tài)存儲方式 靜態(tài)存儲方式是指在程序運行期間由系統(tǒng)分配固定的存儲空間的方式 動態(tài)存儲方式是在程序運行期間根據(jù)需要進(jìn)行動態(tài)的分配存儲空間的方式,P195,7.5.2 變量的存儲方式和生存期,全局變量采用靜態(tài)存儲方式,在程序開始執(zhí)行時給全局變量分配存儲區(qū),程序執(zhí)行完畢釋放。在程序執(zhí)行過程中它們占據(jù)固定的存儲單元,而不是動態(tài)地進(jìn)行分配和釋放。,P195,7.5.2 變量的存儲方式和生存期,在函數(shù)中定義的變量,在函數(shù)調(diào)用開始時分配動態(tài)存儲空間,函數(shù)結(jié)束時釋放這些空間。在程序執(zhí)行過程中,這種分配和釋放是動態(tài)的。,P195,7.5.2 變量的存儲方式和生存期,每一個變量和函數(shù)都有兩個屬性:數(shù)據(jù)類型和數(shù)據(jù)的存儲類別 數(shù)據(jù)類型,如整型、浮點型等 存儲類別指的是數(shù)據(jù)在內(nèi)存中存儲的方式(如靜態(tài)存儲和動態(tài)存儲),P195,1.auto聲明自動變量(auto變量) 函數(shù)中的形參和在函數(shù)中定義的變量(包括在復(fù)合語句中定義的變量),都屬于此類 在調(diào)用該函數(shù)時,系統(tǒng)給這些變量分配存儲空間,在函數(shù)調(diào)用結(jié)束時就自動釋放這些存儲空間。因此這類局部變量稱為自動變量。 自動變量用關(guān)鍵字auto作存儲類別的聲明,int f(int a) auto int b,c=3; ,可以省略,2. static聲明靜態(tài)變量 以下情況需要指定static存儲類別: 希望函數(shù)中的局部變量值在函數(shù)調(diào)用結(jié)束后不消失而繼續(xù)保留原值,即其占用的存儲單元不釋放,在下一次該函數(shù)調(diào)用時,該變量已有值,就是上一次函數(shù)調(diào)用結(jié)束時的值。這時就應(yīng)用關(guān)鍵字static指定該局部變量為“靜態(tài)局部變量”。,例7.12 輸出到的階乘值。 解題思路: 可以編一個函數(shù)用來進(jìn)行一次累乘 如第1次調(diào)用時進(jìn)行1乘1 第2次調(diào)用時再乘以2 第3次調(diào)用時再乘以3 依此規(guī)律進(jìn)行下去 這時希望上一次求出的連乘值保留,以便下一次再乘上一個數(shù)??梢杂胹tatic。,#include void main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,int fac(int n) static int f=1; f=f*n; return(f); ,調(diào)用五次,每調(diào)用一次,開辟新n,但f不是,#include void main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,int fac(int n) static int f=1; f=f*n; return(f); ,i=1:第一次調(diào)用,1,f,#include void main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,int fac(int n) static int f=1; f=f*n; return(f); ,1,f,i=2:第二次調(diào)用,2,#include void main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,int fac(int n) static int f=1; f=f*n; return(f); ,f,i=3:第三次調(diào)用,2,6,#include void main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,int fac(int n) static int f=1; f=f*n; return(f); ,f,i=4:第四次調(diào)用,6,24,#include void main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,int fac(int n) static int f=1; f=f*n; return(f); ,f,i=5:第五次調(diào)用,24,120,對靜態(tài)局部變量的說明: (1)靜態(tài)局部變量屬于靜態(tài)存儲類別,在靜態(tài)存儲區(qū)內(nèi)分配存儲單元。在程序整個運行期間都不釋放。而自動變量(即動態(tài)局部變量)屬于動態(tài)存儲類別,占動態(tài)存儲區(qū)空間而不占靜態(tài)存儲區(qū)空間,函數(shù)調(diào)用結(jié)束后即釋放,對靜態(tài)局部變量的說明: (2)對靜態(tài)局部變量是在編譯時賦初值的,即只賦初值一次,在程序運行時它已有初值。以后每次調(diào)用函數(shù)時不再重新賦初值而只是保留上次函數(shù)調(diào)用結(jié)束時的值。而對自動變量賦初值,不是在編譯時進(jìn)行的,而是在函數(shù)調(diào)用時進(jìn)行,每調(diào)用一次函數(shù)重新給一次初值,相當(dāng)于執(zhí)行一次賦值語句。,對靜態(tài)局部變量的說明: (3)如在定義局部變量時不賦初值的話,則對靜態(tài)局部變量來說,編譯時自動賦初值(對數(shù)值型變量)或空字符(對字符變量)。而對自動變量來說,如果不賦初值則它的值是一個不確定的值。這是由于每次函數(shù)調(diào)用結(jié)束后存儲單元已釋放,下次調(diào)用時又重新另分配存儲單元,而所分配的單元中的值是不可知的。,對靜態(tài)局部變量的說明: (4)雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其他函數(shù)是不能引用它的。因為它是局部變量,只能被本函數(shù)引用,而不能被其他函數(shù)引用。,對靜態(tài)局部變量的說明: (5)用靜態(tài)存儲要多占內(nèi)存(長期占用不釋放,而不能像動態(tài)存儲那樣一個存儲單元可供多個變量使用,節(jié)約內(nèi)存),而且降低了程序的可讀性,當(dāng)調(diào)用次數(shù)多時往往弄不清靜態(tài)局部變量的當(dāng)前值是什么。因此,若非必要,不要多用靜態(tài)局部變量。,3. register聲明寄存器變量 一般情況下,變量(包括靜態(tài)存儲方式和動態(tài)存儲方式)的值是存放在內(nèi)存中的 寄存器變量允許將局部變量的值放在CPU中的寄存器中 現(xiàn)在的計算機能夠識別使用頻繁的變量,從而自動地將這些變量放在寄存器中,而不需要程序設(shè)計者指定,4. extern聲明外部變量的作用范圍 (1)在一個文件內(nèi)擴展外部變量的作用域 如果外部變量不在文件的開頭定義,其有效的作用范圍只限于定義處到文件結(jié)束 如果由于某種考慮,在定義點之前的函數(shù)需要引用該外部變量,則應(yīng)該在引用之前用關(guān)鍵字extern對該變量作“外部變量聲明”,4. extern聲明外部變量的作用范圍 (2)將外部變量的作用域擴展到其他文件 在任一個文件中定義外部變量,而在另一文件中用extern對該變量作外部變量聲明,7.5.3 作用域和生存期的小結(jié),對一個變量的屬性可以從兩個方面分析,一是變量的作用域,一是變量的生存期。 前者是從空間的角度,后者是從時間的角度。 二者有聯(lián)系但不是同一回事,P195,int a; void main( ) f2( );f1( ); void f1( ) auto int b; f2( ); void f2( ) static int c; ,a的作用域,b的作用域,c的作用域,文件file1.c,a生存期,b生存期,c生存期,main,f2,f1,main,f2,f1,main,各種類型變量的作用域和存在性的情況,7.6 內(nèi)部函數(shù)和外部函數(shù),7.6.1 內(nèi)部函數(shù) 7.6.2 外部函數(shù),P200,7.6.1 內(nèi)部函數(shù),P200,如果一個函數(shù)只能被本文件中其他函數(shù)所調(diào)用,它稱為內(nèi)部函數(shù)。 在定義內(nèi)部函數(shù)時,在函數(shù)名和函數(shù)類型的前面加static,即: static 類型名 函數(shù)名(形參表),7.6.1 內(nèi)部函數(shù),P200,內(nèi)部函數(shù)又稱靜態(tài)函數(shù),因為它是用static聲明的 通常把只能由本文件使用的函數(shù)和外部變量放在文件的開頭,前面都冠以static使之局部化,其他文件不能引用 提高了程序的可靠性,7.6.2 外部函數(shù),P201,如果在定義函數(shù)時,在函數(shù)首部的最左端加關(guān)鍵字extern,則此函數(shù)是外部函數(shù),可供其他文件調(diào)用。 如函數(shù)首部可以為 extern int fun (int a, int b) 如果在定義函數(shù)時省略extern,則默認(rèn)為外部函數(shù),例7.13 有一個字符串,內(nèi)有若干個字符,今輸入一個字符,要求程序?qū)⒆址性撟址麆h去。用外部函數(shù)實現(xiàn)。,j=0,假設(shè)刪除空格,刪除空格的思路為,非空,I,空,非空,a,非空,m,空,非空,h,非空,a,非空,p,非空,p,非空,y,結(jié)束,0,0,i=0,1,1,2,2,3,3,4,5,4,6,5,7,6,8,7,9,8,10,#include void main() extern void enter_string(char str); extern void delete_string(char str, char ch); extern void print_string(char str); char c,str80; enter_string(str); scanf(“%c”, ,file1(文件1),聲明在本函數(shù)中將要調(diào)用的已在其他文件中定義的3個函數(shù),void enter_string(char str80) gets(str); void delete_string(char str,char ch) int i,j; for(i=j=0;stri!=0;i+) if(stri!=ch) strj+=stri; strj=0; void print_string(char str) printf(“%sn“,str); ,file2(文件2),file3(文件3),file4(文件4),7.7 提高部分,7.7.1 實參求值的順序 7.7.2 遞歸的典型例子 -Hanoi(漢諾)塔問題,P203,7.7.1 實參求值的順序,如果實參表列包括多個實參,對實參求值的順序并不是確定的 有的系統(tǒng)按自左至右順序求實參的值 有的系統(tǒng)(如Turbo C 2.0, Turbo C+ 3.0,VC+ 6.0)則按自右至左順序求值。,P203,7.7.2 遞歸的典型例子 -Hanoi(漢諾)塔問題,P203,例7.8 Hanoi(漢諾)塔問題。古代有一個梵塔,塔內(nèi)有3個柱子A、B、C,開始時柱上有64個盤子,盤子大小不等,大的在下,小的在上。有一個老和尚想把這64個盤子從A柱移到C柱,
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 六一活動游街活動方案
- 六一活動踢球活動方案
- 六一游園手工活動方案
- 六一玩具團隊活動方案
- 六一結(jié)對活動方案
- 六一節(jié)團委活動方案
- 六一節(jié)景區(qū)活動方案
- 六一葵花義賣活動方案
- 醫(yī)生的考試試題及答案
- 醫(yī)德醫(yī)風(fēng)考試試題及答案
- 第4章 頜位(雙語)
- 課程綜述(數(shù)電)
- 塔吊負(fù)荷試驗方案
- 購買社區(qū)基本公共養(yǎng)老、青少年活動服務(wù)實施方案
- 傷口和傷口敷料基礎(chǔ)知識.ppt
- 安徽省中等職業(yè)學(xué)校學(xué)歷證明書辦理申請表
- 《慢性腎臟病》PPT課件.ppt
- 例析物理競賽中純電阻電路的簡化和等效變換
- 六年級下冊美術(shù)課件第13課《祖國美景知多少》浙美版
- 智能照明系統(tǒng)的外文文獻(xiàn)原稿和譯文.doc
- 氣象觀測場坪防雷設(shè)計
評論
0/150
提交評論