函數(shù)與預(yù)編譯_第1頁
函數(shù)與預(yù)編譯_第2頁
函數(shù)與預(yù)編譯_第3頁
函數(shù)與預(yù)編譯_第4頁
函數(shù)與預(yù)編譯_第5頁
已閱讀5頁,還剩87頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

函數(shù)與預(yù)編譯第1頁,課件共92頁,創(chuàng)作于2023年2月模塊化思想模塊各司其職每個(gè)模塊只負(fù)責(zé)一件事情,它可以更專心便于進(jìn)行單個(gè)模塊的設(shè)計(jì)、開發(fā)、調(diào)試、測試和維護(hù)等工作一個(gè)模塊一個(gè)模塊地完成,最后再將它們集成開發(fā)人員各司其職按模塊分配任務(wù),職責(zé)明確并行開發(fā),縮短開發(fā)時(shí)間分而治之(Wirth,1971)

信息隱藏(Parnas,1972)第2頁,課件共92頁,創(chuàng)作于2023年2月在結(jié)構(gòu)化程序設(shè)計(jì)中,函數(shù)是將任務(wù)進(jìn)行模塊劃分的基本單位。一個(gè)函數(shù)實(shí)現(xiàn)一項(xiàng)功能。在面向?qū)ο蟪绦蛟O(shè)計(jì)中,函數(shù)是對數(shù)據(jù)的一項(xiàng)操作,也是實(shí)現(xiàn)一項(xiàng)功能。第四章函數(shù)與預(yù)編譯

要掌握函數(shù)的使用,必須理解函數(shù)調(diào)用時(shí)的內(nèi)部實(shí)現(xiàn)機(jī)制,以及與此相關(guān)的內(nèi)存分配機(jī)制、變量生命期和作用域。

本章還將介紹關(guān)于函數(shù)重載的概念,介紹遞歸算法、內(nèi)聯(lián)函數(shù)、默認(rèn)參數(shù)函數(shù)以及多文件組織、編譯預(yù)處理、工程文件的概念和運(yùn)行庫函數(shù)。第3頁,課件共92頁,創(chuàng)作于2023年2月第四章函數(shù)與預(yù)編譯

4.1函數(shù)的定義與調(diào)用

4.5作用域與標(biāo)識符的可見性

4.4函數(shù)調(diào)用機(jī)制

4.3全局變量和局部變量

4.2函數(shù)的參數(shù)傳遞,返回值及函數(shù)聲明

4.10編譯預(yù)處理4.9頭文件與多文件結(jié)構(gòu)4.6存儲類型與標(biāo)識符的生命期4.8函數(shù)的一些高級議題

4.7函數(shù)的遞歸調(diào)用

第4頁,課件共92頁,創(chuàng)作于2023年2月

4.1

函數(shù)的定義與調(diào)用4.1.1

函數(shù)概述4.1.2

函數(shù)的定義4.1.3

函數(shù)的調(diào)用

