C++程序設(shè)計(jì)-過(guò)程抽象-函數(shù)省公開(kāi)課一等獎(jiǎng)全國(guó)示范課微課金獎(jiǎng)?wù)n件_第1頁(yè)
C++程序設(shè)計(jì)-過(guò)程抽象-函數(shù)省公開(kāi)課一等獎(jiǎng)全國(guó)示范課微課金獎(jiǎng)?wù)n件_第2頁(yè)
C++程序設(shè)計(jì)-過(guò)程抽象-函數(shù)省公開(kāi)課一等獎(jiǎng)全國(guó)示范課微課金獎(jiǎng)?wù)n件_第3頁(yè)
C++程序設(shè)計(jì)-過(guò)程抽象-函數(shù)省公開(kāi)課一等獎(jiǎng)全國(guó)示范課微課金獎(jiǎng)?wù)n件_第4頁(yè)
C++程序設(shè)計(jì)-過(guò)程抽象-函數(shù)省公開(kāi)課一等獎(jiǎng)全國(guó)示范課微課金獎(jiǎng)?wù)n件_第5頁(yè)
已閱讀5頁(yè),還剩78頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第四章功效(過(guò)程)抽象--函數(shù)第1頁(yè)本章內(nèi)容基于過(guò)程抽象程序設(shè)計(jì)子程序概念C++函數(shù)變量局部性和變量生存期標(biāo)識(shí)符作用域遞歸函數(shù)內(nèi)聯(lián)函數(shù)函數(shù)名重載條件編譯--程序調(diào)試與多環(huán)境程序編制標(biāo)準(zhǔn)庫(kù)函數(shù)第2頁(yè)基于過(guò)程抽象程序設(shè)計(jì)人們?cè)谠O(shè)計(jì)一個(gè)復(fù)雜程序時(shí),經(jīng)常會(huì)用到功效分解和復(fù)合兩種伎倆:功效分解:在進(jìn)行程序設(shè)計(jì)時(shí),首先把程序功效分解成若干子功效,每個(gè)子功效又能夠分解成若干子功效,等等,從而形成了一個(gè)自頂向下(top-down)、逐步精化(step-wise)設(shè)計(jì)過(guò)程。功效復(fù)合:把已經(jīng)有(子)功效逐步組合成更大(子)功效,從而形成一個(gè)自底向上(bottom-up)設(shè)計(jì)過(guò)程。過(guò)程抽象:一個(gè)功效使用者只需要知道對(duì)應(yīng)功效是什么(whattodo),而無(wú)須知道它是怎樣做(howtodo)。第3頁(yè)子程序子程序是取了名一段程序代碼,在程序中經(jīng)過(guò)名字來(lái)使用(調(diào)用)它們。子程序作用:降低重復(fù)代碼,節(jié)約勞動(dòng)力實(shí)現(xiàn)過(guò)程抽象(功效抽象)封裝和信息隱藏作用語(yǔ)言功效擴(kuò)充第4頁(yè)子程序之間數(shù)據(jù)傳遞一個(gè)子程序所需要數(shù)據(jù)往往要從調(diào)用者(也是一個(gè)子程序)那里取得,計(jì)算結(jié)果也需要返回給調(diào)用者。子程序之間數(shù)據(jù)傳遞方式能夠經(jīng)過(guò):全局變量:全部子程序都能訪問(wèn)到變量。(不好)參數(shù):形式參數(shù)(形參)和實(shí)在參數(shù)(實(shí)參)。值傳遞:把實(shí)參值復(fù)制一份給形參。地址或引用傳遞:把實(shí)參地址傳給形參。返回值機(jī)制:返回計(jì)算結(jié)果。第5頁(yè)C++函數(shù)函數(shù)是C++提供用于實(shí)現(xiàn)子程序語(yǔ)言成份。函數(shù)定義:

<返回值類(lèi)型><函數(shù)名>(<形式參數(shù)表>)<函數(shù)體><返回值類(lèi)型>描述了函數(shù)返回值類(lèi)型,能夠?yàn)槿我釩++數(shù)據(jù)類(lèi)型。當(dāng)返回值類(lèi)型為void時(shí),它表示函數(shù)沒(méi)有返回值。<函數(shù)名>用于標(biāo)識(shí)函數(shù)名字,用標(biāo)識(shí)符表示。<形式參數(shù)表>描述函數(shù)形式參數(shù),由零個(gè)、一個(gè)或多個(gè)形參說(shuō)明(用逗號(hào)隔開(kāi))組成,形參說(shuō)明格式為:

<類(lèi)型><形參名>第6頁(yè)<函數(shù)體>

