C++Primer課后習題解答(第1~18章答案)_第1頁
C++Primer課后習題解答(第1~18章答案)_第2頁
C++Primer課后習題解答(第1~18章答案)_第3頁
C++Primer課后習題解答(第1~18章答案)_第4頁
C++Primer課后習題解答(第1~18章答案)_第5頁
已閱讀5頁,還剩230頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

目錄

第一章快速入門...............................................................................2

第二章變量和基本類型........................................................................12

第三章標準庫類型...........................................................................21

第四章數(shù)組和指針...........................................................................35

第五章表達式.................................................................................53

第六章語句...................................................................................64

第七章函數(shù)...................................................................................64

第八章標準10庫............................................................................64

第九章順序容器...............................................................................75

第十章關(guān)聯(lián)容器..............................................................................104

第十一章泛型算法...........................................................................129

第十二章類和數(shù)據(jù)抽象.......................................................................146

第十三章復(fù)制控制...........................................................................159

第十四章重載操作符與轉(zhuǎn)換...................................................................174

第十五章面向?qū)ο缶幊?......................................................................197

第十六章部分選做習題.......................................................................227

第十七章用于大型程序的工具................................................................235

第十八章特殊工具與技術(shù)....................................................................235

第一章快速入門

習題1.1

查看所用的編譯器文檔,了解它所用的文件命名規(guī)范。編譯并運行本節(jié)的main程序。

【解答】

一般而言,C++編譯器要求待編譯的程序保存在文件中。C++程序中一般涉及兩類文件:頭文件和源文件.大多數(shù)系統(tǒng)中,

文件的名字由文件名和文件后綴(又稱擴展名)組成。文件后綴通常表明文件的類型,如頭文件的后綴可以是.h或.hpp等;

源文件的后綴可以是.cc或.cpp等,具體的后綴與使用的編譯器有關(guān)。通??梢酝ㄟ^編譯器所提供的聯(lián)機幫助文檔了解其文

件命名規(guī)范。

習題1.2

修改程序使其返回-L返回值-1通常作為程序運行失敗的指示器。然而,系統(tǒng)不同,如何(甚至是否)報告main函數(shù)運

行失敗也不同.重新編譯并再次運行程序,看看你的系統(tǒng)如何處理main函數(shù)的運行失敗指示器。

【解答】

筆者所使用的Windows操作系統(tǒng)并不報告main函數(shù)的運行失敗,因此,程序返回-1或返回0在運行效果上沒有什么區(qū)

別。但是,如果在DOS命令提示符方式下運行程序,然后再鍵入echo%ERRORLEVEL%命令,則系統(tǒng)會顯示返回值-1。

習題1.3

編一個程序,在標準輸出上打印"Hell。,World".

【解答】

#include<iostream>

intmain()

(

std::cout<<"Hello,World"<<std::endl;

return0;

)

習題1.4

我們的程序利用內(nèi)置的加法操作符"+"來產(chǎn)生兩個數(shù)的和。編寫程序,使用乘法操作符"*"產(chǎn)生兩個數(shù)的積。

【解答】

#include<iostream>

intmain()

(

std::cout<<"Entertwonumbers:"<<std::endl;

intvl,v2;

std::cin>>vl>>v2;

std::cout<<"Theproductof"<<vl<<nand"<<v2

<<"is"<<vl*v2<<stdzendl;

return0;

)

習題1.5

我們的程序使用了一條較長的輸出語句。重寫程序,使用單獨的語句打印每一個操作數(shù)。

【解答】

#include<iostream>

intmain()

(

std::cout<<"Entertwonumbers:"<<std::endl;

intvl,v2;

std::cin>>vl>>v2;

std::cout<<"Thesumof

std::cout<<vl;

std::cout<<"andN;

std::cout<<v2;

std::cout<<"is

std::cout<<vl+v2;

std::cout<<std::endl;

return0;

)

習題1.6

解釋下面的程序段:

std::cout<<"Thesumofn<<vl;

<<"and"<<v2;

<<"is"<<vl+v2

<<std::endl;

這段代碼合法嗎?如果合法,為什么?如果不合法,又為什么?

【解答】

這段代碼不合法。

注意,第1、2、4行的末尾有分號,表示這段代碼包含三條語句,即第1、2行各為一個語句,第3、4行構(gòu)成一個語句。

"v<"為二元操作符,在第2、3兩條語句中第一個“<<〃缺少左操作數(shù),因此不合法。在第2、3行的開頭加上"std::cout",

即可更正。

習題1.7

編譯有不正確嵌套注釋的程序。

【解答】

由注釋對嵌套導(dǎo)致的蘿鰲鰭叁編譯器錯誤信息通常令人迷惑。例如,在筆者所用的編譯器中編譯L3節(jié)中給出的帶有不

正確嵌套注釋的程序:

#include<iostream>

/*

*commentpairs/**/cannotnest.

*"cannotnest"isconsideredsourcecode,

*asistherestoftheprogram

*/

intmain()

return0;

}

編譯器會給出如下錯誤信息:

errorC2143:syntaxerror:missingbefore'<'

errorC2501:'include*:missingstorage-classortypespecifiers

warningC4138:'*/'foundoutsideofcomment(第6行)

