C++反向'for'循环

SKI*_*KIP 6 c++ unsigned for-loop

我有一个向量:

std::vector<int> vec = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

我想做一个反向for循环。它有效,当我写:

for(int i = vec.size() - 1; i >= 0; --i) {
    std::cout << i << std::endl; // 2, 1, 0
}
Run Code Online (Sandbox Code Playgroud)

但是如果我这样写,我会得到一个非常大的数字(比如 18446744073709223794):

for(size_t i = vec.size() - 1; i >= 0; --i) {
    std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是当我写的时候它们都有效:

for(int i = 0; i < vec.size() - 1; ++i) {
    std::cout << i << std::endl; // 1, 2, 3
}

// Or
for(size_t i = 0; i < vec.size() - 1; ++i) {
    std::cout << i << std::endl; // 1, 2, 3
}
Run Code Online (Sandbox Code Playgroud)

为什么我在使用时得到了错误的向量大小size_t?

我认为转换有问题。

ein*_*ica 9

让编译器告诉你出了什么问题!

如果你在启用警告的情况下编译你的程序,编译器会告诉你这样的事情:

<source>: In function 'int main()':

7:43: warning: comparison of unsigned expression in '>= 0' is always true [-Wtype-limits]
    7 |     for(std::size_t i = vec.size() - 1; i >= 0; --i) {
      |                                         ~~^~~~
Run Code Online (Sandbox Code Playgroud)

这是为什么?这是因为std::size_t是C++ 中的无符号类型;它只代表非负数。阅读更多关于打开警告以及为什么它很重要:为什么我应该总是启用编译器警告?

那么,我们应该如何反向迭代呢?

我决定将我的答案拆分为一个单独的问题,与 OP 的错误无关。请去阅读它。


Haa*_*hii 6

问题是它size_t是一个无符号整数,即它只能有正值。当您为无符号类型减少 0 时,会发生下溢,结果通常是该类型可表示的最大整数,例如 18446744073709223794 在您的情况下。最后,i >= 0对于任何无符号类型,检查始终为真,并且您的循环永远不会终止。