第2章 函數(shù)和作用_第1頁
第2章 函數(shù)和作用_第2頁
第2章 函數(shù)和作用_第3頁
第2章 函數(shù)和作用_第4頁
第2章 函數(shù)和作用_第5頁
已閱讀5頁,還剩58頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第2章函數(shù)的定義當(dāng)設(shè)計(jì)較大程序時(shí),通常需要用若干個(gè)模塊來實(shí)現(xiàn)較復(fù)雜的功能,而每一個(gè)模塊自成結(jié)構(gòu),用來解決一些子問題。這種能完成某一獨(dú)立功能的子程序模塊,在C++中成為函數(shù)??梢?,函數(shù)是實(shí)現(xiàn)模塊化程序的基本單位。事實(shí)上,函數(shù)還能體現(xiàn)代碼重用的思想,因?yàn)橐粋€(gè)函數(shù)可以在同一個(gè)程序中被多次調(diào)用或在多個(gè)程序中被調(diào)用。第2章函數(shù)和作用域2.1函數(shù)定義和調(diào)用2.2C++函數(shù)特性2.3作用域和存儲(chǔ)類型2.4名稱空間2.1函數(shù)定義和調(diào)用2.1.1函數(shù)定義C++的任何一個(gè)程序都可由一個(gè)主函數(shù)和若干個(gè)子函數(shù)組合而成。主函數(shù)可以調(diào)用子函數(shù),子函數(shù)還可以調(diào)用其他子函數(shù)。C++規(guī)定主函數(shù)名必須是main,而其他函數(shù)可以是庫函數(shù)或自定義函數(shù)。(1)主函數(shù)main不僅是程序的入口函數(shù),而且與其他函數(shù)相比較還有許多使用上的限制。例如,它不能被其他函數(shù)調(diào)用,不能用inline和static來說明等。(2)庫函數(shù),又稱標(biāo)準(zhǔn)函數(shù),是ANSI/ISOC++編譯系統(tǒng)已經(jīng)預(yù)先定義好的函數(shù),程序設(shè)計(jì)時(shí)可根據(jù)實(shí)際需要,直接使用這類函數(shù),而不必重新定義。調(diào)用時(shí),必須在程序中包含相應(yīng)的頭文件,并指明使用名稱空間std。2.1函數(shù)定義和調(diào)用

(3)自定義函數(shù)是用戶根據(jù)程序的需要,將某一個(gè)功能相對獨(dú)立的程序定義成的一個(gè)函數(shù),或?qū)⒔鉀Q某個(gè)問題的算法用一個(gè)函數(shù)來組織。

與變量的使用規(guī)則相同,在C++程序中一定要先說明和定義函數(shù),然后才能調(diào)用函數(shù)。C++中每一個(gè)函數(shù)的定義都是由4個(gè)部分組成的,即函數(shù)名、函數(shù)類型、形式參數(shù)表和函數(shù)體,其定義的格式如下:

<函數(shù)類型><函數(shù)名>(<形式參數(shù)表>){ <若干語句>}函數(shù)體2.1.1函數(shù)定義其中,函數(shù)名應(yīng)是一個(gè)合法有效的C++標(biāo)識(shí)符;函數(shù)頭的形式參數(shù)又簡稱為形參。參數(shù)表中的每一個(gè)形參都是由形參的數(shù)據(jù)類型和形參名來構(gòu)成,根據(jù)上述定義格式,可以編寫一個(gè)函數(shù)sum,如圖2.1所示,注意它們的書寫規(guī)范。intsum(intx,inty){intz=x+y;returnz;}對齊函數(shù)頭函數(shù)體縮進(jìn)函數(shù)類型函數(shù)名形參圖2.1定義一個(gè)函數(shù)sum2.1.1函數(shù)定義需要說明的是:(1)C/C++不允許在一個(gè)函數(shù)體中再定義函數(shù),即禁止嵌套定義,但允許嵌套調(diào)用。(2)函數(shù)體也可不含有任何語句,這樣的函數(shù)稱為空函數(shù),它僅為程序結(jié)構(gòu)而設(shè)定,本身沒有任何操作。(3)函數(shù)類型決定了函數(shù)所需要的返回值類型,它可以是除數(shù)組類型之外的任何有效的C++數(shù)據(jù)類型,包括引用、指針等。2.1.1函數(shù)定義(4)若函數(shù)類型為void時(shí),則表示該函數(shù)沒有返回值。但仍然可以在函數(shù)體中使用return語句“return

