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

下載本文檔

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

文檔簡介

第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];

(2)cc=c;(11)cc=,a;

(3)pcc=&c;(12)*cpc=*pc;

(4)pcc=&cc;(13)pc=*pcpc;

(5)pc=&c;(14)**pcpc=*pc;

(6)pc=&cc,(15)*pc=**pcpc;

(7)pc=pcc;(16)*pcc=,b";

(8)pc=cpcc;(17)*pcpc=,c);

(9)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ù)原型charEstreat(char*dest,constchar*src)?定

義函數(shù)strcat的函數(shù)體?使其將sre指示的字符串添加到dest指示的字符串的后面?并將

調(diào)用時dest的值作為函數(shù)的返回值?

解:注意strcat的返回值和傳入第一個參數(shù)的值相同?

char*strcat(char*dest,constchar*src){

char*temp=dest;while(*temp)temp++;

while(*(temp++)=*(src++));

returndest;

}

2.3C按優(yōu)先級和結(jié)合性解釋類型?下述聲明是什么意思?

⑴typedefvoidVFPCRI(char*,int&)

⑵typedefVF_PC_RI*P_VF_PC_RI;

⑶typedefint&RIFFII(int,int);

(4)externVF_PC_RIfunca;

⑸externP_VF_PC_RIptra;

(6)externvoidfund(P_VF_PC_RI*);

⑺externP_VF_PC_RIfunc2(intc);

(8)P_VF_PC_]RIfunc3(P.VF_PC_RIa);

(9)typedefvoid(*(**VF_PAPPFV(void))[])(constint);

解:(1)定義一個名為VF_PC_RI的類型?該類型定義了一個參數(shù)為(char*,int&)沒有返

回值的函數(shù)?

(2)定義一個名為P_VF_PC_RI的類型?該類型定義了一個指向VF_PC_RI類型的指針?

(3)定義一個名為RIFFII的類型,該類型定義了一個參數(shù)為(int,int)返回一個引用的函

數(shù)?該引用引用一個整型量?

(4)說明一個類型為VF_PC_RI的函數(shù)funca?

(5)說明一個類型為P_VF_PC_RI的指針變量ptra?

(6)說明一個沒有返回值的函數(shù)funcl?該函數(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ù)?

2.4運行如下程序?打印結(jié)果ri和gi相等嗎?為什么?刪除printf語句中的8?結(jié)果有

什么變化?再刪除printf語句中的7?結(jié)果又有什么變化?

ftinclude<stdio.h>

int&f(){inti=10;int&j=i;returnj;}intg(){intj=20;returnj;}

voidmain(void){

int&ri=f();

intrj=g();

printf(/zri=%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)打印結(jié)果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的輸出結(jié)果由原來的6變?yōu)??

(4)再刪除printf語句中的7?ri的輸出結(jié)果由原來的5變?yōu)??即ri的值總是打印其值

的printf函數(shù)調(diào)用的倒數(shù)第三個參數(shù)?

2.5如下聲明和定義是否會導(dǎo)致編譯錯誤?

floatg(int);

intg(int);

intg(int,inty=3);

intg(int,L);

inti=g(8);

解:(1)不能定義返回類型僅和floatg(int)不同的函數(shù)intg(int)?

