C語言程序設(shè)計 課件 (張惠濤 ) 西電 第5章 函數(shù)_第1頁
C語言程序設(shè)計 課件 (張惠濤 ) 西電 第5章 函數(shù)_第2頁
C語言程序設(shè)計 課件 (張惠濤 ) 西電 第5章 函數(shù)_第3頁
C語言程序設(shè)計 課件 (張惠濤 ) 西電 第5章 函數(shù)_第4頁
C語言程序設(shè)計 課件 (張惠濤 ) 西電 第5章 函數(shù)_第5頁
已閱讀5頁,還剩61頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第5章

函數(shù)函數(shù)

6C語言程序的開發(fā)環(huán)境5.1模塊化程序設(shè)計與函數(shù)5.2函數(shù)定義5.3函數(shù)調(diào)用5.4函數(shù)遞歸調(diào)用5.5變量的作用域與儲存期5.6編譯預(yù)處理5.1模塊化程序設(shè)計與函數(shù)

在設(shè)計較復(fù)雜的程序時,一般采用自頂向下的方法,將問題劃分為幾個部分,各個部分再進行細(xì)化,直到分解為很容易求解的小問題為止。求解小問題的程序算法叫做“功能模塊”,把復(fù)雜的問題分解為單獨的模塊后,稱為模塊化設(shè)計。因此C語言程序設(shè)計是模塊化程序設(shè)計。5.1.1模塊與函數(shù)C語言中程序是由基本語句和函數(shù)組成,每個函數(shù)負(fù)責(zé)完成獨立的小任務(wù)。c語言程序設(shè)計是模塊化程序設(shè)計。任務(wù)、模塊和函數(shù)的關(guān)系是:解決整個特定問題的大任務(wù)被分解成若干個小問題即功能模塊,功能模塊由一個或者多個函數(shù)來具體實現(xiàn)。解決整個特定問題的程序就通過這些函數(shù)的調(diào)用來完成。總結(jié)來說,模塊化程序設(shè)計就是由設(shè)計函數(shù)和調(diào)用函數(shù)來實現(xiàn)。5.1.1模塊與函數(shù)編程輸出以下圖形。

*********團結(jié)就是力量!*********方法一:(不用函數(shù)實現(xiàn)的程序源代碼)#include<bits/stdc++.h>intmain(){ printf("*********\n"); printf("團結(jié)就是力量!\n"); printf("*********\n"); }【例5.1】5.1.1模塊與函數(shù)方法二:(用函數(shù)實現(xiàn)的程序源代碼)#include<bits/stdc++.h>intmain(){ voidprintstar();/*對printstar函數(shù)進行聲明*/ voidprintunity();/*對printhelloworld函數(shù)進行聲明*/ printstar();/*調(diào)用printstar函數(shù)*/ printunity();/*調(diào)用printhelloworld函數(shù)*/ printstar();/*調(diào)用printstar函數(shù)*/}voidprintstar(){/*定義printstar函數(shù)*/ printf("*********\n");}voidprintunity(){/*定義printhelloworld函數(shù)*/ printf("團結(jié)就是力量!\n");}5.1.2模塊化設(shè)計的基本原則

1.模塊獨立模塊完成獨立的功能,和其他模塊間的關(guān)系簡單,各模塊可以單獨調(diào)試。修改某一模塊,不會造成整個程序的混亂。

模塊的獨立性原則是指模塊完成獨立的功能,可單獨進行調(diào)試。各個模塊之間的聯(lián)系簡單,修改一個模塊不會對整個程序產(chǎn)生大的影響。這要求我們在模塊設(shè)計中注意幾個問題:首先,因為模塊具有相對獨立性,所以在分解任務(wù)時要注意對問題的綜合。其次,各個模塊之間的聯(lián)系簡單,盡量只包含簡單的數(shù)據(jù)傳遞這種聯(lián)系,不要涉及到控制聯(lián)系。最后要注意模塊的私有數(shù)據(jù)的使用。5.1.2模塊設(shè)計原則

2.模塊規(guī)模適當(dāng)

模塊的規(guī)模不能太大或者太小。功能太強的模塊,一般可讀性就會很差,功能太小的模塊,會出現(xiàn)很多接口。初學(xué)者只需記住此原則,在以后的實踐中需經(jīng)常總結(jié)經(jīng)驗。