errorC2143:syntaxerror:missingbefore'{'(第8行)

errorC2447:'{':missingfunctionheader(old-styleformallist?)(第8行)

習題1.8

指出下列輸出語句哪些(如果有)是合法的。

std::cout<<7*";

std::cout<<"*/";

std::cout<</*"*/"*/;

預(yù)測結(jié)果,然后編譯包含上述三條語句的程序,檢查你的答案。糾正所遇到的錯誤。

【解答】

第一條和第二條語句合法。

第三條語句中<<操作符之后至第二個雙引號之前的部分被注釋掉了,導(dǎo)致<<操作符的右操作數(shù)不是一個完整的字符串,所

以不合法。在分號之前加上一個雙引號即可更正。

習題1.9

下列循環(huán)做什么?sum的最終值是多少?

intsum=0;

for(inti=-100;i<=100;++i)

sum+=i;

【解答】

該循環(huán)求-100~100之間所有整數(shù)的和(包括-100和100、sum的最終值是0。

習題1.10

用for循環(huán)編程,求從50~100的所有自然數(shù)的和。然后用while循環(huán)重寫該程序。

【解答】

用for循環(huán)編寫的程序如下:

#include<iostream>

intmain()

{

intsum=0;

for(inti=50;i<=100;++i)

sum+=i;

std::cout<<"Sumof50to100inclusiveis"

<<sum<<std::endl;

return0;

)

用while循環(huán)編寫的程序如下:

#include<iostream>

intmain()

(

intsum=0,inti=50;

while(i<=100){

sum+=i;

++i;

)

std::cout<<"Sumof50to100inclusiveis"

<<sum<<std::endl;

return0;

)

習題1.11

用while循環(huán)編程,輸出10-0遞減的自然數(shù)。然后用for循環(huán)重寫該程序。

【解答】

用while循環(huán)編寫的程序如下:

#include<iostream>

intmain()

(

inti=10;

while(i>=0){

std::cout<<i

-i;

)

return0;

)

用for循環(huán)編寫的程序如下:

#include<iostream>

intmain(www.bbobyoom)

for(inti=10;i>=0;—i)

std::cout<<i<<"

return0;

)

習題1.12

對比前面兩個習題中所寫的循環(huán)。兩種形式各有何優(yōu)缺點?

【解答】

在for循環(huán)中,循環(huán)控制變量的初始化和修改都放在語句頭部分,形式較簡潔,且特別適用于循環(huán)次數(shù)已知的情況。在while

循環(huán)中,循環(huán)控制變量的初始化一般放在while語句之前,循環(huán)控制變量的修改一般放在循環(huán)體中,形式上不如for語句簡

潔,但它匕徽適用于循環(huán)次數(shù)不易預(yù)知的情況(用某一條件控制循環(huán)\兩種形式各有優(yōu)點,但它們在功能上是等價的,可以

相互轉(zhuǎn)換。

習題1.13

編譯器不同,理解其診斷內(nèi)容的難易程度也不同。編寫一些程序,包含本小節(jié)"再談編譯”部分討論的那些常見錯誤。研究

編譯器產(chǎn)生的信息,這樣你在編譯更復(fù)雜的程序遇到這些信息時不會陌生。

【解答】

對于程序中出現(xiàn)的錯誤,編譯器通常會給出簡略的提示信息,包括錯誤出現(xiàn)的文件及代碼行、錯誤代碼、錯誤性質(zhì)的描述。

如果要獲得關(guān)于該錯誤的詳細信息,一般可以根據(jù)編譯器給出的錯誤代碼在其聯(lián)機幫助文檔中查找。

習題1.14

如果輸入值相等,本節(jié)展示的程序?qū)a(chǎn)生什么問題?

【解答】

sum的值即為輸入值。因為輸入的vl和v2值相等(假設(shè)為x),所以lower和upper相等,均為x。for循環(huán)中的循環(huán)

變量val初始化為lower,從而val<=upper為真,循環(huán)體執(zhí)行一次,sum的值為val(即輸入值x);然后val加1,val的

值就大于upper,循環(huán)執(zhí)行結(jié)束。

習題1.15

用兩個相等的值作為輸入編譯并運行本節(jié)中的程序。將實際輸出與你在習題1.14中所做的預(yù)測相比較,解釋實際結(jié)果和你

預(yù)計的結(jié)果間的不相符之處。

【解答】

運行1.4.3節(jié)中給出的程序,輸入兩個相等的值(例如3,3),則程序輸出為:

Sumof3to3inclusiveis3

與習題1.14中給出的預(yù)測一致。

習題1.16

編寫程序,輸出用戶輸入的兩個數(shù)中的較大者.

【解答】

#include<iostream>

intmain()

std::cout<<"Entertwonumbers:"<<std::endl;

intvl,v2;

std::cin>>vl>>v2;〃讀入數(shù)據(jù)

if(vl>=v2)

std::cout<<-Thebiggernumberis"<<vl<<std::endl;

else

std::cout<<"Thebiggernumberis"<<v2<<std::endl;

return0;

習題1.17

編寫程序,要求用戶輸入一組數(shù)。輸出信息說明其中有多少個負數(shù)。

【解答】

