如何使用哨兵触发结束向量

How to use a sentinel to trigger end of vector?

本文关键字:结束 向量 何使用 哨兵      更新时间:2023-10-16

我对编程(一般来说)和c++(特别是)是新手。我正在学习向量,并试图写一个简单的程序,

  1. 允许用户输入学生考试成绩的矢量
  2. 当用户输入哨兵(在本例中为-1)时,向量终止
  3. 输出学生成绩的统计

下面是我的代码:

#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int SENTINEL = -1;
vector<int> studentGrades = { 0 };
int myInput;
int main()
{
    do
    {
        cout << "Please enter a student's grade: ";
        cin >> myInput;
        if (myInput < 1000)
        {
            studentGrades[myInput]++;
        }
        studentGrades.push_back(myInput);
    } while (myInput != SENTINEL);

    cout << "n";
    for (int i = 0; i < 1000; i++)
        cout << i << " grade(s) of " << studentGrades[i] << endl;
    return 0;
}

两个问题:

1)谁能提供指导,为什么这个代码只允许我进入一个学生的成绩?

2)计算"计数"的for循环是否正确?

提前感谢你看一看,瑞安

*修订代码*

@ jx -这是修改后的代码:

#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int SENTINEL = -1;
vector<int> studentGrades = { 0 };
int myInput;
int main()
{
    do
    {
        cout << "Please enter a student's grade (or -1 to QUIT): ";
        cin >> myInput;
        if (myInput < 1000)
        {
            studentGrades.at(myInput)++;
        }
        studentGrades.push_back(myInput);
    } while (myInput != SENTINEL);

    cout << "n";
    for (int i = 0; i < 1000; i++)
        cout << i << " grade(s) of " << studentGrades.at(myInput) << endl;
    return 0;
}

和,我看到这个错误:

0x7707C42D异常

Microsoft c++异常:std::out_of_range at memory location 0x0035F890

问题不止一个。当用户输入哨兵值时,试图访问studentGrades[-1],默认向量只包含一个0的条目,以及使用push_back。

让我们来看看其中的一些问题:

  • 用户运行程序。用户输入100。studentGrades[100]超出了范围。当vector只有一个元素时,会出现未定义行为。
  • 用户运行程序,输入-1 studentGrades[-1]超出范围。
  • 用户运行程序,输入0。studentGrades[0]在范围内,递增到1。studentGrades.push_back(1)添加一个元素到向量studentGrades[1]现在也等于1。

作为一个很好的起点,如果您将下标向量引用交换为方法中的向量,如我下面所示,您将得到超出范围的错误,这将有很大帮助。下面的代码仍然需要工作,但至少你会有运行时错误,而不是奇怪的行为。

int main()
{
    do
    {
        cout << "Please enter a student's grade: ";
        cin >> myInput;
        if (myInput < 1000)
        {
            studentGrades.at(myInput)++;
        }
        studentGrades.push_back(myInput);
    } while (myInput != SENTINEL);

    cout << "n";
    for (int i = 0; i < 1000; i++)
        cout << i << " grade(s) of " << studentGrades.at(myInput) << endl;
    return 0;
}

我想如果我实现这个,我会使用std::map而不是一个向量。它可以让你有一个studentGrade[1000],而不必先为studentGrade[0]分配内存到[999]。

然而,当你学习std::vector时,检查vector::resize以设置vector的大小足以容纳所需的元素,std::vector::size以确定是否需要增加vector的大小。然后可以去掉push_back。

引用

向量:http://www.cplusplus.com/reference/vector/vector/at/

向量:大小:http://www.cplusplus.com/reference/vector/vector/size/