(2)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ù)沒有固定?因此要應(yīng)用省略參數(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++的類

3.2二叉樹類的頭文件node,h如下?請定義其中的函數(shù)成員?

classNODE{

char*data;

NODEbright;

public:

NODE(char*);

NODE(char*data?NODENODE*right);

~NODE();

};

解:以下程序構(gòu)造函數(shù)申請了內(nèi)存?必須在析購函數(shù)釋放?

#include<string.h>

〃在此引用上述類型說明

NODE::NODE(char*){

if(NODE::data=newchar[strlen(data)+l]){

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;}

}

3.3隊列(queue)就是一種先進先出表?隊列通常有插入?刪除?測空和清除四種操作?

“插入”即將一個元素插到隊列尾部?“刪除”就是從隊列首部取走一個元素?“測空”就

是要檢查隊列是否為空?當(dāng)隊列為空時返回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=0

rear=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(charftelem)

(

if(front==rear)return0;

elem=queue[front=front+l];

return1;

)

voidmain(void){QUEUEqueue(20);}

3.4改用數(shù)組定義習(xí)題3.3中的字符隊列?并將該隊列定義為循環(huán)隊列?使隊列的“插

入”?“刪除”操作能并發(fā)進行?其他公有函數(shù)成員的原型不變?

解:注意?函數(shù)成員insert和remove的尾部帶有volatile?表示函數(shù)的隱含參數(shù)this的

類型為volatile*constthis?即this指向的當(dāng)前對象是揮發(fā)易變的?揮發(fā)性通??梢?/p>

用來修飾并行操作的對象?即當(dāng)前隊列是可以同時進行插入和刪除操作的?構(gòu)造函數(shù)和析

構(gòu)函數(shù)不能用volatile?因為構(gòu)造和析構(gòu)時對象必須是穩(wěn)定的?以下程序使用字符數(shù)組作

為循環(huán)隊列?

classQUEUE{

char*queue;

intsize,front,rear;

public:

intinsert(charelem)volatile;

intremove(char&elem)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+1)%size]=elem;

return1;

)

intQUEUE::remove(char&elem)volatile

(

if(rear==front)return0;

e1em=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?否則返回0

intremove(intv);〃刪除元素v成功時返回1?否則返回0

intfind(intv);〃查找元素v成功時返回1?否則返回0

intget(intk);〃取表的第k個元素的值作為返回值

"INTLIST(void);

};

解:構(gòu)造函數(shù)申請了內(nèi)存資源?必須在析構(gòu)函數(shù)釋放?

〃在此引用上述類型說明

INTLIST::INTLIST(ints){

if(list=newint[s]){size=s;

used=0;

)

}

INTLIST::"INTLIST(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+l];

return1;

)

return0;

)

intINTLIST::find(intv){

for(inti=0;i<used;i++)

if(list[i]==v)return1;

return0;

)

第4章作用域及成員指針

4.1為什么要引入名字空間?名字空間能否在函數(shù)內(nèi)部定義?

解:名字空間是C++引入的一種新的作用域?用于減少軟件項目中的命名沖突?同一名字

空間中的標(biāo)識符名必須唯一?不同名字空間中的標(biāo)識符名可以相同?名字空間必須在程序

的全局作用域內(nèi)定義?不能在函數(shù)及函數(shù)成員內(nèi)定義?

4.2匿名名字空間能否分多次定義?它和沒有對象的匿名聯(lián)合有何區(qū)別?

解:名字空間包括匿名名字空間可以分多次定義?即可以先在初始定義中定義一部分成員?

然后在擴展定義中再定義另?部分成員?或者再定義初始定義聲明的函數(shù)原型?匿名名字

空間的作用域規(guī)則和沒有對象的匿名聯(lián)合相同?但匿名名字空間不能看作類?盡管它可以

定義類型?變量及函數(shù)等?匿名名字空間的局部變量內(nèi)存是獨立分配的?而沒有對象的匿

名聯(lián)合的成員變量是共享內(nèi)存的?匿名名字空間只能在函數(shù)的外面定義?而沒有對象的匿

名聯(lián)合可在函數(shù)的內(nèi)部定義?

4.3為統(tǒng)計正文的單詞定義一個類?其類型聲明的頭文件word,h如卜:

classW0RD{

char*word;

intcount;

public:

intgettimes()const;

intinctimes();

constchar*getword()const;

WORD(constchar*);

?WORD();};

定義其中的函數(shù)成員?要求構(gòu)造函數(shù)使用new為結(jié)點分配空間?析構(gòu)函數(shù)使用delete回

收分配的空間?

解:構(gòu)造函數(shù)申請了內(nèi)存資源?必須在析構(gòu)函數(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;}}

4.4利用上述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(z/amour,,)->inctimes();

cout?,zTimesofamour=,/;

cout<<ws.find(''amour77)->gettimes();

)

