essential c++ 第一章教学程序还原

前言

在阅读Essential c++ 的过程中,我发现作者所使用的教学片段似乎是从同一个文件中摘录而来,但并没有给出该文件的代码。于是我决定自己尝试复原它。在这一过程中,我收益匪浅,捡回了很多看书时忽略的知识点。希望能与大家分享这些感受。

我所遇到的一些问题

1.指针类型不同所带来的错误(error: cannot convert ‘int*’ to ‘std::vector*’ in initialization)

以下为错误代码:

const int max_seq = 6;
const int seq_size = 18;
int elem_vals[seq_size] = {
        1, 2, 3,
        3, 4, 7,
        2, 5, 12,
        3, 6, 10,
        4, 9, 16,
        5, 12, 22
    };

vector<int> *seq_addrs[max_seq] = {
        elem_vals, (elem_vals+3), (elem_vals+6),
        (elem_vals+9), (elem_vals+12), (elem_vals+15)
    };

可以看出
//int* 可以作为 vector 的参数创建vector object
//但却不能用以创建指针数组 vector *seq_addrs[max_seq]
修正如下:

    const int seq_size = 18;
    int elem_vals[seq_size] = {
        1, 2, 3,
        3, 4, 7,
        2, 5, 12,
        3, 6, 10,
        4, 9, 16,
        5, 12, 22
    };
    vector<int> elem_seq(elem_vals,elem_vals + seq_size);
    //int* 可以作为 vector<int> 的参数创建vector object
    //但却不能用以创建指针数组 vector<int> *seq_addrs[max_seq]
    const int max_seq = 6;
    string seq_names[max_seq] = {
        "Fibonacci",
        "Lucas",
        "Pell",
        "Triangular",
        "Square",
        "Pentagonal"
    };
    vector<int> Fibonacci(elem_vals,elem_vals+3), 
                Lucas(elem_vals+3,elem_vals+6),
				Pell(elem_vals+6,elem_vals+9), 
				Triangular(elem_vals+9,elem_vals+12), 
				Square(elem_vals+12,elem_vals+15),
				Pentagonal(elem_vals+15,elem_vals+18);
    vector<int> *seq_addrs[max_seq] = {
        &Fibonacci, &Lucas, &Pell, &Triangular, &Square, &Pentagonal
    };

2. 关于rand() 和 srand()

rand() 和 srand() 是标准程序库提供的伪随机数(pseudo-random number)产生器。srand() 是随机数产生种子(seed)。使用它们需要头文件 cstdlib。
以下为示例:

int num = 1,seq_index = 0;
    vector<int> *cur_tuple = 0;
    cout << "Please enter a number to reset the random number.\n";
    cin  >> num;
    srand(num);
    seq_index = rand() % max_seq;
    cur_tuple = seq_addrs[seq_index];

3. 下标运算符的较高优先级带来的问题(error: no match for ‘operator*’ (operand type is ‘std::vector’))

提领(dereference):即取得位于该指针所指内存地址上的对象
如:

int a;
a = *pi;

但下标运算符的优先级较高,所以有可能出现以下错误:

cout << "The first two elements of the sequence are: "
             << *cur_tuple[0] << ", "// 0
             << (*cur_tuple)[1]      // 1
             << "\nWhat is the next element?\n";
//error: no match for 'operator*' (operand type is 'std::vector<int>')

这时将 0 处改为 1 处即可,即现执行提领操作,再下标运算。

4.对书中内容的一些改动

else
        {
            string name;
            int nt;
            int nc;

            while(in_file >> name)
            {
                in_file >> nt >> nc;
                if(name == usr_name)
                {
                    num_tries_t = nt;
                    num_right = nc;
                }
            }
            cout << "Welcome back, " << usr_name
                 << "\nYour current score is " << nc
                 << " out of " << nt << "\nGood Luck!\n";
        }

最终代码

