第6,7章函數(shù)(作用域)_第1頁
第6,7章函數(shù)(作用域)_第2頁
第6,7章函數(shù)(作用域)_第3頁
第6,7章函數(shù)(作用域)_第4頁
第6,7章函數(shù)(作用域)_第5頁
已閱讀5頁,還剩86頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第6,7章

函數(shù)

變量存儲類型

第6章函數(shù)

函數(shù)的定義函數(shù)參數(shù)的值的傳遞函數(shù)的調用數(shù)組作為函數(shù)的參數(shù)函數(shù)與指針變量的作用域及存貯類型(指向函數(shù)的指針不要求?。┍菊乱c如前所述,C程序是由函數(shù)組成的。通過函數(shù),我們可以一個較大的問題分成若干個小問題來解決,如用積木建房子?!?

函數(shù)概述一、函數(shù)的分類:標準庫函數(shù):由系統(tǒng)提供,用戶可以不必自己去編寫程序段而直接調用這些函數(shù)。但必須打開相應的頭文件。如printf、scanf等函數(shù)。用戶自定義函數(shù):為了實現(xiàn)用戶的特殊需要而自編的函數(shù)。如max(intx,inty){……}用戶角度有參函數(shù):在調用函數(shù)時,需要進行參數(shù)傳遞的函數(shù),如max(a,b);無參函數(shù):如getchar();有無參數(shù)1.無參函數(shù)的定義:

類型標識符函數(shù)名(){聲明部分;/*定義變量*/語句;/*執(zhí)行部分*/}2.有參函數(shù)的定義:

類型標識符函數(shù)名(形式參數(shù)說明表列){聲明部分;/*定義變量*/語句;/*執(zhí)行部分*/}§2

函數(shù)定義和調用函數(shù)的“類型標識符”用來說明函數(shù)的返回值的類型,通常我們稱之為函數(shù)的類型。如果定義這個函數(shù)只是為了實現(xiàn)某個操作而不需要返回值,則應將該函數(shù)定義為無返回值類型,即void類型。如果你定義的函數(shù)不是void類型,則意味著該函數(shù)只有一個值。此時,在該函數(shù)的結束處,應使用return語句給主調函數(shù)帶回一個值。當函數(shù)執(zhí)行到return語句時,立即中止本函數(shù)的執(zhí)行,而返回到主調函數(shù)處,同時將相應return語句中的值帶回到主調函數(shù)。一個函數(shù)中可以有多個return語句,先執(zhí)行到哪個,哪個就起作用,即執(zhí)行到return語句時,程序將不再向下執(zhí)行,而返回到調用它的地方。§3函數(shù)的返回值“形參”與“實參”:在定義函數(shù)時函數(shù)名后面括號中的變量稱為“形式參數(shù)”,簡稱“形參”;調用函數(shù)時函數(shù)名后括號中對應參數(shù)稱為“實際參數(shù)”,簡稱“實參”。如:intmax(intx,inty){return(x>y?x:y);}

形參voidmain(){inta=1,b=4;

……c=max(a,b)

……}

實參§4

函數(shù)的參數(shù)傳遞1、形參與實參必須一一對應。(個數(shù)、類型)2、定義函數(shù)時,必須指定形式參數(shù)的類型。函數(shù)定義舉例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}“函數(shù)類型”指函數(shù)返回值的類型,也就是說,當該函數(shù)執(zhí)行完成以后,得到一個什么類型的結果。若省略此項,則認為返回類型是int若函數(shù)無返回值,則應定義類型為void函數(shù)定義舉例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}函數(shù)名:通常是一個標識符,在一個程序中除了主函數(shù)外其余函數(shù)的名字可以任意取,但應盡量做到見名知意。函數(shù)名后面的