第5頁,課件共92頁,創(chuàng)作于2023年2月4.1.1函數(shù)概述函數(shù)是C++程序的基本組成模塊。通過函數(shù),可以把一個(gè)復(fù)雜任務(wù)分解成為若干個(gè)易于解決的小任務(wù)。充分體現(xiàn)逐步細(xì)化的設(shè)計(jì)思想。組成C++程序的若干函數(shù)中,有一個(gè)稱為main()函數(shù),是程序執(zhí)行的入口,它可以調(diào)用其他函數(shù),但不可以被調(diào)用。而其他一般函數(shù)既可以調(diào)用也可以被調(diào)用。函數(shù)概念的引入:入口函數(shù):第6頁,課件共92頁,創(chuàng)作于2023年2月4.1.1函數(shù)概述main()fun2()fun1()fun3()funa()funb()func()圖4.1函數(shù)調(diào)用層次關(guān)系第7頁,課件共92頁,創(chuàng)作于2023年2月4.1.1函數(shù)概述4.1.1結(jié)束庫函數(shù)和自定義函數(shù):庫函數(shù)或標(biāo)準(zhǔn)函數(shù),是由編譯系統(tǒng)預(yù)定義的,如一些常用的數(shù)學(xué)計(jì)算函數(shù)、字符串處理函數(shù)、圖形處理函數(shù)、標(biāo)準(zhǔn)輸入輸出函數(shù)等。庫函數(shù)都按功能分類,集中說明在不同的頭文件中。用戶只需在自己的程序中包含某個(gè)頭文件,就可直接使用該文件中定義的函數(shù)。用戶根據(jù)需要將某個(gè)具有相對獨(dú)立功能的程序定義為函數(shù),稱自定義函數(shù)。第8頁,課件共92頁,創(chuàng)作于2023年2月4.1.2函數(shù)的定義無參函數(shù)定義格式為:《數(shù)據(jù)類型》函數(shù)名(《void》){函數(shù)體}說明:數(shù)據(jù)類型指函數(shù)返回值類型,可以是任一種數(shù)據(jù)類型,默認(rèn)為返回整型值(但新標(biāo)準(zhǔn)要求寫明,不用默認(rèn)方式)。沒有返回值應(yīng)將返回值類型定義為void。函數(shù)名采用合法標(biāo)識符表示。對無參函數(shù),參數(shù)括號中的void通常省略,但括號不能省略。函數(shù)體由一系列語句組成。函數(shù)體可以為空,稱為空函數(shù)。1無參函數(shù)第9頁,課件共92頁,創(chuàng)作于2023年2月4.1.2函數(shù)的定義例:打印一個(gè)表頭voidTableHead(){cout<<″****************″<<endl;cout<<″*example*″<<endl;cout<<″****************″<<endl;}第10頁,課件共92頁,創(chuàng)作于2023年2月2有參函數(shù)有參函數(shù)的定義格式為《數(shù)據(jù)類型》函數(shù)名(參數(shù)類型1形式參數(shù)1《,參數(shù)類型2形式參數(shù)2,…》{函數(shù)體}例:寫一函數(shù),返回兩個(gè)整數(shù)中較大一個(gè)的值有參函數(shù)的參數(shù)表中列出所有形式參數(shù)的類型和參數(shù)名稱。各參數(shù)即使類型相同也必須分別加以說明。形式參數(shù)簡稱形參,只能是變量名,不允許是常量或表達(dá)式。intmax(inta,intb){return(a>=b?a:b);}第11頁,課件共92頁,創(chuàng)作于2023年2月問題:定義函數(shù)時(shí)究竟哪些變量應(yīng)當(dāng)作為函數(shù)的參數(shù)?哪些應(yīng)當(dāng)定義在函數(shù)體內(nèi)?提示原則:函數(shù)在使用時(shí)被看成“黑匣子”,除了輸入輸出外,其他部分可不必關(guān)心。從函數(shù)的定義看出,函數(shù)頭正是用來反映函數(shù)的功能和使用接口,它所定義的是“做什么”。即明確了“黑匣子”的輸入輸出部分,輸出就是函數(shù)的返回值,輸入就是參數(shù)。因此,只有那些功能上起自變量作用的變量才必須作為參數(shù)定義在參數(shù)表中;函數(shù)體中具體描述“如何做”,因此除參數(shù)之外的為實(shí)現(xiàn)算法所需用的變量應(yīng)當(dāng)定義在函數(shù)體內(nèi)。

C++中不允許函數(shù)的嵌套定義,即在一個(gè)函數(shù)中定義另一個(gè)函數(shù)。第12頁,課件共92頁,創(chuàng)作于2023年2月4.1.3

函數(shù)的調(diào)用函數(shù)調(diào)用:所謂函數(shù)調(diào)用,就是使程序轉(zhuǎn)去執(zhí)行函數(shù)體。在C++中,除了主函數(shù)外,其他任何函數(shù)都不能單獨(dú)作為程序運(yùn)行。任何函數(shù)功能的實(shí)現(xiàn)都是通過被主函數(shù)直接或間接調(diào)用進(jìn)行的。

無參函數(shù)的調(diào)用格式:函數(shù)名()

有參函數(shù)的調(diào)用格式:函數(shù)名(實(shí)際參數(shù)表)其中實(shí)際參數(shù)簡稱實(shí)參,用來將實(shí)際參數(shù)的值傳遞給形參,因此可以是常量、具有值的變量或表達(dá)式?!纠?.1】輸入兩個(gè)實(shí)數(shù),輸出其中較大的數(shù)第13頁,課件共92頁,創(chuàng)作于2023年2月4.2

函數(shù)的參數(shù)傳遞、返回值及

函數(shù)聲明

4.2.1函數(shù)的參數(shù)傳遞及傳值調(diào)用

4.2.3函數(shù)聲明4.2.2函數(shù)返回值

第14頁,課件共92頁,創(chuàng)作于2023年2月參數(shù)傳遞:函數(shù)調(diào)用首先要進(jìn)行參數(shù)傳遞,參數(shù)傳遞的方向是由實(shí)參傳遞給形參。傳遞過程是,先計(jì)算實(shí)參表達(dá)式的值,再將該值傳遞給對應(yīng)的形參變量。一般情況下,實(shí)參和形參的個(gè)數(shù)和排列順序應(yīng)一一對應(yīng),并且對應(yīng)參數(shù)應(yīng)類型匹配(賦值兼容),即實(shí)參的類型可以轉(zhuǎn)化為形參類型。而對應(yīng)參數(shù)的參數(shù)名則不要求相同。

4.2.1函數(shù)的參數(shù)傳遞及傳值調(diào)用

傳值調(diào)用和引用調(diào)用:按照參數(shù)形式的不同,C++有兩種調(diào)用方式:傳值調(diào)用和引用調(diào)用。傳值調(diào)用傳遞的是實(shí)參的值,本章介紹傳值調(diào)用。第15頁,課件共92頁,創(chuàng)作于2023年2月4.2.1函數(shù)的參數(shù)傳遞及傳值調(diào)用

傳值調(diào)用:將實(shí)參的值復(fù)制給形參,在函數(shù)中參加運(yùn)算的是形參,而實(shí)參不會發(fā)生任何改變。傳值調(diào)用起了一種隔離作用?!纠?.2】實(shí)參和形參對應(yīng)關(guān)系的示例。第16頁,課件共92頁,創(chuàng)作于2023年2月4.2.2函數(shù)返回值return語句的格式:return表達(dá)式;函數(shù)的計(jì)算結(jié)果通過該語句傳遞回主調(diào)函數(shù)?!纠?.3】設(shè)計(jì)函數(shù),根據(jù)三角形的三邊長求面積。如果不能構(gòu)成三角形,給出提示信息。分析:函數(shù)為計(jì)算三角形面積,一般三角形返回面積值,若不能構(gòu)成三角形則返回-1。設(shè)計(jì)一個(gè)主函數(shù)完成函數(shù)測試。根據(jù)返回值情況輸出相應(yīng)結(jié)果。第17頁,課件共92頁,創(chuàng)作于2023年2月4.2.2函數(shù)返回值函數(shù)可以有返回值,也可以沒有返回值。對于沒有返回值的函數(shù),功能只是完成一定操作,應(yīng)將返回值類型定義為void,函數(shù)體內(nèi)可以沒有return語句,當(dāng)需要在程序指定位置退出時(shí),可以在該處放置一個(gè):

return

;討論:4.2.2結(jié)束第18頁,課件共92頁,創(chuàng)作于2023年2月4.2.3

函數(shù)聲明

函數(shù)聲明是一條以分號結(jié)束的語句:《函數(shù)返回值類型》函數(shù)名(《形參表》);

語法上對程序文件中函數(shù)的排列次序要求滿足先定義后使用。但從結(jié)構(gòu)化程序設(shè)計(jì)的角度,通常是先調(diào)用后定義。使用函數(shù)聲明,則既符合由粗到精的思維方式,又滿足了語法要求。

其中形參表可以逐個(gè)列出每個(gè)參數(shù)的類型和參數(shù)名,也可以列出每個(gè)形參的類型,參數(shù)名可省略,各形參之間以逗號分隔。函數(shù)聲明和所定義的函數(shù)必須在返回值類型、函數(shù)名、形參個(gè)數(shù)和類型及次序等方面完全對應(yīng)一致,否則將導(dǎo)致編譯錯誤。函數(shù)聲明的引入:函數(shù)聲明的格式:第19頁,課件共92頁,創(chuàng)作于2023年2月

下面是一個(gè)使用結(jié)構(gòu)化程序設(shè)計(jì)思想開發(fā)的企業(yè)管理報(bào)表程序的框架。它使用了函數(shù)聲明。voidmenu_print();voidaccount_report();voidengineering_report();voidmarketing_report();intmain(){

intchoice;

do{

menu_print(); cin>>choice;}while(choice<=0||choice>=4);

switch(choice){

case1:account_report();break;

case2:engineering_report();break;

case3:marketing_report();break;}

return0;}第20頁,課件共92頁,創(chuàng)作于2023年2月voidmenu_print(){cout<<”系統(tǒng)功能:”<<endl;cout<<”1 財(cái)務(wù)報(bào)表”<<endl;cout<<”2 工程報(bào)表”<<endl;cout<<”3 市場報(bào)表”<<endl;cout<<”選擇業(yè)務(wù)序號:”;}voidaccount_report(){//生成財(cái)務(wù)報(bào)表}voidengineering_report(){//生成工程報(bào)表}voidmarketing_report(){//生成市場報(bào)表;}第21頁,課件共92頁,創(chuàng)作于2023年2月4.2.3

函數(shù)聲明【例4.4】

輸出所有滿足下列條件的正整數(shù)m:10<m<1000且m、m2、m3均為回文數(shù)。分析:回文指左右對稱的序列。如121、353等就是回文數(shù)。判斷整數(shù)是否回文數(shù)用函數(shù)實(shí)現(xiàn),其思想是將該數(shù)各位拆開后反向組成新的整數(shù),如果該整數(shù)與原數(shù)相等則為回文數(shù)。mm*mm*m*m111211331101102011030301111123211367631

運(yùn)行結(jié)果:第22頁,課件共92頁,創(chuàng)作于2023年2月4.3全局變量和局部變量4.4.1變量的存儲機(jī)制與C++的內(nèi)存布局

4.4.2全局變量

4.4.3局部變量

第23頁,課件共92頁,創(chuàng)作于2023年2月4.4.1變量的存儲機(jī)制與C++的內(nèi)存布局自由存儲區(qū)(動態(tài)數(shù)據(jù))棧區(qū)(函數(shù)局部數(shù)據(jù))(main()函數(shù)局部數(shù)據(jù))全局?jǐn)?shù)據(jù)區(qū)(全局、靜態(tài))代碼區(qū)(程序代碼)