為一個(gè)<復(fù)合語(yǔ)句>,用于實(shí)現(xiàn)對(duì)應(yīng)函數(shù)功效。函數(shù)體內(nèi)能夠包含return語(yǔ)句,格式為:return<表示式>;return;當(dāng)函數(shù)體執(zhí)行到return語(yǔ)句時(shí),函數(shù)馬上返回到調(diào)用者。假如有返回值,則把返回值帶回給調(diào)用者。假如return中<表示式>類(lèi)型與函數(shù)<返回值類(lèi)型>不一致,則進(jìn)行隱式類(lèi)型轉(zhuǎn)換,基本標(biāo)準(zhǔn)為:把<表示式>轉(zhuǎn)成<返回值類(lèi)型>。注意:在函數(shù)體中不能用goto語(yǔ)句轉(zhuǎn)出函數(shù)體。第7頁(yè)函數(shù)例子intfactorial(intn)//求n階乘{(lán) inti,f=1; for(i=2;i<=n;i++)f*=i; returnf;}第8頁(yè)doublepower(doublex,intn)//求xn次冪{ if(x==0)return0; doubleproduct=1.0; if(n>=0) while(n>0) { product*=x; n--; } else while(n<0) { product/=x; n++; } returnproduct;}第9頁(yè)函數(shù)main每個(gè)C++程序都要定義一個(gè)名字為main函數(shù),C++程序執(zhí)行是從main開(kāi)始。對(duì)于函數(shù)main,其返回值類(lèi)型為int,比如:intmain(){ ...... ...return-1; ...... return0;}普通情況下,返回0表示程序正常結(jié)束;返回負(fù)數(shù)(如-1)表示程序非正常結(jié)束。第10頁(yè)函數(shù)調(diào)用

對(duì)于定義一個(gè)函數(shù),必須要調(diào)用它,它函數(shù)體才會(huì)執(zhí)行。除了函數(shù)main外,程序中對(duì)其它函數(shù)調(diào)用都是從main開(kāi)始。main普通是由操作系統(tǒng)來(lái)調(diào)用。函數(shù)調(diào)用格式以下:<函數(shù)名>(<實(shí)在參數(shù)表>)<實(shí)在參數(shù)表>由零個(gè)、一個(gè)或多個(gè)表示式組成(逗號(hào)分割)實(shí)參個(gè)數(shù)和類(lèi)型應(yīng)與對(duì)應(yīng)函數(shù)形參相同。類(lèi)型假如不一樣,編譯器會(huì)試圖進(jìn)行隱式轉(zhuǎn)換,轉(zhuǎn)換規(guī)則是把實(shí)參類(lèi)型轉(zhuǎn)換成形參類(lèi)型。注意:不能用goto語(yǔ)句從函數(shù)外轉(zhuǎn)入函數(shù)體第11頁(yè)函數(shù)調(diào)用例子......intmain(){ intx; cout<<"請(qǐng)輸入一個(gè)正整數(shù):"; cin>>x; cout<<"Factorialof"<<x<<"is" <<factorial(x)//調(diào)用階乘函數(shù)

<<endl; return0;}第12頁(yè)......intmain(){ doublea; intb; cout<<"請(qǐng)輸入a和b:"; cin>>a>>b; cout<<a<<""<<b<<"次方是:" <<power(a,b)<<endl; return0;}第13頁(yè)函數(shù)調(diào)用執(zhí)行過(guò)程計(jì)算實(shí)參值(對(duì)于多個(gè)實(shí)參,C++沒(méi)有要求計(jì)算次序);把實(shí)參分別傳遞給被調(diào)用函數(shù)形參;執(zhí)行函數(shù)體;函數(shù)體中執(zhí)行return語(yǔ)句返回函數(shù)調(diào)用點(diǎn),調(diào)用點(diǎn)取得返回值(假如有返回值)并執(zhí)行調(diào)用之后操作。能夠把有返回值函數(shù)調(diào)用作為操作數(shù)放在表示式中參加運(yùn)算:x+power(x,y)*z

第14頁(yè)函數(shù)申明程序中調(diào)用全部函數(shù)都要有定義。假如函數(shù)定義在其它文件(如:C++標(biāo)準(zhǔn)庫(kù))中或定義在根源文件中使用點(diǎn)之后,則在調(diào)用前需要對(duì)被調(diào)用函數(shù)進(jìn)行申明。函數(shù)申明格式以下:<返回值類(lèi)型><函數(shù)名>(<形式參數(shù)表>);//函數(shù)原型或extern<返回值類(lèi)型><函數(shù)名>(<形式參數(shù)表>);在函數(shù)申明中,<形式參數(shù)表>中能夠只列出形參類(lèi)型而不寫(xiě)形參名

第15頁(yè)//file2.cppintg(inti)//定義{externintx,y;//申明

intz;//定義

z=x+y;returnz+i;}//file1.cppintx=0;//定義intmain()//定義{externvoidf();//申明

externintg(int);//申明

externinty;//申明

y=x+2;f();//調(diào)用

y=g(x);//調(diào)用

return0;}inty=0;//定義voidf()//定義{x=y+1;}函數(shù)申明作用是什么?第16頁(yè)例:用函數(shù)實(shí)現(xiàn)求小于n全部素?cái)?shù)。#include<iostream>#include<cmath>usingnamespacestd;boolis_prime(intn);//函數(shù)申明voidprint_prime(intn,intcount);//函數(shù)申明intmain(){ inti,n,count=1; cout<<"請(qǐng)輸入一個(gè)正整數(shù):" cin>>n;//從鍵盤(pán)輸入一個(gè)正整數(shù)

if(n<2)return-1; cout<<2<<",";//輸出第一個(gè)素?cái)?shù)

