C++ primer(第五版)第4章習題答案
第四章 表示式
4.1
105
4.2
(a) *(vec.begin()) (b) (*(vec.begin())) + 1
4.3
是的,我認為有必要進行權衡。因為速度永遠是C++最大的優勢。有時,我們需要編譯器的特性來進行高效的工作。但如果你不是專家。我必須建議你不要觸控未定義的行為。舉個例子,cout << i << ++i << endl 不應該出現在你的程式碼中。
4.4
((12 / 3) * 4) + (5 * 15) + ((24 % 4) / 2)
// 16 + 75 + 0 = 91
4.5
(a) -90 + 4 = -86
(b) -30 + 12 = -18
(c) 0
(d) -210 % 4 = -2
4.6
i % 2 == 0 ? "even" : "odd"
4.7
short svalue = 32767; ++svalue; //-32768
unsigned uivalue = 0; --uivalue; //4294967295
unsigned short usvalue = 65535; ++usvalue; //0
4.8
邏輯與運算子,當且僅當左側運算物件為真時才對右側運算物件求值。
邏輯或運算子,當且僅當左側運算物件為假時才對右側運算物件求值。
相等性運算子,僅當兩側運算物件相等時為真,否則為假。
4.9
cp是一個指向常量字元型別的指標,為真。
*cp是常量字元:‘H',為真。
4.10
int i = 0;
while (cin >> i && i != 42)
4.11
a > b && b > c && c > d
4.12
與 i != (j < k)相同, i與布林型別進行比較。
4.13
(a) i = 3, d= 3.0
(b) d=3.5, i = 3
4.14
(1) 賦值語句非法,字面值是左值,而賦值運算子的左側運算物件必須是一個可修改的左值。
(2) 條件判斷為真。
4.15
int型指標無法轉換為int型。
dval = ival = 0;
pi = 0;
4.16
(a) if ( (p = getPtr()) != 0)
(b) if (i == 1024)
4.17
前置版本運算子首先將運算物件增減,然後將改變後的物件作為求值結果,後置版本也會講運算物件增減,但是求值結果是運算物件改變之前那個值的副本。前置版本將物件本身作為左值返回,後置版本則將物件原始值的副本作為右值返回。
4.18
將會從第二個與元素開始列印,並將解引用尾後迭代器,是未定義的且危險。
4.19
(a)檢查ptr不是一個空指標,並檢查給指標的值。
(b)檢查ival和ival+1兩者中任一是否為0.
(c)求值順序未定義。vec[ival] <= vec[ival+1]
4.20
(a)返回*iter,然後++iter
(b)非法,*iter是一個字串,不能自增。
(c)非法,應該用箭頭運算子。
(d)指出迭代器所指向的值是否為空。
(e)字串型別不可以自增。
(f)返回iter->empty(),然後++iter。
4.21
#include <iostream>
#include <vector>
int main()
{
std::vector<int> ivec{1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto& i : ivec) i = (i % 2) ? (i * 2) : i;
// Check
for (auto i : ivec) std::cout << i << " ";
std::cout << std::endl;
return 0;
}
4.22
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main()
{
unsigned grade;
while (cin >> grade) {
// first version(only use conditional operators)
cout << ((grade > 90) ? "high pass" : (grade < 60)
? "fail"
: (grade < 75) ? "low pass"
: "pass");
cout << endl;
// second version(only use if statements)
if (grade > 90)
cout << "high pass";
else if (grade < 60)
cout << "fail";
else if (grade < 75)
cout << "low pass";
else
cout << "pass";
cout << endl;
}
return 0;
4.23
加法運算子優先於條件運算子
string p1 = s + (s[s.size() - 1] == 's' ? "" : "s");
4.24
左結合率:
finalgrade = ((grade > 90) ? "high pass" : (grade < 60)) ? "fail" : "pass";
4.25
'q' 01110001
~'q' ~00000000000000000000000001110001
取反後為負數,左移操作將會產生未定義的行為。
4.26
16位,放不下30個學生,結果未定義。
4.27
(a) 3
(b) 7
(c) ture
(d) true
4.28
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "bool\t\tis " << sizeof(bool) << "bytes." << endl;
cout << "char\t\tis " << sizeof(char) << "bytes." << endl;
cout << "wchar_t\t\tis " << sizeof(wchar_t) << "bytes." << endl;
cout << "char16_t\tis " << sizeof(char16_t) << "bytes." << endl;
cout << "char32_t\tis " << sizeof(char32_t) << "bytes." << endl;
cout << "short\t\tis " << sizeof(short) << "bytes." << endl;
cout << "int\t\tis " << sizeof(int) << "bytes." << endl;
cout << "long\t\tis " << sizeof(long) << "bytes." << endl;
cout << "long long\tis " << sizeof(long long) << "bytes." << endl;
cout << "float\t\tis " << sizeof(float) << "bytes." << endl;
cout << "double\t\tis " << sizeof(double) << "bytes." << endl;
cout << "long double\tis " << sizeof(long double) << "bytes." << endl;
cout << endl;
return 0;
}
4.29
第一個結果是10,得到的是陣列中元素的個數,第二個是 指標所佔空間大小/4,64位機器結果是2,32位機器結果是1。
4,30
(a) (sizeof x) + y
(b) sizeof (p -> men[i])
(c) sizeof (a) < b
(d) sizeof f() //如果f()返回void,則該語句未定義,否則其他返回其返回型別所佔的位元組數
4.31
前置版本可以避免不必要的工作,它遞增並返回遞增的結果。而後置版本的運算子必須儲存原始值,以便它可以返回未遞增的值作為其結果。如果不需要未增加的值,則不需要後置版本的運算子完成額外的工作。對於int和指標,編譯器可以優化這些額外的工作。 對於更復雜的迭代器型別,這種額外的工作可能會更昂貴。 通過習慣使用字首版本,我們不必擔心效能差異是否重要。 此外,也許更重要的是,我們可以更直接地表達我們的方案的意圖。
這裡不需要改動。
4.32
ptr和ix有相同的功能,前者使用指標,後者使用陣列的下標,我們使用這個迴圈遍歷陣列。
4.33
因為逗號優先順序最低,所以表示式等同於
(someValue ? ++x, ++y : --x), --y
如果someValue為真,那麼y先自增後自減,還是自己。如果someValue為假,那麼y僅僅自減,可以發現,最終的輸出和x的值一點關係都沒有。
4.34
(a) fval轉化為bool
(b) ival轉化為float,相加後的結果轉換為double.
(c)cval轉化為int,相加後的結果轉化為double.
4.35
(a) 'a'會提升為int,結果再轉換為char.
(b) ival轉換為double,ui轉換為double,相減後的結果轉換為float.
(c) ui提升為flaot,結果轉換為double.
(d) ival轉換為flaot,和fval相加的結果轉換為double,最後的結果轉換為char.
4.36
i *= static_cast<int>(d);
4.37
(a) pv = const_cast<string*>(ps) 或者 pv = static_cast<void*>(const_cast<string*>(ps)) // const_cast只改變常量屬性
(b) i = static_cast<int>(*pc)
(c) pv = static_cast<void*>(&d)
(d) pc = reinterpret_cast<char*>(pv)
4.38
將 j/i 的結果顯式轉換為doubl並初始化slope