[Essential C++ notes] Chapter 2 配套练习题

原书:Essential C++, Stanley B. Lippman, 电子工业出版社, 2013.
章节:第2章 面向过程的编程风格
环境:CLion + MinGW + GCC 8.1.0


2.1 改写程序,让用户不断输入位置值,直到用户希望停止

#include <iostream>
#include <iomanip>
using namespace std;
bool fibonacci_elem(int, int &);
int main() {
    int index, elem;
    cout << "Please enter a positive integer, and you can enter -1 to terminate" << endl;
    while(cin >> index) {
        if(index == -1)
            break;
        fibonacci_elem(index, elem);
        cout << elem << endl;
        cout << "Please enter a positive integer, and you can enter -1 to terminate" << endl;
    }
    return 0;
}

bool fibonacci_elem(int index, int &elem) {
    const int max_index = 45;		// 限制最大索引值,否则结果可能会溢出
    if(index <= 0 || index > max_index){
        cerr << "Your should enter a positive integer no more than "
             << max_index << endl;
        return false;	// 返回值为布尔类型,表示能否计算得到指定索引的Fibonacci序列元素
    }
    int ans = 1;
    int n1 = 1, n2 = 1;
    for(int i = 3; i <= index; ++i){
        ans = n1 + n2;
        n1 = n2;
        n2 = ans;
    }
    elem = ans;		// 通过引用返回对应的Fibonacci序列元素值
    return true;
}

2.2 Pentagonal数列的求值公式为P(n) = n(3n - 1) / 2,借此产生1,5,12,22,35等元素值。定义一个函数利用上述公式将元素放到用户传入的vector中,元素个数由用户指定,检查元素个数的有效性。定义另一个函数,将给定的vector的所有元素一一打印出来,函数的第二参数接受一个字符串,表示存放在vector内的数列的类型。最后编写main()函数测试以上函数

#include <iostream>
#include <vector>
using namespace std;
bool pent_seq(vector<int> & vec, int size);
void display(const vector<int> & vec, string msg);
int main(){
    int size;
    cin >> size;
    vector<int> vec;
    if(pent_seq(vec, size))
        display(vec, "int");
    return 0;
}
bool pent_seq(vector<int> & vec, int size) {	
	// 题目要求用户传入vector,使用pass by reference,返回bool值表示size有效性
    const int max_size = 1024;
    if(size <= 0 || size > max_size) {
        cerr << "Invalid size" << endl;
        return false;
    }
    for(int i = 1; i <= size; i++)
        vec.push_back(i * (3 * i - 1) / 2);
    return true;
}
void display(const vector<int> & vec, string msg){
    cout << "The type of the elements in the vector is " << msg << endl;
    for(int i = 0; i < vec.size(); i++){
        cout << vec[i] << ' ';
        if((i + 1) % 10 == 0)
            cout << endl;
    }
}

2.3 将2.2中的Pentagonal数列求值函数拆分为两个函数,其中之一为inline,用于检验元素个数是否合理,若合理且尚未被计算则执行第二个函数以执行实际的求职工作

(1) 将inline函数check_size()定义在头文件中

// pent.h
#ifndef CHAPTER2_PENT_H
#define CHAPTER2_PENT_H

#include <iostream>
inline bool check_size(int size) {		// 将inline函数定义在头文件中
    const int max_size = 1024;
    if(size <= 0 || size > max_size) {
        std::cerr << "Invalid size" << std::endl;
        return false;
    }
    return true;
}
#endif //CHAPTER2_PENT_H

(2) 相对于用户传入vector,在pent_seq中定义静态局部对象,并返回指向该对象的const vector<int>*指针给用户可能是更好的实现方式

// main.cpp
#include <iostream>
#include <vector>
#include "pent.h"		// 包含自定义的pent.h头文件,其中包含inline函数check_size的定义
using namespace std;

const vector<int>* pent_seq(int size);
void display(const vector<int> & vec, const string& msg);
int main(){
    int size;
    cin >> size;
    const vector<int>* vec;
    if(check_size(size)){
        vec = pent_seq(size);
        display(*vec, "int");
    }
    return 0;
}
const vector<int>* pent_seq(int size) {
    static vector<int> vec;		// 静态局部对象
    for(int i = vec.size() + 1; i <= size; i++)
        vec.push_back(i * (3 * i - 1) / 2);
    return &vec;
}
void display(const vector<int> & vec, const string& msg){
    cout << "The type of the elements in the vector is " << msg << endl;
    for(int i = 0; i < vec.size(); i++){
        cout << vec[i] << ' ';
        if((i + 1) % 10 == 0)
            cout << endl;
    }
}

2.4 编写函数,以局部静态的vector存储Pentagonal数列元素,返回一个const指针指向该vector,若vector的大小小于指定的元素个数,扩充vector。实现第二个函数,接受位置值,返回该位置上的元素,编写main()函数测试