請定義其中的函數(shù)成員?并用main進行測試?

解:構(gòu)造函數(shù)申請了內(nèi)存資源?必須在析構(gòu)函數(shù)釋放?尤其要注意new(&words[count++])

WORD(w)的用法?表示利用已有對象的存儲單元重新構(gòu)造該對象?WORDS的函數(shù)成員定義如

下:

#include<string.h>

#include<alloc.h>

WORDS::WORDS(inttotal){

words=(WORD*)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ù)組存放雜湊表元素?以字符串作關(guān)鍵字存放和查找表元

素?并提供用于插入?查詢和刪除雜湊表元素的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::N0DE*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定義二維坐標(biāo)系上的三角形類?要求該類提供計算面積和周長的函數(shù)成員?計算時不

能改變類的任何數(shù)據(jù)成員的值?

解:由于計算時不能改變類當(dāng)前對象任何數(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」的內(nèi)容如下:

#include<string.h>

#include<iostream.h>

classSTACK(

constintmax;〃棧能存放的最大元素個數(shù)

inttop;〃棧頂元素位置

char*stk;

public:

STACK(intmax);

"STACK();

intpush(charv);〃將v壓棧,成功時返回1,否則返回0

intpop(char&v);〃彈出棧頂元素,成功時返回1,否則返回0

);

解:注意STACK中的const數(shù)據(jù)成員max?其初始化不能在構(gòu)造函數(shù)的函數(shù)體內(nèi)完成?此

外?引用類型和類類型的成員也不能在構(gòu)造函數(shù)的函數(shù)體內(nèi)完成?

〃在此引用上述類型說明

STACK::STACK(intmax):top(O),max((stk=newchar[max])?max:0){}

STACK:rSTACK(){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)成員與友元

5.1定義一個類RANDOM?該類的構(gòu)造函數(shù)用來指定隨機數(shù)的分布參數(shù)?在對象不同而分

布參數(shù)相同的情況下?構(gòu)造函數(shù)自動地使分布參數(shù)互不相同?該類的函數(shù)rand用于返

回下一個隨機數(shù)?

解:在面向?qū)ο蟮某绦蛟O(shè)計中?注意應(yīng)用對象識別標(biāo)志的唯?性?即使對象的構(gòu)造函數(shù)的

參數(shù)完全相同?但對象的識別標(biāo)志是唯一性的?據(jù)此可使隨機數(shù)的分布參數(shù)互不相同?

在C++中?對象的首地址即隱含參數(shù)this可作為對象的唯?性識別標(biāo)志?

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;}

5.2定義節(jié)點類NODE和棧類STACK?棧元素由節(jié)點構(gòu)成并形成節(jié)點鏈表?壓棧時將節(jié)點

加入棧的鏈?zhǔn)??出棧時從棧的鏈?zhǔn)讋h除節(jié)點?

解:注意NODE的構(gòu)造函數(shù)?提供了為STACK元素形成鏈表的潛在功能?

classNODE{

intvalue;

NODE*next;

public:

NODE(intvalue,NODE*next);

intgetv(){returnvalue;};

NODE*getn(){returnnext;};

);

NODE::NODE(intv,NODE*n){valuer;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!=0)head=p;

returnp!=0;

)

intSTACK::pop(int&v)

(

NODE*p=head;

if(head==0)return0;

v=head->getv();

head=head->getn();

deletep;

return1;

)

STACK:rSTACK()

{

NODE*q,*p=head;

while(p!=0){

q=p->getn();

deletep;

P=q:

)

5.5定義三維坐標(biāo)系的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可通過構(gòu)造函數(shù)和析構(gòu)維護?

〃在此引用上述類型說明

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::>OINT(){total—;}

intPOINT::number(){returntotal;}

5.6現(xiàn)有一棵二叉樹和一個有序數(shù)組?要求通過這棵二叉樹構(gòu)造有序數(shù)組?它們的類型聲

明如下?請定義有序數(shù)組的構(gòu)造函數(shù)?classSEQUENCE;

classTREE{

intitem;

TREE*left,*right;

friendSEQUENCE;

public:

//...

);

classSEQUENCE{

int*items;

intsize;

public:

SEQUENCE(TREE&);

);

解:本習(xí)題主要考查如何為對象添加所需要的函數(shù)成員?

classSEQUENCE;

classTREE{

intitem;

TREE*left,bright;

friendSEQUENCE;

public:

intgetnodes();

intgetnodes(int*items);

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);

)