3.分解模塊要注意層次

在對任務(wù)進行多層次分解時,要尤其注意對問題進行抽象化。開始只需考慮大的模塊,不要過分注意細(xì)節(jié)。在中期,大模塊的設(shè)計中,再逐步細(xì)化求精,分解成較小的模塊進行設(shè)計。5.2函數(shù)定義

在C語言中,函數(shù)(Function)是一個處理過程,把一段程序的工作放在函數(shù)中進行,函數(shù)結(jié)束時可以攜帶或不帶處理結(jié)果。C語言中的程序處理過程全部都是以函數(shù)形式出現(xiàn),最簡單的程序至少也包含一個main()函數(shù)。函數(shù)必須先定義和聲明后才能調(diào)用。5.2函數(shù)定義用戶使用的函數(shù)通常有兩種:標(biāo)準(zhǔn)庫函數(shù)和自定義函數(shù)。標(biāo)準(zhǔn)庫函數(shù):是系統(tǒng)提供給用戶,c語言的強大功能依賴于它豐富的庫函數(shù)。需要注意的是,如果用戶想調(diào)用這些函數(shù),則必須先用編譯預(yù)處理命令將相應(yīng)的頭文件包含到程序中。在前面各章的例題中反復(fù)用到printf、scanf、getchar、putchar、gets、puts、strcat等函數(shù)均屬此類。自定義函數(shù):用戶自己編寫。不僅要在程序中定義函數(shù)本身,而且在主調(diào)函數(shù)模塊中還必須對該被調(diào)函數(shù)進行類型說明,然后才能使用。5.2.1函數(shù)定義的一般形式函數(shù)的定義就是把子任務(wù)的程序?qū)懙揭粋€函數(shù)里。函數(shù)包含函數(shù)的說明部分和函數(shù)體兩大部分。一般形式:類型名函數(shù)名(參數(shù)類型說明及列表)

{局部變量說明語句序列

}例如:輸入兩個整數(shù),以下函數(shù)minpear輸出兩個數(shù)中較小者:intminpear(inta,intb)/*函數(shù)定義和形式參數(shù)類型說明*/{intt;/*局部變量說明*/if(a<b)t=a;/*執(zhí)行語句*/elset=b;returnt;/*返回語句*/}

1.函數(shù)的說明部分函數(shù)的說明部分包括函數(shù)的類型、函數(shù)名、參數(shù)表和參數(shù)類型的說明。例如上例中第一行為函數(shù)的說明部分。(1)函數(shù)的類型。即函數(shù)的返回值類型。表示給調(diào)用者提供什么類型的返回值。函數(shù)可以有或者沒有返回值。

如果函數(shù)沒有返回值,則定義函數(shù)類型為空,用標(biāo)識符void表示空類型。例如:voiddata(inta)

如果函數(shù)有返回值,例如上例中min函數(shù)的類型為int,即函數(shù)的返回值類型是int。(2)函數(shù)名。也叫函數(shù)標(biāo)識符。它遵循C語句標(biāo)識符的命名規(guī)范。(3)參數(shù)表。函數(shù)名后面的括號“()”里的內(nèi)容是參數(shù)表,由變量標(biāo)識符和類型標(biāo)識符構(gòu)成。參數(shù)表中的變量也叫作形式參數(shù),即形參。5.2.1函數(shù)定義的一般形式

1.函數(shù)的說明部分

根據(jù)參數(shù)表中是否有參數(shù)可將函數(shù)分為無參函數(shù)和有參函數(shù)。無參函數(shù):函數(shù)可以沒有形參,叫作無參函數(shù),注意無參函數(shù)的括號“()”不能省略。有參函數(shù):如果有形參,在定義形參時,必須指定形參的類型。例如:intmin(inta,intb)5.2.1函數(shù)定義的一般形式

2.函數(shù)體

在函數(shù)定義中,函數(shù)體是用花括號括起來的部分,函數(shù)的具體功能在函數(shù)體中完成。函數(shù)體內(nèi)的開頭部分是定義和說明部分,后面是語句部分。函數(shù)聲明和函數(shù)體構(gòu)成了函數(shù)定義。

