




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
關(guān)于函數(shù)和作用域第1頁(yè),共52頁(yè),2023年,2月20日,星期三2.1函數(shù)定義和調(diào)用C++的任何一個(gè)程序都可由一個(gè)主函數(shù)和若干個(gè)子函數(shù)組合而成。主函數(shù)可以調(diào)用子函數(shù),子函數(shù)還可以調(diào)用其他子函數(shù)。C++規(guī)定主函數(shù)名必須是main,而其他函數(shù)可以是庫(kù)函數(shù)或自定義函數(shù)。主函數(shù)main不僅是程序的入口函數(shù),而且與其他函數(shù)相比較還有許多使用上的限制。例如,它不能被其他函數(shù)調(diào)用,不能用inline和static來(lái)說(shuō)明等。ANSI/ISOC++還規(guī)定主函數(shù)main的函數(shù)類型必須是int,以保證程序的移植性。庫(kù)函數(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。自定義函數(shù)是用戶根據(jù)程序的需要,將某一個(gè)功能相對(duì)獨(dú)立的程序定義成的一個(gè)函數(shù),或?qū)⒔鉀Q某個(gè)問(wèn)題的算法用一個(gè)函數(shù)來(lái)組織。與變量的使用規(guī)則相同,在C++程序中一定要先說(shuō)明和定義函數(shù),然后才能調(diào)用函數(shù)。C++中每一個(gè)函數(shù)的定義都是由4個(gè)部分組成的,即函數(shù)名、函數(shù)類型、形式參數(shù)表和函數(shù)體,其定義的格式如下:2.1.1函數(shù)定義<函數(shù)類型><函數(shù)名>(<形式參數(shù)表>){ <若干語(yǔ)句>}函數(shù)體第2頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.1函數(shù)定義其中,函數(shù)名應(yīng)是一個(gè)合法有效的C++標(biāo)識(shí)符;函數(shù)頭的形式參數(shù)又簡(jiǎn)稱為形參。參數(shù)表中的每一個(gè)形參都是由形參的數(shù)據(jù)類型和形參名來(lái)構(gòu)成,形數(shù)個(gè)數(shù)可以是0,表示沒有形式參數(shù),但圓括號(hào)不能省略,也可以是1個(gè)或多個(gè)形參,但多個(gè)形參間要用逗號(hào)分隔。由花括號(hào)構(gòu)成的是函數(shù)的函數(shù)體部分,它可以有若干條語(yǔ)句,用于實(shí)現(xiàn)這個(gè)函數(shù)執(zhí)行的功能。根據(jù)上述定義格式,可以編寫一個(gè)函數(shù)sum,如圖2.1所示,注意它們的書寫規(guī)范。intsum(intx,inty){intz=x+y;returnz;}對(duì)齊函數(shù)頭函數(shù)體縮進(jìn)函數(shù)類型函數(shù)名形參圖2.1定義一個(gè)函數(shù)sum第3頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.1函數(shù)定義需要說(shuō)明的是:(1)C/C++不允許在一個(gè)函數(shù)體中再定義函數(shù),即禁止嵌套定義,但允許嵌套調(diào)用。(2)函數(shù)體也可不含有任何語(yǔ)句,這樣的函數(shù)稱為空函數(shù),它僅為程序結(jié)構(gòu)而設(shè)定,本身沒有任何操作。(3)函數(shù)類型決定了函數(shù)所需要的返回值類型,它可以是除數(shù)組類型之外的任何有效的C++數(shù)據(jù)類型,包括引用、指針等。一旦指定了函數(shù)類型,則須在函數(shù)體中通過(guò)return語(yǔ)句來(lái)指定函數(shù)的返回值,且返回值的類型應(yīng)與函數(shù)類型相同,若返回值的類型與函數(shù)類型不相同,則程序按類型自動(dòng)轉(zhuǎn)換方式轉(zhuǎn)換成函數(shù)的類型或?qū)eturn后面的表達(dá)式進(jìn)行強(qiáng)制轉(zhuǎn)換。(4)若函數(shù)類型為void時(shí),則表示該函數(shù)沒有返回值。但仍然可以在函數(shù)體中使用return語(yǔ)句“return
;”,此時(shí)可將“return;”語(yǔ)句理解為是函數(shù)體花括號(hào)“}”的作用,當(dāng)流程遇到函數(shù)體的“}”時(shí),函數(shù)調(diào)用結(jié)束,控制權(quán)返回給主調(diào)函數(shù)。例如: voidf1(inta) { if(a>10) return; //return;一旦執(zhí)行,后面的語(yǔ)句不再被執(zhí)行
… }當(dāng)a>10條件滿足時(shí),“return;”語(yǔ)句將控制權(quán)返回給主調(diào)函數(shù)。第4頁(yè),共52頁(yè),2023年,2月20日,星期三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ù),簡(jiǎn)稱實(shí)參,并與形參相對(duì)應(yīng)。要注意形參和實(shí)參的區(qū)別:(1)從模塊概念來(lái)說(shuō),形參是函數(shù)的接口,是存在于函數(shù)內(nèi)部的變量。而實(shí)參是存在于函數(shù)外部的變量。它們不是同一個(gè)實(shí)體,也就是說(shuō),形參變量和實(shí)參變量所對(duì)應(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ù)體中的語(yǔ)句,而當(dāng)調(diào)用結(jié)束后,形參所占的內(nèi)存空間又會(huì)被釋放。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ù)。例如,下面的示例用來(lái)輸出一個(gè)三角形的圖案。第5頁(yè),共52頁(yè),2023年,2月20日,星期三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; }
程序運(yùn)行的結(jié)果如下:
第6頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.2函數(shù)的調(diào)用和聲明代碼中,main函數(shù)的for循環(huán)語(yǔ)句共調(diào)用了5次printline函數(shù)(A句),每次調(diào)用時(shí)因?qū)崊+1值不斷改變,從而使函數(shù)printline打印出來(lái)的星號(hào)個(gè)數(shù)也隨之改變。printline函數(shù)由于沒有返回值,因此它作為一個(gè)語(yǔ)句來(lái)調(diào)用。事實(shí)上,對(duì)于有返回值的函數(shù)也可進(jìn)行這種方式的調(diào)用,只是此時(shí)不使用返回值,僅要求函數(shù)完成一定的操作。實(shí)際上,在C++中,一個(gè)函數(shù)的調(diào)用方式還有很多。例如,對(duì)于前面sum函數(shù)還可有下列調(diào)用方式: intb=2*sum(4,5); //B intc=1; c=sum(c,sum(c,4)); //C其中,B語(yǔ)句把函數(shù)作為表達(dá)式的一部分,并將返回值參與運(yùn)算,結(jié)果b=18;C是將函數(shù)作為函數(shù)的實(shí)參,等價(jià)于“c=sum(1,sum(1,4));”,執(zhí)行sum(1,4)后,等價(jià)于“c=sum(1,5);”,最后結(jié)果為c=6。3.函數(shù)的聲明由于前面函數(shù)printline的定義代碼是放在main函數(shù)中調(diào)用語(yǔ)句A之前,因而A語(yǔ)句執(zhí)行不會(huì)有問(wèn)題。但若將函數(shù)printline的定義代碼放在調(diào)用語(yǔ)句A之后,即函數(shù)定義在后,而調(diào)用在前,就會(huì)產(chǎn)生“printline標(biāo)識(shí)符未定義”的編譯錯(cuò)誤。此時(shí)必須在調(diào)用前進(jìn)行函數(shù)聲明。第7頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.2函數(shù)的調(diào)用和聲明聲明一個(gè)函數(shù)按下列格式進(jìn)行: <函數(shù)類型><函數(shù)名>(<形參表>);可見,函數(shù)聲明的格式是在函數(shù)頭的后面加上分號(hào)“;”。但要注意,函數(shù)聲明的內(nèi)容應(yīng)和函數(shù)的定義應(yīng)相同。例如,對(duì)于前面sum函數(shù)和最后一個(gè)printline函數(shù)可有如下聲明: int sum(intx,inty); voidprintline(charch,intn);由于函數(shù)的聲明僅是對(duì)函數(shù)的原型進(jìn)行說(shuō)明,即函數(shù)原型聲明,其聲明的形參變量名在聲明語(yǔ)句中并沒有任何語(yǔ)句操作它,因此這里的形參名和函數(shù)的定義時(shí)的形參名可以不同,且函數(shù)聲明時(shí)的形參名還可以省略,但函數(shù)名、函數(shù)類型、形參類型及個(gè)數(shù)應(yīng)與定義時(shí)相同。例如,下面幾種形式都是對(duì)sum函數(shù)原型的合法聲明: intsum(inta,intb); //允許原型聲明時(shí)的形參名與定義時(shí)不同 intsum(int,int); //省略全部形參名 intsum(inta,int); //省略部分形參名 intsum(int,intb); //省略部分形參名不過(guò),從程序的可讀性考慮,在聲明函數(shù)原型時(shí),為每一個(gè)形參指定有意義的標(biāo)識(shí)符,并且和函數(shù)定義時(shí)的參數(shù)名相同,是一個(gè)非常好的習(xí)慣。第8頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.3值傳遞在C++中,函數(shù)的參數(shù)傳遞有兩種方式,一是按值傳遞,二是地址傳遞或引用傳遞。這里先來(lái)說(shuō)明按值傳遞的參數(shù)傳遞方法,地址傳遞或引用傳遞在以后來(lái)討論。當(dāng)函數(shù)的形參定義成一般變量時(shí),如前面printline和sum函數(shù)的形參都是一般變量,此時(shí)函數(shù)的參數(shù)傳遞就是按值傳遞方式,簡(jiǎn)稱值傳遞,是指當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),C++根據(jù)實(shí)參和形參的對(duì)應(yīng)關(guān)系將實(shí)際參數(shù)的值一一傳遞給形參,供函數(shù)執(zhí)行時(shí)使用。值傳遞的特點(diǎn)是:(1)若實(shí)參指定是變量,則傳遞的是實(shí)參變量的值而不是實(shí)參變量的地址。(2)在執(zhí)行函數(shù)代碼時(shí),由于對(duì)實(shí)參數(shù)據(jù)的操作最終是在形參的內(nèi)存空間中進(jìn)行,因此形參值的改變只是改變了形參的內(nèi)存空間存儲(chǔ)的值,而不會(huì)改變實(shí)參變量所對(duì)應(yīng)的內(nèi)存空間的值。也就是說(shuō),即使形參的值在函數(shù)中發(fā)生了變化,函數(shù)調(diào)用結(jié)束后,實(shí)參的值不會(huì)受到影響。例如:第9頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.3值傳遞 [例Ex_SwapValue]交換函數(shù)兩個(gè)參數(shù)的值。#include<iostream>usingnamespacestd;voidswap(floatx,floaty); //函數(shù)原型說(shuō)明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";}第10頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.3值傳遞程序的運(yùn)行結(jié)果為:可以看出,雖然函數(shù)swap中交換了兩個(gè)形參x和y的值,但交換的結(jié)果并不能改變實(shí)參的值,所以調(diào)用該函數(shù)后,變量a和b的值仍然為原來(lái)的值。函數(shù)值傳遞方式的最大好處是保持函數(shù)的獨(dú)立性。在值傳遞方式下,函數(shù)只有通過(guò)指定函數(shù)類型并在函數(shù)體中使用return來(lái)返回某一類型的數(shù)值。第11頁(yè),共52頁(yè),2023年,2月20日,星期三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í)作用 }這樣,當(dāng)有調(diào)用delay(); //和delay(1000)等效時(shí),程序就會(huì)自動(dòng)將loops當(dāng)作成1000的默認(rèn)值來(lái)進(jìn)行處理。當(dāng)然,也可在函數(shù)調(diào)用時(shí)指定相應(yīng)的實(shí)際的參數(shù)值,例如:delay(2000); //形參loops的值為2000在設(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ù) { //… }第12頁(yè),共52頁(yè),2023年,2月20日,星期三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); //合法:可以對(duì)所有的參數(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ù)(3)當(dāng)帶有默認(rèn)參數(shù)的函數(shù)調(diào)用時(shí),系統(tǒng)按從左到右的順序?qū)?shí)參與形參結(jié)合,當(dāng)實(shí)參的數(shù)目不足時(shí),系統(tǒng)將按同樣的順序用聲明或定義中的默認(rèn)值來(lái)補(bǔ)齊所缺少的參數(shù)。第13頁(yè),共52頁(yè),2023年,2月20日,星期三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é)果如下:第14頁(yè),共52頁(yè),2023年,2月20日,星期三2.1.4函數(shù)的默認(rèn)形參值(4)由于對(duì)同一個(gè)函數(shù)的原型可作多次聲明,因此在函數(shù)聲明中指定多個(gè)默認(rèn)參數(shù)時(shí),可用多條函數(shù)原型聲明語(yǔ)句來(lái)指定,但同一個(gè)參數(shù)的默認(rèn)值只能指定一次。例如,例Ex_Default可改寫為: #include<iostream> usingnamespacestd; //下面2條函數(shù)說(shuō)明語(yǔ)句等效于voiddisplay(inta,intb=2,intc=3); voiddisplay(inta,intb,intc=3); //指定c為默認(rèn)參數(shù) voiddisplay(inta,intb=2,intc); //指定b為默認(rèn)參數(shù) …第15頁(yè),共52頁(yè),2023年,2月20日,星期三
2.2C++函數(shù)特性
函數(shù)重載(overloaded)是C++對(duì)C的擴(kuò)展,它允許多個(gè)同名的函數(shù)存在,但同名的各個(gè)函數(shù)的形參必須有區(qū)別:要么形參的個(gè)數(shù)不同;要么形參的個(gè)數(shù)相同,但參數(shù)類型有所不同。 [例Ex_OverLoad]編程求兩個(gè)或三個(gè)操作數(shù)之和程序的運(yùn)行結(jié)果為:從上面的例子可以看出:由于使用了函數(shù)的重載,因而不僅方便函數(shù)名的記憶,而且更主要的是完善了同一個(gè)函數(shù)的代碼功能,給調(diào)用帶來(lái)了許多方便。程序中各種形式的sum函數(shù)都稱為sum的重載函數(shù)。需要說(shuō)明的是:(1)重載函數(shù)必須具有不同的參數(shù)個(gè)數(shù)或不同的參數(shù)類型,若只有返回值的類型不同是不行的。例如: voidfun(inta,intb); intfun(inta,intb);是錯(cuò)誤的。因?yàn)槿绻泻瘮?shù)調(diào)用fun(2,3)時(shí),編譯器無(wú)法準(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í),編譯器也是無(wú)法準(zhǔn)確地確定應(yīng)調(diào)用哪一個(gè)函數(shù)。第16頁(yè),共52頁(yè),2023年,2月20日,星期三2.2.2函數(shù)嵌套調(diào)用C++允許在函數(shù)中再調(diào)用其他函數(shù),這種調(diào)用稱為函數(shù)的嵌套調(diào)用。例如,下面的示例是通過(guò)多個(gè)函數(shù)以及函數(shù)的嵌套調(diào)用來(lái)求解一元二次方程的根。
[例Ex_Root]函數(shù)嵌套調(diào)用:求解一元二次方程的根本例main函數(shù)中調(diào)用了root函數(shù),root函數(shù)中又調(diào)用了sdelta和print函數(shù),而sdelta函數(shù)還調(diào)用了cmath頭文件定義的庫(kù)函數(shù)sqrt(求平方根)和fabs(求浮點(diǎn)數(shù)的絕對(duì)值)。它們的調(diào)用關(guān)系如圖2.2所示。main函數(shù)root函數(shù)sdelta函數(shù)fabs庫(kù)函數(shù)print函數(shù)sqrt庫(kù)函數(shù)圖2.2例Ex_Root中的各函數(shù)調(diào)用的關(guān)系第17頁(yè),共52頁(yè),2023年,2月20日,星期三2.2.2函數(shù)嵌套調(diào)用函數(shù)print用來(lái)輸出根的信息,當(dāng)n=0時(shí),參數(shù)r1和r2無(wú)效,但調(diào)用該函數(shù)時(shí)還必須指定相應(yīng)的實(shí)際參數(shù),只是此時(shí)的實(shí)參值在函數(shù)執(zhí)行中不起作用。當(dāng)n=1時(shí),只有參數(shù)r1有效,而當(dāng)n=2時(shí),參數(shù)r1和r2才會(huì)都有效。函數(shù)sdelta用來(lái)計(jì)算一元二次方程的系數(shù)a、b和c的b2-4ac的平方根。由于“d=b*b-4.0*a*c;”計(jì)算誤差,d值不一定剛好等于0.0,因此調(diào)用庫(kù)函數(shù)fabs求d的絕對(duì)值,并當(dāng)小于1.0e-10(1.0x1010)時(shí),將d值視為0.0,并返回0.0。當(dāng)d值大于0.0時(shí),函數(shù)返回其平方根。當(dāng)d值小于0.0時(shí),由于無(wú)法求出實(shí)平方根,因此作為程序技巧,函數(shù)返回-1.0。這樣當(dāng)在root函數(shù)中調(diào)用時(shí),通過(guò)返回值的判斷來(lái)決定有無(wú)方程根。root函數(shù)用來(lái)求解一元二次方程的方程根并輸出,函數(shù)設(shè)計(jì)時(shí)要考慮:有無(wú)根、同根、不同根、系數(shù)a為0以及系數(shù)b為0等多種情況。程序運(yùn)行的結(jié)果如下:
第18頁(yè),共52頁(yè),2023年,2月20日,星期三2.2.3遞歸函數(shù)C++允許在調(diào)用一個(gè)函數(shù)的過(guò)程中出現(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è)問(wèn)題的求解,因此可將n!用遞歸函數(shù)longfactorial(intn)來(lái)描述,程序代碼如下: [例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;}n!=1 當(dāng)n=0時(shí)n*(n-1)! 當(dāng)n>0時(shí)第19頁(yè),共52頁(yè),2023年,2月20日,星期三2.2.3遞歸函數(shù)在函數(shù)factorial中,當(dāng)n不等于0時(shí),又調(diào)用了該函數(shù)本身。下面來(lái)分析此函數(shù)的執(zhí)行過(guò)程:(1)因n=4,不等于0,故執(zhí)行“result=4*factorial(3);”,函數(shù)返回的值為4*factorial(3),即factorial(4)=4*factorial(3);(2)調(diào)用“factorial(3);”,n=3不等于0,執(zhí)行“result=3*factorial(2);”,函數(shù)返回的值為3*factorial(2),即factorial(3)=3*factorial(2);(3)調(diào)用“factorial(2);”,n=2不等于0,執(zhí)行“result=2*factorial(1);”,函數(shù)返回的值為2*factorial(1),即factorial(2)=2*factorial(1);(4)調(diào)用“factorial(1);”,n=1不等于0,執(zhí)行“result=1*factorial(0);”,函數(shù)返回的值為1*factorial(0),即factorial(1)=1*factorial(0);(5)調(diào)用“factorial(0);”,n等于0,結(jié)果函數(shù)返回的值為1。上述過(guò)程是根據(jù)程序運(yùn)行過(guò)程進(jìn)行推算的,這個(gè)過(guò)程稱為“遞推”過(guò)程。函數(shù)的遞歸調(diào)用在遞推過(guò)程后還進(jìn)行另一稱為“回歸”的過(guò)程,它是按“遞推”的逆過(guò)程,逐一求值回歸,一直到達(dá)遞推的開始處。因此,當(dāng)factorial(0)=1后,factorial(1)=1*1,factorial(2)=2*1*1,factorial(3)=3*2*1*1,factorial(4)=4*3*2*1*1,結(jié)果為4!,值為24。第20頁(yè),共52頁(yè),2023年,2月20日,星期三2.2.3遞歸函數(shù)以上的例子可以看出,函數(shù)的遞歸調(diào)用能使程序精巧、高效。但要注意,遞歸函數(shù)中必須要有結(jié)束遞歸過(guò)程的條件,否則遞歸會(huì)無(wú)限制地進(jìn)行下去。例如,在上述代碼中, if(n==0) result=1;就是結(jié)束遞歸過(guò)程的條件,若函數(shù)factorial變?yōu)椋?longfactorial(intn) { longresult=0; result=n*factorial(n-1); returnresult; }則遞歸會(huì)無(wú)限制地進(jìn)行下去,此程序?qū)⒆兊煤翢o(wú)用途。需要說(shuō)明的是:雖然遞歸調(diào)用編寫的程序簡(jiǎn)潔清晰,但每次調(diào)用函數(shù)時(shí),都需要分配內(nèi)存來(lái)保存現(xiàn)場(chǎng)和返回地址,內(nèi)存空間開銷很大,有時(shí)會(huì)引起棧內(nèi)存溢出。第21頁(yè),共52頁(yè),2023年,2月20日,星期三2.2.4內(nèi)聯(lián)函數(shù)在程序的執(zhí)行過(guò)程中,調(diào)用函數(shù)時(shí)首先需要保存主調(diào)函數(shù)的現(xiàn)場(chǎng)和返回地址,然后程序轉(zhuǎn)移到被調(diào)函數(shù)的起始地址繼續(xù)執(zhí)行。被調(diào)函數(shù)執(zhí)行結(jié)束后,先恢復(fù)主調(diào)函數(shù)的現(xiàn)場(chǎng),取出返回地址并將返回值賦給函數(shù)調(diào)用本身,最后在返回地址處開始繼續(xù)執(zhí)行。當(dāng)函數(shù)體比較小且執(zhí)行的功能比較簡(jiǎn)單時(shí),這種函數(shù)調(diào)用方式的系統(tǒng)開銷相對(duì)較大。為了解決這一問(wèn)題,C++引入了內(nèi)聯(lián)函數(shù)的概念,它把函數(shù)體的代碼直接插入到調(diào)用處,將調(diào)用函數(shù)的方式改為順序執(zhí)行直接插入的程序代碼,這樣可以減少程序的執(zhí)行時(shí)間,但同時(shí)增加了代碼的實(shí)際長(zhǎng)度。內(nèi)聯(lián)函數(shù)的使用方法與一般函數(shù)相同,只是在內(nèi)聯(lián)函數(shù)定義時(shí),需在函數(shù)的類型前面加上inline關(guān)鍵字。例如: [例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;}第22頁(yè),共52頁(yè),2023年,2月20日,星期三
2.2.4內(nèi)聯(lián)函數(shù)這樣,當(dāng)程序編譯時(shí),A語(yǔ)句變成了: a=5>10?5:10;程序的運(yùn)行結(jié)果如下:在使用內(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語(yǔ)句。(4)遞歸函數(shù)不能被用來(lái)做內(nèi)聯(lián)函數(shù)。(5)編譯器是否將用戶定義成的內(nèi)聯(lián)函數(shù)作為真正的內(nèi)聯(lián)函數(shù)處理,由編譯器自行決定??傊?,內(nèi)聯(lián)函數(shù)一般是比較小的、經(jīng)常被調(diào)用的、大多可在一行寫完的函數(shù),并常用來(lái)代替以后要討論的帶參數(shù)的宏定義。第23頁(yè),共52頁(yè),2023年,2月20日,星期三2.3作用域和存儲(chǔ)類型
作用域又稱作用范圍,是指程序中標(biāo)識(shí)符(變量名、函數(shù)名、數(shù)組名、類名、對(duì)象名等)的有效范圍。一個(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,這里介紹其他幾種。1.函數(shù)原型作用域函數(shù)原型作用域指的是在聲明函數(shù)原型所指定的參數(shù)標(biāo)識(shí)符的作用范圍。這個(gè)作用范圍是在函數(shù)原型聲明中的左、右圓括號(hào)之間。正因?yàn)槿绱?,在函?shù)原型中聲明的標(biāo)識(shí)符可以與函數(shù)定義中說(shuō)明的標(biāo)識(shí)符名稱不同。由于所聲明的標(biāo)識(shí)符與該函數(shù)的定義及調(diào)用無(wú)關(guān),所以可以在函數(shù)原型聲明中只作參數(shù)的類型聲明,而省略參數(shù)名。例如: doublemax(doublex,doubley); 和 doublemax(double,double); 是等價(jià)的。2.函數(shù)作用域具有函數(shù)作用域的標(biāo)識(shí)符在聲明它的函數(shù)內(nèi)可見,但在此函數(shù)之外是不可見的。在C++語(yǔ)言中,只有g(shù)oto語(yǔ)句使用的標(biāo)號(hào)是惟一具有函數(shù)作用域的標(biāo)識(shí)符。2.3.1作用域第24頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.1作用域這里的塊就是由“{”和“}”組成的塊語(yǔ)句(復(fù)合語(yǔ)句)。在塊中聲明的標(biāo)識(shí)符,其作用域從聲明處開始,一直到結(jié)束塊的花括號(hào)為止。塊作用域也稱作局部作用域,具有塊作用域的變量是局部變量。例如:voidfun(void) //在形參中指定void,表示沒有形參,void可不要{a的作用域b的作用域 inta; //a的作用域起始處 cin>>a; if(a<0){ a=-a; intb; //b的作用域起始處 … } //b的作用域終止處} //a的作用域終止處代碼中,聲明的局部變量a和b處在不同的塊中。其中變量a是在fun函數(shù)的函數(shù)體塊中,因此在函數(shù)體這個(gè)范圍內(nèi),該變量是可見的。而b是在if語(yǔ)句塊中聲明的,故它的作用域是從聲明處開始到if語(yǔ)句結(jié)束處終止。a的作用域b的作用域第25頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.1作用域需要說(shuō)明的是:當(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è)作用域。但同時(shí)出現(xiàn)另外一個(gè)問(wèn)題,語(yǔ)句“i=100;”中的i是使用A塊中的變量i還是使用B中的變量i?C++規(guī)定在這種作用域嵌套的情況下,如果內(nèi)層(塊B)和外層(塊A)作用域聲明了同名的標(biāo)識(shí)符,那么在外層作用域中聲明的標(biāo)識(shí)符對(duì)于該內(nèi)層作用域是不可見的。也就是說(shuō),在塊B聲明的變量i與塊A聲明的變量i無(wú)關(guān),當(dāng)塊B中的i=100時(shí),不會(huì)影響塊A中變量i的值。塊A塊B第26頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.1作用域4.文件作用域在所有函數(shù)外定義的標(biāo)識(shí)符稱為全局標(biāo)識(shí)符。全局標(biāo)識(shí)符的作用域是文件作用域,它從聲明之處開始,直到文件結(jié)束一直是可見的。具有文件作用域的變量和常量稱為全局變量和全局常量,例如: constfloatPI=3.14; //全局常量PI,其作用域從此開始到文件結(jié)束 inta; //全局變量a,其作用域從此開始到文件結(jié)束 voidmain() { //… } voidfunA(intx) { //… }其中,全局常量PI和全局變量a的作用域是文件作用域。標(biāo)識(shí)符的文件作用域一般還有以下幾種情況:第27頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.1作用域(1)若函數(shù)定義在后,調(diào)用在前,必須進(jìn)行函數(shù)原型聲明。若函數(shù)定義在前,調(diào)用在后,函數(shù)定義包含了函數(shù)的原型聲明。一旦聲明了函數(shù)原型,函數(shù)標(biāo)識(shí)符的作用域是從定義開始到源程序文件結(jié)束。例如: voidfunA(intx); //函數(shù)funA的作用域從此開始到文件結(jié)束 voidfunB() //函數(shù)funA的作用域從此開始到文件結(jié)束 { //… } voidmain() { //… } voidfunA(intx) { //… }(2)對(duì)于在頭文件中定義的標(biāo)識(shí)符,當(dāng)它們被預(yù)編譯時(shí),會(huì)將頭文件的內(nèi)容在源文件的相應(yīng)位置展開,所以在頭文件中定義的標(biāo)識(shí)符的作用域可以看成從#include該頭文件開始的位置到源程序文件結(jié)束。例如,以前示例中頭文件iostream的std::cin和std::cout的作用域是從#include預(yù)處理指令開始一直到源程序文件結(jié)束。注意,若使用ANSI/ISOC++新文件格式的包含,則cin和cout的作用域是從using語(yǔ)句開始一直到源程序文件結(jié)束。第28頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.2域運(yùn)算符在C++中,若在塊作用域內(nèi)使用與局部標(biāo)識(shí)符同名的塊外標(biāo)識(shí)符時(shí),則須使用域運(yùn)算符“::”來(lái)引用,且該標(biāo)識(shí)符一定要是全局標(biāo)識(shí)符,即它具有文件作用域。例如:
[例Ex_Process]在塊作用內(nèi)引用文件作用域的同名變量#include<iostream>usingnamespacestd;inti=10; //Aintmain(){ inti=20; //B { inti=5; //C intj; ::i=::i+4; //::i是引用A定義的變量i,不是B中的i j=::i+i; //這里不加::的i是C中定義的變量 cout<<"::i="<<::i<<",j="<<j<<"\n"; } cout<<"::i="<<::i<<",i="<<i<<"\n"; //這里不加::的i是B中定義的變量 return0;}
程序的運(yùn)行結(jié)果為:需要說(shuō)明的是,域運(yùn)算符“::”往往還用于指定引用對(duì)象所屬的類、名稱空間等。第29頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型存儲(chǔ)類型是針對(duì)變量而言的,它規(guī)定了變量的生存期。無(wú)論是全局變量還是局部變量,編譯系統(tǒng)往往根據(jù)其存儲(chǔ)方式定義、分配和釋放相應(yīng)的內(nèi)存空間。變量的存儲(chǔ)類型反映了變量在哪開辟內(nèi)存空間以及占用內(nèi)存空間的有效期限。在C++中,變量有4種存儲(chǔ)類型:自動(dòng)類型、靜態(tài)類型、寄存器類型和外部類型,這些存儲(chǔ)類型是在變量定義時(shí)來(lái)指定的,其一般格式如下:<存儲(chǔ)類型><數(shù)據(jù)類型><變量名表>;
1.自動(dòng)類型和寄存器類型一般說(shuō)來(lái),用自動(dòng)存儲(chǔ)類型聲明的變量都是限制在某個(gè)程序范圍內(nèi)使用,即為局部變量。從系統(tǒng)角度來(lái)說(shuō),自動(dòng)存儲(chǔ)類型變量是采用動(dòng)態(tài)分配方式在棧區(qū)中來(lái)分配內(nèi)存空間。因此,當(dāng)程序執(zhí)行到超出該變量的作用域時(shí),就釋放它所占用的內(nèi)存空間,其值也隨之消失了。在C++語(yǔ)言中,聲明一個(gè)自動(dòng)存儲(chǔ)類型的變量是在變量類型前加上關(guān)鍵字auto,例如: auto inti;若自動(dòng)存儲(chǔ)類型的變量是在函數(shù)內(nèi)或語(yǔ)句塊中聲明的,則可省略關(guān)鍵字auto,例如: voidfun() { inti; //省略auto //… }第30頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型使用關(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.靜態(tài)類型從變量的生存期來(lái)說(shuō),一個(gè)變量的存儲(chǔ)空間可以是永久的,即在程序運(yùn)行期間該變量一直存在,如全局變量;也可以是臨時(shí)的,如局部變量,當(dāng)流程執(zhí)行到它的說(shuō)明語(yǔ)句時(shí),系統(tǒng)為其在棧區(qū)中動(dòng)態(tài)分配一個(gè)臨時(shí)的內(nèi)存空間,并在它的作用域中有效,一旦流程超出該變量的作用域時(shí),就釋放它所占用的內(nèi)存空間,其值也隨之消失。但是,若在聲明局部變量類型前面加上關(guān)鍵字static,則將其定義成了一個(gè)靜態(tài)類型的變量。這樣的變量雖具有局部變量的作用域,但由于它是用靜態(tài)分配方式在靜態(tài)數(shù)據(jù)區(qū)中來(lái)分配內(nèi)存空間。因此,在這種方式下,只要程序還在繼續(xù)執(zhí)行,靜態(tài)類型變量的值就一直有效,不會(huì)隨它所在的函數(shù)或語(yǔ)句塊的結(jié)束而消失。簡(jiǎn)單地說(shuō),靜態(tài)類型的局部變量雖具有局部變量的作用域,但卻有全局變量的生存期。值得注意的是,如需定義一個(gè)很大的數(shù)組時(shí),則應(yīng)將數(shù)組定義成全局?jǐn)?shù)組或?qū)?shù)組的存儲(chǔ)類型定義成static,而不應(yīng)定義成自動(dòng)存儲(chǔ)類型或局部數(shù)組,因?yàn)殪o態(tài)數(shù)據(jù)區(qū)的內(nèi)存要比棧區(qū)內(nèi)存大許多。例如:staticint array[5000]; //指定靜態(tài)存儲(chǔ)類型第31頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型需要說(shuō)明的是,靜態(tài)類型的局部變量只在第一次執(zhí)行時(shí)進(jìn)行初始化,正因?yàn)槿绱?,在聲明靜態(tài)類型變量時(shí)一定要指定其初值,若沒有指定,編譯器還會(huì)將其初值置為0。例如: [例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;}第32頁(yè),共52頁(yè),2023年,2月20日,星期三
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)行過(guò)初始化,因此語(yǔ)句“staticintj=0;”被跳過(guò),執(zhí)行j++后,j值為2。故程序運(yùn)行結(jié)果為:事實(shí)上,在程序中聲明的全局變量總是靜態(tài)存儲(chǔ)類型,若在全局變量前加上static,使該變量只在這個(gè)源程序文件內(nèi)使用,稱之為全局靜態(tài)變量或靜態(tài)全局變量。若一個(gè)程序由一個(gè)文件組成,在聲明全局變量時(shí),有無(wú)static并沒有區(qū)別,但若多個(gè)文件組成一個(gè)程序時(shí),加與不加static,其作用完全不同。例如:
第33頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型
[例Ex_StaticScope]使用靜態(tài)類型的全部變量(1)用VisualC++中的AppWizard創(chuàng)建一個(gè)控制臺(tái)應(yīng)用程序Ex_StaticScope,在創(chuàng)建過(guò)程中選擇項(xiàng)目類型為“一個(gè)簡(jiǎn)單的程序(Asimpleapplication)”。(2)在Ex_StaticScope.cpp文件中添加下列代碼: #include"stdafx.h" #include<iostream> usingnamespacestd; intn; voidf(); //先作函數(shù)原型聲明,函數(shù)定義在另一個(gè)文件中 intmain() { n=20; cout<<"n="<<n<<"\n"; f(); return0; }第34頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型代碼中,#include"stdafx.h"語(yǔ)句是VisualC++應(yīng)用程序向?qū)ё詣?dòng)添加的。stdafx.h是每個(gè)VisualC++應(yīng)用程序所必有的預(yù)編譯頭文件,程序所用到的VisualC++頭文件包含語(yǔ)句一般均應(yīng)添加到這個(gè)文件中。函數(shù)f先在該文件中作函數(shù)的原型聲明,函數(shù)的定義在另一個(gè)文件中,這是VisualC++所允許的。選擇“文件”→“新建”菜單命令,默認(rèn)時(shí)會(huì)自動(dòng)將“新建”對(duì)話框切換到“文件”頁(yè)面,選中“C++SourceFile”文件類型,在文件編輯框中輸入Ex_StaticScope_1.cpp,如圖2.3所示。單擊[確定]按鈕,在Ex_StaticScope_1.cpp中添加下列代碼: #include"stdafx.h" #include<iostream> usingnamespacestd; staticintn; //默認(rèn)初值為0 voidf() //函數(shù)定義 { n++; //這里的n是本文件定義的靜態(tài)類型變量 cout<<"n="<<n<<"\n"; }第35頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型圖2.3向項(xiàng)目中添加C++文件項(xiàng)目Ex_StaticScope運(yùn)行后,其結(jié)果如下:可見,函數(shù)f輸出1而不是21,表明Ex_StaticScope.cpp中的全局變量n和Ex_Static-Scope_1.cpp中的靜態(tài)全局變量n是互不相干的。因此,靜態(tài)全局變量對(duì)組成該程序的其他源文件是無(wú)效的,它能很好地解決在程序多文件組織中全局變量的重名問(wèn)題。同靜態(tài)全局變量相類似,靜態(tài)函數(shù)也是在某個(gè)函數(shù)聲明前加上static,它的目的也是使該函數(shù)只在聲明的源文件中使用,對(duì)于其他源文件則無(wú)效。
第36頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型3.外部類型使用關(guān)鍵字extern聲明的變量稱為外部變量,一般是指定義在本程序外部的變量。當(dāng)某個(gè)變量被聲明成外部變量時(shí),不必再次為它分配內(nèi)存就可以在本程序中引用這個(gè)變量。在C++中,只有在兩種情況下需要使用外部變量。第一種情況:在同一個(gè)源文件中,若定義的變量使用在前,聲明在后,這時(shí)在使用前要聲明為外部變量。例如: [例Ex_Extern1]同一個(gè)源文件中的外部變量使用#include<iostream>usingnamespacestd;externinta; //聲明外部變量a, //若沒有此語(yǔ)句,函數(shù)count中的語(yǔ)句將出錯(cuò)voidcount(){ a++; cout<<a<<"\n";}inta=10; //外部變量a的實(shí)際聲明處intmain(){ count(); cout<<a<<"\n"; return0;} 第37頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型運(yùn)行結(jié)果為:第二種情況:當(dāng)由多個(gè)文件組成一個(gè)完整的程序時(shí),在一個(gè)源程序文件中定義的變量要被其他若干個(gè)源文件引用時(shí),引用的文件中要用extern對(duì)該變量作外部聲明。例如,創(chuàng)建一個(gè)Ex_Extern2項(xiàng)目,包含兩個(gè)源文件,一個(gè)是Ex_Extern2.cpp,另一個(gè)是Ex_Extern2_1.cpp。 [例Ex_Extern2]不在同一個(gè)源文件中的外部變量使用●Ex_Extern2.cpp文件內(nèi)容#include"stdafx.h"#include<iostream>usingnamespacestd;intn;voidf();intmain(){ n=20; cout<<"n="<<n<<"\n"; f(); return0;
第38頁(yè),共52頁(yè),2023年,2月20日,星期三2.3.3存儲(chǔ)類型●
Ex_Extern2_1.cpp文件內(nèi)容#include"stdafx.h"#include<iostream>usingnamespacestd;externintn; //外部變量聲明,它在另一個(gè)文件中定義voidf(){ n++; cout<<"n="<<n<<"\n";}項(xiàng)目Ex_StaticScope經(jīng)運(yùn)行后,結(jié)果如下:需要注意的是:(1)可以對(duì)同一個(gè)變量進(jìn)行多次extern的聲明。若在聲明時(shí),給一個(gè)外部變量賦初值,則編譯器認(rèn)為是一個(gè)具體的變量定義,而不是一個(gè)外部變量的聲明,此時(shí)要注意同名標(biāo)識(shí)符的重復(fù)定義。例如: externintn=1; //變量定義 … intn; //錯(cuò)誤:變量n重復(fù)定義(2)雖然外部變量對(duì)不同源文件中或函數(shù)之間的數(shù)據(jù)傳遞特別有用。但也應(yīng)該看到,這種能被許多函數(shù)共享的外部變量,其數(shù)值的任何一次改變,都將影響到所有引用此變量的函數(shù)的執(zhí)行結(jié)果,其危險(xiǎn)性是顯然的。
第39頁(yè),共52頁(yè),2023年,2月20日,星期三2.4名稱空間在C++中,定義一個(gè)名稱空間的格式如下:2.4.1名稱空間的定義namespace[標(biāo)識(shí)符]{成員;…}體其中,namespace是C++關(guān)鍵字,標(biāo)識(shí)符用作名稱空間的名稱,屬于該名稱空間體中的變量、函數(shù)、結(jié)構(gòu)、枚舉、聯(lián)合以及以后要討論的類等都可以認(rèn)為是該名稱空間的成員。需要說(shuō)明的是:第40頁(yè),共52頁(yè),2023年,2月20日,星期三2.4.1名稱空間的定義(1)同一個(gè)文件中,可以允許定義多個(gè)名稱空間。一旦定義名稱空間后,標(biāo)識(shí)符就標(biāo)識(shí)名稱空間體的那個(gè)區(qū)域。例如: usingnamespacestd; namespaceDING1 { charname[]="thisisinDING1region!"; voidshowname(void) { cout<<name<<endl; } } namespaceDING2 { charname[]="thisisinDING2region!"; voidshowname(void) { cout<<name<<endl; } }盡管名稱空間DIN1和DING2中定義的成員名都相同,但它們由于分屬不同的名稱區(qū)域,因而是合法的。此后,在引用各自的成員時(shí)就可使用域作用符來(lái)指定DIN1或DING2來(lái)標(biāo)識(shí)各自所在的名稱區(qū)域。第41頁(yè),共52頁(yè),2023年,2月20日,星期三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)放在體外完成,則必須用域作用符“::”指明其所屬名稱空間。例如: usingnamespacestd; namespaceDING1 { charname[]="thisisinDING1region!"; voidshowname(void); } namespaceDING2 { charname[]="thisisinDING2region!"; voidshowname(void); } voidDING1::showname(void) //在體外實(shí)現(xiàn)函數(shù)showname { cout<<name<<endl; } voidDING2::showname(void) //在體外實(shí)現(xiàn)函數(shù)showname { cout<<name<<endl; }第42頁(yè),共52頁(yè),2023年,2月20日,星期三2.4.1名稱空間的定義(3)同一個(gè)名稱空間的區(qū)域中,不能出現(xiàn)相同的標(biāo)識(shí)符。若名稱空間定義時(shí)省略標(biāo)識(shí)符,則名稱空間的區(qū)域是全局的、靜態(tài)的(static)、開放的,可以在本文件中直接使用,而勿需要使用using來(lái)指定。第43頁(yè),共52頁(yè),2023年,2月20日,星期三2.4.2名稱空間的使用在C++中,對(duì)已定義的名稱空間的使用可以有以下幾種方式:(1)直接引用方式對(duì)已定義的名稱空間的成員可用下列格式來(lái)直接引用:名稱空間名::成員例如,下列示例是直接引用名稱空間DING下的name和成員函數(shù)showname。 [例Ex_Namespace]直接引用名稱空間的成員#include<iostream>#include<cstring>usingnamespacestd;namespaceDING{ charname[]="thisisinDINGregion!"; voidshowname(void) { cout<<name<<endl; }}intmain(){ strcpy(DING::name,"直接引用DING成員!");
DING::showname(); return0;}第44頁(yè),共52頁(yè),2023年,2月20日,星期三2.4.2名稱空間的使用程序運(yùn)行的結(jié)果如下:(2)using個(gè)別成員這種方式稱為名稱空間成員的使用聲明方式,其格式為:using名稱空間名M::成員N它表明以后所使用的成員N是來(lái)自名稱空間M。例如,下列示例是先作using聲明,然后引用名稱空間DING下的name和成員函數(shù)showname。
第45頁(yè),共52頁(yè),2023年,2月20日,星期三2.4.2名稱空間的使用
[例Ex_Using1]名稱空間的成員使用聲明#include<iostream>#include<cstring>usingnamespacestd;namespaceDING{ charname[]="thisisinDINGregion!"; voidshowname(void) { cout<<name<<endl; }}intmain(){ usingDING::name; usingDING::showname; strcpy(name,"名稱空間的成員使用聲明!"); showname(); return0;}第46頁(yè),共52頁(yè),2023年,2月20日,星期三2.4.2名稱空間的使用程序運(yùn)行的結(jié)果如下:
溫馨提示
- 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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 防火卷簾門采購(gòu)安裝合同范本
- 勞動(dòng)保密協(xié)議書范本
- 上海個(gè)人住宅租賃合同
- 上市路演合作合同范本
- 小百區(qū)檔口轉(zhuǎn)讓合同范本
- 裝修工程保險(xiǎn)合同樣本
- 環(huán)境衛(wèi)生知識(shí)宣傳
- 馬克思主義在心理學(xué)研究中的范文
- 人教版四年級(jí)上冊(cè)語(yǔ)文作業(yè)布置計(jì)劃
- 幼兒園災(zāi)害應(yīng)急預(yù)案計(jì)劃
- 2025年湖北省技能高考(建筑技術(shù)類)《建筑制圖與識(shí)圖》模擬練習(xí)試題庫(kù)(含答案)
- 集成電路研究報(bào)告-集成電路項(xiàng)目可行性研究報(bào)告2024年
- 2024年湖南生物機(jī)電職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測(cè)驗(yàn)歷年參考題庫(kù)(頻考版)含答案解析
- 樁基承載力自平衡法檢測(cè)方案資料
- 2025云南昆明空港投資開發(fā)集團(tuán)招聘7人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 簡(jiǎn)單的路線圖(說(shuō)課稿)2024-2025學(xué)年三年級(jí)上冊(cè)數(shù)學(xué)西師大版
- 成都市2024-2025學(xué)年度上期期末高一期末語(yǔ)文試卷(含答案)
- 2025年教育局財(cái)務(wù)工作計(jì)劃
- Unit 5 Now and Then-Lesson 3 First-Time Experiences 說(shuō)課稿 2024-2025學(xué)年北師大版(2024)七年級(jí)英語(yǔ)下冊(cè)
- 中小學(xué)智慧校園建設(shè)方案
- 中國(guó)食物成分表2020年權(quán)威完整改進(jìn)版
評(píng)論
0/150
提交評(píng)論