《C語言程序設(shè)計教程(第5版)》第8章函數(shù)_第1頁
《C語言程序設(shè)計教程(第5版)》第8章函數(shù)_第2頁
《C語言程序設(shè)計教程(第5版)》第8章函數(shù)_第3頁
《C語言程序設(shè)計教程(第5版)》第8章函數(shù)_第4頁
《C語言程序設(shè)計教程(第5版)》第8章函數(shù)_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第8章函數(shù)

用戶自定義函數(shù)函數(shù)間的數(shù)據(jù)傳遞函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的存儲類別本章要點**

一個C語言源程序通常由一個主函數(shù)和若干個子函數(shù)組成,各子函數(shù)之間的關(guān)系是平行的,因此不能嵌套定義,但能相互調(diào)用。一個C語言源程序無論包含了多少個函數(shù),程序的執(zhí)行總是從主函數(shù)main()開始,并終止于主函數(shù)main()。**通常將一個C語言源程序分解成一個或多個文件,這些文件可分別編寫、編譯、最后連接為一個.EXE

文件。**從用戶使用的角度將函數(shù)分為兩種:標(biāo)準(zhǔn)函數(shù)(庫函數(shù))和用戶自定義函數(shù)。

8.1用戶自定義函數(shù)8.1.1用戶自定義函數(shù)的定義

[類型標(biāo)識符]函數(shù)名([形式參數(shù)表])

{[函數(shù)體]}函數(shù)名:由用戶命名,命名規(guī)則與標(biāo)識符命名規(guī)則相同。類型標(biāo)識符:

定義了函數(shù)返回值的數(shù)據(jù)類型。當(dāng)函數(shù)的返回值是整形或字符型,可省略類型標(biāo)識符。當(dāng)函數(shù)無返回值時,則類型標(biāo)識符用void關(guān)鍵字。

形式參數(shù)表的一般形式為:類型標(biāo)識符形參1,類型標(biāo)識符形參2,···若省略形式參數(shù)表,則稱為無參函數(shù)。否則稱為有參函數(shù)。函數(shù)體:包含了說明語句和執(zhí)行語句。當(dāng)函數(shù)無函數(shù)體時,則為空函數(shù)。例8.1:編寫一個求n!的函數(shù)(n為整數(shù))

longfac(intn){longk=1;inti; /*定義一個累乘器*/for(i=1;i<=n;i++)k*=i;return(k);}例8.2編寫一個打印30個*號的函數(shù)

voidprintstar() {intj;for(j=1;j<=30;j++)printf(“*”);}所定義的函數(shù)有返回值、返回值的類型為長整型,有一個形參,參數(shù)類型為整型所定義的函數(shù)無返回值,無形式參數(shù)8.1.2用戶自定義函數(shù)的返回值函數(shù)的返回值是通過return語句實現(xiàn)的。格式:return(表達式);或return表達式;語義:當(dāng)函數(shù)執(zhí)行到return語句時,程序的流程立即返回到調(diào)用該函數(shù)的地方(通常稱為退出調(diào)用函數(shù)),并通過return語句返回函數(shù)值。return語句中表達式的值就是函數(shù)值。如果return語句不包含表達式,則返回一個不確定的函數(shù)值。longfac(intn){inti;longk;

for(i=1,k=1;i<=n;i++)k=k*i;

return(k);}

如果函數(shù)有返回值,這個值就應(yīng)該有一個確定的數(shù)據(jù)類型,所以在定義函數(shù)首部時應(yīng)指定函數(shù)值的類型。說明:在同一個函數(shù)內(nèi)可根據(jù)需要在多處設(shè)置return語句,函數(shù)執(zhí)行過程中遇到任何一個return語句時,都將立即返回到調(diào)用該函數(shù)的地方。如果需要從被調(diào)函數(shù)中帶回一個確定的值,被調(diào)函數(shù)中必須包含return

