本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版 | |||
cs:programming:cpp:cpp_primer:answers:chpt_3 [2024/01/14 13:46] – 移除 - 外部编辑 (未知日期) 127.0.0.1 | cs:programming:cpp:cpp_primer:answers:chpt_3 [2024/01/14 13:46] (当前版本) – ↷ 页面programming:cpp:cpp_primer:answers:chpt_3被移动至cs:programming:cpp:cpp_primer:answers:chpt_3 codinghare | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ======Chapter.3====== | ||
+ | 第三章的习题答案 | ||
+ | ---- | ||
+ | ====Ex3.1-3.10==== | ||
+ | ==ex.3.1== | ||
+ | > | ||
+ | CODE: | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | ==ex.3.2== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | //read a line at time | ||
+ | string s; | ||
+ | while (getline(cin, | ||
+ | cout << s << endl; | ||
+ | } | ||
+ | //read a word at time | ||
+ | string s2; | ||
+ | while (cin >> s2) { | ||
+ | cout << s2 << endl; | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.2== | ||
+ | > | ||
+ | * In the string input, whitespace characters will be the end sign of the print, that is, string input will save whatever before the first whitespace character and end the print. | ||
+ | * In the getline function, whitespace character will be deemed as a plain character, except the '' | ||
+ | ==ex.3.3== | ||
+ | ==ex.3.4== | ||
+ | > | ||
+ | <code cpp> | ||
+ | /*comparing the value*/ | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string s1,s2; | ||
+ | cout << "Enter two strings: " << endl; | ||
+ | cin >> s1 >> s2; | ||
+ | |||
+ | if(s1 == s2) { | ||
+ | cout << "Two strings are equal." | ||
+ | } | ||
+ | else { | ||
+ | cout << (s1 > s2 ? s1:s2) << " is greater." | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | <code cpp> | ||
+ | /*comparing the length*/ | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string s1,s2; | ||
+ | cout << "Enter two strings: " << endl; | ||
+ | cin >> s1 >> s2; | ||
+ | |||
+ | if(s1.size() == s2.size()) { | ||
+ | cout << "Two strings have the same length." | ||
+ | } | ||
+ | else { | ||
+ | cout << (s1.size() > s2.size() ? s1:s2) << " is longer." | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.5== | ||
+ | > | ||
+ | <code cpp> | ||
+ | / | ||
+ | */ | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string str, largeStr; | ||
+ | |||
+ | while(cin >> str) { | ||
+ | largeStr += str; | ||
+ | } | ||
+ | cout << largeStr << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | <code cpp> | ||
+ | /* | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string str, largeStr; | ||
+ | while(cin >> str) { | ||
+ | largeStr = largeStr + str + " "; | ||
+ | } | ||
+ | cout << largeStr << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.6== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string s (" | ||
+ | for(auto &c : s) { | ||
+ | c = ' | ||
+ | } | ||
+ | cout << s << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.7== | ||
+ | > | ||
+ | The result is going to identical with what we have in the original string. Usually, if we want to manipulate the data in the string, we use reference to access and modify it. In this case, if we use char type instead of char& type, when executing the statement '' | ||
+ | ==ex.3.8== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string s(" | ||
+ | //while ver | ||
+ | decltype(s.size()) curStrSub = 0; | ||
+ | while (curStrSub < s.size()) { | ||
+ | s[curStrSub] = ' | ||
+ | ++curStrSub; | ||
+ | } | ||
+ | cout << s << endl; | ||
+ | s = "Hello World!!"; | ||
+ | //normal for type | ||
+ | for(decltype(s.size()) curStrSub2 = 0; | ||
+ | curStrSub2 < s.size(); ++curStrSub2 ) { | ||
+ | s[curStrSub2] = ' | ||
+ | } | ||
+ | cout << s << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | For some sort of traversal work like this, I prefer to use Range For statement to process it. There are two advantages: | ||
+ | On the one hand, we can avoid using subscript to access and modify the character unit if using the Range For statement. Using reference to manipulate the data is much safer and would prevent us away from calculating the length of the whole string. On the other hand, Range For statement provided a much cleaner form for the traversal. It makes the program more readable. | ||
+ | ==e.x.3.9== | ||
+ | > | ||
+ | <code cpp> | ||
+ | string s; | ||
+ | cout << s[0] << endl; | ||
+ | </ | ||
+ | The program is trying to print out the first character of the string '' | ||
+ | ==e.x.3.10== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string s1; | ||
+ | getline(cin, | ||
+ | for (auto c : s1) { | ||
+ | if (!ispunct(c)) { | ||
+ | cout << c; | ||
+ | } | ||
+ | } | ||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ====Ex.3.11-3.20==== | ||
+ | ==ex.3.11== | ||
+ | > | ||
+ | <code cpp> | ||
+ | const string s = "Keep out!"; | ||
+ | for (auto &c : s) { /* ... */ } | ||
+ | </ | ||
+ | Yes, it is legal. The type of '' | ||
+ | ==ex.3.12== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) vector< | ||
+ | (b) vector< | ||
+ | (c) vector< | ||
+ | </ | ||
+ | ==ex.3.13== | ||
+ | > | ||
+ | <code cpp> | ||
+ | (a) vector< | ||
+ | (b) vector< | ||
+ | (c) vector< | ||
+ | (d) vector< | ||
+ | (e) vector< | ||
+ | (f) vector< | ||
+ | (g) vector< | ||
+ | </ | ||
+ | ==ex.3.14== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | int i = 0; | ||
+ | vector< | ||
+ | while (cin >> i) { | ||
+ | vi.push_back(i); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.15== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | using std:: | ||
+ | using std:: | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string str; | ||
+ | vector< | ||
+ | while (cin >> str) { | ||
+ | vs.push_back(str); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.16== | ||
+ | > | ||
+ | CODE: | ||
+ | ==ex.3.17== | ||
+ | > | ||
+ | CODE: | ||
+ | |||
+ | ==ex.3.18== | ||
+ | > | ||
+ | <code cpp> | ||
+ | vector< | ||
+ | ivec[0] = 42; | ||
+ | </ | ||
+ | illegal. There is no way to use the subscript method to create a new element for the vector. Accessing a non-exist vector element through subscript would cause undefined behavior. | ||
+ | <code cpp> | ||
+ | vector< | ||
+ | ivec2[0] = 42; | ||
+ | vector< | ||
+ | ivec3.push_back(42); | ||
+ | </ | ||
+ | ==3.19== | ||
+ | > | ||
+ | <code cpp> | ||
+ | //direct initialization | ||
+ | vector< | ||
+ | //list initialization | ||
+ | vector< | ||
+ | //push_back | ||
+ | vector< | ||
+ | for (int i = 0; i < 10; ++i) { | ||
+ | ivec3.push_back(42); | ||
+ | } | ||
+ | </ | ||
+ | It is recommended to use the first method since it is simple and easy. However, if elements in the vector are not identical and the size of the vector is unknown, then the third method is preferred because the first method is going to cause some sort of poor performance due to the implementation scheme of vector. | ||
+ | ==ex.3.20== | ||
+ | > | ||
+ | CODE: | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | ====Ex.3.21-3.30==== | ||
+ | ==ex.3.21== | ||
+ | >Redo the first exercise from § 3.3.3 (p. 105) using iterators. | ||
+ | CODE: | ||
+ | ==ex.3.22== | ||
+ | >Revise the loop that printed the first paragraph in text to instead change the elements in text that correspond to the first paragraph to all uppercase. After you’ve updated text, print its contents. | ||
+ | Notes:To my CHAOS head: so we got a program in previous example: | ||
+ | <code cpp> | ||
+ | for (auto it = text.cbegin(); | ||
+ | it != text.cend() && !it-> | ||
+ | cout << *it << endl; | ||
+ | </ | ||
+ | The program itself actually did the work "print the first paragraph" | ||
+ | CODE: | ||
+ | ==ex.3.23== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.3.24== | ||
+ | >Redo the last exercise from § 3.3.3 (p. 105) using iterators. | ||
+ | CODE: | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | ==ex.3.25== | ||
+ | >Rewrite the grade clustering program from § 3.3.3 (p. 104) using iterators instead of subscripts. | ||
+ | CODE: | ||
+ | [[https:// | ||
+ | ==ex.3.26== | ||
+ | > | ||
+ | There is no adding operation between iterators. | ||
+ | ==ex.3.27== | ||
+ | > | ||
+ | <code cpp> | ||
+ | unsigned buf_size = 1024; | ||
+ | (a) int ia[buf_size]; | ||
+ | (b) int ia[4 * 7 - 14]; //legal | ||
+ | (c) int ia[txt_size()]; | ||
+ | (d) char st[11] = " | ||
+ | </ | ||
+ | ==ex.3.28== | ||
+ | > | ||
+ | <code cpp> | ||
+ | string sa[10]; //10 null strings | ||
+ | int ia[10]; // 10 zero | ||
+ | int main() { | ||
+ | string sa2[10]; // 10 null strings | ||
+ | int ia2[10]; // undefined | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.29== | ||
+ | > | ||
+ | |||
+ | * The biggest drawback is Array has no flexibility. | ||
+ | * It can be bug-prone since it uses subscript to access and modify data | ||
+ | * It is not a part of STL data structure, hence it can't benefit from Generic Programming. | ||
+ | ==ex.3.30== | ||
+ | > | ||
+ | <code cpp> | ||
+ | constexpr size_t array_size = 10; | ||
+ | int ia[array_size]; | ||
+ | for (size_t ix = 1; ix <= array_size; ++ix) | ||
+ | ia[ix] = ix; | ||
+ | </ | ||
+ | In this program, the subscript range of the array is from '' | ||
+ | ====Ex.3.31-3.40==== | ||
+ | ==ex.3.31== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | using std::cin; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | int ai[10] = {0}; | ||
+ | for (unsigned i = 0; i < 10; ++i) { | ||
+ | ai[i] = i; | ||
+ | } | ||
+ | for (auto i : ai) | ||
+ | cout << i << " "; | ||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.32== | ||
+ | >Copy the array you defined in the previous exercise into another array. Rewrite your program to use vectors. | ||
+ | CODE: | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | ==ex.3.33== | ||
+ | > | ||
+ | Don't do this. All build-in type arrays where are default initialized inside a function are undefined. | ||
+ | ==ex.3.34== | ||
+ | > | ||
+ | <code cpp> | ||
+ | p1 += p2 - p1; | ||
+ | </ | ||
+ | In C++, the precedence of compound assignment is much lower than subtraction. Thus, the above statement is actually like: | ||
+ | <code cpp> | ||
+ | p1 = p1 + (p2 - p1); | ||
+ | </ | ||
+ | The operation let p1 points to the emelent that '' | ||
+ | Since '' | ||
+ | Ref: | ||
+ | ==ex.3.35== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | using std::begin; | ||
+ | using std::end; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | int ai[] = {1, | ||
+ | for(auto pBeg = begin(ai); pBeg != end(ai); ++pBeg) { | ||
+ | *(pBeg) = 0; | ||
+ | } | ||
+ | |||
+ | for (auto i : ai) { | ||
+ | cout << i << " "; | ||
+ | } | ||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.36== | ||
+ | > | ||
+ | CODE: | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | ==ex.3.37== | ||
+ | > | ||
+ | <code cpp> | ||
+ | const char ca[] = {' | ||
+ | const char *cp = ca; | ||
+ | while (*cp) { | ||
+ | cout << *cp << endl; | ||
+ | ++cp; | ||
+ | } | ||
+ | </ | ||
+ | The code is going to print out '' | ||
+ | '' | ||
+ | You may want to define as c style string with ''/ | ||
+ | <code cpp> | ||
+ | const char ca[] = {' | ||
+ | </ | ||
+ | ==ex.3.38== | ||
+ | > | ||
+ | The result of adding two addresses is absolutely meaningless. A pointer arithmetic operation is only meaningful when it has the meaning '' | ||
+ | * If the result is an integral type, then it must denote a " | ||
+ | * If the result is a pointer, then the location pointed by the pointer must **in the range**. | ||
+ | ==ex.3.39== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | using std:: | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | string s1 = " | ||
+ | string s2 = " | ||
+ | |||
+ | (s1 == s2) ? cout << "s1 Equal to s2. " : cout << "s1 is not Equal to s2. " ; | ||
+ | cout << endl; | ||
+ | |||
+ | const char cs1[] = {" | ||
+ | const char cs2[] = {" | ||
+ | |||
+ | (strcmp(cs1, | ||
+ | |||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.40== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | char cs1[] = {" | ||
+ | char cs2[] = {" | ||
+ | char cs3[20] ={"" | ||
+ | |||
+ | strcpy(cs3, | ||
+ | strcat(cs3, | ||
+ | |||
+ | cout << cs3 << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ====Ex.3.41-3.45==== | ||
+ | ==ex.3.41== | ||
+ | > | ||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | using std:: | ||
+ | using std::begin; | ||
+ | using std::end; | ||
+ | using std::cout; | ||
+ | using std::endl; | ||
+ | |||
+ | int main(int argc, char const *argv[]) | ||
+ | { | ||
+ | int ai[] = {1, | ||
+ | vector< | ||
+ | |||
+ | for(auto i : vi) | ||
+ | cout << i << " "; | ||
+ | cout << endl; | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | ==ex.3.42== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.3.43== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.3.44== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.3.45== | ||
+ | > | ||
+ | CODE: [[https:// |