5.7現(xiàn)欲通過有序數(shù)組構(gòu)造二叉樹?請定義二叉樹的構(gòu)造函數(shù)(提示:可將數(shù)組平均分成兩

個部分?將中間的數(shù)組元素作為根?將二邊的數(shù)組元素分別作為根的左?右子樹?重復(fù)

上.述過程便可以得到基本平衡的二叉樹)?

解:任何函數(shù)都是可以遞歸調(diào)用的?但要注意控制遞歸結(jié)束的條件?以下程序通過遞歸調(diào)

用構(gòu)造函數(shù)構(gòu)造二叉樹?

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+l)?newTREE(a+x+1,t-x-1):0;

)

voidmain(){

staticints[10]={l,2,3,4,5,6,7,8,9,10);

TREEt(s,10);

)

5.8請指出如下程序中的錯誤之處:

classA{

inta;

staticfriendintf();

friendintg();

public:friendintA();

A(int);

}a(5);

intg(){returna.a;}

解:在staticfriendintf()中?static和friend不能同時出現(xiàn)?注意不要把intA()

當(dāng)作構(gòu)造函數(shù)?該非成員函數(shù)可以在函數(shù)g的后面定義為intA()(return3;}?但是?

如果在函數(shù)名前加上A::則表示要定義成員函數(shù)?顯然?friendintA::A()是錯誤的?

因為friend不能用于修飾當(dāng)前類的成員函數(shù)?而說明A::A(int)則是正確的?因為

A::A(int)出現(xiàn)在類A的定義中?故一般情況下A::是可以省略的?

5.9定義類描述有限狀態(tài)自動機?狀態(tài)的輸入和輸出關(guān)系可以描述為鏈表數(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);〃插入list

constSTATE*next(charin)const;〃輸入in轉(zhuǎn)移到下一個狀態(tài)

constSTATE*start(char*)const;〃啟動有限自動機

STATE(char*name);

"STATE();

};

使用有限自動機編程解決如下問題:有一個人帶著狼?羊和草來到河的左岸?左岸只有

一條無人擺渡的船?這個人要從左岸過河到右岸?可是這條船最多只能裝一個人和其他

三者之一?否則便會沉沒?如果沒有人看管?狼會吃掉羊?或者羊吃掉草?問如何過河

才能保證羊和草的安全?

提示:作為有限狀態(tài)自動機的輸入?人單獨過河用字符加表示?人帶狼過河用字符w

表示?人帶羊過河用字符s表示?人帶草過河用字符g表示?聲明有限自動機的start?

stop以及error狀態(tài)對象?如果start,start("smwsgms")=&stop?則過河成功?否則?如

果start,start("smwsgms")==&error?則過河失???

解:以下定義的類STATE用于表示自動機的狀態(tài)?其中staticSTATE*error表示自動機的

錯誤陷阱?進入錯誤陷阱后其他任何輸入都不能改變自動機的狀態(tài)?開始時?人狼羊草都

在河的左岸?初試狀態(tài)start表示為"WSGM,,人帶著羊過河后狀態(tài)變?yōu)?WG_SM",

用start.enlist('S',&WG_SM)將這一操作加入狀態(tài)轉(zhuǎn)移表?自動機的狀態(tài)轉(zhuǎn)移表存放類

LIST中?由以下自動的狀態(tài)轉(zhuǎn)移圖可知?本題有兩個過河路徑最小解?

圖5」人帶狼羊草過河的有限狀態(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=0;

}LIST::"LIST(){

if(this->next){deletethis->next;}

)

