第 2 章 C++的變量、類型及函數(shù)_第1頁
第 2 章 C++的變量、類型及函數(shù)_第2頁
第 2 章 C++的變量、類型及函數(shù)_第3頁
第 2 章 C++的變量、類型及函數(shù)_第4頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第2章C++的變量、類型及函數(shù)2.1若給出聲明:charc,*pc;constcharcc=,a;constchar*pcc;char*constcpc=&c;constchar*constcpcc=&cc;char*const*pcpc;則下面的賦值哪些是合法的?哪些是非法的,為什么?(1)c=cc; (10)*pc="ABCD"[2];cc=c; (11)cc='a';pcc=&c;(12)*cpc=*pc;pcc=&cc;(13)pc=*pcpc;pc=&c;(14)**pcpc=*pc;pc=&cc,(15)*pc=**pcpc;pc=pcc;(16)*pcc='b';pc=cpcc;(17)*pcpc=,c,;cpc=pc:(18)*cpcc='d';解:(1)合法c不是const類型的變量,可以賦值?(2)非法cc是const類型的變量?不能賦值?(3)合法?pcc不是const類型的指針變量?可以指向非const類型的字符變量?(4)合法?pcc不是const類型的變量?賦值后指向的cc的類型為constchar?同其要求指向的類型一致?(5)合法?pc不是const類型的指針變量?賦值后指向的c的類型為char?同其要求指向的類型一致?(6)非法?pc要求指向char類型的變量?不能用constchar*類型的&c賦值?(7)非法?pc要求指向char類型的變量?不能用指向constchar*類型的pcc賦值?(8)非法?pc要求指向char類型的變量?不能用指向constchar*類型的cpcc賦值?(9)非法?cpc是const類型的變量?不能賦值?(10)合法?pc指向的是非const類型的變量?可以賦值?等價于*pc='C'?(11)非法?cc是const類型的變量?不能賦值?(12)合法?cpc指向的是非const類型的變量?可以賦值?(13)合法?pc是非const類型的指針變量?可以用char*類型的值*pcpc賦值?(14)合法?**pcpc代表的是非const類型的字符變量?可以任何字符類型的值賦值?(15)合法?*pc代表的是非const類型的字符變量?可以任何字符類型的值賦值?(16)非法?*pcc代表的字符是const類型的字符變量?不能賦值?(17)非法?*pcpc代表的是const類型的指針變量?不能賦值?(18)非法?*cpcc代表的是const類型的只讀變量?不能賦值?2.2頭文件string,h定義了函數(shù)原型char*strcat(char*dest,constchar*src)?定義函數(shù)strcat的函數(shù)體?使其將src指示的字符串添加到dest指示的字符串的后面?并將調(diào)用時dest的值作為函數(shù)的返回值?解:注意strcat的返回值和傳入第一個參數(shù)的值相同?char*strcat(char*dest,constchar*src){char*temp=dest:while(*temp)temp++;while(*(temp++)-*(src++));returndest;)C按優(yōu)先級和結合性解釋類型?下述聲明是什么意思?typedefvoidVF_PC_RI(char*,int&)typedefVF_PC_RI*P_VF_PC_RI;typedefint&RIFFII(int,int);externVF_PC_RIfunca;externPVF_PC_RIptra;externvoidfund(P_VF_PC_RI*);externPVFPC_RIfunc2(intc);P_VF_PC_RIfunc3(P_VF_PC_RIa);typedefvoid(*(**VF_PA_P.PFV(void))[])(constint);解:(D定義一個名為VF_PC_RI的類型?該類型定義了一個參數(shù)為(char*,int&)沒有返回值的函數(shù)?(2)定義一個名為P_VF_PC_RI的類型?該類型定義了一個指向VF_PC_RI類型的指針?(3)定義一個名為RIFFH的類型,該類型定義了一個參數(shù)為(int,int)返回一個引用的函數(shù)?該引用引用一個整型量?(4)說明一個類型為VF_PC_RI的函數(shù)funca?(5)說明一個類型為P_VF_PC_RI的指針變量ptra?(6)說明一個沒有返回值的函數(shù)fund?該函數(shù)的參數(shù)是一個指向P_VF_PC_RI類型的指針?(7)說明一個參數(shù)為int類型的函數(shù)func2?該函數(shù)的返回值是一個P_VF_PC_RI類型的指針?(8)說明一個參數(shù)為P_VF_PC_RI類型的函數(shù)func3?該函數(shù)的返回值是一個P_VF_PC_RI類型的指針?(9)定義一個名為VF_PA_P_PF_V的類型?該類型定義了一個沒有參數(shù)的函數(shù)?該函數(shù)返回一個指針?該指針又指向另一個指針?被指向的指針指向一個數(shù)組?數(shù)組的每個元素存放一個函數(shù)指針?該函數(shù)指針指向一個參數(shù)為constint類型沒有返回值的函數(shù)?運行如下程序?打印結果ri和gi相等嗎?為什么?刪除printf語句中的8?結果有什么變化?再刪除printf語句中的7?結果又有什么變化?^include<stdio.h>int&f(){inti=10;int&j=i;returnj;}intg(){intj=20;returnj;}voidmain(void){int&ri=f();intrj=g();printf("ri=%d\trj=%d\n”,ri,rj,1,2,3,4,5,6,7,8);int&gi=f();intgj=g();printf("gi=%d\tgj=%d\n”,gi,gj);解:(1)打印結果ri和gi不等?(2)這是因為主調(diào)函數(shù)main的變量引用了被調(diào)函數(shù)f()的局部自動變量i?該變量的內(nèi)存是位于棧上的某個固定位置?該位置的值會被其他函數(shù)調(diào)用傳遞參數(shù)改變?例如被調(diào)用rj=g()和調(diào)用printf("ri=%d\trj二%d\n",ri,rj,1,2,3,4,5,6,7,8)改變?因為值參傳遞也是通過棧完成的?(3)刪除printf語句中的8?ri的輸出結果由原來的6變?yōu)??(4)再刪除printf語句中的7?ri的輸出結果由原來的5變?yōu)??即ri的值總是打印其值的printf函數(shù)調(diào)用的倒數(shù)第三個參數(shù)?如下聲明和定義是否會導致編譯錯誤?floatg(int);intg(int);int g(int,inty=3);int g(int,L);inti=g(8);解:(1)不能定義返回類型僅和floatg(int)不同的函數(shù)intg(int)?g(8)在調(diào)用時出現(xiàn)二義性?無法確定是調(diào)用intg(int,inty=3)還是intg(int,L)?2.6定義函數(shù)求1個以上的整數(shù)中的最大值intmax(intc,??)?整數(shù)個數(shù)山參數(shù)c指定?解:山于參數(shù)個數(shù)沒有固定?因此要應用省略參數(shù)?intmax(intc,...){intm,k,*p=&c+l;m=p[0];for(k=l;k<c;k++)if(m<p[k])m=p[k];returnm;}voidmain(){intm;m=max(3,4,8,10);m=max(4,6,8,5,4);}第3章C++的類二叉樹類的頭文件node,h如下?請定義其中的函數(shù)成員?classN0DE{char*data;NODE*left,*right;public:NODE(char*);NODE(char*data?NODE*left,NODE*right);~NODE();};解:以下程序構造函數(shù)申請了內(nèi)存?必須在析購函數(shù)釋放?#include<string.h>〃在此引用上述類型說明NODE::NODE(char*){if(NODE::data=newchar[strlen(data)+1]){strcpy(NODE::data,data);left=right=O;)}NODE::NODE(char*data,NODE*left,NODE*right){if(NODE::data=newchar[strlen(data)+1]){strcpy(NODE::data,data);NODE::left=left;NODE::right=right;}}NODE:rNODE(){if(left)left->~NODE();if(right)right->~NODE();if(data){deletedata;data=0;}隊列(queue)就是一種先進先出表?隊列通常有插入?刪除?測空和清除四種操作?“插入”即將一個元素插到隊列尾部?“刪除”就是從隊列首部取走一個元素?“測空”就是要檢查隊列是否為空?當隊列為空時返回1?否則返回0?“清除”就是將隊列清空?用鏈表定義一個字符隊列?并定義完成上述操作的公有成員函數(shù)?解:以下程序沒有使用循環(huán)對列?其出入隊列操作次數(shù)有限?classQUEUE{char*queue;intsize,front,rear;public:intinsert(charelem);intremove(char&elem);QUEUE(intsize);"QUEUE(void););QUEUE::QUEUE(intsz)(queue=newchar[size=sz];front=0rear=0;}QUEUE::"QUEUE(void){if(queue){deletequeue;queue=O;front=0;rear=O;intQUEUE::insert(charelem){if(rear=size)return0;queue[rear++]=elem;return1;)intQUEUE::remove(char&elem){if(front==rear)return0;elem=queue[front=front+l];return1;)voidmain(void){QUEUEqueue(20);}4改用數(shù)組定義習題3.3中的字符隊列?并將該隊列定義為循環(huán)隊列?使隊列的“插入”?“刪除”操作能并發(fā)進行?其他公有函數(shù)成員的原型不變?解:注意?函數(shù)成員insert和remove的尾部帶有volatile?表示函數(shù)的隱含參數(shù)this的類型為volatile*constthis?即this指向的當前對象是揮發(fā)易變的?揮發(fā)性通??梢杂脕硇揎棽⑿胁僮鞯膶ο??即當前隊列是可以同時進行插入和刪除操作的?構造函數(shù)和析構函數(shù)不能用volatile?因為構造和析構時對象必須是穩(wěn)定的?以下程序使用字符數(shù)組作為循環(huán)隊列?classQUEUE{char*queue;intsize,front,rear;public:intinsert(charelem)volatile;intremove(charftelem)volatile;QUEUE(intsize);?QUEUE(void););QUEUE::QUEUE(intsz)(queue=newchar[size=sz];front=rear=0;}QUEUE::"QUEUE(void){if(queue){deletequeue;queue=0;front=0;rear=O;intQUEUE::insert(charelem)volatile(if((rear+l)%size==front)return0;queue[rear=(rear+l)%size]=e1em;return1:)intQUEUE::remove(char&elem)volatile(if(rear==front)return0;elem=queue[front=(front+l)%size];return1;}voidmain(void)(QUEUEqueue(20);3.6線性表通常提供元素查找?插入和刪除等功能?以下線性表是一個整型線性表?表元素存放在動態(tài)申請的內(nèi)存中?請編程定義整型線性表的函數(shù)成員?classINTLIST{int*list; /動態(tài)申請的內(nèi)存的指針intsize; //線性表能夠存放的元素個數(shù)intused; 〃線性表已經(jīng)存放的元素個數(shù)public:INTLIST(ints);〃s為線性表能夠存放的元素個數(shù)intinsert(intv): //插入元素v成功時返回1?否則返回0intremove(intv);〃刪除元素v成功時返回1?否則返回0intfind(intv);〃查找元素v成功時返回1?否則返回0intget(intk); //取表的第k個元素的值作為返回值'lNTLIST(void););解:構造函數(shù)申請了內(nèi)存資源?必須在析構函數(shù)釋放?〃在此引用上述類型說明INTLIST::INTLIST(ints){if(list=newint[s]){size=s;used=0;INTLIST::"lNTLIST(void){if(list){deletelist;list=0;size=used=0;}intINTLIST::insert(intv){if(used<size){list[used++]=v;return1;)return0;}intINTLIST::remove(intv){for(inti=0;i<used;i++)if(list[i]==v){used一;for(;i<used;i++)list[i]=list[i+1];return1;)return0;)intINTLIST::find(intv){for(inti=0;i<used;i++)if(list[i]==v)return1;return0;)第4章作用域及成員指針為什么要引入名字空間?名字空間能否在函數(shù)內(nèi)部定義?解:名字空間是C++引入的-種新的作用域?用于減少軟件項目中的命名沖突?同一名字空間中的標識符名必須唯一?不同名字空間中的標識符名可以相同?名字空間必須在程序的全局作用域內(nèi)定義?不能在函數(shù)及函數(shù)成員內(nèi)定義?匿名名字空間能否分多次定義?它和沒有對象的匿名聯(lián)合有何區(qū)別?解:名字空間包括匿名名字空間可以分多次定義?即可以先在初始定義中定義一部分成員?然后在擴展定義中再定義另一部分成員?或者再定義初始定義聲明的函數(shù)原型?匿名名字空間的作用域規(guī)則和沒有對象的匿名聯(lián)合相同?但匿名名字空間不能看作類?盡管它可以定義類型?變量及函數(shù)等?匿名名字空間的局部變量內(nèi)存是獨立分配的?而沒有對象的匿名聯(lián)合的成員變量是共享內(nèi)存的?匿名名字空間只能在函數(shù)的外面定義?而沒有對象的匿名聯(lián)合可在函數(shù)的內(nèi)部定義?為統(tǒng)計正文的單詞定義一個類?其類型聲明的頭文件word.h如下:classW0RD{char*word;intcount;public:intgettimes()const;intinctimes();constchar*getword()const;WORD(constchar*);、WORD();};定義其中的函數(shù)成員?要求構造函數(shù)使用new為結點分配空間?析構函數(shù)使用delete回收分配的空間?解:構造函數(shù)申請了內(nèi)存資源?必須在析構函數(shù)釋放?〃在此引用上述類型說明intWORD::gettimes()const{returncount;}intWORD::inctimes(){return++count;}constchar*WORD::getword()const{returnword;}WORD::WORD(constchar*w){if(word=newchar[strlen(w)+l])strcpy(word,w);count=0;)WORD::"WORD(){if(word){deleteword;word=0;}}利用上述WORD類實現(xiàn)一個單詞表?其類型WORDS定義如下:^include<string.h>#include<iostream.h>#include"word,h”classWORDS{WORD*words;intcount,total;public:intinsert(constchar*);WORD*constfind(constchar*);WORDS(inttotal);"WORDS();};voidmain(void)(WORDSws(20);ws.insert("amour");ws.find("amour")->gettimes();ws.find(//amour,z)->inctimes();cout?*Timesofamour=*;cout<<ws.find("amour")-〉gettimes();)請定義其中的函數(shù)成員?并用main進行測試?解:構造函數(shù)申請了內(nèi)存資源?必須在析構函數(shù)釋放?尤其要注意new(&words[count++])WORD(w)的用法?表示利用已有對象的存儲單元重新構造該對象?WORDS的函數(shù)成員定義如下:^include<string.h>#include<alloc.h>WORDS::WORDS(inttotal){words=(W0RD*)malloc(total*sizeof(WORD));if(words){count=0;WORDS::total=total;})WORDS::"WORDS(){for(intx=0;x<count;x++)words[x].'WORD();free(words);)intWORDS::insert(constchar*w){if(find(w))return0;new(&words[count++])WORD(w);return1;}WORD*constWORDS::find(constchar*w){for(intk=0;k<count;k++)if(strcmp(w,words[k].getword())==0)return&words[k];return0;)4.6定義一個雜湊表類?要求用數(shù)組存放雜湊表元素?以字符串作關鍵字存放和查找表元素?并提供用于插入?查詢和刪除雜湊表元素的public函數(shù)成員?#include<string.h>^include<alloc.h>classHASH{classNODE{intvalue;NODE*next;public:intgetvalue(){returnvalue;}NODE*getnext(){returnnext;}NODE*setnext(NODE*n){next=n;returnthis;}NODE(intv,NODE*n){value=v;next=n;}“NODE(){if(next)deletenext;}};structBARREL{char*s;NODE*n;}*h;intc;constintt;public:HASH(intm);NODE*lookup(constchar*s,intv);intinsert(constchar*s,intv);intremove(constchar*s,intv);?HASH();解:注意NODE是局部于HASH的類型?請注意以下lookup函數(shù)的返回類型?〃在此引用上述類型說明HASH::HASH(intm):t((h=newBARREL[m])?m:0),c(0){}HASH::NODE*HASH::lookup(constchar*s,intv){for(intk=0;k<c;k++)if(strcmp(s,h[k].s)==0){NODE*p=h[k].n;while(p!=0){if(p->getvalue()==v)returnp;P=p—>getnext();))return0;)intHASH::insert(constchar*s,intv){for(intk=0;k<c;k++)if(strcmp(s,h[k].s)==0){h[k].n=newNODE(v,h[k].n);return1;}if(c<t){h[c].s=newchar[strlen(s)+l];strcpy(h[c].s,s);h[c++].n=newNODE(v,0);return1;}return0;)intHASH::remove(constchar*s,intv){for(intk=0;k<c;k++)if(strcmp(s,h[k].s)==0){NODE*p,*q=h[k].n;if((p=q)==0)return0;if(p->getvalue()==v){h[k].n=p->getnext();free(p);return1;}while(p=p->getnext()){if(p->getvalue()==v){q->setnext(p->getnext());free(p);return1;q二p;return0;}HASH::"HASH(){for(intk=0;k<c;k++)deleteh[k].n;deleteh;}voidmain(){HASHh(10);h.insert(*A*,1);h.insert("A",2);h.remove("A",1);h.insert("A",3);h.insert("B",1);h.insert("B",2);)4.8定義二維坐標系上的三角形類?要求該類提供計算面積和周長的函數(shù)成員?計算時不能改變類的任何數(shù)據(jù)成員的值?解:由于計算時不能改變類當前對象任何數(shù)據(jù)成員的值?故計算函數(shù)的隱含參數(shù)this必須用const修飾?即在計算函數(shù)的參數(shù)表后加上const?#include<math.h>classTRIANGLE{doublexl,yl,x2,y2,x3,y3;public:TRIANGLE(doublexl,doubleyl,doublex2,doubley2,doublex3,doubley3);doublearea()const;doubleperimeter()const;};TRIANGLE::TRIANGLE(doublexl,doubleyl,doublex2,doubley2,doublex3,doubley3){TRIANGLE::xl=xl;TRIANGLE::yl=yl;TRIANGLE::x2=x2;TRIANGLE::y2=y2;TRIANGLE::x3=x3;TRIANGLE::y3=y3;)doubleTRIANGLE::area()const{returnabs((yl+y3)*(x3-xl)+(yl+y2)*(xl-x2)+(y2+y3)*(x2-x3))/2;doubleTRIANGLE::perimeter()const{doublesl=sqrt(pow(xl-x2,2)+pow(yl-y2,2));doubles2=sqrt(pow(xl-x3,2)+pow(yl-y3,2));doubles3=sqrt(pow(x3-x2,2)+pow(y3-y2,2))returnsl+s2+s3;}4.10完成如下棧類STACK的函數(shù)成員定義?STACK類的頭文件stack.h的內(nèi)容如下:#include<string.h>#include<iostream.h>classSTACK{constintmax; 〃棧能存放的最大元素個數(shù)inttop; 〃棧頂元素位置char*stk;public:STACK(intmax);"STACK();intpush(charv);〃將v壓棧,成功時返回1,否則返回0intpop(char&v);〃彈出棧頂元素,成功時返回1,否則返回0};解:注意STACK中的const數(shù)據(jù)成員max?其初始化不能在構造函數(shù)的函數(shù)體內(nèi)完成?此外?引用類型和類類型的成員也不能在構造函數(shù)的函數(shù)體內(nèi)完成?〃在此引用上述類型說明STACK::STACK(intmax):top(0),max((stk=newchar[max])?max:0){}STACK::?STACK(){if(stk){deletestk;stk=0;}}intSTACK::push(charv){if(top>=max)return0;stk[top++]=v;return1;}intSTACK::pop(char&v){if(top<=l)return0;v=stk[—top]=v;return1;)第5章靜態(tài)成員與友元定義一個類RANDOM?該類的構造函數(shù)用來指定隨機數(shù)的分布參數(shù)?在對象不同而分布參數(shù)相同的情況下?構造函數(shù)自動地使分布參數(shù)互不相同?該類的函數(shù)rand用于返回下一個隨機數(shù)?解:在面向對象的程序設計中?注意應用對象識別標志的唯一性?即使對象的構造函數(shù)的參數(shù)完全相同?但對象的識別標志是唯一性的?據(jù)此可使隨機數(shù)的分布參數(shù)互不相同?在C++中?對象的首地址即隱含參數(shù)this可作為對象的唯一性識別標志?classRANDOM{intm,r,f,y;public:RANDOM(intmod,intran,intfac);intgetran(););RANDOM::RANDOM(intmod,intran,intfac)(m=mod;r=ran;f=fac;y=(int)this;}intRANDOM::getran(){returnr=(r*f+y)%m;}定義節(jié)點類NODE和棧類STACK?棧元素由節(jié)點構成并形成節(jié)點鏈表?壓棧時將節(jié)點加入棧的鏈首?出棧時從棧的鏈首刪除節(jié)點?解:注意NODE的構造函數(shù)?提供了為STACK元素形成鏈表的潛在功能?classNODE{intvalue;NODE*next;public:NODE(intvalue,NODE*next);intgetv(){returnvalue;};NODE*getn(){returnnext;};);NODE::NODE(intv,NODE*n){value二v;next=n;}classSTACK{NODE*head;public:STACK(){head=0;};intpush(v);intpop(int&v);"STACK();};intSTACK::push(intv){NODE*p=newN0DE(v,head);if(p!=O)head=p;returnp!=0;)intSTACK::pop(int&v){NODE*p=head;if(head==0)return0;v=head->getv();head=head->getn();deletep;return1;STACK::"STACK()(NODE*q,*p=head;while(p!=0){q=p->getn();deletep;p=q;定義三維坐標系的POINT類?并完成POINT聲明中的函數(shù)成員定義?classPOINT{intx,y,z;staticinttotal;〃點的總個數(shù)public:POINT();POINT(int,int,int);"POINT();staticintnumber();〃返回點的個數(shù));解:靜態(tài)數(shù)據(jù)成員total用于存放類型的總體信息?在面向的對象的思想中稱之為類變量?而普通數(shù)據(jù)成員如x等則稱為類實例變量?同理?number和POINT()等分別被稱為類函數(shù)和類實例函數(shù)?類的總體信息即對象個數(shù)total可通過構造函數(shù)和析構維護?〃在此引用上述類型說明intPOINT::total=0;POINT::POINT(){x=y=z=0;total++;}POINT::POINT(intx,inty,intz){POINT::x=x;POINT::y=y;POINT::z=z;total++;)POINT::"POINT(){total—;}intPOINT::number(){returntotal;}現(xiàn)有一棵二叉樹和一個有序數(shù)組?要求通過這棵二叉樹構造有序數(shù)組?它們的類型聲明如下?請定義有序數(shù)組的構造函數(shù)?classSEQUENCE;classTREE{intitem;TREE*left,*right;friendSEQUENCE;public:〃…);classSEQUENCE{int*items;intsize;public:SEQUENCE(TREE&);};解:本習題主要考查如何為對象添加所需要的函數(shù)成員?classSEQUENCE;classTREE{intitem;TREE*left,*right;friendSEQUENCE;public:intgetnodes();intgetnodes(int*iterns);TREE(intv,TREE*1,TREE*r):item(v),left(l),right(r){};);intTREE::getnodes(){int1=0,r=0;if(left)l=left->getnodes();if(right)r=right->getnodes();return1+r+l;)intTREE::getnodes(int*items){intn=0;if(left)n=left->getnodes(items);iterns[n++]=TREE::item;if(right)n=n+right->getnodes(items);returnn;)classSEQUENCE(int*iterns;intsize;public:SEQUENCE(TREE&););SEQUENCE:SEQUENCE(TREE&t){intm;items=newint[size=t.getnodes()];t.getnodes(items);現(xiàn)欲通過有序數(shù)組構造二義樹?請定義二叉樹的構造函數(shù)(提示:可將數(shù)組平均分成兩個部分?將中間的數(shù)組元素作為根?將二邊的數(shù)組元素分別作為根的左?右子樹?重復上述過程便可以得到基本平衡的二叉樹)?解:任何函數(shù)都是可以遞歸調(diào)用的?但要注意控制遞歸結束的條件?以下程序通過遞歸調(diào)用構造函數(shù)構造二叉樹?classTREE{intitem;TREE*left,*right;public:TREE(int*a,intt););TREE::TREE(int*a,intt){intx=t/2;item=a[x];left=(x>l)?newTREE(a,x-1):0;right=(t>x+1)?newTREE(a+x+1,t-x-l):0;)voidmain(){staticints[10]={l,2,3,4,5,6,7,8,9,10);TREEt(s,10);)請指出如下程序中的錯誤之處:classA{inta;staticfriendintf();friendintg();public:friendintA();A(int);}a(5);intg(){returna.a;}解:在staticfriendintf()中?static和friend不能同時出現(xiàn)?注意不要把intA()當作構造函數(shù)?該非成員函數(shù)可以在函數(shù)g的后面定義為intA(){return3;}?但是?如果在函數(shù)名前加上A::則表示要定義成員函數(shù)?顯然?friendintA::A()是錯誤的?因為friend不能用于修飾當前類的成員函數(shù)?而說明A::A(int)則是正確的?因為A::A(int)出現(xiàn)在類A的定義中?故一般情況下A::是可以省略的?定義類描述有限狀態(tài)自動機?狀態(tài)的輸入和輸出關系可以描述為鏈表數(shù)據(jù)成員:classSTATE;classLIST{LIST*next;charinput;STATE*output;LIST(charin,STATE*out);〃私有?僅供STATE使用?LIST();friendSTATE;);classSTATE{char*name;〃狀態(tài)名LIST*list;//輸入及輸出列表staticSTATE*error;public:voidenlist(charin,STATE*out);〃插入listconstSTATE*next(charin)const;//輸入in轉移到下一個狀態(tài)constSTATE*start(char*)const;〃啟動有限自動機STATE(char*name);"STATE();};使用有限自動機編程解決如下問題:有一個人帶著狼?羊和草來到河的左岸?左岸只有一條無人擺渡的船?這個人要從左岸過河到右岸?可是這條船最多只能裝一個人和其他三者之一?否則便會沉沒?如果沒有人看管?狼會吃掉羊?或者羊吃掉草?問如何過河才能保證羊和草的安全?提示:作為有限狀態(tài)自動機的輸入?人單獨過河用字符m表示?人帶狼過河用字符w表示?人帶羊過河用字符s表示?人帶草過河用字符g表示?聲明有限自動機的start?stop以及error狀態(tài)對象?如果start,start("smwsgms")=&stop?則過河成功?否則?如果start,start("smwsgms")==&error?則過河失?。拷猓阂韵露x的類STATE用于表示自動機的狀態(tài)?其中staticSTATE*error表示自動機的錯誤陷阱?進入錯誤陷阱后其他任何輸入都不能改變自動機的狀態(tài)?開始時?人狼羊草都在河的左岸?初試狀態(tài)start表示為"WSGMJ,人帶著羊過河后狀態(tài)變?yōu)?WG_SM",用start,enlist('S',&WG_SM)將這一操作加入狀態(tài)轉移表?自動機的狀態(tài)轉移表存放類LIST中?山以下自動的狀態(tài)轉移圖可知?本題有兩個過河路徑最小解?圖5.1人帶狼羊草過河的有限狀態(tài)自動機#include<string.h>#include<iostream.h>classSTATE;classLIST(LIST*next;charinput;STATE*output;LIST(charin,STATE*out);〃私有?僅供STATE使用?LIST();friendSTATE;};LIST::LIST(charin,STATE*out){input=in;output=out;next=O;}LIST::"LIST(){if(this->next){deletethis->next;})classSTATE{char*name;〃狀態(tài)名LIST*list; 〃輸入及輸出狀態(tài)轉移列表staticSTATE*error;public:voidenlist(charin,STATE*out);〃插入listconstSTATE*next(charin)const;//輸入in轉移到下一個狀態(tài)constSTATE*start(char*)const;〃啟動有限自動機STATE(char*name);"STATE(););STATE*STATE::error=0;STATE::STATE(char*name):name(0),list(0){if(name==0){error=this;return;}STATE::name=newchar[strlen(name)+l];strcpy(STATE::name,name);)voidSTATE::enlist(charin,STATE*out){〃插入listLIST*temp;if(list==0){1ist=newLIST(in,out);return;)temp二newLIST(in,out);temp->next=list;list=temp;)constSTATE*STATE::next(charin)const{〃輸入in轉移到下一個狀態(tài)LIST*temp=list;