函數(shù)的返回值,是指函數(shù)被調(diào)用之后,執(zhí)行函數(shù)體中的程序段后得到的結(jié)果,并返回給主調(diào)函數(shù)。關(guān)于函數(shù)的返回值有下面幾點說明:

(1)有返回值的函數(shù)體:需要有return返回語句。格式如下:return(表達式);該語句的執(zhí)行順序是先計算表達式的值,然后把結(jié)果返回給主調(diào)函數(shù)。

(2)return語句表達式的類型要和函數(shù)定義中函數(shù)的類型保持一致。如果不一致,則以函數(shù)的類型為準(zhǔn),自動進行類型轉(zhuǎn)換。

(3)若函數(shù)類型為整型,則函數(shù)定義時可以省略函數(shù)類型。

例如,上面提到的自定義函數(shù)min(a,b),根據(jù)傳入的a和b兩個值的大小返回一個t值,也就是兩個數(shù)中的較小者。5.2.1函數(shù)定義的一般形式

函數(shù)調(diào)用時,應(yīng)該遵循先定義后使用的原則。如果函數(shù)調(diào)用出現(xiàn)在函數(shù)定義之前,則要對函數(shù)先進行聲明,也就是讓系統(tǒng)先知道要用哪個函數(shù)以及函數(shù)類型等信息。5.3函數(shù)調(diào)用

函數(shù)聲明與函數(shù)定義時的第一行是基本一致的,包括函數(shù)類型、函數(shù)名、形參個數(shù)、類型、次序。不同的是,函數(shù)聲明是函數(shù)定義時的第一行在結(jié)尾時加上“;”,并且參數(shù)列表中可以省略參數(shù)名。

格式如下:

類型名函數(shù)名(參數(shù)類型說明列表);5.3.1函數(shù)的聲明5.3.1函數(shù)的聲明編程實現(xiàn)孔融讓梨,輸出較小的梨。步驟分析:輸入兩個整數(shù),表示梨的重量;調(diào)用函數(shù)minpear()進行較小值的比較運算;輸出運算結(jié)果;Intmain(){ intminpear(inta,intb);/*對minpear函數(shù)的聲明*/ intx,y,z; printf("inputtwonumbers:\n"); scanf("%d%d",&x,&y); z=minpear(x,y);/*調(diào)用minpear函數(shù)*/ printf("minmum=%d",z);#include<bits/stdc++.h>intminpear(inta,intb){/*函數(shù)定義和形式參數(shù)類型說明*/ intt;/*局部變量說明*/ if(a<b)t=a;/*執(zhí)行語句*/ elset=b; returnt;/*返回語句*/}【例5.2】5.3.1函數(shù)的聲明

本例中,把x,y中的值傳送給minpear的形參a,b。minpear函數(shù)執(zhí)行的結(jié)果(a或b)將返回給變量z。最后由主函數(shù)輸出z的值。

注意:孔融讓梨程序運行結(jié)果如圖:

根據(jù)函數(shù)有參數(shù)或者無參數(shù)兩種情況,函數(shù)調(diào)用可分為:有參函數(shù)調(diào)用和無參函數(shù)調(diào)用。1、有參函數(shù)調(diào)用的形式:函數(shù)名(實參表達式)

例如:min(inta,intb);2、無參函數(shù)調(diào)用的形式:函數(shù)名()

例如:func();5.3.2函數(shù)的調(diào)用

根據(jù)調(diào)用方式不同,函數(shù)調(diào)用可分為:語句調(diào)用和表達式調(diào)用1、語句調(diào)用的形式:

例如:scanf(“%d”,&x);2、表達式調(diào)用的形式:

例如:a+min(x,y);5.3.3函數(shù)的嵌套調(diào)用

在C語言中不允許“嵌套定義函數(shù)”,即不能在一個函數(shù)的定義中作另一個函數(shù)的定義。例如下面的例子,在main函數(shù)的定義中作printdata函數(shù)的定義,這種寫法是錯誤的:intmain(intargc,char*argv[]){//定義func函數(shù)voidprintdata(inta){printf("inprintdata,a=%d\n",a);}printdata(8);return0;}

這樣的代碼,在VC編譯器,或者VisualStudio編譯器中,屬于非法定義的代碼。雖然在func函數(shù)的調(diào)用之前,定義了func函數(shù)。但是,不能夠在main函數(shù)中定義func函數(shù),就是不能夠嵌套定義函數(shù)。

注意:5.3.3函數(shù)的嵌套調(diào)用

但是C語言允許在一個函數(shù)的定義中出現(xiàn)對另一個函數(shù)的調(diào)用。這叫作函數(shù)的嵌套調(diào)用。也就是在被調(diào)函數(shù)中又調(diào)用其它函數(shù)。這與其它語言的子程序嵌套的情形是類似的。例如:intb()/*定義函數(shù)b*/{…….}inta()/*定義函數(shù)a*/{…….b();/*a中調(diào)用函數(shù)b*/}voidmain(){……a();/*主函數(shù)中調(diào)用函數(shù)a*/}調(diào)用a()f2()調(diào)用b()main()b()5.3.3函數(shù)的嵌套調(diào)用

圖中表示了兩層嵌套的情況。其執(zhí)行過程是:在執(zhí)行main函數(shù)時遇到了調(diào)用a函數(shù)的語句,即轉(zhuǎn)到a函數(shù)去執(zhí)行,在執(zhí)行a函數(shù)時遇到了調(diào)用b函數(shù)的語句,則轉(zhuǎn)到b函數(shù)去執(zhí)行,當(dāng)b函數(shù)執(zhí)行完畢后返回a函數(shù)的斷點繼續(xù)執(zhí)行,a函數(shù)執(zhí)行完畢后返回main函數(shù)的斷點繼續(xù)執(zhí)行。5.3.3函數(shù)的嵌套調(diào)用

學(xué)校為鼓勵學(xué)生和輔導(dǎo)老師以賽促教、以賽促學(xué)、以賽促改,進一步推進學(xué)校創(chuàng)新創(chuàng)業(yè)教育邁上新臺階,要求統(tǒng)計計算機專業(yè)兩個班的大學(xué)生計算機應(yīng)用能力競賽獲獎人數(shù),學(xué)校把任務(wù)分配給了輔導(dǎo)員,輔導(dǎo)員把任務(wù)分配給了班長。試編程實現(xiàn)。代碼設(shè)計如下:#include<bits/stdc++.h>intmain(){ intcounselor(); printf("%d",counselor());}intcounselor(){ intmonitor(); return(monitor());}intmonitor(){ inta,b; scanf("%d,%d",&a,&b); returna+b;}【例5.3】5.3.3函數(shù)的嵌套調(diào)用大學(xué)生計算機應(yīng)用能力競賽獲獎人數(shù)程序運行結(jié)果如圖:main函數(shù)相當(dāng)于學(xué)校,在輸出函數(shù)中調(diào)用counselor函數(shù)。counselor函數(shù)中,在return語句中調(diào)用了monitor函數(shù),monitor函數(shù)來求兩個班的人數(shù),并且通過return語句返回人數(shù)之和,層層返回。5.3.3函數(shù)的嵌套調(diào)用【例5.4】計算s=12!+22!+32!#include<bits/stdc++.h>longf1(intd){ /*定義求立方值的函數(shù)f1*/ intcube; longr; longf2(int); /*嵌套調(diào)用階乘函數(shù)f2*/ cube=d*d; r=f2(cube); returnr;}

解題思路:本題可通過編寫兩個函數(shù)來實現(xiàn),第一個函數(shù)f1用來實現(xiàn)計算平方值,第二個函數(shù)f2用來實現(xiàn)計算階乘值。代碼設(shè)計如下:5.3.3函數(shù)的嵌套調(diào)用longf2(intq){ /*定義求階乘值的函數(shù)f2*/ longc=1; inti; for(i=1;i<=q;i++) c=c*i; returnc;}main(){ inti; longs=0; for(i=1;i<=3;i++) s=s+f1(i); /*調(diào)用求立方值的函數(shù)f1*/ printf("\ns=%ld\n",s);}5.3.4參數(shù)傳遞

形參出現(xiàn)在函數(shù)定義中,在整個函數(shù)體內(nèi)都可以使用,離開該函數(shù)則不能使用。實參出現(xiàn)在主調(diào)函數(shù)中,進入被調(diào)函數(shù)后,實參變量也不能使用。形參和實參的功能是作數(shù)據(jù)傳送。發(fā)生函數(shù)調(diào)用時,主調(diào)函數(shù)把實參的值傳送給被調(diào)函數(shù)的形參從而實現(xiàn)主調(diào)函數(shù)向被調(diào)函數(shù)的數(shù)據(jù)傳送。

5.3.4參數(shù)傳遞

函數(shù)的形參和實參具有以下特點:1、形參變量只有在被調(diào)用時才分配內(nèi)存單元,在調(diào)用結(jié)束時,即刻釋放所分配的內(nèi)存單元。因此,形參只有在函數(shù)內(nèi)部有效。函數(shù)調(diào)用結(jié)束返回主調(diào)函數(shù)后則不能再使用該形參變量。2、實參可以是常量、變量、表達式、函數(shù)等,無論實參是何種類型的量,在進行函數(shù)調(diào)用時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應(yīng)預(yù)先用賦值,輸入等辦法使實參獲得確定值。3、實參和形參在數(shù)量上,類型上,順序上應(yīng)嚴(yán)格一致,否則會發(fā)生類型不匹配”的錯誤。4、函數(shù)調(diào)用中發(fā)生的數(shù)據(jù)傳送是單向的。即只能把實參的值傳送給形參,而不能把形參的值反向地傳送給實參。因此在函數(shù)調(diào)用過程中,形參的值發(fā)生改變,而實參中的值不會變化。5.3.4參數(shù)傳遞【例5.5】參數(shù)傳遞算法實例。#include<bits/stdc++.h>intmain(){ intn; printf("inputnumber\n"); scanf("%d",&n); ints(intn); s(n); printf("n=%d\n",n);}ints(intn){ inti; for(i=n-1;i>=1;i--) n=n+i; printf("n=%d\n",n);}5.3.4參數(shù)傳遞

本程序中定義了一個函數(shù)s,該函數(shù)的功能是求n+(n-1)+….+1的值。在主函數(shù)中輸入n值,并作為實參,在調(diào)用時傳送給s函數(shù)的形參量n(注意,本例的形參變量和實參變量的標(biāo)識符都為n,但這是兩個不同的量,各自的作用域不同)。

在主函數(shù)中用printf語句輸出一次n值,這個n值是實參n的值。在函數(shù)s中也用printf語句輸出了一次n值,這個n值是形參最后取得的n值0。從運行情況看,輸入n值為10。即實參n的值為10。把此值傳給函數(shù)s時,形參n的初值也為10,在執(zhí)行函數(shù)過程中,形參n的值變?yōu)?5。返回主函數(shù)之后,輸出實參n的值仍為10??梢妼崊⒌闹挡浑S形參的變化而變化。5.4函數(shù)遞歸調(diào)用直接遞歸形式如下:voidfunc(){......func();/*函數(shù)func中調(diào)用函數(shù)func,直接遞歸*/......}

在函數(shù)內(nèi)部調(diào)用自己,叫作函數(shù)的遞歸調(diào)用。遞歸調(diào)用分為直接遞歸和間接遞歸。

某一函數(shù)在函數(shù)體內(nèi)部直接調(diào)用自身函數(shù)叫作函數(shù)的直接遞歸。即函數(shù)的嵌套調(diào)用的是函數(shù)本身。嵌套調(diào)用自身函數(shù)在我們的學(xué)習(xí)生活中就好像是榜樣的示范!修身立德,才能言傳身教,彰顯榜樣力量!

某一函數(shù)在函數(shù)體內(nèi)部調(diào)用其他函數(shù),其他函數(shù)再調(diào)用本函數(shù),叫作函數(shù)的間接遞歸。5.4函數(shù)遞歸調(diào)用(2)間接遞歸形式如下:voidfunc1(){......func2();/*函數(shù)func1中調(diào)用函數(shù)func2*/......}voidfunc2(){......func1();/*函數(shù)func2中調(diào)用函數(shù)func1,間接遞歸*/

遞歸思想是一個非常有用的解決問題的思路。它不僅可以解決本身是遞歸定義的問題,還可以把看起來很復(fù)雜不容易描述出來的過程變得簡單明了。下面針對這兩方面分別舉例說明遞歸思想。5.4函數(shù)遞歸調(diào)用【例5.6】用遞歸算法計算n!由于n!=n*(n-1)!是遞歸定義,所以求n!

(n-1)!

(n-1)!

(n-2)!

(n–2)!

(n-3)!

……

0!的問題,

根據(jù)公式有0!=1,

再反過來依次求出1!,2!……直到最后求出n!。5.4函數(shù)遞歸調(diào)用#include<stdio.h>longfac(intn){longf;if(n<0)printf("n<0,inputerror");elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}intmain(){intn;longy;printf("\ninputainteagernumber:\n");scanf("%d",&n);y=fac(n);printf("%d!=%ld",n,y);}直到最后的fac(n)都做完了,f的值被返回到了它的調(diào)用點:主函數(shù)中,這樣就是一個遞歸運算。

程序中給出的函數(shù)fac是一個遞歸函數(shù)。主函數(shù)調(diào)用fac后即執(zhí)行函數(shù)fac,如果n<0,n==0或n=1時都將結(jié)束函數(shù)的執(zhí)行,否則就遞歸調(diào)用fac函數(shù)自身。注意每次遞歸調(diào)用的實參為n-1,即把n-1的值賦予形參n,最后當(dāng)n-1的值為1時再作遞歸調(diào)用,形參n的值也為1,將使遞歸終止。然后可逐層退回。5.4函數(shù)遞歸調(diào)用

運行上述程序,若輸入為5,則求5!。在主函數(shù)中調(diào)用語句y=fac(5),進入fac函數(shù)執(zhí)行,判斷n=5,不滿足n等于0或1,故應(yīng)該執(zhí)行f=fac(n-1)*n,即f=fac(5-1)*5。此語句為遞歸調(diào)用。轉(zhuǎn)為求fac(4)。進行四次遞歸調(diào)用后,fac函數(shù)的形參變?yōu)?,滿足elseif(n==0||n==1),將結(jié)束函數(shù)的執(zhí)行,故不再進行遞歸調(diào)用,而開始逐層返回主調(diào)函數(shù)。fac(1)的函數(shù)返回值為1,fac(2)的返回值為1*2=2,fac(3)的返回值為2*3=6,fac(4)的返回值為6*4=24,最后返回值fac(5)為24*5=120。遞歸算法程序運行結(jié)果如圖所示:5.4函數(shù)遞歸調(diào)用

【例5.7】漢諾塔游戲是理論指導(dǎo)實踐,鍛煉學(xué)生們動手操作的經(jīng)典游戲,請編程實現(xiàn)。漢諾塔是一個很繁雜的游戲,但可以用遞歸的方法異常簡單的完成。規(guī)則:(1)一次只能移動一個金片。

(2)大的不能放在小的上面。

(3)只能在三個位置中移動??傮w思想:1.將i-1個盤子先放到B座位上。2.將A座上地剩下的一個盤移動到C盤上。3.將i-1個盤從B座移動到C座上。5.4函數(shù)的遞歸調(diào)用遞歸法解漢諾塔#include<bits/stdc++.h>voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}再將n-1個盤子從b經(jīng)過a移動到cn=1時,直接將金片從a移動到cn-1個金片從a經(jīng)過c移動到b5.4函數(shù)的遞歸調(diào)用voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}遞歸解漢諾塔步驟輸入3,則n=35.4函數(shù)的遞歸調(diào)用voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}遞歸解漢諾塔步驟n=3

主函數(shù)調(diào)用hanoi(n,1,2,3);第一次調(diào)用。第一次調(diào)用hanoi(n,a,b,c)(第一層)即要把三個金片移到c5.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}由于n>1則執(zhí)行hanoi(n-1,a,c,b)

