![第3章c++基本控制結(jié)構(gòu)和函數(shù)_第1頁](http://file4.renrendoc.com/view/287f8033de91ca5c2063f1ce7ef2b574/287f8033de91ca5c2063f1ce7ef2b5741.gif)
![第3章c++基本控制結(jié)構(gòu)和函數(shù)_第2頁](http://file4.renrendoc.com/view/287f8033de91ca5c2063f1ce7ef2b574/287f8033de91ca5c2063f1ce7ef2b5742.gif)
![第3章c++基本控制結(jié)構(gòu)和函數(shù)_第3頁](http://file4.renrendoc.com/view/287f8033de91ca5c2063f1ce7ef2b574/287f8033de91ca5c2063f1ce7ef2b5743.gif)
![第3章c++基本控制結(jié)構(gòu)和函數(shù)_第4頁](http://file4.renrendoc.com/view/287f8033de91ca5c2063f1ce7ef2b574/287f8033de91ca5c2063f1ce7ef2b5744.gif)
![第3章c++基本控制結(jié)構(gòu)和函數(shù)_第5頁](http://file4.renrendoc.com/view/287f8033de91ca5c2063f1ce7ef2b574/287f8033de91ca5c2063f1ce7ef2b5745.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
C++程序設(shè)計(jì)第3章基本控制結(jié)構(gòu)和函數(shù)3.1算法和基本控制結(jié)構(gòu)3.2選擇型控制結(jié)構(gòu)3.3循環(huán)型控制結(jié)構(gòu)3.4文本文件的輸入和輸出3.5函數(shù)基礎(chǔ)第3章基本控制結(jié)構(gòu)和函數(shù)3.6內(nèi)存模型、作用域和生存期3.7案例實(shí)訓(xùn)3.1算法和基本控制結(jié)構(gòu)
3.1.1算法與流程圖
算法(algorithm)是在有限步驟內(nèi)求解某一問題所使用的一組定義明確的規(guī)則,是解題方法的精確描述。無論是形成解題思路還是編寫程序,都是在實(shí)施某種算法。前者是推理實(shí)現(xiàn)的算法,后者是操作實(shí)現(xiàn)的算法。
計(jì)算機(jī)處理的問題一般分為數(shù)值運(yùn)算和非數(shù)值運(yùn)算,用于科學(xué)與工程計(jì)算的問題基本屬于數(shù)值計(jì)算,如:矩陣計(jì)算、方程求解等。非數(shù)值運(yùn)算應(yīng)用包括數(shù)據(jù)處理、知識處理,如:信息系統(tǒng)、工廠自動化、辦公室自動化、家庭自動化、專家系統(tǒng)、模式識別、機(jī)器翻譯等。3.1算法和基本控制結(jié)構(gòu)
主要研究數(shù)值運(yùn)算實(shí)現(xiàn)方法的算法通常稱為數(shù)值算法,如:求解多項(xiàng)式與線性代數(shù)方程組、解矩陣與非線性方程、數(shù)字信號處理、小波變換等。非數(shù)值算法則是研究數(shù)據(jù)存儲和處理相關(guān)的算法,常見的有線性表、棧、隊(duì)列、樹、圖、排序、查找與文件操作、并行計(jì)算等。一個(gè)算法應(yīng)具有以下五個(gè)基本特征:(1)有窮性:一個(gè)算法必須保證執(zhí)行有限步操作之后終止,不能是無限制地執(zhí)行。
(2)確定性:算法的每一步驟必須有確切的定義,應(yīng)當(dāng)是明確無誤的,不能含義模糊。
(3)輸入:一個(gè)算法有零或多個(gè)輸入,以刻畫運(yùn)算對象的初始情況,所謂零個(gè)輸入是指算法本身已確定了初始條件
(4)輸出:一個(gè)算法有一個(gè)或多個(gè)輸出,以反映對輸入數(shù)據(jù)加工后的結(jié)果。沒有輸出的算法是毫無意義的。
(5)有效性:算法中的每一步都應(yīng)該能夠精確地運(yùn)行,并且算法執(zhí)行后應(yīng)得到確定的結(jié)果。3.1算法和基本控制結(jié)構(gòu)
3.1算法和基本控制結(jié)構(gòu)為描述一個(gè)算法,可以采用許多不同的方法。比較常用的有:自然語言、流程圖、偽代碼。流程圖使用圖形來表示算法,是一種直觀易懂、應(yīng)用最廣的方法。這里主要介紹傳統(tǒng)流程圖的表示方法。流程圖用一組幾何圖形框來表示各種不同類型的操作。圖3-1給出了一些常用的流程圖符號。3.1算法和基本控制結(jié)構(gòu)【例3-1】用流程圖表示已知三角形的三邊a、b、c,求三角形面積的算法。3.1算法和基本控制結(jié)構(gòu)
理論和實(shí)踐證明,無論多復(fù)雜的算法均可通過順序、選擇、循環(huán)三種基本控制結(jié)構(gòu)構(gòu)造實(shí)現(xiàn)。所有的結(jié)構(gòu)都是單入口和單出口,結(jié)構(gòu)化程序是由基本控制結(jié)構(gòu)經(jīng)多層嵌套組合而成。順序結(jié)構(gòu)是一種最簡單的結(jié)構(gòu),程序按從上到下的順序一步一步地執(zhí)行各個(gè)模塊。參見圖3-3A。程序在運(yùn)行過程中會根據(jù)某個(gè)條件成立與否,改變程序的執(zhí)行順序,跳轉(zhuǎn)到另一模塊,這一過程被稱為控制轉(zhuǎn)移。選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)就是二種最基本的控制轉(zhuǎn)移結(jié)構(gòu)。選擇結(jié)構(gòu)是程序根據(jù)判別條件的不同結(jié)果做出不同路徑的選擇,從而執(zhí)行不同的模塊。圖3-3B是選擇結(jié)構(gòu)。循環(huán)結(jié)構(gòu)是程序根據(jù)判別條件是否成立,不斷重復(fù)執(zhí)行某個(gè)模塊。參見圖3-3C。3.1.2三種基本控制結(jié)構(gòu)3.1算法和基本控制結(jié)構(gòu)與自然語言相似,C++程序也是由語句組成。C++語言的語句通常用分號表示結(jié)束,語句主要有下列幾類。1.說明語句又稱聲明語句,用于在程序中命名變量與常量,用戶自定義枚舉類型、類、結(jié)構(gòu)類型和函數(shù)聲明等。說明語句僅供編譯器生成程序代碼使用,在程序執(zhí)行過程中不對數(shù)據(jù)進(jìn)行任何操作。2.表達(dá)式語句在表達(dá)式后面加上分號即構(gòu)成一條表達(dá)式語句。賦值語句、自增與自減語句都是表達(dá)式語句。函數(shù)調(diào)用可作為一個(gè)操作數(shù),是表達(dá)式的一部分,故函數(shù)調(diào)用語句也是一種表達(dá)式語句。3.1算法和基本控制結(jié)構(gòu)3.1.3語句3.1算法和基本控制結(jié)構(gòu)3.1算法和基本控制結(jié)構(gòu)3.控制語句
用于實(shí)現(xiàn)程序流程控制的語句,有if選擇語句、switch選擇語句、循環(huán)控制語句、break、continue、return等。4.復(fù)合語句
用一對花括號{}把若干條語句括在一起,構(gòu)成一條復(fù)合語句。復(fù)合語句后面不需要加分號。復(fù)合語句內(nèi)部可嵌套多條復(fù)合語句。復(fù)合語句有時(shí)也稱塊語句。5.異常處理語句
程序執(zhí)行過程中,可能引發(fā)某些異常,程序中專門處理異常的語句稱為異常處理語句。6.空語句
只有一個(gè)分號的語句,它不執(zhí)行任何操作,一般用于語法上要求有一條語句但實(shí)際沒有任何操作的場合。例如:for(inti=1;i<10000;i++);//空語句,起延時(shí)作用3.2選擇型控制結(jié)構(gòu)3.2.1if…else選擇結(jié)構(gòu)
if語句的語法格式為:
if(<表達(dá)式>) <語句1> [else <語句2>]3.2選擇型控制結(jié)構(gòu)其中:(1)<表達(dá)式>計(jì)算的值為0,則為邏輯假,非0為邏輯真。當(dāng)為真時(shí),程序執(zhí)行<語句1>,否則執(zhí)行<語句2>。(2)如果執(zhí)行語句有多條,則將它們置于花括號之中構(gòu)成復(fù)合語句。(3)if語句的流程圖見圖3-3B。(4)if語句可以嵌套使用。在<語句1>和<語句2>中又可以是一條if語句。C++規(guī)定else與其前邊最近未配對的if相匹配。(5)條件運(yùn)算符的功能與if語句相似。在根據(jù)條件對變量進(jìn)行賦值時(shí),有時(shí)用?:運(yùn)算符實(shí)現(xiàn)則更為簡單高效?!纠?-2】輸入三個(gè)整數(shù),找出其中最大數(shù)。3.2選擇型控制結(jié)構(gòu)【例3-3】判斷某年是否為閏年。
分析:閏年要滿足的條件是它能被4整除且不能被100整除,或者能被400整除。判斷一個(gè)整數(shù)能否被另一個(gè)整數(shù)整除的方法是用模運(yùn)算。如果模運(yùn)算的值為0,表示該數(shù)能被模數(shù)整除,否則為不能。如:整數(shù)x能被4整數(shù)的邏輯表達(dá)式是:x%4==0。3.2選擇型控制結(jié)構(gòu)3.2.2switch多分支選擇結(jié)構(gòu)
判別條件僅為真假兩種結(jié)果,用if語句表示比較方便。當(dāng)判別條件有多種可能值時(shí),雖然可以通過if語句嵌套的方法進(jìn)行描述,但其結(jié)構(gòu)則顯得比較復(fù)雜。switch語句又稱開關(guān)語句,它能根據(jù)給定的條件從多個(gè)分支語句序列中選擇一個(gè)作為執(zhí)行入口,其語法格式如下:
switch(<表達(dá)式>){ case<常量表達(dá)式1>:[語句1][break;] case<常量表達(dá)式2>:[語句2][break;] …… case<常量表達(dá)式n-1>:[語句n-1][break;] [default:語句n]}3.2選擇型控制結(jié)構(gòu)【例3-4】輸入0~6之間的一個(gè)整數(shù),輸出所對應(yīng)的星期幾字符串?!纠?-5】輸入課程的百分制成績,輸出對應(yīng)的等級制成績。90~100為優(yōu),80~89為良,70~79為中,60~69為合格,60以下為不合格。3.3循環(huán)型控制結(jié)構(gòu)3.3.1for循環(huán)結(jié)構(gòu)
for語句的語法格式為:
for(<表達(dá)式1>;<表達(dá)式2>;<表達(dá)式3>) <循環(huán)體語句>for循環(huán)是用得最多的一種循環(huán),其中的<表達(dá)式3>不僅能控制循環(huán),而且還能實(shí)現(xiàn)循環(huán)體中的操作。下面幾段程序所完成的功能相同,都是計(jì)算1至100之間整數(shù)的和,但表示方法卻相差較大,從中可以看出for語句的使用方法非常靈活。3.3循環(huán)型控制結(jié)構(gòu)//方法1intsum=0;for(inti=1;i<=100;i++) sum+=i;
//方法2intsum=0;for(inti=1;i<=100;i++,sum+=i)//表達(dá)式3用逗號分隔了二條語句;//空語句//方法3intsum=0;for(inti=1;i<=100;sum+=i++)//sum+=i++二句合一句;
3.3循環(huán)型控制結(jié)構(gòu)
//方法4intsum=0,i=1;for(;i<=100;)//表達(dá)式1和表達(dá)式2均空
sum+=i++;//方法5intsum=0,i=1;for(;;)//三個(gè)表達(dá)式均為空
if(i>100) break; else sum+=i++;【例3-6】用循環(huán)嵌套,打印九九乘法表。3.3循環(huán)型控制結(jié)構(gòu)【例3-7】狐貍找兔子
圍繞著山頂有10個(gè)洞,一只狐貍和一只兔子住在各自的洞里。狐貍想吃掉兔子。一天,兔子對狐貍說:“你想吃我有一個(gè)條件,先把洞從1至10編上號,你從10號洞出發(fā),先到1號洞找我;第二次隔1個(gè)洞找我,第三次隔2個(gè)洞找我,以后依次類推,次數(shù)不限,若能找到我,你就可以飽餐一頓。不過在沒有找到我以前不能停下來?!焙倽M口答應(yīng),就開始找了。它從早到晚進(jìn)了1000次洞,累得昏了過去,也沒找到兔子,請問兔子躲在幾號洞里?
分析:首先要考慮的是10個(gè)洞在計(jì)算機(jī)里用什么方法描述,狐貍進(jìn)洞信息又怎樣記錄。用整型數(shù)組在內(nèi)存開10個(gè)單元表示洞,并初始化其中的值為零,表示狐貍沒有到過此洞,狐貍進(jìn)入洞一次則使該單元的值增1,1000次進(jìn)洞用循環(huán)來表示。3.3循環(huán)型控制結(jié)構(gòu)3.3.2while循環(huán)結(jié)構(gòu)While語句的語法格式為:
while(<表達(dá)式>) <循環(huán)語句>【例3-8】搬磚問題:36個(gè)人搬36塊磚,男搬4,女搬3,2個(gè)小孩抬一磚。要求一次全部搬完,問男、女、小孩各若干?分析:用窮舉法。所謂窮舉法是對問題的所有可能狀態(tài)進(jìn)行一一測試,直至找到解或測試全部結(jié)束。根據(jù)題義,男的人數(shù)men取值0~8,女的人數(shù)women取值0~11,小孩的人數(shù)children取值0~36,并且有等式men*4+women*3+children/2=36成立。3.3循環(huán)型控制結(jié)構(gòu)【例3-9】編程計(jì)算正弦函數(shù)的近似值,要求誤差小于10-1。計(jì)算公式如下:分析:用遞推法。遞推法又稱迭代法,是指根據(jù)已有的值推算出其它新值的解題方法。本例中,參加累加的每一項(xiàng)的值均可通過前一項(xiàng)的值推算出來。公式中奇數(shù)是正數(shù)而偶數(shù)項(xiàng)是負(fù)數(shù),程序中可設(shè)置一個(gè)整型變量sign,設(shè)其初值為1,每計(jì)算一項(xiàng)就用-1乘之,再將其與對應(yīng)項(xiàng)相乘,實(shí)現(xiàn)符號項(xiàng)的正負(fù)交替出現(xiàn)。3.3循環(huán)型控制結(jié)構(gòu)3.3.3do…while循環(huán)結(jié)構(gòu)do…while循環(huán)語句的語法格式為:
do <循環(huán)體語句> while(<表達(dá)式>);【例3-10】輸入一個(gè)無符號型整數(shù),分解出整數(shù)的每一位值并輸出。分析:VC2010中無符號型整數(shù)用4個(gè)字節(jié)保存,其取值范圍是0~4294967295。整數(shù)變量中每個(gè)位上位元的獲取方法:用模運(yùn)算取得數(shù)的個(gè)位,再對變量自身除10并保存,去除變量中的原個(gè)位數(shù)使原來的十位成為個(gè)位,重復(fù)上述步驟直至整數(shù)值為0。3.3循環(huán)型控制結(jié)構(gòu)【例3-11】用歐幾里得算法求兩個(gè)非負(fù)整數(shù)的最大公約數(shù)。分析:歐幾里得算法又稱輾轉(zhuǎn)相除法。算法思想示例如下:求a=481和b=221的最大公因數(shù)。首先用a除以b(481=2×221+39)得余數(shù)r0=39;再用b=221除以r0=39(221=5×39+26)得余數(shù)r1=26;再以r0=39除以r1=26(39=1×26+13)得r2=13;最后用r1=26除以r2=13得余數(shù)r3=0,二數(shù)的最大公約數(shù)為13。3.3循環(huán)型控制結(jié)構(gòu)3.3.4跳轉(zhuǎn)語句C++的跳轉(zhuǎn)語句包括break、continue、goto、return和throw語句,本節(jié)重點(diǎn)介紹break語句和continue語句。1.break語句break語句在switch語句中已出現(xiàn)過,功能是跳轉(zhuǎn)去執(zhí)行switch語句之后的語句。在循環(huán)語句中,break語句的作用是將跳轉(zhuǎn)至循環(huán)語句之后,終止循環(huán)。需要注意的是,對于循環(huán)嵌套語句,如果break語句是在內(nèi)循環(huán)中,則其只能終止其所在的循環(huán)語句的執(zhí)行,流程跳轉(zhuǎn)至外循環(huán)。3.3循環(huán)型控制結(jié)構(gòu)下面程序段的功能是在屏幕上顯示由星號構(gòu)成的直角三角形for(inti=0;i<5;i++)//外循環(huán)
for(intj=0;j<5;j++)//內(nèi)循環(huán)
if(j<=i) cout<<"*"; else{ cout<<endl;break;//跳到外循環(huán)
}3.3循環(huán)型控制結(jié)構(gòu)【例3-12】編程輸出100以內(nèi)的所有素?cái)?shù)。分析:P是素?cái)?shù)的條件是它不能被中任一整數(shù)所整除,所以素?cái)?shù)的判別方法是用這些數(shù)依次除整數(shù)P,如果有一數(shù)能整除之,則即可判定其不是素?cái)?shù),終止測試。程序設(shè)計(jì)可采用循環(huán)語句對2~100內(nèi)的數(shù)依次進(jìn)行是否為素?cái)?shù)的測試。3.3循環(huán)型控制結(jié)構(gòu)2.continue語句continue語句的語法格式為:continue;其功能是將流程跳轉(zhuǎn)至當(dāng)前循環(huán)語句的條件表達(dá)式處,判斷是否繼續(xù)進(jìn)行循環(huán)。例如:下面二段程序的功能是:輸出1~100之間的不能被7整除的數(shù)。//程序段1for(inti=1;i<=100;i++){ if(i%7==0) continue;//流程跳過下面輸出語句,轉(zhuǎn)到i++和i<=100判定。
cout<<i<<endl;
}3.3循環(huán)型控制結(jié)構(gòu)//程序段2inti=1; do{ if(i%7==0) continue;//流程跳過下面輸出語句,轉(zhuǎn)到i++和i<=100判定。
cout<<i<<endl; }while(i++<=100);continue語句與break語句的區(qū)別是:continue語句是終止本輪循環(huán),而break語句是終止本層循環(huán)。此外,continue語句只能用在循環(huán)語句中。3.3循環(huán)型控制結(jié)構(gòu)【例3-13】設(shè)計(jì)模擬計(jì)算器中整數(shù)累加功能的程序。輸入的正負(fù)整數(shù)個(gè)數(shù)不限,當(dāng)輸入0時(shí),程序結(jié)束累加,并顯示所有數(shù)的累加和。
3.4文本文件的輸入與輸出3.4.1輸出數(shù)據(jù)至文本文件
系統(tǒng)所提供的文本文件輸入與輸出功能是在C++標(biāo)準(zhǔn)流類庫中,使用它們需要在程序源文件開頭加入#include<fstream>語句。針對文本文件的輸入與輸出操作需要經(jīng)歷三個(gè)主要步驟:打開、操作和關(guān)閉。
3.4文本文件的輸入與輸出向文本文件輸出數(shù)據(jù)的操作步驟:(1)ofstreamoutFile;//用ofstream類定義變量outFile,聲明了一個(gè)流對象。類與對象的概念在第4章介紹,其實(shí)類是一種特殊的數(shù)據(jù)類型,對象就是用該數(shù)據(jù)類型定義的變量。(2)outFile.open(“e:\\appData.txt”);//打開指定文件。建立磁盤文件與對象的關(guān)聯(lián)。(3)outFile<<…;//向文件寫數(shù)據(jù)。方式與cout相似。(4)outFile.close();//打開的文件最后一定要關(guān)閉。文件關(guān)閉時(shí),系統(tǒng)把與該文件在緩沖區(qū)中的信息寫到磁盤文件中。不關(guān)閉文件流的后果是可能丟失數(shù)據(jù)。3.4文本文件的輸入與輸出【例3-14】向顯示屏和文件同時(shí)輸出下列格式的楊輝三角形。楊輝三角形的形狀如下:
11112113311464115101051分析:打印楊輝三角形的方法有多種,本例中用三維數(shù)組存儲楊輝三角形的每一行數(shù)據(jù)。數(shù)據(jù)的賦值通過編程完成,首先在定義數(shù)組時(shí)為所有單元賦0,再對第0行第0列單元賦值1。因?yàn)闂钶x三角形的特點(diǎn)是非1數(shù)的值都是其上一行的“左上”和“右上”元素的和,故可用循環(huán)語句對其它行進(jìn)行賦值。3.4文本文件的輸入與輸出3.4.2從文本文件中輸入數(shù)據(jù)從文本文件中讀取數(shù)據(jù)的方法與輸出類似,其主要步驟如下:(1)ifstreaminFile;//ifstream類為輸入流類,用其定義了對象inFile。(2)inFile.open(“e:\\myData.txt”);//打開文本文件。(3)inFile>>…;//從文件中讀取數(shù)據(jù)賦給內(nèi)存變量。方法與cin相似。(4)inFile.close();//關(guān)閉打開的文件。
【例3-15】從文本文件中讀取學(xué)生學(xué)號、姓名和成績信息,統(tǒng)計(jì)輸出平均分。3.5函數(shù)基礎(chǔ)3.5.1函數(shù)定義與函數(shù)調(diào)用C++的函數(shù)分為系統(tǒng)庫函數(shù)和用戶自定義函數(shù),庫函數(shù)是由編譯系統(tǒng)提供的函數(shù),如:前面例程中使用的用于輸入輸出的函數(shù)、常見的數(shù)學(xué)函數(shù)等。庫函數(shù)的原型說明在特定的頭文件中,使用這些函數(shù)只需在程序前端包含相關(guān)的頭文件。用戶自定義函數(shù)是程序員根據(jù)需要而定義的函數(shù),面向?qū)ο蟪绦蛟O(shè)計(jì)的主要工作就是進(jìn)行對象和函數(shù)設(shè)計(jì)。3.5函數(shù)基礎(chǔ)1.函數(shù)定義(functiondefinition)函數(shù)的定義由兩個(gè)部分組成:函數(shù)頭和函數(shù)體,其語法格式如下:<返回類型><函數(shù)名>([<形參表>]){ <函數(shù)體>}<形參表>::=<數(shù)據(jù)類型><形參>[=<缺省值>],<形參表>3.5函數(shù)基礎(chǔ)其中:(1)<返回類型>是函數(shù)返回值的類型,又稱為函數(shù)的類型,它可以是基本數(shù)據(jù)類型,也可以是用戶已定義的一種數(shù)據(jù)類型。程序中return語句所返回的值的類型應(yīng)與函數(shù)頭中的返回類型兼容。一個(gè)函數(shù)也可以不返回任何類型,這種函數(shù)稱為無類型函數(shù),在函數(shù)定義時(shí)其返回類型部分為void無值類型。3.5函數(shù)基礎(chǔ)(2)<函數(shù)名>是一個(gè)有意義的標(biāo)識符,用戶通過函數(shù)名使用該函數(shù)。例如:
doublemin(doublex,doubley) { returnx<y?x:y; }該函數(shù)的函數(shù)名為min,功能為返回兩個(gè)數(shù)中的小者。函數(shù)的返回類型為double類型。3.5函數(shù)基礎(chǔ)(3)<形參表>是由參數(shù)項(xiàng)構(gòu)成,如果有多個(gè)參數(shù)項(xiàng)則它們之間用逗號分隔。每個(gè)參數(shù)項(xiàng)由一種已定義的數(shù)據(jù)類型和一個(gè)標(biāo)識符組成,該標(biāo)識符被稱為是函數(shù)的形式參數(shù),簡稱形參,形參前面的數(shù)據(jù)類型稱為該形參的類型。沒有形參的函數(shù)稱為無參函數(shù),此時(shí)函數(shù)的形參表部分為空白或void型。相應(yīng)地,形參表不空的函數(shù)稱為帶參函數(shù)。函數(shù)形參描述的是執(zhí)行該函數(shù)所需要傳遞的數(shù)據(jù),C++容許在函數(shù)定義時(shí)為形參指定缺省值(default)。缺省值的作用是在函數(shù)調(diào)用時(shí)如果用戶不給具體的實(shí)參,則用缺省值為形參賦值。缺省值的指定遵守“自右向左連續(xù)定義”的規(guī)則,即缺省值的定義是從形參的最右端開始,依次連續(xù)地向左賦缺省值,中間不能有沒賦值的項(xiàng)。
3.5函數(shù)基礎(chǔ)例如:
doublevolume(doublelength,doublewidth=10,doublehigh=10){……}//正確doublevolume(doublelength=10,doublewidth,doublehigh=10){……}//錯(cuò)誤!不連續(xù)doublevolume(doublelength=10,doublewidth,doublehigh){……}//錯(cuò)誤!自左開始3.5函數(shù)基礎(chǔ)(4)C++中的函數(shù)有被調(diào)用前,編譯器需要事先知道程序中存有被調(diào)函數(shù)。讓編譯器在調(diào)用前知道確實(shí)有被調(diào)函數(shù)的方法有二種:一種是在函數(shù)調(diào)用之前定義被調(diào)函數(shù),另一種是在函數(shù)調(diào)用前先聲明被調(diào)函數(shù)原型。例如:
//在調(diào)用前先定義//在調(diào)用前先聲明
intmax(intx,inty){……}intmax(intx,inty);//用分號結(jié)束
voidmain()voidmain(){…{…cout<<max(5,10);cout<<max(5,10);}}intmax(intx,inty){……}//后定義3.5函數(shù)基礎(chǔ)(5)<函數(shù)體>是實(shí)現(xiàn)該函數(shù)所具有的功能的語句序列,是算法的實(shí)現(xiàn)部分。其一般形式是前端為局部變量定義,中間是函數(shù)功能的實(shí)現(xiàn),最后是值返回(對于有返回類型的函數(shù))。2.函數(shù)調(diào)用(functioncall)函數(shù)調(diào)用暫停調(diào)用函數(shù)的執(zhí)行,轉(zhuǎn)而執(zhí)行被調(diào)函數(shù)。在函數(shù)調(diào)用時(shí),需要指定函數(shù)名并為形參給出相應(yīng)的實(shí)參。函數(shù)被調(diào)用時(shí),程序流程從調(diào)用點(diǎn)跳轉(zhuǎn)到被調(diào)函數(shù),執(zhí)行完被調(diào)函數(shù)后再返回到原處,繼續(xù)后面語句的執(zhí)行。函數(shù)調(diào)用的語法格式為:
<函數(shù)名>([<實(shí)參表>])
3.5函數(shù)基礎(chǔ)其中:(1)<函數(shù)名>是一個(gè)已定義的函數(shù)名稱。(2)<實(shí)參表>是由與函數(shù)形參類型相匹配的表達(dá)式組成,多個(gè)實(shí)參之間用逗號分隔。對于有缺省值的形參可以不提供實(shí)參,直接使用缺省值。(3)對于有返回值的函數(shù),在主調(diào)函數(shù)中一般將返回值賦給同質(zhì)的變量,保存函數(shù)運(yùn)行的結(jié)果。函數(shù)執(zhí)行結(jié)果不僅可以通過返回值帶回,還可以依靠實(shí)參傳遞,詳情見3.5.2節(jié)。【例3-16】函數(shù)調(diào)用及其機(jī)制解析示例。3.5函數(shù)基礎(chǔ)3.5.2函數(shù)的參數(shù)傳遞從前面的函數(shù)調(diào)用過程分析可知,函數(shù)在沒有被調(diào)用前,函數(shù)的形參并沒有占用內(nèi)存,形參的實(shí)際生成是函數(shù)調(diào)用后,是在保存自動變量時(shí)完成的。1.按值傳遞按值傳遞法簡稱為傳值法,其實(shí)參向形參傳遞數(shù)據(jù)的過程為:首先計(jì)算出實(shí)參表達(dá)式的值,再將對應(yīng)的形參變量壓入堆棧中,然后將求出的值保存至形參變量所獲得的存儲空間中,成為形參變量的初始值,供被調(diào)用函數(shù)執(zhí)行時(shí)使用。使用這種方式,被調(diào)用函數(shù)形參接收的是實(shí)參的值。如果實(shí)參是變量,則形參變量與實(shí)參變量是相互獨(dú)立的。因此,在被調(diào)用函數(shù)中對形參變量所做的修改不會影響實(shí)參變量,其仍為調(diào)用前的值。3.5函數(shù)基礎(chǔ)【例3-17】按值傳遞法示例。2.地址傳遞法地址傳遞法簡稱傳址法,這種方法在函數(shù)定義時(shí)需要將形參說明成指針,在函數(shù)調(diào)用時(shí)需要指定地址值形式的實(shí)參,形參接收的是指針類型的值。地址傳遞法與按值傳遞法的不同點(diǎn)在于,它把實(shí)參的存儲地址傳送給對應(yīng)的形參,從而使得形參指針和實(shí)參指針指向同一個(gè)地址。這種方法的特點(diǎn)是:被調(diào)函數(shù)中對形參指針?biāo)赶虻牡刂分袃?nèi)容的任何改變都會影響到實(shí)參,主調(diào)函數(shù)能通過實(shí)參帶回被調(diào)函數(shù)的執(zhí)行結(jié)果?!纠?-18】地址傳遞法示例。3.5函數(shù)基礎(chǔ)3.引用傳遞法引用傳遞法要求被調(diào)用函數(shù)的形參以引用為參數(shù),由于引用是另一個(gè)變量的別名,這樣在函數(shù)調(diào)用時(shí)實(shí)參變量與形參變量是內(nèi)存中同一個(gè)實(shí)體,因而對形參的任何操作都會影響到實(shí)參。引用傳遞法是C++新引入的參數(shù)傳遞方法,它即有按值傳遞法調(diào)用方式自然方便的特點(diǎn),又有按址傳遞法的直接與效率?!纠?-19】引用傳遞法示例。3.5函數(shù)基礎(chǔ)4.三種參數(shù)傳遞方法對比C++提供的三種參數(shù)傳遞方式,能滿足不同類型和格式數(shù)據(jù)的參數(shù)傳遞。下面從幾個(gè)方面對三種參數(shù)傳遞方式作簡要對比。傳遞效果按值傳遞在傳遞的時(shí)候,實(shí)參值被復(fù)制了一份傳遞給形參。在地址傳遞過程中,形參得到的是實(shí)參的地址,被調(diào)用函數(shù)是通過間接尋址方式訪問實(shí)參中的值。在引用傳遞過程中,被調(diào)用函數(shù)的形參在堆棧中開辟了內(nèi)存空間,存放的是由主調(diào)函數(shù)放進(jìn)來的實(shí)參變量的地址。被調(diào)用函數(shù)對形參的任何操作都被處理成間接尋址。如果想在調(diào)用函數(shù)中修改實(shí)參的值,使用按值傳遞是不能達(dá)到目的的,只能使用引用或地址傳遞。3.5函數(shù)基礎(chǔ)傳遞效率。對于像整型這樣的基本數(shù)據(jù)類型,從主調(diào)函數(shù)復(fù)制數(shù)據(jù)至堆棧與拷貝地址到堆棧的開銷相當(dāng)。然而對于結(jié)構(gòu)、類、數(shù)組這類用戶自定義數(shù)據(jù)類型,由于其自身的尺寸比較大,按值傳遞方式的內(nèi)存占用和執(zhí)行時(shí)間開銷都比較大。3) 執(zhí)行效率。執(zhí)行效率是指在被調(diào)用函數(shù)體內(nèi)執(zhí)行時(shí)的效率。在被調(diào)用函數(shù)執(zhí)行期間,傳值調(diào)用訪問形參是采用直接尋址方式,而地址傳遞和引用傳遞則是間接尋址方式,所以按值傳遞的執(zhí)行效率要高些。有些編譯器會對引用傳遞進(jìn)行優(yōu)化,也采用直接尋址方式。直接尋址的效率要高于間接尋址,不過訪問不是十分頻繁,則它們的執(zhí)行效率其實(shí)相差不大。3.5函數(shù)基礎(chǔ)4) 類型檢查。按值傳遞與引用傳遞在參數(shù)傳遞過程中都執(zhí)行強(qiáng)類型檢查,而指針傳遞的類型檢查較弱。利用編譯器的類型檢查,能減少程序的出錯(cuò)機(jī)率,增加代碼的健壯性。5) 參數(shù)檢查。參數(shù)檢查是保證輸入合法數(shù)據(jù)的有效途徑。按值傳遞和引用傳遞均不允許傳遞一個(gè)不存在的值,而使用指針就有可能,所以使用按值傳遞和引用傳遞的代碼更健壯。6) 靈活性。地址傳遞是最靈活,其不僅可以像按值傳遞和引用傳遞那樣傳遞一個(gè)特定類型的對象,還可以傳遞空指針。地址傳遞的靈活性利用得好能發(fā)揮其優(yōu)點(diǎn),使用不當(dāng)會導(dǎo)致程序崩潰。3.5函數(shù)基礎(chǔ)對于尺寸較大的實(shí)參用地址傳遞和引用傳遞不僅能減少系統(tǒng)的時(shí)間和空間開銷,同時(shí)還具有修改形參等同于修改實(shí)參的功能。然而在程序設(shè)計(jì)中有時(shí)需要禁止被調(diào)用函數(shù)修改主調(diào)函數(shù)中的實(shí)參,在C++中可用const關(guān)鍵字修飾指針和引用形參,達(dá)到在函數(shù)中禁止修改形參的目的。如果函數(shù)中出現(xiàn)修改形參變量的語句,編譯器將檢測出并報(bào)錯(cuò)?!纠?-20】三種參數(shù)傳遞方式對比示例3.5函數(shù)基礎(chǔ)3.5.3函數(shù)的返回值函數(shù)調(diào)用結(jié)束時(shí),可回傳一個(gè)數(shù)值或?qū)ο蠼o調(diào)用函數(shù)。C++中用于函數(shù)返回的語句的語法格式為:
return<表達(dá)式>;其中:(1)<表達(dá)式>的值即為函數(shù)的返回值,返回值的類型應(yīng)與函數(shù)定義相一致。(2)void類型函數(shù)在函數(shù)體中可以無reutrn語句,也可以書寫return;語句。3.5函數(shù)基礎(chǔ)主調(diào)函數(shù)在調(diào)用函數(shù)時(shí),系統(tǒng)將根據(jù)函數(shù)的返回類型說明在函數(shù)調(diào)用堆棧中先壓入一個(gè)數(shù)據(jù)類型為返回類型的臨時(shí)無名變量,之后再在無名變量之上壓入自動變量。當(dāng)函數(shù)返回時(shí),自動變量被彈出,占用的空間被回收,而返回的函數(shù)值被保存在臨時(shí)變量中,然后由主調(diào)函數(shù)中含函數(shù)調(diào)用的語句負(fù)責(zé)將臨時(shí)變量中的值賦給調(diào)用函數(shù)中的變量,再彈出調(diào)用堆棧中的臨時(shí)無名變量?!纠?-21】函數(shù)返回值使用示例。3.5函數(shù)基礎(chǔ)3.5.4函數(shù)重載
函數(shù)重載(overload)是C++引入的新特征,在C語言中相同功能的函數(shù)如果所處理的數(shù)據(jù)類型不同,則需要用不同的函數(shù)名加以區(qū)別,因?yàn)樵谕粋€(gè)程序中系統(tǒng)不允許有重名的函數(shù)。例如:max函數(shù)的功能為返回兩個(gè)元素中的最大者,而元素的數(shù)據(jù)類型可能有整型、實(shí)型或類類型,為此需要定義互不同名的函數(shù)分別實(shí)現(xiàn)相應(yīng)功能。C++的函數(shù)重載功能允許在同一作用域中定義幾個(gè)相同名稱的函數(shù),只要這幾個(gè)函數(shù)具有不同的函數(shù)簽名(singnature)。函數(shù)簽名是由函數(shù)的名稱及它的形參類型組成,因此函數(shù)重載的語法規(guī)則是函數(shù)名可以相同,但它們的簽名不能相同,即重載函數(shù)的形參類型、個(gè)數(shù)以及順序不能完全相同。3.5函數(shù)基礎(chǔ)編譯器又是怎樣區(qū)分重載函數(shù)的呢?是通過它們的簽名進(jìn)行區(qū)分的。在具有函數(shù)重載的程序中,系統(tǒng)能根據(jù)函數(shù)調(diào)用時(shí)所傳遞實(shí)參的個(gè)數(shù)和數(shù)據(jù)類型確定調(diào)用重載函數(shù)中的那一個(gè)函數(shù)。需要說明的是函數(shù)簽名不包括函數(shù)的返回類型,因此函數(shù)返回類型不同不能作為區(qū)別重載函數(shù)的依據(jù)。例如:intprint(intx);和voidprint(intx);是錯(cuò)誤的函數(shù)重載,編譯將報(bào)錯(cuò):無法重載僅按返回類型區(qū)分的函數(shù)?!纠?-22】函數(shù)重載示例。3.5函數(shù)基礎(chǔ)3.5.5內(nèi)聯(lián)函數(shù)在函數(shù)調(diào)用中,程序?qū)⒔?jīng)歷現(xiàn)場保護(hù)、保存自動變量、執(zhí)行被調(diào)用函數(shù)、釋放自動變量和恢復(fù)現(xiàn)場幾個(gè)過程,將占用計(jì)算機(jī)系統(tǒng)的時(shí)間和空間,增加運(yùn)行時(shí)的開銷。對于較大的函數(shù),這種開銷相對于函數(shù)在整個(gè)運(yùn)行過程中所占用的時(shí)空來說比例很小,然而對于較小的函數(shù)這種開銷則顯得有些“得不償失”。內(nèi)聯(lián)函數(shù)的聲明或定義的方法是在函數(shù)前加上關(guān)鍵字inline,定義格式如下:inline<返回類型><函數(shù)名>([<形參表>]){ <函數(shù)體>}3.5函數(shù)基礎(chǔ)通常inline限定符只用于那些非常小并且被頻繁使用的函數(shù),例如:用于獲取或設(shè)置變量值的函數(shù)。關(guān)鍵字inline可以同時(shí)用在函數(shù)聲明和定義處,也可只用在一處。如果函數(shù)定義在調(diào)用之后,則在函數(shù)聲明中必須加上inline,否則將被視為普通函數(shù)。下面程序段演示了內(nèi)聯(lián)函數(shù)的用法。3.5函數(shù)基礎(chǔ)inlineboolisNumber(charch){ returnch>='0'&&ch<='9'?true:false;}intmain(){ charinCh; cout<<"請從鍵盤輸入一個(gè)字符:"; cin>>inCh; cout<<"\""<<inCh<<"\""<<(isNumber(inCh)?"是":"不是")<<"數(shù)字字符!"<<endl; return0;}3.6內(nèi)存模型、作用域和生存期
3.6.1C++程序內(nèi)存模型操作系統(tǒng)把C++程序從硬盤加載至內(nèi)存執(zhí)行,程序運(yùn)行時(shí)在內(nèi)存中的布局如圖所示。其中每個(gè)區(qū)域所存儲的信息如下:
3.6內(nèi)存模型、作用域和生存期(1)程序代碼區(qū)。存放程序中所有函數(shù)的二進(jìn)制可執(zhí)行代碼。(2)全局?jǐn)?shù)據(jù)區(qū)。存放的是全局變量、靜態(tài)變量等信息。該部分內(nèi)存在分配時(shí),如果沒有賦值,則自動初始化為0。存放在全局?jǐn)?shù)據(jù)區(qū)中的變量直到程序結(jié)束后才由系統(tǒng)釋放。(3)自由存儲區(qū)。也稱堆區(qū),是由程序員管理的區(qū)域,C++中有專門的運(yùn)算符用于該區(qū)域空間的分配(new)和釋放(delete)。自由存儲區(qū)的變量如果沒有賦值,則其取值是隨機(jī)值。3.6內(nèi)存模型、作用域和生存期(4)棧區(qū)。存放的是函數(shù)的返回值、形參值和局部變量的值。在3.5.1節(jié)中已對函數(shù)調(diào)用過程進(jìn)行了詳解,其中的調(diào)用堆棧實(shí)際上就是程序的棧區(qū)。因在程序調(diào)試狀態(tài)下編譯器使用的是調(diào)用堆棧名稱,就沿用了該名稱,兩者本質(zhì)上是同一個(gè)內(nèi)容。調(diào)用棧是實(shí)現(xiàn)函數(shù)調(diào)用的一種有效手段。程序運(yùn)行時(shí),變量由于所存放區(qū)域的不同,導(dǎo)致它們之間在性質(zhì)和使用方法上存有許多差異。變量的存儲類型、可見性、作用域等一些概念都與存儲位置相關(guān),在本節(jié)的下面幾小節(jié)重點(diǎn)討論變量的相關(guān)特性。3.6內(nèi)存模型、作用域和生存期3.6.2全局變量和局部變量全局變量(globalvariable)是定義在所有的函數(shù)體之外的變量,其被存儲在全局?jǐn)?shù)據(jù)區(qū)。它們在程序開始運(yùn)行時(shí)分配存儲空間,在程序結(jié)束時(shí)釋放存儲空間,在程序的任何函數(shù)中都可以訪問全局變量。局部變量(LocalVariable)是在函數(shù)中定義的變量,由于形參相當(dāng)于函數(shù)中定義的變量,所以形參也是一種局部變量。局部變量被存放在程序的棧區(qū)。局部變量在每次函數(shù)調(diào)用時(shí)分配存儲空間,壓入棧成為棧頂元素;在每次函數(shù)返回時(shí)釋放存儲空間,從堆棧中彈出。局部變量的“局部”有兩層含義:一是函數(shù)中定義的局部變量不能被另一個(gè)函數(shù)使用;二是每次調(diào)用函數(shù)時(shí)局部變量都獲得存儲空間,結(jié)束時(shí)釋放空間。3.6內(nèi)存模型、作用域和生存期全局變量在任何函數(shù)中都可以訪問,所以在程序運(yùn)行過程中全局變量被讀寫的順序從源代碼中是看不出來的,源代碼的書寫順序并不能反映函數(shù)的調(diào)用順序。程序?qū)θ肿兞康淖x寫順序不正確是導(dǎo)致程序發(fā)生錯(cuò)誤的原因之一,并且如果代碼規(guī)模很大,這種錯(cuò)誤是很難查找。而對局部變量的訪問不僅局限在一個(gè)函數(shù)內(nèi)部,而且局限在一次函數(shù)調(diào)用之中,從函數(shù)的源代碼能看出訪問的先后順序是怎樣的,所以比較容易找到出現(xiàn)錯(cuò)誤的原因。因此,雖然全局變量用起來很方便,但一定要慎用,能用函數(shù)參數(shù)傳遞代替的就不要用全局變量。3.6內(nèi)存模型、作用域和生存期3.6.3作用域和可見性如果程序中全局變量和局部變量重名了會怎么樣呢?這個(gè)問題與標(biāo)識符的作用域和可見性相關(guān)。作用域(scope)就是標(biāo)識符的有效范圍??梢娦允侵笜?biāo)識符是否可以被引用,標(biāo)識符在其作用域內(nèi)是可見的。在C++中,作用域主要有:函數(shù)原型作用域、塊作用域(局部作用域)、文件作用域和類作用域。類作用域在后面章節(jié)介紹。3.6內(nèi)存模型、作用域和生存期1.函數(shù)原型作用域在函數(shù)原型聲明中,形參表中說明的標(biāo)識符的作用域僅限于函數(shù)聲明的括號中,稱函數(shù)原型作用域。形參標(biāo)識符與函數(shù)的定義和調(diào)用無關(guān),僅是形式上的標(biāo)識,因此可以省略。例如:intmax(int,int);//函數(shù)聲明時(shí)可以省略形參標(biāo)識符,只要有數(shù)據(jù)類型即可。2.塊作用域(局部作用域)塊就是用一對花括號引起來的程序段,定義在塊中的標(biāo)識符其作用域始于說明處,止于塊結(jié)尾處。具有塊作用域的變量的可見范圍是從變量說明處到塊尾。具有塊作用域的變量就是局部變量,其存儲位置在棧區(qū)。函數(shù)的形參具有塊作用域,其可見范圍是從說明處直到函數(shù)體結(jié)束。3.6內(nèi)存模型、作用域和生存期for循環(huán)語句的第一個(gè)表達(dá)式說明的循環(huán)控制變量具有塊作用域,其可見范圍在for語句之內(nèi)。在標(biāo)準(zhǔn)C++中,其作用域限于for語句之內(nèi)。VC++6.0對此有擴(kuò)展,允許在塊外使用循環(huán)控制變量,而VC++2010編譯器執(zhí)行C++標(biāo)準(zhǔn),其作用域被限制在塊內(nèi)。3.文件作用域定義在所有塊和類之外的標(biāo)識符具有文件作用域,文件作用域的可見范圍是從標(biāo)識符定義處到當(dāng)前源文件結(jié)束。在文件中定義的全局變量和函數(shù)都具體文件作用域。如果一個(gè)文件被另一個(gè)文件所包含,則源文
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 三方合作協(xié)議產(chǎn)生沖突
- 暑期二年級數(shù)學(xué)口算題
- 2024-2025學(xué)年九年級物理下冊第19章電磁波與信息時(shí)代章末小結(jié)與提升新版粵教滬版
- 重慶工商大學(xué)派斯學(xué)院《作物生物信息學(xué)及應(yīng)用》2023-2024學(xué)年第二學(xué)期期末試卷
- 2025年高精度數(shù)字電壓表合作協(xié)議書
- 山西衛(wèi)生健康職業(yè)學(xué)院《先進(jìn)制造技術(shù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 大連航運(yùn)職業(yè)技術(shù)學(xué)院《CAAD》2023-2024學(xué)年第二學(xué)期期末試卷
- 水庫建設(shè)安全管理與應(yīng)急預(yù)案
- 浙江舟山群島新區(qū)旅游與健康職業(yè)學(xué)院《現(xiàn)代產(chǎn)業(yè)經(jīng)濟(jì)學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 鄂爾多斯生態(tài)環(huán)境職業(yè)學(xué)院《醫(yī)學(xué)科研方法與論文撰寫1》2023-2024學(xué)年第二學(xué)期期末試卷
- 高三日語一輪復(fù)習(xí)助詞「と」的用法課件
- 物業(yè)管理服務(wù)房屋及公用設(shè)施維修養(yǎng)護(hù)方案
- 醫(yī)療器械法規(guī)培訓(xùn)
- 無子女離婚協(xié)議書范文百度網(wǎng)盤
- 2023中華護(hù)理學(xué)會團(tuán)體標(biāo)準(zhǔn)-注射相關(guān)感染預(yù)防與控制
- 一年級數(shù)學(xué)個(gè)位數(shù)加減法口算練習(xí)題大全(連加法-連減法-連加減法直接打印版)
- 《數(shù)字電子技術(shù)》課程說課課件
- 2024河南省鄭州市公安局輔警招聘2024人歷年高頻難、易錯(cuò)點(diǎn)500題模擬試題附帶答案詳解
- 五年級上冊數(shù)學(xué)試題試卷(8篇)
- 冀教版五年級下冊數(shù)學(xué)全冊教學(xué)課件
- 開發(fā)商物業(yè)維修合同
評論
0/150
提交評論