/*
"The value 2, 3 for two consecutive
    elements of a numerical sequence.
 What is the next value?
pineklll 
2021/3/27
*/
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <cstdlib>
//rand() and srand() 都是伪随机(pseudo-random)数生成器, 包含于此头文件中
using namespace std;
int main()
{
    string usr_name;
    int usr_val, num_tries = 0, num_right = 0, num_tries_t = 0;
    double usr_score = 0.0;
    bool next_seq = true;
    int usr_guess = 0;
    char usr_rsp;

    cout << "Enter your name:\n";
    cin >> usr_name;
     ofstream out_file("D:\\cpp code\\my blog code_1\\seq_data.txt",ios_base::app);
    if(!out_file)
        {cerr << "Oops! Unable to open output file!\n"; return -2;}
    ifstream in_file("D:\\cpp code\\my blog code_1\\seq_data.txt");
    if(!in_file)
        {cerr << "Nice to meet you!\n"; }
    else
        {
            string name;
            int nt;
            int nc;

            while(in_file >> name)
            {
                in_file >> nt >> nc;
                if(name == usr_name)
                {
                    num_tries_t = nt;
                    num_right = nc;
                }
            }
            cout << "Welcome back, " << usr_name
                 << "\nYour current score is " << nc
                 << " out of " << nt << "\nGood Luck!\n";
        }

    const int seq_size = 18;
    int elem_vals[seq_size] = {
        1, 2, 3,
        3, 4, 7,
        2, 5, 12,
        3, 6, 10,
        4, 9, 16,
        5, 12, 22
    };
    vector<int> elem_seq(elem_vals,elem_vals + seq_size);
    const int max_seq = 6;
    string seq_names[max_seq] = {
        "Fibonacci",
        "Lucas",
        "Pell",
        "Triangular",
        "Square",
        "Pentagonal"
    };
    vector<int> Fibonacci(elem_vals,elem_vals+3), 
                Lucas(elem_vals+3,elem_vals+6),
				Pell(elem_vals+6,elem_vals+9), 
				Triangular(elem_vals+9,elem_vals+12), 
				Square(elem_vals+12,elem_vals+15),
				Pentagonal(elem_vals+15,elem_vals+18);
    vector<int> *seq_addrs[max_seq] = {
        &Fibonacci, &Lucas, &Pell, &Triangular, &Square, &Pentagonal
    };


    int num = 1,seq_index = 0;
    vector<int> *cur_tuple = 0;
    cout << "Please enter a number to reset the random number.\n";
    cin  >> num;
    srand(num);
    seq_index = rand() % max_seq;
    cur_tuple = seq_addrs[seq_index];
    while(next_seq == true)
    {
        cout << "The first two elements of the sequence are: "
             << (*cur_tuple)[0] << ", "
             << (*cur_tuple)[1]
             << "\nWhat is the next element?\n";
        cin  >> usr_guess;
        ++num_tries;
        ++num_tries_t;
        if(usr_guess == (*cur_tuple)[2])
        {
            ++num_right;
            cout << "Very good. Yes, "
                 << (*cur_tuple)[2]
                 << " is the next element in the "
                 << seq_names[seq_index] << " sequence.\n";
                 break;
        }
        else
        {
            switch (num_tries)
            {
            case 1:
                cout << "Oops! Nice guess but not quite it.\n";
                break;
            case 2:
                cout << "Hum. Sorry but wrong a second time.\n";
                break;
            case 3:
                cout << "Ah, this is harder than it looks, isn't it?\n";
                break;
            default:
                cout << "It must be getting pretty frustrating by now!\n";
                break;

            }
            cout << "Want to try again?(Y/N)";
            cin >> usr_rsp;
            if(usr_rsp == 'N' || usr_rsp == 'n')
            {
                next_seq = false;
                cout << "Thanks for playing!";
            }
            else
            {
                seq_index = rand() % max_seq;
                cur_tuple = seq_addrs[seq_index];
            }
        }
    }
    out_file << usr_name << ' '
             << num_tries_t << ' '
             << num_right << endl;
    return 0;
}

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值