(第二次調(diào)用)n=35.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}由于仍然n>1則執(zhí)行hanoi(n-1,a,c,b)

(第三次調(diào)用)5.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}n=2第三層執(zhí)行完畢,返回到第二層,即下去執(zhí)行printf(“%d->%d”,a,c);把第二個金片擺到第二根針上5.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}n=2執(zhí)行下一條語句,又調(diào)用第三層hanoi(1,3,1,2)5.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}n=1n=1,執(zhí)行結(jié)果為3

25.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}n=3第二層也執(zhí)行完了,返回第一層,執(zhí)行接下來的語句,結(jié)果為1

3。5.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}n=3執(zhí)行接下來的語句,再次調(diào)用

第二層hanoi(2,2,1,3)5.4函數(shù)的遞歸調(diào)用遞歸解漢諾塔步驟voidhanoi(intn,inta,intb,intc)

{

if(n==1)

printf(“%d->%d”,a,c);

else

{hanoi(n-1,a,c,b);

printf(“%d->%d”,a,c);

hanoi(n-1,b,a,c);

}

}voidmain()

{intn;

printf(“inputn:”);

scanf(“%d”,&n);

hanoi(n,1,2,3);

}5.5變量的作用域與儲存期

變量的作用域,即變量有效性的范圍。例如函數(shù)中的形參變量,只在函數(shù)調(diào)用時才給形參分配內(nèi)存單元,函數(shù)調(diào)用結(jié)束后該內(nèi)存單元就會被釋放。這說明形參有效性的范圍即作用域是函數(shù)內(nèi)。形參在函數(shù)以外的范圍是不起作用的。C語言中的變量,根據(jù)作用域可劃分為兩類,即局部變量和全局變量。5.5.1變量根據(jù)作用域進行劃分變量