#include<iostream>

intmain()

(

intamount=0,value;

〃讀入數(shù)據(jù)直到遇見文件結(jié)束符,計算所讀入的負數(shù)的個數(shù)

while(std::cin>>value)

if(value<=0)

++amount;

std::cout<<"Amountofallnegativevaluesreadis"

<<amount<<std::endl;

return0;

)

習題1.18

編寫程序,提示用戶輸入兩個數(shù)并將這兩個數(shù)范圍內(nèi)的每個數(shù)寫到標準輸出。

【解答】

#include<iostream>

intmain()

(

std::cout<<"Entertwonumbers:"<<std::endl;

intvl,v2;

std::cin>>vl>>v2;〃讀入兩個數(shù)

//用較小的數(shù)作為下界lower較大的數(shù)作為上界upper

intlower,upper;

if(vl<=v2){

lower=vl;

upper=v2;

}else{

lower=v2;

upper=vl;

)

//輸出從lower到upper之間的值

std::cout<<"ValuesofB<<lower<<"to"

<<upper<<"inclusiveare:"<<std::endl;

for(intval=lower;val<=upper;++val)

std::cout<<val<<"n;

return0;

)

習題1.19

如果上題給定數(shù)1000和2000,程序?qū)a(chǎn)生什么結(jié)果?修改程序,使每一行輸出不超過10個數(shù)。

【解答】

所有數(shù)的輸出連在一起,不便于閱讀。

程序修改如下:

#include<iostream>

intmain()

(

std::cout<<"Entertwonumbers:"<<std::endl;

intvl,v2;

std::cin>>vl>>v2;//讀入兩個數(shù)

//用較小的數(shù)作為下界lower、較大的數(shù)作為上界upper

intlower,upper;

if(vl<=v2){

lower=vl;

upper=v2;

}else{

lower=v2;

upper=vl;

)

//輸出從lower到upper之間的值

std::cout<<"Valuesof"<<lower<<"to"

<<upper<<"inclusiveare:"<<std::endl;

for(intval=lower,count=l;val<=upper;++val,++count){

std::cout<<val<<"

if(count%10==0)〃每行輸出10個值

std::cout<<std::endl;

)

return0;

}

粗黑體部分為主要的修改:用變量count記錄已輸出的數(shù)的個數(shù);若count的值為10的整數(shù)倍,則輸出一個換行符。

習題1.20

編寫程序,求用戶指定范圍內(nèi)的數(shù)的和,省略設(shè)置上界和下界的if測試。假定輸入數(shù)是7和3,按照這個III酹,預(yù)測程序運

行結(jié)果。然后按照給定的數(shù)是7和3運行程序,看結(jié)果是否與你預(yù)測的相符。如果不相符,反復(fù)研究關(guān)于for和while循環(huán)

的討論直到弄清楚其中的原因。

【解答】

可編寫程序如下:

//l-20.cpp

//省略設(shè)置上界和下界的if測試,求用戶指定范圍內(nèi)的數(shù)的和

#include<iostream:>

intmain()

(

std::cout<<"Entertwonumbers:"<<std::endl;

intvl,v2;

std::cin>>vl>>v2;〃讀入數(shù)據(jù)

intsum=0;

//求和

for(intval=vl;val<=v2;++val)

sum+=val;〃sum=sum+val

std::cout<<"Sumof"<<vl

<<"to"<<v2

<<"inclusiveis"

<<sum<<std::endl;

return0;

)

如果輸入數(shù)據(jù)為和,則值為值為語句頭中將的初始值設(shè)為第一次測試表達式時,

73vl7,v23eforval7,val<=v2

該表達式的值為false,for語句的循環(huán)體一次也不執(zhí)行,所以求和結(jié)果sum為0。

習題1.21

本書配套網(wǎng)站(http:〃/cpp_primer)的第1章的代碼目錄下有Sales_item.h源文件。復(fù)制該

文件到你的工作目錄。編寫程序,循環(huán)遍歷一組書的銷售交易,讀入每筆交易并將交易寫至標準輸出。

【解答】

#include<iostream>

#include"Salesjtem.h"

intmain()

(

Salesjtembook;

〃讀入ISBN,售出書的本數(shù),銷售價格

std::cout<<"Entertransactions:"<<std::endl;

while(std::cin>>book)

(

//輸出ISBN,售出書的本數(shù),總收入,平均價格

std::cout<<"ISBN,numberofcopiessold,"

<<"totalrevenue,andaveragepriceare:"

<<std::endl;

std::cout<<book<<std::endl;

)

return0;

)

習題1.22

編寫程序,讀入兩個具有相同ISBN的Salesjtem對象并產(chǎn)生它們的和。

【解答】

#include<iostream>

#include"Salesjtem.h"

intmainO

(

Salesjtemtransl,trans2;

〃讀入交易

std::cout<<"Entertwotransactions:"<<std::endl;

std::cin>>transl>>trans2;

if(transl.samejsbn(trans2))

std::cout<<"Thetotalinformation:"<<std::endl

<<"ISBN,numberofcopiessold,"

<<"totalrevenue,andaveragepriceare:"

<<std::endl<<transl+trans2;

else

std::cout<<"ThetwotransactionshavedifferentISBN."

<<std::endl;

return0;

}

