解釋string 類型的輸入操作符和getline 函數分別如何處理空白字符。
【解答】
string 類型的輸入操作符對空白字符的處理:讀取並忽略有效字符(非空白字符)之前所有的空白字符,然後讀取字符直至再次遇到空白字符,讀取終止(該 空白字符仍留在輸入流中)。 getline 函數對空白字符的處理:不忽略行開頭的空白字符,讀取字符直至遇到 換行符,讀取終止並丟棄換行符(換行符從輸入流中去掉但並不存儲在string 對象中)。
習題3.9
下列程序實現什麼功能?實現合法嗎?如果不合法,說明理由。
string s;
cout << s[0] << endl;
【解答】
該程序段輸出string 對象s 所對應字符串的第一個字符。 實現不合法。因爲s 是一個空字符串,其長度爲0,因此s[0]是無效的。
注意,在一些編譯器(如Microsoft Visual C++ .NET 2003)的實現中,該
程序段並不出現編譯錯誤。
習題3.11
下面哪些vector 定義不正確? (a) vector< vector<int> > ivec; (b) vector<string> svec = ivec (c) vector<string> svec(10,"null");
【解答】
(b)不正確。因爲svec 定義爲保存string 對象的vector 對象,而ivec 是
保存vector <int>對象的vector 對象(即ivec 是vector 的vector),二者
的元素類型不同,所以不能用ivec 來初始化svec。
習題3.12
下列每個vector 對象中元素個數是多少?各元素的值是什麼?
(a) vector<int> ivec1;
(b) vector<int> ivec2(10);
(c) vector<int> ivec3(10,42);
(d) vector<string> svec1;
(e) vector<string> svec2(10);
(f) vector<string> svec3(10,"hello");
【解答】
(a) 元素個數爲0。
(b) 元素個數爲10,各元素的值均爲0。 (c) 元素個數爲10,各元素的值均爲42。 (d) 元素個數爲0。
(e) 元素個數爲10,各元素的值均爲空字符串。 (f) 元素個數爲10,各元素的值均爲"hello"。
習題3.15
下面程序合法嗎?如果不合法,如何更正? vector<int> ivec; ivec[0] = 42;
【解答】
不合法。因爲ivec 是空的vector 對象,其中不含任何元素,而下標操作只
能用於獲取已存在的元素。
更正:將賦值語句改爲語句ivec.push_back(42);。
習題3.16
列出三種定義vector 對象的方法,給定10 個元素,每個元素值爲42。指出是
否還有更好的實現方法,並說明爲什麼。
【解答】
方法一:
vector<int> ivec(10, 42);
方法二:
vector<int> ivec(10); for (ix = 0; ix < 10; ++ix) ivec[ix] = 42;
方法三:
vector<int> ivec(10);
for (vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter) *iter = 42;
方法四:
vector<int> ivec;
for (cnt = 1; cnt <= 10; ++cnt) ivec.push_back(42);
方法五:
vector<int> ivec;
vector<int>::iterator iter = ivec.end(); for (int i = 0; i != 10; ++i) { ivec.insert(iter, 42); iter = ivec.end(); }
各種方法都可達到目的,也許最後兩種方法更好一些。它們使用標準庫中定義
的容器操作在容器中增添元素,無需在定義vector 對象時指定容器的大小,比 較靈活而且不容易出錯。
習題3.21
何時使用const 迭代器?又在何時使用const_iterator?解釋兩者的區別。
【解答】
const 迭代器是迭代器常量,該迭代器本身的值不能修改,即該迭代器在定義時
需要初始化,而且初始化之後,不能再指向其他元素。若需要指向固定元素的
迭代器,則可以使用const 迭代器。
const_iterator 是一種迭代器類型,對這種類型的迭代器解引用會得到一個指
向const 對象的引用,即通過這種迭代器訪問到的對象是常量。該對象不能修
改,因此,const_iterator 類型只能用於讀取容器內的元素,不能修改元素的
值。若只需遍歷容器中的元素而無需修改它們,則可以使用const_iterator。
習題3.22
如果採用下面的方法來計算mid 會產生什麼結果?
vector<int>::iterator mid = (vi.begin() + vi.end())/2;
【解答】
將兩個迭代器相加的操作是未定義的,因此用這種方法計算mid 會出現編譯錯 誤。
習題3.23
解釋下面每個bitset 對象包含的位模式:
(a) bitset<64> bitvec(32); (b) bitset<32> bv(1010101);
(c) string bstr; cin >> bstr; bitset<8> bv(bstr);
【解答】
(a) bitvec 有64 個二進制位,(位編號從0 開始)第5 位置爲1,其餘位置均 爲0。
(b) bv 有32 個二進制位,(位編號從0 開始)第0、2、4,5、7、8、11、13、
14、16、17、18、19 位置爲1,其餘位置均爲0。因爲十進制數1010101 對應的
二進制數爲000000000000011110110100110110101。 (c) bv 有8 個二進制位,(位編號從0 開始)用讀入的字符串的從右至左的8
個字符對bv 的0~7 位進行初始化。