操作系統(tǒng)為一個(gè)C++程序的運(yùn)行所分配的內(nèi)存分為四個(gè)區(qū)域,如圖4.3

所示:第24頁,課件共92頁,創(chuàng)作于2023年2月存儲區(qū)域說明:(1)代碼區(qū)(Codearea):存放程序代碼,即程序中各個(gè)函數(shù)的代碼塊;(2)全局?jǐn)?shù)據(jù)區(qū)(Dataarea):存放全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù);分配該區(qū)時(shí)內(nèi)存全部清零,結(jié)果變量的所有字節(jié)自動初始化為零。(3)棧區(qū)(Stackarea):存放局部變量,如函數(shù)中的變量等;分配棧區(qū)時(shí)不處理內(nèi)存,即變量取隨機(jī)值。(4)自由存儲區(qū)(Freestorearea):存放與指針相關(guān)的動態(tài)數(shù)據(jù)。分配自由存儲區(qū)時(shí)不處理內(nèi)存。參見第七章。4.4.1變量的存儲機(jī)制與C++的內(nèi)存布局第25頁,課件共92頁,創(chuàng)作于2023年2月4.4.2全局變量在所有函數(shù)之外定義的變量稱為全局變量。全局變量在編譯時(shí)建立在全局?jǐn)?shù)據(jù)區(qū),在未給出初始化值時(shí)系統(tǒng)自動初始化為全0。全局變量可定義在程序開頭,也可定義在中間位置,該全局變量在定義處之后的任何位置都是可以訪問的,稱為可見的?!纠?.5】多個(gè)函數(shù)使用全局變量的例子。全局變量引入:第26頁,課件共92頁,創(chuàng)作于2023年2月4.4.3局部變量

定義在函數(shù)內(nèi)或塊內(nèi)的變量稱為局部變量。程序中使用的絕大多數(shù)變量都是局部變量。局部變量在程序運(yùn)行到它所在的塊時(shí)建立在棧中,該塊執(zhí)行完畢局部變量占有的空間即被釋放。局部變量在定義時(shí)可加修飾詞auto,但通常省略。局部變量在定義時(shí)若未初始化,其值為隨機(jī)數(shù)。局部變量引入:【例4.6】使用局部變量的例子。第27頁,課件共92頁,創(chuàng)作于2023年2月4.4函數(shù)調(diào)用機(jī)制

局部變量占用的內(nèi)存是在程序執(zhí)行過程中“動態(tài)”地建立和釋放的。這種“動態(tài)”是通過棧由系統(tǒng)自動管理進(jìn)行的。(1)建立??臻g;(6)恢復(fù)現(xiàn)場:取主調(diào)函數(shù)運(yùn)行狀態(tài)及返回地址,釋放??臻g;(7)繼續(xù)主調(diào)函數(shù)后續(xù)語句。(5)釋放被調(diào)函數(shù)中局部變量占用的??臻g;(4)執(zhí)行被調(diào)函數(shù)函數(shù)體;(3)為被調(diào)函數(shù)中的局部變量分配空間,完成參數(shù)傳遞;(2)保護(hù)現(xiàn)場:主調(diào)函數(shù)運(yùn)行狀態(tài)和返回地址入棧;調(diào)用過程:第28頁,課件共92頁,創(chuàng)作于2023年2月4.4函數(shù)調(diào)用機(jī)制voidfun1(int,int);voidfun2(float);intmain(){intx=1;y=2;fun1(x,y);

returno;}voidfun1(inta,intb){

floatx=3;fun2(x);}voidfun2(floaty){

intx;…}x棧頂棧底y3fun2()fun1()運(yùn)行狀態(tài)及返回地址x3b2a1fun1()main()運(yùn)行狀態(tài)及返回地址y2x1main()操作系統(tǒng)運(yùn)行狀態(tài)及返回地址此圖例說明在程序執(zhí)行過程中怎樣通過?!皠討B(tài)”地建立和釋放局部變量占用的內(nèi)存的第29頁,課件共92頁,創(chuàng)作于2023年2月

4.5作用域與標(biāo)識符的可見性3文件作用域

2函數(shù)聲明作用域

作用域:指標(biāo)識符能夠被使用的范圍。只有在作用域內(nèi)標(biāo)識符才可以被訪問(稱為可見)。本節(jié)重點(diǎn)討論局部域和文件域(全局域),其中局部域包括塊域和函數(shù)聲明域。任何標(biāo)識符作用域的起始點(diǎn)均為標(biāo)識符說明處。下面分別介紹:1塊作用域

第30頁,課件共92頁,創(chuàng)作于2023年2月函數(shù)中定義的標(biāo)識符,包括形參和函數(shù)體中定義的局部變量,作用域都在該函數(shù)內(nèi),也稱作函數(shù)域。塊域塊指一對大括號括起來的程序段。塊中定義的標(biāo)識符,作用域在塊內(nèi)。復(fù)合語句是一個(gè)塊。函數(shù)也是一個(gè)塊。復(fù)合語句中定義的標(biāo)識符,作用域僅在該復(fù)合語句中?!纠?.7】輸入兩數(shù),按從大到小的順序保存。塊的引入:第31頁,課件共92頁,創(chuàng)作于2023年2月塊域由VC++平臺運(yùn)行,結(jié)果如下:輸入兩整數(shù):35調(diào)用前:實(shí)參a=3,b=5調(diào)用中…交換前:形參a=3,b=5交換后:形參a=5,b=3調(diào)用后:實(shí)參a=3,b=5

交換失敗局部變量具有局部作用域使得程序在不同塊中可以使用同名變量。這些同名變量各自在自己的作用域中可見,在其它地方不可見?!纠?.8】設(shè)計(jì)函數(shù)完成兩數(shù)交換,用主函數(shù)進(jìn)行測試。第32頁,課件共92頁,創(chuàng)作于2023年2月塊域

對于塊中嵌套其它塊的情況,如果嵌套塊中有同名局部變量,服從局部優(yōu)先原則,即在內(nèi)層塊中屏蔽外層塊中的同名變量,換句話說,內(nèi)層塊中局部變量的作用域?yàn)閮?nèi)層塊;外層塊中局部變量的作用域?yàn)橥鈱映グ兞康膬?nèi)層塊部分。如果塊內(nèi)定義的局部變量與全局變量同名,塊內(nèi)仍然局部變量優(yōu)先,但與塊作用域不同的是,在塊內(nèi)可以通過域運(yùn)算符“::”訪問同名的全局變量?!纠?.9】顯示同名變量可見性。第33頁,課件共92頁,創(chuàng)作于2023年2月函數(shù)聲明作用域

函數(shù)聲明不是定義函數(shù),在作函數(shù)聲明時(shí),其中的形參作用域只在聲明中,即作用域結(jié)束于右括號。正是由于形參不能被程序的其他地方引用,所以通常只要聲明形參個(gè)數(shù)和類型,形參名可省略。第34頁,課件共92頁,創(chuàng)作于2023年2月3文件作用域