int pent_elem(int pos) {
    const vector<int> * vec = pent_seq(pos);
    if(vec)
        return (*vec)[pos-1];
    else
        return -1;
}
const vector<int>* pent_seq(int size) {
    static vector<int> vec;
    if(!check_size(size))
        return nullptr;
    for(int i = vec.size() + 1; i <= size; i++)
        vec.push_back(i * (3 * i - 1) / 2);
    return &vec;
}

2.5 实现一个重载的max()函数,接受两个整数,两个浮点数,两个字符串,一个整数vector,一个浮点数vector,一个字符串vector,一个整数数组以及一个表示数组大小的整数,一个浮点数数组以及表示数组大小的整数,一个字符串数组即表示数组大小的整数,编写main()测试这些函数

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int max(int, int);
double max(double, double);
string max(const string&, const string&);
int max(const vector<int>*);
double max(const vector<double>*);
string max(const vector<string>*);
int max(const int*, int);
double max(const double*, int);
string max(const string*, int);
int main() {
    int i1 = 1, i2 = 2;
    double d1 = 1.0, d2 = 2.0;
    string s1 = "abc", s2 = "ABC";
    int arr1[] = {i1, i2};
    double arr2[] = {d1, d2};
    string arr3[] = {s1, s2};
    vector<int> vec1(arr1, arr1 + 2);
    vector<double> vec2(arr2, arr2 + 2);
    vector<string> vec3(arr3, arr3 + 2);

    cout << max(i1, i2) << endl;
    cout << max(d1, d2) << endl;
    cout << max(s1, s2) << endl;

    cout << max(&vec1) << endl;
    cout << max(&vec2) << endl;
    cout << max(&vec3) << endl;

    cout << max(arr1, 2) << endl;
    cout << max(arr2, 2) << endl;
    cout << max(arr3, 2) << endl;
    return 0;
}
int max(int val1, int val2) {
    return val1 >= val2? val1 : val2;
}
double max(double val1, double val2) {
    return val1 >= val2? val1 : val2;
}
string max(const string& val1, const string& val2) {
    return val1 >= val2? val1 : val2;
}
int max(const vector<int>* vec) {
    return *max_element(begin(*vec), end(*vec));
}
double max(const vector<double>* vec) {
    return *max_element(begin(*vec), end(*vec));
}
string max(const vector<string>* vec) {
    return *max_element(begin(*vec), end(*vec));
}
int max(const int *arr, int size) {
    int max_val = -10e6;
    for(int i = 0; i < size; i++) {
        if(arr[i] > max_val)
            max_val = arr[i];
    }
    return max_val;
}
double max(const double *arr, int size) {
    double max_val = -10e6;
    for(int i = 0; i < size; i++) {
        if(arr[i] > max_val)
            max_val = arr[i];
    }
    return max_val;
}
string max(const string *arr, int size) {
    string max_val;
    for(int i = 0; i < size; i++) {
        if(arr[i] > max_val)
            max_val = arr[i];
    }
    return max_val;
}

2.6 以template重新完成2.5,编写main()进行测试

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<typename type> type max_elem(type, type);
template<typename elem_type> elem_type max_elem(const vector<elem_type>*);
template<typename array_type> array_type max_elem(const array_type*, int);

int main() {
    int i1 = 1, i2 = 2;
    double d1 = 1.0, d2 = 2.0;
    string s1 = "abc", s2 = "ABC";
    int arr1[] = {i1, i2};
    double arr2[] = {d1, d2};
    string arr3[] = {s1, s2};
    vector<int> vec1(arr1, arr1 + 2);
    vector<double> vec2(arr2, arr2 + 2);
    vector<string> vec3(arr3, arr3 + 2);

    cout << max_elem(i1, i2) << endl;
    cout << max_elem(d1, d2) << endl;
    cout << max_elem(s1, s2) << endl;

    cout << max_elem(&vec1) << endl;
    cout << max_elem(&vec2) << endl;
    cout << max_elem(&vec3) << endl;

    cout << max_elem(arr1, 2) << endl;
    cout << max_elem(arr2, 2) << endl;
    cout << max_elem(arr3, 2) << endl;
    return 0;
}

template<typename type>
type max_elem(type val1, type val2) {
    return val1 >= val2? val1 : val2;
}
template<typename elem_type>
elem_type max_elem(const vector<elem_type>* vec) {
    return *max_element(begin(*vec), end(*vec));
}
template<typename array_type>
array_type max_elem(const array_type *arr, int size) {
    return *max_element(arr, arr + size);
}

在CLion + MinGW + GCC8.1.0环境下,命名为max()函数引发了冲突,错误信息如下

error: call of overloaded 'max(int&, int&)' is ambiguous
     cout << max(i1, i2) << endl;

函数名改为max_elem后能正常编译运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值