;”,此時(shí)可將“return;”語句理解為是函數(shù)體花括號(hào)“}”的作用,當(dāng)流程遇到函數(shù)體的“}”時(shí),函數(shù)調(diào)用結(jié)束,控制權(quán)返回給主調(diào)函數(shù)。例如: voidf1(inta) { if(a>10)

return; //return;一旦執(zhí)行,后面的語句不再被執(zhí)行

… }當(dāng)a>10條件滿足時(shí),“return;”語句將控制權(quán)返回給主調(diào)函數(shù)。2.1.2函數(shù)的調(diào)用和聲明1.函數(shù)的實(shí)參和形參定義一個(gè)函數(shù)就是為了以后的調(diào)用。調(diào)用函數(shù)時(shí),先寫函數(shù)名,然后緊跟括號(hào),括號(hào)里是實(shí)際調(diào)用該函數(shù)時(shí)所給定的參數(shù),稱為實(shí)際參數(shù),簡稱實(shí)參,并與形參相對應(yīng)。要注意形參和實(shí)參的區(qū)別:(1)從模塊概念來說,形參是函數(shù)的接口,是存在于函數(shù)內(nèi)部的變量。而實(shí)參是存在于函數(shù)外部的變量。它們不是同一個(gè)實(shí)體,也就是說,形參變量和實(shí)參變量所對應(yīng)的內(nèi)存空間不是同一個(gè)內(nèi)存空間。(2)按函數(shù)定義時(shí)所指定的形參類型,實(shí)參除變量外還可以是數(shù)值或表達(dá)式等,而形參只能是變量。(3)形參在函數(shù)調(diào)用之前是不存在的,只有在發(fā)生函數(shù)調(diào)用時(shí),函數(shù)中的形參才會(huì)被分配內(nèi)存空間,然后執(zhí)行函數(shù)體中的語句,而當(dāng)調(diào)用結(jié)束后,形參所占的內(nèi)存空間又會(huì)被釋放。2.1.2函數(shù)的調(diào)用和聲明2.函數(shù)的調(diào)用函數(shù)調(diào)用的一般格式為:

<函數(shù)名>(<實(shí)參表>);調(diào)用函數(shù)時(shí)要注意:實(shí)參與形參的個(gè)數(shù)應(yīng)相等,類型應(yīng)一致,且按順序?qū)?yīng),一一傳遞數(shù)據(jù)。

例如,下面的示例用來輸出一個(gè)三角形的圖案。2.1.2函數(shù)的調(diào)用和聲明

[例Ex_Call]函數(shù)的調(diào)用#include<iostream>usingnamespacestd;voidprintline(charch,intn){ for(inti=0;i<n;i++) cout<<ch; cout<<endl; }intmain(){ introw=5; for(inti=0;i<row;i++)

printline('*',i+1); //A return0; }

2.1.2函數(shù)的調(diào)用和聲明程序運(yùn)行的結(jié)果如下:代碼中,main函數(shù)的for循環(huán)語句共調(diào)用了5次printline函數(shù)(A句),每次調(diào)用時(shí)因?qū)崊+1值不斷改變,從而使函數(shù)printline打印出來的星號(hào)個(gè)數(shù)也隨之改變。

2.1.2函數(shù)的調(diào)用和聲明3.函數(shù)的聲明由于前面函數(shù)printline的定義代碼是放在main函數(shù)中調(diào)用語句A之前,因而A語句執(zhí)行不會(huì)有問題。但若將函數(shù)printline的定義代碼放在調(diào)用語句A之后,即函數(shù)定義在后,而調(diào)用在前,就會(huì)產(chǎn)生“printline標(biāo)識(shí)符未定義”的編譯錯(cuò)誤。此時(shí)必須在調(diào)用前進(jìn)行函數(shù)聲明。2.1.2函數(shù)的聲明聲明一個(gè)函數(shù)按下列格式進(jìn)行:

<函數(shù)類型><函數(shù)名>(<形參表>);可見,函數(shù)聲明的格式是在函數(shù)頭的后面加上分號(hào)“;”。但要注意,函數(shù)聲明的內(nèi)容應(yīng)和函數(shù)的定義應(yīng)相同。例如,對于前面sum函數(shù)和最后一個(gè)printline函數(shù)可有如下聲明: intsum(intx,inty); voidprintline(charch,intn);2.1.3值傳遞函數(shù)的調(diào)用實(shí)質(zhì)上就是參數(shù)傳遞,在C++中,函數(shù)的參數(shù)傳遞有兩種方式,一是按值傳遞,二是地址傳遞或引用傳遞。這里先來說明按值傳遞的參數(shù)傳遞方法,地址傳遞或引用傳遞在以后來討論。當(dāng)函數(shù)的形參定義成一般變量時(shí),如前面printline和sum函數(shù)的形參都是一般變量,此時(shí)函數(shù)的參數(shù)傳遞就是按值傳遞方式,簡稱值傳遞,是指當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),C++根據(jù)實(shí)參和形參的對應(yīng)關(guān)系將實(shí)際參數(shù)的值一一傳遞給形參,供函數(shù)執(zhí)行時(shí)使用。2.1.3值傳遞值傳遞的特點(diǎn)是:(1)若實(shí)參指定是一般變量,則傳遞的是實(shí)參變量的值而不是實(shí)參變量的地址。(2)在執(zhí)行函數(shù)代碼時(shí),由于對實(shí)參數(shù)據(jù)的操作最終是在形參的內(nèi)存空間中進(jìn)行,因此形參值的改變只是改變了形參的內(nèi)存空間存儲(chǔ)的值,而不會(huì)改變實(shí)參變量所對應(yīng)的內(nèi)存空間的值。也就是說,即使形參的值在函數(shù)中發(fā)生了變化,函數(shù)調(diào)用結(jié)束后,實(shí)參的值不會(huì)受到影響。例如:2.1.3值傳遞[例Ex_SwapValue]交換函數(shù)兩個(gè)參數(shù)的值。#include<iostream>usingnamespacestd;voidswap(floatx,floaty);

//函數(shù)原型說明intmain(){ floata=20,b=40; cout<<"a="<<a<<",b="<<b<<"\n";

swap(a,b);

//函數(shù)調(diào)用 cout<<"a="<<a<<",b="<<b<<"\n"; return0;}voidswap(floatx,floaty)

//函數(shù)定義{ floattemp; temp=x;x=y;y=temp; cout<<"x="<<x<<",y="<<y<<"\n";}2.1.3值傳遞程序的運(yùn)行結(jié)果為:可以看出,雖然函數(shù)swap中交換了兩個(gè)形參x和y的值,但交換的結(jié)果并不能改變實(shí)參的值,所以調(diào)用該函數(shù)后,變量a和b的值仍然為原來的值。2.1.4函數(shù)的默認(rèn)形參值在C++中,允許在函數(shù)的聲明或定義時(shí)給一個(gè)或多個(gè)參數(shù)指定默認(rèn)值。這樣在調(diào)用時(shí),可以不給出實(shí)際參數(shù),而按指定的默認(rèn)值進(jìn)行工作。例如:

voiddelay(intloops=1000)//函數(shù)定義,1000為形參loops的默認(rèn)值 { if(0==loops)return; for(inti=0;i<loops;i++);//空循環(huán),起延時(shí)作用 }2.1.4函數(shù)的默認(rèn)形參值這樣,當(dāng)有調(diào)用delay(); //和delay(1000)等效程序就會(huì)自動(dòng)將loops當(dāng)作成1000的默認(rèn)值來進(jìn)行處理。當(dāng)然,也可在函數(shù)調(diào)用時(shí)指定相應(yīng)的實(shí)際的參數(shù)值,例如:delay(2000); //形參loops的值為20002.1.4函數(shù)的默認(rèn)形參值在設(shè)置函數(shù)的默認(rèn)形參值時(shí)要注意:(1)當(dāng)函數(shù)既有原型聲明又有定義時(shí),默認(rèn)參數(shù)只能在原型聲明中指定,而不能在函數(shù)定義中指定。例如: voiddelay(intloops); //函數(shù)原型聲明 //… voiddelay(intloops=1000)//錯(cuò)誤:此時(shí)不能函數(shù)定義中指定默認(rèn)參數(shù) { //… }2.1.4函數(shù)的默認(rèn)形參值(2)當(dāng)一個(gè)函數(shù)中需要有多個(gè)默認(rèn)參數(shù)時(shí),則形參分布中,默認(rèn)參數(shù)應(yīng)嚴(yán)格從右到左逐次定義和指定,中間不能跳開。例如: voiddisplay(inta,intb,intc=3); //合法 voiddisplay(inta,intb=2,intc=3);//合法 voiddisplay(inta=1,intb=2,intc=3); //合法:可以對所有的參數(shù)設(shè)置默認(rèn)值 voiddisplay(inta,intb=2,intc);//錯(cuò)誤:默認(rèn)參數(shù)應(yīng)從最右邊開始 voiddisplay(inta=1,intb=2,intc); //錯(cuò)誤:默認(rèn)參數(shù)應(yīng)從最右邊開始 voiddisplay(inta=1,intb,intc=3);//錯(cuò)誤:多個(gè)默認(rèn)參數(shù)中間不能有非默認(rèn)參數(shù)2.1.4函數(shù)的默認(rèn)形參值(3)當(dāng)帶有默認(rèn)參數(shù)的函數(shù)調(diào)用時(shí),系統(tǒng)按從左到右的順序?qū)?shí)參與形參結(jié)合。當(dāng)實(shí)參的數(shù)目不足時(shí),系統(tǒng)將按同樣的順序用聲明或定義中的默認(rèn)值來補(bǔ)齊所缺少的參數(shù)。例如:2.1.4函數(shù)的默認(rèn)形參值[例Ex_Default]在函數(shù)定義中設(shè)置多個(gè)默認(rèn)參數(shù)#include<iostream>usingnamespacestd;voiddisplay(inta,intb=2,intc=3)//在函數(shù)定義中設(shè)置默認(rèn)參數(shù){ cout<<"a="<<a<<",b="<<b<<",c="<<c<<"\n";}intmain(){

