C語言程序設(shè)計(第二版)課件第7章 函數(shù)_第1頁
C語言程序設(shè)計(第二版)課件第7章 函數(shù)_第2頁
C語言程序設(shè)計(第二版)課件第7章 函數(shù)_第3頁
C語言程序設(shè)計(第二版)課件第7章 函數(shù)_第4頁
C語言程序設(shè)計(第二版)課件第7章 函數(shù)_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第7章函數(shù)

理解并掌握函數(shù)的概念、定義和調(diào)用的方法和實質(zhì)掌握有參函數(shù)的數(shù)據(jù)傳遞方法,區(qū)分“值傳遞”與“地址傳遞”理解標(biāo)識符作用域和生成期的概念理解并掌握存儲類型的概念理解并學(xué)會設(shè)計簡單的遞歸函數(shù)引言函數(shù)可以實現(xiàn)程序的模塊化,使得程序設(shè)計簡單、直觀,提高程序的可讀性和可維護(hù)性,程序員還可以將一些常用的算法編寫成通用函數(shù),以供隨時調(diào)用。無論程序的設(shè)計規(guī)模有多大、多復(fù)雜,都是劃分為若干個相對獨立、功能較單一的函數(shù),通過對這些函數(shù)的調(diào)用,從而實現(xiàn)程序的功能。C語言的函數(shù)分為庫函數(shù)和用戶自定義函數(shù)7.1案例:計算

(1)+(1+2)+(1+2+3)+(1+2+3+4)+(1+2+3+4+5)#include<stdio.h>intsum(intn){inti,s=0;for(i=1;i<=n;i++) s=s+i;returns;}voidmain(){ints,i;for(i=1,s=0;i<=5;i++) s=s+sum(i);printf("s=%d\n",s);}7.2函數(shù)的定義和調(diào)用7.2.1函數(shù)定義函數(shù)的定義如下:類型函數(shù)名(參數(shù)列表){//函數(shù)體

…}7.2.1函數(shù)定義類型指函數(shù)返回值的數(shù)據(jù)類型,函數(shù)名采用標(biāo)識符,一對括號“()”內(nèi)是參數(shù)列表,一對大括號“{}”內(nèi)是函數(shù)體,由一組語句組成,完成函數(shù)具體功能的實現(xiàn)。函數(shù)值的返回通常是運行結(jié)果或狀態(tài)值。返回采用return

語句,例如:return0;returnx>y?x:y;return

后面跟表達(dá)式。返回值的類型也可以是void類型,這種情況下可以寫成:return;也可以省略返回語句。參數(shù):void

表示函數(shù)沒有參數(shù),通常把這種函數(shù)稱為無參函數(shù)。例如:intsum(void){inti,s=0;for(i=1,s=0;i<=100;i++)s=s+i;returns}函數(shù)計算并返回1到100之間的整數(shù)之和。參數(shù):參數(shù)類型1參數(shù)名1,參數(shù)類型2參數(shù)名2,…函數(shù)包含一個或多個參數(shù),每個參數(shù)都必須標(biāo)注具體的數(shù)據(jù)類型。這樣的函數(shù)又稱為有參函數(shù)。例如:intsum(int

n){inti,s=0;for(i=1,s=0;i<=n;i++)s=s+i;returns;}函數(shù)計算并返回1到n之間的整數(shù)之和。7.2.2函數(shù)調(diào)用

函數(shù)調(diào)用的形式如下:函數(shù)名(實參列表)例如:s=sum(100)+sum(200); s=sum(100+200);s=sum(n);