for(i=3;i<n;i+=2) { if(is_prime(i)) { count++;

print_prime(i,count); } } cout<<endl; return0;}第17頁(yè)boolis_prime(intn){ inti,j,k=sqrt(n); for(i=2,j=k;i<=j;i++) if(n%i==0)returnfalse; returntrue;}voidprint_prime(intn,intcount){ cout<<n<<','; if(count%6==0)cout<<endl;}第18頁(yè)函數(shù)參數(shù)傳遞C++提供了兩種參數(shù)傳遞機(jī)制:值傳遞把實(shí)參值賦值給形參。地址或引用傳遞把實(shí)參地址賦值給形參。C++默認(rèn)參數(shù)傳遞方式是值傳遞。第19頁(yè)值傳遞在函數(shù)調(diào)用時(shí),采取類(lèi)似變量初始化形式把實(shí)參值傳給形參。函數(shù)執(zhí)行過(guò)程中,經(jīng)過(guò)形參取得實(shí)參值,函數(shù)體中對(duì)形參值改變不會(huì)影響對(duì)應(yīng)實(shí)參值。第20頁(yè)值參數(shù)傳遞例子//函數(shù)main調(diào)用函數(shù)power計(jì)算ab#include<iostream>usingnamespacestd;doublepower(doublex,intn);intmain(){ doublea=3.0,c; intb=4; c=power(a,b); cout<<a<<","<<b<<","<<c<<endl; return0;}第21頁(yè)doublepower(doublex,intn){ if(x==0)return0; doubleproduct=1.0; if(n>=0) while(n>0) { product*=x; n--; } else while(n<0) { product/=x; n++; } returnproduct;}第22頁(yè)執(zhí)行main時(shí),產(chǎn)生三個(gè)變量(分配內(nèi)存空間)a、b和c:

a:3.0b:4c:?調(diào)用power函數(shù)時(shí),又產(chǎn)生三個(gè)個(gè)變量x、n和product,然后分別用a、b以及1.0對(duì)它們初始化:

a:3.0b:4c:? x:3.0n:4product:1.0函數(shù)power中循環(huán)結(jié)束后(函數(shù)返回前):

a:3.0b:4c:? x:3.0n:0product:81.0函數(shù)power返回后:

a:3.0b:4c:81.0第23頁(yè)變量局部性在C++中,依據(jù)變量定義位置,把變量分成:局部變量和全局變量。

局部變量是指在復(fù)合語(yǔ)句中定義變量,它們只能在定義它們復(fù)合語(yǔ)句(包含內(nèi)層復(fù)合語(yǔ)句)中使用。全局變量是指在函數(shù)外部定義變量,它們普通能被程序中全部函數(shù)使用(靜態(tài)全局變量除外)。第24頁(yè)局部變量和全局變量例子intx=0;//全局變量voidf(){ inty=0;//局部變量

x++;//OK y++;//OK a++;//Error}intmain(){ inta=0;//局部變量

f(); a++;//OK x++;//OK y++;//Error

while(x<10) {intb=0;//局部變量

a++;//OK b++;//OK x++;//OK } b++;//Error return0;}第25頁(yè)變量生存期(存放分配)把程序運(yùn)行時(shí)一個(gè)變量占有內(nèi)存空間時(shí)間段稱(chēng)為該變量生存期。靜態(tài):從程序開(kāi)始執(zhí)行時(shí)就進(jìn)行內(nèi)存空間分配,直到程序結(jié)束才收回它們空間。全局變量含有靜態(tài)生存期。自動(dòng):內(nèi)存空間在程序執(zhí)行到定義它們復(fù)合語(yǔ)句(包含函數(shù)體)時(shí)才分配,當(dāng)定義它們復(fù)合語(yǔ)句執(zhí)行結(jié)束時(shí),它們空間將被收回。局部變量和函數(shù)參數(shù)普通含有自動(dòng)生存期。動(dòng)態(tài):內(nèi)存空間在程序中顯式地用new操作或malloc庫(kù)函數(shù)分配、用delete操作或free庫(kù)函數(shù)收回。動(dòng)態(tài)變量含有動(dòng)態(tài)生存期。含有靜態(tài)生存期變量,假如沒(méi)有顯式初始化,系統(tǒng)將把它們初始化成0。第26頁(yè)存放類(lèi)修飾符在定義局部變量時(shí),能夠?yàn)樗鼈兗由洗娣蓬?lèi)修飾符來(lái)顯式地指出它們生存期。auto:使局部變量含有自動(dòng)生存期。局部變量默認(rèn)存放類(lèi)為auto。static:使局部變量含有靜態(tài)生存期。它只在函數(shù)第一次調(diào)用時(shí)進(jìn)行初始化,以后調(diào)用中不再進(jìn)行初始化,它值為上一次函數(shù)調(diào)用結(jié)束時(shí)值。register:使局部變量也含有自動(dòng)生存期,由編譯程序依據(jù)CPU存放器使用情況來(lái)決定是否存放在存放器中。第27頁(yè)voidf(){autointx=0;//auto普通不寫(xiě)

staticinty=1;registerintz=0;x++;y++;z++;cout<<x<<y<<z<<endl;}第一次調(diào)用f時(shí),輸出:121第二次調(diào)用f時(shí),輸出:131第28頁(yè)程序?qū)嶓w在內(nèi)存中安排靜態(tài)數(shù)據(jù)區(qū)用于全局變量、static存放類(lèi)局部變量以及常量?jī)?nèi)存分配。代碼區(qū)用于存放程序指令,對(duì)C++程序而言,代碼區(qū)存放是全部函數(shù)代碼;棧區(qū)用于auto存放類(lèi)局部變量、函數(shù)形式參數(shù)以及函數(shù)調(diào)用時(shí)相關(guān)信息(如:函數(shù)返回地址等)內(nèi)存分配;堆區(qū)用于動(dòng)態(tài)變量?jī)?nèi)存分配。