display(1); display(1,5); display(1,7,9); return0;}程序的運(yùn)行結(jié)果為:2.2C++函數(shù)特性

在C++中,函數(shù)還有:嵌套調(diào)用、重載、內(nèi)聯(lián)調(diào)用以及遞歸調(diào)用等特性,相應(yīng)的函數(shù)被稱為嵌套函數(shù)、重載函數(shù)、內(nèi)聯(lián)函數(shù)和遞歸調(diào)用等。2.2C++函數(shù)特性

函數(shù)重載(overloaded)是C++對C的擴(kuò)展,它允許多個(gè)同名的函數(shù)存在,但同名的各個(gè)函數(shù)的形參必須有區(qū)別:要么形參的個(gè)數(shù)不同;要么形參的個(gè)數(shù)相同,但參數(shù)類型有所不同。優(yōu)點(diǎn):代碼中使用函數(shù)的重載,不僅方便函數(shù)名的記憶,而且更主要的是完善了同一個(gè)函數(shù)的代碼功能,給調(diào)用帶來了許多方便。下例程序中即是各種形式的sum函數(shù)都稱為sum的重載函數(shù)。

2.2C++函數(shù)特性【例Ex_OverLoad】編程求兩個(gè)或三個(gè)操作數(shù)之和#include<iostream.h>

intsum(intx,inty);intsum(intx,inty,intz);doublesum(doublex,doubley);doublesum(doublex,doubley,doublez);

//聲明4個(gè)同名的函數(shù)intmain(){ cout<<sum(2,5)<<endl; //結(jié)果為7 cout<<sum(2,5,7)<<endl; //結(jié)果為14 cout<<sum(1.2,5.0,7.5)<<endl;//結(jié)果為13.7 return0;}程序的運(yùn)行結(jié)果為:

2.2C++函數(shù)特性intsum(intx,inty){ returnx+y; }intsum(intx,inty,intz){ returnx+y+z; }doublesum(doublex,doubley){ returnx+y; }doublesum(doublex,doubley,doublez){ returnx+y+z; }程序運(yùn)行結(jié)果如下:2.2C++函數(shù)特性需要說明的是:(1)重載函數(shù)必須具有不同的參數(shù)個(gè)數(shù)或不同的參數(shù)類型,若只有返回值的類型不同是不行的。例如:voidfun(inta,intb); intfun(inta,intb);是錯(cuò)誤的。因?yàn)槿绻泻瘮?shù)調(diào)用fun(2,3)時(shí),編譯器無法準(zhǔn)確地確定應(yīng)調(diào)用哪一個(gè)函數(shù)。(2)當(dāng)函數(shù)的重載帶有默認(rèn)參數(shù)時(shí),也要應(yīng)該注意避免上述的二義性情況。例如:intfun(inta,intb=0);intfun(inta);是錯(cuò)誤的。因?yàn)槿绻泻瘮?shù)調(diào)用fun(2)時(shí),編譯器也是無法準(zhǔn)確地確定應(yīng)調(diào)用哪一個(gè)函數(shù)。2.2.2函數(shù)嵌套調(diào)用C++允許在函數(shù)中再調(diào)用其他函數(shù),這種調(diào)用稱為函數(shù)的嵌套調(diào)用。

