版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
C語(yǔ)言程序設(shè)計(jì)第5章模塊化程序設(shè)計(jì)第5章內(nèi)容模塊化程序設(shè)計(jì)思想函數(shù)的定義函數(shù)的調(diào)用函數(shù)的聲明函數(shù)的嵌套調(diào)用函數(shù)的遞歸調(diào)用變量的作用域變量的存儲(chǔ)類型內(nèi)部函數(shù)和外部函數(shù)模塊化程序設(shè)計(jì)思想在軟件工程中,通常采用“自頂向下、分而治之”的方法,將大問(wèn)題分解成若干小的問(wèn)題,如果小問(wèn)題還不容易解決,就再分解成更小的問(wèn)題。模塊化程序設(shè)計(jì)的基本思想,是將一個(gè)大的復(fù)雜的程序按功能分割成一些小的功能模塊。當(dāng)開(kāi)發(fā)一個(gè)軟件系統(tǒng)時(shí),最好的辦法是從編寫主程序開(kāi)始,在主程序中,將問(wèn)題作為一個(gè)整體考慮,找出完成任務(wù)的主要步驟,再沿著這條主線將整個(gè)問(wèn)題繼續(xù)分解為獨(dú)立的簡(jiǎn)單模塊,這就是模塊化程序設(shè)計(jì)的主要思想。模塊分解的原則模塊分解——“自頂向下、逐步求精”的程序設(shè)計(jì)過(guò)程模塊分解的基本原則——高聚合、低耦合及信息隱藏高聚合——一個(gè)模塊只能完成單一的功能,不能“身兼數(shù)職”低耦合——模塊之間參數(shù)傳遞盡量少,也不能通過(guò)全局變量來(lái)實(shí)現(xiàn)數(shù)據(jù)傳遞信息隱藏——把不需要調(diào)用者知道的信息都包裝在模塊內(nèi)部隱藏起來(lái)凡是被眾多模塊公用的程序,均應(yīng)設(shè)計(jì)成一個(gè)獨(dú)立的模塊各模塊間應(yīng)在功能上、邏輯上相互獨(dú)立,模塊間的接口應(yīng)盡量簡(jiǎn)單,其數(shù)據(jù)傳遞使用參數(shù)來(lái)完成每個(gè)模塊應(yīng)設(shè)計(jì)成單入口、單出口形式,以便調(diào)試與閱讀,提高程序的可靠性模塊化設(shè)計(jì)方法功能分解自頂向下、逐步求精的過(guò)程。每個(gè)模塊的功能盡量單一,程序代碼最好不要超過(guò)50行。模塊分解的原則保證模塊的相對(duì)獨(dú)立性(高聚合、低耦合)。模塊的實(shí)現(xiàn)細(xì)節(jié)對(duì)外不可見(jiàn)(外部:關(guān)心做什么;內(nèi)部:關(guān)心怎么做)。設(shè)計(jì)好模塊接口接口是指羅列出一個(gè)模塊的所有的與外部打交道的變量等。定義好后不要輕易改動(dòng)。在模塊開(kāi)頭(文件的開(kāi)頭)進(jìn)行函數(shù)聲明。模塊化程序設(shè)計(jì)的特點(diǎn)各模塊相對(duì)獨(dú)立、功能單一、結(jié)構(gòu)清晰、接口簡(jiǎn)單程序設(shè)計(jì)的復(fù)雜性得到了有效控制縮短開(kāi)發(fā)周期避免程序開(kāi)發(fā)的重復(fù)勞動(dòng)易于維護(hù)和功能擴(kuò)充模塊與函數(shù)在C語(yǔ)言中,每個(gè)模塊都是由函數(shù)完成的,一個(gè)小模塊就是一個(gè)函數(shù)。將一些常用的功能模塊編寫成函數(shù),放在函數(shù)庫(kù)中,組成C庫(kù)函數(shù),供公共選用。編寫某個(gè)函數(shù)時(shí),遇到具有相對(duì)獨(dú)立功能的程序段,都應(yīng)獨(dú)立成另一個(gè)函數(shù),供另一個(gè)函數(shù)調(diào)用;當(dāng)某一個(gè)函數(shù)代碼較長(zhǎng)時(shí),也應(yīng)將其中相對(duì)獨(dú)立的代碼分成另一個(gè)函數(shù)從函數(shù)定義的角度看,C語(yǔ)言的函數(shù)可分為庫(kù)函數(shù)、用戶定義函數(shù)(包括主函數(shù)main)兩種。從函數(shù)的使用性質(zhì)來(lái)看,C語(yǔ)言的函數(shù)還分為內(nèi)部函數(shù)、外部函數(shù)兩種。函數(shù)的本質(zhì)是外部函數(shù)。函數(shù)設(shè)計(jì)的原則函數(shù)的功能要單一,不要設(shè)計(jì)多用途的函數(shù)函數(shù)的規(guī)模要小,盡量控制在50行代碼以內(nèi)1986年IBM在OS/360的研究結(jié)果:大多數(shù)有錯(cuò)誤的函數(shù)都大于500行1991年對(duì)148,000行代碼的研究表明:小于143行的函數(shù)比更長(zhǎng)的函數(shù)更容易維護(hù)參數(shù)和返回值的規(guī)則參數(shù)要書寫完整,不要省略對(duì)函數(shù)的入口參數(shù)進(jìn)行有效性檢查沒(méi)有參數(shù)和返回值時(shí),用void填充每個(gè)函數(shù)只有一個(gè)入口和一個(gè)出口,盡量不使用全局變量盡量少用靜態(tài)局部變量,以避免使函數(shù)具有“記憶”功能函數(shù)的定義合法標(biāo)識(shí)符函數(shù)返回值類型:缺省int型,無(wú)返回值void函數(shù)體函數(shù)類型函數(shù)名(形式參數(shù)類型說(shuō)明表){
聲明部分 執(zhí)行部分}現(xiàn)代風(fēng)格:例有參函數(shù)(現(xiàn)代風(fēng)格)
intmax(intx,inty){intz;z=x>y?x:y;return(z);}例空函數(shù)
dummy(){}函數(shù)體為空例無(wú)參函數(shù)voidprintstar(){printf(“**********\n”);}或voidprintstar(void){printf(“**********\n”);}參數(shù):傳遞數(shù)據(jù)信息的通道函數(shù)定義說(shuō)明①類型說(shuō)明符可為:int、char、float、double等。表示在調(diào)用了該函數(shù)后,其返回值的數(shù)據(jù)類型;如果函數(shù)無(wú)數(shù)據(jù)返回時(shí),應(yīng)使用void
作類型定義符。注意,省略了類型說(shuō)明符,編譯程序默認(rèn)的函數(shù)返回值為一個(gè)整型值類型(int)。②函數(shù)名,由用戶取的合法標(biāo)識(shí)符。C語(yǔ)言的關(guān)鍵字不能作函數(shù)名。自定義函數(shù)的名稱可以使用庫(kù)函數(shù)名,但這時(shí)庫(kù)函數(shù)被屏蔽。③形式參數(shù)表是一個(gè)用逗號(hào)分隔的變量表,當(dāng)函數(shù)被調(diào)用時(shí)這些變量接受調(diào)用參數(shù)的值。相當(dāng)于函數(shù)調(diào)用時(shí)傳遞信息的通道。④在函數(shù)的定義中,如果沒(méi)有函數(shù)體,即函數(shù)什么功能都不做,稱為空函數(shù)??蘸瘮?shù)的功能主要是在程序設(shè)計(jì)中,留出該函數(shù)的功能,以后在需要的時(shí)候補(bǔ)充上去。特別注意(1)函數(shù)不能單獨(dú)運(yùn)行,函數(shù)可以被主函數(shù)或其它函數(shù)調(diào)用,也可以調(diào)用其它函數(shù),但是不能調(diào)用主函數(shù)。(2)C規(guī)定,函數(shù)體的聲明部分和執(zhí)行部分應(yīng)嚴(yán)格劃分,且聲明部分放在函數(shù)體的開(kāi)始。例如,以下定義是不允許的:voidmain(){doublex;scanf("%lf",&x);
doubles;/*不能在執(zhí)行語(yǔ)句中穿插定義變量*/scanf("%lf",&s);…}主調(diào)函數(shù)與被調(diào)函數(shù)C語(yǔ)言程序是由若干個(gè)函數(shù)組成的,各函數(shù)在結(jié)構(gòu)上是獨(dú)立的,但它們所處理的對(duì)象即數(shù)據(jù)卻是相互聯(lián)系的。一個(gè)函數(shù)調(diào)用另一個(gè)函數(shù),將調(diào)用的函數(shù)稱為主調(diào)函數(shù),將被調(diào)用的函數(shù)稱為被調(diào)函數(shù)。主調(diào)函數(shù)和被調(diào)函數(shù)具有數(shù)據(jù)傳遞的關(guān)系,其傳遞的實(shí)施是通過(guò)函數(shù)的參數(shù)來(lái)實(shí)現(xiàn)的。主調(diào)函數(shù)和被調(diào)函數(shù)的概念是相對(duì)的。函數(shù)調(diào)用的一般形式#include<stdio.h>voidmain(){inta=5,b=7,c;c=max(a,b);printf(“較大的數(shù)是%d",c);}
intmax(intx,inty){intz;z=x>y?x:y;return(z);}作為一個(gè)表達(dá)式調(diào)用,調(diào)用后只是返回一個(gè)結(jié)果值函數(shù)調(diào)用過(guò)程中的參數(shù)傳遞c=max(a,b);
intmax(intx,inty){intz;z=x>y?x:y;return(z);}按順序?qū)?yīng)參數(shù)傳遞實(shí)參數(shù)形式參數(shù)函數(shù)調(diào)用過(guò)程中的結(jié)果返回c=;
intmax(intx,inty){intz;z=x>y?x:y;return(z);}max(a,b)57=77777無(wú)返回函數(shù)的調(diào)用#include<stdio.h>voidmain(){printstar();}voidprintstar(){printf(“**********\n”);}作為一個(gè)函數(shù)語(yǔ)句調(diào)用函數(shù)調(diào)用說(shuō)明如果調(diào)用的是無(wú)參函數(shù),“實(shí)際參數(shù)表”可以沒(méi)有,但括號(hào)()不能省略。如果實(shí)參表包含多個(gè)實(shí)參,則各參數(shù)間用逗號(hào)隔開(kāi)。實(shí)參與形參的個(gè)數(shù)應(yīng)相等、類型應(yīng)一致。實(shí)參與形參按順序?qū)?yīng),一一傳遞數(shù)據(jù)。函數(shù)不能嵌套定義,即在一個(gè)定義好的函數(shù)中,不能又定義另一個(gè)函數(shù)。函數(shù)之間允許相互調(diào)用,也允許嵌套調(diào)用。但main函數(shù)不能被調(diào)用。函數(shù)還可以自己調(diào)用自己,稱為遞歸調(diào)用。補(bǔ)充實(shí)例1求任意正整數(shù)n的階乘n!=1×2×3×……×n計(jì)算階乘#include<stdio.h>voidmain(){ longi,m,n; printf("請(qǐng)輸入一個(gè)正整數(shù):");
scanf("%d",&n); //鍵盤輸入一個(gè)正整數(shù)n
m=1; for(i=2;i<=n;i++){ m*=i; } printf("%d!=%d\n",n,m);}編寫一個(gè)計(jì)算階乘的函數(shù)longfact(intn){ longi,m;
m=1; for(i=2;i<=n;i++){ m*=i; } return(m);}補(bǔ)充實(shí)例2計(jì)算以下公式的值(其中n為鍵盤輸入的任意數(shù))sum=1!+2!+3!+……+n!計(jì)算階乘之和#include<stdio.h>voidmain(){ longi,sum=0,n; printf("請(qǐng)輸入一個(gè)正整數(shù):");
scanf("%d",&n);
for(i=1;i<=n;i++){ sum+=fact(i); } printf("計(jì)算結(jié)果=%d\n",sum);}longfact(intn){longi,m;
m=1;for(i=2;i<=n;i++){ m*=i;}return(m);}補(bǔ)充實(shí)例3計(jì)算以下公式的值(其中n為鍵盤輸入的任意數(shù))longfact(intn){longi,m;
m=1;for(i=2;i<=n;i++){ m*=i;}return(m);}計(jì)算多項(xiàng)式之和的程序#include<stdio.h>voidmain(){ longi,n; doublesum=1.0; printf("請(qǐng)輸入一個(gè)正整數(shù):");
scanf("%d",&n); for(i=1;i<=n;i++){ sum+=1.0/fact(i); } printf("計(jì)算結(jié)果=%f\n",sum);}判斷一個(gè)數(shù)是否為素?cái)?shù)的程序#include<stdio.h>#include<math.h>voidmain(){inti,m,flag;printf("請(qǐng)輸入一個(gè)正整數(shù)m>2:");
scanf("%d",&m); //鍵盤輸入一個(gè)正整數(shù)m
flag=1;
//假設(shè)m是素?cái)?shù)
for(i=2;i<=sqrt(m)+1;i++){if(m%i==0) //若能被i整除,返回1,說(shuō)明m不是素?cái)?shù){ flag=0; break;} //跳出循環(huán),減少無(wú)效的循環(huán)次數(shù)}
if(flag==1)printf("%d是素?cái)?shù)\n",m);elseprintf("%d不是素?cái)?shù)\n",m);}補(bǔ)充實(shí)例4找出50~100之間的所有素?cái)?shù),并在屏幕上輸出找出50~100之間的所有素?cái)?shù)#include"stdio.h"#include"math.h"voidmain(){ inti,j,flag; for(i=50;i<=100;i++) { flag=1; for(j=2;j<=sqrt(i)+1;j++) { if(i%j==0) { flag=0; break; } } if(flag==1)printf("%d",i); }}自定義一個(gè)專門判斷是否素?cái)?shù)的函數(shù)intPrime(intnumber){inti,flag=1;
for(i=2;i<=sqrt(number)+1;i++){ if(number%i==0) { flag=0; break;} }
return(flag);
}找出50~100之間的所有素?cái)?shù)#include<stdio.h>#include<math.h>voidmain(){ inti;
for(i=50;i<=100;i++){ if(Prime(i))
{ printf("%5d",i); } }}intPrime(intnumber){inti,flag=1;for(i=2;i<=sqrt(number)+1;i++){if(number%i==0) { flag=0; break;} }
return(flag);
}500找出50~100之間的所有素?cái)?shù)#include<stdio.h>#include<math.h>voidmain(){ inti;
for(i=50;i<=100;i++){ if(Prime(i))
{ printf("%5d",i); } }}intPrime(intnumber){inti,flag=1;for(i=2;i<=sqrt(number)+1;i++){if(number%i==0) { flag=0; break;} }
return(flag);
}510找出50~100之間的所有素?cái)?shù)#include<stdio.h>#include<math.h>voidmain(){ inti;
for(i=50;i<=100;i++){ if(Prime(i))
{ printf("%5d",i); } }}intPrime(intnumber){inti,flag=1;for(i=2;i<=sqrt(number)+1;i++){if(number%i==0) { flag=0; break;} }
return(flag);
}520找出50~100之間的所有素?cái)?shù)#include<stdio.h>#include<math.h>voidmain(){ inti;
for(i=50;i<=100;i++){ if(Prime(i))
{ printf("%5d",i); } }}intPrime(intnumber){inti,flag=1;for(i=2;i<=sqrt(number)+1;i++){if(number%i==0) { flag=0; break;} }
return(flag);
}531自定義頭文件student.h#include<stdio.h>#include<math.h>#include"e:\student.h"voidmain(){ inti;
for(i=50;i<=100;i++){ if(Prime(i))
{ printf("%5d",i); } }}把自定義函數(shù)保存在自行編寫的頭文件中,是一個(gè)方便實(shí)用的方法。用戶自行編寫的頭文件,最好不要與系統(tǒng)提供的頭文件保存在同一路徑下。補(bǔ)充實(shí)例5查找1000以內(nèi)的最大素?cái)?shù)查找1000以內(nèi)最大的素?cái)?shù)#include"stdio.h"#include"math.h"voidmain(){ inti,j,flag; for(i=1000;i>=2;i--) //注意循環(huán)控制方法的改變 { flag=1; for(j=2;j<=sqrt(i)+1;j++) { if(i%j==0) { flag=0; break; } } if(flag==1) { printf("1000以內(nèi)的最大素?cái)?shù)是:%d\n",i); break; } }}查找1000以內(nèi)的最大素?cái)?shù)#include<stdio.h>#include<math.h>voidmain(){ inti,m; for(i=1000;i>=2;i--){ if(Prime(i)) { printf("1000以內(nèi)的最大素?cái)?shù)為%d\n",i); break; } }}補(bǔ)充實(shí)例6哥德巴赫猜想:一個(gè)足夠大的偶數(shù),必定可以表示成兩個(gè)素?cái)?shù)之和分析思路:設(shè)計(jì)一個(gè)判斷任意指定數(shù)是否為素?cái)?shù)的子函數(shù)把輸入的偶數(shù)拆分成兩個(gè)數(shù),并分別調(diào)用上述子函數(shù),判斷它們是否為素?cái)?shù)例如:128=19+109驗(yàn)證哥德巴赫猜想的程序代碼#include<stdio.h>#include<math.h>voidmain(){inti,j,m,flag1,flag2;printf("請(qǐng)輸入一個(gè)足夠大的偶數(shù):");scanf("%d",&m);for(i=2;i<=m/2;i++) {
flag1=1; for(j=2;j<=sqrt(i)+1;j++) { if(i%j==0) { flag1=0; break; } }
flag2=1; for(j=2;j<=sqrt(m-i)+1;j++) { if((m-i)%j==0) { flag2=0; break; } } if(flag1==1&&flag2==1) { printf("%d=%d+%d\n",m,i,m-i); break; } }}驗(yàn)證哥德巴赫猜想的程序代碼#include<stdio.h>#include<math.h>voidmain(){ inti,m;printf("請(qǐng)輸入一個(gè)足夠大的偶數(shù):");
scanf("%d",&m); //鍵盤輸入一個(gè)正整數(shù)m
for(i=2;i<=m/2;i++){ if(Prime(i)&&Prime(m-i)) { printf("%d=%d+%d\n",m,i,m-i); break; } }}課堂作業(yè)1寫出可以根據(jù)主調(diào)函數(shù)提供的數(shù)值n,用來(lái)計(jì)算以下多項(xiàng)式之和的函數(shù)sum=1+2+3+……+n課堂作業(yè)2編寫一個(gè)能根據(jù)提供的數(shù)值n,在屏幕上輸出一行n個(gè)星號(hào)的函數(shù)(n由主調(diào)函數(shù)傳遞而來(lái))課堂作業(yè)3編寫一個(gè)能根據(jù)提供的數(shù)值n,在屏幕上輸出由星號(hào)組成的如下圖案的函數(shù)(本例設(shè)n=4)****************課堂作業(yè)4編寫一個(gè)能根據(jù)提供的數(shù)值n,在屏幕上輸出由星號(hào)組成的如下圖案的函數(shù)(本例設(shè)n=5,并限制n小于10)*************************課堂作業(yè)5判斷鍵盤輸入的一個(gè)正整數(shù)是不是回文數(shù)所謂回文數(shù),就是從左看或從右看均是同一個(gè)數(shù)的數(shù),如2552、73837判斷是否回文數(shù)的程序#include<stdio.h>voidmain(){longm=0,n,p;printf("請(qǐng)輸入一個(gè)正整數(shù):");scanf("%d",&n); //鍵盤輸入一個(gè)正整數(shù)n p=n; while(p>0) { m=m*10+p%10; p=p/10; } if(n==m) printf("%d是回文數(shù)\n",n); else printf("%d不是回文數(shù)\n",n);}回文數(shù)計(jì)算過(guò)程x=32768y=0y=y*10+x%10=0*10+8=8x=x/10=3276y=y*10+x%10=8*10+6=86x=x/10=327回文數(shù)計(jì)算過(guò)程y=y*10+x%10=86*10+7=867x=x/10=32y=y*10+x%10=867*10+2=8672x=x/10=3y=y*10+x%10=8672*10+3=86723x=x/10=0課堂作業(yè)5寫出判斷給定的數(shù)n是否為回文數(shù)的函數(shù),若n為回文數(shù),函數(shù)返回值為1,否則返回值為0課堂作業(yè)1答案#include<stdio.h>intsum(intx){ inti,s=0; for(i=1;i<=x;i++) s+=i; return(s);}voidmain(){intn;printf("請(qǐng)輸入一個(gè)正整數(shù):");scanf("%d",&n); //鍵盤輸入一個(gè)正整數(shù)n printf("累加和=%d\n",sum(n));}課堂作業(yè)2答案#include<stdio.h>voidstars(intx){ inti; for(i=1;i<=x;i++) printf("*"); printf("\n");}voidmain(){intn; printf("請(qǐng)輸入一個(gè)正整數(shù):");scanf("%d",&n); //鍵盤輸入一個(gè)正整數(shù)n stars(n); //注意調(diào)用方式}課堂作業(yè)3答案#include<stdio.h>voidstars(intx){ inti,j; for(i=1;i<=x;i++) { for(j=1;j<=2*i-1;j++) printf("*"); printf("\n"); }}voidmain(){intn; printf("請(qǐng)輸入一個(gè)正整數(shù):");scanf("%d",&n); //鍵盤輸入一個(gè)正整數(shù)n stars(n);}課堂作業(yè)4答案#include<stdio.h>voidstars(intx){ inti,j,k; for(i=1;i<=x;i++) { for(k=1;k<20-2*i+1;k++) printf(""); for(j=1;j<=2*i-1;j++) printf("*"); printf("\n"); }}voidmain(){intn; printf("請(qǐng)輸入一個(gè)正整數(shù):");scanf("%d",&n); //鍵盤輸入一個(gè)正整數(shù)n stars(n);}課堂作業(yè)5答案charhuiwen(longn){ longm=0,p; p=n; while(p>0) { m=m*10+p%10; p=p/10; } if(m==n) return(1); else return(0);}找出1~999之間的所有回文數(shù)#include<stdio.h>voidmain(){longi;for(i=1;i<=999;i++) { if(huiwen(i)) printf("%5d",i); }}找出n和n2均為回文數(shù)的數(shù)#include<stdio.h>voidmain(){longi;for(i=1;i<=999;i++) { if(huiwen(i)&&huiwen(i*i)) printf("%10d%10d\n",i,i*i); }}例5.1【例5.1】求三個(gè)數(shù)中最大數(shù)和最小數(shù)的差值。分析問(wèn)題:首先在主函數(shù)main()中調(diào)用求差值的函數(shù)dif()在求差值函數(shù)中再調(diào)用求三個(gè)數(shù)的最大值函數(shù)max()和最小值函數(shù)min()將一個(gè)復(fù)雜的問(wèn)題分解成了三個(gè)小問(wèn)題:求兩個(gè)數(shù)的差求三個(gè)數(shù)的最大值求三個(gè)數(shù)的最小值程序?qū)崿F(xiàn)#include<stdio.h>/*自定義函數(shù)的聲明*/intdif(intx,inty,intz);intmax(intx,inty,intz);intmin(intx,inty,intz);intmain(){inta,b,c,d;printf("InputData:");scanf("%d%d%d",&a,&b,&c);/*輸入三個(gè)數(shù)*/
/*調(diào)用差值函數(shù),并將函數(shù)的返回值賦給d*/d=dif(a,b,c);printf("Max-Min=%d\n",d);/*輸出*/return(0);}程序?qū)崿F(xiàn)(續(xù))/*定義求三個(gè)數(shù)x、y、z的差值函數(shù)dif*/intdif(intx,inty,intz){intm1,m2;m1=max(x,y,z); /*調(diào)用求最大值函數(shù),返回值賦給m1*/m2=min(x,y,z); /*調(diào)用求最小值函數(shù),返回值賦給m2*/returnm1-m2; /*返回最大值與最小值的差*/}/*定義求三個(gè)數(shù)x、y、z的最大值函數(shù)max*/intmax(intx,inty,intz){intr1,r2;r1=(x>y)?x:y;r2=(r1>z)?r1:z;return(r2); /*返回三個(gè)數(shù)的最大值*/}/*定義求三個(gè)數(shù)x、y、z的最小值函數(shù)min*/intmin(intx,inty,intz){intr;r=(x<y)?x:y;return(r<z?r:z); /*返回三個(gè)數(shù)的最小值*/}程序的調(diào)用關(guān)系main()調(diào)用函數(shù)dif輸出結(jié)束dif函數(shù)max函數(shù)調(diào)用函數(shù)max調(diào)用函數(shù)minmin函數(shù)本例程序涉及到模塊化程序設(shè)計(jì)思想、函數(shù)的定義、函數(shù)的調(diào)用、函數(shù)的聲明、變量的作用域、變量的存儲(chǔ)類型、內(nèi)部函數(shù)和外部函數(shù)等知識(shí)點(diǎn)。例5.2【例5.2】用函數(shù)實(shí)現(xiàn):編程求的值。分析問(wèn)題:可以定義一個(gè)函數(shù)doublefff(doublex)來(lái)求值,然后在主函數(shù)main()中調(diào)用該函數(shù)。例5.2程序#include<stdio.h>doublefff(doublex){doublef;f=x*x;return(f);}/*主函數(shù)中調(diào)用fff()函數(shù)*/intmain(){doublef=0.3,ff;ff=fff(f);printf(“%f\n”,ff);return(0);}函數(shù)參數(shù)傳遞形參與實(shí)參形式參數(shù):定義函數(shù)時(shí)函數(shù)名后面括號(hào)中的變量名實(shí)際參數(shù):調(diào)用函數(shù)時(shí)函數(shù)名后面括號(hào)中的表達(dá)式c=max(a,b);(main函數(shù))(max函數(shù))max(intx,inty){intz;z=x>y?x:y;return(z);}例5.3
編程求兩個(gè)數(shù)的最大值#include<stdio.h>intmax(intx,inty){intz;z=x>y?x:y;return(z);}intmain(){inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf("Maxis%d",c);return(0);}形參實(shí)參(主調(diào)函數(shù))c=max(a,b);(被調(diào)函數(shù))max(intx,inty)實(shí)際參數(shù)形式參數(shù)參數(shù)傳遞參數(shù)傳遞——值傳遞方式值傳遞方式方式:函數(shù)調(diào)用時(shí),為形參分配單元,并將實(shí)參的值復(fù)制到形參中;調(diào)用結(jié)束,形參單元被釋放,實(shí)參單元仍保留并維持原值特點(diǎn):形參與實(shí)參占用不同的內(nèi)存單元單向傳遞實(shí)參a10形參x10復(fù)制實(shí)參內(nèi)存空間形參內(nèi)存空間參數(shù)傳遞——地址傳遞方式地址傳遞方式:函數(shù)調(diào)用時(shí),將數(shù)據(jù)的存儲(chǔ)地址作為參數(shù)傳遞給形參特點(diǎn):形參與實(shí)參占用同樣的存儲(chǔ)單元“雙向”傳遞實(shí)參和形參必須是地址常量或變量實(shí)參a形參x實(shí)參內(nèi)存空間形參內(nèi)存空間函數(shù)的返回值返回語(yǔ)句形式:return(表達(dá)式);或return表達(dá)式;或return;功能:使程序控制從被調(diào)用函數(shù)返回到調(diào)用函數(shù)中,同時(shí)把返值帶給調(diào)用函數(shù)說(shuō)明:函數(shù)中可有多個(gè)return語(yǔ)句,但只能返回唯一的函數(shù)值若無(wú)return語(yǔ)句,遇
}
時(shí),自動(dòng)返回調(diào)用函數(shù),返回值是一個(gè)不確定的值若函數(shù)類型與return語(yǔ)句中表達(dá)式值的類型不一致,按函數(shù)類型為準(zhǔn),表達(dá)式值類型在函數(shù)調(diào)用時(shí)自動(dòng)轉(zhuǎn)換成函數(shù)類型void型函數(shù):表示“空類型”或“無(wú)類型”例無(wú)返回值函數(shù)
voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}例有返回值函數(shù)intmaxmum(intx,inty){intz;z=(x>y)
?x:y
;return(z);/*返回最大值*/}函數(shù)返回不確定值
intprintstar(){printf("**********");}intmain(){inta;a=printstar();printf("%d",a);return(0);}輸出:10voidprintstar(){printf("**********");}intmain(){inta;a=printstar();printf("%d",a);return(0);}編譯錯(cuò)誤!函數(shù)返回值類型轉(zhuǎn)換#include<stdio.h>intmain(){floata,b;intc;scanf("%f,%f",&a,&b);c=max(a,b);printf("Maxis%d\n",c);return(0);}intmax(floatx,floaty){floatz;z=x>y?x:y;return(z);}函數(shù)值轉(zhuǎn)換成float函數(shù)返回值類型int例5.4【例5.4】用函數(shù)實(shí)現(xiàn):編程計(jì)算兩個(gè)數(shù)之和。分析問(wèn)題:可以定義一個(gè)函數(shù)intadd(intx,inty)來(lái)求兩個(gè)數(shù)之和的值,并通過(guò)return語(yǔ)句將和值返回到主函數(shù)中。例5.4程序#include<stdio.h>intadd(intx,inty){intz;z=a+b;return(z);}intmain(){inta,b,c;scanf("%d%d",&a,&b);c=add(a,b);printf("sum=%d\n",c);return(0);}函數(shù)聲明對(duì)被調(diào)用函數(shù)要求:必須是已存在的函數(shù)庫(kù)函數(shù):#include<*.h>用戶自定義函數(shù):函數(shù)類型聲明函數(shù)聲明一般形式:函數(shù)類型函數(shù)名(形參類型[形參名],…..);或函數(shù)類型函數(shù)名();作用:告訴編譯系統(tǒng)函數(shù)類型、參數(shù)個(gè)數(shù)及類型,以便檢驗(yàn)函數(shù)定義與函數(shù)聲明不同函數(shù)聲明位置:程序的數(shù)據(jù)聲明部分(函數(shù)內(nèi)或外)下列情況下,可不作函數(shù)聲明若函數(shù)返值是char或int型,系統(tǒng)自動(dòng)按int型處理被調(diào)用函數(shù)定義出現(xiàn)在主調(diào)函數(shù)之前有些系統(tǒng)(如BorlandC++)要求函數(shù)聲明指出函數(shù)返值類型和形參類型,并且對(duì)void和int
型函數(shù)也要進(jìn)行函數(shù)聲明函數(shù)聲明舉例voidmain(){floata,b;intc;scanf("%f,%f",&a,&b);
c=max(a,b);printf("Maxis%d\n",c);}intmax(floatx,floaty){floatz;z=x>y?x:y;return(z);}int型函數(shù)可不作函數(shù)說(shuō)明(BorlandC++不行)floatadd(floatx,floaty){floatz;z=x+y;return(z);}voidmain(){floata,b,c;scanf("%f,%f",&a,&b);
c=add(a,b);printf("sumis%f",c);}被調(diào)函數(shù)出現(xiàn)在主調(diào)函數(shù)之前,不必函數(shù)說(shuō)明voidmain(){
floatadd(float,float);/*functiondeclaration*/
floata,b,c;scanf("%f,%f",&a,&b);c=add(a,b);printf("sumis%f",c);}floatadd(floatx,floaty){floatz;z=x+y;return(z);}可以:floatadd();不提倡。或:floatadd(floatx,floaty);例5.5【例5.5】用函數(shù)實(shí)現(xiàn):求兩個(gè)數(shù)的最大公約數(shù)和最小公倍數(shù)。分析問(wèn)題:
最大公約數(shù)(或稱最大公因子)是能夠同時(shí)被兩個(gè)數(shù)整除的最大數(shù),其性質(zhì)為:
①如果a>b,則a和b的最大公約數(shù)與a-b和b的最大公約數(shù)相同;②如果b>a,則a和b的最大公約數(shù)與a和b-a的最大公約數(shù)相同;③如果a=b,則a和b的最大公約數(shù)與a值和b值相同。換句話說(shuō),最大公約數(shù)是最后能使余數(shù)為0的被除數(shù)。最小公倍數(shù)為:兩數(shù)相乘,再除以最大公約數(shù)。例5.5解法一(窮舉法)#include<stdio.h>/*函數(shù)聲明*/inthcf(intu,intv);intlcd(intu,intv,inth);intmain(){intn1,n2,h,l;scanf("%d,%d",&n1,&n2); /*輸入兩個(gè)數(shù)*/h=hcf(n1,n2); /*調(diào)用求最大公約數(shù)函數(shù)*/printf("greatestcommondivisor:%d\n",h);l=lcd(n1,n2,h); /*調(diào)用求最小公倍數(shù)函數(shù)*/printf("leasecommonmultiple:%d\n",l);return(0);}例5.5解法一(續(xù))/*函數(shù)定義:求兩個(gè)數(shù)的最大公約數(shù)*/inthcf(intu,intv){intt;if(v>u){t=u;u=v;v=t;}
t=v;while(u%t!=0||v%t!=0)t--;return(t);}/*函數(shù)定義:求兩個(gè)數(shù)的最小公倍數(shù),h為最大公約數(shù)*/intlcd(intu,intv,inth){return(u*v/h);}例5.5程序解法二(輾轉(zhuǎn)相除法)#include<stdio.h>/*函數(shù)聲明*/inthcf(intu,intv);intlcd(intu,intv,inth);intmain(){intn1,n2,h,l;scanf("%d,%d",&n1,&n2);h=hcf(n1,n2);printf("greatestcommondivisor:%d\n",h);l=lcd(n1,n2,h);printf("leasecommonmultiple:%d\n",l);return(0);}例5.5解法二(續(xù))/*函數(shù)定義:求兩個(gè)數(shù)的最大公約數(shù)*/inthcf(intu,intv){intt;if(v>u){t=u;u=v;v=t;}
while(v!=0){t=u%v;u=v;v=t;}return(u);}/*函數(shù)定義:求兩個(gè)數(shù)的最小公倍數(shù),h為最大公約數(shù)*/intlcd(intu,intv,inth){return(u*v/h);}函數(shù)的嵌套調(diào)用C程序由若干函數(shù)組成,各函數(shù)在結(jié)構(gòu)上是相互平行和獨(dú)立的,函數(shù)不能嵌套定義。如果不考慮函數(shù)的功能和邏輯關(guān)系,函數(shù)之間是平行的,無(wú)主從輕重,可以相互調(diào)用。C規(guī)定:函數(shù)不能嵌套定義,但可以嵌套調(diào)用。主函數(shù)可以調(diào)用自定義函數(shù),自定義函數(shù)之間可以嵌套調(diào)用。所謂函數(shù)嵌套調(diào)用是指一個(gè)函數(shù)調(diào)用另一個(gè)函數(shù),另一個(gè)函數(shù)再調(diào)用其他函數(shù)的層層調(diào)用方式。函數(shù)的嵌套調(diào)用關(guān)系圖main()調(diào)用函數(shù)a結(jié)束函數(shù)a調(diào)用函數(shù)b函數(shù)b⑴⑵⑶⑷⑸⑹⑺⑻⑼調(diào)用函數(shù)d調(diào)用函數(shù)c函數(shù)c⑽⑾⑿⒁⒂函數(shù)d⒃⒀⒄例5.6【例5.6】使用函數(shù)的嵌套調(diào)用方法計(jì)算:分析問(wèn)題:從表達(dá)式中可以看出,每項(xiàng)都是一樣的,不同的是起止數(shù)不同,因此每項(xiàng)的計(jì)算可以由一個(gè)相同的函數(shù)sum()來(lái)完成。而每項(xiàng)中還有一個(gè)階乘,因此還需要一個(gè)求階乘的函數(shù)fac()。例5.6程序#include<stdio.h>doublefac(intn);doublesum(intn1,intn2);intmain(){doubles;s=sum(1,3)+sum(6,9)+sum(12,15);printf("\ns=%f",s);return(0);}/*求項(xiàng)的值:n1和n2為起止數(shù)*/doublesum(intn1,intn2){inti;doubles=0;for(i=n1;i<=n2;i++)s=s+1/fac(i);return(s);}例5.6程序(續(xù))/*求n的階乘函數(shù)*/doublefac(intn){doubles=n;if(n<=1)return1;for(;--n;)s*=n;return(s);}
main()調(diào)用函數(shù)sum結(jié)束函數(shù)fac例5.6函數(shù)嵌套調(diào)用關(guān)系用遞歸方法求n!值【例5.7】用遞歸方法求n!值。分析:使用遞歸方法。如計(jì)算5!可以用 5!=5×4! 4!=4×3! 3?。?×2! 2?。?×1! 1!=1其遞歸公式如下:n?。?當(dāng)(n=0,1)//遞歸結(jié)束條件n×(n-1)!當(dāng)(n>1)//遞歸方式分析問(wèn)題求n!時(shí),要先求(n-1)!;求(n-1)!時(shí),要先求(n-2)!值;……;直到求2!要知道1!為止。這個(gè)過(guò)程稱之為“回推”過(guò)程。規(guī)定1!=1;這時(shí)就可以求2!,……;當(dāng)求出(n-1)!值時(shí),就可以求出n!。這個(gè)過(guò)程稱之為“遞推”過(guò)程?!盎赝啤焙汀斑f推”過(guò)程構(gòu)成了“遞歸”問(wèn)題的兩個(gè)階段。如果要求遞歸過(guò)程在有限步驟內(nèi),就必須有一個(gè)結(jié)束遞歸過(guò)程的條件。n!問(wèn)題的結(jié)束條件就是1!=1,過(guò)程就是n!=(n-1)!*n?!盎赝啤焙汀斑f推”5!5×4!4×3!3×2!2×1!15!4!×53!×42!×31!×21回推過(guò)程返回1返回1!×2=2返回2!×3=6返回3!×4=24返回4!×5=120終值120遞推過(guò)程調(diào)用函數(shù)函數(shù)返回值例5.7程序#include<stdio.h>longfac(intn); /*自定義函數(shù)聲明*/intmain(){intn;longr; /*定義長(zhǎng)整型變量存放n的階乘的值*/printf("\nInputn:");scanf("%d",&n);if(n<0) /*當(dāng)n正確時(shí)求階乘,錯(cuò)誤時(shí)則提示*/printf("InputDataerror(n<0).\n");else{r=fac(n); /*調(diào)用求n的階乘函數(shù),返回r*/printf("%d!=%ld\n",n,r);/*輸出n和r的值*/}return(0);}/*定義求n的階乘的遞歸函數(shù)fac*/longfac(intn){longr;if(n==0||n==1)r=1;/*結(jié)束條件,其返回值是1*/elser=fac(n-1)*n;/*遞歸方式,返回n!值*/return(r);/*返回fac的函數(shù)值*/}函數(shù)的遞歸調(diào)用
在函數(shù)調(diào)用中,如果直接或間接地調(diào)用該函數(shù)本身,稱為遞歸調(diào)用。遞歸有時(shí)也稱為循環(huán)定義。遞歸又分為:直接遞歸調(diào)用,即函數(shù)直接調(diào)用自身。和間接調(diào)用,即函數(shù)互相調(diào)用對(duì)方。fun()調(diào)fun調(diào)g調(diào)ff()g()intfun(intx){inty,z;……
z=fun(y);…….return(2*z);}intf(intx){inty,z;……
z=g(y);…….return(2*z);}intg(intt){inta,c;……
c=f(a);…….return(3+c);}遞歸調(diào)用的說(shuō)明上述兩種遞歸調(diào)用都是無(wú)終止的自身調(diào)用。程序中不應(yīng)出現(xiàn)無(wú)終止調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的有終止的遞歸調(diào)用??梢允褂胕f語(yǔ)句來(lái)控制。遞歸程序由遞歸方式與遞歸終止條件兩部分組成。即一個(gè)遞歸的問(wèn)題可以分為:首先“回推”,然后“遞推”。在遞歸過(guò)程中,必須具有一個(gè)結(jié)束遞歸過(guò)程的條件。C編譯系統(tǒng)對(duì)遞歸函數(shù)的自調(diào)用次數(shù)沒(méi)有限制。每調(diào)用函數(shù)一次,在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù)變量、返回值等信息,所以遞歸次數(shù)過(guò)多,可能引起堆棧溢出。遞歸形式當(dāng)有函數(shù)返回值時(shí),通用的遞歸函數(shù)體表述如下:if(遞歸結(jié)束條件)return(遞歸公式的初值);elsereturn(遞歸函數(shù)調(diào)用返回的結(jié)果值);有時(shí)遞歸函數(shù)并不返回任何值,只是輸出顯示結(jié)果。有時(shí)遞歸子問(wèn)題和原問(wèn)題的形式并不完全相同,這時(shí)必須把問(wèn)題作一個(gè)小的變化,使得遞歸子問(wèn)題與原問(wèn)題完全相同。例5.8【例5.8】用遞歸方法求解斐波納契(Fibonacci)數(shù)列。分析問(wèn)題:斐波納契數(shù)列:0,1,1,2,3,5,8,13,21,34,…。第n項(xiàng)的遞歸公式為:fib(n)=n(n=0,1)/*遞歸結(jié)束條件*/fib(n-2)+fib(n-1)(n>1)/*遞歸方式*/第n項(xiàng)斐波納契數(shù)列值是前兩項(xiàng)的和,這是遞歸方式;而當(dāng)n=0和1時(shí),斐波納契數(shù)列就是n值本身,這是遞歸結(jié)束條件。例5.8程序#include<stdio.h>longfib(intn);/*自定義函數(shù)聲明*/voidmain(){longs;/*第i項(xiàng)斐波納契數(shù)列的值*/inti=0;/*斐波納契數(shù)列某項(xiàng)的序號(hào)*/do{printf("InputFibonacciNumber:");scanf("%d",&i);/*輸入要求的某一項(xiàng)的序號(hào)*/s=fib(i);/*求斐波納契數(shù)列第i項(xiàng)*/printf("Fib(%d)=%ld\n",i,s);}while(i>0);/*循環(huán)輸入序號(hào),直到i值小于等于0*/}/*定義求第n項(xiàng)斐波那契數(shù)列值的函數(shù)*/longfib(intn){if(n==0||n==1)/*判斷是否為結(jié)束條件*/returnn;elsereturnfib(n-2)+fib(n-1);/*求斐波納契數(shù)列的遞歸方式*/}變量的作用域局部變量——在語(yǔ)句塊(一對(duì)花括號(hào)括起來(lái)的區(qū)域)內(nèi)定義,僅在定義它的語(yǔ)句塊內(nèi)有效,并且擁有自己獨(dú)立的存儲(chǔ)空間全局變量——在函數(shù)之外定義的變量,可以在本文件的所有函數(shù)中使用,有效范圍從定義變量的位置開(kāi)始到文件結(jié)束說(shuō)明在一個(gè)函數(shù)中既可以使用本函數(shù)中的局部變量,又可以使用有效的全局變量可以利用全局變量增加與函數(shù)聯(lián)系的渠道,從函數(shù)得到一個(gè)以上的返回值。全局變量相當(dāng)于各個(gè)函數(shù)間的傳遞通道為了便于區(qū)別全局變量和局部變量,C語(yǔ)言中有一個(gè)不成文的規(guī)定,即將全局變量名的第一個(gè)字母用大寫表示編程時(shí)一般不要使用全局變量,因?yàn)槿肿兞恳恢闭加么鎯?chǔ)空間,降低了函數(shù)的通用性,降低了程序的清晰性,易出錯(cuò)變量的存儲(chǔ)空間變量是對(duì)程序中數(shù)據(jù)的存儲(chǔ)空間的抽象內(nèi)存…….voidmain(){inta;a=10;printf(“%d”,a);}編譯或函數(shù)調(diào)用時(shí)為其分配內(nèi)存單元1020002001程序中使用變量名對(duì)內(nèi)存操作變量的屬性變量的屬性包括操作屬性和存儲(chǔ)屬性。操作屬性以數(shù)據(jù)類型形式表現(xiàn)出來(lái)。存儲(chǔ)屬性即存儲(chǔ)器類型,它說(shuō)明變量占用存儲(chǔ)空間的區(qū)域。數(shù)據(jù)類型:變量所持有的數(shù)據(jù)的性質(zhì)(操作屬性)存儲(chǔ)屬性:存儲(chǔ)器類型:寄存器、靜態(tài)存儲(chǔ)區(qū)、動(dòng)態(tài)存儲(chǔ)區(qū)生存期:變量在某一時(shí)刻存在-------靜態(tài)變量與動(dòng)態(tài)變量作用域:變量在某區(qū)域內(nèi)有效-------局部變量與全局變量變量的作用域變量的作用域是指變量的可見(jiàn)范圍或可使用的有效范圍,即變量的“可見(jiàn)性”。變量的作用域可以在一個(gè)函數(shù)范圍內(nèi),也可以在整個(gè)程序范圍內(nèi)。變量可以在程序中三個(gè)地方說(shuō)明:函數(shù)內(nèi)部、函數(shù)的參數(shù)定義中或所有函數(shù)的外部。函數(shù)內(nèi)部定義的變量、函數(shù)的參數(shù)變量、被一對(duì)大括號(hào){}括起來(lái)的區(qū)域(語(yǔ)句塊)定義的變量等均為局部變量,函數(shù)外部定義的變量則為全局變量。局部變量、全局變量等的作用域是不一樣的。局部變量的作用域舉例#include<stdio.h>voidmain(){inta,b;…{intc;c=a+b;…}…}變量c的作用范圍變量a、b的作用范圍全局變量的作用域舉例#include<stdio.h>floatf1(inta);/*函數(shù)聲明*/intx=1,y=5;/*定義全局變量*/voidmain(){intm,n;/*定義局部變量*/m=x+10;…}floatf2(inta,intb);/*函數(shù)聲明*/floatf1(inta)/*定義函數(shù),函數(shù)參數(shù)是局部變量*/{intb,c;/*定義局部變量*/…}charc1,c2;/*定義全局變量*/floatf2(inta,intb)/*定義函數(shù),函數(shù)參數(shù)是局部變量*/{inti,j,x;/*定義局部變量*/x=6;…}floats1,s2;/*定義全局變量*/全局變量c1、c2的作用范圍全局變量x、y的作用范圍例5.9【例5.9】輸入正方體的長(zhǎng)l、寬w、高h(yuǎn),求體積及三個(gè)不同面的面積。分析問(wèn)題:可以定義s1、s2、s3三個(gè)全局變量,分別表示三個(gè)不同面的面積,并在求體積vs()函數(shù)中一并計(jì)算,然后在主函數(shù)main()中輸出。例5.9程序#include<stdio.h>ints1,s2,s3;/*定義全局變量s1、s2、s3*/intvs(inta,intb,intc);/*自定義函數(shù)聲明*/intmain(){intv,l,w,h;/*定義局部變量v、l、w、h*/printf("\ninputlength,widthandheight\n");scanf("%d,%d,%d",&l,&w,&h);v=vs(l,w,h);printf("v=%d,s1=%d,s2=%d,s3=%d\n",v,s1,s2,s3);return(0);}intvs(inta,intb,intc){intv;/*在vs()函數(shù)中定義局部變量v*/v=a*b*c;s1=a*b;/*自定義函數(shù)中引用s1、s2、s3*/s2=b*c;s3=a*c;return(v);}變量的存儲(chǔ)類型從變量的作用域角度來(lái)分,變量可以分為全局變量和局部變量而從變量值存在的時(shí)間(即生存期)角度來(lái)分,變量可以分為靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式靜態(tài)存儲(chǔ)方式是指程序運(yùn)行期間分配固定的存儲(chǔ)空間,該空間從分配時(shí)刻開(kāi)始存在,直到程序運(yùn)行結(jié)束才釋放動(dòng)態(tài)存儲(chǔ)方式是指程序運(yùn)行期間根據(jù)需要?jiǎng)討B(tài)分配存儲(chǔ)空間,該空間使用結(jié)束后自動(dòng)釋放,下次需要時(shí)再分配存儲(chǔ)類型的提出下面程序的最后定義全局變量A、B有意義嗎?要使它能使用,必須通過(guò)通過(guò)externintA,B;語(yǔ)句擴(kuò)展其作用域。這就是變量的存儲(chǔ)類型所要做的事情(參見(jiàn)例5.11)。#include<stdio.h>intmax(intx,inty){intz;z=x>y?x:y;return(z);}voidmain(){printf("max=%d",max(a,b));}intA=13,B=-8;externintA,B;變量A、B本程序中無(wú)效變量A、B的有效范圍存儲(chǔ)類型的分類與定義變量的存儲(chǔ)類型分類auto-----自動(dòng)型register-----寄存器型static------靜態(tài)型extern-----外部型變量定義格式:[存儲(chǔ)類型]數(shù)據(jù)類型變量表;如:intsum;
autointa,b,c;
registerinti;
staticfloatx,y;動(dòng)態(tài)變量與靜態(tài)變量動(dòng)態(tài)變量與靜態(tài)變量,是從變量的生存期角度來(lái)分類的。1.存儲(chǔ)方式靜態(tài)存儲(chǔ):程序運(yùn)行期間分配固定存儲(chǔ)空間。動(dòng)態(tài)存儲(chǔ):程序運(yùn)行期間根據(jù)需要?jiǎng)討B(tài)分配存儲(chǔ)空間。2.內(nèi)存用戶區(qū)程序區(qū)靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)存儲(chǔ)區(qū)全局變量、局部靜態(tài)變量形參變量局部動(dòng)態(tài)變量(autoregister)函數(shù)調(diào)用現(xiàn)場(chǎng)保護(hù)和返回地址等3.生存期靜態(tài)變量:從程序開(kāi)始執(zhí)行到程序結(jié)束。動(dòng)態(tài)變量:從包含該變量定義的函數(shù)開(kāi)始執(zhí)行至函數(shù)執(zhí)行結(jié)束。自動(dòng)變量auto在C語(yǔ)言中,函數(shù)內(nèi)部定義的變量(局部變量)默認(rèn)為自動(dòng)變量(automaticvariable)。關(guān)鍵字auto能夠顯式地指定存儲(chǔ)類別。顯式定義
autointx,y;隱含定義等價(jià)intx,y;關(guān)鍵字“auto”可以省略,auto不寫則隱含確定為“自動(dòng)存儲(chǔ)類別”,即動(dòng)態(tài)存儲(chǔ)方式。程序中大多數(shù)變量屬于自動(dòng)變量。auto的作用域main(){intx=1;voidprt(void);{intx=3;prt();printf(“2ndx=%d\n”,x);}printf(“1stx=%d\n”,x);}voidprt(void){intx=5;printf(“3thx=%d\n”,x);}運(yùn)行結(jié)果:3thx=52ndx=31stx=1x=1作用域x=1作用域x=3作用域x=5作用域寄存器變量register
對(duì)于使用頻繁的變量,可以使用register聲明為寄存器變量,其值存儲(chǔ)在CPU中,加快了運(yùn)行速度。如:registerintx;registercharc;說(shuō)明:①只有局部自動(dòng)變量和形式參數(shù)可以作為寄存器變量,其余非法。②一個(gè)計(jì)算機(jī)系統(tǒng)中的寄存器數(shù)目是有限的,不能定義任意多個(gè)寄存器變量。③一般來(lái)講只允許int和char才能定義為寄存器變量,但目前大多數(shù)系統(tǒng)都支持指針型變量定義為寄存器變量。④局部靜態(tài)變量不能定義為寄存器變量,即不能定義:registerstaticintx;,對(duì)一個(gè)變量只能聲明一個(gè)存儲(chǔ)類別。⑤當(dāng)今優(yōu)化的編譯系統(tǒng),能夠自動(dòng)識(shí)別使用頻繁的變量,從而自動(dòng)的將這些變量放在寄存器中。因此程序設(shè)計(jì)者實(shí)際上根本不需要去聲明寄存器變量。用static聲明局部變量
有時(shí)希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,以便下一次調(diào)用該函數(shù)時(shí)可以使用上一次調(diào)用的最后結(jié)果。這時(shí)就應(yīng)該指定該局部變量為“靜態(tài)局部變量”。#include<stdio.h>voidmain(){voidincrement(void);increment();increment();increment();}voidincrement(void){intx=0;x++;printf(“%d\n”,x);}運(yùn)行結(jié)果:111#include<stdio.h>voidmain(){voidincrement(void);increment();increment();increment();}voidincrement(void){staticintx=0;x++;printf(“%d\n”,x);}運(yùn)行結(jié)果:123例:局部靜態(tài)變量值具有可繼承性例5.10【例5.10】用靜態(tài)變量實(shí)現(xiàn)計(jì)算1~5的階乘的程序。分析問(wèn)題:
n!=1*2*…*(n-1)*n,可以依次計(jì)算1!=1,2!=1!*2,3!=2!*3,…,n!=(n-1)!*n。也就是說(shuō),計(jì)算n!需要使用前面的(n-1)!值,而(n-1)!值可以使用靜態(tài)變量來(lái)存儲(chǔ)。例5.10程序#include<stdio.h>intfac(inti);/*計(jì)算階乘的函數(shù)聲明*/intmain(){inti,r;/*如果i值頻繁使用,編譯器會(huì)自動(dòng)以寄存器變量存放*/for(i=1;i<=5;i++){r=fac(i);/*調(diào)用計(jì)算i的階乘函數(shù)*/printf("%d!=%d\n",i,r);}return(0);}/*定義計(jì)算i的階乘的函數(shù)*/intfac(inti){staticintf=1;/*定義靜態(tài)變量f存放階乘值,第一次調(diào)用時(shí)賦初值*/if(i>=1)f=f*i;/*f的初值為上次計(jì)算的f值*/return(f);}用extern聲明外部變量外部變量(即全局變量)是在函數(shù)的外部定義的,它的作用域?yàn)閺淖兞康亩x處開(kāi)始,到本程序文件的末尾。在此作用域內(nèi),全局變量可以為程序中各個(gè)函數(shù)所引用。編譯時(shí)將外部變量分配在靜態(tài)存儲(chǔ)區(qū)。有時(shí)需要用extern來(lái)聲明外部變量,以擴(kuò)展外部變量的作用域。如果全局變量在后面定義,而在前面的函數(shù)中要使用,則必須在使用前用extern聲明該全局變量。如:externintAbc;
也可以省略int成:externAbc;全局變量的定義與使用extern聲明的主要區(qū)別
項(xiàng)目全局變量的定義使用extern聲明次數(shù)只能1次可聲明多次位置所有函數(shù)之外函數(shù)內(nèi)或函數(shù)外分配內(nèi)存分配內(nèi)存
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- JJG 2097-2024太赫茲輻射功率計(jì)量器具檢定系統(tǒng)表
- 2024年度云南省高校教師資格證之高等教育學(xué)模擬考試試卷A卷含答案
- 贛南師范大學(xué)《課外音樂(lè)活動(dòng)的組織與指導(dǎo)》2022-2023學(xué)年第一學(xué)期期末試卷
- 阜陽(yáng)師范大學(xué)《學(xué)前比較教育》2023-2024學(xué)年第一學(xué)期期末試卷
- 阜陽(yáng)師范大學(xué)《非政府組織管理》2022-2023學(xué)年第一學(xué)期期末試卷
- 南京市2024-2025學(xué)年三年級(jí)上學(xué)期11月期中調(diào)研數(shù)學(xué)試卷一(有答案)
- 福建師范大學(xué)《綜合自然地理》2023-2024學(xué)年第一學(xué)期期末試卷
- 福建師范大學(xué)《演藝娛樂(lè)經(jīng)營(yíng)管理》2022-2023學(xué)年第一學(xué)期期末試卷
- 專題77 實(shí)驗(yàn)八:其它測(cè)量電阻的方法(含答案)-十年(2014-2023)高考物理真題分項(xiàng)匯編(全國(guó)用)
- 福建師范大學(xué)《小學(xué)課程與教學(xué)研究》2022-2023學(xué)年第一學(xué)期期末試卷
- 2022年癲癇性精神病臨床路徑
- 三年級(jí)心理健康教學(xué)課件 第15課 專注的力量
- 廣西壯族自治區(qū)北海市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名明細(xì)居民村民委員會(huì)
- 藥劑科質(zhì)量與安全管理考核表正式版
- 新教材高考化學(xué)一輪復(fù)習(xí)元素“位-構(gòu)-性”推斷技巧及元素周期律應(yīng)用中的關(guān)鍵點(diǎn)課件(19張)
- 無(wú)機(jī)離子檢測(cè)
- 五年級(jí)上冊(cè)數(shù)學(xué)課件 - 三角形的面積 人教版(共16張PPT)
- 乳腺癌科普講座課件
- 2022年《國(guó)民經(jīng)濟(jì)行業(yè)分類》
- 通止規(guī)設(shè)計(jì)公差自動(dòng)計(jì)算表
- 胃癌淋巴結(jié)清掃ppt課件(PPT 39頁(yè))
評(píng)論
0/150
提交評(píng)論