計算機C語言—第八章.ppt_第1頁
計算機C語言—第八章.ppt_第2頁
計算機C語言—第八章.ppt_第3頁
計算機C語言—第八章.ppt_第4頁
計算機C語言—第八章.ppt_第5頁
已閱讀5頁,還剩117頁未讀 繼續免費閱讀

VIP免費下載

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

文檔簡介

第8章 函數 8.1 概述 一個C程序,由一個主函數和若干其它函數組成,它們之間的關系是: 主函數可以調用其它函數,其它函數可相互調用。且一個函數可以被調用若干次 注:每個函數都是獨立的,平等的! 函數:完成特定功能的程序段,通常由用戶定義或系統定義 各函數可存放在一個文件中,也可以存放在不同的文件中。,某程序整體結構,,程序運行軌跡: maina d a e a main b f e f b g b h b main c h g h c i c main,舉例:用常規、文件包含兩種方法打印字符串 一、常規方法:各函數包含在一個文件中 例T8-1.c main( ) p1( ); p2( ); p1( ); p1( ) printf (“* n” ); p2( ) printf (“_ _ _ _ _How_do_you_do!n”) ;,運行結果: * _ _ _ _ _How_do_you_do! _ _ _ _ * *,二、文件包含的方法 在主函數所在的文件中使用文件包含預編譯命令,將不在本文件而在其它文件中的函數進行預編譯處理,把各文件中的函數包含到本文件中來,然后一起進行編譯、連接、運行。 T8-1-3.c #include “T8-1-1.c” #include “T8-1-2.c” main( ) p1( ); p2( ) ; p1( ) ; 運行結果同上 友情提示:還可以用項目的方法,T8-1-1.c p1( ) printf (“* n”); ,T8-1-2.c p2( ) printf (“_ _ _ _ How_do_you_do! n”); ,說明: (1)一個文件可含多個函數,編譯的單位是文件而不是函數; (2)一個完整的程序可由若干個文件組成,可用項目或文件包含的方法對其編譯; (3)C執行總是從main函數開始執行,調用其它函數后又返回到main函數; (4)函數定義是獨立的、平等的,不能嵌套定義(即函數里不能再定義函數)但可相互調用; (5)函數的類型: 標準庫函數,由系統提供,用戶直接使用 用戶定義的函數 (6) 函數的形式: 無參函數 主調函數無數據傳給被調函數,可帶或不帶返回值. 有參函數 主調函數與被調函數間有參數傳遞,主調函數可將實際參數傳送給被調函數的形式參數,被調函數的函數值可傳回主調函數。,8.2 函數定義的一般形式 1.無參函數的定義形式: 類型標識符 函數名( ) 聲明部分 語句部分 注:無參函數一般不返回函數值,故類型標識符可省。 2.有參函數的定義形式: 類型標識符 函數名(形式參數表列) 聲明部分 語句部分 ,其中: 類型標識符:指出函數返回值的數據類型 (int, float,char等),系統默認為int 函數名:合法的標識符; 形參表列:接收主調函數傳遞過來的實參,其中包括對形參類型的聲明(老版本中形參類型進一步聲明放在下一行)。 形參類型:與實參類型要一致。 :稱函數體,包括 聲明部分:定義局部變量的數據類型; 語句部分:完成函數功能的若干執行語句。,例: int max(int x,int y) int z; z= xy ? x : y ; return(z) ; ,3.空函數的定義形式 類型說明符 函數名( ) 例: p1( ) 空函數不作任何操作,但是合法,它對調試程序或以后在此處補充完整的函數體是 有作用的。,4.對形參聲明的傳統方式 傳統方式中,形參類型說明在函數定義的第2行 如:傳統形參聲明形式 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中都認可,8.3 函數參數和函數的值 8.3.1 形式參數和實際參數 實際參數:主調函數中提供的數據。 可以是常量、變量、表達式等,是具體的數值。 形式參數:被調函數中用以接收主調函數數據的變量。 被調用函數名后面括號內的若干變量名。,例T8-2.c 調用函數時的數據傳遞 main( ) int a, b, c; scanf(%d%d”, ,輸入:-100 200 Max is 200,關于形、實參的說明: 1.形參只有在函數調用時才分配存儲單元,調用結束后,釋放所分配的單元; 2.實參可以是常量、變量、表達式:max(3,a+b),總之要有確定的值,當函數調用時,將實參的值傳遞給形參,若是數組名,則傳送的是數組的首地址。 3.被調函數中,形參類型必須指定,以便分配存儲單元。,4.實參、形參的數據類型一致,賦值要兼容,順序要一致。 如果形、實參類型不一致時,則按賦值規則進行。通常被調函數放在主調函數之前,以便編譯系統對函數類型和形參類型作合法性檢查。若被調函數在主調函數之后,一般要對被調函數作原型聲明。 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); 結果:x=4,y=4,5.若被調函數類型為非整形或實參形參類型不匹配,要在主調函數中對被調函數作原形聲明。另外若被調函數在主調函數之前定義,則原形聲明可省,因為編譯系統已經知道被調函數的類型及其形參的個數、類型了。 6.實參對形參的數據傳送是值傳送,也是單向傳送,當被調函數的形參發生變化時,并不改變主調函數實參的值。,例T8-2-1.c 形、實參占據的是不同的存儲單元 main( ) int a=2,b=3; printf (“a=%d, b=%d n”,a, b); printf(“ ,運行結果: 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 函數的返回值 調用一個函數一般都希望返回一個確定的值。 有關函數值的幾點說明: 1.若需要返回值則用return語句; 2.被調函數中可用多個return語句,執行哪一個由程序執行情況來定。 例:函數中有如下語句 if(ab) return(a); else return(b); 3.return后面的括號可省,如:return a;,4.return 后的值可以是一個表達式,如:return(x y ? x : y); 5.函數值的類型是在定義函數時指定的 如: int max(x, y) float min(a,b) double abc(d1,d2) 6.語句return(a,b,c)是合法的,返回表達式c的值。 注意: (1)函數定義時,函數名的括號后無 “ ;” ; (2) 未加類型說明的函數自動按整型處理; (3) 定義函數時,函數值的類型一般與return 后面表達式的類 型一致,若不一致, 則以函數值為準。,例T8-3.c 函數值類型為整型,而返回值的類型是實型,最后以整型值返回。即以函數類型為準 main( ) int max(float,float);/*原型聲明*/ float a, b; int c; scanf(“%f%f”, ,輸入: 1. 5 2. 5 輸出:max is 2,6.函數中無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”); ,運行結果: * I am happy! * a=6,b=12,c=6,7.為明確表示不帶返回值,可用void(無值,空類型)定義函數。 例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 意即:在定義函數 p1, p2 時類型不匹配,8.4 函數的調用 主調函數:主動去調用其它函數 被調函數:被其它函數所調用 8.4.1 函數調用的一般形式 函數名(實參表列) 操作:把控制和實參傳送給被調函數,當無參時,實參表列為空,但( )不能省。 函數名:是已存在的被調用的函數; 實參表列:有確定值的數據,當有多個實參時,實參間用“ ,”分隔,通常形實、參個數要相等,類型要一致,實參求值順序在Turbo C中是從右向左。,例T8-4.c 實參求值順序從右向左 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); ,運行結果: p=0, i=3 若將參數改為f(i,i+), 則結果為: p=1, i=3 思考:若從左至右呢? 回憶一下printf的求值順序,8.4.2 函數的調用方法 1.函數語句:把函數調用作為一個單獨的語句; 如:f1( ); 2.函數表達式:函數調用出現在表達式中,其函數返回的值參加整個表達式的運算。 如:c=max(a,b) + min(c,d); 3.函數參數:函數調用作為另一個函數的參數,如:m=max(a,max(b,c); printf(“%d”,max(a,b);,8.4.3 對被調用函數的聲明和函數原型 被調函數應具備的條件 1.被調函數必須存在(標準或用戶定義),如不在同一文件中,可用項目或文件包含的方法將各被調用函數連接起來。 2.若使用庫函數,應在文件開頭用#include命令將調用庫函數時用到的宏定義信息包含到本文件中來。 如:#include “stdio.h” #include “math.h” 3.若主調和被調函數在同一文件中,一般應在主調函數中對被調函數的類型作聲明,即向編譯系統聲明即將調用的函數 形式: 類型標識符 被調用函數名(類型 形參. );,例T8-5.c 在主調函數中,對被調函數的數據類型進行說明 main( ) float add( float x,float y ); /*聲明:函數類型、名,形參類型等通知編譯系統*/ 再看 float a, b, c; scanf(%f%f”, ,輸入:3.6 6. 5 輸出:sum is 10.10000,問題: (1)若不對函數類型進行聲明,則指出:在重定義函 數add時,類型不匹配; (2)在聲明時指出類型,若定義時沒有指出類型,編譯指出:定義add時類型不匹配(此處是實型)。 函數聲明(原型):與函數首部一致。 順序、個數、類型等都要相同 有關函數的定義、聲明、返回值等概念 1.函數定義:對函數功能的確定,指定函數名、函數值類型、形參及類型、函數體等,它是完整的、獨立的函數單位。,2.函數聲明:也稱函數原型,其作用是把函數的名字、函數類型以及形參的類型、個數和順序通知編譯系統,以便調用函數時進行對照檢查。 函數聲明(原型)的形式: (1)函數類型 函數名(參數類型1,參數類型2.); (2)函數類型 函數名(參數類型1 參數名1,參數類型2 參數名2.); 3.當函數返回的值為整型或字符型時,可不必聲明。系統會默認把第一次碰到的函數視為INT 4.被調用函數在主調函數之前定義時,在主調函數中可不必聲明。,友情提示1,函數的原型聲明必須放在程序開始處或main之前,例T8-5-1.c被調函數出現在主調函數之前,則在主調函數中不必聲明 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,主調函數中沒對被調函數的返回值進行類型聲明,原因是: 編譯系統已經預知定義的函數的類型,并進行自動處理。 5.如果在所有函數定義之前,在文件的開頭,在函數的外部對函數的類型作了聲明,則在各主調函數中不必對所調用的函數再作類型聲明。 例T8-5-2.c 在文件的開頭,在所有函數的外部對函數作類型聲明 。 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); ,運行結果: a1( )=d a2( )=9.230000 a3( )=120 a4( )=33333333.333000 問題的提出: (1)不在文件開頭,不在 函數外部說明,情況如何? (2)不在主調函數開始部 分說明,解決的辦法?,友情提示2,不要將空函數和void函數弄混了,8.5 函數的嵌套調用,例T8-6 用弦截法求方程 x3 -5x2 +16x =0 的根(請仔細研究),方法與步驟: 2.連接f(x1),f(x2)兩點成一直線(弦),此線交x軸于x。 X點的坐標求法: 連接f(x1),f(x2)兩點的直線 f(x) 稱商差(弦、斜率): 求x點的坐標 從x值得f(x) 3.若f(x)與f(x1)同號,則根必在(x,x2)區間,此時將x作新的x1; 若f(x)與f(x2)同號,則根必在(x1,x)區間,此時將x作新的x2; 4.重復步驟2,3直到| f(x) | 為止, 設 10-6 , 則 f(x)0,異號:x1,x2之間必有一根 1.取x1,x2兩點 得f(x1), f(x2) 同號:改變x1, x2,直到f(x1), f(x2)異號為止。,用三個函數實現各部分的功能: f(x):用來求x的函數:x3 - 5x2 +16x-80 xpoint(x1,x2): 求f(x1)與f(x2)的連線(弦)與x軸交點x的坐標 root(x1, x2) :求(x1, x2)區間的實根 例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”, ,運行: input x1, x2: 2, 6 A root of equation is 5.0000,8.6 函數的遞歸調用 遞歸:在函數調用過程中,直接或間接的調用自身。 1.直接遞歸:在函數體內又調用自身,2.間接遞歸:當函數去調用另一函數時,而另一函數反過來又調用自身。 解決無終止遞歸調用的方法是:確定好結束遞歸的條件。,遞歸調用 定義:函數直接或間接的調用自身叫函數的遞歸調用,說明 C編譯系統對遞歸函數的自調用次數沒有限制 所以,必須要用if 語句限制遞歸的次數,以免無限遞歸下去了,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); /*返回給主調函數*/ main( ) printf(“%d n”, age(5); ,運行結果:18,在遞歸調用過程中,有些信息被臨時壓入堆棧 回推到已知:結束 這里控制有限次遞歸的一個條件就是if (n=1),有些問題,可以用遞推,也可以用遞歸的方法解決 遞推:從一個已知的事實出發,按一定規律推出下一個事實,再從已知的新的事實,推出下一個新的事實. 例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); ,運行結果:s=120,遞歸:回推(問題先壓入堆棧暫存)+遞推 從哪里開始遞推?從滿足結束遞歸的條件處開始遞推 如: 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函數第 1次調用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函數第 2次調用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函數調用 第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函數第 4次調用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函數第 5次調用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),恢復facto4 現場,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),恢復facto3 現場,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),恢復facto2 現場,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),堆棧,恢復facto1 現場,3!= 6,40E2(n=4),返回主函數,例T8-9.c hanoi (漢諾)塔問題(請仔細研究) 十九世紀未,歐洲珍奇商店出現一種漢諾塔游戲,并有推銷材料,說是古代印度布拉瑪廟里的僧侶們當時正在玩這種游戲,如果游戲結束,世界未日即來臨。 一、規則及分析: n個盤子從一個座移到另一個座,每次只能移動一個盤子,不允許大盤在小盤上面。 共有三個座,n個盤子由A座移到C座,需移動的次數是2n -1, 若64個盤子移動的次數為: 264 - 1=18, 446, 744, 073, 709, 551, 615 一年的秒數是: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座,三、實例:將A上3個盤子移到C 步驟:1.A座上兩個盤子借助C座移到B座 2.A座上最后一個盤子移到C座 3.B座上兩個盤子借助A座移到C座 第一步進一步分解: 1.1 A座上一個盤子從AC 1.2 A座上一個盤子從AB 1.3 C座上一個盤子從CB 第二步進一步分解: A座上最后一個盤子從AC 第三步進一步分解: 3.1 B座上一個盤子從BA 3.2 B座上一個盤子從BC 3.3 A座上一個盤子從AC,結論: 13步都是把n-1個盤子從一個座移到另一個座上,方法一樣,只是座的名稱不同而已,為使之一般化,將13步表示為:將one 座上的n-1個盤子移到two座,借助 three座,只是對應關系不同。 第一步對應關系:one A two B three C 第三步對應關系: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”,運行: 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 數組作為函數參數 函數調用形式一:函數名(數組名)實參或形參 函數調用形式二:函數名(數組元素)實參 數組名作為參數:傳遞的是數組的首地址; 數組元素作實參時:傳遞的是數組元素的值, 是單向的值傳送。,8.7 數組作為函數參數 函數調用形式一:函數名(數組名)實參或形參 函數調用形式二:函數名(數組元素)實參 數組名作為參數:傳遞的是數組的首地址; 數組元素作實參時:傳遞的是數組元素的值, 是單向的值傳送。,數組元素作函數實參值傳遞,例 兩個數組大小比較,n=0 m=0 k=0,a和b為有10個元素的整型數組 比較兩數組對應元素 變量n,m,k記錄aibi, ai=bi, aik,認為數組ab 若nk,認為數組ab 若n=k,認為數組a=b,2、數組名作為函數實參 此時,傳送的是數組的地址,調用函數時,對形參數組元素的操作,實際上也是對實參數組元素的操作。 *地址傳遞 *在主調函數與被調函數分別定義數組,且類型應一致,例 求學生的平均成績,#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; ,實參用數組名,形參用數組定義, int stu ,幾點說明: 1.數組名作形、實參數時,應分別在主、被調函數中對其定義 2.數組名作參數時,傳遞的是地址,對形參數組的操作實際 上也是對實參數組的操作。兩個數組是共用同一個內存單元則形參中的數據變化了實參也會變化這與變量做形參區別很大 3.作為形、實參數的數組,其類型要一致,大小一般相等,以保證形式上的對應; 4.當形參數組大小未指定時,用一實參將數組長度傳遞給形 參以便對數組進行操作; 5、字符串的傳遞同數組的傳遞字符串是用數組存儲的,例8-12.c 求兩組學生的平均成績,形參數組長度缺省 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,例 數組元素與 數組名 作函數參數比較,#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); ,地址傳遞,例 數組元素與 數組名 作函數參數比較,例 數組排序-簡單選擇排序(請同學們自行思考),9,49,i=0,例 數組排序-簡單選擇排序,13,68,i=1,i=8,例 數組排序-簡單選擇排序,例 求二維數組中最大元素值,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); ,例 求二維數組中各行元素之和,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 局部變量 變量:按其作用域,可分為局部和全局 局部:作用域僅限于其所定義的函數或復合語句內部,離開該函數或復合語句則釋放內存單元 特點: (1)在不同的函數中允許同名,它們占據不同的內存單元, 相互之間互不影響。 (2)形參屬局部變量,只能在其所在的函數內部使用。,例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); ,運行結果: 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 復合語句中局部變量的例子 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) ; ,運行結果: a=1, b=2, c=-1 a=1, b=2, c=3,8.8.2 全局變量 全局變量:在一個文件的所有函數以外定義的變量稱為外部或全局變量。 作用域:從定義變量的位置開始到源程序結束。所有該源文件中的函數公用,幾點說明,在源程序開始定義的全局變量,對源程序中所有函數有效 在源程序中間定義的全局變量,僅對其后面的所有函數有效,幾點說明2,在函數或復合語句中定義的局部變量若與全局變量同名,當該函數或復合語句被執行時,則局部變量優先,全局變量不起作用(被屏蔽)。,例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); ,運行: 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,幾點說明3,全局變量的使用,增加了函數間數據聯系的渠道,同一文件中的所有函數都能引用全局變量的值,當某函數改變了全局變量的值時,便會影響其它的函數。,例T8-15.c 用一維數組存放10個學生的成績,在函數中求最高分、最低分和平均值。 float max=0, min=0; (習慣上: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”, 一個函數可以返回3個值了!,運行: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)函數可移植性差 2.程序可讀性差,且一旦外部變量被改變將影響所有函數,int i; main() void prt(); for(i=0;i5;i+) prt(); void prt() for(i=0;i5;i+) printf(“%c”,*); printf(“n”); ,例 外部變量副作用,運行結果:*,變量的存儲屬性 概述 每個變量有兩個基本屬性:變量的數據類型!那么,變量的存儲類型呢?,編譯或函數調用時為其分配內存單元,10,程序中使用變量名對內存操作,變量的屬性 數據類型:變量所持有的數據的性質(操作屬性) 存儲屬性 存儲器類型:寄存器、靜態存儲區、動態存儲區 生存期:變量在某一時刻存在-靜態變量與動態變量 作用域:變量在某區域內有效-局部變量與全局變量 變量的存儲類型 auto -自動型 register-寄存器型 static -靜態型 extern -外部型 變量定義格式: 存儲類型 數據類型 變量表;,如: int sum; auto int a,b,c; register int i; static float x,y;,程序運行時,在內存中的存儲情況: (1)靜態存儲方式:即程序運行期間為其分配的存儲單元是固定的。直到文件執行完 (2)動態存儲方式:程序運行期間根據需要為其分配存儲單元。用完就釋放,格式:auto int a; 說明符“auto”可以省略。 auto float pi; 說明: 1.說明自動變量必須在一個函數體的內部。 2.函數的形參也是自動變量。,作用域 函數內部,實質上是一個局部變量。只有在函數被調用時才存在,從函數中返回時即消失,其值僅限于說明它的函數。 由于自動變量具有局部性,所以在兩個不同的函數中可以分別使用同名的變量而互不影響。,自動變量auto,8.9.2 auto變量 函數內部無static聲明的局部量均為動態存儲類別,被

溫馨提示

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

最新文檔

評論

0/150

提交評論