diff --git a/README.md b/README.md index 8cacdb32..d9d6ba65 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,18 @@ -#C++ Primer (第5版) 课后习题答案 +#C++ Primer (第5版) 习题答案 ##C++ Primer (5th Edition) exercise answers. -### Something I hope you know before go into the answers. +### Note - Use `-std=c++11`(optional: `-pedantic -Wall`) flag when compiling.(or you can use Visual Studio 2012+) -- I don't know the standard answer, but I tried my best to keep the correctness, if you found any bug, please [tell me](https://github.com/Mooophy/Cpp-Primer/issues/new), thanks. +- If you found any bug, please [let me know](https://github.com/Mooophy/Cpp-Primer/issues/new), thanks. - I have downloaded the headers from this book's [web site](http://www.informit.com/store/c-plus-plus-primer-9780321714114) and put them in the `include` folder. - In order to test the program in an efficient way, I also put the test data file in the `data` folder. -- If you find any mistake of the questions. Please check the [Errata](http://ptgmedia.pearsoncmg.com/images/9780321714114/errata/9780321714114_errata_10-31-12.html) first. -### If you want to contribute this repository. +### How to contribute -- Please **fork**([How?](https://help.github.com/articles/fork-a-repo)) this repository. +- Please **fork**([How?](https://help.github.com/articles/fork-a-repo)) this repository first. - **commit**([How?](https://help.github.com/articles/create-a-repo#commit-your-first-change)) in your own repository. -- Create a **pull request**([How?](https://help.github.com/articles/using-pull-requests)) for me. +- Give me a **pull request**([How?](https://help.github.com/articles/using-pull-requests)). ### Table of Contents @@ -40,7 +39,7 @@ - Chapter 18. Tools for Large Programs - Chapter 19. Specialized Tools and Techniques -### Read more? +### If you speak Chinese 1. [PO在StackOverflow上的习题](http://book.douban.com/review/6500246/) 2. [C++ Primer issues(豆瓣讨论组)](http://www.douban.com/group/532124/) diff --git a/ch05/ex5_10.cpp b/ch05/ex5_10.cpp new file mode 100644 index 00000000..5042bbc0 --- /dev/null +++ b/ch05/ex5_10.cpp @@ -0,0 +1,28 @@ +#include + +using namespace std; + +int main(void) +{ + char c; + int aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; + while (cin >> c) + { + if (c == 'a' || c == 'A') + ++aCnt; + else if (c == 'e' || c == 'E') + ++eCnt; + else if (c == 'i' || c == 'I') + ++iCnt; + else if (c == 'o' || c == 'O') + ++oCnt; + else if (c == 'u' || c == 'U') + ++uCnt; + } + cout << "Num of vowel a : " << aCnt << endl; + cout << "Num of vowel e : " << eCnt << endl; + cout << "Num of vowel i : " << iCnt << endl; + cout << "Num of vowel o : " << oCnt << endl; + cout << "Num of vowel u : " << uCnt << endl; + return 0; +} \ No newline at end of file diff --git a/ch05/ex5_23.cpp b/ch05/ex5_23.cpp new file mode 100644 index 00000000..61b0cd36 --- /dev/null +++ b/ch05/ex5_23.cpp @@ -0,0 +1,11 @@ +#include +using namespace std; + +int main(void) +{ + int a, b; + cin >> a >> b; + cout << static_cast(a) / b << endl; + + return 0; +} \ No newline at end of file diff --git a/ch05/ex5_23_24_25.cpp b/ch05/ex5_23_24_25.cpp index 2ba9f850..e40f82b3 100644 --- a/ch05/ex5_23_24_25.cpp +++ b/ch05/ex5_23_24_25.cpp @@ -36,7 +36,7 @@ int main() while(cin>>n1>>n2) { - if(n2==1) + if(n2==0) { try { diff --git a/ch05/ex5_24.cpp b/ch05/ex5_24.cpp new file mode 100644 index 00000000..7f9b488d --- /dev/null +++ b/ch05/ex5_24.cpp @@ -0,0 +1,15 @@ +#include +using namespace std; + +int main(void) +{ + int a, b; + cin >> a >> b; + + if (b == 0) + throw runtime_error("divisor is 0"); + + cout << static_cast(a) / b << endl; + + return 0; +} \ No newline at end of file diff --git a/ch05/ex5_25.cpp b/ch05/ex5_25.cpp new file mode 100644 index 00000000..3bd23aeb --- /dev/null +++ b/ch05/ex5_25.cpp @@ -0,0 +1,34 @@ +#include +#include + +using namespace std; + +int main(void) +{ + int a, b; + cout << "Enter two numbers :" << endl; + + while (cin >> a >> b) + { + try{ + if (b == 0) + throw runtime_error("divisor is 0"); + cout << static_cast(a) / b << endl; + break; + } + catch (runtime_error err){ + cout << err.what() + << "\nTry again ? Enter y or n" << endl; + char c; + cin >> c; + if (!cin || c == 'n') + break; + else + { + cout << "Enter two numbers :" << endl; + } + } + } + + return 0; +} diff --git a/ch06/ex6_27.cpp b/ch06/ex6_27.cpp new file mode 100644 index 00000000..395d6f7d --- /dev/null +++ b/ch06/ex6_27.cpp @@ -0,0 +1,23 @@ +#include +#include + +using namespace std; + +int add(initializer_list il); + +int main(void) +{ + int result = add({ 1, 2, 3, 4, 5 }); + + cout << result << endl; + + return 0; +} + +int add(initializer_list il) +{ + int sum = 0; + for (auto a : il) + sum += a; + return sum; +} \ No newline at end of file diff --git a/ch13/ex13.43/strvec.cpp b/ch13/ex13.43/strvec.cpp index 89262bda..76bfae8f 100644 --- a/ch13/ex13.43/strvec.cpp +++ b/ch13/ex13.43/strvec.cpp @@ -22,6 +22,7 @@ #include #include +std::allocator StrVec::alloc; //! copy constructor StrVec::StrVec(const StrVec &s) diff --git a/ch13/ex13.43/strvec.h b/ch13/ex13.43/strvec.h index 17ccdc02..66db89e4 100644 --- a/ch13/ex13.43/strvec.h +++ b/ch13/ex13.43/strvec.h @@ -53,7 +53,7 @@ class StrVec std::string* first_free; // pointer to the first free element std::string* cap; // pointer to one past the end - std::allocator alloc; + static std::allocator alloc; //! utilities for Big 3/5 void reallocate(); diff --git a/ch14/ex14.18.19/StrBlob.h b/ch14/ex14.18.19/StrBlob.h index eeb4e7a4..91918643 100644 --- a/ch14/ex14.18.19/StrBlob.h +++ b/ch14/ex14.18.19/StrBlob.h @@ -161,8 +161,10 @@ StrBlob::operator =(const StrBlob &sb) */ class StrBlobPtr { - friend bool eq (const StrBlobPtr&, const StrBlobPtr&); - friend bool operator == (const StrBlobPtr&, const StrBlobPtr&); + friend bool operator==(const StrBlobPtr&, const StrBlobPtr&); + friend bool operator!=(const StrBlobPtr&, const StrBlobPtr&); + friend bool operator<(const StrBlobPtr&, const StrBlobPtr&); + friend bool operator>(const StrBlobPtr&, const StrBlobPtr&); public: StrBlobPtr(): curr(0) { } StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) { } @@ -177,7 +179,8 @@ class StrBlobPtr //! check returns a shared_ptr to the vector if the check succeeds std::shared_ptr> check(std::size_t, const std::string&) const; - + //! a valid iterator ? + bool valid()const; //! store a weak_ptr, which means the underlying vector might be destroyed std::weak_ptr> wptr; std::size_t curr; // current position within the array @@ -191,20 +194,40 @@ class StrBlobPtr //! in eq(), if l and r both are null then it returns true wiout caomparing curr //! in this operator, it returns true only when both pointer and curr are identical. //! -inline bool -operator==(const StrBlobPtr& lhs, const StrBlobPtr& rhs) +inline +bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs) { - //! lock () returns shared_ptr when possible ,or nullptr otherwise. - auto l = lhs.wptr.lock(); - auto r = rhs.wptr.lock(); + //only valid StrBlobPtrs which point to the same element are compatible + if (lhs.valid() && rhs.valid() && lhs.wptr.lock() == rhs.wptr.lock()) + return lhs.curr == rhs.curr; + else + throw std::logic_error("StrBlobPtr incompatible"); +} - return (l == r) ? (lhs.curr == lhs.curr) : false; +inline +bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs) +{ + return !(lhs == rhs); } -inline bool -operator !=(const StrBlobPtr& lhs, const StrBlobPtr& rhs) +inline +bool operator<(const StrBlobPtr &lhs, const StrBlobPtr &rhs) { - return !(lhs == rhs); + //only valid StrBlobPtrs which point to the same element are compatible + if (lhs.valid() && rhs.valid() && lhs.wptr.lock() == rhs.wptr.lock()) + return lhs.curr < rhs.curr; + else + throw std::logic_error("StrBlobPtr incompatible"); +} + +inline +bool operator>(const StrBlobPtr &lhs, const StrBlobPtr &rhs) +{ + //only valid StrBlobPtrs which point to the same element are compatible + if (lhs.valid() && rhs.valid() && lhs.wptr.lock() == rhs.wptr.lock()) + return lhs.curr > rhs.curr; + else + throw std::logic_error("StrBlobPtr incompatible"); } @@ -229,6 +252,15 @@ StrBlobPtr::check(std::size_t i, const std::string &msg) const return ret; // otherwise, return a shared_ptr to the vector } +inline +bool StrBlobPtr::valid()const +{ + auto ret = wptr.lock(); + if (ret&&curr <= ret->size()) + return true; + return false; +} + //! prefix: return a reference to the incremented object inline StrBlobPtr& StrBlobPtr::incr() @@ -264,23 +296,5 @@ StrBlob::end() return ret; } -//! named equality operators for StrBlobPtr -inline -bool eq(const StrBlobPtr &lhs, const StrBlobPtr &rhs) -{ - auto l = lhs.wptr.lock(), r = rhs.wptr.lock(); - // if the underlying vector is the same - if (l == r) - // then they're equal if they're both null or - // if they point to the same element - return (!r || lhs.curr == rhs.curr); - else - return false; // if they point to difference vectors, they're not equal -} -inline -bool neq(const StrBlobPtr &lhs, const StrBlobPtr &rhs) -{ - return !eq(lhs, rhs); -} #endif diff --git a/ch15/ex15.11/bulk_quote.cpp b/ch15/ex15.11/bulk_quote.cpp index 40ac5854..4282f41c 100644 --- a/ch15/ex15.11/bulk_quote.cpp +++ b/ch15/ex15.11/bulk_quote.cpp @@ -7,7 +7,7 @@ double Bulk_quote::net_price(std::size_t n) const void Bulk_quote::debug() const { - std::cout << "data members of this class:\n" - << "min_qty= " << this->min_qty << " " - << "discount= " << this->discount<< " \n"; + Quote::debug(); + std::cout << "min_qty= " << this->min_qty << " " + << "discount= " << this->discount<< " "; } diff --git a/ch15/ex15.11/bulk_quote.h b/ch15/ex15.11/bulk_quote.h index 95128182..14661d67 100644 --- a/ch15/ex15.11/bulk_quote.h +++ b/ch15/ex15.11/bulk_quote.h @@ -1,6 +1,6 @@ #ifndef BULK_QUOTE_H #define BULK_QUOTE_H -#include +#include"quote.h" class Bulk_quote : public Quote { diff --git a/ch15/ex15.11/limit_quote.cpp b/ch15/ex15.11/limit_quote.cpp index 6fe3b4d1..7ac4150c 100644 --- a/ch15/ex15.11/limit_quote.cpp +++ b/ch15/ex15.11/limit_quote.cpp @@ -3,7 +3,7 @@ void Limit_quote::debug() const { - std::cout << "data members of this class:\n" - << "max_qty= " << this->max_qty << " " - << "discount= " << this->discount<< " \n"; + Quote::debug(); + std::cout << "max_qty= " << this->max_qty << " " + << "discount= " << this->discount<< " "; } diff --git a/ch15/ex15.11/main.cpp b/ch15/ex15.11/main.cpp index abd9b8f4..eba4e2d6 100644 --- a/ch15/ex15.11/main.cpp +++ b/ch15/ex15.11/main.cpp @@ -33,10 +33,13 @@ int main() */ Quote& r = q; r.debug(); + std::cout << "\n"; r = bq; r.debug(); + std::cout << "\n"; r = lq; r.debug(); + std::cout << "\n"; std::cout << "====================\n"; @@ -54,9 +57,11 @@ int main() * */ print_debug(q); + std::cout << "\n"; print_debug(lq); + std::cout << "\n"; print_debug(bq); - + std::cout << "\n"; return 0; } diff --git a/ch15/ex15.11/quote.cpp b/ch15/ex15.11/quote.cpp index de2b8844..7ab50533 100644 --- a/ch15/ex15.11/quote.cpp +++ b/ch15/ex15.11/quote.cpp @@ -4,5 +4,5 @@ void Quote::debug() const { std::cout << "data members of this class:\n" << "bookNo= " <bookNo << " " - << "price= " <price<< " \n"; + << "price= " <price<< " "; } diff --git a/ch15/ex15.15.16.17/bulk_quote.cpp b/ch15/ex15.15.16.17/bulk_quote.cpp index 7191b9cf..010544f9 100644 --- a/ch15/ex15.15.16.17/bulk_quote.cpp +++ b/ch15/ex15.15.16.17/bulk_quote.cpp @@ -7,7 +7,8 @@ double Bulk_quote::net_price(std::size_t n) const void Bulk_quote::debug() const { + Quote::debug(); std::cout //<< "data members of this class:\n" << "min_qty= " << quantity << " " - << "discount= " << this->discount<< " \n"; + << "discount= " << discount<< " "; } diff --git a/ch15/ex15.15.16.17/limit_quote.cpp b/ch15/ex15.15.16.17/limit_quote.cpp index fa9100fc..37996259 100644 --- a/ch15/ex15.15.16.17/limit_quote.cpp +++ b/ch15/ex15.15.16.17/limit_quote.cpp @@ -3,7 +3,8 @@ void Limit_quote::debug() const { + Quote::debug(); std::cout //<< "data members of this class:\n" - << "max_qty= " << this->quantity << " " - << "discount= " << this->discount<< " \n"; + << "max_qty= " << quantity << " " + << "discount= " << discount<< " "; } diff --git a/ch15/ex15.15.16.17/main.cpp b/ch15/ex15.15.16.17/main.cpp index cd4744ca..981399ba 100644 --- a/ch15/ex15.15.16.17/main.cpp +++ b/ch15/ex15.15.16.17/main.cpp @@ -39,6 +39,11 @@ int main() { + /* + error C2259 : 'Disc_quote' : cannot instantiate abstract class + 1> due to following members : + 1> 'double Disc_quote::net_price(size_t) const' : is abstract + */ Disc_quote d; return 0; diff --git a/ch15/ex15.15.16.17/quote.cpp b/ch15/ex15.15.16.17/quote.cpp index f1b6b5ed..d6526321 100644 --- a/ch15/ex15.15.16.17/quote.cpp +++ b/ch15/ex15.15.16.17/quote.cpp @@ -4,5 +4,5 @@ void Quote::debug() const { std::cout //<< "data members of this class:\n" << "bookNo= " <bookNo << " " - << "price= " <price<< " \n"; + << "price= " <price<< " "; } diff --git a/ch15/ex15.30/main.cpp b/ch15/ex15.30/main.cpp index 72e64857..b2673026 100644 --- a/ch15/ex15.30/main.cpp +++ b/ch15/ex15.30/main.cpp @@ -33,10 +33,10 @@ int main() basket.add_item(Bulk_quote("Bible",20.6,20,0.3)); for (unsigned i = 0; i != 10; ++i) - basket.add_item(Bulk_quote("C++Primer",30.9,20,0.4)); + basket.add_item(Bulk_quote("C++Primer",30.9,5,0.4)); for (unsigned i = 0; i != 10; ++i) - basket.add_item(Bulk_quote("CLRS",40.1,10,0.5)); + basket.add_item(Quote("CLRS",40.1)); std::ofstream log("log.txt",std::ios_base::app|std::ios_base::out);