靜態(tài)數(shù)據(jù)區(qū)代碼區(qū)棧區(qū)堆區(qū)第29頁(yè)C++程序多模塊結(jié)構(gòu)邏輯上,一個(gè)C++程序由一些全局函數(shù)(區(qū)分于類(lèi)定義中組員函數(shù))、全局常量、全局變量/對(duì)象以及類(lèi)定義組成,其中必須有且僅有一個(gè)名字為main全局函數(shù)。函數(shù)內(nèi)部能夠包含形參、局部常量、局部變量/對(duì)象定義以及語(yǔ)句。物理上,能夠按某種規(guī)則對(duì)組成C++程序各個(gè)邏輯單位(全局函數(shù)、全局常量、全局變量/對(duì)象、類(lèi)等)定義進(jìn)行分組,分別把它們放在若干個(gè)源文件中,組成程序模塊。程序模塊是為了便于從物理上對(duì)程序進(jìn)行組織、管理和了解,便于多人合作開(kāi)發(fā)一個(gè)程序。程序模塊是可單獨(dú)編譯程序單位。第30頁(yè)C++模塊組成一個(gè)C++模塊普通包含兩個(gè)部分:接口(.h文件):給出在本模塊中定義、提供給其它模塊使用一些程序?qū)嶓w(如:函數(shù)、全局變量等)申明;實(shí)現(xiàn)(.cpp文件):模塊實(shí)現(xiàn)給出了模塊中程序?qū)嶓w定義。第31頁(yè)在模塊A中要用到模塊B中定義程序?qū)嶓w時(shí),能夠在A.cpp文件中用文件包含命令(#include)把B.h文件包含進(jìn)來(lái)。文件包含命令是一個(gè)編譯預(yù)處理命令,其格式為:

#include<文件名>或#include"文件名"include命令含義是:在編譯前,用命令中文件名所指定文件內(nèi)容替換該命令。第32頁(yè)//file1.hexternintx;//全局變量x申明externdoubley;//全局變量y申明intf();//全局函數(shù)f申明//file1.cppintx=1;//全局變量x定義doubley=2.0;//全局變量y定義intf()//全局函數(shù)f定義{ intm;//局部變量m定義

...... m+=x;//語(yǔ)句

...... returnm;}第33頁(yè)//file2.hvoidg();//全局函數(shù)g申明//file2.cpp#include"file1.h"http://把文件file1.h中內(nèi)容包含進(jìn)來(lái)voidg()//全局函數(shù)g定義{ doublez;//局部變量z定義

...... z=y+10;//語(yǔ)句

......}第34頁(yè)//main.cpp#include"file1.h"http://把文件file1.h中內(nèi)容包含進(jìn)來(lái)#include"file2.h"http://把文件file2.h中內(nèi)容包含進(jìn)來(lái)intmain()//全局函數(shù)main定義{ doubler;//局部變量r定義

...... r=x+y*f();//語(yǔ)句

...... g();//語(yǔ)句

