在向量中使用for循环时是否存在错误?

时间:2019-05-17 13:13:07

标签: c++ loops vector unsigned-integer integer-arithmetic

问题是当我执行“ for(int i = 0; i

这有效:

    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();
        }
    }

3 个答案:

答案 0 :(得分:7)

program test use cwd, only: getCWD implicit none character(len=255) :: path integer :: error error = getCWD(path) print *, error if (error == 0) print *, path end program positionsX.size()类型。如果为零,则由于 wrap-around 以及表达式以无符号算术求值的事实而从中减去1,即可得到无符号类型的最大值!

使用

unsigned
取而代之的是,

总是会省略向量中的最后一个元素。如果您不想这样做,请放下for (std::size_t i = 0; i + 1 < positionsX.size(); i++) {

答案 1 :(得分:2)

如果positionsX向量为空,则positionsX.size() - 1的计算结果为size_t(-1),这是一个非常大的正值。

在转换为int时,如您的第一个代码段中所示,该值可能会变成'-1'。并且循环主体被跳过。

当在比较i < positionsX.size() - 1中使用时,编译器将i转换为无符号size_t,比较结果为true。循环体被执行。然后它尝试访问不存在的positionsX[0] ...

答案 2 :(得分:2)

您没有指出“不起作用”的含义,在这种情况下,代码不起作用。

尽管如此回答您的问题

  

在向量中使用for循环时是否存在错误?

我会说代码确实有错误。

首先将向量的大小定义为无符号整数类型。类型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++) {
    //...
}