




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1第4章模塊化程序設(shè)計(jì)
2教學(xué)目標(biāo)理解如何用函數(shù)構(gòu)造程序模塊會(huì)聲明、定義和調(diào)用函數(shù)并理解函數(shù)調(diào)用的機(jī)制掌握變量的作用域和存儲(chǔ)類別34.1模塊化程序設(shè)計(jì)概述4.2函數(shù)的聲明、定義和調(diào)用4.3函數(shù)的多級(jí)調(diào)用4.4變量的作用域和存儲(chǔ)類別4.5計(jì)算機(jī)隨機(jī)模擬方法〔不要求〕4.6編譯預(yù)處理4復(fù)雜任務(wù)可以分解為假設(shè)干子任務(wù)。重復(fù)使用的程序段,將其進(jìn)行獨(dú)立設(shè)計(jì),使計(jì)算機(jī)可以重復(fù)執(zhí)行。程序執(zhí)行從主控程序開始、也從主控程序結(jié)束。分段設(shè)計(jì)的出發(fā)點(diǎn)在于一個(gè)程序模塊對(duì)于某個(gè)問題的解決應(yīng)保持相對(duì)的完整性。main()func1()func2()func3()func4()func5()func6()圖4-1程序模塊結(jié)構(gòu)圖4.1
模塊化程序設(shè)計(jì)概述5源文件1函數(shù)n函數(shù)2函數(shù)1源文件m源文件2函數(shù)是C語言的根本構(gòu)件一個(gè)C程序
一個(gè)C程序的源文件............64.2函數(shù)的聲明、定義和調(diào)用引例函數(shù)說明函數(shù)定義函數(shù)調(diào)用及參數(shù)的傳遞帶自定義函數(shù)的程序設(shè)計(jì)7引例
/*程序名:4_1.cpp*//*功能:計(jì)算兩個(gè)實(shí)數(shù)中大的值*/#include<stdio.h>floatfmax(floatx,floaty);
/*函數(shù)說明*/voidmain(){floata,b,c;scanf("%f,%f",&a,&b);c=fmax(a,b);/*函數(shù)調(diào)用*/printf("max=%f\n",c);}floatfmax(floatx,floaty)
/*函數(shù)定義*/{floatz;z=x>y?x:y;returnz;}8函數(shù)定義
函數(shù)定義的一般形式:函數(shù)返回值類型函數(shù)名(類型名形參1,類型名形參2,…)/*函數(shù)頭*/{ /*函數(shù)體*/
函數(shù)實(shí)現(xiàn)過程}例如floatfmax(floatx,floaty){floatz;z=x>y?x:y;
returnz;}不能省略必為變量結(jié)束本函數(shù)的執(zhí)行并返回函數(shù)值此處不能有分號(hào)可以沒有參數(shù)9函數(shù)定義的幾點(diǎn)說明在定義函數(shù)時(shí)不指定函數(shù)返回值類型,系統(tǒng)會(huì)隱含指定函數(shù)返回值類型為int型。一個(gè)函數(shù)可有多個(gè)return語句。一個(gè)return語句只能返回一個(gè)值。如果被調(diào)函數(shù)中沒有return語句,函數(shù)并不是不帶回值。對(duì)不返回值的函數(shù),要使用關(guān)鍵字void,但可以在函數(shù)體中使用return;。即使函數(shù)沒有參數(shù),其名后的括弧也不能省。函數(shù)頭與函數(shù)說明不同,函數(shù)頭不是一條語句。10函數(shù)說明(函數(shù)原型)
說明格式為:
函數(shù)返回值類型函數(shù)名(參數(shù)表);#include<stdio.h>floatfmax(floatx,floaty);
/*函數(shù)說明*/voidmain(){floata,b,c;scanf("%f,%f",&a,&b);
c=fmax(a,b);printf("max=%f\n",c);}函數(shù)說明是一條語句,它指出函數(shù)返回值的類型、函數(shù)的名稱、函數(shù)要接收的參數(shù)的個(gè)數(shù)、順序和類型。如果在一個(gè)函數(shù)中要調(diào)用另外一個(gè)函數(shù),那么在調(diào)用之前要對(duì)該函數(shù)進(jìn)行說明。如果函數(shù)定義出現(xiàn)在程序中首次使用該函數(shù)之前,那么不需要說明函數(shù)原型。可省略必須有分號(hào)11函數(shù)調(diào)用及參數(shù)的傳遞
函數(shù)調(diào)用的一般形式為:
函數(shù)名(實(shí)參表)
voidmain(){floata,b,c;scanf("%f,%f",&a,&b);
c=fmax(a,b);printf("max=%f\n",c);}可用兩種方式調(diào)用函數(shù):(1)函數(shù)的調(diào)用可以作為表達(dá)式出現(xiàn)在允許表達(dá)式出現(xiàn)的任何地方。如:c=fmax(a,b)+3;(2)函數(shù)調(diào)用可以作為一條獨(dú)立的語句。比方,有函數(shù)定義:voidprintstar(){printf(“***************〞);}那么可以把該函數(shù)調(diào)用作為一個(gè)獨(dú)立語句。printstar();printf(“max=%f\n〞,fmax(a,b));可為常量,變量或表達(dá)式12函數(shù)返回值(函數(shù)值) 函數(shù)返回值的類型是由函數(shù)說明中的函數(shù)返回類型決定的。如果返回的類型與函數(shù)說明的不同,那么在返回值時(shí),先作隱含的類型轉(zhuǎn)換,然后再返回。#include<stdio.h>intfmax(floatx,floaty){returnx>y?x:y;}voidmain(){intmax;floata=3.5,b=2.6;
max=fmax(a,b);
printf("max=%d\n",max);}max=3floatreturn(x>y?x:y);13形參和實(shí)參形式參數(shù):定義函數(shù)時(shí)放在函數(shù)名稱之后括號(hào)中的參數(shù),簡(jiǎn)稱形參。形參必須是變量。實(shí)際參數(shù):調(diào)用函數(shù)時(shí)括號(hào)中的參數(shù),簡(jiǎn)稱實(shí)參。實(shí)參可為常量、變量或表達(dá)式。形參與實(shí)參的結(jié)合:函數(shù)調(diào)用時(shí),將生成實(shí)參值的一個(gè)副本傳遞給對(duì)應(yīng)的形參,這個(gè)過程稱為形參與實(shí)參的結(jié)合。只允許實(shí)參向形參傳遞數(shù)據(jù),那么稱為“單向傳遞〞。圖4-2實(shí)參和形參數(shù)據(jù)的傳遞3.53.52.62.6實(shí)參a實(shí)參b形參x形參y實(shí)參與形參必須一一對(duì)應(yīng),數(shù)量相同且類型一致14函數(shù)的調(diào)用過程
#include<stdio.h>floatfmax(float,float);voidmain(){floata,b,c;scanf(“%f,%f〞,&a,&b);c=fmax(a,b);printf(“max=%f\n〞,c);}floatfmax(floatx,floaty)
{floatz;z=x>y?x:y;returnz;}保存返回地址及當(dāng)前現(xiàn)場(chǎng),為形參分配內(nèi)存并將實(shí)參值的副本傳給形參變量恢復(fù)main函數(shù)的現(xiàn)場(chǎng),取得返回地址和返回值15帶自定義函數(shù)的程序設(shè)計(jì)
程序設(shè)計(jì)思路:(1)定義一個(gè)函數(shù)isprime(inta)判斷a是否為素?cái)?shù),假設(shè)是素?cái)?shù),函數(shù)返回1,否那么返回0。#include<stdio.h>#include<math.h>intisprime(inta)//函數(shù)定義{inti;if(a==1)return0;for(i=2;i<=sqrt(a);i++)if(a%i==0) return0;return1;}(2)在主函數(shù)中輸入一個(gè)整數(shù),調(diào)用isprime函數(shù),如果函數(shù)值為1,那么打印是素?cái)?shù),否那么打印不是素?cái)?shù)。voidmain(){intiNumber;printf("請(qǐng)輸入一個(gè)整數(shù):");scanf("%d",&iNumber);if(isprime(iNumber))//函數(shù)調(diào)用printf("%d是素?cái)?shù)\n",iNumber);elseprintf("%d不是素?cái)?shù)\n",iNumber);}【例4-2】從鍵盤輸入一個(gè)整數(shù),判斷該整數(shù)是否為素?cái)?shù)。16例題輸入圓柱的高和半徑,求圓柱體積,
volume=×r2×h。 要求定義和調(diào)用cylinder(r,h)計(jì)算圓柱體的體積。17/*計(jì)算圓柱體積*/#include<stdio.h>voidmain(){doubleheight,radius,volume; doublecylinder(doubler,doubleh);/*函數(shù)聲明*/ printf("Enterradiusandheight:"); scanf("%lf%lf",&radius,&height); /*調(diào)用函數(shù),返回值賦給volume*/ volume=cylinder(radius,height); printf("Volume=%.3f\n",volume);}/*定義求圓柱體積的函數(shù)*/doublecylinder(doubler,doubleh) { doubleresult; result=3.1415926*r*r*h;/*計(jì)算體積*/ returnresult; /*返回結(jié)果*/}18例題輸出5之內(nèi)的數(shù)字金字塔。
12233344445555519/*輸出數(shù)字金字塔*/#include<stdio.h>voidmain(){
voidpyramid(intn); /*函數(shù)聲明*/
pyramid(5); /*調(diào)用函數(shù),輸出數(shù)字金字塔*/}voidpyramid(intn) /*函數(shù)定義*/{ inti,j; for(i=1;i<=n;i++)/*需要輸出的行數(shù)*/{ for(j=1;j<=n-i;j++) /*輸出每行左邊的空格*/ printf(""); for(j=1;j<=i;j++) /*輸出每行的數(shù)字*/ printf("%d",i); /*每個(gè)數(shù)字的后各有一個(gè)空格*/
putchar('\n');
}}20例題
輸入精度e,使用格里高利公式求π的近似值,精確到最后一項(xiàng)的絕對(duì)值小于e。要求定義和調(diào)用函數(shù)funpi(e)求π的近似值。21/*用格里高利公式計(jì)算π的近似值,精度為e*/#include<stdio.h>#include<math.h>voidmain(){ doublee,pi;
doublefunpi(doublee); printf("Entere:"); scanf("%lf",&e);
pi=funpi(e); printf("pi=%.4f\n",pi); }doublefunpi(doublee){ intdenominator,flag;doubleitem,sum;
flag=1; denominator=1;
item=1.0; sum=0;while(fabs(item)>=e){ item=flag*1.0/denominator;sum=sum+item;flag=-flag; denominator=denominator+2;} returnsum*4;}224.3函數(shù)的多級(jí)調(diào)用函數(shù)的嵌套調(diào)用函數(shù)的遞歸調(diào)用遞歸與遞推23引例
設(shè)計(jì)一個(gè)常用圓形體體積的計(jì)算器,采用命令方式輸入1、2、3,分別選擇計(jì)算球體、圓柱體、圓錐體的體積,并輸入計(jì)算所需相應(yīng)參數(shù)。24#include<stdio.h>#definePI3.141592654voidcal(intsel);voidmain(){intsel;
while(1)
{printf("1-計(jì)算球體體積\n"); printf("2-計(jì)算圓柱體積\n"); printf("3-計(jì)算圓錐體積\n"); printf("其他-退出程序運(yùn)行\(zhòng)n"); printf("請(qǐng)輸入計(jì)算命令:"); scanf("%d",&sel); if(sel<1||sel>3)
break; /*輸入非1~3,循環(huán)結(jié)束*/ else
cal(sel); /*輸入1~3,調(diào)用cal()*/
}}25/*常用圓形體體積計(jì)算器的主控函數(shù)*/voidcal(intsel){doublevol_ball();doublevol_cylind();doublevol_cone();switch(sel){ case1: printf("球體積為:%.2f\n",vol_ball()); break;case2: printf("圓柱體積為:%.2f\n",vol_cylind()); break;case3: printf("圓錐體積為:%.2f\n",vol_cone()); break; }}26/*計(jì)算球體體積V=4/3*PI*r*r*r*/doublevol_ball(){doubler;printf("請(qǐng)輸入球的半徑");scanf("%lf",&r);return(4.0/3.0*PI*r*r*r);}/*計(jì)算圓柱體積V=PI*r*r*h*/doublevol_cylind(){doubler,h;printf("請(qǐng)輸入圓柱的底圓半徑和高:");scanf("%lf%lf",&r,&h);return(PI*r*r*h);}/*計(jì)算圓錐體積V=h/3*PI*r*r*/doublevol_cone(){doubler,h;printf("請(qǐng)輸入圓錐的底圓半徑和高:");scanf("%lf%lf",&r,&h);return(PI*r*r*h/3.0);}27嵌套調(diào)用
main函數(shù){……x=root(x1,x2);……}root函數(shù){……x=xpoint(x1,x2);……}xpoint函數(shù){……return(x1*f(x2)-x2*f(x1))/(f(x2)–f(x1));……}f函數(shù){……}圖4-5函數(shù)調(diào)用關(guān)系示意圖C語言不允許嵌套定義函數(shù),但允許嵌套調(diào)用函數(shù)。除了主函數(shù)外,其它函數(shù)可以相互調(diào)用。28遞歸調(diào)用
遞歸調(diào)用指的是一個(gè)函數(shù)執(zhí)行過程中出現(xiàn)了直接或間接調(diào)用函數(shù)本身的調(diào)用方式。如果直接調(diào)用函數(shù)本身稱為直接遞歸;如果調(diào)用了另外一個(gè)函數(shù),那個(gè)函數(shù)又調(diào)用該函數(shù),那么稱為間接遞歸。遞歸方法的根本思想是將一個(gè)問題向下分解具有同樣解決方法但規(guī)模不斷縮小的子問題,不斷進(jìn)行這樣的分解,直到分解的子問題有一個(gè)解。29
例如:有4個(gè)人坐在一起,問第4個(gè)人多少歲?他說比第3個(gè)人大2歲。問第3個(gè)人多少歲?他說比第2個(gè)人大2歲。問第2個(gè)人多少歲?他說比第1個(gè)人大2歲。最后問第1個(gè)人,他說他10歲。請(qǐng)問第4個(gè)人多大。30分析:age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10可以用數(shù)學(xué)公式表示為:
age(n-1)+2(1<n≤4)age(n)=10(n=1)31age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(2)=12age(3)=14age(4)=16求第4個(gè)人年齡的過程如以下圖第一階段“回推〞,第二階段“遞推〞遞歸過程結(jié)束條件32可以看出,當(dāng)n>1時(shí),求第n個(gè)人的年齡的公式是相同的。因此可以編寫一個(gè)函數(shù)來表示上述關(guān)系。33#include<stdio.h>intage(intn){ intc; if(n==1) c=10;
else
c=age(n-1)+2;
returnc;}voidmain(){ printf("%d\n",age(4));}其中:age函數(shù)共被調(diào)用4次,即age(4),age(3),age(2),age(1)34age(4)mainc=age(3)+2age函數(shù)n=4c=age(2)+2age函數(shù)n=3c=age(1)+2age函數(shù)n=2c=10age函數(shù)n=1age(2)=12age(3)=14age(4)=16輸出age(4)age(1)=1035#include<stdio.h>floatfac(intn){ floatf; if(n==1) f=1; else f=n*fac(n-1);
returnf; }voidmain(){ intn; floaty; printf("inputanintergernumber:"); scanf("%d",&n); if(n>0) { y=fac(n); printf("%d!=%10.0f\n",n,y); } else printf("n<=0,dataerror!\n");}用遞歸的方法求n!36遞歸的條件 設(shè)計(jì)一個(gè)函數(shù)來實(shí)現(xiàn)遞歸算法,這個(gè)函數(shù)必須不斷使用下一級(jí)值調(diào)用自己,但不能無限地調(diào)用下去,最終應(yīng)能終止遞歸。因此遞歸函數(shù)一般必須滿足以下條件:必須有完成函數(shù)任務(wù)的語句〔return語句〕;必須有一個(gè)確定是否能終止遞歸調(diào)用的語句;必須有一個(gè)遞歸調(diào)用語句。37遞歸與遞推
大多數(shù)遞歸問題都可以轉(zhuǎn)化為遞推求解,遞歸調(diào)用使用選擇結(jié)構(gòu),而遞推調(diào)用使用循環(huán)結(jié)構(gòu)。
38intage(intn){ intc=10,i=1;
while(i<n) { i++; c=c+2; } returnc;}intage(intn){ intc; if(n==1) c=10; else c=age(n-1)+2; returnc;}遞歸遞推39遞歸的優(yōu)點(diǎn):使用遞歸能夠更自然地反映解決問題的過程,符合人的思維習(xí)慣,易于理解和調(diào)試程序,簡(jiǎn)化程序,便于閱讀遞歸的缺點(diǎn):大量的遞歸調(diào)用會(huì)占用處理器很多時(shí)間和大量的內(nèi)存遞推的優(yōu)點(diǎn):效率高遞推的缺點(diǎn):比較難編程,可讀性較差404.4變量的作用域和存儲(chǔ)類別程序在內(nèi)存中的分布區(qū)域局部變量及存儲(chǔ)類別全局變量及存儲(chǔ)類別引例用函數(shù)實(shí)現(xiàn)財(cái)務(wù)現(xiàn)金記賬。先輸入操作類型〔1--收入;2--支出;0--結(jié)束〕,再輸入操作金額,計(jì)算現(xiàn)金剩余額,經(jīng)屢次操作直到操作類型為0時(shí)結(jié)束。要求定義并調(diào)用函數(shù),其中現(xiàn)金收入與現(xiàn)金支出分別用不同函數(shù)實(shí)現(xiàn)。41#include<stdio.h>floatcash;intmain(void){ voidincome(floatnumber),expend(floatnumber); intchoice; floatvalue;
cash=0; printf("Enteroperatechoice(0--end,1--income,2--expend):"); scanf("%d",&choice); while(choice!=0) { if(choice==1||choice==2) { printf("Entercashvalue:"); scanf("%f",&value); if(choice==1)
income(value); else
expend(value); printf("Currentcash:%.2f\n",cash); } printf("Enteroperatechoice(0--end,1--income,2--expend):"); scanf("%d",&choice); } return0;}voidincome(floatnumber){ cash=cash+number;}voidexpend(floatnumber){ cash=cash-number;}4243從變量占用空間的角度〔作用范圍〕來分析問題,劃分出全局變量和局部變量,這是變量的作用域問題。從變量值存在的時(shí)間角度〔生存周期〕來分析問題,劃分出變量的靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ),這是變量的存儲(chǔ)類別問題。44(1)程序區(qū):存放用戶程序代碼,即程序中各個(gè)函數(shù)的代碼。(2)靜態(tài)存儲(chǔ)區(qū):存放程序的全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù)。分配在靜態(tài)存儲(chǔ)區(qū)中的變量的生命期最長(zhǎng),它們?cè)趍ain函數(shù)運(yùn)行之前就存在了,在程序的整個(gè)活動(dòng)期〔從程序開始執(zhí)行到執(zhí)行結(jié)束〕中,這些變量始終占用靜態(tài)存儲(chǔ)區(qū)中對(duì)應(yīng)的存儲(chǔ)空間,即程序開始執(zhí)行時(shí)分配存儲(chǔ)單元,程序執(zhí)行完畢后釋放。(3)動(dòng)態(tài)存儲(chǔ)區(qū):存放局部變量。分配在動(dòng)態(tài)存儲(chǔ)區(qū)中的變量只有在所定義的函數(shù)被調(diào)用時(shí)才分配存儲(chǔ)單元,函數(shù)結(jié)束時(shí)就釋放。系統(tǒng)對(duì)函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)保護(hù)、返回地址等也占用動(dòng)態(tài)存儲(chǔ)區(qū)。程序在內(nèi)存中的分布區(qū)域
45局部變量:在一個(gè)函數(shù)內(nèi)定義的變量。局部變量作用域:塊內(nèi)定義、塊內(nèi)使用。所謂塊內(nèi)是指一對(duì)以{}為界限的假設(shè)干個(gè)語句,例如函數(shù)體、復(fù)合語句。塊內(nèi)使用是指變量的作用范圍僅僅局限在從變量定義處開始、到變量定義所在的那個(gè)塊結(jié)束。如:voidmain(){intn;/*……*/}voidfunc(){intn;/*……*/}局部變量及存儲(chǔ)類別
main的局部變量func的局部變量46形式參數(shù)也為局部變量,其作用范圍是形式參數(shù)所在的整個(gè)函數(shù)。例如:voidmain(){printf("%d,%d",x,y);
……}voidfunc(intx,inty){
……}在main函數(shù)中不能使用在func函數(shù)中定義的局部變量47在復(fù)合語句中定義局部變量。#include<stdio.h>voidmain(){int a;a=1;
{ /*復(fù)合語句開始*/intb=2;b=a+b;a=a+b;
}
/*復(fù)合語句結(jié)束*/ printf("%d",a);}b:小范圍內(nèi)的臨時(shí)變量
48局部變量的存儲(chǔ)類別:自動(dòng)變量:用關(guān)鍵字auto(可缺省)加以說明的局部變量。如:autofloatb;或floatb;特點(diǎn):是短生命期的局部變量,安排在動(dòng)態(tài)存儲(chǔ)區(qū),由系統(tǒng)自動(dòng)分配和釋放,用到時(shí)分配內(nèi)存,不用時(shí)釋放內(nèi)存,以節(jié)省程序執(zhí)行時(shí)的內(nèi)存資源。局部靜態(tài)變量:用關(guān)鍵字static加以說明的局部變量。如:staticintcount;特點(diǎn):是長(zhǎng)生命期的局部變量。函數(shù)執(zhí)行結(jié)束后,分配給該變量的存儲(chǔ)區(qū)不釋放。局部靜態(tài)變量安排在靜態(tài)存儲(chǔ)區(qū)。存放器變量:關(guān)鍵字register說明的局部變量為存放器變量。特點(diǎn):存放器變量的值存放在CPU的存放器中,可以提高程序的執(zhí)行效率。如registerinti;49局部靜態(tài)變量說明:如staticintcount局部靜態(tài)變量屬于靜態(tài)存儲(chǔ)類別;局部靜態(tài)變量是在編譯時(shí)賦初值的,即只賦初值一次;局部靜態(tài)變量不賦初值,編譯時(shí)自動(dòng)賦初值0;局部靜態(tài)變量在函數(shù)調(diào)用結(jié)束仍存在,但其他函數(shù)不能引用它。形參不能是局部靜態(tài)變量。存放器變量說明:如registerinti;只有局部自動(dòng)變量和形式參數(shù)可以作為存放器變量,其它〔如全局變量〕不行。一個(gè)計(jì)算機(jī)系統(tǒng)中的存放器數(shù)目有限,不能定義太多存放器變量;局部靜態(tài)變量不能定義為存放器變量。如:registerstaticinta,b;//error50【例4-10】局部變量存儲(chǔ)方式舉例,分析下面程序運(yùn)行結(jié)果:/*程序名:4_10.cpp*//*功能:局部變量存儲(chǔ)方式例如*/#include<stdio.h>intfun1(int);intfun2(int);voidmain(){inti;for(i=2;i<5;i++)printf("%d\t",fun1(i));printf("\n");for(i=2;i<5;i++)printf("%d\t",fun2(i));printf("\n");}intfun1(intx){
intf=1;return(f*=x);}intfun2(intx){
staticintf=1;return(f*=x);}2342624staticintf;f=1;23423451全局變量:在所有函數(shù)外定義的變量。全局變量作用域:從變量定義處開始到所定義的源文件結(jié)束處,即從全局變量定義所在處開始到源文件結(jié)束處之間的所有函數(shù)都可以訪問該變量。如:intn=1;voidmain(){/*……*/}floatm;voidfunc(){/*……*/}全局變量及存儲(chǔ)類別
52全局變量定義#include"stdio.h"intx; /*定義全局變量x*/intf(){
intx=4;/*x為局部變量*/returnx;}voidmain(){
inta=1;
x=a; /*對(duì)全局變量x賦值*/a=f(); /*a的值為4*/{
intb=2; b=a+b; /*b的值為4*/
x=x+b; /*全局變量運(yùn)算*/}printf("%d%d",a,x);}假設(shè)局部變量與全局變量同名,局部變量?jī)?yōu)先53【例4-11】全局變量的作用域舉例,分析下面程序運(yùn)行結(jié)果。#include<stdio.h>voidswap(void);
inta,b;
voidmain(){scanf("%d,%d",&a,&b);printf("交換前的a和b是%d,%d\n",a,b);
swap();printf("交換后的a和b是%d,%d\n",a,b);}voidswap(){intt;
t=a;a=b;b=t;}54不要濫用全局變量使用全局變量會(huì)帶來如下問題:程序的清晰度降低函數(shù)的靈活性、通用性降低存儲(chǔ)空間的利用率降低55局部變量與全局變量同名時(shí):小范圍優(yōu)先【例4-12】分析下面程序運(yùn)行結(jié)果:#include<stdio.h>inti=1;/*變量i定義在所有函數(shù)之外,屬于全局變量*/inttest();voidmain(){printf("主函數(shù)中i:%d其地址%p\n",i,&i);i=test()+1;printf("主函數(shù)中i:%d其地址%p\n",i,&i);}inttest(){inti;printf("test中i:%d其地址%p\n",i,&i);i=2;printf("test中i:%d其地址%p\n",i,&i);return(i);}56全局變量的存儲(chǔ)類別:〔靜態(tài)存儲(chǔ)〕靜態(tài)全局變量:使用關(guān)鍵字static定義的全局變量。特點(diǎn):只能被其定義所在的源文件中的函數(shù)訪問,同一程序的其它源文件中的函數(shù)都不能訪問該變量。非靜態(tài)全局變量:也稱為外部變量,不使用任何關(guān)鍵字。特點(diǎn):該變量不僅能被定義所在的源文件中的函數(shù)訪問,而且組成程序的其它源文件中的函數(shù)也都能訪問該變量。因此,從作用范圍看,外部變量的作用域要比使用關(guān)鍵字static的靜態(tài)全局變量的大。關(guān)鍵字extern的作用關(guān)鍵字extern的作用是對(duì)要使用的某個(gè)尚未定義的全局變量在使用前作變量說明,該全局變量或者是以后會(huì)在該源文件中定義的全局變量,或者是在另一個(gè)源文件中定義的非靜態(tài)全局變量。57/*程序名:a.cpp*//*功能:全局變量存儲(chǔ)方式例如*/#include<stdio.h>externinta;/*對(duì)c.cpp中定義的變量進(jìn)行說明*/voidfun1();voidfun2();voidmain(){fun1();fun2();printf("函數(shù)main中的a是%d\n",a);}【例4-13】全局變量存儲(chǔ)方式舉例,分析下面程序運(yùn)行結(jié)果:58/*程序名:c.cpp*/#include<stdio.h>inta;
/*允許其它文件中函數(shù)訪問的全局變量*/voidfun2(){a=4;printf("函數(shù)fun2中的a是%d\n",a);}/*程序名:b.cpp*/#include<stdio.h>staticinta;/*只允許文件b.cpp中函數(shù)訪問的全局變量*/voidfun1(){a=2;printf("函數(shù)fun1中的a是%d\n",a);}59函數(shù)與程序文件模塊如果一個(gè)程序包含多個(gè)文件模塊,要實(shí)現(xiàn)在一個(gè)文件模塊A中調(diào)用另一個(gè)文件模塊B中的函數(shù)時(shí),就要在文件模塊A中對(duì)函數(shù)進(jìn)行外部聲明。聲明格式為:
extern函數(shù)類型函數(shù)名(參數(shù)表說明);C語言也允許把函數(shù)定義成靜態(tài)的,以便把函數(shù)的使用范圍限制在文件模塊內(nèi)。即使其他文件模塊有同名的函數(shù)定義,相互也沒有任何關(guān)聯(lián),增強(qiáng)了文件模塊的獨(dú)立性。
static函數(shù)類型函數(shù)名(參數(shù)表說明);extern可省略604.5計(jì)算機(jī)隨機(jī)模擬方法偽隨機(jī)數(shù)的產(chǎn)生蒙特卡羅方法(不要求)61rand()函數(shù)可隨機(jī)生成0~RAND_MAX之間的一個(gè)整數(shù)。RAND_MAX是頭文件<stdlib.h>中定義的一個(gè)符號(hào)常量。ANSI規(guī)定RAND_MAX的值不小于32767。根據(jù)下面公式可以得到所需范圍內(nèi)的隨機(jī)數(shù):n=a+rand()%b其中a為位移,是所需連續(xù)整數(shù)范圍的第一個(gè)數(shù),b是比例因子,是所需連續(xù)整數(shù)范圍的寬度,那么希望產(chǎn)生1~6之間隨機(jī)數(shù)的公式為:face=1+rand()%6偽隨機(jī)數(shù)的產(chǎn)生
62【例4-14】編寫一個(gè)模擬投擲硬幣的程序,模擬20次,統(tǒng)計(jì)出正面出現(xiàn)的次數(shù)。#include<stdio.h>#include<stdlib.h>voidmain(){ inti,face,iCount=0; for(i=1;i<=20;i++) { face=0+rand()%2; printf("%5d",face); if(i%10==0)printf("\n"); if(face)iCount++; } printf("正面出現(xiàn)次數(shù):%d次\n",iCount);}63運(yùn)行程序,結(jié)果為:11001000001111111010正面出現(xiàn)次數(shù):11次再次運(yùn)行該程序結(jié)果為:11001000001111111010正面出現(xiàn)次數(shù):11次用函數(shù)void
srand(
unsigned
int
seed
),通過提供不同的種子產(chǎn)生不同的隨機(jī)數(shù)序列。64用srand()函數(shù)進(jìn)行隨機(jī)化#include<stdio.h>#include<stdlib.h>voidmain(){ unsignedseed; printf("輸入一個(gè)非負(fù)整數(shù)做種子:"); scanf("%d",&seed); srand(seed); for(inti=1;i<=10;i++) printf("%3d",1+rand()%6);}運(yùn)行3次程序:輸入一個(gè)非負(fù)整數(shù)做種子:161343565262輸入一個(gè)非負(fù)整數(shù)做種子:333153565415輸入一個(gè)非負(fù)整數(shù)做種子:16134356526265使用系統(tǒng)定時(shí)/計(jì)數(shù)器的值做為隨機(jī)種子:
srand(time(NULL));time()函數(shù)返回以秒為單位的當(dāng)前時(shí)間值,因?yàn)橛袝r(shí)鐘參數(shù),而時(shí)間始終在變,隨機(jī)數(shù)序列就不會(huì)固定不變了。【例4-16】編寫程序,用來生成一個(gè)隨機(jī)小寫字符串。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>voidmain(){srand(time(NULL)); for(inti=1;i<=20;i++) printf("%c",97+rand()%26); printf("\n");}664.6編譯預(yù)處理文件包含#include宏定義#define條件編譯#if67“文件包含〞是指一個(gè)源文件可以將另一個(gè)源文件的全部?jī)?nèi)容包含進(jìn)來。在編譯預(yù)處理時(shí)#include指令讓預(yù)處理器用指定文件內(nèi)容替換該語句,然后作為一個(gè)源文件編譯形成新文件。文件包含的一般形式為:(1)#include<文件名>(2)#include"文件名"例如:#include<stdio.h>(只查C語言的系統(tǒng)目錄)#include“stdio.h〞(首先查當(dāng)前目錄)文件包含#include68(1)定義符號(hào)常量#define標(biāo)識(shí)符字符串如:#definePI3.14預(yù)處理器將在源文件中搜索PI,并把每個(gè)PI替換成3.14。完成搜索和操作替換后,預(yù)處理器刪除#define行。(2)定義宏#define宏名(參數(shù)表)字符串如:#defineS(a,b)a*b對(duì)程序中帶有實(shí)參的宏(如S(3,4)),按#define命令中指定的字符串從左到右進(jìn)行替換。如果字符串中包含宏的形參(如a,b),那么將程序語句中相應(yīng)的實(shí)參代替形參,如果宏定義中字符串中的字符不是參數(shù)字符(如a*b中的*)那么原樣保存。宏定義#define宏名中間不能有空格69宏的用途符號(hào)常量簡(jiǎn)單的函數(shù)功能實(shí)現(xiàn)如:#defineMAX(a,b)(a)>(b)?(a):(b)為程序書寫帶來一些方便如:#defineSINA"sina"C語言允許宏嵌套定義如:#definePI3.14159#defineSPI*r*r#include<stdio.h>voidmain(){ intr=2; printf("%f\n",S);}70宏的范圍宏可以寫在程序中的任何位置,它的作用范圍從定義書寫處到該文件尾,在此范圍內(nèi)都可以用宏名進(jìn)行替換,并可以通過#undef強(qiáng)制指定的宏的結(jié)束范圍.#include<stdio.h>#defineA"Thisisthefirstmacro"voidf1(){printf("A\n");}#defineB"Thisisthesecondmacro"
voidf2(){printf(B); }#undefBvoidmain(){f1();f2();printf("\n");}71帶參數(shù)宏例1:#include<stdio.h>#defineSQR(n)(n)*
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 租客合同終止租房協(xié)議
- 技術(shù)開發(fā)與轉(zhuǎn)讓合同保密范本
- 智能化系統(tǒng)供貨安裝合同樣本
- 礦山企業(yè)輪換工勞動(dòng)合同模板及示例
- 農(nóng)村土地出租權(quán)屬合同樣本
- 標(biāo)準(zhǔn)貨物銷售合同簡(jiǎn)版
- 城市配送服務(wù)合同一覽
- 小學(xué)生種花演講課件
- 影視設(shè)備行業(yè)交流服務(wù)批發(fā)考核試卷
- 廣播電視節(jié)目的心理影響與教育意義考核試卷
- 低溫絕熱液氧瓶充裝操作規(guī)程模版(2篇)
- 大眾汽車使用說明書
- (高清版)DZT 0145-2017 土壤地球化學(xué)測(cè)量規(guī)程
- 供熱公司安全教育知識(shí)
- 高中英語課程綱要
- 《藥物設(shè)計(jì)學(xué)》課件
- 隨機(jī)微分方程
- 道路設(shè)施施工現(xiàn)場(chǎng)安全管理基本要求
- 公寓樓改造裝修施工方案
- 煙臺(tái)大學(xué)化學(xué)化工學(xué)院實(shí)驗(yàn)室儀器設(shè)備搬遷項(xiàng)目
- 2022版10kV架空配電線路無人機(jī)自主巡檢作業(yè)導(dǎo)則
評(píng)論
0/150
提交評(píng)論