文件作用域也稱全局作用域。定義在所有函數(shù)之外的標(biāo)識符,具有文件作用域,作用域?yàn)閺亩x處到整個(gè)源文件結(jié)束。文件中定義的全局變量和函數(shù)都具有文件作用域。如果某個(gè)文件中說明了具有文件作用域的標(biāo)識符,該文件又被另一個(gè)文件包含,則該標(biāo)識符的作用域延伸到新的文件中。如cin和cout是在頭文件iostream中說明的具有文件作用域的標(biāo)識符,它們的作用域也延伸到嵌入iostream的文件中。第35頁,課件共92頁,創(chuàng)作于2023年2月存儲類型(storageclass)決定標(biāo)識符的存儲區(qū)域,即編譯系統(tǒng)在不同區(qū)域?yàn)椴煌鎯︻愋偷臉?biāo)識符分配空間。由于存儲區(qū)域不同,標(biāo)識符的生命期也不同。所謂生命期,指的是標(biāo)識符從獲得空間到空間釋放之間的期間,標(biāo)識符只有在生存期中、并且在其自己的作用域中才能被訪問。4.6存儲類型與標(biāo)識符的生命期

4.6.1存儲類型

4.4.2生命期

第36頁,課件共92頁,創(chuàng)作于2023年2月自動變量為用auto說明的變量,通常auto缺省。局部變量都是自動變量,生命期開始于塊的執(zhí)行,結(jié)束于塊的結(jié)束,其原因是自動變量的空間分配在棧中,塊開始執(zhí)行時(shí)系統(tǒng)自動分配空間,塊執(zhí)行結(jié)束時(shí)系統(tǒng)自動釋放空間。故自動變量的生命期和作用域是一致的。4.6.1存儲類型

為提高程序運(yùn)行效率,可以將某些變量保存在寄存器中,即用register說明為寄存器變量,但不提倡使用。C++中關(guān)于存儲類型的說明符(storageclassspecifier)有四個(gè):auto、register、static和extern。其中用auto和register修飾的稱為自動存儲類型,用static修飾的稱為靜態(tài)存儲類型,用extern修飾的稱為外部存儲類型。1自動存儲類型第37頁,課件共92頁,創(chuàng)作于2023年2月static說明的變量稱為靜態(tài)變量。根據(jù)定義的位置不同,還分為局部靜態(tài)變量和全局靜態(tài)變量,也稱內(nèi)部靜態(tài)變量和外部靜態(tài)變量。靜態(tài)變量均存儲在全局?jǐn)?shù)據(jù)區(qū),如果程序未顯式給出初始化值,系統(tǒng)自動初始化為全0,且初始化只進(jìn)行一次;靜態(tài)變量占有的空間要到整個(gè)程序執(zhí)行結(jié)束才釋放,故靜態(tài)變量具有全局生命期。4.6.1存儲類型局部靜態(tài)變量是定義在塊中的靜態(tài)變量,當(dāng)塊第一次被執(zhí)行時(shí),編譯系統(tǒng)在全局?jǐn)?shù)據(jù)區(qū)為其開辟空間并保存數(shù)據(jù),該空間一直到整個(gè)程序結(jié)束才釋放。局部靜態(tài)變量具有局部作用域,但卻具有全局生命期。2靜態(tài)存儲類型【例4.10】自動變量與局部靜態(tài)變量的區(qū)別第38頁,課件共92頁,創(chuàng)作于2023年2月4.6.1存儲類型3外部存儲類型一個(gè)C++程序可以由多個(gè)源程序文件組成。多文件程序系統(tǒng)可以通過外部存儲類型的變量和函數(shù)來共享某些數(shù)據(jù)和操作。在一個(gè)程序文件中定義的全局變量和函數(shù)缺省為外部的,即其作用域可以延伸到程序的其他文件中。其他文件如果要使用這個(gè)文件中定義的全局變量和函數(shù),應(yīng)該在使用前用“extern”作外部聲明。外部聲明通常放在文件的開頭(函數(shù)總是省略extern)。外部變量聲明不同于全局變量定義,變量定義時(shí)編譯器為其分配存儲空間,而變量聲明則表示該全局變量已在其他地方定義過,編譯系統(tǒng)不再分配存儲空間。外部的全局變量或函數(shù)加上static修飾,就成為靜態(tài)全局變量或靜態(tài)函數(shù)。靜態(tài)的全局變量和函數(shù)作用域限制在本文件,其他文件即使使用外部聲明也無法使用該全局變量或函數(shù)?!纠?.11】外部存儲類型的例子第39頁,課件共92頁,創(chuàng)作于2023年2月4.6.2

生命期1.

靜態(tài)生命期靜態(tài)生命期(Staticextent或Staticstorageduration)指的是標(biāo)識符從程序開始運(yùn)行時(shí)就存在,具有存儲空間,到程序運(yùn)行結(jié)束時(shí)消亡,釋放存儲空間。具有靜態(tài)生命期的標(biāo)識符存放在全局?jǐn)?shù)據(jù)區(qū),如全局變量、靜態(tài)全局變量、靜態(tài)局部變量。具有靜態(tài)生命期的標(biāo)識符在未被用戶初始化的情況下,系統(tǒng)會自動將其初始化為0。函數(shù)駐留在代碼區(qū),也具有靜態(tài)生命期。所有具有文件作用域的標(biāo)識符都具有靜態(tài)生命期。第40頁,課件共92頁,創(chuàng)作于2023年2月

4.6.2

生命期2.局部生命期

在函數(shù)內(nèi)部或塊中定義的標(biāo)識符具有局部生命期(Automaticextent或Automaticstorageduration),其生命期開始于執(zhí)行到該函數(shù)或塊的標(biāo)識符定義處,結(jié)束于該函數(shù)或塊的結(jié)束處。具有局部生命期的標(biāo)識符存放在棧區(qū)。具有局部生命期的標(biāo)識符如果未被初始化,其內(nèi)容是隨機(jī)的,不可引用。具有局部生命期的標(biāo)識符必定具有局部作用域;但反之不然,靜態(tài)局部變量具有局部作用域,但卻具有靜態(tài)生命期。第41頁,課件共92頁,創(chuàng)作于2023年2月4.6.2

生命期具有動態(tài)生命期(dynamicextent或dynamicstorageduration)的標(biāo)識符存放在自由存儲區(qū),由特定的函數(shù)調(diào)用或運(yùn)算來創(chuàng)建和釋放,如用new運(yùn)算符(或調(diào)用malloc()函數(shù))為變量分配存儲空間時(shí),變量的生命期開始,而用delete運(yùn)算符(或調(diào)用free()函數(shù))釋放空間或程序結(jié)束時(shí),變量生命期結(jié)束。關(guān)于new運(yùn)算符和delete運(yùn)算符將在第七章中介紹。4.動態(tài)生命期第42頁,課件共92頁,創(chuàng)作于2023年2月4.7

函數(shù)的遞歸調(diào)用

遞歸是一種描述問題的方法,或稱算法。遞歸的思想可以簡單地描述為“自己調(diào)用自己”。例如用如下方法定義階乘:可以看出是用階乘定義階乘,這種自己定義自己的方法稱為遞歸定義。遞歸的引入:第43頁,課件共92頁,創(chuàng)作于2023年2月遞歸定義的階乘函數(shù):fac(intn){if(n==0||n==1)return1;elsereturnn*fac(n-1);}只要設(shè)計(jì)主函數(shù)調(diào)用階乘函數(shù),即可實(shí)現(xiàn)計(jì)算階乘。4.7

函數(shù)的遞歸調(diào)用【例4.12】求4!運(yùn)行結(jié)果:4 3 2 1 1 2 6 244!=24說明:cout<<”\n4!=”<<fac(4)<<endl;執(zhí)行時(shí)是先算函數(shù)值,然后再從左到右輸出各表達(dá)式的值。所以有兩行輸出,而不是第一行插在第二行賦值號與24之間。第44頁,課件共92頁,創(chuàng)作于2023年2月4.7

