问题是(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]
...