版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(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ì)思想在軟件工程中,通常采用“自頂向下、分而治之”的方法,將大問題分解成若干小的問題,如果小問題還不容易解決,就再分解成更小的問題。模塊化程序設(shè)計(jì)的基本思想,是將一個(gè)大的復(fù)雜的程序按功能分割成一些小的功能模塊。當(dāng)開發(fā)一個(gè)軟件系統(tǒng)時(shí),最好的辦法是從編寫主程序開始,在主程序中,將問題作為一個(gè)整體考慮,找出完成任務(wù)的主要步驟,再沿著這條主線將整個(gè)問題繼續(xù)分解為獨(dú)立的簡(jiǎn)單模塊,這就是模塊化程序設(shè)計(jì)的主要思想。模塊分解的原則模塊分解——“自頂向下、逐步求精”的程序設(shè)計(jì)過程模塊分解的基本原則——高聚合、低耦合及信息隱藏高聚合——一個(gè)模塊只能完成單一的功能,不能“身兼數(shù)職”低耦合——模塊之間參數(shù)傳遞盡量少,也不能通過全局變量來實(shí)現(xiàn)數(shù)據(jù)傳遞信息隱藏——把不需要調(diào)用者知道的信息都包裝在模塊內(nèi)部隱藏起來凡是被眾多模塊公用的程序,均應(yīng)設(shè)計(jì)成一個(gè)獨(dú)立的模塊各模塊間應(yīng)在功能上、邏輯上相互獨(dú)立,模塊間的接口應(yīng)盡量簡(jiǎn)單,其數(shù)據(jù)傳遞使用參數(shù)來完成每個(gè)模塊應(yīng)設(shè)計(jì)成單入口、單出口形式,以便調(diào)試與閱讀,提高程序的可靠性模塊化設(shè)計(jì)方法功能分解自頂向下、逐步求精的過程。每個(gè)模塊的功能盡量單一,程序代碼最好不要超過50行。模塊分解的原則保證模塊的相對(duì)獨(dú)立性(高聚合、低耦合)。模塊的實(shí)現(xiàn)細(xì)節(jié)對(duì)外不可見(外部:關(guān)心做什么;內(nèi)部:關(guān)心怎么做)。設(shè)計(jì)好模塊接口接口是指羅列出一個(gè)模塊的所有的與外部打交道的變量等。定義好后不要輕易改動(dòng)。在模塊開頭(文件的開頭)進(jìn)行函數(shù)聲明。模塊化程序設(shè)計(jì)的特點(diǎn)各模塊相對(duì)獨(dú)立、功能單一、結(jié)構(gòu)清晰、接口簡(jiǎn)單程序設(shè)計(jì)的復(fù)雜性得到了有效控制縮短開發(fā)周期避免程序開發(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ì)來看,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)行有效性檢查沒有參數(shù)和返回值時(shí),用void填充每個(gè)函數(shù)只有一個(gè)入口和一個(gè)出口,盡量不使用全局變量盡量少用靜態(tài)局部變量,以避免使函數(shù)具有“記憶”功能函數(shù)的定義合法標(biāo)識(shí)符函數(shù)返回值類型:缺省int型,無返回值void函數(shù)體函數(shù)類型函數(shù)名(形式參數(shù)類型說明表){
聲明部分 執(zhí)行部分}現(xiàn)代風(fēng)格:例有參函數(shù)(現(xiàn)代風(fēng)格)
intmax(intx,inty){intz;z=x>y?x:y;return(z);}例空函數(shù)
dummy(){}函數(shù)體為空例無參函數(shù)voidprintstar(){printf(“**********\n”);}或voidprintstar(void){printf(“**********\n”);}參數(shù):傳遞數(shù)據(jù)信息的通道函數(shù)定義說明①類型說明符可為:int、char、float、double等。表示在調(diào)用了該函數(shù)后,其返回值的數(shù)據(jù)類型;如果函數(shù)無數(shù)據(jù)返回時(shí),應(yīng)使用void
作類型定義符。注意,省略了類型說明符,編譯程序默認(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ù)的定義中,如果沒有函數(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ù)體的開始。例如,以下定義是不允許的: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í)施是通過函數(shù)的參數(shù)來實(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)用過程中的參數(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)用過程中的結(jié)果返回c=;
intmax(intx,inty){intz;z=x>y?x:y;return(z);}max(a,b)57=77777無返回函數(shù)的調(diào)用#include<stdio.h>voidmain(){printstar();}voidprintstar(){printf(“**********\n”);}作為一個(gè)函數(shù)語(yǔ)句調(diào)用函數(shù)調(diào)用說明如果調(diào)用的是無參函數(shù),“實(shí)際參數(shù)表”可以沒有,但括號(hào)()不能省略。如果實(shí)參表包含多個(gè)實(shí)參,則各參數(shù)間用逗號(hào)隔開。實(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,說明m不是素?cái)?shù){ flag=0; break;} //跳出循環(huán),減少無效的循環(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,用來計(jì)算以下多項(xiàng)式之和的函數(shù)sum=1+2+3+……+n課堂作業(yè)2編寫一個(gè)能根據(jù)提供的數(shù)值n,在屏幕上輸出一行n個(gè)星號(hào)的函數(shù)(n由主調(diào)函數(shù)傳遞而來)課堂作業(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ì)算過程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ì)算過程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ù)的差值。分析問題:首先在主函數(shù)main()中調(diào)用求差值的函數(shù)dif()在求差值函數(shù)中再調(diào)用求三個(gè)數(shù)的最大值函數(shù)max()和最小值函數(shù)min()將一個(gè)復(fù)雜的問題分解成了三個(gè)小問題:求兩個(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):編程求的值。分析問題:可以定義一個(gè)函數(shù)doublefff(doublex)來求值,然后在主函數(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ù)說明:函數(shù)中可有多個(gè)return語(yǔ)句,但只能返回唯一的函數(shù)值若無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ù):表示“空類型”或“無類型”例無返回值函數(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ù)之和。分析問題:可以定義一個(gè)函數(shù)intadd(intx,inty)來求兩個(gè)數(shù)之和的值,并通過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ù)說明(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ù)說明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();不提倡?;颍篺loatadd(floatx,floaty);例5.5【例5.5】用函數(shù)實(shí)現(xiàn):求兩個(gè)數(shù)的最大公約數(shù)和最小公倍數(shù)。分析問題:
最大公約數(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值相同。換句話說,最大公約數(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ù)之間是平行的,無主從輕重,可以相互調(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ì)算:分析問題:從表達(dá)式中可以看出,每項(xiàng)都是一樣的,不同的是起止數(shù)不同,因此每項(xiàng)的計(jì)算可以由一個(gè)相同的函數(shù)sum()來完成。而每項(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?。?×4! 4!=4×3! 3?。?×2! 2?。?×1! 1?。?其遞歸公式如下:n!=1當(dāng)(n=0,1)//遞歸結(jié)束條件n×(n-1)!當(dāng)(n>1)//遞歸方式分析問題求n!時(shí),要先求(n-1)!;求(n-1)!時(shí),要先求(n-2)!值;……;直到求2!要知道1!為止。這個(gè)過程稱之為“回推”過程。規(guī)定1!=1;這時(shí)就可以求2!,……;當(dāng)求出(n-1)!值時(shí),就可以求出n!。這個(gè)過程稱之為“遞推”過程?!盎赝啤焙汀斑f推”過程構(gòu)成了“遞歸”問題的兩個(gè)階段。如果要求遞歸過程在有限步驟內(nèi),就必須有一個(gè)結(jié)束遞歸過程的條件。n!問題的結(jié)束條件就是1!=1,過程就是n!=(n-1)!*n?!盎赝啤焙汀斑f推”5!5×4!4×3!3×2!2×1!15!4!×53!×42!×31!×21回推過程返回1返回1!×2=2返回2!×3=6返回3!×4=24返回4!×5=120終值120遞推過程調(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)用的說明上述兩種遞歸調(diào)用都是無終止的自身調(diào)用。程序中不應(yīng)出現(xiàn)無終止調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的有終止的遞歸調(diào)用。可以使用if語(yǔ)句來控制。遞歸程序由遞歸方式與遞歸終止條件兩部分組成。即一個(gè)遞歸的問題可以分為:首先“回推”,然后“遞推”。在遞歸過程中,必須具有一個(gè)結(jié)束遞歸過程的條件。C編譯系統(tǒng)對(duì)遞歸函數(shù)的自調(diào)用次數(shù)沒有限制。每調(diào)用函數(shù)一次,在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù)變量、返回值等信息,所以遞歸次數(shù)過多,可能引起堆棧溢出。遞歸形式當(dāng)有函數(shù)返回值時(shí),通用的遞歸函數(shù)體表述如下:if(遞歸結(jié)束條件)return(遞歸公式的初值);elsereturn(遞歸函數(shù)調(diào)用返回的結(jié)果值);有時(shí)遞歸函數(shù)并不返回任何值,只是輸出顯示結(jié)果。有時(shí)遞歸子問題和原問題的形式并不完全相同,這時(shí)必須把問題作一個(gè)小的變化,使得遞歸子問題與原問題完全相同。例5.8【例5.8】用遞歸方法求解斐波納契(Fibonacci)數(shù)列。分析問題:斐波納契數(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)括起來的區(qū)域)內(nèi)定義,僅在定義它的語(yǔ)句塊內(nèi)有效,并且擁有自己獨(dú)立的存儲(chǔ)空間全局變量——在函數(shù)之外定義的變量,可以在本文件的所有函數(shù)中使用,有效范圍從定義變量的位置開始到文件結(jié)束說明在一個(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)出來。存儲(chǔ)屬性即存儲(chǔ)器類型,它說明變量占用存儲(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)有效-------局部變量與全局變量變量的作用域變量的作用域是指變量的可見范圍或可使用的有效范圍,即變量的“可見性”。變量的作用域可以在一個(gè)函數(shù)范圍內(nèi),也可以在整個(gè)程序范圍內(nèi)。變量可以在程序中三個(gè)地方說明:函數(shù)內(nèi)部、函數(shù)的參數(shù)定義中或所有函數(shù)的外部。函數(shù)內(nèi)部定義的變量、函數(shù)的參數(shù)變量、被一對(duì)大括號(hào){}括起來的區(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è)不同面的面積。分析問題:可以定義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ǔ)類型從變量的作用域角度來分,變量可以分為全局變量和局部變量而從變量值存在的時(shí)間(即生存期)角度來分,變量可以分為靜態(tài)存儲(chǔ)方式和動(dòng)態(tài)存儲(chǔ)方式靜態(tài)存儲(chǔ)方式是指程序運(yùn)行期間分配固定的存儲(chǔ)空間,該空間從分配時(shí)刻開始存在,直到程序運(yùn)行結(jié)束才釋放動(dòng)態(tài)存儲(chǔ)方式是指程序運(yùn)行期間根據(jù)需要?jiǎng)討B(tài)分配存儲(chǔ)空間,該空間使用結(jié)束后自動(dòng)釋放,下次需要時(shí)再分配存儲(chǔ)類型的提出下面程序的最后定義全局變量A、B有意義嗎?要使它能使用,必須通過通過externintA,B;語(yǔ)句擴(kuò)展其作用域。這就是變量的存儲(chǔ)類型所要做的事情(參見例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本程序中無效變量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)變量,是從變量的生存期角度來分類的。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)變量:從程序開始執(zhí)行到程序結(jié)束。動(dòng)態(tài)變量:從包含該變量定義的函數(shù)開始執(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;說明:①只有局部自動(dòng)變量和形式參數(shù)可以作為寄存器變量,其余非法。②一個(gè)計(jì)算機(jī)系統(tǒng)中的寄存器數(shù)目是有限的,不能定義任意多個(gè)寄存器變量。③一般來講只允許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的階乘的程序。分析問題:
n!=1*2*…*(n-1)*n,可以依次計(jì)算1!=1,2!=1!*2,3!=2!*3,…,n!=(n-1)!*n。也就是說,計(jì)算n!需要使用前面的(n-1)!值,而(n-1)!值可以使用靜態(tà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處開始,到本程序文件的末尾。在此作用域內(nèi),全局變量可以為程序中各個(gè)函數(shù)所引用。編譯時(shí)將外部變量分配在靜態(tài)存儲(chǔ)區(qū)。有時(shí)需要用extern來聲明外部變量,以擴(kuò)展外部變量的作用域。如果全局變量在后面定義,而在前面的函數(shù)中要使用,則必須在使用前用extern聲明該全局變量。如:externintAbc;
也可以省略int成:externAbc;全局變量的定義與使用extern聲明的主要區(qū)別
項(xiàng)目全局變量的定義使用extern聲明次數(shù)只能1次可聲明多次位置所有函數(shù)之外函數(shù)內(nèi)或函數(shù)外分配內(nèi)存分配內(nèi)存
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司勞務(wù)派遣協(xié)議書七篇
- 公司協(xié)議書大全
- 萬能施工安全協(xié)議書
- 面部發(fā)紅發(fā)熱病因介紹
- 進(jìn)行性球麻痹病因介紹
- 29化學(xué)中考真題匯編《溶液》及答案
- 中考政治第一部分知識(shí)闖關(guān)能力提升第5課時(shí)平等禮貌待人理解寬容他人復(fù)習(xí)課獲
- (范文)卷板機(jī)項(xiàng)目立項(xiàng)報(bào)告
- (2024)吸痰管項(xiàng)目可行性研究報(bào)告寫作范本(一)
- 2023年電子陶瓷材料項(xiàng)目融資計(jì)劃書
- 主要農(nóng)作物(糧食作物)課件
- 百詞斬-定語(yǔ)從句課件-(;)
- 珍惜時(shí)間主題班會(huì)-做時(shí)間的主人課件
- 市政工程施工總體部署
- 護(hù)士準(zhǔn)入申請(qǐng)表
- 三年級(jí)上冊(cè)英語(yǔ)課件-Unit3 Look at me-人教(PEP) (6)(共30張PPT)
- 西方音樂史課程大綱
- 糖皮質(zhì)激素在呼吸科的應(yīng)用課件
- 合法離婚協(xié)議書(2篇)
- 2022年廣東南方報(bào)業(yè)傳媒集團(tuán)有限公司招聘筆試題庫(kù)及答案解析
- 20m29.6m30.4m20m鋼箱梁橋?qū)嵗O(shè)計(jì)內(nèi)容與表達(dá)
評(píng)論
0/150
提交評(píng)論