......}第35頁(yè)標(biāo)識(shí)符作用域?yàn)榱藢?duì)程序中實(shí)體名字進(jìn)行管理,引進(jìn)了標(biāo)識(shí)符作用域概念。一個(gè)定義了標(biāo)識(shí)符有效范圍(能被訪問(wèn)程序段)稱(chēng)為該標(biāo)識(shí)符作用域。在不一樣作用域中,能夠用相同標(biāo)識(shí)符來(lái)標(biāo)識(shí)不一樣程序?qū)嶓w。第36頁(yè)C++標(biāo)識(shí)符作用域C++把標(biāo)識(shí)符作用域分成若干類(lèi),其中包含:局部作用域全局作用域文件作用域函數(shù)作用域函數(shù)原型作用域類(lèi)作用域名空間作用域第37頁(yè)局部作用域在函數(shù)定義或復(fù)合語(yǔ)句中、從標(biāo)識(shí)符定義點(diǎn)開(kāi)始到函數(shù)定義或復(fù)合語(yǔ)句結(jié)束之間程序段。C++中局部常量名、局部變量名/對(duì)象名以及函數(shù)形參名含有局部作用域。第38頁(yè)voidf(intn){x++;//Errorintx=0;x++; n++; .......}voidg(){x++;//Errorn++;//Error}intmain(){intx=0;intn;cin>>n;f(n); ......}第39頁(yè)假如在一個(gè)標(biāo)識(shí)符局部作用域中包含內(nèi)層復(fù)合語(yǔ)句,而且在該內(nèi)層復(fù)合語(yǔ)句中定義了一個(gè)同名不一樣實(shí)體,則外層定義標(biāo)識(shí)符作用域應(yīng)該是從其潛在作用域中扣除內(nèi)層同名標(biāo)識(shí)符作用域之后所得到作用域。voidf(){ intx;//外層x定義

...x...//外層x while(...x...)//外層x {...x...//外層x,

doublex;//內(nèi)層x定義

...x...//內(nèi)層x } ...x...//外層x}第40頁(yè)全局作用域在函數(shù)級(jí)定義標(biāo)識(shí)符含有全局作用域。全局變量名/對(duì)象名、全局函數(shù)名和全局類(lèi)名作用域普通含有全局作用域,它們?cè)谡麄€(gè)程序中可用。假如在某個(gè)局部作用域中定義了與某個(gè)全局標(biāo)識(shí)符同名標(biāo)識(shí)符,則該全局標(biāo)識(shí)符作用域應(yīng)扣掉與之同名局部標(biāo)識(shí)符作用域。在局部標(biāo)識(shí)符作用域中若要使用與其同名全局標(biāo)識(shí)符,則需要用全局域選擇符(::)對(duì)全局標(biāo)識(shí)符進(jìn)行修飾(受限)。第41頁(yè)doublex;//外層x定義voidf(){ intx;//內(nèi)層x定義

...x...//內(nèi)層x ...::x...//外層x}第42頁(yè)文件作用域在全局標(biāo)識(shí)符定義中加上static修飾符,則該全局標(biāo)識(shí)符就成了含有文件作用域標(biāo)識(shí)符,它們只能在定義它們?cè)次募K)中使用。C++中關(guān)鍵詞static有兩個(gè)不一樣含義。在局部變量定義中,static修飾符用于指定局部變量采取靜態(tài)存放分配;而在全局標(biāo)識(shí)符定義中,static修飾符用于把全局標(biāo)識(shí)符作用域改變?yōu)槲募饔糜颉?/p>

普通情況下,含有全局作用域標(biāo)識(shí)符主要用于標(biāo)識(shí)被程序各個(gè)模塊共享程序?qū)嶓w,而含有文件作用域標(biāo)識(shí)符用于標(biāo)識(shí)在一個(gè)模塊內(nèi)部共享程序?qū)嶓w。第43頁(yè)//file1.cppstaticinty;//文件作用域staticvoidf()//文件作用域{......}//file2.cppexterninty;externvoidf();voidg(){...y...//Errorf();//Error}第44頁(yè)函數(shù)作用域語(yǔ)句標(biāo)號(hào)是唯一含有函數(shù)作用域標(biāo)識(shí)符,它們?cè)诙x它們函數(shù)體中任何地方都能夠訪問(wèn)。函數(shù)作用域與局部作用域區(qū)分是:函數(shù)作用域包含整個(gè)函數(shù),而局部作用域是從定義點(diǎn)開(kāi)始到函數(shù)定義或復(fù)合語(yǔ)句結(jié)束。在函數(shù)體中,一個(gè)語(yǔ)句標(biāo)號(hào)只能定義一次,即使是在內(nèi)層復(fù)合語(yǔ)句中,也不能再定義與外層相同語(yǔ)句標(biāo)號(hào)。第45頁(yè)voidf(){ ...... gotoL;//OK ...... L:... ......{......L:...//Error ......} ...... gotoL;//OK ......}voidg(){ ...... gotoL;//Error ......}第46頁(yè)名空間作用域?qū)τ谝粋€(gè)多文件組成程序,有時(shí)見(jiàn)面臨一個(gè)問(wèn)題:在一個(gè)源文件中要用到兩個(gè)分別在另外兩個(gè)源文件中定義不一樣全局程序?qū)嶓w(如:全局函數(shù)),而這兩個(gè)全局程序?qū)嶓w名字相同。C++提供了名空間(namespace)設(shè)施來(lái)處理上述名沖突問(wèn)題。在一個(gè)名空間中定義全局標(biāo)識(shí)符,其作用域?yàn)樵撁臻g。當(dāng)在一個(gè)名空間外部需要使用該名空間中定義全局標(biāo)識(shí)符時(shí),可用該名空間名字來(lái)修飾或受限。第47頁(yè)//模塊1namespaceA{ intx=1; voidf() {...... }}//模塊2namespaceB{ intx=0; voidf() {...... }}...A::x...//A中xA::f();//A中f...B::x...//B中xB::f();//B中fusingnamespaceA;...x...//A中xf();//A中f...B::x...//B中xB::f();//B中fusingA::f;...A::x...//A中x