[例Ex_Root]函數(shù)嵌套調(diào)用:求解一元二次方程的根。(見書35頁)本例main函數(shù)中調(diào)用了root函數(shù),root函數(shù)中又調(diào)用了sdelta和print函數(shù),而sdelta函數(shù)還調(diào)用了cmath頭文件定義的庫函數(shù)sqrt(求平方根)和fabs(求浮點(diǎn)數(shù)的絕對值)。它們的調(diào)用關(guān)系如圖2.2所示。main函數(shù)root函數(shù)sdelta函數(shù)fabs庫函數(shù)print函數(shù)sqrt庫函數(shù)圖2.2例Ex_Root中的各函數(shù)調(diào)用的關(guān)系2.2.3遞歸函數(shù)C++允許在調(diào)用一個(gè)函數(shù)的過程中出現(xiàn)直接地或間接地調(diào)用函數(shù)本身,這種情況稱為函數(shù)的遞歸調(diào)用。遞歸(Recursion)是一種常用的程序方法(算法),相應(yīng)的函數(shù)稱為遞歸函數(shù)例如,用遞歸函數(shù)編程求n的階乘n!。n!=n*(n-1)*(n-2)*...*2*1。它也可用下式表示:由于n!和(n-1)!都是同一個(gè)問題的求解,因此可將n!用遞歸函數(shù)longfactorial(intn)來描述,程序代碼如下:

2.2.3遞歸函數(shù)[例Ex_Factorial]編程求n的階乘n!#include<iostream>usingnamespacestd;longfactorial(intn);intmain(){ cout<<factorial(4)<<endl; //結(jié)果為24 return0;}