“()”必須有,表示是函數(shù)。函數(shù)定義舉例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}形參表:函數(shù)定義時的參數(shù)稱為形式參數(shù),形式參數(shù)彼此間用逗號分隔。每個參數(shù)應分別指明其類型。沒有形式參數(shù)的函數(shù)稱為無參函數(shù)。注意無參函數(shù)名字后的圓括號不能省。函數(shù)定義舉例intfactor(intn){ints=1,k;for(k=1;k<=n;k++){s=s*k;}

returns;}函數(shù)中所需變量的定義注:形參及函數(shù)中的變量均是在函數(shù)被調用時才為它們分配存儲單元,函數(shù)調用結束后,其存儲單元會被系統(tǒng)收回!函數(shù)定義舉例intfactor(intn){ints=1,k;

for(k=1;k<=n;k++){s=s*k;}

returns;}Return語句:將函數(shù)計算之后的值通過return語句返回(帶回)到調用的地方函數(shù)一旦執(zhí)行到return語句,則該函數(shù)的執(zhí)行就此結束,不再執(zhí)行下面其它的語句。實參是如何將值傳給形參的?先看下面的例子:實參是如何將值傳給形參的?voidadd(intx,inty){x=x+10;y=y+10;}voidmain(){inta=3,b=5;add(a,b);printf(“%d,%d”,a,b);}例:驗證C中函數(shù)調用時參數(shù)的值的傳遞。