f();//A中f...B::x...//B中xB::f();//B中f//模塊31、2、3、第48頁(yè)遞歸函數(shù)函數(shù)調(diào)用是能夠嵌套。voidh(){......}voidg(){......h();......}voidf(){......g();.......}第49頁(yè)直接遞歸voidf(){..........f()..........}間接遞歸externvoidg();voidf(){..........g()..........}voidg(){.........f().........}假如一個(gè)函數(shù)在其函數(shù)體中直接或間接地調(diào)用了自己,則該函數(shù)稱(chēng)為遞歸函數(shù)。第50頁(yè)遞歸函數(shù)作用在程序設(shè)計(jì)中經(jīng)常需要實(shí)現(xiàn)重復(fù)性操作。循環(huán)為實(shí)現(xiàn)重復(fù)操作提供了一個(gè)路徑。實(shí)現(xiàn)重復(fù)操作另一個(gè)路徑是采取遞歸函數(shù)?!胺侄沃保―ivideandConquer)設(shè)計(jì)方法:把一個(gè)問(wèn)題分解成若干個(gè)子問(wèn)題,而每個(gè)子問(wèn)題性質(zhì)與原問(wèn)題相同,只是在規(guī)模上比原問(wèn)題要小。每個(gè)子問(wèn)題求解過(guò)程能夠采取與原問(wèn)題相同方式來(lái)進(jìn)行。遞歸函數(shù)為上述設(shè)計(jì)方法提供了一個(gè)自然、簡(jiǎn)練實(shí)現(xiàn)機(jī)制第51頁(yè)例:求第n個(gè)fibonacci數(shù)(遞歸解法)intfib(intn){ if(n==1||n==2) return1; else returnfib(n-2)+fib(n-1);}第52頁(yè)遞歸函數(shù)執(zhí)行過(guò)程//用遞歸函數(shù)求n!

intf(intn){ if(n==0) return1; else returnn*f(n-1);}第53頁(yè)遞歸條件和結(jié)束條件在定義遞歸函數(shù)時(shí),一定要對(duì)兩種情況給出描述:遞歸條件。指出何時(shí)進(jìn)行遞歸調(diào)用,它描述了問(wèn)題求解普通情況,包含:分解和綜合過(guò)程。結(jié)束條件。指出何時(shí)不需遞歸調(diào)用,它描述了問(wèn)題求解特殊情況或基本情況第54頁(yè)例:解漢諾塔問(wèn)題

漢諾塔問(wèn)題:有A,B,C三個(gè)柱子,柱子A上穿有n個(gè)大小不一樣圓盤(pán),大盤(pán)在下,小盤(pán)在上?,F(xiàn)要把柱子A上全部圓盤(pán)移到柱子B上,要求每次只能移動(dòng)一個(gè)圓盤(pán),且大盤(pán)不能放在小盤(pán)上,移動(dòng)時(shí)可借助柱子C。編寫(xiě)一個(gè)C++函數(shù)給出移動(dòng)步驟,如:n=3時(shí),移動(dòng)步驟為:1:A

B,2:A

C,1:B

C,3:A

B,1:C

A,2:C

B,1:A

B。

ABC第55頁(yè)當(dāng)n=1時(shí),只要把1個(gè)圓盤(pán)從A移至B就能夠了cout<<"1:A

B"<<endl;當(dāng)n大于1時(shí),我們能夠把該問(wèn)題分解成下面三個(gè)子問(wèn)題:把n-1個(gè)圓盤(pán)從柱子A移到柱子C。把第n個(gè)圓盤(pán)從柱子A移到柱子B。cout<<n<<":A->B"<<endl;把n-1個(gè)圓盤(pán)從柱子C移到柱子B。上面子問(wèn)題1和3與原問(wèn)題相同,只是盤(pán)子個(gè)數(shù)少了一個(gè)以及移動(dòng)位置不一樣;子問(wèn)題2是移動(dòng)一個(gè)盤(pán)子簡(jiǎn)單問(wèn)題。第56頁(yè)#include<iostream>usingnamespacestd;voidhanoi(charx,chary,charz,intn)//把n個(gè)圓盤(pán)從x表示

//柱子移至y所表示柱子。{ if(n==1) cout<<"1:"<<x<<"→"<<y<<endl;//把第1個(gè)

//盤(pán)子從x表示柱子移至y所表示柱子。

else { hanoi(x,z,y,n-1);//把n-1個(gè)圓盤(pán)從x表示柱子移至

//z所表示柱子。

cout<<n<<":"<<x<<"→"<<y<<endl; //把第n個(gè)圓盤(pán)從x表示柱子移至y所表示柱子。

hanoi(z,y,x,n-1);//把n-1個(gè)圓盤(pán)從z表示柱子移至

//y所表示柱子。

}}第57頁(yè)遞歸與循環(huán)選擇對(duì)于一些遞歸定義問(wèn)題,用遞歸函數(shù)來(lái)處理會(huì)顯得比較自然和簡(jiǎn)練,而用循環(huán)來(lái)處理這么問(wèn)題,有時(shí)會(huì)很復(fù)雜,不易設(shè)計(jì)和了解。在實(shí)現(xiàn)數(shù)據(jù)操作上,它們有一點(diǎn)不一樣:循環(huán)是在同一組變量上進(jìn)行重復(fù)操作(循環(huán)經(jīng)常又稱(chēng)為迭代)遞歸則是在不一樣變量組(屬于遞歸函數(shù)不一樣實(shí)例)上進(jìn)行重復(fù)操作。遞歸缺點(diǎn):因?yàn)檫f歸表示重復(fù)操作是經(jīng)過(guò)函數(shù)調(diào)用來(lái)實(shí)現(xiàn),而函數(shù)調(diào)用是需要開(kāi)銷(xiāo);??臻g大小也會(huì)限制遞歸深度。遞歸算法有時(shí)會(huì)出現(xiàn)重復(fù)計(jì)算。第58頁(yè)處理小函數(shù)低效問(wèn)題因?yàn)楹瘮?shù)調(diào)用是需要開(kāi)銷(xiāo),尤其是對(duì)一些小函數(shù)頻繁調(diào)用將使程序效率有很大降低。C++提供了兩種處理上述問(wèn)題方法:宏定義內(nèi)聯(lián)函數(shù)第59頁(yè)宏定義在C++中,利用一個(gè)編譯預(yù)處理命令:宏定義,用它能夠?qū)崿F(xiàn)類(lèi)似函數(shù)功效:#define凵<宏名>(<參數(shù)表>)凵<文字串>比如:#define凵max(a,b)凵(((a)>(b))?(a):(b))在編譯之前,將對(duì)宏使用進(jìn)行文字替換!比如:編譯前將把cout<<max(x,y);替換成:cout<<(((x)>(y))?(x):(y));第60頁(yè)宏定義不足之處需要加上很多括號(hào)。比如:#definemax(a,b)a>b?a:b10+max(x,y)+z將被替換成:10+x>y?x:y+z有時(shí)會(huì)出現(xiàn)重復(fù)計(jì)算。比如:#define凵max(a,b)凵(((a)>(b))?(a):(b))max(x+1,y*2)將被替換成:(((x+1)>(y*2))?(x+1):(y*2))不進(jìn)行參數(shù)類(lèi)型檢驗(yàn)和轉(zhuǎn)換。