語句。如果函數(shù)中沒有return語句,程序的流程一直執(zhí)行到函數(shù)末尾的右花括號“}”處,然后返回到調(diào)用該函數(shù)的地方并返回一個不確定的、無用的函數(shù)值。為了明確表示“不返回值”,可以用“void”定義“無類型”(或稱“空類型”)函數(shù)。max(intx,inty){if(x>y)returnx;elsereturny;}printf(“***”);8.1.3用戶自定義函數(shù)的調(diào)用1、函數(shù)的調(diào)用函數(shù)調(diào)用的一般形式:函數(shù)名([實參表])

實參表:可以是常量、變量或表達式。其類型、順序和個數(shù)必須與函數(shù)定義時形參表的一致。對于無參函數(shù),則省略實參,但括號不能省略。函數(shù)的調(diào)用過程:程序控制從主調(diào)函數(shù)轉(zhuǎn)移到被調(diào)函數(shù);將實參的值按位置一一對應(yīng)傳遞給形參;從被調(diào)函數(shù)的第一條語句開始執(zhí)行該函數(shù)各個語句;在執(zhí)行完所有語句或遇到return語句時,返回到主調(diào)函數(shù)中原來的調(diào)用處繼續(xù)執(zhí)行主調(diào)函數(shù)。

主函數(shù)fun1

fun2{...

{...

{...fun1();

fun2()

...

...

...

......

...

...}RETURN}RETURN}

8.1.4用戶自定義函數(shù)的聲明

在一個函數(shù)中調(diào)用另一函數(shù)(即被調(diào)函數(shù))必須具備以下三個條件:被調(diào)函數(shù)必須是已經(jīng)存在的函數(shù)(標(biāo)準(zhǔn)函數(shù)或用戶自定義函數(shù))。如果調(diào)用的是標(biāo)準(zhǔn)函數(shù),一般還應(yīng)該在源程序的開始處用預(yù)處理命令

#include

將該函數(shù)對應(yīng)的頭文件包含進來。如果調(diào)用用戶自定義函數(shù),而且該函數(shù)與調(diào)用它的函數(shù)(即主調(diào)函數(shù))在同一個文件中,一般還應(yīng)該在主調(diào)函數(shù)中對被調(diào)用函數(shù)返回值的類型以及形參的個數(shù)和類型作聲明。#include"stdio.h"main(){intm,n;longcmn;longfac(int);

printf("inputm,n:");scanf("%d%d",&m,&n);

cmn=fac(m)/fac(n)/fac(m-n);printf("%ld\n",cmn);}例8.3:試編寫一個C程序按下列公式求排列組合問題longfac(intn){inti;longk=1;for(i=1;i<=n;i++)k*=i;return(k);}Cmn=m!/(n!*(m-n)!)函數(shù)聲明的一般形式:類型標(biāo)識符被調(diào)函數(shù)的函數(shù)名([形式參數(shù)表]);這種包含參數(shù)和返回值類型的函數(shù)聲明稱為函數(shù)原型。注意:主調(diào)函數(shù)中的函數(shù)聲明只是聲明了要調(diào)用的函數(shù)返回值的類型以及形參的個數(shù)和類型,不是定義一個函數(shù)。函數(shù)聲明時指定的函數(shù)返回值類型必須與該函數(shù)定義時所指定的類型一致。在同一個文件中,如果被調(diào)函數(shù)位于主調(diào)函數(shù)之前,或者被調(diào)函數(shù)的返回值是int型或char型時,則對被調(diào)函數(shù)的聲明可以省略。用戶自定義函數(shù)的調(diào)用和函數(shù)的聲明例:

#include“stdio.h” main(){inta,b,c;

intmax(intx,inty);/*函數(shù)說明*/ scanf(“%d%d”,&a,&b);

c=max(a,b);/*函數(shù)調(diào)用*/ printf(“%d\n”,c);}

