修复向后的array.size()无符号整数

时间:2018-12-27 10:33:39

标签: c++ arrays

我想向后打印数组。为什么返回array.size()-1会给出无符号long的最大数量?

int main(){

  array<double, 5> zArray = {};

  for (unsigned int i = 0; i < zArray.size(); ++i) {
     cout << "Input "<< i+1 << ". Number: ";
     cin >> zArray.at(i);
  }

  cout << "Backwards" << endl;


  for (unsigned int j = zArray.size() -1; j >= 0; j--) {
     cout << zArray.at(j) << " ";
  }

  cout << endl;
}

当我用普通整数替换for循环时,程序正常运行。为什么unsigned int返回最大为std::out_of_range的错误4294967295? array.size()的返回值是一个无符号的整数吗?

完整错误:terminate called after throwing an instance of 'std::out_of_range' what(): array::at: __n (which is 4294967295) >= _Nm (which is 5)

2 个答案:

答案 0 :(得分:2)

您的for循环永远不会结束。由于junsigned,因此它将始终大于或等于零。因此j >= 0将永远是正确的。

在从unsigned值中减去之前,您确实需要测试以确保减法不会下溢。并且您的编译器应该警告您比较将始终为真。

答案 1 :(得分:0)

数组的size()方法返回一个 unsigned 值,因此当您向后循环并到达索引0时,下一次迭代会将j设置为0 - 1,环绕到无符号类型的最大值。这是语言的定义行为。因此,您的>= 0条件将始终为真。

std::out_of_range错误是因为数组的at()方法执行边界检查,并且换行的结果产生的值超出了数组定义的边界,就像错误消息所指出的那样。

您可以通过使用迭代器而不是索引来避免这种情况:

int main(){
    array<double, 5> zArray = {};
    std::size_t idx = 0;

    for (auto &d : zArray) {
        cout << "Input " << idx + 1 << ". Number: ";
        cin >> d;
        ++idx;
    }

    cout << "Backwards" << endl;

    for (auto iter = zArray.rbegin(); iter != zArray.rend(); ++iter) {
        cout << *iter << " ";
    }

    cout << endl;
}