longfactorial(intn){ longresult=0; if(0==n) result=1; else result=n*factorial(n-1); //進(jìn)行自身調(diào)用 returnresult;}1.5.4函數(shù)的遞歸調(diào)用程序運(yùn)行結(jié)果如下:24下面來分析main函數(shù)中“factorial(4);”語句的執(zhí)行過程,這一過程用圖1.8來表示:見書(p36)2.2.4內(nèi)聯(lián)函數(shù)在程序的執(zhí)行過程中,調(diào)用函數(shù)時(shí)首先需要保存主調(diào)函數(shù)的現(xiàn)場和返回地址,然后程序轉(zhuǎn)移到被調(diào)函數(shù)的起始地址繼續(xù)執(zhí)行。被調(diào)函數(shù)執(zhí)行結(jié)束后,先恢復(fù)主調(diào)函數(shù)的現(xiàn)場,取出返回地址,并將返回值賦給函數(shù)調(diào)用本身,最后在返回地址處開始繼續(xù)執(zhí)行。當(dāng)函數(shù)體比較小且執(zhí)行的功能比較簡單時(shí),這種函數(shù)調(diào)用方式的系統(tǒng)開銷相對較大。

2.2.4內(nèi)聯(lián)函數(shù)為了解決這一問題,C++引入了內(nèi)聯(lián)函數(shù)的概念,它把函數(shù)體的代碼直接插入到調(diào)用處,將調(diào)用函數(shù)的方式改為順序執(zhí)行、直接插入的程序代碼,這樣可以減少程序的執(zhí)行時(shí)間,但同時(shí)增加了代碼的實(shí)際長度。內(nèi)聯(lián)函數(shù)的使用方法與一般函數(shù)相同,只是在內(nèi)聯(lián)函數(shù)定義時(shí),需在函數(shù)的類型前面加上inline關(guān)鍵字。例如:2.2.4內(nèi)聯(lián)函數(shù)[例Ex_Inline]用內(nèi)聯(lián)函數(shù)實(shí)現(xiàn)求兩個(gè)實(shí)數(shù)的最大值#include<iostream>usingnamespacestd;

inlinefloatfmax(floatx,floaty){ returnx>y?x:y; }intmain(){ floata; a=fmax(5,10); //A cout<<"最大的數(shù)為:"<<a<<"\n"; return0;}這樣,當(dāng)程序編譯時(shí),A語句變成了:a=5>10?5:10;2.2.4內(nèi)聯(lián)函數(shù)在使用內(nèi)聯(lián)函數(shù)時(shí),還需要注意的是:(1)內(nèi)聯(lián)函數(shù)也要遵循定義在前,調(diào)用在后的原則。形參與實(shí)參之間的關(guān)系與一般函數(shù)相同。(2)關(guān)鍵字inline必須放在函數(shù)定義體前才是內(nèi)聯(lián)函數(shù),僅在函數(shù)聲明時(shí)使用inline,不能定義內(nèi)聯(lián)函數(shù)。(3)在C++中,需要定義成的內(nèi)聯(lián)函數(shù)不能含有循環(huán)、switch和復(fù)雜嵌套的if語句。(4)遞歸函數(shù)不能被用來做內(nèi)聯(lián)函數(shù)??傊?,內(nèi)聯(lián)函數(shù)一般是比較小的、經(jīng)常被調(diào)用的、大多可在一行寫完的函數(shù)。2.3作用域和存儲(chǔ)類型

2.3.1作用域作用域又稱作用范圍,是指程序中標(biāo)識(shí)符(變量名、函數(shù)名、數(shù)組名、類名、對象名等)的有效范圍。一個(gè)標(biāo)識(shí)符是否可以被引用,稱之為標(biāo)識(shí)符的可見性。在一個(gè)C++程序項(xiàng)目中,一個(gè)標(biāo)識(shí)符只能在聲明或定義它的范圍內(nèi)可見,在此之外是不可見的。根據(jù)標(biāo)識(shí)符的作用范圍,可將其作用域分為5種:函數(shù)原型作用域、函數(shù)作用域、塊作用域、類作用域和文件作用域。其中,類作用域?qū)⒃谝院蠼榻B,這里介紹其他幾種。2.3作用域和存儲(chǔ)類型1.函數(shù)原型作用域函數(shù)原型作用域指的是在聲明函數(shù)原型所指定的參數(shù)標(biāo)識(shí)符的作用范圍。這個(gè)作用范圍是在函數(shù)原型聲明中的左、右圓括號(hào)之間。

正因?yàn)槿绱?,在函?shù)原型中聲明的標(biāo)識(shí)符可以與函數(shù)定義中說明的標(biāo)識(shí)符名稱不同。由于所聲明的標(biāo)識(shí)符與該函數(shù)的定義及調(diào)用無關(guān),所以可以在函數(shù)原型聲明中只作參數(shù)的類型聲明,而省略參數(shù)名。例如: doublemax(doublex,doubley); 和 doublemax(double,double); 是等價(jià)的。2.3.1作用域2塊作用域塊語句就是由“{”和“}”組成的(復(fù)合語句)。在塊中聲明的標(biāo)識(shí)符,其作用域從聲明處開始,一直到結(jié)束塊的花括號(hào)為止。塊作用域也稱作局部作用域,具有塊作用域的變量是局部變量。例如:voidfun(void){a的作用域b的作用域 inta; //a的作用域起始處 cin>>a; if(a<0){ a=-a;

intb; //b的作用域起始處 … } //b的作用域終止處} //a的作用域終止處2.3.1作用域需要說明的是:當(dāng)標(biāo)識(shí)符的作用域完全相同時(shí),不允許出現(xiàn)相同的標(biāo)識(shí)符名。而當(dāng)標(biāo)識(shí)符具有不同的作用域時(shí),卻允許標(biāo)識(shí)符同名。例如: voidfun(void)塊A塊B { //塊A開始 inti; … { //塊B開始 inti;

i=100; … } //塊B結(jié)束 }

//塊A結(jié)束代碼中,在A和B塊中都聲明了變量i,這是允許的,因?yàn)閴KA和塊B不是同一個(gè)作用域。塊A塊B2.3.1作用域但同時(shí)出現(xiàn)另外一個(gè)問題,語句“i=100;”中的i是使用A塊中的變量i還是使用B中的變量i?C++規(guī)定在這種作用域嵌套的情況下,如果內(nèi)層(塊B)和外層(塊A)作用域聲明了同名的標(biāo)識(shí)符,那么在外層作用域中聲明的標(biāo)識(shí)符對于該內(nèi)層作用域是不可見的。也就是說,在塊B聲明的變量i與塊A聲明的變量i無關(guān),當(dāng)塊B中的i=100時(shí),不會(huì)影響塊A中變量i的值。2.3.1作用域4.文件作用域在所有函數(shù)外定義的標(biāo)識(shí)符稱為全局標(biāo)識(shí)符。全局標(biāo)識(shí)符的作用域是文件作用域。它從聲明之處開始,直到文件結(jié)束一直是可見的。具有文件作用域的變量和常量稱為全局變量和全局常量。例如:

constfloatPI=3.14; //全局常量PI,其作用域從此開始 inta; //全局變量a,其作用域從此開始 voidmain() { //… } voidfunA(intx) { //… }2.3.1作用域5函數(shù)作用域若函數(shù)定義在后,調(diào)用在前,必須進(jìn)行函數(shù)原型聲明。若函數(shù)定義在前,調(diào)用在后,函數(shù)定義包含了函數(shù)的原型聲明。一旦聲明了函數(shù)原型,函數(shù)標(biāo)識(shí)符的作用域是從聲明或定義之處開始到源程序文件結(jié)束。例如:

voidfunA(intx);//函數(shù)funA的作用域從此開始到文件結(jié)束

voidfunB() //函數(shù)funB的作用域從此開始到文件結(jié)束

{ //… } voidmain() { //… } voidfunA(intx) { //… }2.3.3存儲(chǔ)類型存儲(chǔ)類型是針對變量而言的,它規(guī)定了變量的生存期。無論是全局變量還是局部變量,編譯系統(tǒng)往往根據(jù)其存儲(chǔ)方式定義、分配和釋放相應(yīng)的內(nèi)存空間。變量的存儲(chǔ)類型反映了變量在哪開辟內(nèi)存空間以及占用內(nèi)存空間的有效期限。在C++中,變量有4種存儲(chǔ)類型:自動(dòng)類型、靜態(tài)類型、寄存器類型和外部類型,這些存儲(chǔ)類型是在變量定義時(shí)來指定的.其一般格式如下:<存儲(chǔ)類型><數(shù)據(jù)類型><變量名表>;

2.3.3存儲(chǔ)類型1.自動(dòng)存儲(chǔ)類型一般說來,用自動(dòng)存儲(chǔ)類型聲明的變量都是限制在某個(gè)程序范圍內(nèi)使用,即為局部變量。從系統(tǒng)角度來說,自動(dòng)存儲(chǔ)類型變量是采用動(dòng)態(tài)分配方式在棧區(qū)中來分配內(nèi)存空間。因此,當(dāng)程序執(zhí)行到超出該變量的作用域時(shí),就釋放它所占用的內(nèi)存空間,其值也隨之消失了。在C++語言中,聲明一個(gè)自動(dòng)存儲(chǔ)類型的變量是在變量類型前加上關(guān)鍵字auto,例如:

auto inti;2.3.3存儲(chǔ)類型若自動(dòng)存儲(chǔ)類型的變量是在函數(shù)內(nèi)或語句塊中聲明的,則可省略關(guān)鍵字auto,例如: voidfun() {

inti; //省略auto //… }2.3.3存儲(chǔ)類型2寄存器類型使用關(guān)鍵字register聲明寄存器類型的變量的目的是將所聲明的變量放入寄存器內(nèi),從而加快程序的運(yùn)行速度。例如:

registerinti; //聲明寄存器類型變量但有時(shí),在使用register聲明時(shí),若系統(tǒng)寄存器已經(jīng)被其他數(shù)據(jù)占據(jù)時(shí),寄存器類型的變量就會(huì)自動(dòng)當(dāng)作auto變量。2.3.3存儲(chǔ)類型2.靜態(tài)類型從變量的生存期來說,一個(gè)變量的存儲(chǔ)空間可以是永久的,即在程序運(yùn)行期間該變量一直存在,如全局變量。也可以是臨時(shí)的,如局部變量,當(dāng)流程執(zhí)行到它的說明語句時(shí),系統(tǒng)為其在棧區(qū)中動(dòng)態(tài)分配一個(gè)臨時(shí)的內(nèi)存空間,并在它的作用域中有效,一旦流程超出該變量的作用域時(shí),就釋放它所占用的內(nèi)存空間,其值也隨之消失。

2.3.3存儲(chǔ)類型但是,若在聲明局部變量類型前面加上關(guān)鍵字static,則將其定義成了一個(gè)靜態(tài)類型的變量。這樣的變量雖具有局部變量的作用域,但由于它是用靜態(tài)分配方式在靜態(tài)數(shù)據(jù)區(qū)中來分配內(nèi)存空間。因此,在這種方式下,只要程序還在繼續(xù)執(zhí)行,靜態(tài)類型變量的值就一直有效,不會(huì)隨它所在的函數(shù)或語句塊的結(jié)束而消失。簡單地說,靜態(tài)類型的局部變量雖具有局部變量的作用域,但卻有全局變量的生存期。2.3.3存儲(chǔ)類型[例Ex_Static]使用靜態(tài)類型的局部變量#include<iostream>usingnamespacestd;voidcount(){ inti=0;

staticintj=0; //靜態(tài)類型 i++; j++; cout<<"i="<<i<<",j="<<j<<"\n";}intmain(){ count(); count(); return0;}

2.3.3存儲(chǔ)類型程序中,當(dāng)?shù)?次調(diào)用函數(shù)count時(shí),由于變量j是靜態(tài)類型,因此其初值設(shè)為0后不再進(jìn)行初始化,執(zhí)行j++后,j值為1,并一直有效。第2次調(diào)用函數(shù)count時(shí),由于j已分配內(nèi)存且進(jìn)行過初始化,因此語句“staticintj=0;”被跳過,執(zhí)行j++后,j值為2。故程序運(yùn)行結(jié)果為:

2.3.3存儲(chǔ)類型需要說明的是,靜態(tài)類型的局部變量只在第一次執(zhí)行時(shí)進(jìn)行初始化,正因?yàn)槿绱耍诼暶黛o態(tài)類型變量時(shí)一定要指定其初值,若沒有指定,編譯器還會(huì)將其初值置為0。2.4名稱空間