if(this==error)returnerror;while(temp)if(temp->input=in)returntemp->output;elsetemp=temp->next;returnerror;}constSTATE*STATE::start(char*s)const{//啟動有限自動機constSTATE*temp=this;while(*s)temp=temp->next(*s++);returntemp;)STATE::"STATE(){if(name){cout?name<</,\n*;deletename;name=0;}if(list)(deletelist;list=0;}voidmainSTATESTATESTATESTATESTATESTATESTATESTATESTATESTATESTATE(){voidmainSTATESTATESTATESTATESTATESTATESTATESTATESTATESTATESTATEstart("WSGM_");stop("WSGM");error(0);WG_SM("WG_SM");WGM_S("WGM_S");G_WSM(*G_WSM*);SGM_W("SGM_W");W_SGM(*W_SGM*);WSM_G("WSM_G");S_WGM(*S_WGM*);SM_WG("SM_WG");start,enlist('S',&WG_SM);WG_SM.enlistCS',WG_SM.enlistCM),WGM_S.enlistCM",WGM_S.enlistCW),WGM_S.enlistCC,G_WSM.enlist('W),W_SGM.enlistCG',G_WSM.enlistCS",SGM_W.enlist('S',SGM_W.enlistCG",S_WGM.enlistCG',W_SGM.enlist('S',WSM_G.enlistCS',WSM_G.enlistCW),S_WGM.enlistCW",SM_WG.enlistCM),SM_WG.enlistCS',&start);WG_SM.enlistCS',WG_SM.enlistCM),WGM_S.enlistCM",WGM_S.enlistCW),WGM_S.enlistCC,G_WSM.enlist('W),W_SGM.enlistCG',G_WSM.enlistCS",SGM_W.enlist('S',SGM_W.enlistCG",S_WGM.enlistCG',W_SGM.enlist('S',WSM_G.enlistCS',WSM_G.enlistCW),S_WGM.enlistCW",SM_WG.enlistCM),SM_WG.enlistCS',&WGM_S);&WG_SM);&G_WSM);&W_SGM);&WGM_S);&WGM_S);&SGM_W);&G_WSM);&S_WGM);&SGM_W);&WSM_G);&W_SGM);&S_WGM);&WSM_G);S_WGM.enlistCM',&SM_WG);&S_WGM);&stop);stop,enlistCS',&SMWG):if(start,start("SMWSGMSSS")==&stop)cout<<"0K";5.10有限自動機也可以解決三個修道士與三個野人的過河問題?假定船最多只能載兩個修道土或者野人,野人服從修道土的指揮?無論何時?只要野人多于修道土?野人就會吃掉修道土?以有限自動機為基礎?編程解決三個修道士與三個野人的過河問題?解:自動機仍然可以使用上述定義?只要改寫主函數(shù)即可?用M表示人?用W表示野人?初始狀態(tài)為"MMMYYYJ?過河動作可以有五種:人單獨過河s?兩個人過河d?野人單獨過河w?兩個野人過河t?人帶著野人過河b?例如?從初始狀態(tài)"MMMYYYJ由人帶著野人過河后狀態(tài)為7MMMYYY"?第6章單繼承類定義一個類LOCATION?用數(shù)據(jù)成員x?y表示該類對象在二維坐標系中的坐標位置?用函數(shù)成員move移動對象坐標位置?然后?以類LOCATION為基類?派生出點類POINT和圓類CIRCLE?定義點類和圓類相應的move和draw函數(shù)?解:在C++中?不能隨意使用父類和子類這兩個概念?當派生方式為public時?基類和派生類才能分別稱為父類和子類?當兩個類或多級派生的類構成父子關系時?父類指針可以直接指向子類對象?父類引用也可以直接引用子類對象?無須在指針或引用變量賦值時進行強制類型轉換?如果沒有構成父子關系?則必須進行進行強制類型轉換?注意?在派生類的成員函數(shù)的函數(shù)體中?無論派生方式是否為public?都認為基類和派生類構成父子關系?ftinclude<stdio.h>classLOCATION{intx,y;public:intgetx(),gety();voidmove(intx,inty);LOCATION(intx,inty););voidLOCATION::move(intx,inty)(LOCATION::x=x;LOCATION::y=y;}intLOCATION::getx(){returnx;}intLOCATION::gety(){returny;}LOCATION::L0CATI0N(intx,inty)(LOCATION::x=x;LOCATION::y=y;)classPOINT:publicLOCATION{//派生方式為public?構成父子關系intvisible;public:intisvisible(){returnvisible;};voiddraw();voidmove(intx,inty);POINT(intx,inty):LOCATION(x,y){visible=0;};};voidPOINT::draw()(visible=l;printf(*drawapoint\n");)voidPOINT::move(intx,inty){visible=l;LOCATION::move(x,y);〃帶類名訪問LOCATION::movetoif(visible)draw();)classCIRCLE:publicPOINT{〃派生方式為public?構成父子關系intr;public:intgetr(){returnr;}voiddraw(){printf("drawacircle'n");};CIRCLE(intx,inty,intr):POINT(x,y){CIRCLE::r=r;};};voidmain(){LOCATION*h;POINT p(2,3);CIRCLE c(3,4,5);h=&p; 〃不需要強制類型轉換:h=(LOCATION*)&ph=&c; 〃不需要強制類型轉換:h=(LOCATION*)&c由點類派生出線段類?點類定義了函數(shù)成員move和draw?請定義線段類的函數(shù)成員?解:山于線段有兩個端點?而單繼承只能提供一個端點?故必須在類LINE中定義另一個端點?由于該端點是POINT類的對象?故這樣的數(shù)據(jù)成員被稱為對象成員?注意?對象成員POIN的初始化不能在LINE構造函數(shù)的函數(shù)體內(nèi)進行?classLINE:publicPOINT{//構成父子關系POINTend; 〃定義對象成員public:intgetsx(){returngetx();}intgetsy(){returngety();}intgetex(){returnend.getx();}intgetey(){returnend.gety();}voiddraw(){printf("drawaline\n");};voidmove(intx,inty){POINT::move(x,y);end.move(x,y);};LINE(intsx,intsy,intex,intey):POINT(sx,sy),end(ex,ey){};};6.4利用第四章練習中的STACK?定義如下REVERSE類的函數(shù)成員?其構造函數(shù)將字符串壓棧?其析構函數(shù)彈出字符并將其打印出來?打印的字符串正好是原字符串的逆序?然后?用main函數(shù)檢驗定義是否正確?ftinclude<stack.h>classREVERSE:STACK{public:REVERSE(char*str);//將字符串壓棧"REVERSE(); 〃按逆序打印字符串);voidmain(void){REVERSEa("abcdefghij");REVERSEbCabcdefghijk");)解:注意?析構是構造的逆序?先定義的后析構?后定義的先析構?先執(zhí)行輸出的是b的析構函數(shù)?后執(zhí)行輸出的是a的析構函數(shù)?ttinclude<string.h>^include<stack.h> 〃在此弓I用STACK的類型說明classREVERSE:STACK{public:REVERSE(char*str);//將字符串壓棧^REVERSE(); 〃按逆序打印字符串};REVERSE::REVERSE(char*str):STACK(strlen(str)){for(ints=0,t=strlen(str);s<t;s++)push(str[s]);)REVERSE::"REVERSE(){charc;while(pop(c))printf("%c",c);)voidmain(void){REVERSEa("abcdefghij");REVERSEb("abcdefghijk");6.6如下程序定義了類WINDOW和類MENU,山這兩個類派生出下拉菜單類PULLMENU和彈出菜單類POPMENU,并進一步派生出帶下拉菜單的窗口類PULLWIND和帶下拉及彈出菜單的窗口類PULLPOPWIND,請補充和完善PULLMENU?POPMENU?PULLWIND和PULLPOPWIND的類型定義?classWINDOW{char*title; 〃窗口的標題char*cover; //用于保存和恢更窗口覆蓋的區(qū)域intx,y; 〃窗口的左上角坐標intw,h; //窗口的寬度和高度staticWINDOW*head;〃窗口鏈?鏈首為最外層窗口public:intmoveto(intx,inty);〃窗口移動到新的坐標voidtop()const; 〃當前窗口成為頂層窗口voidshow()const; 〃顯示窗口?注意窗口的相互覆蓋voidhide()const; 〃消隱窗口?注意窗口的相互覆蓋WINDOW(char*n,intx,inty,intw,inth);"WINDOW();};classMENU{char*title; 〃菜單標題intactive; 〃菜單項是否可選的標志int(*entry)(); 〃該菜單項要執(zhí)行的函數(shù)入口地址public:intshow()const; 〃顯示菜單項intisactive()const; 〃判定菜單項是否可選intsetactive(inta): //設置可選標志并返回設置前的標志int(*setentry(int(*)()))(); 〃設置新入口函數(shù)并返回舊入口函數(shù)的地址intexecute()const; //調(diào)用該菜單項的函數(shù)MENU(char*t,inta,int(*e)());~MENU();};classPULLMENU{MENU(&menus)[]; 〃下拉菜單的各菜單項intcount;〃下拉菜單的菜單項數(shù)//... //其他數(shù)據(jù)成員和函數(shù)成員);classPOPMENU{MENU(&menus)[]; 〃下拉菜單的各菜單項intcount;〃下拉菜單的菜單項數(shù)//... //其他數(shù)據(jù)成員和函數(shù)成員};classPULLWIND:WINDOW(PULLMENUftpullm;//... 〃其他數(shù)據(jù)成員和函數(shù)成員};classPULLPOPWIND:PULLWIND{POPMENUpopm;//... 〃其他數(shù)據(jù)成員和函數(shù)成員};解:本習題考察如何為類添加所需要的成員函數(shù)?以下僅列出相關的類型說明?classPULLMENU{MENU(&menus)[]; 〃下拉菜單的各菜單項intcount; //下拉菜單的菜單項數(shù)public:intshow()const; 〃顯示菜單MENUgetmenu(intx);PULLMENU(MENUmenus[]);~PULLMENU(););classPOPMENU(MENU(&menus)[]; 〃下拉菜單的各菜單項intcount;〃下拉菜單的菜單項數(shù)public:intshow()const;〃顯示菜單MENUgetmenu(intx);POPMENU(MENUmenus[]);"POPMENU();};classPULLWIND:WINDOW{PULLMENU&pullm;public:intshow()const; 〃顯示菜單PULLMENUgetmenu()(returnpullm;};PULLWIND(char*n,intx,inty,intw,inth,PULLMENUpulIm);"PULLWIND(););classPULLPOPWIND:PULLWIND{POPMENUpopm;public:intshow()const; 〃顯示菜單POPMENUgetmenu(){returnpopm;};PULLPOPWIND(char*n,intx,inty,intw,inth,PULLMENUm,POPMENUp);'PULLPOPWIND();};第7章虛函數(shù)7.1從如下基類base派生多個類?每個類都定義voidisa()函數(shù)?調(diào)用voidisa()打印每個類的類名?#include<iostream.h>classbase(public:base(){cout?//Constructingbase\n,z;}virtualvoidisa(){cout?*base\nr,;)~base(){cout<<,zConstruetingbase\n”;}j.解:由于isa被定義為虛函數(shù)?在調(diào)用p->isa()時?將根據(jù)p實際指向的對象類型映射到相應類型的isa()函數(shù)?從而使函數(shù)的行為同對象類型一致?否則對象的行為同對象的類型不一致?參見習題6.3?

〃在此引用上述類型說明classderive:publicbase{〃構成父子關系public:derive(){cout?*Constructingderive'n";}virtualvoidisa(){cout?/zderive\n,z;}?derive(){cout?/zConstructingderive'n";}};classclique:publicbase{〃構成父子關系public:clique(){cout?//Constructingclique\n”;}virtualvoidisa(){cout〈<"clique\n〃;}~clique(){cout<</zConstructingclique\n”;});voidmain(){base*p,b;clique c;derive d;b.isa();c.isa();d.isa();p=&b;p->isa();〃調(diào)用base的isa()p=&c;p->isa();//調(diào)用clique的isa()p=&d;p->isa();〃調(diào)用derive的isa()7.4在二維坐標系上定義GRAPH抽象類?該類具有基點坐標和圖形顯示等純虛函數(shù)?從該類派生出三角形?圓等特定圖形類?并為特定圖形類定義相應純虛函數(shù)?解:在以下程序片段中?類GRAPH的純虛函數(shù)的原型為doublearea()const=0?其中?const限定所有自GRAPH派生的類的對象:在計算面積時不能改變當前對象的值?由于定義了純虛函數(shù)?類GRAPH是個抽象類?#include<math.h>classGRAPH{doublex,y;public:doublegetx()const{returnx;}doublegety()const(returny;}virtualdoublearea()const=0;GRAPH(doublexl,doubleyl){x=xl;y=yl;});classTRIANGLE:publicGRAPH{doublex2,y2,x3,y3;public:returnreturnreturnreturnreturngetx()gety()x2;}y2;}x3;}doublegetxl()const{doublegetyl()const{doublegetx2()const{doublegety2()const{returnreturnreturnreturnreturngetx()gety()x2;}y2;}x3;}doublegety3()const{returny3;}doublearea()const;TRIANGLE(doublexl,doubleyl,doublex2,doubley2,doublex3,doubley3););TRIANGLE::TRIANGLE(doublexl,doubleyl,doublex2,doubley2,doublex3,doubley3):GRAPH(xl,yl),x2(x2),y2(y2),x3(x3),y3(y3){};doubleTRIANGLE::area()const(doublea;a=(gety()+y3)*(x3-getx());a=a+(gety()+y2)*(getx()-x2);a=a+(y2+y3)*(x2-x3);returnabs(a)/2;)classCIRCLE:publicGRAPH{doubler;public:doublegetr()const(returnr;};doublearea()const;CIRCLE(doublex,doubley,doubler):GRAPH(x,y){CIRCLE::r=r;};);doubleCIRCLE::area()const{return3.1415926536*r*r;}公司員工分臨時和正式兩種類型?只有正式工才能擔任經(jīng)理?每個員工都由一個經(jīng)理主管?并由主管經(jīng)理發(fā)放工資?只有老板才沒有主管經(jīng)理?試定義公司員工?經(jīng)理和老板三個類?解:在定義該類時?要注意員工和經(jīng)理是互相依存的:每個員工都由一個經(jīng)理主管?一個經(jīng)理是一個正式員工?出現(xiàn)這種循環(huán)依賴時?必須使用前向引用聲明?先聲明其中一個類型再定義其他類型才能完成類型定義?#include<iostream.h>classMANAGER;//前向引用聲明classCLERK{charname[10];charflag;〃職員正式和臨時標志MANAGER*monitor;doublebalance;public:virtualdoubledrawwage();virtualdoublegetbalance();virtualvoidsetmonitor(MANAGER*m);CLERK(char*n,MANAGER*m,doubleb,charf='t');};classMANAGER:publicCLERK{

chartitle[10];public:virtualdoublepaywage();MANAGER(char*n,char*t,MANAGER*m,doubleb);};doubleMANAGER::paywage(){doubled;cin>>d;returnd;}MANAGER::MANAGER(char*n,char*t,MANAGER*m,doubleb):CLERK(n,m,b,'f'){strcpy(title,t);doubleCLERK::drawwage(){doubled;balance+=monitor->paywage();returnd;}doubleCLERK::getbalance(){returnbalance;}voidCLERK::setmonitor(MANAGER*m){monitorF;}CLERK::CLERK(char*n,MANAGER*m,doubleb,charf){strcpy(name,n);monitor=m;balance=b;flag=f;voidmain(){MANAGERMANAGERMANAGERCLERKCLERKboss("Wang",manl("Yang",man2(“Zang",form("Cang”,temp("Cang〃,MANAGERMANAGERMANAGERCLERKCLERKboss("Wang",manl("Yang",man2(“Zang",form("Cang”,temp("Cang〃,"Tycon”,0,100000);“Monitor”,&boss,20000);"Manager”,&manl,30000);&man2,1000,'f');CLERKtemp("Tang”,&man2,1000,&manl,1000);廣義表的元素要么是單個字符?要么又是一個廣義表?試定義廣義表存放單個字符的類?該類提供一個打印字符的函數(shù)print?由上述類派生出廣義表類?同時定義插入函數(shù)insert和廣義表打印函數(shù)print?解:注意廣義表是可以自遞歸的或間接遞歸的?出現(xiàn)這種情況時將導致廣義表打印函數(shù)陷入無窮遞歸?#include<stdio.h>classELEMS{charc;ELEMS*n;public:virtualvoidprint();ELEMS*getn(){returnn;}ELEMS*setn(ELEMS*a){n=a;returnthis;}ELEMS(charx,ELEMS*y=0){c=x;n=y;}};voidELEMS::print(){printfc);classLISTS:publicELEMS{ELEMS*e;public:voidprint();〃自動成為虛函數(shù)LISTS&join(ELEMS*e);LISTS(charx):ELEMS(x){e=0;}};voidLISTS::print(){ELEMS::print();printf("(");ELEMS*h=e;if(h)h->print();while(h=h->getn()){printf(*,*);h->print();}printfO*);)LISTS&LISTS::join(ELEMS*a){e=a->setn(e);return*this;)voidmain(){ELEMSa('a'),b('b'),c('c'),d('d'),e('e');LISTSA('A'),B('B');join(&a);A.join(&b);A.join(&c);A.print();join(&a);B.join(&A);B.join(&e);print();}第8章多繼承類定義兩個類:classfruit{public:virtualchar*identify(){return“fruit”;}};classtree{public:virtualchar?identify(){return"tree";}請派生出一些既是fruit又是tree的類及其派生類?例如?apple類:classapple:publicfruit,publictree{//**,)為每個派生類定義一個函數(shù)成員?該函數(shù)成員顯示自己的類名?并顯示類由哪些基類派生?例如?apple類的函數(shù)成員顯示如下信息:(apple:fruit,tree)蘋果梨apple_pear類的函數(shù)成員顯示如卜信息:(apple_pear:(apple:fruit,tree)?(pear:fruit,tree))解:多重派生時?通常要注意虛函數(shù)的使用?要注意在基類中定義虛函數(shù)?則派生類的原型相同的函數(shù)成員?即使不使用virtual聲明也會自動成為虛函數(shù)?classApple:publicfruit,publictree{public:char*identify(){staticchars[40];strcpy(s,"(apple:");strcat(s,fruit::identify());strcat(s,",

溫馨提示

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

評論

0/150

提交評論