




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第四章 函數(shù) 概述 函數(shù)的定義 函數(shù)參數(shù)及函數(shù)返回值 函數(shù)的調(diào)用 函數(shù)的嵌套與遞歸調(diào)用 變量存儲(chǔ)類型、生存期和作用域 編譯預(yù)處理模塊化程序設(shè)計(jì)基本思想:將一個(gè)大的程序按功能分割成一些小模塊,C語言中模塊的功能用函數(shù)來實(shí)現(xiàn)。特點(diǎn):各模塊相對(duì)獨(dú)立、功能單一、結(jié)構(gòu)清晰、接口簡單控制了程序設(shè)計(jì)的復(fù)雜性,提高了可讀性縮短了程序開發(fā)周期,避免程序開發(fā)的重復(fù)勞動(dòng)程序易于維護(hù)和功能擴(kuò)充開發(fā)方法:自上向下,逐步分解,分而治之概 述 C語言是函數(shù)式語言 必須有且只能有一個(gè)名為main的主函數(shù) C程序的執(zhí)行總是從main函數(shù)開始,在main中結(jié)束 函數(shù)不能嵌套定義,可以嵌套調(diào)用概述:C程序結(jié)構(gòu)C程序源程序文件1源程
2、序文件i源程序文件n預(yù)處理命令函數(shù)1函數(shù)n聲明部分執(zhí)行部分#includeint max(int x,int y) int max; if(xy) max=x; else max=y; return max;void main() int a,b,c; scanf(“%d,%d”,&a,&b); c=max(a,b); printf(“Max=%d”,c);概述:C程序結(jié)構(gòu)【例】簡單函數(shù)的例子:從鍵盤輸入兩個(gè)整數(shù),求較大的整數(shù)。#includevoid main() int a,b,max; scanf(“%d,%d”,&a,&b); if(ab) max=a; else max=b; pri
3、ntf(“Max=%d”,max);運(yùn)行結(jié)果:14,8Max=14主函數(shù)main()c=max(a,b);函數(shù)max()return max執(zhí)行執(zhí)行執(zhí)行函數(shù)類型 函數(shù)名(形參表及類型) 數(shù)據(jù)描述(變量聲明) 數(shù)據(jù)處理(執(zhí)行語句)一般格式現(xiàn)代風(fēng)格:例: 有參函數(shù)(現(xiàn)代風(fēng)格) int max(int x,int y) int z; z=xy?x:y; return(z);/ return z; 例: 有參函數(shù)(現(xiàn)代風(fēng)格) int max(int x, y) int z; z=xy?x:y; return(z); 例:空函數(shù)void input( ) 例:無參函數(shù) void line( ) prin
4、tf(“*n”); 或 void line(void ) printf(“*n”); 函數(shù)的定義返回值類型,缺省為int型或char,無返回值void函數(shù)體注意:此處無;注意:此處括號(hào)不能省略函數(shù)類型 函數(shù)名(形參表)形參類型說明 變量聲明 執(zhí)行語句傳統(tǒng)風(fēng)格:例: 有參函數(shù)(傳統(tǒng)風(fēng)格) int max(x,y) int x,y; int z; z=xy?x:y; return(z); 函數(shù)的定義例: 有參函數(shù)(錯(cuò)誤) int max(int x,y) int y; int z; z=xy?x:y; return(z); 格式不能混用!注意:VC環(huán)境不支持【例】求整數(shù)的最大公因子int gcd(
5、int u, int v) int tmp; while(v!=0) tmp=u%v; u=v; v=tmp; return u;函數(shù)的參數(shù)與傳遞main() int x=145,y=25,z; z=gcd(x,y); printf(“The GCD of %d and %d is %dn”,x,y,z); x=16; y=24; printf(“The GCD of %d and %d is %dn”,x,y,gcd(x,y); z=gcd(x,x+y); printf(“The GCD of %d and %d is %dn”,x,x+y,z);函數(shù)的參數(shù)與傳遞【例】求三個(gè)數(shù)的最大值/ E
6、xam.cpp#includeint max (int x,int y) /自定義有參函數(shù),求兩個(gè)數(shù)的較大值return xy?x:y;void line(void) /自定義無參函數(shù),實(shí)現(xiàn)輸出一行“*”號(hào)int i;for(i=1;i40;i+) printf(*);printf(n); void main(void)int a,b,c;int m;printf(請(qǐng)輸入三個(gè)整數(shù): );scanf(%d,%d,%d,&a,&b,&c);m=max(a,b); /有參數(shù)調(diào)用,實(shí)參分別是a,bm=max(c,m); /有參數(shù)調(diào)用,實(shí)參分別是c,mline(); /無參函數(shù)調(diào)用printf(%d,%
7、d和%d中的最大數(shù)為:%dn,a,b,c,m);line(); 說明: 實(shí)參必須有確定的值,可以是常量、變量或表達(dá)式 形參必須指定類型 形參與實(shí)參類型一致,個(gè)數(shù)相同 若形參與實(shí)參類型不一致,自動(dòng)按形參類型轉(zhuǎn)換-函數(shù) 調(diào)用轉(zhuǎn)換 形參在函數(shù)被調(diào)用前不占內(nèi)存,函數(shù)調(diào)用時(shí)為形參分配 內(nèi)存,調(diào)用結(jié)束時(shí),形參內(nèi)存釋放 實(shí)參對(duì)形參的數(shù)據(jù)傳遞是“值傳遞”,即單向傳遞。函數(shù)的參數(shù)與傳遞函數(shù)的參數(shù)與傳遞【例】實(shí)參與形參不匹配#includevoid test(float a,int b) printf(%f,%dn,a,b);void main( ) int x=3,y=2; float z=9.4; print
8、f(%d,%dn,x,y); test( );/無實(shí)參調(diào)用,編譯錯(cuò)誤 test(x,y);/實(shí)參的類型不匹配,會(huì)自動(dòng)轉(zhuǎn)換,但容易引起錯(cuò)誤 test(z,y,x);/實(shí)參個(gè)數(shù)不匹配,編譯錯(cuò)誤 test(float)x,y);/正確調(diào)用參數(shù)傳遞方式:值傳遞方式:函數(shù)調(diào)用時(shí),為形參分配單元,并將實(shí)參的值復(fù)制到形參內(nèi)存中;調(diào)用結(jié)束,形參單元被釋放,實(shí)參單元仍保留并維持原值特點(diǎn):形參與實(shí)參占用不同的內(nèi)存單元實(shí)參向形參傳遞次序依不同系統(tǒng)而定單向傳遞,即形參值的改變不會(huì)影響實(shí)參的值函數(shù)的參數(shù)與傳遞711x:y:調(diào)用前:調(diào)用結(jié)束:711x:y:【例】單向值傳遞 #include void swap(int a
9、,int b) int t; t=a; a=b; b=t; void main() int x=7,y=11; printf(x=%d,y=%dn,x,y); printf(swapped:n); swap(x,y); printf(x=%d,y=%dn,x,y);調(diào)用:711a:b:711x:y:swap:711x:y:117a:b:t函數(shù)的參數(shù)與傳遞運(yùn)行結(jié)果:x=7, y=11swapped:x=7, y=11函數(shù)返回值說明:函數(shù)中可有多個(gè)return語句,執(zhí)行哪個(gè)return,哪個(gè)語句 起作用;若無return語句,遇時(shí),自動(dòng)返回主調(diào)函數(shù)若函數(shù)類型與return語句中表達(dá)式值的類型不一致
10、,按 前者為準(zhǔn),自動(dòng)轉(zhuǎn)換-函數(shù)調(diào)用轉(zhuǎn)換無返回值函數(shù):void函數(shù)返回值【例】存在多個(gè)return語句#include void main() int max(int x,int y); /函數(shù)聲明 int a,b,c; scanf(%d,%d,&a,&b); c=max(a,b); printf(Max is %dn,c);int max(int x, int y) if(xy) return x; else return y;說明:xy:返回xxy:返回y函數(shù)調(diào)用:在一個(gè)函數(shù)中引用另一個(gè)函數(shù)說明:主函數(shù)main()只能被系統(tǒng)調(diào)用。調(diào)用無參函數(shù)時(shí),實(shí)參表可以沒有,但括號(hào)不能省略。如line(
11、)實(shí)參與形參個(gè)數(shù)相等,類型匹配,按順序一一對(duì)應(yīng)各參數(shù)用逗號(hào)分隔,實(shí)參向形參傳遞順序,因系統(tǒng)而定(VC 自左向右)函數(shù)的調(diào)用函數(shù)名(實(shí)參表);void func(int a;int b) /*函數(shù)定義*/void main() int a=2,b=1; func(a,b); /*函數(shù)調(diào)用*/函數(shù)的調(diào)用【例】實(shí)參傳值的順序#includeint f(int a,int b) int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return c;void main() int i=2,p; p=f(i,+i); printf(“%dn”,p);運(yùn)行結(jié)果:T
12、urbo C環(huán)境運(yùn)行結(jié)果:VC環(huán)境-f(3,3)f(2,3)語句調(diào)用: 例 : line(); printf(“Hello,World!n”);表達(dá)式調(diào)用: 例: m=max(a,b)*2;函數(shù)參數(shù)調(diào)用: 例: printf(“%d”,max(a,b); m=max(a,max(b,c);函數(shù)的調(diào)用方式對(duì)被調(diào)用函數(shù)要求:必須是已存在的函數(shù)使用庫函數(shù),用#include將所需的信息包含到本文件中。 #include 用戶自定義函數(shù): 若函數(shù)位置在主調(diào)函數(shù)后面,必須在主調(diào)函數(shù)中對(duì)該函數(shù)進(jìn)行聲明。主調(diào)函數(shù)和被調(diào)函數(shù)的相對(duì)位置被調(diào)用函數(shù)聲明與函數(shù)原型 函數(shù)聲明形式:作用:告訴編譯系統(tǒng)函數(shù)類型、參數(shù)個(gè)數(shù)
13、及類型,以便檢驗(yàn)函數(shù)定義與函數(shù)聲明不同。函數(shù)聲明位置:程序的數(shù)據(jù)說明部分(函數(shù)內(nèi)或外)若被調(diào)用函數(shù)定義出現(xiàn)在主調(diào)函數(shù)之前,可不作函數(shù)聲明。有些系統(tǒng)要求函數(shù)說明指出函數(shù)返回值類型和形參類型,并且對(duì)void和int型函數(shù)也要進(jìn)行函數(shù)說明。函數(shù)類型 函數(shù)名(類型1,類型2);或函數(shù)類型 函數(shù)名(類型 參數(shù)1,類型 參數(shù)2);必須有分號(hào)可以只寫明類型main() int max(int,int); /函數(shù)聲明int max(int x , int y) /函數(shù)定義#include long sum(int a, int b); long factorial(int n);void main() int
14、 n1,n2; long a; scanf(%d,%d,&n1,&n2); a=sum(n1,n2); printf(a=%1d,a);long sum(int a,int b) long c1,c2; c1=factorial(a); c2=factorial(b); return(c1+c2); long factorial(int n) long rtn=1; int i; for(i=1;i=n;i+) rtn*=i; return(rtn); long sum(int a, int b);long factorial(int n);函數(shù)調(diào)用函數(shù)調(diào)用被調(diào)用函數(shù)聲明與函數(shù)原型函數(shù)聲明函數(shù)
15、定義若被調(diào)函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之后,必須在主調(diào)函數(shù)或文件中對(duì)被調(diào)函數(shù)進(jìn)行聲明?!纠亢瘮?shù)調(diào)用示例 計(jì)算:A(x,y)=#include#includedouble fun(double f) double f2=f*f+sqrt(1+2*f+3*f*f); return (sqrt(f2);main () int x,y; double f1,fun(double ); scanf(“%d,%d”,&x,&y); f1=x*x/fun(exp(x-y); printf(A(x,y)=%fn,f1);被調(diào)用函數(shù)聲明與函數(shù)原型嵌套調(diào)用C規(guī)定:函數(shù)定義不可嵌套,但可以嵌套調(diào)用函數(shù)函數(shù)的嵌套調(diào)用m
16、ain( )調(diào)用函數(shù)a結(jié)束a函數(shù)b函數(shù)調(diào)用函數(shù)b兩層嵌套示例錯(cuò)誤,函數(shù)的嵌套定義main() int max(int x,int y) return(xy?x:y); 遞歸調(diào)用:函數(shù)直接或間接的調(diào)用自身。int f(int x) int y,z; z=f(y); . return(2*z);int f1(int x) int y,z; z=f2(y); . return(2*z);int f2(int t) int a,c; c=f1(a); . return(3+c);函數(shù)的遞歸調(diào)用f( )調(diào)f調(diào)f2調(diào)f1f1( )f2( )說明: C編譯系統(tǒng)對(duì)遞歸函數(shù)的自調(diào)用次數(shù)沒有限制。 每調(diào)用函數(shù)一次
17、,在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù) 變量、返回值等信息,所以遞歸次數(shù)過多,可能引起堆 棧溢出。 程序中應(yīng)避免無終止的遞歸調(diào)用(有遞歸出口)函數(shù)的遞歸調(diào)用【例】有5個(gè)人坐在一起,問第5個(gè)人多少歲?他說比第4個(gè)人大2歲。問第4個(gè)人的歲數(shù),他說比第3個(gè)人大2歲。而第3個(gè)人,又比第2個(gè)人大2歲,第2個(gè)人又比第1個(gè)人大2歲。已知第1個(gè)人10歲。求第5個(gè)人的年齡。遞推回歸遞歸結(jié)束的條件函數(shù)的遞歸調(diào)用#includeint age(int n) int c; if(n=1) c=10; else c=age(n-1)+2; return c;void main() printf(“The fifth pe
18、ople is %d years old.”,age(5);運(yùn)行結(jié)果:The fifth people is 18 years old.遞歸結(jié)束條件if遞歸調(diào)用(4次)函數(shù)調(diào)用main()遞 推回 歸c=age(5)age(5)c=age(4)+2age(4)c=age(3)+2age(3)c=age(2)+2age(2)c=age(1)+2結(jié)束結(jié)束結(jié)束結(jié)束結(jié)束0函數(shù)的遞歸調(diào)用age(1)c=10結(jié)束1234#include int fac(int n) int f; if(n0) printf(n0,data error!); else if(n=0|n=1) f=1; else f=fac
19、(n-1)*n; return(f);main() int n, y; printf(Input a integer number:); scanf(%d,&n); y=fac(n); printf(%d! =%10d,n,y);【例】求n的階乘函數(shù)的遞歸調(diào)用運(yùn)行結(jié)果:Input a integer number:88!= 40320main() int i,s=1; for(i=1;i=10;i+) s=s*i;函數(shù)的遞歸調(diào)用【例】漢諾塔問題 設(shè)計(jì)一個(gè)移動(dòng)盤子的程序,使塔A上的所有盤子借助塔B移到塔C上。要求: 一次只能移動(dòng)一個(gè)盤子; 任何時(shí)候不能把大盤子放在比它小的盤子上面。ABCABC初
20、始結(jié)果(1)從A移動(dòng)1n-1號(hào)圓盤至B,C作輔助;(遞歸調(diào)用)分析此問題可歸之于三個(gè)子問題(2)從A移動(dòng)n號(hào)圓盤至C;(一次搬運(yùn))(3)從B移動(dòng)1n-1號(hào)圓盤至C,A作輔助。(遞歸調(diào)用)ABC1n-1nABC(1)n1n-1ABC(2)n1n-1ABC(3)n1n-1函數(shù)的遞歸調(diào)用分析如下:首先,分析如何將A柱上3個(gè)盤子移到C柱上的過程;1)將A柱上2個(gè)盤子移到B柱上(借助C);2)將A柱上1個(gè)盤子移到C柱上;3)將B柱上2個(gè)盤子移到C柱上(借助A).其中2)可以直接實(shí)現(xiàn)。其中1)可用遞歸方法分解:1.1將A上1個(gè)盤子從A移到C;1.2將A上1個(gè)盤子從A移到B;1.3將C上1個(gè)盤子從C移到B。
21、其中3)分解為3.1將B上1盤子從B移到A上;3.2將B上1盤子從B移到C上;3.3將A上1盤子從A移到C上。函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用【例】漢諾塔問題#includevoid hanio(int num,char A,char B,char C) if(num0) hanio(num-1,A,C,B); printf(“移動(dòng)第%d個(gè)盤:從%c柱到%c柱n”,num,A,C); hanio(num-1,B,A,C);void main() int num; printf(“please input the number of plate(0):”); scanf(“%d”,&num); ha
22、nio(num,A,B,C);運(yùn)行結(jié)果:Please input the number of plate:3移動(dòng)第1個(gè)盤:從A柱到C柱移動(dòng)第2個(gè)盤:從A柱到B柱移動(dòng)第1個(gè)盤:從C柱到B柱移動(dòng)第3個(gè)盤:從A柱到C柱移動(dòng)第1個(gè)盤:從B柱到A柱移動(dòng)第2個(gè)盤:從B柱到C柱移動(dòng)第1個(gè)盤:從A柱到C柱函數(shù)的遞歸調(diào)用讀程序,寫結(jié)果#includevoid f(int x) if(x%3!=0) f(x/3); printf(%dt,x); main( ) f(5); printf(end); 運(yùn)行結(jié)果:0 1 5 endf(5)f(1)f(1)f(0)f(0)遞推結(jié)束打印 x打印 x打印 xmain()f(
23、5)打印”end”變量存儲(chǔ)類型、生存期和作用域變量的數(shù)據(jù)類型規(guī)定了變量的存儲(chǔ)空間大小和取值范圍; (已介紹)變量的存儲(chǔ)類型規(guī)定了變量的生存期和作用域。變量的存儲(chǔ)類型有4個(gè),分別是自動(dòng)型、寄存器型、外部型和靜態(tài)型,其說明符分別是auto、register、extern和static。 變量定義格式: 存儲(chǔ)類型 數(shù)據(jù)類型 變量表;如: int sum; auto int a,b,c; register int i; static float x,y; 存儲(chǔ)類型:變量存儲(chǔ)類型、生存期和作用域生存期,就是變量存活的周期。 一是變量從程序開始定義就被分配內(nèi)存(即產(chǎn)生),直 到程序運(yùn)行結(jié)束內(nèi)存釋放,這種變
24、量稱為靜態(tài)變量;二是變量帶有臨時(shí)性,隨調(diào)用的模塊(如文件、函數(shù)或 復(fù)合語句)分配內(nèi)存單元,模塊調(diào)用結(jié)束,釋放內(nèi)存, 這種變量稱為動(dòng)態(tài)變量。作用域,就是某個(gè)變量在其生命期內(nèi),程序模塊是否可使用該變量。一種變量在從定義點(diǎn)開始或整個(gè)源程序都可有效,稱為全局變量;另一種變量只能在所定義的模塊內(nèi)部有效,稱為局部變量。局部變量-內(nèi)部變量定義:在模塊內(nèi)定義,只在本模塊內(nèi)有效說明:main中定義的變量只在main中有效,各函數(shù)不能使用其他函數(shù)中定義的變量。不同函數(shù)中的同名局部變量,占不同內(nèi)存單元形參屬于局部變量復(fù)合語句中定義的局部變量只在該復(fù)合語句中有效局部變量可用存儲(chǔ)類型:auto、register、sta
25、tic (默認(rèn)為auto)float f1(int a) int b,c; .char f2(int x,int y) int i,j; main() int m,n; .a,b,c有效x,y,i,j有效m,n有效/定義在復(fù)合語句中的變量#includemain() int x=1,y=2; /復(fù)合語句中定義 int x=10; x=x+10; printf(“x=%d,”,x); printf(“y=%d,”,y); x=x+9; printf(“x=%dn”,x);/不同函數(shù)中的同名變量sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b);
26、main() int a,b; a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);運(yùn)行結(jié)果:main:a=3,b=4sub:a=6,b=7main:a=3,b=4變量的作用域-局部變量 復(fù)合語句中x的作用域 sub中的a、b作用域 main中的a、b作用域 main中x、y的作用域運(yùn)行結(jié)果:x=20,y=2,x=10全局變量-外部變量定義:在函數(shù)外定義,可為本文件中所有函數(shù)共用有效范圍:從定義變量的位置開始到本源文件結(jié)束,及有extern說明的其它源文件說明:外部變量可用存儲(chǔ)類型:缺省 或 sta
27、tic若外部變量與局部變量同名,則外部變量被屏蔽變量的作用域-全局變量/全局變量的作用域 int p=1,q=5; /*全局變量*/float f1(int a) int b,c; char c1,c2; /*全局變量*/char f2(int x, int y) int i,j; void main() int m,n;c1,c2的作用范圍p,q的作用范圍/外部變量被屏蔽#include int a=3,b=5;max(int a, int b) int c; c=ab?a:b; return(c);main() int a=8; /與外部變量同名 printf(max=%d,max(a,b
28、);運(yùn)行結(jié)果:max=8變量的作用域-全局變量變量的作用域-全局變量【例】外部變量的使用#includeint x;void add(void) x=x+5; printf(“add_x=%dn”,x);void sub(void) x=x-2; printf(“sub_x=%dn”,x);void main() add(); sub(); printf(“外部_x=%dn”,x);未初始化的外部變量,系統(tǒng)賦初值為0運(yùn)行結(jié)果: add_x=5 sub_x=3 外部_x=3變量的作用域-全局變量【例】外部變量的使用#includeint x1=30 , x2=40;sub(int x , int
29、 y) x1=x; x=y; y=x1;void main() int x3=10 , x4=20; sub(x3,x4); sub(x2,x1); printf(“%d,%d,%d,%d”,x3,x4,x1,x2);運(yùn)行結(jié)果: 10 ,20 ,40 ,40變量的作用域-全局變量應(yīng)盡量少使用全局變量: 全局變量在程序全部執(zhí)行過程中占用存儲(chǔ)單元 降低了函數(shù)的通用性、可靠性,可移植性 降低程序清晰性,且容易出錯(cuò)靜態(tài)變量與動(dòng)態(tài)變量存儲(chǔ)方式靜態(tài)存儲(chǔ):程序運(yùn)行期間分配固定存儲(chǔ)空間動(dòng)態(tài)存儲(chǔ):程序運(yùn)行期間根據(jù)需要?jiǎng)討B(tài)分配存儲(chǔ)空間生存期靜態(tài)變量:從程序開始執(zhí)行到程序結(jié)束動(dòng)態(tài)變量:從包含該變量定義的模塊開始執(zhí)行
30、至模塊執(zhí)行結(jié)束全局變量、靜態(tài)變量外部變量形參變量局部變量程序區(qū)靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)變量 auto變量 數(shù)據(jù):函數(shù)中的形參和函數(shù)中定義的變量。 動(dòng)態(tài)存儲(chǔ)方式:調(diào)用函數(shù)時(shí)分配空間,函數(shù)執(zhí) 行結(jié)束釋放。 聲明: int f(int a) auto int b,c=3; 等價(jià)于:int b,c=3; (auto可省略)動(dòng)態(tài)變量 register變量作用:減少頻繁使用變量的存取開銷。/輸出1!到n!的值#include void main() long fac(long); long i,n; scanf(“%ld”,&n); for(i=1;i=n;i+) printf(“%ld!=%ldn“,i
31、,fac(i);long fac(long n) register long i,f=1; for(i=1;i=n;i+) f=f*i; return(f);運(yùn)行結(jié)果:51!12!23!64!245!120動(dòng)態(tài)變量說明: 只有局部自動(dòng)變量和形式參數(shù)可以作為寄存器變量 寄存器變量數(shù)目有限 局部靜態(tài)變量不能定義為寄存器變量 錯(cuò)誤:register static int a,b,c; 一般優(yōu)化的編譯系統(tǒng)能識(shí)別使用頻繁的變量,并將 其放入寄存器,不需要程序設(shè)計(jì)者指定。靜態(tài)變量 static變量 靜態(tài)存儲(chǔ)方式:編譯時(shí)分配空間,整個(gè)程序運(yùn)行過程中 有效。 靜態(tài)局部變量: 限于本函數(shù)(或復(fù)合語句中)使用,函
32、數(shù)調(diào)用后仍可保留空間,其值可用于下次調(diào)用時(shí)繼續(xù)使用。(其值具有可繼承性) 靜態(tài)外部變量: 外部變量只限于本文件使用。靜態(tài)變量#includevoid main() void increment(void); increment(); increment(); increment();void increment(void) int x=0; /auto x+; printf(“%dn”,x); #includevoid main() void increment(void); increment(); increment(); increment();void increment(void)
33、static int x=0; /static x+; printf(“%dn”,x); 運(yùn)行結(jié)果: 1 1 1運(yùn)行結(jié)果: 1 2 3【例】static聲明為局部變量【例】static聲明為局部變量#includevoid main() int f(int); /函數(shù)聲明 int a=2,i; for(i=0;i3;i+) printf(“%dt”, f(a);int f(int a) auto int b=0; /局部變量 static int c=3; /靜態(tài)局部變量 b=b+1; c=c+1; return(a+b+c);運(yùn)行結(jié)果:7 8 9調(diào)用次數(shù)調(diào)用初值調(diào)用結(jié)束值bcbca+b+c1
34、03147204158305169注意: 靜態(tài)局部變量:局限于變量所在 的模塊; 每次函數(shù)調(diào)用時(shí),其初值是上次 調(diào)用結(jié)束時(shí)的值;靜態(tài)變量說明: 靜態(tài)局部變量屬于靜態(tài)存儲(chǔ)類別,其存儲(chǔ)單元在整個(gè)程序 運(yùn)行期間不釋放。自動(dòng)變量屬于動(dòng)態(tài)存儲(chǔ)類別。 靜態(tài)局部變量在編譯時(shí)賦初值,即只賦初值一次。每次函 數(shù)調(diào)用時(shí)不再重新賦初值,而是保留上次函數(shù)調(diào)用結(jié)束時(shí) 的值。自動(dòng)變量每次執(zhí)行函數(shù)調(diào)用時(shí),重新賦初值。 靜態(tài)局部變量未賦初值時(shí),編譯時(shí)自動(dòng)賦初值0或空字符 。自動(dòng)變量則是不確定的值。 靜態(tài)局部變量只限于定義它的函數(shù)使用,其它函數(shù)不能引 用。靜態(tài)變量【例】static聲明為外部變量/*File1.c*/stati
35、c int a;void main() /*File2.c*/extern int a;void fun(int n) a=a*n; 錯(cuò)誤:a只能用于本文件(file1.c)中靜態(tài)變量靜態(tài)變量static unsigned int r; /static外部變量random(void) r=(r*123+59)%65535; return (r);/*產(chǎn)生r的初值*/unsigned radom_start(unsigned int seed) r=seed;【例】產(chǎn)生一個(gè)隨機(jī)數(shù)序列main() int i,n; printf(“please enter the seed:”); scanf(“
36、%d”,&n); random_start(n); for(i=1;i10;i+) printf(“%u”,random();外部變量 用extern聲明外部變量 非變量定義,而是用于擴(kuò)展外部變量的作用域 應(yīng)用:在一個(gè)文件內(nèi)聲明外部變量在多個(gè)文件的程序中聲明外部變量 聲明方式:extern 數(shù)據(jù)類型 變量名; 如:extern a; 或 extern int a;c1,c2的作用范圍p,q的作用范圍extern char c1,c2;extern char c1,c2; 外部變量定義與聲明(extern)擴(kuò)展后的c1,c2的作用范圍擴(kuò)展后的c1,c2的作用范圍int p=1,q=5; floa
37、t f1(int a) int b,c; .int f3().char c1,c2; char f2(int x,int y) int i,j; main() int m,n; .#includeint max(int x, int y) int z; z=xy?x:y; return(z);main() extern int a,b; /聲明外部變量 printf(max=%d,max(a,b);int a=13,b=-8; /定義外部變量運(yùn)行結(jié)果:max=13#includeextern int a,b;int max() int z; z=ab?a:b; return(z);main()
38、 printf(max=%d,max();int a=13,b=-8;【例】外部變量定義與說明外部變量定義與聲明(extern)注意: 若在外部變量定義點(diǎn)之前引用該變量,必須在引用前用 extern對(duì)該變量作出聲明。 聲明后,作用域從“聲明”處起有效。外部變量定義與聲明(extern)【例】用extern將外部變量的作用域擴(kuò)展到其他文件/file1.c#include void main() int power(int); int b=3,c,d,m; printf(“enter the number a and its power m:n”); scanf(“%d,%d”,&A,&m); c
39、=A*b; printf(“%d*%d=%dn”,A,b,c); d=power(m); printf(“%d*%d=%dn”,A,m,d);/file1.c#include #includeextern int a; /擴(kuò)展file2中的a的作用域void main() int power(int); /函數(shù)聲明 int b=3,c,d,m; printf(“enter the number a and its power m:n”); scanf(“%d,%d”,&a,&m); c=a*b; printf(“%d*%d=%dn”,a,b,c); d=power(m); printf(“%d
40、*%d=%dn”,a,m,d);/file2.cint a; /外部變量定義int power( int n) int i,y=1; for(i=1;i=n;i+) y*=a; return(y);運(yùn)行結(jié)果:enter the number a and its power m5,35*3=155*3=125外部變量定義與聲明(extern)【例6-18】外部變量的副作用示例。/Exam6-18.cpp#includeint i;/定義外部變量i/-void output(void)for(i=1;i5;i+) putchar(*);/-void main(void)for(i=1;i6;i+)
41、 output();/= 運(yùn)行結(jié)果:*【例】外部變量的副作用示例。/Exam.cpp#includeint i;/定義外部變量i/-void output(void)for(i=1;i5;i+) putchar(*);/-void main(void)for(i=1;i6;i+) output();/= 運(yùn)行結(jié)果:*若此處i6改為i7,程序結(jié)果會(huì)是怎樣?變量存儲(chǔ)類型【例】靜態(tài)外部變量與外部變量的區(qū)別示例。/file1.cpp#include/-int x=2;/定義外部變量xstatic int y=3;/定義靜態(tài)外部變量y/-void func( )x+;y+;printf(“x=%d,y=
42、%dn,x,y);/=/file2.cpp#include/-extern int x;/擴(kuò)展文件file1中的外部變量x的作用域int y;/外部變量/-void main() void func(); /函數(shù)聲明func(); / 函數(shù)調(diào)用printf(“x=%d,y=%dn,x,y);/=運(yùn)行結(jié)果:x=3,y=4x=3,y=0注意: 靜態(tài)外部變量只能在定義的文件中使用,具有局部可見性。 外部變量可以被其他文件使用,具有全局性。#include int i=1;main() static int a; register int b=-10; int c=0; void other(); p
43、rintf(-MAIN-n); printf(i:%d a:%d b:%d c:%dn,i,a,b,c); c=c+8; other(); printf(-MAIN-n); printf(i:%d a:%d b:%d c:%dn,i,a,b,c); i=i+10; other();void other() static int a=2; static int b; int c=10; a=a+2; i=i+32; c=c+5; printf(-OTHER-n); printf(i:%d a:%d b:%d c:%dn,i,a,b,c); b=a;運(yùn)行結(jié)果:-Main-i:1 a:0 b:-10
44、 c:0 -Other-i:33 a:4 b:0 c:15 -Main-i:33 a:0 b:-10 c:8-Other-i:75 a:6 b:4 c:15變量存儲(chǔ)類型變量存儲(chǔ)類型 外部變量的作用域可以在不同的函數(shù)中多次擴(kuò)展,但 外部變量的定義在一個(gè)源程序中只能定義一次,可以 定義時(shí)進(jìn)行初始化 外部變量和局部變量在同一個(gè)模塊中有效時(shí),同名的 外部變量被屏蔽 靜態(tài)外部變量和外部變量定義時(shí)如果沒有賦初值,數(shù) 值型變量默認(rèn)為0,字符型為空字符靜態(tài)動(dòng)態(tài)存儲(chǔ)方式程序整個(gè)運(yùn)行期間函數(shù)調(diào)用開始至結(jié)束生存期編譯時(shí)賦初值,只賦一次每次函數(shù)調(diào)用時(shí)賦初值自動(dòng)賦初值0或空字符不確定未賦初值靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)區(qū)存儲(chǔ)區(qū)寄存器
45、局部變量全局變量作用域定義變量的函數(shù)或復(fù)合語句內(nèi)本文件其它文件register局部staticauto外部staticextern存儲(chǔ)類別變量存儲(chǔ)類型小結(jié)變量存儲(chǔ)類型小結(jié)#includeint fun(int x,int y) static int m=0,i=2; i+=m+1; m=i+x+y; return m; void main() int j=4,m=1,k; k=fun(j,m); printf(%d,k); k=fun(j,m); printf(%dn,k); 讀程序,寫結(jié)果結(jié)果:8,17函數(shù)的存儲(chǔ)類別內(nèi)部函數(shù)(又稱為靜態(tài)函數(shù)) :只能被本文件中的其它函數(shù)調(diào)用,而不能被同一源程
46、序中其它文件中的函數(shù)調(diào)用,這種函數(shù)稱為內(nèi)部函數(shù)。外部函數(shù):在定義函數(shù)時(shí),如果沒有加關(guān)鍵字“static”,或冠以關(guān)鍵字“extern”,表示此函數(shù)是外部函數(shù):說明此函數(shù)可以被同源文件中的其它文件調(diào)用。static 函數(shù)類型 函數(shù)名(形參列表) 函數(shù)體 static的含義不是指存儲(chǔ)方式,而是限定函數(shù)的作用域于本文件中。 extern 函數(shù)類型 函數(shù)名(形參列表) 函數(shù)體 編譯預(yù)處理 宏定義 文件包含 條件編譯第八章編譯預(yù)處理命令作用:不是C語言的組成部分,對(duì)源程序編譯之前做一些預(yù)處理,生成擴(kuò)展C源程序。種類宏定義 #define文件包含 #include條件編譯 #if-#else-#endif
47、 等格式:“#”開頭(區(qū)別于其它C語句)單獨(dú)占書寫行語句尾不加分號(hào)功能:一個(gè)源文件可將另一個(gè)源文件的內(nèi)容全部包含進(jìn)來一般形式:#include “文件名” 或 #include 處理過程:預(yù)編譯時(shí),用被包含文件的內(nèi)容取代該預(yù)處理命令,再對(duì)“包含”后的文件作為一個(gè)源文件編譯。#include “file2.c”file1.cfile2.cfile1.cfile2.cABBAB 直接按標(biāo)準(zhǔn)目錄搜索“” 先在當(dāng)前目錄搜索,再搜索標(biāo)準(zhǔn)目錄,可指定路徑文件包含 一次只能包含一個(gè)文件 被包含的文件一定是文 本文件,不能是執(zhí)行程 序或目標(biāo)程序源文件(*.c)頭文件(*.h)宏定義數(shù)據(jù)結(jié)構(gòu)定義函數(shù)說明等文件包
48、含可嵌套#include “file2.c”file1.cAfile3.cC#include “file3.c”file2.c Bfile1.cAfile3.cfile2.c文件包含/* powers.h */#define sqr(x) (x)*(x)#define cube(x) (x)*(x)*(x)#define quad(x) (x)*(x)*(x)*(x)/*Exam.c*/#include /一個(gè)#include只包含一個(gè)文件#include d:c_propowers.h#define MAX_POWER 10void main() int n; printf(numbert
49、exp2t exp3t exp4n); for(n=1;n=MAX_POWER;n+) printf(%2dt %3dt %4dt %5dn,n,sqr(n),cube(n),quad(n);文件包含#define sqr(x) (x)*(x)#define cube(x) (x)*(x)*(x)#define quad(x) (x)*(x)*(x)*(x)不帶參數(shù)宏定義一般形式:#define 標(biāo)識(shí)符 字符串功能:預(yù)處理程序中用字符串(或宏體)代替標(biāo)識(shí)符(或宏名),此過程稱為“宏展開”。宏定義【例】不帶參數(shù)的宏定義#include#define PI 3.14159void main() d
50、ouble s,r; printf(“Input radius:”); scanf(“%f”,&r); s=PI*r*r; printf(“The circles area is %10.4f”,s);運(yùn)行結(jié)果:Input radius:4The circles area is 50.26543.14159*r*r,宏展開是任意類型數(shù)據(jù) #define A 3.6#define A “CHINA”宏定義說明: 宏名一般用大寫形式 使用宏定義,可以減少重復(fù)書寫某字符串的工作量 用宏體替換宏名,只作簡單的替換,不作任何語法檢查 如:#define PI 3.14l59 宏定義,行末不加分號(hào) #de
51、fine一般用在函數(shù)的外面,其有效范圍為定義命令之后 到本源文件結(jié)束。也可以用#undef命令終止宏定義的作用域。 如: #define G 9.8 void main() #undef G f1()G的有效范圍宏定義 宏定義可以嵌套,但不能遞歸。如:#define MAX MAX+10 ()如:#define MIN 10 #define MAX MIN*10 ()【例】 #include #define MIN 10 #define MAX MIN*10 void main() printf(“min=%d,max=%d”,MIN,MAX); 運(yùn)行結(jié)果:min=10,max=100【修改】
52、#define MIN 5+5#define MAX MIN*10輸出:min=10,max=55宏展開:5+5*10注意:宏名出現(xiàn)在引號(hào)中,不作宏替換。如:”MIN”如: #define S(a,b) a*b area=S(3,2);宏展開:area=3*2;帶參數(shù)的宏定義: 一般形式:#define 宏名(參數(shù)) 字符串宏定義3*2#include#define PI 3.14159#define S(r) PI*r*rvoid main() float a ,area; a=3.6; area=S(a); printf(“r=%f,area=%fn”,a,area);宏展開:形參用實(shí)參替
53、換,其它字符保留宏展開:3.14159*3.6*3.6宏定義說明: 帶參數(shù)宏的展開只是將宏名括號(hào)內(nèi)的實(shí)參字符串代替宏定 義中的形參。宏名與帶參數(shù)的括號(hào)間不應(yīng)加空格,否則空格后的字符串都 作為宏體的一部分。如: #define S (r) PI*r*r /宏名為S,字符串為(r) PI*r*r 遇area=S(a); 展開為 (r) PI*r*r(a);如:#define POWER(x) x*x x=4; y=6; z=POWER(x+y);宏展開:z=x+y*x+y;注意:實(shí)參是表達(dá)式時(shí),宏定義中要用括號(hào)把參數(shù)括起來。如:#define POWER(x) (x)*(x)宏展開:z=(x+y)
54、*(x+y);#define MAX(x,y) (x)(y)?(x):(y) .main() int a,b,c,d,t; . t=MAX(a+b,c+d); 宏展開:int max(int x,int y) return(xy?x:y);main() int a,b,c,d,t; . t=max(a+b,c+d); 宏定義與函數(shù)t=(a+b)(c+d)?(a+b):(c+d);宏定義與函數(shù) 帶參宏 函數(shù)處理時(shí)間 編譯前 程序運(yùn)行時(shí)參數(shù)類型無類型說明(無類型匹配問題)指明形參類型處理過程不分配內(nèi)存,僅簡單字符替換,不計(jì)算分配內(nèi)存先求實(shí)參值,再傳給形參程序長度變長不變宏定義 【例】用宏定義編制打
55、印不同半徑圓的周長、面積及球的體積的程序。#define PI 3.14159#define SQUARE(x) (x)*(x)#define CUB(x) (x)*(x)*(x)double area(double r) return(PI*SQUARE(r); double cirfer(double r) return(2.0*PI*r); double vol(double r) return(4.0/3.0*PI*CUB(r); main() double r=2.0; printf(“r=%f:%f %f %fn”,r,area(r),cirfer(r),vol(r);宏定義 【例
56、】定義一個(gè)帶參數(shù)的宏,使兩個(gè)參數(shù)的值互換,并編一個(gè)程序,輸入兩個(gè)整數(shù)作為使用宏時(shí)的參數(shù),輸出已經(jīng)交換的兩個(gè)值。#define SWAP(a,b) t=b;b=a;a=t;main() int a,b,t; printf(“請(qǐng)輸入兩個(gè)整數(shù):”); scanf(“%d,%d”,&a,&b); printf(“n原來得數(shù)據(jù)為:a=%d,b=%dn”,a,b); SWAP(a,b); printf(“交換結(jié)果為:a=%d,b=&dn”,a,b);運(yùn)行結(jié)果:請(qǐng)輸入兩個(gè)整數(shù):87,96原來的數(shù)據(jù)為:a=87,b=96交換結(jié)果為:a=96,b=87條件編譯條件編譯:根據(jù)條件選擇被編譯的源程序行。 使用宏定義
57、的標(biāo)識(shí)符作為編譯條件 使用常量表達(dá)式的值作為編譯條件 #ifdef形式:格式1#ifdef 標(biāo)識(shí)符 程序段1 #else 程序段2 #endif 作用:當(dāng)所指定的標(biāo)識(shí)符已經(jīng)被#define 命令定義過,則在程序編譯階段只編譯程序段1,否則編譯程序段2。條件編譯# ifdef 標(biāo)識(shí)符 程序段1 #endif 格式2:作用:當(dāng)所指定的標(biāo)識(shí)符已經(jīng)被#define 命令定義過,則在程序編譯階段只編譯程序段1,# ifndef 標(biāo)識(shí)符 程序段1 # else 程序段2 # endif 格式3:作用:當(dāng)所指定的標(biāo)識(shí)符未被#define 命令定義過,則在程序編譯階段只編譯程序段1,否則編譯程序段2。條件編譯
58、【例】:用于程序調(diào)試#include void main() #ifdef FLAG printf(“FLAG已被定義”); #else printf(“FLAG未被定義”); #endif#define FLAG 1運(yùn)行結(jié)果:FLAG已被定義運(yùn)行結(jié)果:FLAG未被定義條件編譯# if 表達(dá)式 程序段1 # else 程序段2 # endif #if形式:使用常量表達(dá)式的值作為編譯條件作用:當(dāng)所指定的表達(dá)式為真(非零)時(shí)就編譯程序段1,否則編譯程序段2。 可以事先給定一定條件,使程序在不同的條件下執(zhí)行不同的功能。# if 表達(dá)式 程序段# endif 作用:當(dāng)指定的表達(dá)式非零時(shí)編譯程序段條件編
59、譯【例】輸入一行字母字符,根據(jù)需要設(shè)置條件編譯,使之能將字母全改為大寫輸出,或改為小寫字母輸出。#include#define LETTER 1void main() char str20=“C Language”,c; int i=0; while(c=stri)!=0) i+; #if LETTER if(c=a & c=A & c=Z) c=c+32; #endif printf(“%c”,c); 預(yù)處理命令讀程序,寫結(jié)果1.#include#define Sqr(x) x*xvoid main() int a=15,b=2,m=1; a/=Sqr(b+m)/Sqr(b+m); prin
60、tf( %dn,a);結(jié)果:22.#include#define MIN(x,y) (x)(y)?(x):(y)void main() int a=1,b=5,c=4,d=4,t; t=MIN(a+b,c+d)*10; printf(%d,t);結(jié)果:6宏展開:(1+5)limit成立?#includelong series(int limit)long n=0;float sum=0;do +n; sum+=1.0/n;while(sum=limit);return n;void main( )long n=0;int limit;scanf(%d,&limit);n=series(limi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 書銷售返利合同范本
- 2025年武威貨車上崗證理論模擬考試題庫
- 臨街門面房轉(zhuǎn)讓合同范本
- 全款分期購房合同范本
- 公路施工單價(jià)合同范本
- 出售鐵皮房子合同范本
- 分銷平移合同范本
- 債券托管合同范本
- 修建電動(dòng)車車棚合同范本
- 物流園遮雨棚安裝施工方案
- 2021年湖北省煙草專賣局系統(tǒng)招聘考試真題
- 鐵路營業(yè)線施工安全管理培訓(xùn)課件
- 旅行社運(yùn)營實(shí)務(wù)電子課件 1.2 了解旅行社核心業(yè)務(wù)部門
- 部編版五年級(jí)語文下冊(cè)課文四字詞總結(jié)
- 綜合交通運(yùn)輸體系認(rèn)知
- GM/T 0115-2021信息系統(tǒng)密碼應(yīng)用測評(píng)要求
- YY 0670-2008無創(chuàng)自動(dòng)測量血壓計(jì)
- JJF 1458-2014磁軛式磁粉探傷機(jī)校準(zhǔn)規(guī)范
- GB/T 39935-2021塑料制品薄膜和片材抗粘連性的測定
- GB/T 324-2008焊縫符號(hào)表示法
- 機(jī)器人技術(shù) 第一章 緒論
評(píng)論
0/150
提交評(píng)論