《CC 程序設(shè)計(jì)》(黃襄念)附錄與習(xí)題 附錄A-D_第1頁(yè)
《CC 程序設(shè)計(jì)》(黃襄念)附錄與習(xí)題 附錄A-D_第2頁(yè)
《CC 程序設(shè)計(jì)》(黃襄念)附錄與習(xí)題 附錄A-D_第3頁(yè)
《CC 程序設(shè)計(jì)》(黃襄念)附錄與習(xí)題 附錄A-D_第4頁(yè)
《CC 程序設(shè)計(jì)》(黃襄念)附錄與習(xí)題 附錄A-D_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

附錄A 調(diào)試方法可以分為兩大類,即語(yǔ)法錯(cuò)誤和邏輯錯(cuò)誤。語(yǔ)法錯(cuò)誤(OJ文件(XE文件EXEdoue數(shù)據(jù)給ntdoue轉(zhuǎn)換到n邏輯錯(cuò)誤EXE程序,但運(yùn)行結(jié)果不正確。造成調(diào)試是程序員最基本的技能,附錄A介紹兩種邏輯錯(cuò)誤的常用調(diào)試手段——程序斷點(diǎn)和斷言,它們有助于快速定位,進(jìn)而改正邏輯錯(cuò)誤。一、調(diào)試環(huán)境VC+IDEA.1Debug”(或稱開發(fā)版或DebugDebug(從DBXEeeaseXEDebu默認(rèn)EXE提交給用戶。二、斷點(diǎn)調(diào)試斷點(diǎn)eakont暫停,以便觀察程序運(yùn)行時(shí)的情況,諸如變量值、數(shù)組元素值等,它是最基本、最常用的調(diào)試手段。斷點(diǎn)包括位置斷點(diǎn)、數(shù)據(jù)斷點(diǎn)、函數(shù)斷點(diǎn)、消息斷點(diǎn)等,斷點(diǎn)可以設(shè)置多個(gè)。1.位置斷點(diǎn)(簡(jiǎn)稱斷點(diǎn)A.1A.2F9F9取消該行斷點(diǎn)。在該行左邊灰色窄條內(nèi)單擊即可設(shè)置該行斷點(diǎn),再次單擊取消該斷點(diǎn)。A.1A.4。A-1編程實(shí)驗(yàn):設(shè)置調(diào)試環(huán)境與斷點(diǎn)。圖A.1Debug環(huán)境及斷點(diǎn)(3個(gè)) 圖A.2“調(diào)試”菜單項(xiàng)5圖A.“l(fā)5不調(diào)試A.1最后一個(gè)斷點(diǎn)處(show函數(shù))暫停,根據(jù)需要有兩種選擇:showA.show函數(shù)10”表示不進(jìn)入函數(shù)而運(yùn)行到下一條語(yǔ)句(15行。ht5。14arr各個(gè)元素值。局部變量或自動(dòng)窗口A.3數(shù)據(jù)提示A.4arr出現(xiàn)數(shù)據(jù)提示,鼠標(biāo)移開后消失。若按下最右端小圖釘按鈕,則為永久性提示(還可以給它寫注釋。圖A.3局部變量窗口 圖A.4數(shù)據(jù)提示顯示數(shù)組arr元素以上斷點(diǎn)無條件暫停程序的執(zhí)行,稱為無條件斷點(diǎn)(簡(jiǎn)稱斷點(diǎn)??梢詾閿帱c(diǎn)設(shè)置一個(gè)true時(shí)觸發(fā)該斷點(diǎn),稱為條件斷點(diǎn)false時(shí),無視該斷點(diǎn)。A-2編程實(shí)驗(yàn):設(shè)置條件斷點(diǎn)。A.5112個(gè)小圖標(biāo),再把鼠標(biāo)...A.6=4|num45(圖A.7:i2i4條件;sum6sm4條件,故觸發(fā)斷點(diǎn)暫停程序。圖A.第1行5A.,i為(04、sum為1(12345。圖A.6編輯條件表達(dá)式2.?dāng)?shù)據(jù)斷點(diǎn)

圖A.5設(shè)置條件斷點(diǎn) 圖A.7觀察條件斷點(diǎn)結(jié)果A-3編程練習(xí):設(shè)置數(shù)據(jù)斷點(diǎn)。程序代碼如下:7 7 cout<<test<<endl;8 }9 void func2(intb)10{testb; //testcout<<test<<endl;//test//testtest變化double test=0;void func1(inta)5 {6 test=a*10;#include<iostream>usingnamespacestd;13}14int main()15{16cout<<sizeof(int*)<<endl;//x86輸出4,x64輸出817cout<<sizeof(double*)<<endl;//x86輸出4,x64輸出818int a=1,b=15;19func1a); //1020func2b); //2521int data[100];22for(inti=0;i<100;i++)23data[i]=i;24system("pause");25}10或1不能按55,main函數(shù)(15行。A.8。圖A.8新建數(shù)據(jù)斷點(diǎn)數(shù)據(jù)斷點(diǎn)通過監(jiān)視變量的內(nèi)存地址實(shí)現(xiàn),故需輸入變量地址且指明地址的字節(jié)數(shù)(默認(rèn)4位程序(es&es,見圖A.9。由于est是doue8……圖A.9設(shè)置數(shù)據(jù)斷點(diǎn)時(shí)報(bào)錯(cuò)double64(8字節(jié)32324doue64A.1n或8664A.10所示。圖A.10設(shè)置單個(gè)項(xiàng)目平臺(tái)64程序10或1...A.11。圖A.11設(shè)置數(shù)據(jù)斷點(diǎn)5test的地方。unc1和unc2estest>0每F5繼續(xù)運(yùn)行func17func2函數(shù)的12行,暫停時(shí)告訴你此處已完成修改,實(shí)現(xiàn)了對(duì)修改處的快速定位。3.函數(shù)斷點(diǎn)按“l(fā)BA.12。斷點(diǎn)條件是函數(shù)名,調(diào)用指定函數(shù)時(shí)(func2)觸發(fā)函數(shù)斷點(diǎn),程序停留在該函數(shù)入口處。還可以結(jié)合“條件”選項(xiàng),設(shè)置觸發(fā)函數(shù)斷點(diǎn)的更多條件。圖A.12設(shè)置函數(shù)斷點(diǎn)三、監(jiān)視窗口A.3A.A.3。圖A.13監(jiān)視窗口內(nèi)容 圖A.14設(shè)置快速監(jiān)視...ht9A-3testtest添加到監(jiān)視窗口,見圖A.13。dataShift+F9”或鼠標(biāo)右鍵彈出菜單A.14)daa50,data50A.13是24行的情況。data[50]+test、data+10(指針)等。另外,它可以顯示大數(shù)組的某個(gè)元素,而不必顯示整個(gè)數(shù)組。斷言(Assert)也是一種調(diào)試手段,幫助我們發(fā)現(xiàn)和定位程序的邏輯錯(cuò)誤。斷言可分為(言發(fā)生在程序編譯時(shí),也稱編譯時(shí)斷言,靜態(tài)斷言由C++11新標(biāo)準(zhǔn)提供。一、動(dòng)態(tài)斷言頭文件<cassert>提供動(dòng)態(tài)斷言的宏函數(shù),如下:void assert(int expression);expression(非零expressionexpression值為假時(shí)斷言失敗abort函數(shù)非正常終止程序,輸出expression、源程序名稱和行號(hào),便于找到問題所在。例A-4編程實(shí)驗(yàn):使用斷言。程序代碼及程序輸出結(jié)果(圖A.15)如下:}}圖A.15例A-4的輸出結(jié)果system("pause");//斷言失敗func(c);//斷言(保證)i不為空//assert,須在#include<cassert>之前//assert頭文件#include<iostream>//#defineNDEBUG#include<cassert>usingnamespacestd;void func(int*i){cout<<i<<endl;assert(i!=NULL);}int main(){inta=10;int*b=NULL;int*c=NULL;b=&a;func(b);12345678910111213141516171819思考與練習(xí):(1)不注釋第2行,結(jié)果會(huì)如何?程序發(fā)行版應(yīng)該怎么做?(2)不注釋第2行,且交換第2行和第3行,結(jié)果會(huì)如何?斷言是一種調(diào)試手段,用于發(fā)現(xiàn)錯(cuò)誤而不是錯(cuò)誤處理,不能代替錯(cuò)誤處理代碼。A-5編程實(shí)驗(yàn):注意避免斷言的副作用。程序代碼如下:#include#include<iostream>//#defineNDEBUG#include<cassert>usingnamespacestd;int*func(double&a,int&b,intc)}}//正常輸出:10*p=func(a,b,c);for(inti=0; i<b; i++){p[i]=i+10;cout<<p[i]<<endl;}delete[]p;system("pause");//斷言為真//斷言為真b=1;c=-2;intintintmain()double a=10;}int{131415161718192021222324252627//斷言分母不能為0//斷言元素個(gè)數(shù)不能為負(fù)//斷言有副作用assert(c!=0);assert(b>0);//assert(b++>0);double r=a/c;int*pt=new int[b];returnpt;//斷言常用于檢查函數(shù)的參數(shù)6 {78910111278assertc0&&b09b++(2行思考與練習(xí):(1)注釋第8行且不注釋第9行且同時(shí)注釋和不注釋第2行,輸出有何變化?(2)分別將第17、18行改為b=-1、c=0,觀察斷言失敗情況。(3)注釋第8行且第17行改為b=-1,運(yùn)行程序出現(xiàn)什么情況?二、靜態(tài)斷言C++11static_assert,不需要其他頭文件。用法格式如下:static_assert(constexpr,message);constexpr是常量表達(dá)式,如果其值為真表示斷言成功,不做任何事情;如果其值為假(,essaeA-6(如下:#include#include<iostream>usingnamespacestd;3 template<classT1,classT2void arrCopy(T1&dest,T2&src //函數(shù)模板4 {static_assert(sizeof(dest)>=sizeof(src),"內(nèi)存dest<src"); //靜態(tài)斷言memcpy(&dest,&src,sizeof(src));7 };8 void func(constint&m //m可引用不同的常量9{//static_assert(m>=0m<0 //靜態(tài)斷言,ERROR10cout<<"m:"<<m<<endl;11}12intmain()13{int a[4]={};14int b[3]={10,20,30};15cout<<a<<endl;16cout<<&a<<endl;17func10; //m引用-1018func20; //m2019arrCopy(a,b);20const intn=4;21static_assert(n<=4,"n4 //靜態(tài)斷言22for(inti=0;i<n;i++) cout<<a[i]<<endl;23systempause" A.16例A-6的輸出結(jié)果24}6memcpysrcdest5行用靜態(tài)斷言保destT2inta[4]和intb[3],故知道它們的內(nèi)存大小為常量。9m(引用不同常量(要求思考與練習(xí):(1)將第14行b[3]改為b[5],其他不變,有什么編譯錯(cuò)誤?(2)將第20行常量n值改為5,其他不變,有什么編譯錯(cuò)誤?(3)如何將第9行改為動(dòng)態(tài)斷言?附錄B 異常處理一、必要性檢測(cè)即處理只檢測(cè)不處理main)還不處理,則程序停止運(yùn)行。其優(yōu)點(diǎn)在于能專心設(shè)計(jì)和實(shí)現(xiàn)函數(shù)功能而不處理異常,將異常上移到某一層函數(shù)去專門處理。如此分工合理、各司其職,這就是本附錄的異常處理方式。二、try-catch結(jié)構(gòu)下面,通過一個(gè)例子來學(xué)習(xí)try-catch結(jié)構(gòu)。B-1try-catch結(jié)構(gòu)處理異常。程序代碼如下:try try //監(jiān)測(cè)異常{ //大括號(hào)不能省略q=divide(ndiv); //div=0//constchar*類型異常并不處理#include<iostream>#include<string>usingnamespacestd;float divide(int num,int div)5 {if(div0) throw異常:被零除\n";return float(num)/div;8 }9 int main()10{int n,div; float q=0;cout輸入兩個(gè)數(shù):";cin>>n>>div;}}//異常處理代碼//邏輯錯(cuò)//語(yǔ)法錯(cuò),try-catch之間不能有其他語(yǔ)句//捕捉并處理constchar*異常}//cout<<"商:"<<q<<endl;catch(constchar*exception){ //大括號(hào)不能省略coutexception;}//cout<<"商:"<<q<<endl;system("pause");//無異常時(shí)輸出“商”cout<<"商:"<<q<<endl;17181920212223242526第6行:throw拋出constchar*類型異常,異常類型可以是基本類型或自定義類型。第14~18行:把可能產(chǎn)生異常的代碼段放在try大括號(hào)中,大括號(hào)不能省略。20~23行:catch捕捉到指定類型異常時(shí),立即跳轉(zhuǎn)到該處并處理異常。19行:語(yǔ)法錯(cuò)。trycatch結(jié)構(gòu)為一個(gè)整體,之間不能插入其他語(yǔ)句。240,則商沒有意義。思考與練習(xí):1)0正常)和等于0異常(2)第20行改為catch(intexception),分母為0時(shí)會(huì)發(fā)生什么?有何結(jié)論?三、異常傳遞throw拋出異常時(shí),程序立即從throw函數(shù)跳出,沿函數(shù)調(diào)用鏈逐級(jí)上報(bào),直到有函數(shù)捕獲異常且不再throw為止。如果均未捕獲并處理異常,則程序停止運(yùn)行。例B-2編程實(shí)驗(yàn):異常傳遞。B.1f3doubleaf3、f2、f1catchfloat、intchardouble類型而不處理,異常繼續(xù)向上mainmain捕獲并處理。main()……catch(double)main()……catch(double)f1()……catch(char)f2()……catch(int)f3()……throw(a)catch(float)a a a圖B.1異常沿函數(shù)調(diào)用鏈傳遞程序代碼及輸出結(jié)果(圖B.2)如下:#include#include<iostream>usingnamespacestd;void f2();445678910111213141516171819202122232425262728293031323334353637383940voidvoid{f3()throw(double);f1()//f3try{ f2();}catch(char)//f2異常{ coutf1char異常endl;cout<<"f1繼續(xù)"<<endl;}}void{f2()try{f3();}catch(int)//f3異常coutf2int異常endl;cout<<"f2繼續(xù)"<<endl;}void f3()throw(double){doublea=100;//float a=100;//throw(a);try{throw(a);}catch(float)//異常類型//double異常//捕捉float異常{cout<<"f3捕捉float異常\n";}cout<<"f3繼續(xù)"<<endl;}int{main()try{ f1(); }catch(doubleb)//catch(float b){//監(jiān)測(cè)f1()異常//double異常//捕捉float異常coutmaindouble異常endl;cout<<"異常表達(dá)式值:"<<b<<endl;}cout<<"main繼續(xù)"<<endl;system("pause");圖B.2例B-2的輸出結(jié)果}419double)throwhow()(noecept(1)將第4、19行throw(double)改為throw()或noexcept,有何編譯警告?(2)第4、19行:注釋throw聲明部分,有警告和錯(cuò)誤嗎?(3)注釋第21行且不注釋第22行,結(jié)果會(huì)如何?(4)注釋第32行且不注釋第33行,結(jié)果會(huì)如何?有何結(jié)論?(5)注釋第24~27行且不注釋第23行,結(jié)果會(huì)如何?四、專門處理將功能函數(shù)拋出的異常逐級(jí)上報(bào)到某一層去專門處理,這樣層次更清楚、分工更合理。B-3B-2H1H2進(jìn)行專門處理。程序代碼及輸出結(jié)果(圖B.3)如下:B.3B-3的輸出結(jié)果}catch(...){cout<<"捕獲其他異常\n";}}void H2 //異常處理函數(shù){try{H1();}catch(int*p)coutH2int*異常:*pendl}int main(){H2; //H2H1//進(jìn)行某些處理//再次拋出異常(p可省略)*p+=5;throwp;voidf3(){inta=10,*b=&a,&c=a;//throwc;throwb; //int*類型異常}void H1 異常處理函數(shù){try{f1();}//catch(...){cout<<"其他異常\n";}catch(int){cout<<"捕獲int異常"<<endl;}catch(int*p){coutH1int*異常:*pendl;//調(diào)用關(guān)系:f1→f2→f3f2();f3();f1(){f2();}f2(){f3();}voidvoidvoid#include<iostream>usingnamespacestd;12345678910111213141516171819202122232425262728293031323334coutcoutmain繼續(xù)endl;system("pause");37}第24行:catch(...)捕獲未指定的其他各類異常。思考與練習(xí):(1)將catch(...)提前,即注釋第24行且不注釋第16行,有何問題與結(jié)論?(2)注釋第11行且不注釋第10行,結(jié)果會(huì)如何并解釋之?五、釋放內(nèi)存需考慮在發(fā)生異常時(shí),如何正確釋放動(dòng)態(tài)分配的內(nèi)存;否則,可能產(chǎn)生內(nèi)存泄漏。B-4new(B.4)如下:}}}cout<<endl; system("pause");B.4B-4的輸出結(jié)果cout<<"異常釋放"<<endl;for(inti=0;i<3i++) //驗(yàn)證釋放和不釋放cout<<p[i] //的數(shù)據(jù)變化情況//New函數(shù)}int main(){try{New();}catch(int*p){//delete[]p;cout<<"\n正常釋放"<<endl;delete[]p;//int*catch處//103、120、123實(shí)驗(yàn)//元素為0int*p=new int[3];for(inti=0;i<3;i++){cin>>p[i];if(p[i]==0){cout<<"異常"<<endl;throw p;}cout<<p[i]<<"";}5678910111213141516171819202122232425262728#include<iostream>usingnamespacestd;void Newvoid //可能拋出異常4 {12catch16delete[p得不到執(zhí)行,new23catch子句中釋放(本例已注釋。思考與練習(xí):1)103和12012正常2)231六、異常析構(gòu)例B-5編程實(shí)驗(yàn):異常時(shí)調(diào)用析構(gòu)函數(shù)。程序代碼及輸出結(jié)果(圖B.5)如下:}}cout<<"main繼續(xù)"<<endl;system("pause");}{coutIDidendl}catch(intid)B-5的輸出結(jié)果B.5//S1S2//異常時(shí)得不到執(zhí)行S1.data();S2.data();};int main(){//Student S180非法//Student S290合法try{Student S180非法);Student S290合法}//IDint異常if(ID<90) throwID;#include<iostream>#include<string>usingnamespacestd;class Student{int ID;string name;public:Student(intn,conststring&name):ID(n),name(name){cout<<"構(gòu)造: ID="<<ID<<endl;}virtual~Student(){cout<<"析構(gòu): ID="<<ID<<endl;}void data(void) throw(int){cout<<"data():"<<ID<<","<<name<<endl;cout<<"---------------\n";123456789101112131415161718192021222324252627282930313233第17行:檢查ID合法性。ID<90為非法,拋出異常。第25、26行:創(chuàng)建對(duì)象S1和S2,生命期限于try{}花括號(hào)內(nèi)。27try{}子句,此時(shí)釋放(析構(gòu))S1S2;catch子句執(zhí)行(30行。思考與練習(xí):(1)注釋第25、26行且不注釋第22、23行,結(jié)果有什么變化?解釋之。2)繼續(xù)1七、拋出對(duì)象可以將異常的相關(guān)信息封裝到類中,用throw拋出它的對(duì)象。例B-6編程實(shí)驗(yàn):拋出無信息的異常對(duì)象。程序代碼及輸出結(jié)果(圖B.6)如下:#include#include<iostream>usingnamespacestd;class intRange4 {int input,lower,upper;public:class tooLow{};class tooHigh{};//檢查整數(shù)范圍(拋出異常對(duì)象)//inputlowerupper//嵌套定義類(空類)//嵌套定義類(空類)9 intRange(intlow,inthigh):lower(low),upper(high){}101112131415161718192021222324252627282930int getInput(void){cin>>input;if(input<lower)if(input>upper)returninput;}//輸入檢查,拋出異常throwthrowtooLow();tooHigh();//拋出無名對(duì)象//拋出無名對(duì)象};int main(){intRange range(5,9);int cout<<"輸入整數(shù)(5~9):";try{userValue=range.getInput();cout<<userValue<<"有效\n";}catch(intRange::tooLow&){cout<<"數(shù)值太小\n";}catch(intRange::tooHigh&){cout<<"數(shù)值太大\n";}cout<<"main繼續(xù)...\n";B.6B-6的輸出結(jié)果31 31 system("pause");32}B-7(B.7)如下:cout<<obj.value<<":cout<<obj.value<<":太小\n";cout<<obj.value<<":太大\n";//捕獲同類異常B.7B-7的輸出結(jié)果};int main(){intRange range(5,9);int cout<<"輸入整數(shù)(5~9):";try{range.getInput();cout有效\n";}catch(intRange::OutOfRange&obj){if(obj.value<range.getlower())if(obj.value>range.getupper())}}//拋出其無名對(duì)象if(input<lower||input>upper)throw OutOfRange(input);returninput;//輸入檢查,拋出異常int getInput(void){cin>>input;};int getlower(void){returnlower;}int getupper(void){returnupper;}intRange(intlow,inthigh):lower(low),upper(high){}//異常數(shù)據(jù)OutOfRange(inti):value(i){}//嵌套類(拋出其對(duì)象)class OutOfRange{public:int value;//輸入整數(shù)及上限、下限7891011121314151617181920212223242526272829303132333435363738//檢查整數(shù)范圍(拋出異常對(duì)象)#include<iostream>usingnamespacestd;class intRange4 {int input,lower,upper;public:coutmaincoutmain繼續(xù)...\n";system("pause");41}附錄C 命名空間。為避免命名沖突,把命名作用域naespac或稱為名字空間C(全局C++補(bǔ)充了類作用域和命名空間作用域。不同作用域中的成員可以同名,彼此獨(dú)立、互不干擾。一、聲明與使用例C-1編程實(shí)驗(yàn):聲明命名空間、訪問空間內(nèi)成員的三種方式。程序代碼及輸出結(jié)果(圖C.1)如下:////using聲明空間內(nèi)成員cout<<"------------\n";using ns2::m;C.1C-1的輸出結(jié)果//ns1::m=1;//ns1::fun();//②命名空間域名限定m=10;fun();ns2::fun();ns2::m=20;ns2::fun();//m?void FUNC(void){cout<<"m="<<m<<endl;}int main(){//①using聲明整個(gè)命名空間//ERRORmfunstd;ns1;ns2;namespacenamespacenamespace};//usingusing//usingfun(void){ cout<<"ns2::m="<<m<<endl; }void//ns2};//using namespace ns1;namespace ns2{int m;void fun(void){cout<<"ns1::m="<<m<<endl;}std; //系統(tǒng)命名空間ns1; //ERROR:ns1還沒聲明//聲明命名空間ns1#include<iostream>using namespace//using namespacenamespace ns1{int m;123456789101112131415161718192021222324252627 m27 m=30; //ns2::m28 fun(); //ns1::fun();29 ns2::fun();30 cout<<"------------\n";FUNC();//using ns1::m;system("pause");34}第2、14行:using指令在全局范圍(文件作用域)聲明整個(gè)命名空間。第22行:用命名空間域名限定成員,一次有效。26行:using聲明命名空間成員(main函數(shù)作用域。某作用域中using聲明后,在該作用域中一直有效,不能重復(fù)聲明。思考與練習(xí):(1)注釋第2行且不注釋第13行,結(jié)果會(huì)如何?(2)不注釋第3行且注釋第14行,結(jié)果會(huì)如何?(3)注釋第14行且不注釋第8行,結(jié)果會(huì)如何?(4)不注釋第15行,結(jié)果會(huì)如何?(5)不注釋第32行,結(jié)果會(huì)如何?例C-2編程實(shí)驗(yàn):名字相同的命名空間是同一個(gè)命名空間。程序代碼如下:}}system("pause");//輸出func()//輸出func():10}int main(){NS::func();NS::func(10);void funcintmcoutfunc():mendl;}//重載函數(shù)//ERROER:重定義//int a;//重載函數(shù)#include<iostream>usingnamespacestd;namespaceNS{int a;void func(void){cout<<"func()"<<endl;}}namespaceNS{123456789101112131415161718二、嵌套聲明與別名命名空間可以嵌套聲明,還可以取別名。例C-3編程實(shí)驗(yàn):命名空間嵌套與別名。程序代碼及輸出結(jié)果(圖C.2)如下:}}C.2C-3的輸出結(jié)果cout<<"ns2::m="<<ns1::ns2::m<<endl;//cout<<"ns2::m="<<n2::m<<endl;//命名空間別名//命名空間別名}void FUN(void);int main(){namespace n1=ns1;namespace n2=ns1::ns2;n1::m=10;n2::m=20;n2::fun2();FUN();system("pause");}void FUN(void){}//ns1成員//ns2void fun2(void){fun1();}{ cout<<"ns1::m="<<m<<endl; }//嵌套子空間//父空間#include<iostream>usingnamespacestd;namespacens1{int m;void fun1(void)namespace ns2{int m;12345678910111213141516171819202122232425262728聲明命名空間別名,可以縮短命名空間的名字。思考與練習(xí):(1)注釋第26行且不注釋第27行,結(jié)果會(huì)如何?(2)不用命名空間別名,該如何修改程序?三、內(nèi)聯(lián)命名空間C++11例C-4編程實(shí)驗(yàn):內(nèi)聯(lián)子空間與程序版本控制。程序代碼及輸出結(jié)果如下:ParentParent;//m=20//m=10}int main(){using namespacefun();old_ns::fun();system("pause");}}void fun(void){cout<<"m="<<m<<endl;}//新值m=20;namespace new_ns //新版取代舊版(Parent成員)inline{int10111213141516171819202122fun(void){cout<<"m="<<m<<endl;}void//舊值int m=10;789 }#include<iostream>usingnamespacestd;namespace Parent4 {5 namespace old_ns //舊版6 {C-5C-4內(nèi)聯(lián)空間。程序代碼及輸出結(jié)果如下://usingnamespace//usingnamespacenew_ns;fun; //m=20voidfun(void){cout<<"m="<<m<<endl;}}int main(){//非內(nèi)聯(lián)空間//內(nèi)聯(lián)空間//namespace new_nsinline namespace new_ns{int m=20;#include<iostream>usingnamespacestd;namespaceold_ns{int m=10;voidfun(void){cout<<"m="<<m<<endl;}}123456789101112131415old_ns::old_ns::fun //m=10system("pause");20}若不用內(nèi)聯(lián)命名空間,則注釋第9行且不注釋第8行和第16行。C-6編程實(shí)驗(yàn):內(nèi)聯(lián)命名空間應(yīng)用例。1.02.0版,新類庫(kù)可以自由使用,舊類庫(kù)也可繼續(xù)使用。實(shí)現(xiàn)方式:用命名空間重新封裝類(原類庫(kù)沒用命名空間封裝。程序代碼及輸出結(jié)果(圖C.3)如下:#include#include<iostream>usingnamespacestd;namespace ver1 //v1.04 {classA{ int a1;public:891011121314151617181920212223242526272829303132A(inta1):a1(a1){}void fun(){cout<<"a1="<<a1<<endl;}};classB{ int b1;public:B(intb1):b1(b1){}void fun(){cout<<"b1="<<b1<<endl;}};}inline namespace{classA{ int a1,a2;public:A(inta1,intvoid fun()ver2//v2.0//a2a2):a1(a1),a2(a2){}{cout<<"a1="<<a1<<",a2="<<a2<<endl;}};classB{ int b1,b2;public://b2B(intb1,intb2):b1(b1),b2(b2){}voidfun(){cout<<"b1="<<b1<<",b2="<<b2<<endl;}3334333435363738394041424344454647484950515253545556};}void test1(){//1.0版cout<<"=====1.0版=====\n";ver1::Aa1(1);a1.fun();ver1::B b1(2);b1.fun();//舊版可用,需加域名限定//舊版可用,需加域名限定}void test2 //2.0版{cout<<"=====2.0版=====\n";Aa2(10,100);a2.fun();B b2(20,200);b2.fun();//A//B}int main(){test1(); //1.0test2(); //2.0system("pause");}圖C.3例C-6的輸出結(jié)果四、匿名命名空間匿名命名空間即沒名字的命名空間,也稱無名命名空間。C++提倡用它取代static全局變量和函數(shù),限制空間中成員的所在域,即僅在本單元文件使用,其他單元文件不能用。例C-7編程實(shí)驗(yàn):無名命名空間的使用。程序代碼如下:1 1 //=============“1.cpp”==============#include<iostream>classA{ public:void member(){std::cout1.cppstd::endl;}6 };7 namespace //無名(匿名)8 {void test //statictest{Aa;a.member();12 }13}}}system("pause");//鏈接錯(cuò):無法解析外部命令(extern)test();//=============“源2.cpp”==============#include<iostream>usingnamespacestd;externvoidtest();int main(){//test/*static void test(){Aa;a.member();}*/14151617181920212223242526例C-8編程實(shí)驗(yàn):不同單元文件的同名命名空間屬于同一個(gè)命名空間。程序代碼如下:////輸出:OK!system("pause");}//1.cppNS是同一個(gè)test(void); }namespace NS{ extern voidint main(){ NS::test();}//=============“源2.cpp”==============#include<iostream>//NS//無名子空間(內(nèi)聯(lián)或不內(nèi)聯(lián))//inline namespace//{void test(void){Aa;a.member();}//}//=============“源1.cpp”==============#include<iostream>namespace NS{classA{ public:void member(){std::cout<<"OK!"<<std::endl;}};12345678910111213141516171819202122思考與練習(xí):(1)第3行和19行:將兩個(gè)命名空間改為不同的名字,結(jié)果會(huì)如何?(2)不注釋第9、10、

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論