intmax(intx,inty)/*函數(shù)定義*/ {return(x>y?x:y);}形參:形參出現(xiàn)在函數(shù)的定義中,在整個函數(shù)體內(nèi)可以使用,離開該函數(shù)則不能使用;形參必須是變量,在函數(shù)定義時必須進行類型說明;函數(shù)調(diào)用時,形參被臨時分配存儲單元,調(diào)用結(jié)束后,形參所占單元被釋放。實參:實參出現(xiàn)在主調(diào)函數(shù)中,在函數(shù)調(diào)用時,把實參的值傳遞給形參,從而實現(xiàn)主調(diào)函數(shù)向被調(diào)函數(shù)的數(shù)據(jù)傳遞。實參可以是常量和有確定值的變量、數(shù)組元素或表達式8.2簡單變量作函數(shù)實參注意:在函數(shù)調(diào)用期間,實參和形參對應(yīng)不同的內(nèi)存單元,所以在被調(diào)函數(shù)中形參的改變不會影響到主調(diào)函數(shù)的實參,這是一種“單向傳值”調(diào)用。main(){inta,b,c;intmax(intx,inty);scanf(“%d%d”,&a,&b);c=max(a,b);printf(“%d\n”,c);}intmax(intx,inty){return(x>y?x:y);}在被定義的函數(shù)中,必須指定形參的類型。實參與形參應(yīng)在位置、個數(shù)、類型上保持一致。如果實參為整型而形參為實型,或者相反,則發(fā)生“類型不匹配”的錯誤。但字符型與整型可以互相通用。C語言規(guī)定,實參變量對形參變量的數(shù)據(jù)傳遞是“單向值傳遞”。即數(shù)據(jù)只能由實參傳給形參,而不能由形參傳回給實參。關(guān)于單向傳值調(diào)用歸納如下:如果主調(diào)函數(shù)的實參是數(shù)組元素,則對應(yīng)被調(diào)函數(shù)的形參應(yīng)是同類型的變量名,當(dāng)發(fā)生函數(shù)調(diào)用時將數(shù)組元素的值傳遞給相應(yīng)的形參變量main(){intx,y,m;intfun(inta,intb);

scanf("%d,%d",&x,&y);

min=fun(x,y);

printf("min=%d\n",min);}intfun(inta,intb){intc;

if(a<b)c=a;elsec=b;

return(c);}x[2]x[0]x[1]x[0]x[1]8.3.1函數(shù)的嵌套調(diào)用

C語言函數(shù)的定義是平行的、獨立的,不能嵌套定義,但可以嵌套調(diào)用。也就是說,在調(diào)用一個函數(shù)的過程中,被調(diào)函數(shù)又可以調(diào)用另一個函數(shù)。8.3函數(shù)的嵌套調(diào)用和遞歸調(diào)用例:求組合,,,其中:

主函數(shù)fun1

fun2{...

{...

{...fun1();

fun2()

...

...

...

......

...

...}RETURN}RETURN}

