本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版 | |||
cs:programming:cpp:cpp_primer:answers:chpt_4 [2024/01/14 13:46] – 移除 - 外部编辑 (未知日期) 127.0.0.1 | cs:programming:cpp:cpp_primer:answers:chpt_4 [2024/01/14 13:46] (当前版本) – ↷ 页面programming:cpp:cpp_primer:answers:chpt_4被移动至cs:programming:cpp:cpp_primer:answers:chpt_4 codinghare | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ======Chapter.4====== | ||
+ | 第四章的习题答案 | ||
+ | ---- | ||
+ | ====Ex.4.1-4.10==== | ||
+ | ==ex.4.1== | ||
+ | > | ||
+ | - 10 * 20 = 200 | ||
+ | - 200 / 2 - 100 | ||
+ | - 5 + 100 = 105 | ||
+ | ==ex.4.2== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) * vec.begin(); | ||
+ | (b) * vec.begin() + 1; // (*(vec.(begin.()))) + 1 | ||
+ | </ | ||
+ | ==ex.4.3== | ||
+ | > | ||
+ | Yep. Considering if we bind the order of evaluation to precedence and associativity in the previous example: | ||
+ | <code cpp> | ||
+ | f() + g() * h() + j() | ||
+ | </ | ||
+ | what happens is '' | ||
+ | I consider the trade-off is one exampe to demonstrate the philosophy of CPP, that is, let the programmer make the decision. | ||
+ | ==ex.4.4== | ||
+ | > | ||
+ | <code cpp> | ||
+ | ((12 / 3) * 4) + (5 * 15) + ((24 % 4) / 2) | ||
+ | </ | ||
+ | Result: 91 | ||
+ | ==ex.4.5== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) -30 * 3 + 21 / 5 // -90 + 4 = -86 | ||
+ | (b) -30 + 3 * 21 / 5 // -30 + 12 = -18 | ||
+ | (c) 30 / 3 * 21 % 5 // 10 * 21 % 5 = 0 | ||
+ | (d) -30 / 3 * 21 % 4// -210 % 4 = -2 | ||
+ | </ | ||
+ | ==ex.4.6== | ||
+ | Exercise 4.6: Write an expression to determine whether an int value is even or odd. | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | int i = 0; | ||
+ | cin >> i; | ||
+ | (i % 2 == 0) ? cout << " | ||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.4.7== | ||
+ | > | ||
+ | Overflow means value computed is outside the range values that the type can repersent. | ||
+ | <code cpp> | ||
+ | short sv = 32767; ++sv; | ||
+ | unsigned int ui = 0; --ui; | ||
+ | int i = 0; i = 2, | ||
+ | </ | ||
+ | ==ex.4.8== | ||
+ | > | ||
+ | For ''&&'' | ||
+ | For '' | ||
+ | ==ex.4.9== | ||
+ | > | ||
+ | <code cpp> | ||
+ | const char *cp = "Hello World"; | ||
+ | if (cp && *cp) | ||
+ | </ | ||
+ | The left operand is '' | ||
+ | The right operand is '' | ||
+ | In sum, the condition will return true. | ||
+ | ==ex.4.10== | ||
+ | > | ||
+ | <code cpp> | ||
+ | int i = 0; | ||
+ | while (cin >> i && i != 42) {...} | ||
+ | </ | ||
+ | ====Ex.4.11-4.20==== | ||
+ | ==ex.4.11== | ||
+ | > | ||
+ | <code cpp> | ||
+ | a > b && b > c && c >> d | ||
+ | </ | ||
+ | ==ex.4.12== | ||
+ | > | ||
+ | '' | ||
+ | ==ex.4.13== | ||
+ | > | ||
+ | <code cpp> | ||
+ | int i; double d; | ||
+ | (a) d = i = 3.5; // d = (i = 3.5) -> i = 3 -> d = 3.0 | ||
+ | (b) i = d = 3.5; // i = (d = 3.5) -> d = 3.5 -> i = 3 | ||
+ | </ | ||
+ | ==ex.4.14== | ||
+ | Exercise 4.14: Explain what happens in each of the if tests: | ||
+ | < | ||
+ | if (42 = i) // error. assignment operator requires left operand must be a modifiable lvalue. | ||
+ | if (i = 42) // equal to if(42), return true | ||
+ | </ | ||
+ | ==ex.4.15== | ||
+ | > | ||
+ | <code cpp> | ||
+ | double dval; int ival; int *pi; | ||
+ | dval = ival = pi = 0; //illegal. ival is an int that can't be assigned with a pointer value pi. | ||
+ | /* correction */ | ||
+ | dval = ival = *pi = 0; | ||
+ | </ | ||
+ | ==ex.4.16== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) if (p = getPtr() != 0) // due to the low precedence, it would be better that assignment comes with a pair of parenthesis. | ||
+ | fix: if ((p =getPtr()) != 0); | ||
+ | /* ---------- */ | ||
+ | (b) if (i = 1024) // the condition is forever true so it is useless here. May be the author just want to comparing i with 1024? then the fix: | ||
+ | if (i == 1024) | ||
+ | </ | ||
+ | ==ex.4.17== | ||
+ | > | ||
+ | <code cpp> | ||
+ | // prefix | ||
+ | int& int:: | ||
+ | { | ||
+ | *this += 1; // i = i + 1 | ||
+ | return *this; | ||
+ | } | ||
+ | //postfix | ||
+ | const int int:: | ||
+ | { | ||
+ | int oldValue = *this; | ||
+ | ++(*this); | ||
+ | return oldValue; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.4.18== | ||
+ | > | ||
+ | <code cpp> | ||
+ | hile (pbeg != v.end() && *beg >= 0) | ||
+ | cout << *pbeg++ << endl; | ||
+ | </ | ||
+ | Since the '' | ||
+ | It can be dangerous because the iterator may access the off-the-end element when the loop is just finished. | ||
+ | ==ex.4.19== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) ptr != 0 && *ptr++ // correct, check if ptr is a nullptr, then read element through ptr, then to the next element | ||
+ | (b) ival++ && ival // correct. check if ival == 0, if not, then check if(ival + 1) == 0 | ||
+ | (c) vec[ival++] <= vec[ival] // incorrect, op <= can't guarantee the order of evaluation. | ||
+ | vec[ival] <= vec [ival + 1] // if left evaluation happens first | ||
+ | vec[val] <= vec[ival] // if right evaluation happens first | ||
+ | </ | ||
+ | ==ex.4.20== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) *iter++; //legal. read current element and move the iterator to the next position | ||
+ | (b) (*iter)++;// | ||
+ | (c) *iter.empty() //illegal. iterator iter doesn' | ||
+ | (d) iter-> | ||
+ | (e) ++*iter;// | ||
+ | (f) iter++-> | ||
+ | </ | ||
+ | ====Ex.4.21-4.30==== | ||
+ | ==ex.4.21== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | using std:: | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | vector< | ||
+ | for (auto &i : vi) { | ||
+ | (i & 0x1) ? (i *= 2) : i; | ||
+ | } | ||
+ | |||
+ | for (auto i : vi) | ||
+ | cout << i << " "; | ||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.4.22== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | I would go with the if version. Nesting more than 3 condtionals is extreamely harder to read. | ||
+ | ==ex.4.23== | ||
+ | > | ||
+ | <code cpp> | ||
+ | string s = " | ||
+ | string pl = s + s[s.size() - 1] == ' | ||
+ | </ | ||
+ | The second line is actually evaluated in the following order: | ||
+ | <code cpp> | ||
+ | 1. s[s.size() - 1] | ||
+ | 2. s + s[s.sise() -1] | ||
+ | 3. (s + s[s.size() - 1]) == ' | ||
+ | 4. the bool result from 3 ? "" | ||
+ | </ | ||
+ | In my opinion, the orginal logic is : | ||
+ | - check whether the last letter of the string s is letter ' | ||
+ | - if it is, add nothing to the end of the string s | ||
+ | - otherwise, add letter s to string s | ||
+ | Fix: | ||
+ | <code cpp> | ||
+ | string pl = s + ((s[s.size() - 1] == ' | ||
+ | </ | ||
+ | PS. a test of comparing char and stl string, and the result: | ||
+ | <code cpp> | ||
+ | char a = ' | ||
+ | std::string s = " | ||
+ | std::cout << (s == a) << std::endl; | ||
+ | return 0; | ||
+ | </ | ||
+ | |||
+ | <code bash> | ||
+ | test.cc: | ||
+ | std::cout << (s == a) << std::endl; | ||
+ | </ | ||
+ | ==ex.4.24== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (grade > 90) ? "high pass" : (grade < 60) ? " | ||
+ | </ | ||
+ | wll be like | ||
+ | <code cpp> | ||
+ | ((grade > 90) ? "high pass" : (grade < 60)) ? " | ||
+ | </ | ||
+ | if it is left-associative. The whole process is: | ||
+ | - if grade > 90, then the result is "high pass", otherwise a bool (the result of grade < 60) | ||
+ | - depending on the result, the condition for the next operation would be a string or bool. | ||
+ | It is clear that the whole logic is messed up at the second step. Supposing the score is greater than 90, then the result is "high pass" after the first comparison. A non-empty string will always be true in condition. Thus, as long as your score is greater than 90, you will get a fail grade. | ||
+ | ==ex.4.25== | ||
+ | > | ||
+ | The reasult is undefined.\\ \\ | ||
+ | When doing '' | ||
+ | <code cpp> | ||
+ | 01110001 //char | ||
+ | 00000000 00000000 00000000 01110001 //int | ||
+ | </ | ||
+ | Then the inverse appiled: | ||
+ | <code cpp> | ||
+ | 00000000 00000000 00000000 01110001 //int | ||
+ | 11111111 11111111 11111111 10001110 //result of ~q | ||
+ | </ | ||
+ | The result of '' | ||
+ | ==ex.4.26== | ||
+ | > | ||
+ | In the example, we need to compare the value at the 27th bit. However, an unsigned int only has 16 bits, which is not big enough to hold the information. Moreover, a shifting that causes an out-of-range result is undefined. | ||
+ | ==ex.4.27== | ||
+ | >What is the result of each of these expressions? | ||
+ | <code cpp> | ||
+ | unsigned long ul1 = 3, ul2 = 7; | ||
+ | (a) ul1 & ul2 //3 | ||
+ | (b) ul1 | ul2 //7 | ||
+ | (c) ul1 && ul2 //true | ||
+ | (d) ul1 || ul2 //true | ||
+ | </ | ||
+ | ==ex.4.28== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.4.29== | ||
+ | > | ||
+ | <code cpp> | ||
+ | int x[10]; int *p = x; | ||
+ | cout << sizeof(x) / sizeof(*x) << endl; //1 | ||
+ | cout << sizeof(p) / sizeof(*p) << endl; // | ||
+ | </ | ||
+ | The result of the first one is 10. It actually returns the number of the elements in '' | ||
+ | The result of the sec one on my PC is 2. A pointer takes 8 bytes of space, an int takes 4 bytes on my PC. | ||
+ | ==ex.4.30== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) sizeof x + y // (sizeof x) + y | ||
+ | (b) sizeof p-> | ||
+ | (c) sizeof a < b // (sizeof a) < b | ||
+ | (d) sizeof f() // sizeof (f()) | ||
+ | </ | ||
+ | ====Ex.4.31-4.38==== | ||
+ | ==ex.4.31== | ||
+ | > | ||
+ | We have already discussed the difference between prefix in/ | ||
+ | ==ex.4.32== | ||
+ | > | ||
+ | <code cpp> | ||
+ | constexpr int size = 5; | ||
+ | int ia[size] = {1, | ||
+ | for (int *ptr = ia, ix = 0; | ||
+ | ix != size && ptr != ia+size; | ||
+ | ++ix, ++ptr) { | ||
+ | /* ... */ | ||
+ | } | ||
+ | </ | ||
+ | The for loop will traverse the whole array. The pointer '' | ||
+ | ==ex.4.33== | ||
+ | > | ||
+ | <code cpp> | ||
+ | someValue ? ++x, ++y : --x, --y | ||
+ | </ | ||
+ | Since comma operator has low precedence, the program is equivalent to: | ||
+ | <code cpp> | ||
+ | (someValue ? ++x, ++y : --x), --y | ||
+ | </ | ||
+ | Because conditional operator guaranteed the order of evaluate, the '' | ||
+ | - if someValue is true, then '' | ||
+ | - if someValue is false, then '' | ||
+ | The condition switches between '' | ||
+ | ==ex.4.34== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) if (fval) // float to bool, then bool to int | ||
+ | (b) dval = fval + ival; //int to float, then float to double | ||
+ | (c) dval + ival * cval; // char to int, then int to double | ||
+ | </ | ||
+ | ==ex.4.35== | ||
+ | Exercise 4.35: Given the following definitions, | ||
+ | <code cpp> | ||
+ | char cval; int ival; unsigned int ui; | ||
+ | float fval; double dval; | ||
+ | </ | ||
+ | identify the implicit type conversions, | ||
+ | <code cpp> | ||
+ | (a) cval = ' | ||
+ | (b) fval = ui - ival * 1.0; // | ||
+ | (c) dval = ui * fval; //my PC: float 32, int 16. float is big enough to represent all unsigned int, then: unsigned int to float, then float to double | ||
+ | (d) cval = ival + fval + dval; //int to float, float to double, double to char(result truncated). | ||
+ | </ | ||
+ | ==ex.4.36== | ||
+ | > | ||
+ | <code cpp> | ||
+ | i *= static_cast< | ||
+ | </ | ||
+ | ==ex.4.37== | ||
+ | > | ||
+ | <code cpp> | ||
+ | int i; double d; const string *ps; char *pc; void *pv; | ||
+ | (a) pv = (void*) ps; | ||
+ | pv = const_cast< | ||
+ | (b) i = int(*pc); | ||
+ | i = static_cast< | ||
+ | (c) pv = &d; | ||
+ | pv = static_cast< | ||
+ | (d) pc = (char*) pv; | ||
+ | pc = reinterpret_cast< | ||
+ | </ | ||
+ | ==ex.4.38== | ||
+ | > | ||
+ | <code cpp> | ||
+ | double slope = static_cast< | ||
+ | </ | ||
+ | convert result of '' |