函數(shù)的遞歸調(diào)用探討:計(jì)算是先右后左。請看下一條輸出語句:cout<<”\n4!=”<<fac(4)<<”\n3!=”<<fac(3)<<endl;先算fac(3),后算fac(4),先右后左。但輸出還是從左到右:3 2 1 1 2 64 3 2 1 1 2 6 244!=243!=6遞歸的分類:

在函數(shù)調(diào)用中,有這樣兩種情況,一種是在函數(shù)A的定義中有調(diào)用函數(shù)A的語句,即自己調(diào)用自己;另一種是函數(shù)A的定義中出現(xiàn)調(diào)用函數(shù)B的語句,而函數(shù)B的定義中也出現(xiàn)調(diào)用函數(shù)A的語句,即相互調(diào)用。前者稱直接遞歸,后者稱間接遞歸。本節(jié)只介紹直接遞歸。遞歸函數(shù)必須定義遞歸終止條件(Stoppingcondition),避免無窮遞歸(InfiniteRecursion)。第45頁,課件共92頁,創(chuàng)作于2023年2月

遞歸函數(shù)的執(zhí)行分為“遞推”和“回歸”兩個(gè)過程,這兩個(gè)過程由遞歸終止條件控制,即逐層遞推,直至遞歸終止條件,然后逐層回歸。每次調(diào)用發(fā)生時(shí)都首先判斷遞歸終止條件。

遞歸調(diào)用同普通的函數(shù)調(diào)用一樣,每當(dāng)調(diào)用發(fā)生時(shí),在棧中分配單元保存返回地址以及參數(shù)和局部變量;而與普通的函數(shù)調(diào)用不同的是,由于遞推的過程是一個(gè)逐層調(diào)用的過程,因此存在一個(gè)逐層連續(xù)的參數(shù)入棧過程,直至遇到遞歸終止條件時(shí),才開始回歸,這時(shí)才逐層釋放??臻g,返回到上一層,直至最后返回到主調(diào)函數(shù)。

4.7函數(shù)的遞歸調(diào)用遞歸過程的分析:第46頁,課件共92頁,創(chuàng)作于2023年2月4.7

函數(shù)的遞歸調(diào)用從以上幾例可以看出,遞歸算法一般不需要借助循環(huán),但通過不斷遞推和回歸的過程實(shí)現(xiàn)了其他算法用循環(huán)完成的功能。因此,遞歸的終止條件非常重要,否則將會無休止地遞歸下去,陷入死循環(huán)狀態(tài)?!纠?.14】輸入一個(gè)整數(shù),用遞歸算法將整數(shù)倒序輸出【例4.13】漢諾塔問題第47頁,課件共92頁,創(chuàng)作于2023年2月圖4.10遞歸求解斐波那契數(shù)列調(diào)用樹同其他算法相比,用遞歸算法編制的程序非常簡潔易讀,但缺點(diǎn)是增加了內(nèi)存的開銷,在遞推的過程中會占用大量棧空間,且連續(xù)的調(diào)用返回操作占用較多CPU時(shí)間。因此是否選擇使用遞歸算法取決于所解決的問題及應(yīng)用的場合。4.7

函數(shù)的遞歸調(diào)用【例4.15】采用遞推法求解Fibonacii數(shù)列第48頁,課件共92頁,創(chuàng)作于2023年2月4.8函數(shù)的一些高級議題4.8.1函數(shù)重載

4.8.2缺省參數(shù)

4.8.3內(nèi)聯(lián)函數(shù)

第49頁,課件共92頁,創(chuàng)作于2023年2月4.8.1函數(shù)重載

重載的引入:在C++中,如果需要定義幾個(gè)功能相似,而參數(shù)類型不同的函數(shù),那么這樣的幾個(gè)函數(shù)可以使用相同的函數(shù)名,這就是函數(shù)重載。例:求和函數(shù)對應(yīng)不同的參數(shù)類型可以定義如下幾個(gè)重載函數(shù):intsum(inta,intb)doublesum(doublea,doubleb)float

sum(floata,floatb,floatc)第50頁,課件共92頁,創(chuàng)作于2023年2月4.8.1函數(shù)重載重載匹配:當(dāng)某個(gè)函數(shù)中調(diào)用到重載函數(shù)時(shí),編譯器會根據(jù)實(shí)參的類型去對應(yīng)地調(diào)用相應(yīng)的函數(shù)。匹配過程按如下步驟進(jìn)行:(1)如果有嚴(yán)格匹配的函數(shù),就調(diào)用該函數(shù);(2)參數(shù)內(nèi)部轉(zhuǎn)換后如果匹配,調(diào)用該函數(shù);(3)通過用戶定義的轉(zhuǎn)換尋求匹配。因此在定義重載函數(shù)時(shí)必須保證參數(shù)類型不同,僅僅返回值類型不同是不行的。函數(shù)重載的好處在于,可以用相同的函數(shù)名來定義一組功能相同或類似的函數(shù),程序的可讀性增強(qiáng)。【例4.16】重載函數(shù)的應(yīng)用第51頁,課件共92頁,創(chuàng)作于2023年2月4.8.2缺省參數(shù)缺省參數(shù)的引入:缺省參數(shù)指在定義函數(shù)時(shí)為形參指定缺省值(默認(rèn)值)。這樣的函數(shù)在調(diào)用時(shí),對于缺省參數(shù),可以給出實(shí)參值,也可以不給出參數(shù)值。如果給出實(shí)參,將實(shí)參傳遞給形參進(jìn)行調(diào)用,如果不給出實(shí)參,則按缺省值進(jìn)行調(diào)用。缺省參數(shù)的函數(shù)調(diào)用:缺省實(shí)參并不一定是常量表達(dá)式,可以是任意表達(dá)式,甚至可以通過函數(shù)調(diào)用給出。如果缺省實(shí)參是任意表達(dá)式,則函數(shù)每次被調(diào)用時(shí)該表達(dá)式被重新求值。但表達(dá)式必須有意義;

【例4.16】缺省參數(shù)第52頁,課件共92頁,創(chuàng)作于2023年2月4.8.2缺省參數(shù)使用要點(diǎn):

缺省參數(shù)可以有多個(gè),但所有缺省參數(shù)必須放在參數(shù)表的右側(cè),即先定義所有的非缺省參數(shù),再定義缺省參數(shù)。這是因?yàn)樵诤瘮?shù)調(diào)用時(shí),參數(shù)自左向右逐個(gè)匹配,當(dāng)實(shí)參和形參個(gè)數(shù)不一致時(shí)只有這樣才不會產(chǎn)生二義性。在同一個(gè)作用域中一個(gè)參數(shù)只能被指定一次缺省值,不可以在聲明和定義中同時(shí)指定缺省值,即使缺省值一樣也不行。intfun2(int,int=10,int=20); //函數(shù)聲明中給出缺省值。參數(shù)名也可省略voidfun1(){…}intfun2(inta,intb,intc){…}//定義中不再給出缺省值習(xí)慣上,缺省參數(shù)在公共頭文件包含的函數(shù)聲明中指定,否則缺省實(shí)參只能用于包含該函數(shù)定義的文件中的函數(shù)調(diào)用。第53頁,課件共92頁,創(chuàng)作于2023年2月4.8.3內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)的引入:當(dāng)程序執(zhí)行函數(shù)調(diào)用時(shí),系統(tǒng)要建立??臻g,保護(hù)現(xiàn)場,傳遞參數(shù)以及控制程序執(zhí)行的轉(zhuǎn)移等等,這些工作需要系統(tǒng)時(shí)間和空間的開銷。當(dāng)函數(shù)功能簡單,使用頻率很高,為了提高效率,直接將函數(shù)的代碼嵌入到程序中。但這個(gè)辦法有缺點(diǎn),一是相同代碼重復(fù)書寫,二是程序可讀性往往沒有使用函數(shù)的好。為了協(xié)調(diào)好效率和可讀性之間的矛盾,C++提供了另一種方法,即定義內(nèi)聯(lián)函數(shù),方法是在定義函數(shù)時(shí)用修飾詞inline。第54頁,課件共92頁,創(chuàng)作于2023年2月4.8.3內(nèi)聯(lián)函數(shù)請看如下程序段,讀入一行字符串,逐個(gè)判斷是否為數(shù)字字符:inlineIsNumber(charch){

