本文为转载,原博客地址:http://blog.csdn.net/refuil/article/details/51346844
习题答案至于一个.cc 中,编译需要包含Chapter6.h头文件。 需要演示某一题直接修改 #define NUM***, 如运行6.23题为#define NUM623;
- #ifndef CHAPTER6_H
- #define CHAPTER6_H
- int fact(int val);
- int func();
- template <typename T> T abs(T val){
- return val >= 0 ? val : -val;
- }
- #endif
- #include <iostream>
- #include "Chapter6.h"
- using namespace std;
- int main(){
- cout << "5! is "<<fact(5)<<endl;
- cout << func() <<endl;
- cout << abs(-2.34) <<endl;
- }
- #include <iostream>
- #include "Chapter6.h"
- using namespace std;
- int fact(int val){
- if(val == 0 || val ==1)
- return 1;
- else
- return val * fact(val-1);
- }
- int func(){
- int n, ret =1;
- cout<< "Enter a number: "<<endl;
- cin >> n;
- while(n > 1)
- ret *= n--;
- return ret;
- }
- #include <iostream>
- #include <vector>
- #include <cstring>
- #include <cassert>
- #include "Chapter6.h"
- #define NUM648
- #define NDEBUG
- using namespace std;
- /*6.3*/
- int fact(int val){
- if(val == 0 || val ==1)
- return 1;
- else
- return val * fact(val-1);
- }
- /*6.4*/
- int fact2(){
- int val;
- cout << "Enter a number: "<<endl;
- while(cin >> val){
- if( val == 0 || val < 0)
- cout<<"Please input a positive number. "<<endl;
- cout<< val;
- unsigned long long exp = 1;
- exp = fact(val);
- cout<< "! is: ";
- if(exp)
- cout << exp <<endl;
- else
- cout<< "too big. "<<endl;
- }
- }
- /*6.5*/
- #ifdef NUM65
- template <typename T>
- T abs(T val){
- return val > 0 ? val : -val;
- }
- #endif
- /*6.6*/
- int temp(int val1){
- static int val2 = 0;
- val2 += val1;
- return val2;
- }
- /*6.7*/
- int func(){
- static int flag = 0;
- return flag++;
- }
- /*6.10*/
- void swap(int *val1, int *val2){
- int temp;
- temp = *val1;
- *val1 = *val2;
- *val2 = temp;
- }
- /*6.11*/
- void reset(int &val){
- val = 0;
- }
- /*6.12*/
- void swap2(int &val1, int &val2){
- int temp;
- temp = val1;
- val1 = val2;
- val2 = temp;
- }
- /*6.17*/
- bool hasUpper(string &s){
- for(string::iterator it = s.begin(); it != s.end(); ++it){
- if(isupper(*it))
- return true;
- else
- return false;
- }
- }
- void changTolower(string& s){
- for(size_t it = 0; it != s.size()-1; ++it){
- if(isupper(s[it])){
- s[it] = tolower(s[it]);
- }
- }
- }
- /*6.18*/
- class matrix;
- bool compare(matrix &ma1, matrix &ma2);
- vector<int>::iterator change_val(int, vector<int>::iterator);
- /*6.21*/
- int contrast(const int val1, const int *p){
- return val1 > *p ? val1 : *p;
- }
- /*6.22*/
- void swap3(int*& val1, int*& val2){
- int* temp;
- temp = val1;
- val1 = val2;
- val2 = temp;
- }
- /*6.23*/
- void print(const int *p){
- if(p)
- cout<< *p <<endl;
- }
- void print(int size, int str[]){
- for(size_t it = 0; it!= size; ++it)
- cout<< str[it] << endl;
- }
- void print(const int* beg, const int* end){
- for(; beg!= end; )
- cout<< *beg++ <<endl;
- }
- void print(int(&arr)[2]){
- for(int i =0; i<= 1; ++i)
- cout<< arr[i]<<endl;
- }
- /*6.27*/
- #ifdef NUM627
- int sum(initializer_list<int> li){
- int sum(0);
- for(initializer_list<int>::iterator beg = li.begin(); beg!= li.end(); ++beg)
- sum += *beg;
- return sum;
- }
- #endif
- /*6.30*/
- #ifdef NUM630
- bool str_subrange(const string &str1, const string &str2){
- if(str1.size() == str2.size())
- return str1 == str2;
- size_t size = str1.size() < str2.size() ? str1.size() : str2.size();
- for(size_t i =0; i!= size; ++i){
- if(str1[i] != str2[i])
- return;
- }
- }
- #endif
- /*6.33*/
- int &get(vector<int> &ia, int index){ return ia[index]; }
- void print(vector<int>::iterator beg, vector<int>::iterator end){
- if(beg != end){
- cout << *beg <<" ";
- print(next(beg), end);
- }
- }
- /*6.35*/
- int factorial(int val){
- if(val > 1)
- return factorial(val -1) * val;
- return 1;
- }
- /*6.36*/
- string (&func2(string (&str)[10]))[10];
- /*6.37*/
- #ifdef NUM637
- typedef string arrT[10];
- arrT &func3(arrT& str);
- auto func4(arrT& str) -> string(&)[10];
- string arrS[10];
- decltype(arrS)& func5(arrT& str);
- #endif
- /*6.38*/
- int odd[] = {1,3,5,7,9};
- int even[] = {0,2,4,6,8};
- typedef int arrInt[5];
- arrInt& arrPtr(int i){
- return (i % 2) ? odd : even; //返回引用
- }
- /*6.42*/
- string make_plural(size_t ctr, const string& word, const string &ending = "s"){
- return (ctr > 1) ? word + ending : word;
- }
- /*6.44*/
- inline bool isShorter(const string &s1, const string &s2){
- return s1.size() < s2.size();
- }
- #ifdef NUM646
- /*6.46*/
- constexpr bool isShorter1(const string &s1, const string &s2){
- return s1.size() < s2.size();
- }
- #endif
- /*6.47*/
- #ifdef NUM647
- void printVector(vector<int>& vec){
- #ifdef NDEBUG
- cout << "vector size: " << vec.size() <<endl;
- #endif
- if(!vec.empty()){
- auto temp = vec.back();
- vec.pop_back();
- printVector(vec);
- cout << temp <<" ";
- }
- }
- #endif
- /*6.51*/
- #ifdef NUM651
- void f(){
- cout << "f()"<<endl;
- }
- void f(int){
- cout << "f(int)"<<endl;
- }
- void f(int, int){
- cout << "f(int, int)"<<endl;
- }
- void f(double, double = 3.14){
- cout << "f(duble, double)"<<endl;
- }
- #endif
- /*6.54*/
- typedef int func6(int, int);
- vector<func6*> vec;
- /*6.55*/
- int add(int a, int b){
- return a + b;
- }
- int substact(int a, int b){
- return a - b;
- }
- int multiply(int a, int b){
- return a * b;
- }
- int divide(int a, int b){
- return b !=0 ? a/b : 0;
- }
- int main(){
- /*6.1*/
- #ifdef NUM61
- cout<<"实参是形参的初始值,实参的类型必须与对应的形参类型匹配。"<<endl;
- #endif
- /*6.2*/
- #ifdef NUM62
- cout<<"(a)返回类型不匹配,int型改成string;(b)没有定义函数的返回类型,可以用void代替; (c)缺少一个括号; (d)函数体缺少一对括号."<<endl;
- #endif
- /*6.3*/
- #ifdef NUM63
- cout << "5!: " << fact(5) <<endl;
- #endif
- /*6.4*/
- #ifdef NUM64
- fact2();
- #endif
- /*6.5*/
- #ifdef NUM66
- cout << "The absolute of -2.34 is: "<< abs(-2.34)<<endl;
- #endif
- /*6.6*/
- #ifdef NUM66
- cout<< "形参的生命周期是从函数开始到函数终止即被销毁,局部变量的生命周期是从其被创建到函数体结束。静态局部变量在被初始化开始,直到程序结束才会被销毁。"<<endl;
- for(int val3 =0; val3 !=10; ++val3)
- cout << "静态变量与局部变量的和是: "<< temp(val3) <<endl;
- #endif
- /*6.7*/
- #ifdef NUM67
- for(int i =0; i!=4; ++i)
- cout<< func()<<endl;
- #endif
- /*6.8*/
- #ifdef NUM68
- cout<<"见Chapter6.h" <<endl;
- #endif
- /*6.9*/
- #ifdef NUM69
- cout<<"见fact.cc factMain.cc" <<endl;
- #endif
- /*6.10*/
- #ifdef NUM610
- int val1 = 1, val2 = 2;
- swap(&val1, &val2);
- cout<< "val1: "<< val1 << " val2: " << val2<<endl;
- #endif
- /*6.11*/
- #ifdef NUM611
- int val = 23;
- reset(val);
- cout << "val has been reset: "<< val <<endl;
- #endif
- /*6.12*/
- #ifdef NUM612
- for(int val1(0), val2(0); cout<< "Enter two numbers: \n", cin >> val1 >> val2;){
- swap2(val1, val2);
- cout<< "val1: "<< val1 << " val2: " << val2<<endl;
- }
- #endif
- /*6.13*/
- #ifdef NUM613
- cout<<"第一种是传值调用,调用过程中不会修改实参的值,第二种传地址引用调用,在调用过程中将会与实参的绑定。"<<endl;
- #endif
- /*6.14*/
- #ifdef NUM614
- cout<< "6.11例子中引用类型可以避免拷贝,但是在实参不希望被改变时不能使用引用形参."<<endl;
- #endif
- /*6.15*/
- #ifdef NUM615
- cout<<"首先,实参s不能够被改变,但是occur的最后值时通过函数计算的;c可能是一个临时变量,可以换成其他值;如果交换类型,s可以被改变,occur不能改变,=0,报错"<<endl;
- #endif
- /*6.16*/
- #ifdef NUM616
- cout<< "应该设置为const引用,因为s不希望被改变,可以避免拷贝,直接使用字符串常量作为参数. "<<endl;
- #endif
- /*6.17*/
- #ifdef NUM617
- string s = "C++ & Linux";
- if(hasUpper(s)) cout << "has upper letter. "<<endl;
- else cout << "no upper letter. "<<endl;
- changTolower(s);
- cout << "After tolower: " << s <<endl;
- #endif
- /*6.18*/
- #ifdef NUM618
- cout<<"见main函数外函数声明;"<<endl;
- #endif
- /*6.19*/
- #ifdef NUM619
- cout<< "(a)不合法,calc只有一个参数." <<endl;
- #endif
- /*6.20*/
- #ifdef NUM620
- cout<< "一般能用const都加上const,如果设为普通引用,可能在函数中会改变常量的值."<<endl;
- #endif
- /*6.21*/
- #ifdef NUM621
- int val1(2), val2(3);
- cout << "return the larger: " << contrast(val1, &val2) << endl;
- #endif
- /*6.22*/
- #ifdef NUM622
- int val1(2), val2(3);
- int* p1 = &val1; int* p2 = &val2;
- swap3( p1, p2);
- cout << "val1: " << *p1 << " val2: " << *p2 << endl;
- #endif
- /*6.23*/
- #ifdef NUM623
- int i =0, j[2] = {0, 1};
- print(&i);
- print(2, j);
- print(begin(j), end(j));
- print(j);
- #endif
- /*6.24*/
- #ifdef NUM624
- cout<<"没有什么问题,单数如果仅仅为了遍历数组,完全可以指针或引用的形式传递.如:"
- " void print(const int (&ia)[10]) "<<endl;
- #endif
- /*6.25*/
- #ifdef NUM625
- cout<< "见main-6.25.cc"<<endl;
- #endif
- /*6.26*/
- #ifdef NUM626
- cout<< "见main-6.26.cc"<<endl;
- #endif
- /*6.27*/
- #ifdef NUM627
- cout << "Sum of 1-5: "<< sum( {1,2,3,4,5} ) <<endl;
- #endif
- /*6.28*/
- #ifdef NUM628
- cout << "elem 的类型是const string&"<<endl;
- #endif
- /*6.29*/
- #ifdef NUM629
- cout <<"因为initializer_list的元素总是 const类型,不能在函数内改变,应该声明为常量引用类型. "<<endl;
- #endif
- /*6.30*/
- #ifdef NUM630
- cout<<"见main函数外函数声明;"<<endl;
- #endif
- /*6.31*/
- #ifdef NUM631
- cout<< "返回局部变量的引用是无效的; 如果试图对返回常量引用类型赋值,也是无效的."<<endl;
- #endif
- /*6.32*/
- #ifdef NUM632
- cout<< "合法,作用是将0-9赋值给ia数组"<<endl;
- #endif
- /*6.33*/
- #ifdef NUM633
- vector<int> vec(10,0); //需要初始化,否则传参时会出错
- for(int i =0; i != 10; ++i)
- get(vec, i) = i;
- print(vec.begin(), vec.end());
- cout <<endl;
- #endif
- /*6.34*/
- #ifdef NUM634
- cout <<"如果val为负数,将发生堆栈溢出. "<<endl;
- #endif
- /*6.35*/
- #ifdef NUM635
- cout << factorial(5)<<endl;
- cout <<" val--无法递归,报错 "<<endl;
- #endif
- /*6.36*/
- #ifdef NUM636
- cout<<"见main函数外函数声明, 第一种声明清晰,修改和阅读比较方便. "<<endl;
- #endif
- /*6.37*/
- #ifdef NUM637
- cout<<"见main函数外函数声明;"<<endl;
- #endif
- /*6.38*/
- #ifdef NUM638
- cout<<"见main函数外函数声明;"<<endl;
- #endif
- /*6.39*/
- #ifdef NUM639
- cout << "(a)非法,顶层const,重复声明. (b)非法,函数参数相同. (c)合法. "<<endl;
- #endif
- /*6.40*/
- #ifdef NUM640
- cout<< "(b)非法,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值. "<<endl;
- #endif
- /*6.41*/
- #ifdef NUM641
- cout<< "(a)非法,没有给第一个形参传值. (b)合法. (c)合法,we被赋值为'*',但与意图不符. "<<endl;
- #endif
- /*6.42*/
- #ifdef NUM642
- cout << "singual: " << make_plural(1, "success", "es")<<" "<< make_plural(1, "failure")<<endl;
- cout << "plural: " << make_plural(2, "success", "es")<<" "<< make_plural(2, "failure")<<endl;
- #endif
- /*6.43*/
- #ifdef NUM643
- cout <<"(a)内联函数放在头文件中. (b) 函数声明放在头文件中. "<<endl;
- #endif
- /*6.44*/
- #ifdef NUM644
- cout << isShorter("c++", "linux") <<endl;
- #endif
- /*6.45*/
- #ifdef NUM645
- cout << "内联函数的声明适合那些代码短小,并且容易经常被调用的函数. "<<endl;
- #endif
- /*6.46*/
- #ifdef NUM646
- cout << isShorter1("c++", "linux") <<endl;
- #endif
- /*6.47*/
- #ifdef NUM647
- vector<int> vec{1,2,3,4,5};
- printVector(vec);
- cout <<endl;
- #endif
- /*6.48*/
- #ifdef NUM648
- string s, sought("no");
- while(cin >>s && s != sought){ }
- assert(cin);
- cout<< "不合理,因为cin输入总是有内容的,所以assert中的表达式总是为真,就不会执行assert. "<<endl;
- #endif
- /*6.49*/
- #ifdef NUM649
- cout << "函数匹配的第一步是选定本次调用对应的重载函数集,集合中的函数称为候选函数. 第二步考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数. "<<endl;
- #endif
- /*6.50*/
- #ifdef NUM650
- cout << "(a) 2.56匹配double,但是42匹配int.(b)匹配void f(int). (c)匹配void f(int, int). (d)匹配void f(double, double = 3.14);"<<endl;
- #endif
- /*6.51*/
- #ifdef NUM651
- f(2.56, 42);
- f(42);
- f(42, 0);
- f(2.56, 3.14);
- #endif
- /*6.52*/
- #ifdef NUM652
- cout << "(a)3, 通过类型提升实现的匹配. (b)4, 通过算术类型转换实现的匹配. "<<endl;
- #endif
- /*6.53*/
- #ifdef NUM653
- cout <<"(a)没有影响,const是顶层实现,第二句实现了函数重载. (b)非法,重复声明."<<endl;
- #endif
- /*6.54*/
- #ifdef NUM654
- cout <<"见main函数外声明. "<<endl;
- #endif
- /*6.55*/
- #ifdef NUM655
- vec.push_back(add);
- vec.push_back(substact);
- vec.push_back(multiply);
- vec.push_back(divide);
- for(vector<func6*>::iterator it = vec.begin(); it != vec.end(); ++it)
- cout << (*it)(100, 50)<< " "; //*it两端的括号必不可少, 否则函数返回vector类型的指针, 而非函数指针.
- cout <<endl;
- #endif
- return 0;
- }
参考资料:
c++ primer中文版第五版,电子工业出版社。c++ primer第四版习题解答,人民邮电出版社。