局部變量也叫內(nèi)部變量。局部變量的作用域是函數(shù)內(nèi),即它是在函數(shù)內(nèi)作定義說明的。函數(shù)以外的地方使用這種變量是不合法的。例如:voidfunc(){inta=3;c1+=32 c2+=32; c3+=32; c4+=32;}

在函數(shù)func中使用main函數(shù)中定義的局部變量c1,c2,c3和c4是非法的。c1,c2,c3和c4在main函數(shù)中定義說明,只能在main函數(shù)中使用,即c1,c2,c3和c4的作用域僅限main函數(shù)。故在func函數(shù)中使用c1,c2,c3和c4是非法的。

1.局部變量voidmain(){charc1,c2,c3,c4; printf("Enterc1,c2,c3,c4:"); scanf("%c%c%c%c",&c1,&c2,&c3,&c4); func(); printf(“%c%c%c%c\n”,c1,c2,c3,c4);}5.5.1變量根據(jù)作用域進行劃分變量正確的使用如下:【例5.8】#include<bits/stdc++.h>voidfunc(){ charc1,c2,c3,c4; /*定義函數(shù)func中的局部變量c1,c2,c3和c4*/ c1='A',c2='B',c3='C',c4='D’; c1+=32; c2+=32; c3+=32; c4+=32; printf("%c%c%c%c\n",c1,c2,c3,c4);/*輸出函數(shù)func中的c1,c2,c3和c4*/}intmain(){ charc1,c2,c3,c4; printf("Enterc1,c2,c3,c4:"); scanf("%c%c%c%c",&c1,&c2,&c3,&c4); func();/*調(diào)用函數(shù)func()*/ printf("%c%c%c%c\n",c1,c2,c3,c4);/*輸出main函數(shù)中的c1,c2,c3和c4*/}5.5.1變量根據(jù)作用域進行劃分變量