函數(shù)的嵌套調(diào)用和遞歸調(diào)用}{inti;longk=1;for(i=1;i<=n;i++)k*=i;returnk;}printf(“c(9,3)=%ld\n",cmn(9,3));main(){}doublecmn(intm,intn){doublec;c=fac(m)/fac(n)/fac(m-n);returnc;longfac(intn)doublecmn(intmintn);longfac(intn);printf(“c(8,2)=%ld\n",cmn(8,2));printf(“c(7,5)=%ld\n",cmn(7,5));8.3.2函數(shù)的遞歸

一個函數(shù)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。一個問題要采用遞歸方法來解決時,必須滿足以下三個條件:可以把要解決的問題轉(zhuǎn)化為一個新的問題,而這個新的問題的解法仍與原來的解法相同,只是所處理的對象有規(guī)律地遞增或遞減??梢詰?yīng)用這個轉(zhuǎn)化過程使問題得到解決。必定要有一個明確的結(jié)束遞歸的條件。longfac(intn){longf;if(n==0||n==1)f=1;elsef=n*fac(n-1);return(f);}main(){longnf;nf=fac(3);printf(“3!=%ld\n”,nf);} 1n=0,1n!= n*(n-1)!n>1例:利用遞歸計算n! 1n=0,1fac(n)= n*fac(n-1)n>18.4變量的存儲類別C語言中的每個變量和函數(shù)都有兩個屬性:數(shù)據(jù)類型和數(shù)據(jù)的存儲類別。數(shù)據(jù)的存儲類別指的是數(shù)據(jù)在內(nèi)存中的存儲方法。分為:靜態(tài)存儲類和動態(tài)存儲類。變量的存儲類別決定了變量的作用域和生存期。變量的數(shù)據(jù)類型決定了變量的取值范圍。變量的存儲類別作用域:變量能夠起作用的程序范圍。分局部變量和全局變量。生存期:變量占用內(nèi)存單元的時限。有的變量可能在整個程序運行期間一直存在(占用內(nèi)存空間),此變量稱為靜態(tài)變量;也有的變量可能只在某個函數(shù)的執(zhí)行期間才存在,這種變量稱為是動態(tài)變量。與存儲類別有關(guān)的說明符有四個,即:auto,static,register,extern程序區(qū)靜態(tài)存儲區(qū)動態(tài)存儲區(qū)1.局部變量

在函數(shù)內(nèi)(或復(fù)合語句中)定義的變量稱為局部變量。函數(shù)的形參屬于局部變量。局部變量的作用域:本函數(shù)(或復(fù)合語句)內(nèi)。

如:main(){inta,b;/*局部變量a,b在main中有效*/······

{intb,c;/*局部變量b,c在復(fù)合語句中有效*/······}······}floatf1(inta){intb,c; ……}8.4.1局部變量及其存儲類別2.局部變量的存儲類別有三種:

auto,static和register。

auto變量:

在函數(shù)體中定義的局部變量如果使用“auto”關(guān)鍵字或缺省該關(guān)鍵字,這種局部變量叫“自動變量”。

如:autointa,b;或inta,b;

自動變量的生存期:函數(shù)被調(diào)用期間自動變量的值:存放在動態(tài)存儲區(qū)中【例】自動變量示例。

#include"stdio.h"main(){intk;intf(intb);for(k=1;k<=4;k++)f(k);}intf(intb){inta=10;printf(“%d+%d=%d\n”,a,b,a+b);a+=10;}運行結(jié)果:10+1=1110+2=1210+3=1310+4=14注意:

**

在函數(shù)中必須有賦值或賦初值的語句,否則變量的值不定,稱為“無定義”。

**

在同一函數(shù)的兩次調(diào)用之間,自動變量的值不保留。(2)靜態(tài)局部變量

在函數(shù)體中定義的局部變量如果使用“static”關(guān)鍵字,稱為“靜態(tài)局部變量”。

如:staticinta=10;

靜態(tài)局部變量的生存期:整個程序運行期間靜態(tài)局部變量的值:存放在靜態(tài)存儲區(qū)中

注意:

**

在整個程序的運行期間,靜態(tài)局部變量占據(jù)的存儲單元一直保留而不釋放,直到程序運行結(jié)束。

**

兩次函數(shù)調(diào)用期間變量的值保持連續(xù)。【例】局部靜態(tài)變量示例。

#include"stdio.h"main(){intk;intf(intb);for(k=1;k<=4;k++)f(k);}intf(intb){staticinta=10;printf(“%d+%d=%d\n”,a,b,a+b);a+=10;}運行結(jié)果:10+1=1120+2=2230+3=3340+4=44說明:(1)靜態(tài)局部變量在編譯時賦初值,程序運行時,每次調(diào)用函數(shù),該變量保留上一次的值,而非初值。自動變量在執(zhí)行時賦初值。(2)若定義時不賦初值,則局部靜態(tài)變量為0,自動變量值不定。(3)函數(shù)調(diào)用結(jié)束后,雖然靜態(tài)局部變量有值,但其他函數(shù)不能使用它。(3)register變量

