大學(xué)C語言程序設(shè)計(jì)第二版電子工業(yè)第章3_第1頁
大學(xué)C語言程序設(shè)計(jì)第二版電子工業(yè)第章3_第2頁
大學(xué)C語言程序設(shè)計(jì)第二版電子工業(yè)第章3_第3頁
大學(xué)C語言程序設(shè)計(jì)第二版電子工業(yè)第章3_第4頁
大學(xué)C語言程序設(shè)計(jì)第二版電子工業(yè)第章3_第5頁
已閱讀5頁,還剩86頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第6章函數(shù)與編譯預(yù)處理6.1函數(shù)概述6.2函數(shù)的定義和說明6.3函數(shù)的調(diào)用6.4函數(shù)的參數(shù)6.6變量的存儲(chǔ)類型6.7內(nèi)部函數(shù)和外部函數(shù)6.8編譯預(yù)處理命令6.5函數(shù)的嵌套調(diào)用與遞歸調(diào)用

6.1函數(shù)概述

★函數(shù)是封裝了一定功能的模塊

★C語言是函數(shù)驅(qū)動(dòng)式語言(一個(gè)源程序文件由一個(gè)或多個(gè)函數(shù)組成)#include“stdio.h”

voidmain(

)//函數(shù)頭

{

inta=8;

printf(“a=%d”,a);

}

//函數(shù)體★一個(gè)C源程序必須有且只能有一個(gè)主函數(shù)main(

)。C程序總是從main(

)函數(shù)開始執(zhí)行,最后結(jié)束于main(

)函數(shù),其他函數(shù)是通過main(

)直接或間接調(diào)用完成其功能的。#include<stdio.h>intadd(intx,inty){ints;s=x+y;returns;}main(){inta=1,b=2,c;c=add(a,b);printf("%d\n",c);}kj61一、函數(shù)定義二、函數(shù)聲明三、函數(shù)調(diào)用#include<stdio.h>main(){inta=1,b=2,c;

intadd(intx,inty);c=add(a,b);printf("%d\n",c);}intadd(intx,inty){ints;s=x+y;returns;}函數(shù)概述(1)一個(gè)C程序由一個(gè)或多個(gè)源(程序)文件組成——可分別編寫、編譯和調(diào)試。(2)一個(gè)源文件由一個(gè)或多個(gè)函數(shù)組成,可為多個(gè)C程序公用。(3)C語言是以源文件為單位而不以函數(shù)為單位進(jìn)行編譯的。(4)在C語言中,所有函數(shù)(包括主函數(shù)main(

))都是平行的。一個(gè)函數(shù)的定義,可以放在程序中的任意位置,主函數(shù)main(

)之前或之后。但在一個(gè)函數(shù)的函數(shù)體內(nèi),只能調(diào)用其他函數(shù),不能再定義另一個(gè)函數(shù),即不能嵌套定義。(5)主函數(shù)名main是系統(tǒng)定義的,是運(yùn)行時(shí)首先被調(diào)用的函數(shù),它可以調(diào)用其他函數(shù),但不能被其他函數(shù)調(diào)用;其他函數(shù)間可以互相調(diào)用,也允許嵌套調(diào)用。(6)從函數(shù)定義的角度看,函數(shù)可分為庫函數(shù)和用戶定義函數(shù)兩種。①庫函數(shù):由C系統(tǒng)提供,用戶無須定義,也不必在程序中進(jìn)行類型說明,只需在程序前寫出包含有該函數(shù)原型的頭文件即可在程序中直接調(diào)用。在前面各章的例題中反復(fù)用到的printf(

)、scanf(

)、getchar(

)、putchar(

)、gets(

)、puts(

)等函數(shù)均在頭文件stdio.h中,sqrt(),fabs(),pow()等函數(shù)均在頭文件math.h中。②用戶定義函數(shù):由用戶按需要編寫的函數(shù)。對于用戶自定義函數(shù),不僅要在程序中定義函數(shù)本身,而且還必須在主調(diào)函數(shù)模塊中對該被調(diào)函數(shù)進(jìn)行類型說明,然后才能使用。(7)從主調(diào)函數(shù)和被調(diào)函數(shù)之間數(shù)據(jù)傳送角度看,函數(shù)又可分為無參函數(shù)和有參函數(shù)兩種。(8)C語言的函數(shù)兼有其他語言中的函數(shù)和過程兩種功能,從這個(gè)角度看,又可把函數(shù)分為有返回值函數(shù)和無返回值函數(shù)兩種。6.2.1函數(shù)定義C語言函數(shù)定義格式如下:[函數(shù)返回值的類型名]函數(shù)名([類型名形式參數(shù)1,類型名形式參數(shù)2,…])/*函數(shù)頭*/{[說明部分;]/*函數(shù)體*/[語句部分;]}其中[]內(nèi)為可選項(xiàng)。注意:函數(shù)名、一對圓括號和花括號不能省!6.2函數(shù)的定義和說明1.無參函數(shù)無參函數(shù)的一般形式函數(shù)返回值的類型名函數(shù)名(void){[說明語句部分;][可執(zhí)行語句部分;]}例:

構(gòu)造一個(gè)輸出一行”*”的函數(shù):voidprintstar(void){printf(“******************\n”);}

kj622.有參函數(shù)例:編寫函數(shù)交換2個(gè)數(shù);kj63voidswap(inta,intb){inttemp;temp=a;a=b;b=temp;}

不能寫成:voidswap(inta,b){inttemp;temp=a;a=b;b=temp;}函數(shù)返回值類型函數(shù)名參數(shù)類型說明及參數(shù)列表6.2.2函數(shù)的返回值函數(shù)分為有返回值函數(shù)和無返回值函數(shù)。return語句的格式:return(表達(dá)式);或return表達(dá)式;或return;功能:1、把return后面“表達(dá)式”的值帶給調(diào)用函數(shù);

2、把控制轉(zhuǎn)向調(diào)用函數(shù);格式return;只有功能2例:編寫函數(shù),返回2個(gè)整數(shù)的最大公約數(shù)。(輾轉(zhuǎn)相除法)kj64

intf(intx,inty){intr,t;if(x<y){t=x;x=y;y=t;} while((r=x%y)!=0) {x=y;y=r;}returny;}

注意:(1)聲明為為void型的函函數(shù)中中不能能包括括帶值值的return語句;;主函函數(shù)體體內(nèi)一一般不不用return語句。。(2)當(dāng)函數(shù)數(shù)沒有有return語句時(shí)時(shí),以以結(jié)束束函數(shù)數(shù)的大大括號號}作為返返回點(diǎn)點(diǎn)。但但這時(shí)時(shí)并不不表明明函數(shù)數(shù)沒有有返回回值,,這時(shí)時(shí)的返返回值值是系系統(tǒng)給給的不不確定定值。。(3)在同一一函數(shù)數(shù)內(nèi),,可根根據(jù)需需要在在多處處出現(xiàn)現(xiàn)return語句,但但函數(shù)第第一次遇遇到return時(shí)就立即即停止執(zhí)執(zhí)行,并并返回到到主調(diào)函函數(shù);(4)return語句中返返回值表表達(dá)式的的類型應(yīng)應(yīng)該和函函數(shù)類型型一致。。如果不不一致,,則以函函數(shù)類型型為準(zhǔn),,由系統(tǒng)統(tǒng)自動(dòng)進(jìn)進(jìn)行轉(zhuǎn)換換。如果果缺省函函數(shù)類型型,則系系統(tǒng)一律律按int類型處理理。intf(chars1,chars2){if(s1==s2)return1;return0;}kj65例:計(jì)算兩數(shù)數(shù)之和#include<stdio.h>doubleadd(doublex,doubley){doubles;s=x+y;returns;}main(){doublea,b,c;a=10.5;b=20.3;c=add(a,b);printf("%lf",add(a,b));add(a,b);}Kj66運(yùn)行結(jié)果果為:30.8改成:intadd(doublex,doubley)?6.2.3函數(shù)說明明1.函數(shù)說說明的形形式函數(shù)說明明也稱為為函數(shù)聲聲明,使使用函數(shù)數(shù)說明語語句能夠夠讓C編譯程序序了解函函數(shù)返回回值類型型被調(diào)用函函數(shù)說明明一般格格式如下下:函數(shù)類型型函函數(shù)名(數(shù)據(jù)類型型[參數(shù)名1][,數(shù)據(jù)類型型[參數(shù)名2]…]);函數(shù)說明明語句其其實(shí)就是是函數(shù)定定義中的的函數(shù)首首部加上上分號,,這些內(nèi)內(nèi)容稱為為函數(shù)原原型。如:doublemax(doublex,doubley);voidswap(inta,intb);例:計(jì)算兩數(shù)數(shù)之和#include<stdio.h>main(){doublea,b,c;a=10.5;b=20.3;c=add(a,b);printf("%lf",add(a,b));add(a,b);}doubleadd(doublex,doubley){doubles;s=x+y;returns;}kj67doubleadd(doublex,doubley);doubleadd(doublex,doubley);注意:有三種情情況不需需說明::a、函數(shù)返回值值為整型或字字符型;b、被調(diào)用函數(shù)數(shù)定義出出現(xiàn)在主主調(diào)函數(shù)數(shù)之前;;c、已在所有的的函數(shù)定定義之前前(即文文件的開開頭)說說明了函函數(shù)類型型。6.3函數(shù)的調(diào)調(diào)用1、調(diào)用形形式:函數(shù)名((實(shí)參表表列);;實(shí)參與形形參個(gè)數(shù)數(shù)相等,,類型一一致。調(diào)調(diào)用函數(shù)數(shù)時(shí)兩者者按順序序一一對對應(yīng)傳遞遞數(shù)據(jù)。。main(){inta=1,b,f(int,int);b=f(a,++a);printf("%d",b);}intf(intx,inty){intz;if(x>y)z=1;elseif(x==y)z=0;elsez=-1;return(z);}例:參參數(shù)求求值順序序main(){inta=1,b,f(int,int);b=f(a,a++);printf("%d",b);}intf(intx,inty){intz;if(x>y)z=1;elseif(x==y)z=0;elsez=-1;return(z);}運(yùn)行結(jié)果果:0運(yùn)行結(jié)果果:12、調(diào)用方方式:按函數(shù)在在程序中中出現(xiàn)的的位置來來分有三三種方式式。①函數(shù)數(shù)語句。。只完成一一個(gè)操作作,并不不要求函函數(shù)帶回回值。如:printstar();scanf(““%d””,&a);②函數(shù)表達(dá)達(dá)式。出現(xiàn)在表表達(dá)式中中,函數(shù)數(shù)值參與與表達(dá)式式運(yùn)算。。如:c=2*max(a,b);y=x+power(x,3);③函數(shù)參數(shù)數(shù)。函數(shù)調(diào)用用作為一一個(gè)函數(shù)數(shù)的實(shí)參參。如:m=max(a,max(b,c));printf(“%8.2f\n””,power(x,3));課堂練習(xí)習(xí):下面程序序的輸出出結(jié)果是是())。。#include<stdio.h>func(inta,intb){intc;c=a+b;returnc;}main(){intx=6,y=7,z=8,r;r=func((x--,y+=2,x+y),z);printf("%d\n",r);}A.11B.20C.21D.22課堂練習(xí)習(xí):若有以下下函數(shù)調(diào)調(diào)用語句句:fun(a+b,(x,y),fun(n+k,d,(a,b)));fun函數(shù)參數(shù)數(shù)的個(gè)數(shù)數(shù)是A)3B)4C)5D)66.4函數(shù)的參參數(shù)形參與實(shí)實(shí)參形式參數(shù)數(shù):定義義函數(shù)時(shí)時(shí)函數(shù)名名后面括括號中的的變量名名。實(shí)際參數(shù)數(shù):調(diào)用用函數(shù)時(shí)時(shí)函數(shù)名名后面括括號中的的表達(dá)式式。例:編寫程序序?qū)崿F(xiàn)從從兩整數(shù)數(shù)中求較較大數(shù)。。#include<stdio.h>floatmax(floatx,floaty);/*函數(shù)說明明*/main(){floata,b;floatc;scanf("%f,%f",&a,&b);c=max(a,b);/*調(diào)用函數(shù)數(shù)語句,a,b為實(shí)參*/printf("a=%f,b=%f\nmax=%f\n",a,b,c);}floatmax(floatx,floaty)/*函數(shù)定義義,x,y為形參*/{floatz;z=x>y?x:y;printf(“x=%f,y=%f\nz=%f\n””,x,y,z);return(z);}xy形參ab實(shí)參說明:實(shí)參必須須有確定定的值,形參必須須指定類類型形參與實(shí)實(shí)參類型型一致,,個(gè)數(shù)相相同若形參與與實(shí)參類類型不一一致,自自動(dòng)按形形參類型型轉(zhuǎn)換——函數(shù)調(diào)用用轉(zhuǎn)換值傳遞方方式形參在函函數(shù)被調(diào)調(diào)用前不不占內(nèi)存存;函數(shù)調(diào)用用時(shí),為形參分分配單元元,并將實(shí)參參的值復(fù)復(fù)制到形形參中;;調(diào)用結(jié)結(jié)束,形形參單元元被釋放放,實(shí)參參單元仍仍保留并并維持原原值特點(diǎn):形參與實(shí)實(shí)參占用用不同的的內(nèi)存單單元單向傳遞遞例:計(jì)計(jì)算x的立方#include<stdio.h>floatcube(floatx){return(x*x*x);}main(){floata,product;scanf("%f",&a);product=cube(a);printf(”%.4f%.4f\n",a,product);}xaproduct××××1.21.21.7281030x:y:調(diào)用前:調(diào)用結(jié)束:1030x:y:例:交交換兩兩個(gè)數(shù)#include<stdio.h>main(){intx=10,y=30;printf("%d,%d\n",x,y);printf("swapped:\n");swap(x,y);printf("%d,%d\n",x,y);}swap(inta,intb){inttemp;temp=a;a=b;b=temp;}調(diào)用:1030a:b:1030x:y:swap:1030x:y:3010a:b:temp一般函數(shù)數(shù)調(diào)用main()調(diào)用函數(shù)a結(jié)束a函數(shù)執(zhí)行2134566.5函數(shù)的嵌嵌套調(diào)用用和遞歸歸調(diào)用6.5.1函數(shù)的嵌嵌套調(diào)用用函數(shù)的嵌嵌套調(diào)用用是指,,在執(zhí)行行被調(diào)用用函數(shù)時(shí)時(shí),被調(diào)調(diào)用函數(shù)數(shù)又調(diào)用用了其它它函數(shù)。。這與其其它語言言的子程程序嵌套套調(diào)用的的情形是是類似的的,其關(guān)關(guān)系可表表示如右右圖所示示。例:求三個(gè)數(shù)中中最大數(shù)和和最小數(shù)的的差值intmax(intx,inty,intz)/*定義函數(shù)max求x,y,z中最大值*/{intr;r=x>y?x:y;return(r>z?r:z);}intmin(intx,inty,intz)/*定義義函函數(shù)數(shù)min,求x,y,z中最最小小值值*/{intr;r=x<y?x:y;return(r<z?r:z);}intdif(intx,inty,intz)/*定義義函函數(shù)數(shù)dif*/{returnmax(x,y,z)-min(x,y,z);/*嵌套套調(diào)調(diào)用用*/}voidmain(){inta,b,c,d;scanf("%d%d%d",&a,&b,&c);d=dif(a,b,c);/*調(diào)用用函函數(shù)數(shù)dif*/printf("Max-Min=%d\n",d);}若輸輸入入2、3,求求以以下下程程序序的的運(yùn)運(yùn)行行結(jié)結(jié)果果,,分分析析嵌嵌套套調(diào)調(diào)用用的的執(zhí)執(zhí)行行過過程程。。#include<stdio.h>intf(intn){intrtn=0;inti;for(i=1;i<=n;i++)rtn*=i;return(rtn);}longsum(inta,intb){longc1,c2;c1=f(a);c2=f(b);return(c1+c2);}main(){intn1=5,n2=10,a;a=sum(n1,n2);printf("a=%d",a);}6.5.2函數(shù)數(shù)的的遞遞歸歸調(diào)調(diào)用用在調(diào)調(diào)用用一一個(gè)個(gè)函函數(shù)數(shù)的的過過程程中中又又出出現(xiàn)現(xiàn)直直接接或或間間接接地地調(diào)調(diào)用用該該函函數(shù)數(shù)本本身身,,稱稱為為函函數(shù)數(shù)的的遞遞歸歸調(diào)調(diào)用用。。遞歸歸調(diào)調(diào)用用形形式式如如下下:(1)直接接遞遞歸歸voida(){...……a();/*自己己調(diào)調(diào)用用自自己己,直接接遞遞歸歸*/...……}函數(shù)數(shù)a()調(diào)用用函函數(shù)數(shù)a()(2)間接接遞遞歸歸voida(){...……b();/*調(diào)用用函函數(shù)數(shù)b*/...……}voidb(){......a();/*調(diào)用用函函數(shù)數(shù)a,間接接遞遞歸歸*/………}調(diào)b調(diào)aa()b()以上上是是無無終終止止的的函函數(shù)數(shù)調(diào)調(diào)用用,,因因此此,,一一個(gè)個(gè)正正確確的的遞歸歸調(diào)調(diào)用用的的函函數(shù)數(shù)必必須須滿滿足足以以下下條條件件::1、一一個(gè)個(gè)問問題題轉(zhuǎn)轉(zhuǎn)化化成成一一個(gè)個(gè)新新問問題題,,解解題題方方法法相相似似,,只只是是所所處處理理的的對對象象的的值值有有規(guī)規(guī)律律的的遞遞增增或或遞遞減減。。2、可以以應(yīng)用用這個(gè)個(gè)轉(zhuǎn)換換過程程使問問題得得到解解決。。3、必須須有明明確的的結(jié)束束遞歸歸的條條件;;分析問問題2種方法法:遞遞推和和遞歸歸遞推::從一個(gè)個(gè)已知知的事事實(shí)出出發(fā),,按一一定的的規(guī)律律推出出下一一個(gè)事事實(shí)。。通常利利用迭迭代公公式法法,通通過循循環(huán)結(jié)結(jié)構(gòu)實(shí)實(shí)現(xiàn),,循環(huán)環(huán)的終終值是是問題題的結(jié)結(jié)果。。遞歸::從要求求的結(jié)結(jié)果出出發(fā),,歸納納出后后一個(gè)個(gè)結(jié)果果和前前一個(gè)個(gè)結(jié)果果存在在的關(guān)關(guān)系,,直到到一個(gè)個(gè)已知知值為為止((即反反推法法)。。通常設(shè)設(shè)計(jì)函函數(shù)((遞歸歸函數(shù)數(shù)),,不斷斷使用用下一一級值值調(diào)用用自身身,直直到一一個(gè)已已知的的值((遞歸歸出口口)。。0!=11!=0!*1………………….n!=(n-1)!*n例:求求n的階乘乘n!遞推公公式::1n=0sn=sn-1*nn>0程序段段為::#include<stdio.h>main(){intm=1,i,n;scanf("%d",&n);for(i=1;i<=n;i++)m=m*i;printf("theresultis%10d",m);}例:求求n的階乘乘n!遞歸方方法求求n!由于n!=n*(n-1)!是遞歸歸定義義所以求求n!(n-1)!(n-1)!(n-2)!(n––2)!(n-3)!……1!0!的問問題,,已已知條條件為為:0!=1。遞歸函函數(shù)::1n=0f(n)=f(n-1)*nn>0遞歸函函數(shù)一一般形形式::函數(shù)名名f(參數(shù)數(shù)){if(n==初值))結(jié)結(jié)果=….;else結(jié)果=含f(n-1)的表達(dá)達(dá)式;return(返回結(jié)結(jié)果);}#include<stdio.h>intf(intx){intt;if(x==0)t=1;/*遞歸出出口*/elset=f(x-1)*x;;/*遞歸公公式*/return(t);}main(){intn=0,s;scanf("%d",&n);s=f(n);printf("%d!=%10d",n,s);}f函數(shù)在在回推推階段段被調(diào)調(diào)用了了4次次,遞遞歸調(diào)調(diào)用了了3次次,到到終止止條件件才有有確定定的值值,然然后再再遞推推出每每一次次調(diào)用用的值值,最最后得得到所所求的的結(jié)果果。例::求求Fibonacci數(shù)列::打印1,1,2,3,5,8,………的的前40個(gè)個(gè)數(shù)。#include<stdio.h>main(){longf1,f2;inti;f1=1;f2=1;for(i=1;i<20;i++){printf("%12ld%12ld",f1,f2);if(i%2==0)printf("\n");f1=f1+f2;f2=f2+f1;}}方法1:用循循環(huán)結(jié)結(jié)構(gòu)來來實(shí)現(xiàn)現(xiàn)#include<stdio.h>intfib(intn){intf;if(n==1||n==2)f=1;elsef=fib(n-1)+fib(n-2);returnf;}main(){inti;for(i=1;i<=40;i++){printf("%15d",fib(i));if(i%4==0)printf("\n");}}方法2:用遞遞歸函函數(shù)來來實(shí)現(xiàn)現(xiàn)例:反向輸輸出一一個(gè)整整數(shù)#include<stdio.h>main(){intn;scanf("%d",&n);if(n<0){n=-n;printf("-");}while(n!=0){printf("%d",n%10);n=n/10;}}方法1:用循循環(huán)結(jié)結(jié)構(gòu)來來實(shí)現(xiàn)現(xiàn)#include<stdio.h>voidmain(){voidprintn(intx);intn;scanf("%d",&n);if(n<0){n=-n;putchar('-');}printn(n);}voidprintn(intx)/*反向輸輸出整整數(shù)x*/{if(x>=0&&x<=9)/*若x為一位位整數(shù)數(shù)*/printf("%d",x);/*則輸出出整數(shù)數(shù)x*/else/*否則*/{printf("%d",x%10);/*輸出x的個(gè)位位數(shù)字字*/printn(x/10);/*將x中的個(gè)個(gè)位數(shù)數(shù)字去去掉,,形成成新的的x后,繼繼續(xù)遞遞歸操操作*/}}方法2:用遞歸歸函數(shù)來來實(shí)現(xiàn)輸出一個(gè)個(gè)正整數(shù)數(shù)的遞歸歸算法為為:if(n為一位整整數(shù))輸出n;else{輸出n的個(gè)位數(shù)數(shù)字;對剩余數(shù)數(shù)字組成成的新整整數(shù)重復(fù)復(fù)"反向輸出出"操作;}例:漢漢諾塔問問題。初始狀態(tài)態(tài):有3個(gè)塔,每每個(gè)都堆堆放若干干個(gè)盤子子。開始始時(shí),所所有盤子子均在塔塔a上,并且且,盤子子從上到到下,按按直徑增增大的次次序放置置。要求解決決問題::設(shè)計(jì)一個(gè)個(gè)盤子移移動(dòng)的序序列,使使得塔a上的所有有盤子借借助于塔塔b移動(dòng)到塔塔c上。兩個(gè)限制制:1)一次只只能移動(dòng)動(dòng)一個(gè)盤盤子;2)任何時(shí)時(shí)候都不不能把盤盤子放在在比它小小的盤子的的上面。。假設(shè)塔塔a有n個(gè)盤子已知條件件:若只有一一個(gè)盤子子,則是是直接從從1移到到3(遞歸出出口)算法設(shè)計(jì)計(jì)如下::第一步::把n-1個(gè)盤子依依照題目目中的規(guī)規(guī)則從塔塔a(源塔))借助于于塔c(中間塔塔)搬到到塔b(目標(biāo)塔塔)。第二步::將剩下下的一只只盤(也也就是最最大的一一只)直直接從塔塔a(源塔))搬到那那個(gè)仍然然空著的的塔c(目標(biāo)塔塔)。第三步::再次將將b塔(源塔塔)上的的n-1個(gè)盤子借借助于塔塔a(中間塔塔)搬到到塔c(目標(biāo)塔塔)。這這一步是是沒有問問題的,,因?yàn)閏塔上僅有有一只最最大的盤盤。函數(shù)hanoi(intn,inta,intb,intc)設(shè)計(jì):1.如果果(n==1)則ac;2.否則執(zhí)行行3步2-1調(diào)用函數(shù)數(shù)hanoi(n-1,a,c,b);2-2ac;2-3調(diào)用函數(shù)數(shù)hanoi(n-1,b,a,c);例Hanoi問題#include<stdio.h>voidhanoi(intn,inta,intb,intc){if(n==1)printf("%d->%d\n",a,c);else{hanoi(n-1,a,c,b);printf("%d->%d\n",a,c);hanoi(n-1,b,a,c);}}main(){intn;printf("Inputn:");scanf("%d",&n);hanoi(n,1,2,3);}運(yùn)行情況況如下::inputn:3↙↙thestep:1-->31-->23-->21-->32-->12-->31-->3先看一個(gè)個(gè)例子,錯(cuò)在那里里?:#include"stdio.h"voidf1(){intt=2;a*=t;b/=t;}main(){inta,b;scanf("%d,%d",&a,&b);f1();//調(diào)用函數(shù)數(shù)f1()printf("a=%d,b=%d",a,b);}1編譯程序序會(huì)提示示出錯(cuò):Undefinedsymbol‘a(chǎn)’和Undefinedsymbol‘b’。為什么?6.6變量的存存儲(chǔ)類型型6.6.1變量的生生存期和和作用域域生存期:變量在在某一時(shí)時(shí)刻存在在-------靜態(tài)變量量與動(dòng)態(tài)態(tài)變量作用域:變量在在某區(qū)域域內(nèi)有效效-------局部變量量與全局局變量(文件、函函數(shù)、復(fù)復(fù)合語句句)6.6.2變量的存存儲(chǔ)類型型(特性)1.c語言中每每一個(gè)變變量有兩兩個(gè)屬性性:數(shù)據(jù)類型型,存儲(chǔ)類型。完整的變變量定義義:[存儲(chǔ)類型][數(shù)據(jù)類型型]變量名;2.變量的存存儲(chǔ)類型(特性)自動(dòng)型auto靜態(tài)型static寄存器型型register外部型extern程序區(qū)靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)存儲(chǔ)區(qū)2.靜態(tài)存儲(chǔ)儲(chǔ)類型的變變量的生生存期為為程序執(zhí)執(zhí)行的整整個(gè)過程程,在該該過程中中占有固固定的存存儲(chǔ)空間間,稱它它們?yōu)橛谰么鎯?chǔ)儲(chǔ)。staticextern動(dòng)態(tài)存儲(chǔ)儲(chǔ)類型變量量只生存在在某一段段時(shí)間內(nèi)內(nèi)。例如,,函數(shù)的的形參和和函數(shù)體體內(nèi)定義義的變量量,只是在程程序進(jìn)入入該函數(shù)數(shù)時(shí)才分分配存儲(chǔ)儲(chǔ)空間,當(dāng)該函數(shù)數(shù)執(zhí)行完完后,變量對應(yīng)應(yīng)的存儲(chǔ)儲(chǔ)空間又又被撤銷銷了。atuoregister局部變量與全全局變量局部變量---內(nèi)部變量定義:在函數(shù)內(nèi)或復(fù)合語句定義說明:main(函數(shù))中定義的變量量只在main(函數(shù))中有效。復(fù)合語句中定義的變量量只在復(fù)合語句中有效。不同函數(shù)中同同名變量,占占不同內(nèi)存單單元。形參屬于局部部變量。局部變量可用用存儲(chǔ)類型:autoregister。static(默認(rèn)為auto)floatf1(inta){intb,c;…….}charf2(intx,inty){inti,j;……}main(){intm,n;…….}a,b,c有效x,y,i,j有效m,n有效#include<stdio.h>sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}main(){autointa,b;a=3;b=4;sub();printf("main:a=%d,b=%d\n",a,b);}31.自動(dòng)變量量局部靜態(tài)變量量值具有可繼繼承性局部靜態(tài)變量量的初始化只只在編譯時(shí)進(jìn)進(jìn)行一次,每次調(diào)用他們們所在的函數(shù)數(shù)時(shí),不再重重新賦初值;;如定義但不初初始化,自動(dòng)動(dòng)賦0或‘‘\0’1.靜態(tài)局部部變量static數(shù)據(jù)類型變變量名staticinti=1;#include<stdio.h>main(){voidin(void);in();in();in();}voidin(void){intx=0;x++;printf(“%d\n”,x);}4運(yùn)行結(jié)果:111#include<stdio.h>main(){voidin(void);in();in();in();}voidin(void){staticintx=0;x++;printf(“%d\n”,x);}5運(yùn)行結(jié)果::1231.靜態(tài)局局部變量例:分析執(zhí)行結(jié)結(jié)果f(inta){intb=0;staticintc=3;b++;c++;printf("%5d%5d%5d\n",a,b,c);return(a+b+c);}main(){inta=2,k;for(k=0;k<3;k++)printf("%5d\n",f(a));}6靜態(tài)變量只只初始化一一次結(jié)果:214(a,b,c)7(f(a))21582169(3)register(寄存器)型將使用頻率率高的變量量定義為register型,可以提高運(yùn)運(yùn)行速度。。寄存器變量量只限于整型、字符型、指針型的局部變量量。寄存器變量量是動(dòng)態(tài)變變量,而且且數(shù)目有限限,一般僅允許許說明兩個(gè)個(gè)寄存器變變量,過多多的寄存器器變量的編編譯器可能能把它看成成Auto類型。例如:registerintd;registercharc;全局變量---外部變量定義:在函函數(shù)外定義義,可為本本文件所有有函數(shù)共用用有效范圍::從定義變變量的位置置開始到本本源文件結(jié)結(jié)束,及有有extern說明的其它它源文件外部變量說說明:外部變量定定義與外部部變量說明明不同若外部變量量與局部變變量同名,,則外部變變量被屏蔽蔽外部變量可可用存儲(chǔ)類類型:缺省或或static#include<stdio.h>externinta,b;voidswap(){intt;t=a;a=b;b=t;printf(“swap:a=%d,b=%d\n””,a,b);}inta,b;main(){printf(“Entera,b:”);scanf(“%d,%d”,&a,&b);swap();printf(“main:a=%d,b=%d”,a,b);}7Entera,b:5,3↙swap:a=3,b=5main:a=3,b=5運(yùn)行結(jié)果全局變量有有兩個(gè)問題題:其一:當(dāng)全局變量量定義在后后,引用它它的函數(shù)在在前時(shí),如如何使用該該全局變量量?這就需需要把該全全局變量的的作用域延延伸至該函函數(shù);其二:能否使在某某文件中定定義的全局局變量,在在其它文件件中無須再再次定義而而直接使用用它呢?這這就需要把把全局變量量的作用域域進(jìn)行延伸伸。C語言可通過過外部變量量說明達(dá)到到此目的。。定義說明次數(shù):只只能1次可可說說明多次位置:所所有有函數(shù)之外外函函數(shù)內(nèi)或或函數(shù)外分配內(nèi)存::分配內(nèi)存存,可初始化不不分分配內(nèi)存,不可初始化化外部變量說說明:extern數(shù)據(jù)類型變變量表;外部變量定定義與外部部變量說明明不同若外部變量量與局部變變量同名,,則外部變變量被屏蔽蔽例外部變量定義與說明運(yùn)行結(jié)果::max=13#include<stdio.h>externinta,b;//外部變量說說明intmax(intx,inty);//函數(shù)說明main(){printf("max=%d",max(a,b));}inta=13,b=-8;//外部變量定定義intmax(intx,inty)//函數(shù)定義{intz;z=x>y?x:y;return(z);}#include<stdio.h>inta=7,b=9;//a,b為全局變量量voidf1(intx){intt1;t1=b*x;printf("f1:t1=%d,a=%d,b=%d\n",t1,3*a,3*b);}main(){f1(2);//調(diào)用函數(shù)f1()printf("main:a=%d,b=%d\n",a,b);}t8#include<stdio.h>inta,b;/*a,b為全局變量量*/voidf1(intx){intt1,a;//重新定義a,沒重新定義義b,a值傳不過去。。a=x*4;t1=b*3;b=10;printf("f1:t1=%d,a=%d,b=%d\n",t1,a,b);}main(){a=2;b=4;/*此a,b是全局變量,賦值*/f1(2);/*調(diào)用函數(shù)f1()*/printf("main:a=%d,b=%d",a,b);}9f1:t1=12,a=8,b=10main:a=2,b=10結(jié)論:全局變量與與局部變量量同名時(shí),局部變量起作用,全全局變量被被屏蔽(不不影響)變量存儲(chǔ)類類型小結(jié)靜態(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ū)寄存器局部變量外部變量作用域定義變量的函數(shù)或復(fù)合語句內(nèi)本文件其它文件局部變量默默認(rèn)為auto型register型變量個(gè)數(shù)數(shù)受限,且且不能為long,double,float型局部static變量具有全全局壽命和和局部可見見性局部static變量具有可可繼承性extern不是變量定定義,可擴(kuò)展外部部變量作用域域register局部staticauto外部static外部存儲(chǔ)類別6.7內(nèi)部函數(shù)、、外部函數(shù)數(shù)C語言根據(jù)函數(shù)數(shù)能否被其其它源文件件中的函數(shù)數(shù)調(diào)用,將將函數(shù)分為為內(nèi)部函數(shù)數(shù)和外部函函數(shù)。6.7.1內(nèi)部函數(shù)((又稱靜態(tài)態(tài)函數(shù))如果一個(gè)函函數(shù),只能能被本文件件中的函數(shù)數(shù)調(diào)用,而而不能被同同一程序其其它文件中中的函數(shù)調(diào)調(diào)用,則稱稱為內(nèi)部函函數(shù)。定義一個(gè)內(nèi)內(nèi)部函數(shù),,只需在函函數(shù)類型前前再加一個(gè)個(gè)“static”關(guān)鍵字即可可,定義格格式如下::static函數(shù)類型函函數(shù)名(函數(shù)參數(shù)表表){……}如staticintfun(a,b,c){……}6.7.1外部函數(shù)在定義函數(shù)數(shù)時(shí),如果果沒有加關(guān)關(guān)鍵字“static”,或者冠以以“extern”,則表示示此函數(shù)是是外部函數(shù)數(shù),其定義義格式為::[extern]函數(shù)類型函函數(shù)名(函數(shù)參數(shù)表表){……}調(diào)用外部函函數(shù)時(shí),必必須對被調(diào)調(diào)用的外部部函數(shù)進(jìn)行行說明。例/*FILE1*/#include<stdio.h>inti;/*在FILE1中定義外部部變量i*/voidfunc();/*外部函數(shù)說說明*/main(){ i=5;printf("file1:%d\n",i);func();}/*FILE2*/externinti;/*外部變量說說明,F(xiàn)ILE2引用FILE1中定義的外外部變量i*/voidfunc(){ printf("file2:%d\n",i);}該程序的運(yùn)運(yùn)行結(jié)果是是:file1:5file2:56.8編譯預(yù)處理理“編譯預(yù)處理理”是C語言編譯系系統(tǒng)的一一個(gè)組成部部分。是在在編譯前由由編譯系統(tǒng)統(tǒng)中的預(yù)處處理程序?qū)υ闯绦虻牡念A(yù)處理命命令進(jìn)行加加工。源程序序中的的預(yù)處處理命命令均均以““#”開頭,,結(jié)束束不加加分號號,以以區(qū)別別源程程序中中的語語句,,它們們可以以寫在在程序序中的的任何何位置置,作作用域域是自自出現(xiàn)現(xiàn)點(diǎn)到到源程程序的的末尾尾。預(yù)處理理命令令包括括執(zhí)行行宏定定義(宏替換換)、包含含文件件和條條件編編譯。。一.宏定義義簡單宏宏定義義1.一般形形式為為:#define宏名串串(宏體)如:#definePI3.14159/*定義后后,可以用用PI來代替替串3.14159*/2.宏定義義的作作用在宏定定義之之后,該程序序中宏宏名就就代表表了該該字符符串。。說明:占單獨(dú)獨(dú)書寫寫行語句尾尾不加加分號號3.說明①可以以用#undef命令終終止宏宏定義義的作作用域域。例例如::#undefPI②宏定義義的嵌嵌套使使用#defineR3.0#definePI3.1415926#defineL2*PI*R/*宏體是是表達(dá)達(dá)式*/#defineSPI*R*Rmain(){printf("L=%f\nS=%f\n",2*PI*R,PI*R*R);/*2*PI*R替換L,PI*R*R替換S*/}t6-1程序運(yùn)運(yùn)行結(jié)結(jié)果如如下::L=18.849556S=28.274333③雙引號號內(nèi)與與宏同同名的的字母母不作作宏展展開.main(){printf("L=%f\nS=%f\n",L,S);}t6-1#defineX5#defineYX+1#defineZY*X/2main(){inta=Y;printf("%d\n",Z);printf("%d\n",--a);}t6-2//Z=Y*X/2=5+1*5/2=7運(yùn)行結(jié)結(jié)果::75帶參數(shù)數(shù)的宏宏定義義1.帶參數(shù)數(shù)的宏宏定義義的一一般形形式為為#define宏名(參數(shù)表表)字字符串串#defineS(a,b)((a)*(b))2.帶實(shí)參參的宏宏名被被展開開宏名被被所定定義的的宏體體替換換,宏體中中的形形參按按從左左到右右的順序被實(shí)參參替換換。例如:area=S(3,2);展開為為:area=((3)*(2));宏體及及各形形參外外一般般應(yīng)加加括號號())一般寫寫成::#definePOWER(x)((x)*(x))x=4;y=6;z=POWER(x+y);宏展開開:z=((x+y)*(x+y));例#definePOWER(x)x*xx=4;y=6;z=POWER(x+y);宏展開開:z=x+y*x+y;結(jié)果為為:100結(jié)果為為:34課堂練練習(xí)::#include<stdio.h>#defineMIN(x,y)(x)<(y)?(x):(y)main(){inti,j,k;i=10;j=15;k=10*MIN(i,j);printf("%d\n",k);}A)15B)100C)10D)150//10*i<j?10*10<15?(10):(15)使用宏宏替換換應(yīng)注注意的的問題題(1)宏名與與宏體體之間間用空空格相相隔,,宏名名和參參數(shù)之之間不不能有有空格格;如有宏宏定義義:#definef(x)((x)––1)/*宏名f(x)中有空空格*/(2)宏名盡盡管是是字符符串,但不能能用引引號括括起來來(3)在宏定定義中中結(jié)尾尾不能能有分分號””;””(4)宏定義中的的參數(shù)盡量量用圓括號號括起來以以免錯(cuò)誤.(5)較長的宏定定義在一行行中寫不下下時(shí),要在在本行結(jié)尾尾使用反斜斜杠表示續(xù)續(xù)行。如:#defineOUTPUTprintf(“Thisisaninteresting\programwhichteachespepolehowtousedefine\command”)t6-3這是比較特特殊的,因?yàn)樵贑

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論