returnch>=′0′&&ch<=′9′?1:0;}intmain(){

charch;

while(cin.get(ch),ch!=′\n′){

if(IsNumber(ch))cout<<″是數(shù)字字符″<<endl;

elsecout<<″不是數(shù)字字符″<<endl;}

return0;}因使用頻度很高,說明為內(nèi)聯(lián)函數(shù)。第55頁,課件共92頁,創(chuàng)作于2023年2月4.9頭文件與多文件結(jié)構(gòu)(選讀)4.9.1頭文件標(biāo)準(zhǔn)庫頭文件:考慮標(biāo)識符在其他文件中的可見性。使用頭文件是很有效的方法。如:#include<iostream>usingnamespacestd;其中的iostream是在標(biāo)準(zhǔn)名字空間域std中定義的頭文件。對應(yīng)的傳統(tǒng)方式的文件名為<iostream.h>,頭文件以“.h”為后綴。

系統(tǒng)定義的頭文件中定義了一些常用的公用標(biāo)識符和函數(shù),用戶只要將頭文件包含進(jìn)自己的文件,就可使頭文件中定義的標(biāo)識符在用戶文件中變得可見,也就可以直接使用頭文件中定義的標(biāo)識符和函數(shù)。

第56頁,課件共92頁,創(chuàng)作于2023年2月4.9.1頭文件自定義頭文件:除了系統(tǒng)定義的頭文件外,用戶還可以自定義頭文件。對于具有外部存儲類型的標(biāo)識符,可以在其他任何一個(gè)源程序文件中經(jīng)聲明后引用,因此用戶完全可以將一些具有外部存儲類型的標(biāo)識符的聲明放在一個(gè)頭文件中。具體地說,頭文件中可以包括:用戶構(gòu)造的數(shù)據(jù)類型(如枚舉類型),外部變量,外部函數(shù)、常量和內(nèi)聯(lián)函數(shù)等具有一定通用性或常用的量,而一般性的變量和函數(shù)定義不宜放在頭文件中。第57頁,課件共92頁,創(chuàng)作于2023年2月4.9.2多文件結(jié)構(gòu)

在開發(fā)較大程序時(shí),通常將其分解為多個(gè)源程序文件,每個(gè)較小的程序用一個(gè)源程序文件建立。程序經(jīng)過建立、編譯、連接,成為一個(gè)完整的可執(zhí)行程序。多文件結(jié)構(gòu)通過工程進(jìn)行管理,在工程中建立若干用戶定義的頭文件.h和源程序文件.cpp。頭文件中定義用戶自定義的數(shù)據(jù)類型,所有的程序?qū)崿F(xiàn)則放在不同的源程序文件中。編譯時(shí)每個(gè)源程序文件單獨(dú)編譯,如果源程序文件中有編譯預(yù)處理指令,則首先經(jīng)過編譯預(yù)處理生成臨時(shí)文件存放在內(nèi)存,之后對臨時(shí)文件進(jìn)行編譯生成目標(biāo)文件.obj,編譯后臨時(shí)文件撤銷。所有的目標(biāo)文件經(jīng)連接器連接最終生成一個(gè)完整的可執(zhí)行文件.exe。圖4.11是一個(gè)多文件系統(tǒng)的開發(fā)過程。第58頁,課件共92頁,創(chuàng)作于2023年2月4.9.2多文件結(jié)構(gòu)

編譯

預(yù)編譯編譯

預(yù)編譯

預(yù)編譯編譯圖4.11C++程序開發(fā)過程file1.hfile1.cppfile2.hfile2.cppfilen.hfilen.cpp臨時(shí)文件1臨時(shí)文件2臨時(shí)文件nfile1.objfile2.objfilen.objFilename.exe.libC++標(biāo)準(zhǔn)類庫連接運(yùn)行第59頁,課件共92頁,創(chuàng)作于2023年2月4.10編譯預(yù)處理(選讀)4.10.1宏定義指令

4.10.2文件包含指令

4.10.3條件編譯指令

第60頁,課件共92頁,創(chuàng)作于2023年2月4.10.1宏定義指令1不帶參宏定義用來產(chǎn)生與一個(gè)字符串對應(yīng)的常量字符串,格式為:#define宏名常量串預(yù)處理后文件中凡出現(xiàn)該字符串處均用其對應(yīng)的常量串代替。替換過程稱為宏替換或宏展開。例如,如果使用指令#definePI4.1415926則程序中可以使用標(biāo)識符PI,編譯預(yù)處理后產(chǎn)生一個(gè)中間文件,文件中所有PI被替換為4.1415926。宏替換只是字符串和標(biāo)識符之間的簡單替換,預(yù)處理本身不做任何數(shù)據(jù)類型和合法性檢查,也不分配內(nèi)存單元。第61頁,課件共92頁,創(chuàng)作于2023年2月4.10.1宏定義指令2帶參數(shù)的宏定義帶參宏定義的形式很象定義一個(gè)函數(shù),格式為:#define宏名(形參表)表達(dá)式串