全局變量也叫外部變量,它是在函數(shù)外部定義,其作用域是從定義開始,到文件結(jié)束為止。對任何函數(shù)來說,它都不是局部的變量。全局變量具有全局作用域,即定義后,可以用在文件的所有函數(shù)中。如果要在函數(shù)中使用全局變量,應(yīng)先對全局變量進行說明。遵循先說明后使用的原則。全局變量的說明符為extern,可以省略。但是,如果全局變量的定義在前,函數(shù)內(nèi)使用全局變量在后,這種情況可不再加以說明。

2.全局變量5.5.1變量根據(jù)作用域進行劃分變量

2.全局變量【例5.9】全局變量在main函數(shù)中賦值并改變的實例。#include<bits/stdc++.h>charc1,c2,c3,c4; /*定義全局變量c1,c2,c3和c4*/voidfunc(){ c1+=32; /*使用全局變量在main函數(shù)中賦的值,并改變m和n的值*/ c2+=32; c3+=32; c4+=32; printf("%c%c%c%c\n",c1,c2,c3,c4);/*輸出已改變的c1,c2,c3和c4的值*/}intmain(){ c1='T',c2='E',c3='A',c4='M’; /*對全局變量c1,c2,c3和c4賦值*/ func(); /*調(diào)用函數(shù)func()*/ printf("%c%c%c%c\n",c1,c2,c3,c4);/*輸出c1,c2,c3和c4*/}5.5.2變量根據(jù)存儲方式進行劃分