習題1.23

編寫程序,讀入幾個具有相同ISBN的交易,輸出所有讀入交易的和。

【解答】

#include<iostream>

#include"Salesjtem.h"

intmain()

{

Salesjtemtotal,trans;

〃讀入交易

std::cout<<"Entertransactions:"<<std::endl;

if(std::cin>>total){

while(std::cin>>trans)

if(total.samejsbn(trans))//ISBN相同

total=total+trans;

else{//ISBN不同

std::cout<<"DifferentISBN."<<std::endl;

return-1;

)

//輸出交易之和

std::cout<<"Thetotalinformation:"<<std::endl

<<"ISBN,numberofcopiessold,"

<<"totalrevenue,andaveragepriceare:"

<<std::endl<<total;

)

else{

std::cout<<"Nodata?!"<<std::endl;

return-1;

)

return0;

)

習題1.24

編寫程序,讀入幾筆不同的交易。對于每筆新讀入的交易,要確定它的ISBN是否和以前的交易的ISBN一樣,并且記下每

一個ISBN的交易的總數(shù)。通過給定多筆不同的交易來測試程序。這些交易必須代表多個不同的ISBN,但是每個ISBN的記

錄應(yīng)分在同一組。

【解答】

#include<iostream>

#include"Salesjtem.h"

intmain()

(

//聲明變量以保存交易記錄以及具有相同ISBN的交易的數(shù)目

Salesjtemtransl,trans2;

intamount;

//讀入交易

std::cout<<"Entertransactions:"<<std::endl;

std::cin>>transl;

amount=l;

while(std::cin>>trans2)

if(transl.same_isbn(trans2))//ISBN相同

++amount;

else{

//ISBN不同

std::cout<<"TransactionamountofpreviousISBN:"

<<amount<<std::endl;

transl=trans2;

amount=l;

)

//輸出最后一個ISBN的交易數(shù)目

std::cout<<"TransactionamountofthelastISBN:"

<<amount<<std::endl;

return0;

)

習題1.25

使用源自本書配套網(wǎng)站的Salesjtem.h頭文件,編譯并執(zhí)行1.6節(jié)給出的書店程序。

【解答】

可從C++Primer(第4版)的酉己套網(wǎng)站(http:〃/cpp_primer)下載頭文件Salesjtem.h,然后

使用該頭文件編譯并執(zhí)行1.6節(jié)給出的書店程序。

習題1.26

在書店程序中,我們使用了加法操作符而不是復(fù)合賦值操作符將trans力口到total中,為什么我們不使用復(fù)合賦值操作符?

【解答】

因為在151節(jié)中提及的Sales_item對象上的操作中只包含了十和二,沒有包含十=操作。(但事實上,使用Salesjtem.h文

件,已經(jīng)可以用+二操作符取代二和十操作符的復(fù)合使用。)

第二章變量和基本類型

習題2.1

int,long和short類型之間有什么差別?

【解答】

它們的最小存儲空間不同,分別為16位、32位和16位.一般而言,short類型為半個機器字(word)長,int類型為

一個機器字長,而long類型為一個或兩個機器字長(在32位機器中,int類型和long類型的字長通常是相同的1因此,

它們的表示范圍不同。

習題2.2

unsigned和signed類型有什么差別?

【解答】

前者為無符號類型,只能表示大于或等于0的數(shù)。后者為帶符號類型,可以表示正數(shù)、負數(shù)和0。

習題2.3

如果在某機器上short類型占16位,那么可以賦給short類型的最大數(shù)是什么?unsignedshort類型的最大數(shù)又是什

么?

【解答】

若在某機器上short類型占16位,那么可以賦給short類型的最大數(shù)是215-1,即32767;而unsignedshort類型的最

大數(shù)為216-1,即65535.

習題2.4

當給16位的unsignedshort對象賦值100000時,賦的值是什么?

【解答】

34464。

100000超過了16位的unsignedshort類型的表示范圍編譯器對其二進制表示截取低16位相當于對65536求余求

模,%),得34464。

習題2.5

float類型和double類型有什么差別?

【解答】

二者的存儲位數(shù)不同(一般而言,float類型為32個二進制位,double類型為64個二進制位),因而取值范圍不同,精

