




已閱讀5頁,還剩117頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第8章 函數(shù) 8.1 概述 一個C程序,由一個主函數(shù)和若干其它函數(shù)組成,它們之間的關(guān)系是: 主函數(shù)可以調(diào)用其它函數(shù),其它函數(shù)可相互調(diào)用。且一個函數(shù)可以被調(diào)用若干次 注:每個函數(shù)都是獨(dú)立的,平等的! 函數(shù):完成特定功能的程序段,通常由用戶定義或系統(tǒng)定義 各函數(shù)可存放在一個文件中,也可以存放在不同的文件中。,某程序整體結(jié)構(gòu),,程序運(yùn)行軌跡: maina d a e a main b f e f b g b h b main c h g h c i c main,舉例:用常規(guī)、文件包含兩種方法打印字符串 一、常規(guī)方法:各函數(shù)包含在一個文件中 例T8-1.c main( ) p1( ); p2( ); p1( ); p1( ) printf (“* n” ); p2( ) printf (“_ _ _ _ _How_do_you_do!n”) ;,運(yùn)行結(jié)果: * _ _ _ _ _How_do_you_do! _ _ _ _ * *,二、文件包含的方法 在主函數(shù)所在的文件中使用文件包含預(yù)編譯命令,將不在本文件而在其它文件中的函數(shù)進(jìn)行預(yù)編譯處理,把各文件中的函數(shù)包含到本文件中來,然后一起進(jìn)行編譯、連接、運(yùn)行。 T8-1-3.c #include “T8-1-1.c” #include “T8-1-2.c” main( ) p1( ); p2( ) ; p1( ) ; 運(yùn)行結(jié)果同上 友情提示:還可以用項(xiàng)目的方法,T8-1-1.c p1( ) printf (“* n”); ,T8-1-2.c p2( ) printf (“_ _ _ _ How_do_you_do! n”); ,說明: (1)一個文件可含多個函數(shù),編譯的單位是文件而不是函數(shù); (2)一個完整的程序可由若干個文件組成,可用項(xiàng)目或文件包含的方法對其編譯; (3)C執(zhí)行總是從main函數(shù)開始執(zhí)行,調(diào)用其它函數(shù)后又返回到main函數(shù); (4)函數(shù)定義是獨(dú)立的、平等的,不能嵌套定義(即函數(shù)里不能再定義函數(shù))但可相互調(diào)用; (5)函數(shù)的類型: 標(biāo)準(zhǔn)庫函數(shù),由系統(tǒng)提供,用戶直接使用 用戶定義的函數(shù) (6) 函數(shù)的形式: 無參函數(shù) 主調(diào)函數(shù)無數(shù)據(jù)傳給被調(diào)函數(shù),可帶或不帶返回值. 有參函數(shù) 主調(diào)函數(shù)與被調(diào)函數(shù)間有參數(shù)傳遞,主調(diào)函數(shù)可將實(shí)際參數(shù)傳送給被調(diào)函數(shù)的形式參數(shù),被調(diào)函數(shù)的函數(shù)值可傳回主調(diào)函數(shù)。,8.2 函數(shù)定義的一般形式 1.無參函數(shù)的定義形式: 類型標(biāo)識符 函數(shù)名( ) 聲明部分 語句部分 注:無參函數(shù)一般不返回函數(shù)值,故類型標(biāo)識符可省。 2.有參函數(shù)的定義形式: 類型標(biāo)識符 函數(shù)名(形式參數(shù)表列) 聲明部分 語句部分 ,其中: 類型標(biāo)識符:指出函數(shù)返回值的數(shù)據(jù)類型 (int, float,char等),系統(tǒng)默認(rèn)為int 函數(shù)名:合法的標(biāo)識符; 形參表列:接收主調(diào)函數(shù)傳遞過來的實(shí)參,其中包括對形參類型的聲明(老版本中形參類型進(jìn)一步聲明放在下一行)。 形參類型:與實(shí)參類型要一致。 :稱函數(shù)體,包括 聲明部分:定義局部變量的數(shù)據(jù)類型; 語句部分:完成函數(shù)功能的若干執(zhí)行語句。,例: int max(int x,int y) int z; z= xy ? x : y ; return(z) ; ,3.空函數(shù)的定義形式 類型說明符 函數(shù)名( ) 例: p1( ) 空函數(shù)不作任何操作,但是合法,它對調(diào)試程序或以后在此處補(bǔ)充完整的函數(shù)體是 有作用的。,4.對形參聲明的傳統(tǒng)方式 傳統(tǒng)方式中,形參類型說明在函數(shù)定義的第2行 如:傳統(tǒng)形參聲明形式 int max(x,y) int x,y; int z; z=xy ?x:y; return(z); ,新版本形參聲明形式 int max(int x,int y) int z; z=xy ?x:y; return(z); ,以上兩種定義形式在Turbo C中都認(rèn)可,8.3 函數(shù)參數(shù)和函數(shù)的值 8.3.1 形式參數(shù)和實(shí)際參數(shù) 實(shí)際參數(shù):主調(diào)函數(shù)中提供的數(shù)據(jù)。 可以是常量、變量、表達(dá)式等,是具體的數(shù)值。 形式參數(shù):被調(diào)函數(shù)中用以接收主調(diào)函數(shù)數(shù)據(jù)的變量。 被調(diào)用函數(shù)名后面括號內(nèi)的若干變量名。,例T8-2.c 調(diào)用函數(shù)時的數(shù)據(jù)傳遞 main( ) int a, b, c; scanf(%d%d”, ,輸入:-100 200 Max is 200,關(guān)于形、實(shí)參的說明: 1.形參只有在函數(shù)調(diào)用時才分配存儲單元,調(diào)用結(jié)束后,釋放所分配的單元; 2.實(shí)參可以是常量、變量、表達(dá)式:max(3,a+b),總之要有確定的值,當(dāng)函數(shù)調(diào)用時,將實(shí)參的值傳遞給形參,若是數(shù)組名,則傳送的是數(shù)組的首地址。 3.被調(diào)函數(shù)中,形參類型必須指定,以便分配存儲單元。,4.實(shí)參、形參的數(shù)據(jù)類型一致,賦值要兼容,順序要一致。 如果形、實(shí)參類型不一致時,則按賦值規(guī)則進(jìn)行。通常被調(diào)函數(shù)放在主調(diào)函數(shù)之前,以便編譯系統(tǒng)對函數(shù)類型和形參類型作合法性檢查。若被調(diào)函數(shù)在主調(diào)函數(shù)之后,一般要對被調(diào)函數(shù)作原型聲明。 main() float a=4.5,b=4.5; int abc(int,int); abc(a,b); abc(int x,int y) printf(“x=%d,y=%dn”,x,y); 結(jié)果:x=4,y=4,5.若被調(diào)函數(shù)類型為非整形或?qū)崊⑿螀㈩愋筒黄ヅ?,要在主調(diào)函數(shù)中對被調(diào)函數(shù)作原形聲明。另外若被調(diào)函數(shù)在主調(diào)函數(shù)之前定義,則原形聲明可省,因?yàn)榫幾g系統(tǒng)已經(jīng)知道被調(diào)函數(shù)的類型及其形參的個數(shù)、類型了。 6.實(shí)參對形參的數(shù)據(jù)傳送是值傳送,也是單向傳送,當(dāng)被調(diào)函數(shù)的形參發(fā)生變化時,并不改變主調(diào)函數(shù)實(shí)參的值。,例T8-2-1.c 形、實(shí)參占據(jù)的是不同的存儲單元 main( ) int a=2,b=3; printf (“a=%d, b=%d n”,a, b); printf(“ ,運(yùn)行結(jié)果: a=2,b=3 &a=ffd6,&b=ffd8 x=10,y=15 &x=ffd2,&y=ffd4 a=2, b=3 &a=ffd6,&b=ffd8,8.3.2 函數(shù)的返回值 調(diào)用一個函數(shù)一般都希望返回一個確定的值。 有關(guān)函數(shù)值的幾點(diǎn)說明: 1.若需要返回值則用return語句; 2.被調(diào)函數(shù)中可用多個return語句,執(zhí)行哪一個由程序執(zhí)行情況來定。 例:函數(shù)中有如下語句 if(ab) return(a); else return(b); 3.return后面的括號可省,如:return a;,4.return 后的值可以是一個表達(dá)式,如:return(x y ? x : y); 5.函數(shù)值的類型是在定義函數(shù)時指定的 如: int max(x, y) float min(a,b) double abc(d1,d2) 6.語句return(a,b,c)是合法的,返回表達(dá)式c的值。 注意: (1)函數(shù)定義時,函數(shù)名的括號后無 “ ;” ; (2) 未加類型說明的函數(shù)自動按整型處理; (3) 定義函數(shù)時,函數(shù)值的類型一般與return 后面表達(dá)式的類 型一致,若不一致, 則以函數(shù)值為準(zhǔn)。,例T8-3.c 函數(shù)值類型為整型,而返回值的類型是實(shí)型,最后以整型值返回。即以函數(shù)類型為準(zhǔn) main( ) int max(float,float);/*原型聲明*/ float a, b; int c; scanf(“%f%f”, ,輸入: 1. 5 2. 5 輸出:max is 2,6.函數(shù)中無return 語句時,可能返回一個不確定或無用的值 例T8-3-1.c main( ) int a, b, c; a=p1( ); b=p2( ); c=p1( ); printf(“a=%d,b=%d,c=%d n”,a, b, c); p1( ) printf(“* n”); p2( ) printf(“ I am happy! n”); ,運(yùn)行結(jié)果: * I am happy! * a=6,b=12,c=6,7.為明確表示不帶返回值,可用void(無值,空類型)定義函數(shù)。 例T8-3-2.c main( ) int a,b,c; a=p1( ); b=p2( ); c=p1( ); printf(“a=%d, b=%d, c=%d n”,a, b, c); void p1( ) printf(“* n”); void p2( ) printf(“I am happy! n”); ,編譯時指出: Type mismatch in redeclartion of p1 , p2 意即:在定義函數(shù) p1, p2 時類型不匹配,8.4 函數(shù)的調(diào)用 主調(diào)函數(shù):主動去調(diào)用其它函數(shù) 被調(diào)函數(shù):被其它函數(shù)所調(diào)用 8.4.1 函數(shù)調(diào)用的一般形式 函數(shù)名(實(shí)參表列) 操作:把控制和實(shí)參傳送給被調(diào)函數(shù),當(dāng)無參時,實(shí)參表列為空,但( )不能省。 函數(shù)名:是已存在的被調(diào)用的函數(shù); 實(shí)參表列:有確定值的數(shù)據(jù),當(dāng)有多個實(shí)參時,實(shí)參間用“ ,”分隔,通常形實(shí)、參個數(shù)要相等,類型要一致,實(shí)參求值順序在Turbo C中是從右向左。,例T8-4.c 實(shí)參求值順序從右向左 main( ) int i=2, p; p=f(i, +i); printf(“p=%d, i=%d n”,p, i); int f(int a, int b) int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return (c); ,運(yùn)行結(jié)果: p=0, i=3 若將參數(shù)改為f(i,i+), 則結(jié)果為: p=1, i=3 思考:若從左至右呢? 回憶一下printf的求值順序,8.4.2 函數(shù)的調(diào)用方法 1.函數(shù)語句:把函數(shù)調(diào)用作為一個單獨(dú)的語句; 如:f1( ); 2.函數(shù)表達(dá)式:函數(shù)調(diào)用出現(xiàn)在表達(dá)式中,其函數(shù)返回的值參加整個表達(dá)式的運(yùn)算。 如:c=max(a,b) + min(c,d); 3.函數(shù)參數(shù):函數(shù)調(diào)用作為另一個函數(shù)的參數(shù),如:m=max(a,max(b,c); printf(“%d”,max(a,b);,8.4.3 對被調(diào)用函數(shù)的聲明和函數(shù)原型 被調(diào)函數(shù)應(yīng)具備的條件 1.被調(diào)函數(shù)必須存在(標(biāo)準(zhǔn)或用戶定義),如不在同一文件中,可用項(xiàng)目或文件包含的方法將各被調(diào)用函數(shù)連接起來。 2.若使用庫函數(shù),應(yīng)在文件開頭用#include命令將調(diào)用庫函數(shù)時用到的宏定義信息包含到本文件中來。 如:#include “stdio.h” #include “math.h” 3.若主調(diào)和被調(diào)函數(shù)在同一文件中,一般應(yīng)在主調(diào)函數(shù)中對被調(diào)函數(shù)的類型作聲明,即向編譯系統(tǒng)聲明即將調(diào)用的函數(shù) 形式: 類型標(biāo)識符 被調(diào)用函數(shù)名(類型 形參. );,例T8-5.c 在主調(diào)函數(shù)中,對被調(diào)函數(shù)的數(shù)據(jù)類型進(jìn)行說明 main( ) float add( float x,float y ); /*聲明:函數(shù)類型、名,形參類型等通知編譯系統(tǒng)*/ 再看 float a, b, c; scanf(%f%f”, ,輸入:3.6 6. 5 輸出:sum is 10.10000,問題: (1)若不對函數(shù)類型進(jìn)行聲明,則指出:在重定義函 數(shù)add時,類型不匹配; (2)在聲明時指出類型,若定義時沒有指出類型,編譯指出:定義add時類型不匹配(此處是實(shí)型)。 函數(shù)聲明(原型):與函數(shù)首部一致。 順序、個數(shù)、類型等都要相同 有關(guān)函數(shù)的定義、聲明、返回值等概念 1.函數(shù)定義:對函數(shù)功能的確定,指定函數(shù)名、函數(shù)值類型、形參及類型、函數(shù)體等,它是完整的、獨(dú)立的函數(shù)單位。,2.函數(shù)聲明:也稱函數(shù)原型,其作用是把函數(shù)的名字、函數(shù)類型以及形參的類型、個數(shù)和順序通知編譯系統(tǒng),以便調(diào)用函數(shù)時進(jìn)行對照檢查。 函數(shù)聲明(原型)的形式: (1)函數(shù)類型 函數(shù)名(參數(shù)類型1,參數(shù)類型2.); (2)函數(shù)類型 函數(shù)名(參數(shù)類型1 參數(shù)名1,參數(shù)類型2 參數(shù)名2.); 3.當(dāng)函數(shù)返回的值為整型或字符型時,可不必聲明。系統(tǒng)會默認(rèn)把第一次碰到的函數(shù)視為INT 4.被調(diào)用函數(shù)在主調(diào)函數(shù)之前定義時,在主調(diào)函數(shù)中可不必聲明。,友情提示1,函數(shù)的原型聲明必須放在程序開始處或main之前,例T8-5-1.c被調(diào)函數(shù)出現(xiàn)在主調(diào)函數(shù)之前,則在主調(diào)函數(shù)中不必聲明 float add(float x,float y) float z; z=x+y; return(z); main( ) float a, b, c; scanf(“%f%f”, ,輸入:3.6 6.5 輸出:sum is 10.100000,主調(diào)函數(shù)中沒對被調(diào)函數(shù)的返回值進(jìn)行類型聲明,原因是: 編譯系統(tǒng)已經(jīng)預(yù)知定義的函數(shù)的類型,并進(jìn)行自動處理。 5.如果在所有函數(shù)定義之前,在文件的開頭,在函數(shù)的外部對函數(shù)的類型作了聲明,則在各主調(diào)函數(shù)中不必對所調(diào)用的函數(shù)再作類型聲明。 例T8-5-2.c 在文件的開頭,在所有函數(shù)的外部對函數(shù)作類型聲明 。 char a1(char x1,char x2 ); float a2(float y1,float y2 ); int a3( int m ); double a4( double n1,double n2 );,main( ) 返回 char c1=d, c2=a; int i=5; float f1=3.67, f2=5.56; double d1=11111111.111, d2=22222222.222; printf(“a1( )=%c n”, a1(c1, c2); printf(“a2( )=%f n”, a2(f1, f2); printf(“a3( )=%d n”, a3(i);printf(“a4( )=%lf n”, a4(d1, d2); char a1(char x1, char x2) return( x1x2 ? x1 : x2); float a2(float y1, float y2) float z; z=y1+y2; return( z ); int a3(int m) int i, s=1; for(i=1; i=m; i+) s=s*i; return(s) ; double a4(double n1,double n2) double n3; n3=n1+n2; return(n3); ,運(yùn)行結(jié)果: a1( )=d a2( )=9.230000 a3( )=120 a4( )=33333333.333000 問題的提出: (1)不在文件開頭,不在 函數(shù)外部說明,情況如何? (2)不在主調(diào)函數(shù)開始部 分說明,解決的辦法?,友情提示2,不要將空函數(shù)和void函數(shù)弄混了,8.5 函數(shù)的嵌套調(diào)用,例T8-6 用弦截法求方程 x3 -5x2 +16x =0 的根(請仔細(xì)研究),方法與步驟: 2.連接f(x1),f(x2)兩點(diǎn)成一直線(弦),此線交x軸于x。 X點(diǎn)的坐標(biāo)求法: 連接f(x1),f(x2)兩點(diǎn)的直線 f(x) 稱商差(弦、斜率): 求x點(diǎn)的坐標(biāo) 從x值得f(x) 3.若f(x)與f(x1)同號,則根必在(x,x2)區(qū)間,此時將x作新的x1; 若f(x)與f(x2)同號,則根必在(x1,x)區(qū)間,此時將x作新的x2; 4.重復(fù)步驟2,3直到| f(x) | 為止, 設(shè) 10-6 , 則 f(x)0,異號:x1,x2之間必有一根 1.取x1,x2兩點(diǎn) 得f(x1), f(x2) 同號:改變x1, x2,直到f(x1), f(x2)異號為止。,用三個函數(shù)實(shí)現(xiàn)各部分的功能: f(x):用來求x的函數(shù):x3 - 5x2 +16x-80 xpoint(x1,x2): 求f(x1)與f(x2)的連線(弦)與x軸交點(diǎn)x的坐標(biāo) root(x1, x2) :求(x1, x2)區(qū)間的實(shí)根 例T8-6.c 用弦截法求方程x3 - 5x2 +16x-80的根 #include “math.h” float f(float x) float y; y=(x-5.0)*x+16.0)*x-80.0; return(y); float xpoint(float x1, float x2) float y; y=(x1*f(x2)-x2*f(x1)/(f(x2)-f(x1); return(y); ,float root(float x1,float x2) float x, y, y1; y1=f(x1); dox=xpoint(x1, x2); y=f(x); if(y*y1 0) y1=y; x1=x; else x2=x; while(fabs(y) =0.0001); return(x); main( ) float x1, x2, f1, f2, x; do printf(“input x1, x2: n”); scanf(“%f%f”, ,運(yùn)行: input x1, x2: 2, 6 A root of equation is 5.0000,8.6 函數(shù)的遞歸調(diào)用 遞歸:在函數(shù)調(diào)用過程中,直接或間接的調(diào)用自身。 1.直接遞歸:在函數(shù)體內(nèi)又調(diào)用自身,2.間接遞歸:當(dāng)函數(shù)去調(diào)用另一函數(shù)時,而另一函數(shù)反過來又調(diào)用自身。 解決無終止遞歸調(diào)用的方法是:確定好結(jié)束遞歸的條件。,遞歸調(diào)用 定義:函數(shù)直接或間接的調(diào)用自身叫函數(shù)的遞歸調(diào)用,說明 C編譯系統(tǒng)對遞歸函數(shù)的自調(diào)用次數(shù)沒有限制 所以,必須要用if 語句限制遞歸的次數(shù),以免無限遞歸下去了,int f(int x) int y,z; z=f(y); . return(2*z); ,例T8-7.c 有5個人在一起問年齡,第5個人比第4個人大2歲,第4個人比第3個人大2歲. . .第2個人比第1個人大2歲,第1個人為10歲。(回推+遞推),T8-7.c 問年齡程序 age(int n) int c; if(n=1) c=10; else c=2+age(n-1); return(c); /*返回給主調(diào)函數(shù)*/ main( ) printf(“%d n”, age(5); ,運(yùn)行結(jié)果:18,在遞歸調(diào)用過程中,有些信息被臨時壓入堆棧 回推到已知:結(jié)束 這里控制有限次遞歸的一個條件就是if (n=1),有些問題,可以用遞推,也可以用遞歸的方法解決 遞推:從一個已知的事實(shí)出發(fā),按一定規(guī)律推出下一個事實(shí),再從已知的新的事實(shí),推出下一個新的事實(shí). 例T8-7-1.c 用遞推法求n! ,即從1開始, 乘2, 乘3一直到n main( ) int i, s=1; for(i=1;i=5;i+) s=s* i; printf(“s=%d n”,s); ,運(yùn)行結(jié)果:s=120,遞歸:回推(問題先壓入堆棧暫存)+遞推 從哪里開始遞推?從滿足結(jié)束遞歸的條件處開始遞推 如: 5!=5 x 4! 4!=4 x 3! 3!=3 x 2! 2!=2 x 1! 1!=1 0!=1,例T8-8.c 用遞歸法求4! float facto(int n) float s; if(n 0) printf(“ n 0 data error ! n”); else if(n=0 | n=1 ) s=1; else s=n*facto(n-1); return(s); main( ) int n; float y; printf(“input a integer number:”); scanf(%d”, ,facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,facto(int n),int s;,if(n= =0),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,s=facto(n-1),facto(int n),int s;,if(n= =0),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,s=facto(n-1),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,facto(int n),facto(int n),int s;,int s;,if(n= =0),if(n= =0),s=facto(n-1),s = 1,return(1),s=n*s=2*1,return(2),return(6),s=n*s=3*2,s=n*s=4*6,return(24),1,2,3,4,3,2,1,N=4,N=3,N=2,N=1,facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,facto(int n),int s;,else,s=facto(n-1),2,N=4,main函數(shù)第 1次調(diào)用facto,(main),堆棧,(n=4),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,N=3,facto(int n),int s;,else,s=facto(n-1),3,Facto1函數(shù)第 2次調(diào)用facto,(main),堆棧,(n=4),(n=3),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,N=2,facto(int n),int s;,else,s=facto(n-1),4,Facto2函數(shù)調(diào)用 第3次facto,(main),堆棧,(n=4),(n=3),(n=2),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,N=1,facto(int n),int s;,else,s=facto(n-1),4,Facto3函數(shù)第 4次調(diào)用facto,(main),堆棧,(n=4),(n=3),(n=2),(n=1),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,s = 1,N=0,facto(int n),int s;,if(n= =0),Facto4函數(shù)第 5次調(diào)用facto,return(1),(main),堆棧,(n=4),(n=3),(n=2),(n=1),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,s=facto(1-1)=0!=1,s=1*1,return(1),N=1,(main),堆棧,(n=4),(n=3),(n=2),恢復(fù)facto4 現(xiàn)場,40E2(n=1),0!= 1,facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,s=facto(2-1)=1!=1,s=2*1,return(2),N=2,(main),堆棧,(n=4),(n=3),恢復(fù)facto3 現(xiàn)場,40E2(n=2),1!= 1,facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,s=facto(3-1)=2!=2,s=3*2,return(6),N=3,(main),堆棧,(n=4),恢復(fù)facto2 現(xiàn)場,2!= 2,40E2(n=3),facto(int n) int s; if(n= =0) s = 1; else s=facto(n-1); s=n*s; return(s); ,return(24),N=4,s=facto(4-1)=3!=6,s=4*6,(main),堆棧,恢復(fù)facto1 現(xiàn)場,3!= 6,40E2(n=4),返回主函數(shù),例T8-9.c hanoi (漢諾)塔問題(請仔細(xì)研究) 十九世紀(jì)未,歐洲珍奇商店出現(xiàn)一種漢諾塔游戲,并有推銷材料,說是古代印度布拉瑪廟里的僧侶們當(dāng)時正在玩這種游戲,如果游戲結(jié)束,世界未日即來臨。 一、規(guī)則及分析: n個盤子從一個座移到另一個座,每次只能移動一個盤子,不允許大盤在小盤上面。 共有三個座,n個盤子由A座移到C座,需移動的次數(shù)是2n -1, 若64個盤子移動的次數(shù)為: 264 - 1=18, 446, 744, 073, 709, 551, 615 一年的秒數(shù)是:365 x 24 x 60 x 60=31536000 1844674407370955161531536000 =584942417355年 即:5849億年, 從能源角度推算, 太陽系壽命只有150億年,二、方法與步驟 1.將A上n-1個盤子借助C座移到B座 2.把A上剩下一個盤子送到C座 3.將n-1個盤子從B座借助A座移到C座,三、實(shí)例:將A上3個盤子移到C 步驟:1.A座上兩個盤子借助C座移到B座 2.A座上最后一個盤子移到C座 3.B座上兩個盤子借助A座移到C座 第一步進(jìn)一步分解: 1.1 A座上一個盤子從AC 1.2 A座上一個盤子從AB 1.3 C座上一個盤子從CB 第二步進(jìn)一步分解: A座上最后一個盤子從AC 第三步進(jìn)一步分解: 3.1 B座上一個盤子從BA 3.2 B座上一個盤子從BC 3.3 A座上一個盤子從AC,結(jié)論: 13步都是把n-1個盤子從一個座移到另一個座上,方法一樣,只是座的名稱不同而已,為使之一般化,將13步表示為:將one 座上的n-1個盤子移到two座,借助 three座,只是對應(yīng)關(guān)系不同。 第一步對應(yīng)關(guān)系:one A two B three C 第三步對應(yīng)關(guān)系:one B two C three A,1.將 n - 1個盤子從一個座移到另一個座上(n - 1) 2.將 1個盤子從一個座移到另一個座上(n - 1),例T8-9.c 用遞歸的方法解決漢諾塔程序如下: void move(char x, char y) printf(“%c%c n”, x, y); void hanoi(int n, char one, char two, char three) if(n = 1) move(one,three); else hanoi(n-1, one, three, two); move(one, three); hanoi(n-1, two, one, three); main( ) int m; printf(“input the number of diskes:”); scanf(“%d”,運(yùn)行: input number of diskes: 3 the step to moving 3 diskes: A C A B C B A C B A B C A C,8.7 數(shù)組作為函數(shù)參數(shù) 函數(shù)調(diào)用形式一:函數(shù)名(數(shù)組名)實(shí)參或形參 函數(shù)調(diào)用形式二:函數(shù)名(數(shù)組元素)實(shí)參 數(shù)組名作為參數(shù):傳遞的是數(shù)組的首地址; 數(shù)組元素作實(shí)參時:傳遞的是數(shù)組元素的值, 是單向的值傳送。,8.7 數(shù)組作為函數(shù)參數(shù) 函數(shù)調(diào)用形式一:函數(shù)名(數(shù)組名)實(shí)參或形參 函數(shù)調(diào)用形式二:函數(shù)名(數(shù)組元素)實(shí)參 數(shù)組名作為參數(shù):傳遞的是數(shù)組的首地址; 數(shù)組元素作實(shí)參時:傳遞的是數(shù)組元素的值, 是單向的值傳送。,數(shù)組元素作函數(shù)實(shí)參值傳遞,例 兩個數(shù)組大小比較,n=0 m=0 k=0,a和b為有10個元素的整型數(shù)組 比較兩數(shù)組對應(yīng)元素 變量n,m,k記錄aibi, ai=bi, aik,認(rèn)為數(shù)組ab 若nk,認(rèn)為數(shù)組ab 若n=k,認(rèn)為數(shù)組a=b,2、數(shù)組名作為函數(shù)實(shí)參 此時,傳送的是數(shù)組的地址,調(diào)用函數(shù)時,對形參數(shù)組元素的操作,實(shí)際上也是對實(shí)參數(shù)組元素的操作。 *地址傳遞 *在主調(diào)函數(shù)與被調(diào)函數(shù)分別定義數(shù)組,且類型應(yīng)一致,例 求學(xué)生的平均成績,#include float average(int stu10, int n); void main() int score10, i; float av; printf(“Input 10 scores:n“); for( i=0; i10; i+ ) scanf(“%d“, ,float average(int stu10, int n) int i; float av,total=0; for( i=0; in; i+ ) total += stui; av = total/n; return av; ,實(shí)參用數(shù)組名,形參用數(shù)組定義, int stu ,幾點(diǎn)說明: 1.數(shù)組名作形、實(shí)參數(shù)時,應(yīng)分別在主、被調(diào)函數(shù)中對其定義 2.數(shù)組名作參數(shù)時,傳遞的是地址,對形參數(shù)組的操作實(shí)際 上也是對實(shí)參數(shù)組的操作。兩個數(shù)組是共用同一個內(nèi)存單元則形參中的數(shù)據(jù)變化了實(shí)參也會變化這與變量做形參區(qū)別很大 3.作為形、實(shí)參數(shù)的數(shù)組,其類型要一致,大小一般相等,以保證形式上的對應(yīng); 4.當(dāng)形參數(shù)組大小未指定時,用一實(shí)參將數(shù)組長度傳遞給形 參以便對數(shù)組進(jìn)行操作; 5、字符串的傳遞同數(shù)組的傳遞字符串是用數(shù)組存儲的,例8-12.c 求兩組學(xué)生的平均成績,形參數(shù)組長度缺省 float average(float a ,int n) int i; float aver, sum=a0; for(i=1;in;i+) sum=sum+ai; aver=sum/n; return(aver); ,main( ) float s15=98.5, 97, 91.5, 60, 60, 55; float s210=67.5, 89.5, 99, 69.5, 77, 89.5, 76.5, 54, 60, 99.5; printf(“the average of class A is %6.2f n”,average(s1,5); printf(“the average of class B is %6.2f n”,average(s2,10); ,the average of class A is 80.40 the average of class B is 78.20,例 數(shù)組元素與 數(shù)組名 作函數(shù)參數(shù)比較,#include void swap2(int x,int y) int z; z=x; x=y; y=z; main() int a2=1,2; swap2(a0,a1); printf(“a0=%dna1=%dn“,a0,a1); ,值傳遞,#include void swap2(int x) int z; z=x0; x0=x1; x1=z; main() int a2=1,2; swap2(a); printf(“a0=%dna1=%dn“,a0,a1); ,地址傳遞,例 數(shù)組元素與 數(shù)組名 作函數(shù)參數(shù)比較,例 數(shù)組排序-簡單選擇排序(請同學(xué)們自行思考),9,49,i=0,例 數(shù)組排序-簡單選擇排序,13,68,i=1,i=8,例 數(shù)組排序-簡單選擇排序,例 求二維數(shù)組中最大元素值,int max_value(int array34) int i,j,k,max; max=array00; for(i=0;imax) max=arrayij; return(max); main() int a34=1,3,5,7, 2,4,6,8,15,17,34,12; printf(“max value is %dn“,max_value(a); ,例 求二維數(shù)組中各行元素之和,get_sum_row(int x3, int result ,int row, int col) int i,j; for(i=0;irow;i+) resulti=0; for(j=0;jcol;j+) resulti+=xij; main() int a23=3,6,9,1,4,7; int sum_row2,row=2,col=3,i; get_sum_row(a,sum_row,row,col); for(i=0;irow;i+) printf(“The sum of row%d=%dn“,i+1,sum_rowi); ,18,12,8.8 局部變量和全局變量 8.8.1 局部變量 變量:按其作用域,可分為局部和全局 局部:作用域僅限于其所定義的函數(shù)或復(fù)合語句內(nèi)部,離開該函數(shù)或復(fù)合語句則釋放內(nèi)存單元 特點(diǎn): (1)在不同的函數(shù)中允許同名,它們占據(jù)不同的內(nèi)存單元, 相互之間互不影響。 (2)形參屬局部變量,只能在其所在的函數(shù)內(nèi)部使用。,例T8-14-1.c f1( ) int a=10, b=25, c=30; printf(“f1: a=%d, b=%d, c=%d n”, a, b, c); f2( int a,int b ) int c; a=a+2; c=a+b+3; printf(“f2:a=%d, b=%d, c=%d n”,a,b,c); main( ) int a=1, b=2, c=5; /*abc也不例外,也是局部變量*/ printf(“1.main:a=%d, b=%d, c=%d n”,a, b, c); f1( ); printf(“2.main:a=%d, b=%d, c=%d n”,a, b, c); f2(a, b ); printf(“3.main:a=%d, b=%d, c=%d n”,a, b, c); ,運(yùn)行結(jié)果: 1. main:a=1, b=2, c=5 f1:a=10, b=25, c=30 2.main:a=1, b=2, c=5 f2:a=3, b=2, c=8 3.main:a=1, b=2, c=5,例T8-14-2.c 復(fù)合語句中局部變量的例子 main( ) int a=1, b=2, c=3; int c; c=a-b; printf(“a=%d, b=%d, c=%d n”, a, b, c); printf(“a=%d, b=%d, c=%d n”, a, b, c) ; ,運(yùn)行結(jié)果: a=1, b=2, c=-1 a=1, b=2, c=3,8.8.2 全局變量 全局變量:在一個文件的所有函數(shù)以外定義的變量稱為外部或全局變量。 作用域:從定義變量的位置開始到源程序結(jié)束。所有該源文件中的函數(shù)公用,幾點(diǎn)說明,在源程序開始定義的全局變量,對源程序中所有函數(shù)有效 在源程序中間定義的全局變量,僅對其后面的所有函數(shù)有效,幾點(diǎn)說明2,在函數(shù)或復(fù)合語句中定義的局部變量若與全局變量同名,當(dāng)該函數(shù)或復(fù)合語句被執(zhí)行時,則局部變量優(yōu)先,全局變量不起作用(被屏蔽)。,例T8-14-3.c 全局變量的作用域及其使用情況 int a=1; f1( ) int b; b=a+3; printf(“f1:a=%d, b=%d n”,a, b); f2( ) int a, b; a=5; b=a+3; printf(“f2: a=%d, b=%d n”,a, b); f3( ) int b; a=6; b=a+3; printf(“f3:a=%d, b=%d n”,a, b); main( ) int b=3; printf(“1.main : a=%d, b=%d n”,a, b); f1( ); printf(“2.main : a=%d, b=%d n”,a, b); f2( ); printf(“3.main : a=%d, b=%d n”,a, b); f3( ); printf(“4.main : a=%d, b=%d n”,a, b); ,運(yùn)行: 1.main:a=1, b=3 f1:a=1, b=4 2.main:a=1, b=3 f2:a=5, b=8 3.main:a=1, b=3 f3:a=6, b=9 4.main:a=6, b=3,幾點(diǎn)說明3,全局變量的使用,增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道,同一文件中的所有函數(shù)都能引用全局變量的值,當(dāng)某函數(shù)改變了全局變量的值時,便會影響其它的函數(shù)。,例T8-15.c 用一維數(shù)組存放10個學(xué)生的成績,在函數(shù)中求最高分、最低分和平均值。 float max=0, min=0; (習(xí)慣上:Max,Min) float average(float array,int n) int i; float aver,sum=array0; max=min=array0; for(i=1; i max) max=arrayi; else if(arrayi min) min=arrayi; sum=sum+arrayi ; aver=sum/n; return(aver); ,main( ) float ave, score10; int i; printf(“input 10 numbers : n”); for(i=0; i10; i+) scanf(“%f”, 一個函數(shù)可以返回3個值了!,運(yùn)行:input 10 numbers: 99 45 78 97 100 67.5 89 92 66 43 max=100.00 min=43.00 ave=77.65,float max,min; float average(float array, int n) int i; float sum=array0; max=min=array0; for(i=1;imax) max=arrayi; else if(arrayimin) min=arrayi; sum+=arrayi; return(sum/n); main() int i; float ave,score10; /*Input */ ave=average(score,10); printf(“max=%6.2fnmin=%6.2fn average=%6.2fn“,max,min,ave); ,外部(全局)變量的弊端: 1.建議非必要時不要使用全局變量: (1)整個程序中均占用存儲空間 (2)函數(shù)可移植性差 2.程序可讀性差,且一旦外部變量被改變將影響所有函數(shù),int i; main() void prt(); for(i=0;i5;i+) prt(); void prt() for(i=0;i5;i+) printf(“%c”,*); printf(“n”); ,例 外部變量副作用,運(yùn)行結(jié)果:*,變量的存儲屬性 概述 每個變量有兩個基本屬性:變量的數(shù)據(jù)類型!那么,變量的存儲類型呢?,編譯或函數(shù)調(diào)用時為其分配內(nèi)存單元,10,程序中使用變量名對內(nèi)存操作,變量的屬性 數(shù)據(jù)類型:變量所持有的數(shù)據(jù)的性質(zhì)(操作屬性) 存儲屬性 存儲器類型:寄存器、靜態(tài)存儲區(qū)、動態(tài)存儲區(qū) 生存期:變量在某一時刻存在-靜態(tài)變量與動態(tài)變量 作用域:變量在某區(qū)域內(nèi)有效-局部變量與全局變量 變量的存儲類型 auto -自動型 register-寄存器型 static -靜態(tài)型 extern -外部型 變量定義格式: 存儲類型 數(shù)據(jù)類型 變量表;,如: int sum; auto int a,b,c; register int i; static float x,y;,程序運(yùn)行時,在內(nèi)存中的存儲情況: (1)靜態(tài)存儲方式:即程序運(yùn)行期間為其分配的存儲單元是固定的。直到文件執(zhí)行完 (2)動態(tài)存儲方式:程序運(yùn)行期間根據(jù)需要為其分配存儲單元。用完就釋放,格式:auto int a; 說明符“auto”可以省略。 auto float pi; 說明: 1.說明自動變量必須在一個函數(shù)體的內(nèi)部。 2.函數(shù)的形參也是自動變量。,作用域 函數(shù)內(nèi)部,實(shí)質(zhì)上是一個局部變量。只有在函數(shù)被調(diào)用時才存在,從函數(shù)中返回時即消失,其值僅限于說明它的函數(shù)。 由于自動變量具有局部性,所以在兩個不同的函數(shù)中可以分別使用同名的變量而互不影響。,自動變量auto,8.9.2 auto變量 函數(shù)內(nèi)部無static聲明的局部量均為動態(tài)存儲類別,被
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 寵物醫(yī)療設(shè)備調(diào)試員考試試卷及答案
- 環(huán)保工程師(水污染防治)崗位面試問題及答案
- 房地產(chǎn)跨境交易合同專業(yè)翻譯及風(fēng)險評估服務(wù)協(xié)議
- 跨國公司股東入股合作協(xié)議
- 美食外賣配送合作協(xié)議
- 新材料產(chǎn)業(yè)股權(quán)轉(zhuǎn)讓及市場推廣合作補(bǔ)充協(xié)議范本
- 童裝新品發(fā)布會獨(dú)家購銷合作框架合同
- 股權(quán)結(jié)構(gòu)調(diào)整與優(yōu)化合同范本
- 二手房交易房屋租賃權(quán)法律咨詢合同
- 企業(yè)股權(quán)無償轉(zhuǎn)讓與經(jīng)營管理權(quán)移交協(xié)議
- 九師聯(lián)盟2024-2025學(xué)年高二下學(xué)期7月期末質(zhì)量檢測政治試題(含答案)
- 浙江杭州市2024-2025學(xué)年高一下學(xué)期6月期末考試英語試題及答案
- 喘息性支氣管肺炎的護(hù)理查房
- 新型電極材料成本控制-洞察及研究
- 2025年初中數(shù)學(xué)知識點(diǎn)測試題及答案
- 小學(xué)生集體活動安全課件
- 2025-2030年中國高爾夫產(chǎn)品行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 山東威海經(jīng)發(fā)投資控股集團(tuán)有限公司及下屬子公司招聘筆試題庫2025
- 新能源汽車充電樁建設(shè)方案及流程
- 2025-2030年中國人乳寡糖(HMO)行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 動火工作方案
評論
0/150
提交評論