您的位置:首页 > 编程语言 > C语言/C++

c++ primer(第五版)习题答案代码版(第六章)函数

2018-01-16 22:21 267 查看
本文为转载,原博客地址: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

[cpp] view
plain copy

#include <iostream>

#include "Chapter6.h"

using namespace std;

int main(){

cout << "5! is "<<fact(5)<<endl;

cout << func() <<endl;

cout << abs(-2.34) <<endl;

}

[cpp] view
plain copy

#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;

}

[cpp] view
plain copy

#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第四版习题解答,人民邮电出版社。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