度也不同(float類型只能保證6位有效數(shù)字,而double類型至少能保證10位有效數(shù)字\

習題2.6

要計算抵押貸款的償還金額,利率、本金和付款額應(yīng)分別選用哪種類型?解釋你選擇的理由。

【解答】

利率可以選擇float類型,因為利率通常為百分之幾。一般只保留到小數(shù)點后兩位,所以6位有效數(shù)字就足以表示了.本金

可以選擇long類型,因為本金通常為整數(shù)。long類型可表示的最大整數(shù)一般為231-1(即2147483647),應(yīng)該足以表示

了。付款額一般為實數(shù),可以選擇double類型,因為float類型的6位有效數(shù)字可能不足以表示。

習題2.7

解釋下列字面值常量的不同之處.

(a),a',L,a',"a",L"a"

(b)10,10u,10L,10uL,012,0xC

(c)3.14,3.14f,3.14L

【解答】

(a),a',L,a',"a",L"a"

'a'為char型字面值,L'a為wchar_t型字面值,"a"為字符串字面值,L"a”為寬字符串字面值。

(b)10,10u,10L,10uL,012,0xC

10為int型字面值,10u為unsigned型字面值,10L為long型字面值,10uL為unsignedlong型字面值,012為

八進制表示的int型字面值,OxC為十六進制表示的int型字面值。

(c)3.14,3.14f,3.14L

3.14為double型字面值,3.14f為float型字面值,3.14L為longdouble型字面值。

習題2.8

確定下列字面值常量的類型:

(a)-10(b)-10u(c)-10.(d)-10e-2

【解答】

(a)int型

(b)unsignedint型

(c)double型

(d)double型

習題2.9

下列哪些(如果有)是非法的?

(a)"WhogoeswithF\145rgus?\012"

(b)3.14elL(c)"two"L"some"

(d)1024f(e)3.14UL

(f)"multipleline

comment"

【解答】

(c)非法.因為字符串字面值與寬字符串字面值的連接是未定義的。

(d)非法。因為整數(shù)1024后面不能帶后綴f。

(e)非法.因為浮點字面值不能帶后綴U.

(f)非法。因為分兩行書寫的字符串字面值必須在第一行的末尾加上反斜線。

習題2.10

使用轉(zhuǎn)義字符編寫一段程序,輸出2M,然后換行。修改程序,輸出2,跟著一

個制表符,然后是M,最后是換行符。

【解答】

輸出2M、然后換行的程序段:

//輸出"2M”和換行字符

std::cout<<"2M"<<'\n';

修改后的程序段:

//輸出2,、t冒M和換行字符

std::cout<<'2'<<'\t'<<'M'<<'\n';

習題2.11

編寫程序,要求用戶輸入兩個數(shù)一底數(shù)(base)和指數(shù)(exponent),輸出

底數(shù)的指數(shù)次方的結(jié)果。

【解答】

#include<iostream>

intmain()

(

//局部對象

intbase,exponent;

longresult=l;

//讀入底數(shù)(base)和指數(shù)(exponent)

std::cout<<"Enterbaseandexponent:"<<std::endl;

std::cin>>base>>exponent;

if(exponent<0){

std::cout<<"Exponentcan'tbesmallerthan0"<<std::endl;

return-1;

)

if(exponent>0){

//計算底數(shù)的指數(shù)次方

for(intent=1;ent<=exponent;++cnt)

result*=base;

)

std::cout<<base

<<'raisedtothepowerof"

<<exponent"

<<result<<std::endl;

return0;

)

習題2.12

區(qū)分左值和右值,并舉例說明。

【解答】

左值(lvalue)就是變量的地址,或者是一個代表"對象在內(nèi)存中的位置”的表達式。右值(rvalue)就是變量的值,見2.3.1

節(jié)。變量名出現(xiàn)在賦值運算符的左邊,就是一個左值;而出現(xiàn)在賦值運算符右邊的變量名或字面常量就是一個右值。

例如:

vall=val2/8

這里的vail是個左值,而val2和8都是右值.

習題2.13

舉出一個需要左值的例子。

【解答】

賦值運算符的左邊(被賦值的對象)需要左值,見習題2.12。

習題2.14

下面哪些(如果有)名字是非法的?更正每個非法的標識符名字。

(a)intdouble=3.14159;(b)charj

(c)boolcatch-22;(d)charl_or_2='l';

(e)floatFloat=3.14f;

【解答】

(a)double是C++語言中的關(guān)鍵字,不能用作用戶標識符,所以非法。此語句可改為:doubledval=3.14159;.

(c)名字catch-22中包含在字母、數(shù)字和下劃線之外的字符所以非法??蓪⑵涓臑椋篶atch_22;.

(d)名字l_or_2非法,因為標識符必須以字母或下劃線開頭,不能以數(shù)字開頭??蓪⑵涓臑椋?。ne_or_tw。;。

習題2.15

下面兩個定義是否不同?有何不同?

intmonth=9,day=7;

intmonth=09,day=07;

如果上述定義有錯的話,那么應(yīng)該怎樣改正呢?

【解答】

這兩個定義不同。前者定義了兩個int型變量,初值分別為9和7;后者也定義了兩個int型變量,其中day被初始化為

八進制值7;而month的初始化有錯:試圖將month初始化為八進制值09,但進制數(shù)字范圍為0~7,所以出錯??蓪?/p>

第二個定義改為:intmonth=011,day=07;

習題2.16

假設(shè)calc是一個返回double對象的函數(shù)。下面哪些是非法定義?改正所有的非法定義。

(a)intcar=1024,auto=2048;

(b)intival=ival;

(c)std::cin>>intinput_value;

(d)doublesalary=wage=9999.99;

(e)doublecalc=calc();

【解答】

(a)非法:auto是關(guān)鍵字,不能用作變量名.使用另一變量名,如aut即可更正。

(c)非法:>>運算符后面不能進行變量定義。改為:intinput_value;std::cin>>input_value;

(d)非法:同一定義語句中不同變量的初始化應(yīng)分別進行。改為:doublesalary=9999.99,wage=9999.99;

注意,(b)雖然語法上沒有錯誤,但這個初始化沒有實際意義,ival仍是未初始化的。

習題2.17

下列變量的初始值(如果有)是什么?

std::stringglobal_str;

intglobaljnt;

intmain()

(

intlocaljnt;

std::stringlocal_str;

II...

return0;

)

【解答】

global_str和local_str的初始值均為空字符串,globaljnt的初始值為0,local_int沒有初始值。

習題2.18

解釋下列例子中name的意義:

externstd::stringname;

std::stringname("exercise3.5a');

externstd::stringname("exercise3.5a");

【解答】

第一條語句是一個聲明,說明std::string變量name在程序的其他地方定義。

第二條語句是一個定義,定義了std::string變量name,并將name初始化為"exercise3.5a".

第三條語句也是一個定義,定義了std::string變量name,并將name初始化為"exercise3.5a”,但這個語句只能出現(xiàn)在

函數(shù)外部(即,name是一個全局變量I

習題2.19

下列程序中j的值是多少?

inti=42;

intmain()

(

inti=100;

intj=i;

II...

)

【解答】

j的值是100oj的賦值所使用到的i應(yīng)該是main函數(shù)中定義的局部變量i,因為局部變量的定義會屏蔽全局變量的定義。

習題2.20

下列程序段將會輸出什么?

inti=100,sum=0;

for(inti=0;i!=10;++i)

sum+=i;

std::cout<<i<<""<<sum<<std::endl;

【解答】

輸出為:

10045

for語句中定義的變量i,其作用域僅限于for語句內(nèi)部。輸出的i值是for語句之前所定義的變量i的值。

習題2.21

下列程序合法嗎?

intsum=0;

for(inti=0;i!=10;++i)

sum+=i;

std::cout<<"Sumfrom0to"<<i

<<"is"<<sum<<std::endl;

【解答】

不合法.因為變量i具有語句作用域,只能在for語句中使用,輸出語句中使用i屬非法.

習題2.22

下列程序段雖然合法,但是風格很糟糕。有什么問題呢?怎樣改善?

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

//processi

【解答】

問題主要在于使用了具體值100作為循環(huán)上界:100的意義在上下文中沒有體現(xiàn)出來,導(dǎo)致程序的可讀性差;若100這個

值在程序中出現(xiàn)多次,則當程序的需求發(fā)生變化(如將100改變?yōu)?00)時,對程序代碼的修改復(fù)雜且易出錯,導(dǎo)致程序的

可維護性差。改善方法:設(shè)置一個const變量(常量)取代100作為循環(huán)上界使用,并為該變量選擇有意義的名字。

習題2.23

下列哪些語句合法?對于那些不合法的使用,解釋原因。

(a)constintbuf;

(b)intent=0;

constintsz=ent;

(c)cnt++;sz++;

【解答】

(a)不合法。因為定義const變量(常量)時必須進行初始化,而buf沒有初始化。

(b)合法。

(c)不合法。因為修改了const變量sz的值.

習題2.24

下列哪些定義是非法的?為什么?如何改正?

(a)intival=1.01;(b)int&rvall=1.01;

(c)int&rval2=ival;(d)constint&rval3=1;

【解答】

(b)非法.因為rvall是一個非const引用,非const引用不能綁定到右值,而1.01是一個右值。可改正為:int&rvall=

ival;(假設(shè)ival是一個已定義的int變量1

習題2.25

在習題2.24給出的定義下,下列哪些賦值是非法的?如果賦值合法,解釋賦值的作用。

(a)rval2=3.14159;(b)rval2=rval3;

(c)ival=rval3;(d)rval3=ival;

【解答】

(d)非法。因為rval3是一個const弓|用,不能進行賦值。合法賦值的作用:

(a)將一個double型字面值賦給int型變量ival,發(fā)生隱式類型轉(zhuǎn)換,ival得到的值為3.

(b)將int值1賦給變量ival.

(c)將int值1賦給變量ival.

習題2.26

(a)中的定義和(b)中的賦值存在哪些不同?哪些是非法的?

(a)intival=0;(b)ival=ri;

constint&ri=0;ri=ival;

【解答】

intival=0;定義ival為int變量,并將其初始化為0.

constint&ri=0;定義ri為const引用,并將其綁定到右值0。

ival=ri;將0值賦給ival.

ri=ival;試圖對ri賦值,這是非法的,因為ri是const引用,不能賦值。

習題2.27

下列代碼輸出什么?

inti,&ri=i;

i=5;ri=10;

std::cout<<i<<""<<ri<<std::endl;

【解答】

輸出:

1010

ri是i的引用,對ri進行賦值,實際上相當于對i進行賦值,所以輸出i和ri的值均為10。

習題2.28

編譯以下程序,確定你的編譯器是否會警告遺漏了類定義后面的分號。

classFoo{

//empty

}//Note:nosemicolon

intmainO

return0;

如果編譯器的診斷結(jié)果難以理解,記住這些信息以備后用。

【解答】

在筆者所用的編譯器中編譯上述程序,編譯器會給出如下錯誤信息:

errorC2628:'Foo'followedby'int'isillegal(didyouforgeta(第4行)

warningC4326:returntypeof'main'shouldbe'intorvoid'insteadofFoo'(第5行)

errorC2440:'return':cannotconvertfrom'int'to'Foo'(第6行)

也就是說,該編譯器會對遺漏了類定義后面的分號給出提示。

習題2.29

區(qū)分類中的public部分和private部分.

【解答】

類中public部分定義的成員在程序的任1可部分都可以訪問。通常在public部分放置操作,以便程序中的其他部分可以執(zhí)行

這些操作。類中private部分定義的成員只能被作為類的組成部分的代碼(以及該類的友元)訪問。通常在private部分放

置數(shù)據(jù),以對對象的內(nèi)部數(shù)據(jù)進行隱藏。

習題2.30

定義表示下列類型的類的數(shù)據(jù)成員:

(a)電話號碼(b)地址

(c)員工或公司(d)夢芭莎優(yōu)惠券網(wǎng)里面的文章

【解答】

(a)電話號碼

classTel_number{

public:

〃…對象上的操作

private:

std::stringcountry_number;

std::stringcity_number;

std::stringphone_number;

);

(b)ifeilt

classAddress{

public:

〃…對象上的操作

private:

std::stringcountry;

std::stringcity;

std::stringstreet;

std::stringnumber;

);

(c)員工或公司

classEmployee{

public:

//…對象上的操作

private:

std::stringID;

std::stringname;

charsex;

Addressaddr;

TeLnumbertel;

);

classCompany{

public:

〃…對象上的操作

private:

std::stringname;

Addressaddr;

TeLnumbertel;

);

(d)某大學的學生

classStudent{

public:

〃…對象上的操作

private:

std::stringID;

std::stringname;

charsex;

std::stringdept;//所在系

std::stringmajor;

Addresshome_addr;

Tel_numbertel;

};

注意,在不同的具體應(yīng)用中,類的設(shè)計會有所不同,這里給出的只是T殳性的簡單例子。

習題2.31

判別下列語句哪些是聲明,哪些是定義,請解釋原因。

(a)externintix=1024;

(b)intiy;

(c)externintiz;

(d)externconstint&ri;

【解答】

(a)是定義,因為extern聲明進行了初始化。

(b)是定義,變量定義的常規(guī)形式。

(c)是聲明,extern聲明的常規(guī)形式。

(d)是聲明,聲明了一個const引用。

習題2.32

下列聲明和定義哪些應(yīng)該放在頭文件中?哪些應(yīng)該放在源文件中?請解釋原因。

(a)intvar;

(b)constdoublepi=3.1416;

(c)externinttotal=255;

(d)constdoublesq2=squt(2.0);

【解答】

(a)、(c)、(d)應(yīng)放在源文件中,因為(a)和(c)是變量定義,定義通常應(yīng)放在源文件中。(d)中的const變量sq2不是用常量表

達式初始化的,所以也應(yīng)該放在源文件中。

(b)中的const變量pi是用常量表達式初始化的,應(yīng)該放在頭文件中。參見291節(jié)。

習題2.33

確定你的編譯器提供了哪些提高警告級別的選項。使用這些選項重新編譯以前選擇的程序,查看是否會報告新的問題。

【解答】

在筆者所用的編譯器(MicrosoftVisualC++.NET2003)中,在Project菜單中選擇Properties菜單項,在

ConfigurationProperties-C/C++-General—WarningLevel中可以選擇警告級別。

第三章標準庫類型

習題3.1

用適當?shù)膗sing聲明,而不用std::前綴,訪問標準庫中的名字,重新編寫2.3節(jié)的程序,計算一給定數(shù)的給定次幕的結(jié)果。

【解答】

#include<iostream>

usingstd::cin;

usingstd::cout;

intmain()

(

//局部對象

intbase,exponent;

longresult=l;

〃讀入底數(shù)和指數(shù)

cout<<"Enterbaseandexponent:"<<endl;

cin>>base>>exponent;

if(exponent<0){

cout<<"Exponentcan'tbesmallerthan0"<<endl;

return-1;

}

if(exponent>0){

//計算底數(shù)的指數(shù)次方

for(intent=1;ent<=exponent;++cnt)

result*=base;

)

cout<<base

<<"raisedtothepowerof"

<<exponent"

<<result<<endl;

return0;

)

習題3.2

什么是默認構(gòu)造函數(shù)?

【解答】

默認構(gòu)造函數(shù)(defaultconstructor)就是在沒有顯式提供初始化式時調(diào)用的構(gòu)造函數(shù)。它由不帶參數(shù)的構(gòu)造函數(shù),或者為

所有形參提供默認實參的構(gòu)造函數(shù)定義。如果定義某個類的變量時沒有提供初始化式,就會使用默認構(gòu)造函數(shù)。如果用戶定

義的類中沒有顯式定義任何構(gòu)造函數(shù),編譯器就會自動為該類生成默認構(gòu)造函數(shù),稱為合成的默認構(gòu)造函數(shù)(synthesized

defaultconstructor\

習題3.3

列舉出三種初始化string對象的方法。

【解答】

(1)不帶初始化式,使用默認構(gòu)造函數(shù)初始化string對象。

⑵使用一個已存在的string對象作為初始化式,將新創(chuàng)建的string對象初始化為已存在對象的副本。

(3)使用字符串字面值作為初始化式,將新創(chuàng)建的string對象初始化為字符串字面值的副本。

習題3.4

s和s2的值分別是什么?

strings;

intmain(){

strings2;

)

【解答】

s和s2的值均為空字符串。

習題3.5

編寫程序?qū)崿F(xiàn)從標準輸入每次讀入一行文本。然后改寫程序,每次讀入一個單

詞。

【解答】

〃從標準輸入每次讀入一行文本

#include<iostream>

#include<string>

usingnamespacestd;

intmainO

(

stringline;

//一次讀入一行,直至遇見文件結(jié)束符

while(getline(cin,line))

cout<<line<<endl;//輸出相應(yīng)行以進行驗證

return0;

)

修改后程序如下:

〃從標準輸入每次讀入一個單詞

#include<iostream>

#include<string>

usingnamespacestd;

intmain()

(

stringword;

//一次讀入一個單詞,直至遇見文件結(jié)束符

while(cin>>word)

cout<<word<<endl;//輸出相應(yīng)單詞以進行驗證

return0;

)

注意,一般而言,應(yīng)該盡量避免使用using指示而使用using聲明(參見17.2.4

節(jié)),因為如果應(yīng)用程序中使用了多個庫,使用using指示引入這些庫中定義

的名字空間,容易導(dǎo)致名字沖突.但本書中的程序都只使用了標準庫,沒有使

用其他庫。使用using指示引入名字空間std中定義的所有名字不會發(fā)生名字

沖突。因此為了使得代碼更為簡潔以節(jié)省篇幅,本書的許多代碼中都使用了

using指示usingnamespacestd;來引入名字空間std,另外,本題中并未要求

輸出,加入輸出是為了更清楚地表示讀入的結(jié)果。本書后面部分有些地方與此

類似處理,不再贅述.

習題3.6

解釋string類型的輸入操作符和getline函數(shù)分別如何處理空白字符.

【解答】

string類型的輸入操作符對空白字符的處理:讀取并忽略有效字符(非空白字

符)之前所有的空白字符,然后讀取字符直至再次遇到空白字符,讀取終止(該

空白字符仍留在輸入流中\(zhòng)

getline函數(shù)對空白字符的處理:不忽略行開頭的空白字符,讀取字符直至遇到

換行符,讀取終止并丟棄換行符(換行符從輸入流中去掉但并不存儲在string

對象中X

習題3.7

編一個程序讀入兩個string對象,測試它們是否相等。若不相等,則指出兩個

中哪個較大。接著,改寫程序測試它們的長度是否相等,若不相等,則指出兩

個中哪個較長。

【解答】

測試兩個string對象是否相等的程序:

#include<iostream>

#include<string>

usingnamespacestd;

intmainO

(

stringsi,s2;

//讀入兩個string對象

cout<<"Entertwostrings:"<<endl;

C++Primer(4版)習題解答

41

cin>>si>>s2;

//測試兩個string對象是否相等

if(si==s2)

cout<<"Theyareequal."<<endl;

elseif(si>s2)

cout<<<<si<<"\"isbiggerthan"

<<"\""<<s2<<<<endl;

else

cout<<<<s2<<Tisbiggerthan"

<<'\on<<si<<"V"<<endl;

return0;

)

測試兩個string對象的長度是否相等的程序:

#include<iostream>

#include<string>

usingnamespacestd;

intmain()

(

stringsi,s2;

〃讀入兩個string對象

cout<<"Entertwostrings:"<<endl;

cin>>si>>s2;

//比較兩個string對象的長度

string::size_typelenl,Ien2;

C++Primer(4版)習題解答

42

lenl=sl.size();

Ien2=s2.size();

if(lenl==Ien2)

cout<<"Theyhavesamelength."<<endl;

elseif(lenl>Ien2)

cout<<<<si<<"\"islongerthan',

<<"\,,n<<s2<<nVn<<endl;

else

cout<<<<s2<<"\"islongerthan"

<<"\,M,<<si<<<<endl;

return0;

}

習題3.8

編一個程序,從標準輸入讀取多個string對象,把它們連接起來存放到一個更

大的string對象中,并輸出連接后的string對象。接著,改寫程序,將連接

后相鄰string對象以空格隔開。

【解答】

#include<iostream>

#include<string>

usingnamespacestd;

intmain()

(

stringresult_str,str;

〃讀入多個string對象并進行連接

C++Primer(4版)習題解答

43

cout<<"Enterstrings(Ctrl+Ztoend):"<<endl;

while(cin>>str)

result_str=result_str+str;

//輸出連接后的string對象

cout<<"Stringequaltotheconcatenationofthesestringsis:"

<<endl<<result.str<<endl;

return0;

}

改寫后的程序:

#include<iostream>

#include<string>

usingnamespacestd;

intmain()

(

stringresult_str,str;

〃讀入多個string對象并進行連接

cout<<MEnterstrings(Ctrl+Ztoend):"<<endl;

cin>>result_str;〃讀入第一個string對象,放到結(jié)果對象中

while(cin>>str)

result.str=result_str+''+str;

//輸出連接后的string對象

cout<<"Stringequaltothec

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論