例如作如下宏定義:#defineS(a,b)(a)*(b)/2程序中可使用S(a,b),預(yù)處理后產(chǎn)生中間文件,其中S(a,b)被替換成(a)*(b)/2。注意,宏定義時(shí)形參通常要用括號括起來,否則容易導(dǎo)致邏輯錯誤。例如,如果定義:#defineS(a,b)a*b/2那么程序中的S(3+5,4+2)就會被宏展開為3+5*4+2/2,不符合定義的真正的意圖。帶參宏定義形式上象定義函數(shù),但它與函數(shù)的本質(zhì)不同,宏定義仍然只是產(chǎn)生字符串替代,不存在分配內(nèi)存和參數(shù)傳遞。第62頁,課件共92頁,創(chuàng)作于2023年2月4.10.2文件包含指令文件包含用#include指令,預(yù)處理后將指令中指明的源程序文件嵌入到當(dāng)前源程序文件的指令位置處。格式為:#include<文件名>或#include″文件名″第一種方式稱為標(biāo)準(zhǔn)方式,預(yù)處理器將在include子目錄下搜索由文件名所指明的文件。這種方式適用于嵌入C++提供的頭文件,因?yàn)檫@些頭文件一般都存在C++系統(tǒng)目錄的include子目錄下。而第二種方式編譯器將首先在當(dāng)前文件所在目錄下搜索,如果找不到再按標(biāo)準(zhǔn)方式搜索。這種方式適用于嵌入用戶自己建立的頭文件。第63頁,課件共92頁,創(chuàng)作于2023年2月一個(gè)被包含的頭文件中還可以有#include指令,即include指令可以嵌套,但是,如果同一個(gè)頭文件在同一個(gè)源程序文件中被重復(fù)包含,就會出現(xiàn)標(biāo)識符重復(fù)定義的錯誤。例如:頭文件f2.h中包含了f1.h,如果文件f4.cpp中既包含f1.h,又包含f2.h,那么編譯將提示錯誤,原因是f1.h被包含了兩次,那么其中定義的標(biāo)識符在f4.cpp中就被重復(fù)定義。避免重復(fù)包含可以用條件編譯指令。4.10.2文件包含指令第64頁,課件共92頁,創(chuàng)作于2023年2月4.10.3條件編譯指令1用宏名作為編譯的條件格式為:#ifdef<宏名><程序段1>[#else<程序段2>]#endif2表達(dá)式的值作為編譯條件格式為:#if<表達(dá)式><程序段1>[#else<程序段2>]#endif當(dāng)希望在不同條件下編譯程序的不同部分。這種情況就要使用條件編譯指令。其中程序段可以是程序也可以是編譯預(yù)處理指令??梢酝ㄟ^在該指令前面安排宏定義來控制編譯不同的程序段。第65頁,課件共92頁,創(chuàng)作于2023年2月例:在調(diào)試程序時(shí)常常要輸出調(diào)試信息,而調(diào)試完后不需要輸出這些信息,則可以把輸出調(diào)試信息的語句用條件編譯指令括起來。形式如下:#ifdefDEBUGcout<<″a=″<<a<<′\t′<<″x=″<<x<<endl;#endif在程序調(diào)試期間,在該條件編譯指令前增加宏定義:#defineDEBUG調(diào)試好后,刪除DEBUG宏定義,將源程序重新編譯一次。條件編譯指令包括:#if、#else、#ifdef、#ifndef、#endif、#undef等。#ifndef與#ifdef作用一樣,只是選擇的條件相反。#undef指令用來取消#define指令所定義的符號,這樣可以根據(jù)需要打開和關(guān)閉符號。第66頁,課件共92頁,創(chuàng)作于2023年2月第四章函數(shù)再見謝謝!第67頁,課件共92頁,創(chuàng)作于2023年2月4.1.3

函數(shù)的調(diào)用【例4.1】

main()函數(shù)調(diào)用max(2.5,4.7)函數(shù)max(2.5,4.7)return4.7

主程序后續(xù)語句【例4.1】輸入兩個(gè)實(shí)數(shù),輸出其中較大的數(shù)。其中求兩個(gè)實(shí)數(shù)中的較大數(shù)用函數(shù)完成。程序如下:#include<iostream>usingnamespacestd;floatmax(floata,floatb){

return(a>=b?a:b);}intmain(){

floatx,y; cout<<"輸入兩個(gè)實(shí)數(shù):"<<endl; cin>>x>>y; cout<<x<<"和"<<y<<"中較大數(shù)為"<<max(x,y)<<endl;

return0;}第68頁,課件共92頁,創(chuàng)作于2023年2月

4.2.1函數(shù)的參數(shù)傳遞及傳值調(diào)用【例4.2】

調(diào)用power(4.6,3)函數(shù)power(4.6,3)return97.336