參數(shù)從調(diào)用的角度分為實際參數(shù)和形式參數(shù),或簡稱為實參和形參。實參和形參是一一對應(yīng)的關(guān)系,參數(shù)的個數(shù)和類型都必須一致。如果類型不一致將自動轉(zhuǎn)換,不能自動轉(zhuǎn)換的將在編譯或運行時出錯。7.3參考傳遞實參向形參的參數(shù)傳遞有兩種形式:值傳遞和地址傳遞。值傳遞是單向的數(shù)據(jù)傳遞,傳遞完成后,對形參的任何操作都不會影響實參。地址傳遞也可以說是單向的數(shù)據(jù)傳遞,但這種數(shù)據(jù)往往是變量、結(jié)構(gòu)體、對象等的地址,對形參的操作會直接影響實參,從而使得這種形式上的“單向”數(shù)據(jù)傳遞變成“雙向”的7.3參考傳遞【例7-2】演示函數(shù)的參數(shù)傳遞voidmain(){ intx=10,y=20;inta[10]={1,2,3,4,5,6,7,8,9,10};inti,s=0;swap(x,y);/*值傳遞*/printf("x,y=%d(main)\n",x,y);for(i=0;i<10;i++) s=s+a[i];printf("s=%d\n",s);s=0;change(a);/*地址傳遞*/for(i=0;i<10;i++)s=s+a[i];printf("s=%d\n",s);}#include<stdio.h>voidswap(inta,intb){ intt;t=a;a=b;b=t;printf("a,b=%d(swap)\n",a,b);}voidchange(intx[10]){ inti;for(i=0;i<10;i++) x[i]=x[i]+1;}7.4函數(shù)聲明函數(shù)的聲明是對函數(shù)類型、名稱等的說明。對函數(shù)及其函數(shù)體的建立稱為函數(shù)的定義。對函數(shù)的說明可以和定義一起完成,也可以只對函數(shù)的原型進(jìn)行聲明,這種聲明通常稱為引用性聲明,其格式如下:<類型><函數(shù)名>(<形參表>);如:intsum(inta,intb);和完整的函數(shù)聲明不同的是,形參表可以只給出形參的類型,如:intsum(int,int);形參名可以省略。另外,這種聲明是一條語句,后面的分號(;)必不可少。聲明和定義的區(qū)分變量的聲明通常是對變量的類型和名稱的一種說明,不一定會分配內(nèi)存,而變量的定義肯定會分配內(nèi)存空間。函數(shù)的聲明是對函數(shù)的類型和名稱的一種說明,而函數(shù)的定義是一個模塊,包括函數(shù)體部分。聲明可能也是定義,也可能不是。廣義上的聲明包括定義性聲明和引用性聲明,我們通常所說的聲明指的是后者。7.5作用域作用域就是作用范圍,不同作用域允許相同的標(biāo)識符出現(xiàn),同一作用域標(biāo)識符不能重復(fù),嵌套的作用域標(biāo)識符由內(nèi)向外屏蔽。7.5作用域標(biāo)識符a共出現(xiàn)了3次。大圓A中的inta作用范圍是整個程序;小圓B、D中的inta分屬B、D范圍,而且都屏蔽了大圓A中的a,小圓C可以直接訪問大圓中的inta;小圓B不能訪問小圓D中chard,同樣,小圓D不能訪問小圓B中的charb。B、C、D都能訪問大圓A中的charc、intsum(intn);小圓B、C、D可以理解成是3個函數(shù)或復(fù)合語句。在有些教材中用“塊”來表示一段相對獨立的代碼。【例7-3】作用域演示inta=10;staticintadd(inta,intb){returna+b;}main(){inta,b,c;inti,s=0;intsub(int,int);externintd;a=20;c=10; {inta; intc=20; b=10; a=add(b,c);n} printf("a=%d,b=%d,c=%d\n",a,b,c); for(i=1;i<=100;i++){s=s+i;} for(i=1;i<=100;i++){s=sub(s,i);} printf("s=%d\n",s);printf("d=%d\n",d);}externintsub(inta,intb){returna-b;}intd=888;inte=999;7.6存儲類型從分配內(nèi)存到被回收,變量的使用具有時效性,這就是變量的生存期。在整個程序運行過程中,不同存儲類型的變量生存期也各有差異。一個程序在內(nèi)存中占用的存儲空間分為兩個部分:程序區(qū)和數(shù)據(jù)區(qū),數(shù)據(jù)區(qū)也可以分成靜態(tài)數(shù)據(jù)區(qū)和動態(tài)數(shù)據(jù)區(qū)。生存期和作用域是不同的概念,分別從時間上和空間上對變量的使用進(jìn)行界定,相互關(guān)聯(lián)又不完全一致,例如,靜態(tài)變量的生存期貫穿整個程序,但作用域是從聲明位置開始到文件結(jié)束。7.6存儲類型一個程序在內(nèi)存中占用的存儲空間分為兩個部分:程序區(qū)和數(shù)據(jù)區(qū),數(shù)據(jù)區(qū)也可以分成靜態(tài)數(shù)據(jù)區(qū)和動態(tài)數(shù)據(jù)區(qū)7.6存儲類型變量的存儲類型包括:自動(auto)寄存器(register)靜態(tài)(static)外部(extern)7.6.1自動(auto)類型auto用于局部變量的存儲類型聲明,可以省略,系統(tǒng)默認(rèn)局部變量為auto類型。auto類型變量是動態(tài)變量,聲明時系統(tǒng)不會自動初始化,其值是隨機的,所以必須在使用前初始化或賦值。下面的用法是錯誤的:intadd(inta,intb){intc;c=c+a+b;/*錯誤:c沒有初始化*/returnc;}autointa;/*錯誤:外部變量不能聲明為auto*/7.6.2寄存器(register)類型register用于局部變量的存儲類型聲明,表示請求編譯器盡可能直接分配使用CPU的寄存器,在寄存器滿的情況下才分配內(nèi)存。這種類型的變量主要用于循環(huán)變量,可以大大提高對這種變量的存取速度,從而提高程序效率。能實際實現(xiàn)為register類型的變量很少,主要是寄存器數(shù)量有限。7.6.3靜態(tài)(static)類型static類型變量稱為靜態(tài)變量,存放在靜態(tài)存儲區(qū)。全局變量和局部變量都可以聲明為static類型,但意義不同。全局變量總是靜態(tài)存儲,默認(rèn)值為0。全局變量前加上static表示該變量只能在本程序文件內(nèi)使用,其他文件無使用權(quán)限。對于全局變量,static關(guān)鍵字主要用于在程序包含多個文件時限制變量的使用范圍,對于只有一個文件的程序有無static都是一樣。局部變量聲明為static類型,則要求系統(tǒng)對該變量采用靜態(tài)存儲的內(nèi)存分配方式。值得注意的是,對這種static類型的局部變量,系統(tǒng)初始化只進(jìn)行一次,多次遇到該聲明語句,將不再被執(zhí)行?!纠?-5】演示靜態(tài)變量ints;staticintt;/*其他文件不能使用*/main(){ intsum(int); inti; for(i=3;i<=5;i++) {s=sum(i);t=t+s;}/*t自動初始化為0*/ printf("1+2+3+4+5=%d\n",s); printf("(1+2+3)+(1+2+3+4)+(1+2+3+4+5)=%d\n",t);}intsum(intn){ staticints=0;/*該行語句只執(zhí)行一次*/ inti; for(i=1;i<=n;i++) s=s+i; returns;}【程序分析】sum函數(shù)計算1+2+3+…+n。主函數(shù)中利用for循環(huán)3次調(diào)用sum函數(shù),分別計算sum(3)、sum(4)、sum(5)sum(3)==1+2+3==6s等于6sum(4)==6+(1+2+3+4)==6+10==16s等于16sum(5)==16+(1+2+3+4+5)==16+15==31s等于31t==6+16+31==537.6.4外部(extern)類型extern

