i + 1 < vec.size() 和 i < vec.size() - 1 的区别

6

在编程时,我发现当我使用条件i < vec.size() - 1时,我的代码会给出运行时错误,但是当我使用i + 1< vec.size()时,它可以正常工作。这里的vec是一个空的std :: vector

//giving error
vector<int> vec;
for (int i = 0; i < vec.size() - 1; i++)
{
    //some code
}
//not giving error
vector<int> vec;
for (int i = 0; i + 1 < vec.size(); i++)
{
    //some code
}

1
你的代码仅迭代 size() - 1 个元素(意味着它会错过向量的最后一个元素)。这是你真正想要的吗?还是你实际上打算迭代整个向量? - Nikos C.
2个回答

13

std::vector::size 方法返回一个无符号的 std::size_t 值。如果它是空的,你会得到 0 - 1,但如果将其表示为无符号数字,那么它将下溢并变成 18446744073709551615,根据二进制补码表示法


3
请注意,这不是字面上的“0-1”,而是“0u-1”、“0ul-1”或“0ull-1”(取决于实现方式)。 - Stack Danny
2
@StackDanny 这个网站需要一种标记纯数学表达式的方法,以消除与编程语言表达式的歧义 :) - eerorika
2
请注意,“二进制补码”所说的内容不会影响 std::size_t(0) - 1 的结果,因为无符号类型没有符号表示。标准规定,结果在模最大可表示值加1(或2 **位数)的情况下是同余的。-1与X-1模X同余。 - eerorika
实际上,二进制补码与此无关。 - Lightness Races in Orbit
@eerorika 这可能是在 Meta StackOverflow 上一个不错的功能请求。 - Stack Danny

4

附注:不建议将有符号数和无符号数进行比较。在C++20中,我们将会有一个新函数std::ssize,返回一个有符号类型。那么你的示例可以写成:

 for (std::ptrdiff_t i = 0; i < std::ssize(vec) - 1; ++i)
 {
     //some code
 }

将是完全有效的。

还请注意,声明了istd::ptrdiff_t(有符号整数类型),用于表示数组索引。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接