主程序后續(xù)語句n=3x=4.6c=‘a(chǎn)’【例4.2】實(shí)參和形參對應(yīng)關(guān)系的示例。floatpower(floatx,intn){//求x的n次冪floatp=1;while(n--)p*=x;returnp;}intmain(){intn=3;floatx=4.6;charc='a';cout<<"power("<<x<<','<<n<<")="<<power(x,n)<<endl;cout<<"power("<<c<<','<<n<<")="<<power(c,n)<<endl;cout<<"power("<<n<<','<<x<<")="<<power(n,x)<<endl;return0;}第69頁,課件共92頁,創(chuàng)作于2023年2月

4.2.1函數(shù)的參數(shù)傳遞及傳值調(diào)用【例4.2】調(diào)用power('a',3)函數(shù)power(97,3)return912673

主程序后續(xù)語句n=3x=4.6c=‘a(chǎn)’【例4.2】實(shí)參和形參對應(yīng)關(guān)系。floatpower(floatx,intn){//求x的n次冪floatp=1;while(n--)p*=x;returnp;}intmain(){intn=3;floatx=4.6;charc='a';cout<<"power("<<x<<','<<n<<")="<<power(x,n)<<endl;cout<<"power("<<c<<','<<n<<")="<<power(c,n)<<endl;cout<<"power("<<n<<','<<x<<")="<<power(n,x)<<endl;return0;}第70頁,課件共92頁,創(chuàng)作于2023年2月

4.2.1函數(shù)的參數(shù)傳遞及傳值調(diào)用【例4.2】調(diào)用power(3,4.6)函數(shù)power(3,4)return81主程序后續(xù)語句n=3x=4.6c=‘a(chǎn)’【例4.2】實(shí)參和形參對應(yīng)關(guān)系。floatpower(floatx,intn){//求x的n次冪floatp=1;while(n--)p*=x;returnp;}intmain(){intn=3;floatx=4.6;charc='a';cout<<"power("<<x<<','<<n<<")="<<power(x,n)<<endl;cout<<"power("<<c<<','<<n<<")="<<power(c,n)<<endl;cout<<"power("<<n<<','<<x<<")="<<power(n,x)<<endl;return0;}第71頁,課件共92頁,創(chuàng)作于2023年2月【例4.3】程序:float

TriangleArea(floata,floatb,floatc){

if((a+b<=c)||(a+c<=b)||(b+c<=a))return-1;

floats;s=(a+b+c)/2;

returnsqrt(s*(s-a)*(s-b)*(s-c))

;}intmain(){

floata,b,c,area;cout<<"輸入三角形三邊a,b,c:"<<endl;cin>>a>>b>>c;

area=TriangleArea(a,b,c);

if(area==-1)cout<<'('<<a<<','<<b<<','<<c<<')'<<"不能構(gòu)成三角形!"<<endl;

else cout<<"三角形("<<a<<','<<b<<','<<c<<")面積為:"<<area<<endl;

return0;}第72頁,課件共92頁,創(chuàng)作于2023年2月boolpalindrome(int);

//函數(shù)聲明intmain(){

intm; cout<<setw(10)<<'m'<<setw(20)<<"m*m“ <<setw(20)<<"m*m*m"<<endl;

for(m=11;m<1000;m++)

if(palindrome(m)&&palindrome(m*m) &&palindrome(m*m*m))

cout<<setw(10)<<m<<setw(20)<<m*m <<setw(20)<<m*m*<<endl;return0;}【例4.4】輸出回文數(shù)第73頁,課件共92頁,創(chuàng)作于2023年2月boolpalindrome(intn){

//判斷回文數(shù)

intdigit[10];

intm=n,i=0;

do{ digit[i]=n%10;n/=10;i++; }while(n>0);

for(intj=0;j<i;j++)n=n*10+digit[j];

return(n==m);}【例4.4】輸出回文數(shù)第74頁,課件共92頁,創(chuàng)作于2023年2月4.4.2全局變量【例4.5】

打印200調(diào)用func()函數(shù)func()200*2=400打印400n=100n=100*2=200【例4.5】多個(gè)函數(shù)使用全局變量的例子。intn=100;voidfunc(){ n*=2;}intmain(){ n*=2; cout<<n<<endl; func(); cout<<n<<endl;

return0;}第75頁,課件共92頁,創(chuàng)作于2023年2月4.4.3局部變量打印main()中的t=4.5調(diào)用fun()函數(shù)fun()打印fun()中的t=5

打印main()中的t=4.5t=4.5t=5【例4.6】使用局部變量的例子。voidfun(){autointt=5;//fun()中的局部變量,auto可省略cout<<"fun()中的t="<<t<<endl;}intmain(){floatt=4.5;//main()函數(shù)中的局部變量cout<<"main()中的t="<<t<<endl;fun();cout<<"main()中的t="<<t<<endl;return0;}第76頁,課件共92頁,創(chuàng)作于2023年2月塊域【例4.7】

a=3b=535a=3b=5a=5b=3【例4.7】輸入兩數(shù),按從大到小的順序保存,并輸出結(jié)果。結(jié)果棧t=3intmain(){

inta,b; //具有函數(shù)域

cout<<"輸入兩整數(shù):"<<endl;

cin>>a>>b;

cout<<“a="<<a<<'\t'<<"b="<<b<<endl;

if(b>=a){

intt;

//具有塊域

t=a;

a=b;b=t;//交換a,b的值

}cout<<"a="<<a<<'\t'<<"b="<<b<<endl;

return0;}上述程序若在最后一個(gè)cout語句處增加:cout<<t<<endl;則編譯時(shí)會提示錯誤,因?yàn)樽兞縯的作用域只在if語句中,其它地方不可見。第77頁,課件共92頁,創(chuàng)作于2023年2月【例4.8】設(shè)計(jì)函數(shù)完成兩數(shù)交換,用主函數(shù)進(jìn)行測試。voidswap(int,int);intmain(){

inta,b;//a,b作用域?yàn)閙ain()cout<<"輸入兩整數(shù):"<<endl;cin>>a>>b;cout<<"調(diào)用前:實(shí)參a="<<a<<','<<"b="<<b<<endl;swap(a,b);//傳值cout<<"調(diào)用后:實(shí)參a="<<a<<','<<"b="<<b<<endl;

return0;}voidswap(inta,intb){//a,b作用域?yàn)閟wap()cout<<"調(diào)用中…"<<endl;cout<<"交換前:形參a=“<<a<<','<<"b="<<b<<endl;

intt;t=a;a=b;b=t; //交換swap()中的a,b的值cout<<"交換后:形參a="<<a<<','<<"b="<<b<<endl;}第78頁,課件共92頁,創(chuàng)作于2023年2月全局n=100200300內(nèi)i=500內(nèi)j=600內(nèi)n=500+600=11001100500600100200+300=500500

500200300外部i=200外部j=300【例4.9】

顯示同名變量可見性。intn=100;#include<iostream.h>intmain(){inti=200,j=300;cout<<n<<'\t'<<i<<'\t'<<j<<endl;{ //內(nèi)部塊

inti=500,j=600,n;n=i+j;cout<<n<<'\t'<<i<<'\t'<<j<<endl;

//輸出局部變量ncout<<::n<<endl;//輸出全局變量n}n=i+j; //修改全局變量cout<<n<<'\t'<<i<<'\t'<<j<<endl;return0;}第79頁,課件共92頁,創(chuàng)作于2023年2月【例4.10】自動變量與局部靜態(tài)變量的區(qū)別intst(){

staticintt=100;//局部靜態(tài)變量t++;returnt;}intat(){

intt=100;//自動變量t++;returnt;}intmain(){

inti;

for(i=0;i<5;i++)cout<<at()<<'\t';cout<<endl;

for(i=0;i<5;i++)cout<<st()<<'\t';cout<<endl;

return0;}4.6.1存儲類型i=0t=10012345101101101101101第80頁,課件共92頁,創(chuàng)作于2023年2月4.6.1存儲類型i=0t=10012101345102103104105【例4.10】自動變量與局部靜態(tài)變量的區(qū)別intst(){

staticintt=100;//局部靜態(tài)變量t++;returnt;}intat(){

intt=100;//自動變量t++;returnt;}intmain(){

inti;

for(i=0;i<5;i++)cout<<at()<<‘=\t';cout<<endl;

for(i=0;i<5;i++)cout<<st()<<'\t';cout<<endl;

return0;}第81頁,課件共92頁,創(chuàng)作于2023年2月【例4.11】外部存儲類型的例子。假定程序包含兩個(gè)源程序文件Ex4_11_1.cpp和Ex4_11_2.cpp,程序結(jié)構(gòu)如下:/*Ex4_11_1.cpp,由main()組成*/voidfun2();//外部函數(shù)聲明,等價(jià)于externvoidfun2();intn; //全局變量定義intmain(){n=1;fun2(); //fun2()定義在文件Ex4_11_2.cpp中cout<<″n=″<<n<<endl;

return0;}/*Ex4_11_2.cpp,由fun2()組成*/externintn;

//外部變量聲明,n定義在文件Ex4_11_1.cpp中voidfun2(){

//fun2()被文件Ex4_11_1.cpp中的函數(shù)調(diào)用n=3;}

運(yùn)行結(jié)果:n=3第82頁,課件共92頁,創(chuàng)作于2023年2月【例4.12】求4!#include<iostream.h>intfac(intn){

inty;cout<<n<<'\t';

if(n==0||n==1)y=1;elsey=n*fac(n-1); cout<<y<<'\t';

returny;}intmain(){ cout<<"\n4!="<<fac(4)<<endl;

returno;}n=4cout<<4;y=4*fac(3);fac(4)=cout<<2;y=2*fac(1);

n=2cout<<1;y=1;cout<<1;return1;

n=1n=3cout<<3;y=3*fac(2);cout<<24;return24;cout<<6;return6;cout<<2;return2;24第83頁,課件共92頁,創(chuàng)作于2023年2月4.7

函數(shù)的遞歸調(diào)用【例4.13】

【例4.13】

漢諾塔問題。有A、B、C三根柱子,A柱上有n個(gè)大小不等的盤子,大盤在下,小盤在上。要求將所有盤子由A柱搬動到C柱上,每次只能搬動一個(gè)盤子,搬動過程中可以借助任何一根柱子,但必須滿足大盤在下,小盤在上。打印出搬動的步驟。

A柱B柱C柱第84頁,課件共92頁,創(chuàng)作于2023年2月分析:1A柱只有一個(gè)盤子的情況:A柱C柱;2A柱有兩個(gè)盤子的情況:小盤A柱B柱,大盤A柱C柱,小盤B柱C柱。3A柱有n個(gè)盤子的情況:將此問題看成上面n-1個(gè)盤子和最下面第n個(gè)盤子的情況。n-1個(gè)盤子A柱B柱,第n個(gè)盤子A柱C柱,n-1個(gè)盤子B柱C柱。問題轉(zhuǎn)化成搬動n-1個(gè)盤子的問題,同樣,將n-1個(gè)盤子看成上面n-2個(gè)盤子和下面第n-1個(gè)盤子的情況,進(jìn)一步轉(zhuǎn)化為搬動n-2個(gè)盤子的問題,……,類推下去,一直到最后成為搬動一個(gè)盤子的問題。這是一個(gè)典型的遞歸問題,遞歸結(jié)束于只搬動一個(gè)盤子。4.7

函數(shù)的遞歸調(diào)用【例4.13】第85頁,課件共92頁,創(chuàng)作于2023年2月4.7

函數(shù)的遞歸調(diào)用【例4.13】

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論