關(guān)鍵字用于聲明外部的聯(lián)接。對于全局變量,以下定義形式?jīng)]什么區(qū)別:externinta;inta;默認(rèn)情況下,在文件域中聲明的變量和函數(shù)都是外部的。但對于作用域范圍之外的變量和函數(shù),需要extern來進(jìn)行引用性聲明。7.7案例:遞歸計算s=1+2+3+…+100#include<stdio.h>intf(intn){ if(n==1) return1; else returnn*f(n-1);}ints(intn){ if(n==1) return1; else returnn+s(n-1);}voidmain(){ printf("5!=%d\n",f(5)); printf("1+2+3+...+100=%d\n",s(100));}7.7遞歸函數(shù)函數(shù)不能嵌套定義,但可以嵌套調(diào)用。函數(shù)A可以調(diào)用B,函數(shù)B也可以調(diào)用C,這種調(diào)用稱為嵌套調(diào)用。函數(shù)直接或間接調(diào)用自身,則稱為遞歸調(diào)用,該函數(shù)則稱為遞歸函數(shù)。7.9案例:函數(shù)參數(shù)處理次序的案例voidf(inta,intb){ printf("a=%d,b=%d\n",a,b);}voidmain(){ inti,j; i=j=1; f(i,++i); i=j=1; f(i,i++); i=j=1; f(i+j,++i); i=j=1; f(i+j,i++);}7.10案例:9999符合“歌德巴赫猜想”嗎哥德巴赫(GoldbachC.,1690.3.18-1764.11.20)是德國數(shù)學(xué)家,出生于格奧尼格斯別爾格(現(xiàn)名加里寧城),曾在英國牛津大學(xué)學(xué)習(xí);原學(xué)法學(xué),由于在歐洲各國訪問期間結(jié)識了貝努利家族,所以對數(shù)學(xué)研究產(chǎn)生了興趣;曾擔(dān)任中學(xué)教師?!案璧掳秃詹孪搿笔歉璧掳秃赵?742年6月7日給著名數(shù)學(xué)家歐拉的信中提出的一個命題:隨便取某一個奇數(shù),比如77,可以把它寫成3個素數(shù)之和:77=53+17+7再比如461:461=449+7+5【例7-8】驗證9999是否符合“歌德巴赫猜想”。#include<stdio.h>#include<stdlib.h>intisprimer(int);main(){ intn=9999; inta,b,c; for(a=2;a<n;a++) { if(isprimer(a)) for(b=2;b<n;b++) {c=n-a-b; if(isprimer(b)&&isprimer(c)) {printf("%dInGoldbachGuess\n",n); printf("%d=%d+%d+%d\n",n,a,b,c); exit(0); } } } printf("%dOutGoldbachGuess\n",n);}intisprimer(intn){ inti; for(i=2;i<=n/2;i++) if(n%i==0)break; if(i>n/2)return1; else return0;}7.11 案例:星號圖形的打印#include<stdio.h>#defineN5voidlineprint(intn){ while(n--) printf("*"); printf("\n");}voidprint(intn){ if(n>=1) { lineprint(n); /*輸出一行星號*/ print(n-1); /*遞歸調(diào)用*/ } else return;}voidmain(){ print(N);}