classSTATE{

char*name;〃狀態(tài)名

LIST*list;〃輸入及輸出狀態(tài)轉(zhuǎn)移列表

staticSTATE*error;

public:

voidenlist(charin,STATE*out);〃插入list

constSTATE*next(charin)const;〃輸入in轉(zhuǎn)移到下一個狀態(tài)

constSTATE*start(char*)const;//啟動有限自動機

STATE(char*name);

"STATE();

);

STATE*STATE::error=O;

STATE::STATE(char*name):name(0),list(O){

if(name==0){error=this;return;}

STATE::name二newchar[strlen(name)+l];

strcpy(STATE::name,name);

)

voidSTATE::enlist(charin,STATE*out){〃插入list

LIST*temp;

if(list==0){

list=newLIST(in,out);

return;

)

temp二newLIST(in,out);

temp->next=list;

list=temp;

}

constSTATE*STATE::next(charin)const{〃輸入in轉(zhuǎn)移到下一個狀態(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/z;deletename;name=0;}

if(list){deletelist;list=0;}

}

voidmain(){

STATEstart("WSGM_");

STATEstop("WSGM");

STATEerror(0);

STATEWG_SM("WG_SM");

STATEWGM_S("WGM_S");

STATEG_WSM("G_WSM");

STATESGM_W("SGMJT);

STATEW_SGM("W_SGM");

STATEWSM_G("WSM_G");

STATES_WGM("S_WGM");

STATESM_WG("SM_WG");

start,enlistCS',&WG_SM)

WGSM.enlistCS',&start)

WG_SM.enlistCM',&WGM_S)

WGM_S.enlist('M',&WG_SM)

WGM_S.enlistCW',&G_WSM)

WGM_S.enlistCC,&W_SGM)

GJVSM.enlistCW,&WGM_S)

W_SGM.enlistCG',&WGM_S)

G_WSM.enlistCS',&SGM_W)

SGMJV.enlist("S',&G_WSM)

SGMJY.enlist('G',&S_WGM)

S_WGM.enlistCC,&SGM_W)

W_SGM.enlistCS',&WSM_G)

WSM_G.enlistCS',&W_SGM)

WSM_G.enlistCW,&S_WGM)

S_WGM.enlistCW,&WSM_G)S?WGM.enlistCW,&SM_WG);

SM_WG.enlistCM\&S?WGM)

SM_WG.enlistCS',&stop);

stop,enlist('S',&SMWG);

if(start,start("SMWSGMSSS")==&stop)cout〈<"0K”;

5.10有限自動機也可以解決三個修道士與三個野人的過河問題?假定船最多只能載兩個修

道士或者野人,野人服從修道士的指揮?無論何時?只要野人多于修道士?野人就會吃掉

修道士?以有限自動機為基礎(chǔ)?編程解決三個修道士與三個野人的過河問題?

解:自動機仍然可以使用上述定義?只要改寫主函數(shù)即可?用M表示人?用W表示野人?

初始狀態(tài)為"MMMYYY」'?過河動作可以有五種:人單獨過河s?兩個人過河d?野人

單獨過河w?兩個野人過河t?人帶著野人過河b?例如?從初始狀態(tài)"MMMYYY,由

人帶著野人過河后狀態(tài)為''一MMMYYY"?

第6章單繼承類

6.1定義?個類LOCATION?用數(shù)據(jù)成員x?y表示該類對象在二維坐標(biāo)系中的坐標(biāo)位置?

用函數(shù)成員move移動對象坐標(biāo)位置?然后?以類LOCATION為基類?派生出點類POINT

和圓類CIRCLE?定義點類和圓類相應(yīng)的move和draw函數(shù)?

解:在C++中?不能隨意使用父類和子類這兩個概念?當(dāng)派生方式為public時?基類和派

生類才能分別稱為父類和子類?當(dāng)兩個類或多級派生的類構(gòu)成父子關(guān)系時?父類指針可

以直接指向子類對象?父類引用也可以直接引用子類對象?無須在指針或引用變量賦值

時進行強制類型轉(zhuǎn)換?如果沒有構(gòu)成父子關(guān)系?則必須進行進行強制類型轉(zhuǎn)換?注意?