不利于一些工具對(duì)程序處理。第61頁(yè)內(nèi)聯(lián)函數(shù)內(nèi)聯(lián)函數(shù)是指在定義函數(shù)定義時(shí),在函數(shù)返回類(lèi)型之前加上一個(gè)關(guān)鍵詞inline,比如:inlineintmax(inta,intb){ returna>b?a:b;}內(nèi)聯(lián)函數(shù)作用是提議編譯程序把該函數(shù)函數(shù)體展開(kāi)到調(diào)用點(diǎn),以提升函數(shù)調(diào)用效率。內(nèi)聯(lián)函數(shù)形式上屬于函數(shù),它遵照函數(shù)一些要求,如:參數(shù)類(lèi)型檢驗(yàn)與轉(zhuǎn)換。使用內(nèi)聯(lián)函數(shù)時(shí)應(yīng)注意以下幾點(diǎn):編譯程序?qū)?nèi)聯(lián)函數(shù)限制。內(nèi)聯(lián)函數(shù)名含有文件作用域。第62頁(yè)帶缺省值形式參數(shù)在C++中允許在申明函數(shù)時(shí),為函數(shù)一些參數(shù)指定默認(rèn)值。假如調(diào)用這些函數(shù)時(shí)沒(méi)有提供對(duì)應(yīng)實(shí)參,則對(duì)應(yīng)形參采取指定默認(rèn)值。比如,對(duì)于下面函數(shù)申明:voidprint(intvalue,intbase=10);下面調(diào)用:print(28);//28傳給value;10傳給baseprint(32,2);//28傳給value;2傳給base第63頁(yè)在指定函數(shù)參數(shù)默認(rèn)值時(shí),應(yīng)注意下面幾點(diǎn):有默認(rèn)值形參應(yīng)處于形參表右部。比如:voidf(inta,intb=1,intc=0);//OKvoidf(inta,intb=1,intc);//Error

對(duì)參數(shù)默認(rèn)值指定只在函數(shù)申明(包含定義性申明)處有意義。在不一樣源文件中,對(duì)同一個(gè)函數(shù)申明能夠?qū)λ粋€(gè)參數(shù)指定不一樣默認(rèn)值;在同一個(gè)源文件中,對(duì)同一個(gè)函數(shù)申明只能對(duì)它每一個(gè)參數(shù)指定一次默認(rèn)值。

第64頁(yè)函數(shù)名重載對(duì)于一些功效相同、參數(shù)類(lèi)型或個(gè)數(shù)不一樣函數(shù),有時(shí)給它們?nèi)∠嗤謺?huì)帶來(lái)使用上方便。比如,把下面函數(shù):voidprint_int(inti){......}voidprint_double(doubled){......}voidprint_char(charc){......}voidprint_A(Aa){......}//A為自定義類(lèi)型定義為:voidprint(inti){......}voidprint(doubled){......}voidprint(charc){......}voidprint(Aa){......}上述函數(shù)定義形式稱(chēng)為函數(shù)名重載。第65頁(yè)對(duì)重載函數(shù)調(diào)用綁定確定一個(gè)對(duì)重載函數(shù)調(diào)用對(duì)應(yīng)著哪一個(gè)重載函數(shù)定義過(guò)程稱(chēng)為綁定(binding,又稱(chēng)定聯(lián)、聯(lián)編、捆綁)。比如:print(1.0)將調(diào)用voidprint(doubled){......}對(duì)重載函數(shù)調(diào)用綁定在編譯時(shí)刻由編譯程序依據(jù)實(shí)參加形參匹配情況來(lái)決定。從形參個(gè)數(shù)與實(shí)參個(gè)數(shù)相同重載函數(shù)中按下面規(guī)則選擇一個(gè):準(zhǔn)確匹配提升匹配標(biāo)準(zhǔn)轉(zhuǎn)換匹配自定義轉(zhuǎn)換匹配匹配失敗第66頁(yè)準(zhǔn)確匹配類(lèi)型相同對(duì)實(shí)參進(jìn)行“微小”類(lèi)型轉(zhuǎn)換:數(shù)組變量名->數(shù)組首地址函數(shù)名->函數(shù)首地址等等比如,對(duì)于下面重載函數(shù)定義:

voidprint(int); voidprint(double); voidprint(char);下面函數(shù)調(diào)用:

print(1);綁定到函數(shù):voidprint(int); print(1.0);綁定到函數(shù):voidprint(double); print('a');綁定到函數(shù):voidprint(char);第67頁(yè)提升匹配先對(duì)實(shí)參進(jìn)行下面類(lèi)型提升,然后進(jìn)行準(zhǔn)確匹配:按整型提升規(guī)則提升實(shí)參類(lèi)型把float類(lèi)型實(shí)參提升到double把double類(lèi)型實(shí)參提升到longdouble比如,對(duì)于下述重載函數(shù):voidprint(int);voidprint(double);依據(jù)提升匹配,下面函數(shù)調(diào)用:print('a');綁定到函數(shù):voidprint(int);print(1.0f);綁定到函數(shù):voidprint(double);

第68頁(yè)標(biāo)準(zhǔn)轉(zhuǎn)換匹配任何算術(shù)類(lèi)型能夠相互轉(zhuǎn)換枚舉類(lèi)型能夠轉(zhuǎn)換成任何算術(shù)類(lèi)型零能夠轉(zhuǎn)換成任何算術(shù)類(lèi)型或指針類(lèi)型任何類(lèi)型指針能夠轉(zhuǎn)換成void*派生類(lèi)指針能夠轉(zhuǎn)換成基類(lèi)指針每個(gè)標(biāo)準(zhǔn)轉(zhuǎn)換都是平等。

第69頁(yè)比如,對(duì)于下述重載函數(shù):voidprint(char);voidprint(char*);依據(jù)標(biāo)準(zhǔn)轉(zhuǎn)換匹配,下面函數(shù)調(diào)用:print(1);綁定到函數(shù):voidprint(char);第70頁(yè)綁定失敗假如不存在匹配或存在多個(gè)匹配,則綁定失敗比如,對(duì)于下述重載函數(shù):voidprint(char);voidprint(double);依據(jù)標(biāo)準(zhǔn)轉(zhuǎn)換匹配,下面函數(shù)調(diào)用將會(huì)綁定失?。簆rint(1);因?yàn)橐罁?jù)標(biāo)準(zhǔn)轉(zhuǎn)換,1(屬于int型)既能夠轉(zhuǎn)成char,又能夠轉(zhuǎn)成double處理方法是:對(duì)實(shí)參進(jìn)行顯式類(lèi)型轉(zhuǎn)換,如,print((char)1)或print((double)1)增加額外重載,如,增加一個(gè)重載函數(shù)定義:voidprint(int);第71頁(yè)C++標(biāo)準(zhǔn)庫(kù)函數(shù)為了方便程序設(shè)計(jì),C++語(yǔ)言每個(gè)實(shí)現(xiàn)往往會(huì)提供一個(gè)標(biāo)準(zhǔn)庫(kù),其中定義了一些語(yǔ)言本身沒(méi)有提供功效:慣用數(shù)學(xué)函數(shù)字符串處理函數(shù)以及輸入/輸出,等等在C++標(biāo)準(zhǔn)庫(kù)中,依據(jù)功效對(duì)定義程序?qū)嶓w進(jìn)行了分類(lèi),把每一類(lèi)程序?qū)嶓w申明分別放在一個(gè)頭文件中。在C++中,把從C語(yǔ)言保留下來(lái)庫(kù)函數(shù),重新定義在名空間std中;對(duì)對(duì)應(yīng)頭文件進(jìn)了重新命名:*.h->c*第72頁(yè)一些標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)(cmath或math.h)intabs(intn);//int型絕對(duì)值longlabs(longn);//longint型絕對(duì)值doublefabs(doublex);//double型絕對(duì)值doublesin(doublex);//正弦函數(shù)doublecos(doublex);//余弦函數(shù)doubletan(doublex);//正切函數(shù)doubleasin(doublex);//反正弦函數(shù)doubleacos(doublex);//反余弦函數(shù)doubleatan(doublex);//反正切函數(shù)doubleceil(doublex);//大于x最小整數(shù)(返回值為以

//double表示整型數(shù))doublefloor(doublex);//小于x最大整數(shù)(返回值為以

//double表示整型數(shù))doublelog(doublex);//自然對(duì)數(shù)doublelog10(doublex);//以10為底對(duì)數(shù)doublesqrt(doublex);//平方根doublepow(doublex,doubley);//xy次冪第73頁(yè)編譯預(yù)處理命令C++程序中能夠?qū)懸恍┕┚幾g程序使用命令:編譯預(yù)處理命令。編譯預(yù)處理命令不是C++程序所要完成功效,而是用于對(duì)編譯過(guò)程給出指導(dǎo),其功效由編譯預(yù)處理系統(tǒng)來(lái)完成。編譯預(yù)處理命令主要有:文件包含命令(#include)宏定義(#define)命令條件編譯命令第74頁(yè)條件編譯編譯程

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論