使用向量循环时,是否有错误

Is there a bug when using for loop with vectors?

本文关键字:是否 有错误 循环 向量      更新时间:2023-10-16

问题是(int i = 0; i< vector.size(( - 1; i (时,它为我提供了一个"向量下标"范围"错误。但是,如果我将vector.size(( - 1放入变量中,则可以工作。这是小故障还是我只是缺少什么?

这有效:

    int sizePos = positionsX.size() - 1;
    for (int i = 0; i < sizePos; i++) {
        if (snake.getX() == positionsX[i] && snake.getY() == positionsY[i]) {
            gameOver = true;
            std::cout << as << std::endl;
            as++;
        }
        if (apple.getX() == positionsX[i] && apple.getY() == positionsY[i]) {
            apple.eat();
        }
    }

这不是:

    for (int i = 0; i < positionsX.size() - 1; i++) {
        if (snake.getX() == positionsX[i] && snake.getY() == positionsY[i]) {
            gameOver = true;
            std::cout << as << std::endl;
            as++;
        }
        if (apple.getX() == positionsX[i] && apple.getY() == positionsY[i]) {
            apple.eat();
        }
    }

positionsX.size()unsigned类型。如果它为零,则从中减去1,它会给您带来无符号类型的最大值,这是由于 wrap-around ,以及在无符号算术中评估表达式的事实!

使用

for (std::size_t i = 0; i + 1 < positionsX.size(); i++) {

而是,这一切都不会省略向量中的最终元素。如果您不想要那个,请删除+ 1

您没有指出什么含义"不起作用",在这种情况下,代码不起作用。

但是,回答您的问题

使用向量使用循环时是否有错误?

我会说代码确实有错误。

首先,向量的大小定义为无符号积分类型。通常,int类型无法满足未签名积分类型的所有值。

在此表达式

positionsX.size() - 1

使用了无符号积分类型的算术。那就是表达式 positionsX.size() - 1被转换为无符号积分类型,并且等于positionsX.size()等于0的类型的最大值。

static_cast<decltype( positionsX )::size_type>( positionsX.size() - 1 );

例如,对于空矢量,您可以获得以下结果

#include <iostream>
#include <vector>
int main()
{
    std::vector<int> positionsX;
    auto size = static_cast<decltype( positionsX )::size_type>( positionsX.size() - 1 );
    std::cout << size << 'n';
}

控制台输出为

18446744073709551615

在第一种情况下,使用中间变量

int sizePos = positionsX.size() - 1;

表达式的结果

positionsX.size() - 1

可以被截断以适合int类型的对象,并且相应的索引将是有效的(尽管该范围可能是整个无效的,即可能小于实际范围(。

因此,您的问题是您使用的是类型int而不是原始类型

decltype( positionX )::size_type

也省略了向量的最后一个元素。

正确的循环可以看起来以下方式

for (decltype( positionX )::size_type i = 0; i < positionsX.size(); i++) {
    //...
}

或至少您应该使用类型size_t作为变量i的类型(尽管第一个变体更正确(

for ( size_t i = 0; i < positionsX.size(); i++) {
    //...
}

如果positionsX向量为空,则positionsX.size() - 1评估为size_t(-1),这是一个很大的正值。

在您的第一个片段中,当转换为int时,该值可能会变回" -1"。并跳过循环主体。

在比较i < positionsX.size() - 1中使用时,编译器将i转换为未签名的size_t,并且比较得出。循环主体被执行。它尝试访问不存在的positionsX[0] ...