修改lineprint函數(shù)如下:voidlineprint(intn){ inti=n; while(i--) printf(""); while(n--) printf("*"); printf("\n");}將輸出下面的圖形:7.12 案例:演示數(shù)組和函數(shù)的關(guān)系#include<stdio.h>intsum(inta,intb){returna+b;}intsumarray(inta[10]){ ints=0; inti;for(i=0;i<10;i++) s=s+a[i];returns;}voidcleararray(inta[],intpos){inti; a[pos]=0;}voidclear(inta){a=0;}main(){inta[10]={1,2,3,4,5,6,7,8,9,10};printf("a[0]+a[2]=%d\n",sum(a[0],a[2]));printf("a[0]+a[1]+...+a[9]=%d\n",sumarray(a));clear(a[2]); printf("a[0]+a[2]=%d\n",sum(a[0],a[2]));printf("a[0]+a[1]+...+a[9]=%d\n",sumarray(a)); cleararray(a,2);printf("a[0]+a[2]=%d\n",sum(a[0],a[2]));printf("a[0]+a[1]+...+a[9]=%d\n",sumarray(a));}7.12 案例:漢諾塔游戲有3個柱子A、B、C,其中A上由大到小穿插n個中間含孔的圓盤,要求借助柱子B,將這n個圓盤移動到C上,每次只能移動1個盤子,并且任何時候都不能出現(xiàn)大盤在上、小盤在下的情況7.12 案例:漢諾塔游戲算法:將A上n個盤子移動到C上,可以分3步完成:(1)將A上n-1盤子借助C移動到B上(2)將下面的第n個盤子移動到C上(3)將B上n-1盤子借助A移動到C上7.12 案例:漢諾塔游戲#include<stdio.h>/*函數(shù)move:移動一個盤子*/voidmove(intn,chargetone,charputone){printf("%d:%c->%c\n",n,getone,putone);}/*函數(shù)hanoi:移動n個盤子*/voidhanoi(intn

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論