add(a,b);過程分析:voidadd(intx,inty){

3535voidmain(){inta=3,b=5;x=x+10;135y=y+10;1315}

add(a,b);實參是如何將值傳給形參的35voidmain(){inta=3,b=5;printf(“%d,%d”,a,b);}輸出結果:3,5函數(shù)調用結束后,形參所占的內存單元也釋放。實參變量對形參變量進行數(shù)據(jù)傳遞時,遵循的原則是“單向值傳遞”。實參與形參所占內存單元不同。當形參中的值改變時,不會影響到實參中的值。即只能由實參把值傳給形參,而不能反過來。這就是所謂的“單向值傳遞”。通過以上的分析,我們可以有如下結論:分析:以下程序能否實現(xiàn)兩數(shù)交換swap(intm,intn){intz;

z=m;m=n;n=z;

printf("形參:m=%d,n=%d",m,n);}voidmain(){intm=3,n=5;swap(m,n);printf("實參:m=%d,n=%d",m,n);}在被調用函數(shù)中改變形參的值,不會影響到主調函數(shù)中的實參,因為其參數(shù)傳值時的原則是“單向值傳遞”函數(shù)調用的一般形式:有參函數(shù):函數(shù)名(實參表列);無參函數(shù):函數(shù)名();對于有參函數(shù),多個參數(shù)之間用逗號將實參分隔開;而對于無參函數(shù),調用時也不能省略括號。注意:在調用函數(shù)時,對于實參時,不能再將類型說明符寫在括號中。

intmax(int

x,int

y)//-------

函數(shù)定義

c=max(inta,intb);×

//------錯誤的函數(shù)調用

c=max(

a,b);√//------正確的函數(shù)調用§5

函數(shù)的調用

對于調用有參函數(shù),若參數(shù)是表達式或變量,調用時先計算出表達式或變量的值,然后將計算出的表達式(變量)的值傳給形參。對于多數(shù)C系統(tǒng)而言,對實參表列的求值順序是按從右向左的順序。intfunc(inta,intb){intc;if(a>b)c=1;if(a==b)c=0;if(a<b)c=-1;return(c);}

voidmain(){inti=3,a;a=func(i,++i);printf(“%d”,a);}例:驗證實參表列的求值順序

輸出結果:0printf也是函數(shù),因此在使用中,也同樣存在參數(shù)求值順序的問題。例如:設有x=3;

printf(“%d,%d”,x,x++);輸出結果:4,3函數(shù)調用作為一個語句(函數(shù)語句):如:prinft(“Hello,world!!!”);(1)、函數(shù)調用的方式

函數(shù)調用出現(xiàn)在一個表達式中(函數(shù)表達式)。如:c=max(a,b);對于此類調用,參加的函數(shù)必定有一個返回值。函數(shù)調用作為一個函數(shù)調用的實參。(函數(shù)參數(shù))。如:d=max(a,max(b,c));

則將函數(shù)調用max(b,c)的返回值作為另一次函數(shù)調用的實參。被調用的函數(shù)必須是已經存在的函數(shù)。如果該函數(shù)是庫函數(shù),那么必須在程序的開始處用#include語句將相應的頭文件包含進來。如果是用戶自定義的函數(shù),則應在調用到這個函數(shù)之前讓系統(tǒng)知道這個函數(shù)。有兩種方法:(1)將被調用的函數(shù)的定義放在調用這個函數(shù)之前。如:(2)、對被調用函數(shù)的聲明

intmax(intx,inty){returnx>y?x:y;}voidmain(){……..c=max(a,b);……}

3、在調用這個函數(shù)之前對所調用個函數(shù)作一個說明,讓系統(tǒng)知道這個函數(shù)需要的參數(shù)、類型,以及返回值的類型,這即是對該函數(shù)的聲明。但是注意,對函數(shù)說明時,括號后有分號;而函數(shù)定義時則沒有。如:

intmax(intx,inty);

//--------①

函數(shù)的聲明voidmain(){intmax(intx,inty);

//--------

②函數(shù)的聲明c=max(a,b);主程序中對函數(shù)的調用語句……} intmax(intx,inty){returnx>y?x:y;}函數(shù)的定義

(2)、對被調用函數(shù)的聲明函數(shù)聲明可以在主調函數(shù)內,也可以在函數(shù)外。其區(qū)別在于:在函數(shù)體外部進行的聲明,在本文件中的所有地方都有效,無需在主調函數(shù)內再次聲明;在函數(shù)內部進行的聲明,則所聲明的函數(shù)只能在本函數(shù)內部使用;所謂的函數(shù)的嵌套調用,就是在調用一個函數(shù)的過程中,又調用了其它函數(shù)。如在主函數(shù)中調用了a函數(shù),而在a函數(shù)中又調用了b函數(shù),在b函數(shù)中又調用了c函數(shù),這就是函數(shù)的嵌套調用。其調用過程如下圖所示:

§6

函數(shù)的嵌套調用

main(){……a();

a(){……b();c(){……

……

……}

……}

……}b(){……c();

……}main(){inta=1,b;b=func1(a);printf(“%d”,b);}func1(intx){inty;y=func2(x)+1;returny;}

例:函數(shù)的嵌套調用func2(intx){inty;y=func3(x)+1;returny;}func3(intx){inty;y=x+5;returny;}輸出結果:8數(shù)組元素做函數(shù)的實參,其用法與變量相同。(每個的數(shù)組元素相當于一個獨立變量)。例如:§7函數(shù)與數(shù)組數(shù)組作為函數(shù)的參數(shù),可以有兩種情況:例:比較兩個數(shù)組中的元素,統(tǒng)計出a中大于對應b中元素的位置。intcompare(intx,inty){intz;if(x>y)z=1;elseif(x==y)z=0;elsez=-1;returnz;}voidmain(){inta[10]=…,b[10]=…,i,t;

for(i=0;i<10;i++);{t=compare(a[i],b[i]);if(t>0)printf(“a[%d]>b[%d]”,i,i);}}

輸出:a[2]>b[2]……0123auvw…bwvu…數(shù)組名作為函數(shù)參數(shù): 前面我們已經知道:在C中,數(shù)組名代表的是數(shù)組的起始地址。因此,當數(shù)組名作為函數(shù)的參數(shù)時,所傳遞的也是數(shù)組的起始地址。§8數(shù)組作為函數(shù)的參數(shù)例:自編字符串復制函數(shù)strcopy

strcopy(charstr11[30],charstr22[30]){inti;for(i=0;str22[i]!=0;i++)str11[i]=str22[i];str11[i]=0;}voidmain(){charstr1[30];charstr2[30]=”abcde”;

printf(“%s”,str1);

strcopy(str1,str2);printf(“%s”,str1);}思考:main中打印出的結果是?Strcopy退出循環(huán)是時I值?main(){inti,a[5]={1,2,3,4,5};例1:數(shù)組名作為函數(shù)參數(shù)func(a);0x2000a[0]1a[1]2a[2]3a[3]4a[4]5voidfunc(intx[5]){voidfunc(intx[5]){x[3]=0;}for(i=0;i<5;i++)printf(“%d”,a[i]);}0x2000X[3]=0;}X[3](0x2000+3)所對應的元素0x2000a[0]1X[0]a[1]2X[1]a[2]3X[2]a[3]0X[3]a[4]5X[4]X[0]X[1]X[2]X[3]X[4]例2:試比較以下程序與上面程序的區(qū)別輸出結果:12345voidfunc(intx){x=0;}main(){inti,a[5]={1,2,3,4,5};func(a[3]);for(i=0;i<5;i++)printf(“%d”,a[i]);}a[0]10x2000a[1]2a[2]3a[3]4a[4]5X4X01、當用數(shù)組名作為函數(shù)參數(shù)時,并不是象變量作形參一樣,再開空間給形參數(shù)組,而是接收數(shù)組名傳遞來的數(shù)組的首地址。所以,在子函數(shù)中對數(shù)組的修改,實質上就是對主函數(shù)中數(shù)組的修改。2、實參數(shù)組與形參數(shù)組類型必須一致。3、主調函數(shù)和被調函數(shù)中分別定義數(shù)組名,可以一樣,也可不一樣,系統(tǒng)回自動區(qū)分,互不干擾。

由上面兩例所得結論:再看幾例:例1:自編字符串復制函數(shù)strcopy

strcopy(charstr1[30],charstr2[30]){inti;for(i=0;str2[i]!=0;i++)str1[i]=str2[i];str1[i]=‘\0’;}voidmain(){charstr1[30];charstr2[30]=”abcde”;

printf(“%s”,str1);

strcopy(str1,str2);printf(“%s”,str1);}再看幾例:例2:自編求字符串長函數(shù)strlenth

strlenth(charstr[30]){inti;for(i=0;str2[i]!=0;i++);

returni;}voidmain(){charstr1[30]=”abcde”;

intlen;

len=strlenth(str1);printf(“%d”,len);}再看幾例:例3:自編字符串比較函數(shù)strcomp

intstrcomp(charstr1[],charstr2[]){inti;for(i=0;str1[i]==str2[i]&&str1[i]!=0;i++);return(str1[i]-str2[i]);}voidmain(){charstr1[30],str2[30];

intd;

gets(str1);gets(str2);

d=strcomp(str1,str2);printf(“%d”,d);}

§9指針作為函數(shù)參數(shù)

1、傳址調用:指針變量作為函數(shù)參數(shù)當指針變量作為函數(shù)參數(shù)時,傳遞的是變量的地址。讀以下程序:voidtestpoint(int*p){intt;t=*p;t++;}voidmain(){inta=3,*p;p=&a;printf(“a=%d\n”,a);testpoint(p);printf(“a=%d\n”,a);}a30x2000:P主&at30x6000:P函&a如果將程序的第4)行改為(*p)++,請再觀察程序的結果:voidtestpoint(int*p){intt;t=*p;t++;}voidmain(){inta=3,*p;p=&a;printf(“a=%d\n”,a);testpoint(p);printf(“a=%d\n”,a);}(*p)++;a30x2000:p&at30x6000:p&a例1:兩數(shù)交換函數(shù)swapt:voidswap(int*p1,int*p2)