在派生類的成員函數(shù)的函數(shù)體中?無論派生方式是否為public?都認為基類和派生類構(gòu)

成父子關(guān)系?

#include<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::LOCATION(intx,inty)

{

LOCATION::x=x;

LOCATION::y=y;

)

classPOINT:publicLOCATION(〃派生方式為public?構(gòu)成父子關(guān)系

intvisible;

public:

intisvisible(){returnvisible;};

voiddraw();

voidmove(intx,inty);

POINT(intx,inty):LOCATION(x,y){visible=0;};

);

voidPOINT::draw()

(

visible=l;

printf(z,drawapoint\n");

)

voidPOINT::move(intx,inty)

(

visible=l;

LOCATION::move(x,y);〃帶類名訪問LOCATION::moveto

if(visible)draw();

)

classCIRCLE:publicPOINT{〃派生方式為public?構(gòu)成父子關(guān)系

intr;

public:

intgetr(){returnr;}

voiddraw(){printf("drawacircle"");};

CIRCLE(intx,inty,intr):POINT(x,y){CIRCLE::r=r;};

);

voidmain(){

LOCATION*h;

POINTp(2,3);

CIRCLEc(3,4,5);

h=&p;〃不需要強制類型轉(zhuǎn)換:h=(LOCATION*)&p

h=&c;〃不需要強制類型轉(zhuǎn)換:h=(LOCATION*)&c

)

6.2由點類派生出線段類?點類定義了函數(shù)成員move和draw?請定義線段類的函數(shù)成員?

解:山于線段有兩個端點?而單繼承只能提供一個端點?故必須在類LINE中定義另一個端

點?由于該端點是POINT類的對象?故這樣的數(shù)據(jù)成員被稱為對象成員?注意?對象成員

POIN的初始化不能在LINE構(gòu)造函數(shù)的函數(shù)體內(nèi)進行?

classLINE:publicPOINT{//構(gòu)成父子關(guān)系

POINTend;〃定義對象成員

public:

intgetsx(){returngetx();}

intgetsy(){returngety();}

intgetex(){returnend.getx();}

intgetey(){returnend.gety();}

voiddraw(){printf("drawaline\n,z);};

voidmove(intx,inty){POINT::move(x,y);end.move(x,y);};

LINE(intsx,intsy,intex,intey):POINT(sx,sy),end(ex,ey){);

};

6.4利用第四章練習(xí)中的STACK?定義如下REVERSE類的函數(shù)成員?其構(gòu)造函數(shù)將字符

串壓棧?其析構(gòu)函數(shù)彈出字符并將其打印出來?打印的字符串正好是原字符串的逆序?

然后?用main函數(shù)檢驗定義是否正確?

^include<stack.h>

classREVERSE:STACK{

public:

REVERSE(char*str);〃將字符串壓棧

"REVERSE();//按逆序打印字符串

);

voidmain(void){

REVERSEa("abcdefghij");REVERSEbCabcdefghijkO;

}

解:注意?析構(gòu)是構(gòu)造的逆序?先定義的后析構(gòu)?后定義的先析構(gòu)?先執(zhí)行輸出的是b的

析構(gòu)函數(shù)?后執(zhí)行輸出的是a的析構(gòu)函數(shù)?

^include<string.h>

#include<stack.h>//在此引用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(a%c,,,c);

)

voidmain(void){

REVERSEa("abcdefghij");

REVERSEbCabcdefghijk");

}

6.6如下程序定義了類WINDOW和類MENU,由這兩個類派生出下拉菜單類PULLMENU和彈出菜

單類POPMENU,并進一步派生出帶下拉菜單的窗口類PULLWIND和帶下拉及彈出菜單的窗口類

PULLPOPWIND,請補充和完善PULLMENU?POPMENU?PULLWIND和PULLPOPWIND的類型定義?

classWINDOW{

char*title;〃窗口的標(biāo)題

char*cover;//用于保存和恢復(fù)窗口覆蓋的區(qū)域

intx,y;〃窗口的左上角坐標(biāo)

intw,h;〃窗口的寬度

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論