靜態(tài)存儲類型的變量的生存期為程序執(zhí)行的整個過程,在該過程中占有固定的存儲空間,通常稱它們?yōu)橛谰么鎯?。變量按存儲方式劃分:—靜態(tài)存儲—動態(tài)存儲說明

動態(tài)存儲類型變量只生存在某一段時間內(nèi)。例如,函數(shù)的形參和函數(shù)體或分程序中定義的變量,只是在程序進入該函數(shù)或分程序時才分配存儲空間,當(dāng)該函數(shù)或分程序執(zhí)行完后,變量對應(yīng)的存儲空間又被撤銷。5.5.2變量根據(jù)存儲方式進行劃分1、靜態(tài)存儲類別(1)全局變量

全局變量全部存放在靜態(tài)存儲區(qū),在程序開始執(zhí)行時給全局變量分配存儲區(qū),程序執(zhí)行完畢就釋放內(nèi)存。全局變量占據(jù)固定的存儲單元,而不動態(tài)地進行分配和釋放;(2)靜態(tài)局部變量

靜態(tài)局部變量是用static聲明的局部變量,它屬于靜態(tài)存儲方式。局部變量的值在函數(shù)調(diào)用結(jié)束后釋放。有時希望保留函數(shù)中局部變量的原值,這種情況需要指定局部變量為“靜態(tài)局部變量”,用關(guān)鍵字static進行聲明。例如:Staticintm,n;

注意:靜態(tài)局部變量在函數(shù)結(jié)束后仍保留原值,不隨函數(shù)的結(jié)束而消失,生存期為整個程序。靜態(tài)局部變量在編譯時賦初值,即只賦初值一次,若未賦初值,系統(tǒng)自動賦值0.5.5.2變量根據(jù)存儲方式進行劃分【例5.10】靜態(tài)局部變量實例。

#include<bits/stdc++.h>intfunc(){ staticintn=3; n*=2; return(n);}intmain(){ inti; for(i=0;i<3;i++) printf("%d\n",func());}5.5.2變量根據(jù)存儲方式進行劃分2、動態(tài)存儲類別動態(tài)存儲方式:是在程序運行期間根據(jù)需要給變量動態(tài)的分配存儲空間。動態(tài)存儲區(qū)存放函數(shù)的形式參數(shù)和auto自動變量。auto自動變量,是未加static聲明的局部變量。函數(shù)中的局部變量如果不加static存儲類別,都屬于動態(tài)地分配存儲空間,數(shù)據(jù)存儲在動態(tài)存儲區(qū)中。

函數(shù)中的形參和在函數(shù)中定義的變量都屬于自動變量,在調(diào)用該函數(shù)時系統(tǒng)會給它們分配存儲空間,在函數(shù)調(diào)用結(jié)束時就自動釋放這些存儲空間。自動變量用關(guān)鍵字auto作存儲類別的聲明。形式如下:intf(inta)/*定義f函數(shù),a為參數(shù)*/{autointb,c=3;/*定義b,c自動變量*/……}a是形參,b,c是自動變量,對c賦初值3。執(zhí)行完f函數(shù)后,自動釋放a,b,c所占的存儲單元。關(guān)鍵字auto可以省略,auto不寫則隱含定為“自動存儲類別”,屬于動態(tài)存儲方式。5.6編譯預(yù)處理

“編譯預(yù)處理”是C語言編譯系統(tǒng)的一個組成部分。是在編譯前由編譯系統(tǒng)中的預(yù)處理程序?qū)υ闯绦虻念A(yù)處理命令進行加工。

與源程序中的語句不同,源程序中的預(yù)處理命令以“#”開頭,結(jié)束沒有分號,它們可以放在程序中的任何位置,作用域是自出現(xiàn)點到源程序的末尾。

預(yù)處理命令包括執(zhí)行宏定義(宏替換)、文件包含和條件編譯。5.6.1宏定義無參宏的宏名后不帶參數(shù)。無參宏定義的一般形式為:#define標(biāo)識符字符串:其中,“#”表示該行為預(yù)處理命令,“define”為宏定義命令,“標(biāo)識符”為定義的宏名,這里為“M”,“字符串”可以是常數(shù)、表達式、格式串等。例如

溫馨提示

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

評論

0/150

提交評論