{intt;

t=*p1;*p1=*p2;*p2=t;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a50x2000b302002p1&ap2&bp1&ap2&b例1:兩數(shù)交換函數(shù)swapt:voidswap(int*p1,int*p2)

{intt;

t=*p1;*p1=*p2;*p2=t;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a30x2000b502002p1&ap2&bp1&ap2&bvoidswap(int*p1,int*p2)

{int*p;

p=p1;p1=p2;p2=p;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a30x2000b502002p1&ap2&bp1&ap2&bp例2:兩數(shù)交換函數(shù)swapvoidswap(int*p1,int*p2)

{int*p;

p=p1;p1=p2;p2=p;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}a30x2000b502002p1&ap2&bp1&bp2&ap例2:兩數(shù)交換函數(shù)swap例3:兩數(shù)交換函數(shù)swapvoidswap(int*p1,int*p2)

{int*p;*p=*p1;*p1=*p2;*p2=*p;

}

voidmain()

{inta,b,*p1,*p2;

scanf(“%d,%d”,&a,&b);

p1=&a;p2=&b;swap(p1,p2);printf(“a=%d,b=%d”,a,b);printf(“%d,%d”,*p1,*p2);}形參p1和p2得到main函數(shù)中a和b的地址,這樣p1和p2的目標變量就是main函數(shù)的變量a和b。在swap函數(shù)中交換*p1和*p2的內容,就是交換a和b的內容,所以當函數(shù)調用結束后,盡管p1和p2已經釋放,但操作結果仍保留在main函數(shù)的變量a和b中,這就是通過指針形參指向域擴展到主調函數(shù)的方法,達到主調函數(shù)與被調函數(shù)間交換多個數(shù)據(jù)的目的。

主調函數(shù)與被調函數(shù)之間數(shù)據(jù)傳遞的方法:①實參與形參之間的數(shù)據(jù)傳遞;②被調函數(shù)通過return語句把函數(shù)值返回到主調函數(shù);③通過全局變量交換數(shù)據(jù);④利用指針型參數(shù)在主調函數(shù)和被調函數(shù)之間傳遞數(shù)據(jù)。

§9指針與函數(shù)⑴一維數(shù)組的指針作函數(shù)參數(shù)例如被調函數(shù)abc的定義形式有以下三種:voidabc(intb[10]){……}voidabc(intb[]){……}voidabc(int*b){……}在主調函數(shù)有如下定義:inta[10],*p=a;則調用abc函數(shù)時可用abc(a)或abc(p)2023/7/29422.數(shù)組的指針作函數(shù)參數(shù)

當函數(shù)之間需要傳遞數(shù)組時,可以通過傳遞數(shù)組的首地址(即通過指針參數(shù)指向域的擴展),完成存取主調函數(shù)中數(shù)組元素的操作。

§9指針與函數(shù)【例8.20】字符串復制函數(shù)。voidcopystr(char*t,char*s)

{while((*t++=*s++)!='\0');}main(){charc[80],*p="Iamastudent.";copystr(c,p);

printf("%s\n",c);}2023/7/29432.數(shù)組的指針作函數(shù)參數(shù)

§9指針與函數(shù)⑵

二維數(shù)組的指針作函數(shù)參數(shù)

2023/7/29442.數(shù)組的指針作函數(shù)參數(shù)

由于指向二維數(shù)組的指針分為行指針和元素指針,所以他們作為函數(shù)參數(shù)的形式也不同。

二維數(shù)組的行指針作函數(shù)參數(shù)例如被調函數(shù)abc的定義形式有以下三種:voidabc(intb[2][4]){……}voidabc(intb[][4]){……}voidabc(int(*b)[4]){……}在主調函數(shù)有如下定義:inta[2][4],(*p)[4]=a;則調用abc函數(shù)時可用abc(a)或

abc(p)用函數(shù)輸入輸出整型二維數(shù)組,函數(shù)的形參為行指針。voidinarr(int(*p1)[4],intm){inti,j;/*可改寫為void

inarr(intp1[][4],intm)*/for(i=0;i<m;i++)for(j=0;j<4;j++)scanf("%d",*(p1+i)+j);}2023/7/2945main(){inta[3][4],(*p)[4];p=a;inarr(a,3);outarr(p,3);}2.數(shù)組的指針作函數(shù)參數(shù)

voidoutarr(int(*p2)[4],intm){inti,j;for(i=0;i<m;i++){for(j=0;j<4;j++)printf("%6d",p2[i][j]);printf("\n");}}

可改寫為voidoutarr(intp2[3][4],intm)/§9指針與函數(shù)⑵

二維數(shù)組的指針作函數(shù)參數(shù)

②指向二維數(shù)組元素的指針作函數(shù)參數(shù)2023/7/29462.數(shù)組的指針作函數(shù)參數(shù)

指向二維數(shù)組元素的指針作函數(shù)參數(shù)時,是利用二維數(shù)組元素按行連續(xù)存儲的的特點,訪問數(shù)組的每一個元素。被調函數(shù)的形參必須定義為指向二維數(shù)組元素的指針變量。例如被調函數(shù)abc的定義形式如下:voidabc(int*b){……}另外,在主調函數(shù)有如下定義:inta[2][4],*p=a[0];則調用abc函數(shù)時可用abc(a[0])、abc(&a[0][0])或

abc(p)【例】用函數(shù)輸入輸出整型二維數(shù)組,函數(shù)的形參為指向二維數(shù)組元素的指針。voidinarr(int*p1,intm,intn){inti,j;for(i=0;i<m;i++)for(j=0;j<n;j++)scanf("%d",p1+n*i+j);}2023/7/29472.數(shù)組的指針作函數(shù)參數(shù)

main(){inta[3][4],*p;p=&a[0][0];inarr(a[0],3,4);outarr(p,3,4);}voidoutarr(int*p1,intm,intn){inti,j;for(i=0;i<m;i++){for(j=0;j<n;j++)printf("%6d",*(p1+n*i+j));printf("\n");}}就是在調用一個函數(shù)的過程中又直接或間接地調用了該函數(shù)

§10

函數(shù)的遞歸調用(不要求)

直接調用例:設有func函數(shù)定義如下intfunc(){intb;b=func();returnb;}voidmain()

{:

func();}則以下程序執(zhí)行過程如下:func(){intb;b=func();returnb;}func(){intb;b=func();returnb;}func(){intb;b=func();returnb;}間接調用例:設func1函數(shù)、func2函數(shù)定義如下intfunc1(){……;func2();……}voidmain()

{:

func1();}則當主函數(shù)中調用了func1函數(shù)時的執(zhí)行過程如下:func1(){……;func2();……}func2(){……;func1();……}func1(){…func();……}intfunc2(){……;func1();……}顯然,在函數(shù)的遞歸調用中,如果不加以控制,則其最終必將耗盡系統(tǒng)資源,或死循環(huán)。因此,在遞歸調用的函數(shù)中,必須有一個條件來判斷何時遞歸調用停下來。

遞歸出口!用遞歸求n!遞歸過程

。1.應用遞歸的原因和領域

遞歸定義

┏1當n=0

階乘n!=┃┗n*(n-1)!當n>0用遞歸求解更簡單用遞歸求n!例1、求階乘的函數(shù)。

1若n=0Fact(n)=

n*Fact(n-1)若n>0longFact(longn){longs;

if(n==0)return1;//遞歸出口elses=n*Fact(n–1);//遞歸return(s);}Main(){longn;Scanf(“%ld”,&n);Printf(“%ld”,fact(n));}主程序n=4Fact(4)(1)n3Fact(3)(2)(1),4topn2Fact(2)(3)(1),4top(2),3n1Fact(1)(4)top(1),4(2),3(3),2n0Fact(0)top(1),4(2),3(3),2(4),1Return1top(1),4(2),3(3),2(4),1Return1top(1),4(2),3(3),2Return2(1),4top(2),3Return6(1),4topReturn24結束遞歸過程1.遞歸過程的特點:是程序設計的一個強有力的工具,它具有結構清晰,程序易編、易讀、易調試,程序正確性易證明等優(yōu)點;但運行效率低。2.基本原理:基本原理是重復地把問題轉化為與原問題相似的新問題,直到問題可解決為止。3.關鍵點:

①用較簡單的新問題來表示較復雜的原問題例如:n!=n(n-1)!,或n!=(n+1)!/(n+1)前者(n-1)!較原問題n!簡單,可行;而后者(n+1)!較n!更復雜,不可行。②不能產生自己調用自己的無窮序列,即必須有一個遞歸調用序列的“出口”,來終止遞歸調用。遞歸函數(shù):Fun(n){if(n>0)fun(n/2);Printf(“%d”,n);}Main(){inta=6;fun(a);}請問該程序輸出結果是:0136§11返回指針的函數(shù)指針函數(shù):一個函數(shù)的返回值是一個指針(即地址)。函數(shù)定義形式:

類型說明*函數(shù)名(形參表)

函數(shù)體

例:int*rp(int1,inty){………}例:輸入1-7整數(shù),輸出對應星期名#include<stdio.h>#include<string.h>voidmain(){inti;char*day_name(intn);printf(“inputDayNo:\n”);scanf(“%d”,&i);printf(“DayNo:%2d%s\n”,i,day_name(i));}char*day_name(intn){staticchar*name[8]={“error”,”Monday”,”Tuesday”,………};return((n<1||n>7)?name[0],name[n]);}指針數(shù)組變量的作用域:使用變量都必須先定義。但并非定義之后,在程序的任何地方均可使用這一變量。變量是有一定的作用范圍的。根據(jù)變量的作用范圍,可將變量分為局部變量(內部變量)和全局變量(外部變量)。局部變量:作用范圍局限與某個函數(shù)或結構體復合語句內。全局變量:在函數(shù)體外定義的變量是全局變量。其作用范圍為定義之處開始,至整個程序結束。

§12變量的存儲類型intmax(intx,inty){inta;

if(x>y)returnx;elsereturny;}voidmain(){inta=3,b=5,c;c=max(a,b);}局部變量例:

x,y的作用范圍

a的作用范圍不同函數(shù)中可以定義同名變量,互不干擾

a,b,c的作用范圍主函數(shù)中定義的量也屬局部變量如果變量的定義是放在某復合語句中的,那么,該變量的作用范圍就只在這個復合語句中有效。intmax(intx,inty){

c=x-y;

returnc;}voidmain(){inta=3,b=5,c;c=max(a,b);}局部變量例:

x,y的作用范圍

語法錯誤,不能識別的標識符C

a,b,c的作用范圍主函數(shù)中定義的量也屬局部變量

inta,b;voidfunc(intx,inty){a=x+5;b=y+3;}voidmain(){func(3,8);printf(“a=%d,b=%d\n”,a,b);func(4,6);printf(“a=%d,b=%d\n”,a,b);func(a,b);printf(“a=%d,b=%d\n”,a,b);}全局變量例:

a,b的作用范圍

x,y的作用范圍a=8,b=11a=9,b=9a=14,b=12

inta,b;voidfunc(intx,inty)

{intb;a=x+5;

b=y+3;}voidmain(){func(3,8);printf(“a=%d,b=%d\n”,a,b);func(4,6);printf(“a=%d,b=%d\n”,a,b);func(a,b);printf(“a=%d,b=%d\n”,a,b);}全局變量例:

a,b的作用范圍

x,y的作用范圍,全局變量b被屏蔽,局部變量b起作用a=8,b=0a=9,b=0a=14,b=0全局變量自動初始化為0;全局變量在所有函數(shù)之外定義的變量在程序中定義它的位置以后都有效自動初始化為0從程序運行起即占據(jù)內存,程序運行過程中可隨時訪問,程序退出時釋放內存在定義點之前或在其他文件中引用,應該進行如下聲明:extern類型名變量名;使函數(shù)之間的數(shù)據(jù)交換更容易,也更高效但是并不推薦使用因為誰都可以改寫全局變量,所以很難確定是誰改寫了它結論:盡可能不使用全局變量!全局變量與局部變量同名屏蔽原則:局部優(yōu)先局部變量的全局變量比較:根據(jù)變量的存在的時間(生存期),變量可劃分為:動態(tài)存儲變量和靜態(tài)存儲變量。動態(tài)存儲方式:是在程序運行期間根據(jù)需要進行動態(tài)分配存儲空間的方式。與之對應的變量被稱為動態(tài)存儲變量。通常,如果定義的變量沒有其它的說明的話,系統(tǒng)自動將之作為一個動態(tài)存儲變量,簡稱動態(tài)變量。當然,也可用關健字“auto”進行定義。靜態(tài)存儲方式:是指程序在運行期間分配給固定存儲空間的方式。與之對應的變量被稱為靜態(tài)存儲變量,簡稱靜態(tài)變量。必須用關健字“static”進行定義。

§13

動態(tài)存儲變量與靜態(tài)存儲變量

§13

動態(tài)存儲變量與靜態(tài)存儲變量

指數(shù)據(jù)在內存中存儲的方式,即編譯器為變量分配內存的方式,它決定變量的生存期動態(tài)存儲根據(jù)需要臨時分配存儲空間,離開即釋放靜態(tài)存儲在程序運行期間分配固定的存儲空間不釋放程序區(qū)靜態(tài)存儲區(qū)動態(tài)存儲區(qū)形參、自動變量、函數(shù)調用的現(xiàn)場等全局變量、靜態(tài)變量自動變量(auto)“自動”體現(xiàn)在進入語句塊時自動申請內存,退出時自動釋放內存動態(tài)局部變量標準定義格式auto類型名變量名;缺省的存儲類型不初始化時,值是不確定的

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}voidadd(intx,inty){

3535voidmain(){inta=3,b=5;x=x+10;y=y+10;}

add(a,b);voidadd(intx,inty){

35voidmain(){inta=3,b=5;x=x+10;y=y+10;}1315

add(a,b);35voidmain(){inta=3,b=5;printf(“%d,%d”,a,b);}

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}voidadd(intx,inty){

3535voidmain(){inta=3,b=5;x=x+10;y=y+10;}voidadd(intx,inty){

35voidmain(){inta=3,b=5;x=x+10;y=y+10;}1315

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}35voidmain(){inta=3,b=5;

add(a,b);printf(“%d,%d”,a,b);Add(a,b);printf(“%d,%d”,a,b);}靜態(tài)變量(static)一個函數(shù)的內部變量在函數(shù)退出后失效。再次進入函數(shù),變量值重新初始化把此變量定義為static,則變量的值可以保存到下次進入函數(shù)staticinti;靜態(tài)變量和全局變量都是靜態(tài)存儲類型自動初始化為0從靜態(tài)存儲區(qū)分配,生存期為整個程序運行期間但作用域不同對于用“static”關健字定義的靜態(tài)變量則不同:該類型的變量由系統(tǒng)分配一個專門的存儲空間來存放;當函數(shù)調用結束后,該變量所占空間并不釋放,當下次再調用該函數(shù)時,該變量中已有值。如下例所示:§13

動態(tài)存儲變量與靜態(tài)存儲變量

intf(inta){intb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);}

voidmain(){inta=2,b,i;b=f(a);printf(“%d\n”,b);b=f(a);printf(“%d\n”,b);}

b=f(a);2?2voidmain(){inta=2,b;intb=0;b=b+1;staticintc=3;0§13

動態(tài)存儲變量與靜態(tài)存儲變量

3intf(inta){

b=f(a);2?voidmain(){inta=2,b;intb=0;b=b+1;staticintc=3;c=c+1;1§13

動態(tài)存儲變量與靜態(tài)存儲變量

32intf(inta){

b=f(a);2?voidmain(){inta=2,b;intb=0;b=b+1;}staticintc=3;c=c+1;return(a+b+c);1§13

動態(tài)存儲變量與靜態(tài)存儲變量

42intf(inta){

b=f(a);27voidmain(){inta=2,b;§13

動態(tài)存儲變量與靜態(tài)存儲變量

4printf(“b=%d\n”,b);輸出:b=7b=f(a);intf(inta){

2intb=0;0staticintc=3;b=b+1;

b=f(a);27voidmain(){inta=2,b;intb=0;b=b+1;staticintc=3;c=c+1;1§13

動態(tài)存儲變量與靜態(tài)存儲變量

42intf(inta){

printf(“b=%d\n”,b);b=f(a);b=f(a);27voidmain(){inta=2,b;intb=0;b=b+1;}staticintc=0;c=c+1;return(a+b+c);1§13

動態(tài)存儲變量與靜態(tài)存儲變量

52intf(inta){

printf(“b=%d\

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論