在函數(shù)體中定義的局部變量如果使用“register”字樣存儲類別關(guān)鍵字,這種局部變量叫“寄存器變量”。

如:registerinta,b;

寄存器變量的生存期:函數(shù)被調(diào)用期間寄存器變量的值:存放在CPU的寄存器中注意:

**CPU中寄存器的數(shù)目是有限的,因此只能說明少量的寄存器變量。

**

由于register

變量的值是放在寄存器內(nèi)而不是放在內(nèi)存中,所以

register

變量沒有地址,也就不能對他進行求地址運算。

**

register變量的說明應(yīng)盡量靠近其使用的地方,用完之后盡快釋放,以便提高寄存器的利用效率。9.4.2全局變量及其存儲類別

全局變量:在函數(shù)外部定義的變量稱為全局變量。

全局變量的作用域:從定義變量的位置開始到整個源文件結(jié)束止。注意:在一個函數(shù)內(nèi)部,既可以使用本函數(shù)定義的局部變量,也可以使用有效的全局變量(在此函數(shù)之前定義的全局變量)。規(guī)定:在同一個文件中,若全局變量與局部變量同名,則在局部變量的作用域內(nèi),全局變量不起作用。例:#include"stdio.h"intk=10;main(){intm,j=k;intk=20;m=k;printf(“%d,%d,%d\n”,k,j,m);}結(jié)果:20,10,202.全局變量的存儲類別:

外部的(extern)和靜態(tài)的(static)

(1)外部全局變量(extern)

在定義全局變量時缺省其存儲類別,則稱為“外部變量”。外部變量的生存期:整個程序的運行期間

外部變量的值:存放在靜態(tài)存儲區(qū)例:已知兩個實數(shù),編寫一函數(shù)求其和、差、積、商。floatsum=0,mul=0,sub=0;/*定義全局變量*/floatsdj(floatx,floaty){sum=x+y;

sub=x-y;

mul=x*y;

return(x/y);}main(){floatx,y,z;

scanf("%f,%f",&x,&y);

z=sdj(x,y);

printf("%f,%f,%f,%f\n",sum,sub,mul,z);}程序運行結(jié)果:8,20<Enter>28.000000,-12.000000,160.000000,0.400000floatf1(){externinta;……}floatf2(){……}intafloatf3(){……}/*文件1*/intx;main(){……}/*文件3*/externintx;f2(){……}/*文件2*/

externintx;f1(){……}注意:如果在外部變量的定義點之前需使用全局變量,應(yīng)在該函數(shù)中進行外部變量的說明,格式為:

extern外部變量名表

用extern對全局變量加以聲明,就可將其作用域擴充到整個源文件或其它源文件中。【例】外部變量示例

#include"stdio.h"

intmax(intx,inty){intz;

z=(x>y)?x:y;

return(z);

}main(){externinta,b;

/*外部變量的聲明*/

printf("max=%d",max(a,b));

}inta=13,b=8;/*外部變量的定義*/

程序運行結(jié)果:max=13(2)靜態(tài)全局變量

在定義全局變量時加“static”關(guān)鍵字,稱為“靜態(tài)全局變量”。

靜態(tài)全局變量的作用域:僅限于定義它的源文件中靜態(tài)全局變量的生存期:整個程序的運行期間/*文件1*/staticintx;main(){……}/*文件2*/staticintx;main(){……}在兩個文件中都定義了一個名為x的靜態(tài)全局變量,但這兩個變量的作用域分別是定義它的文件,分別占據(jù)各自的存儲單元,互相獨立?!纠快o態(tài)全局變量示例

#include"stdio.h"

staticintx=200;intf1(intx){x+=10;printf(“%d……f1()\n”,x);}intf

溫馨提示

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

評論

0/150

提交評論