隨著程序代碼的增多,名稱相互沖突的可能性也將增加。尤其是在程序中使用多家廠商提供的類庫時(shí),標(biāo)示符名稱的沖突可能性更高。例如,兩個(gè)類庫中可能都定義了名為List、Tree和Node的類,但定義的含義和方式不兼容;或是兩個(gè)類庫定義基個(gè)程序本相同,但兩個(gè)類庫同時(shí)包含在一個(gè)程序中,會(huì)出現(xiàn)標(biāo)示符重復(fù)定義的錯(cuò)誤。這些問題統(tǒng)稱為名稱空間問題。解決這些名稱空間問題的方法是使用C++新的名稱空間特性,通過名稱空間的作用域機(jī)制來解決。2.4名稱空間2.4.1名稱空間的定義在C++中,定義一個(gè)名稱空間的格式如下:其中,namespace是C++關(guān)鍵字,標(biāo)識(shí)符用作名稱空間的名稱,屬于該名稱空間體中的變量、函數(shù)、結(jié)構(gòu)、枚舉、聯(lián)合以及以后要討論的類等都可以認(rèn)為是該名稱空間的成員。namespace[標(biāo)識(shí)符]{成員;…}體2.4.1名稱空間的定義需要說明的是:同一個(gè)文件中,可以允許定義多個(gè)名稱空間。一旦定義名稱空間后,標(biāo)識(shí)符就標(biāo)識(shí)名稱空間體的那個(gè)區(qū)域。例如:

usingnamespacestd; namespaceDING1 { charname[]="thisisinDING1region!"; voidshowname(void) {

cout<<name<<endl; } }2.4.1名稱空間的定義 namespaceDING2 { charname[]="thisisinDING2region!"; voidshowname(void) { cout<<name<<endl; } }

盡管名稱空間DIN1和DING2中定義的成員名都相同,但它們由于分屬不同的名稱區(qū)域,因而是合法的。此后,在引用各自的成員時(shí)就可使用域作用運(yùn)算符來指定DIN1或DING2來標(biāo)識(shí)各自所在的名稱區(qū)域。2.4.1名稱空間的定義(2)名稱空間中的函數(shù)、類等可稱為成員函數(shù)和成員類。成員函數(shù)的原型必須在名稱空間體中聲明,而此時(shí)的函數(shù)定義稱為函數(shù)的實(shí)現(xiàn),可以在體內(nèi)完成,也可在體外完成。例如,前面名稱空間DING1和DING2的成員函數(shù)showname的聲明和定義都是在體內(nèi)一起完成的,若將成員函數(shù)showname的實(shí)現(xiàn)放在體外完成,則必須用域作用符“::”指明其所屬名稱空間。(下頁)2.4.1名稱空間的定義例如: usingnamespacestd;

namespaceDING1 { charname[]="thisisinDING1region!"; voidshow

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(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

提交評論