我不明白为什么迭代带有for循环的容器会产生不同的结果,而不是使用while循环迭代它。以下MWE用向量和一组5个整数来说明这一点。
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main()
{
vector<int> v;
set<int> s;
// add integers 0..5 to vector v and set s
for (int i = 0; i < 5; i++) {
v.push_back(i);
s.insert(i);
}
cout << "Iterating through vector with for loop.\n";
vector<int>::const_iterator itv;
for (itv = v.begin(); itv != v.end(); itv++) cout << *itv << ' ';
cout << '\n';
cout << "Iterating through set with for loop.\n";
set<int>::const_iterator its;
for (its = s.begin(); its != s.end(); its++) cout << *its << ' ';
cout << '\n';
cout << "Iterating through vector with while loop.\n";
itv = v.begin();
while (itv++ != v.end()) cout << *itv << ' ';
cout << '\n';
cout << "Iterating through set with while loop.\n";
its = s.begin();
while (its++ != s.end()) cout << *its << ' ';
cout << '\n';
}
以上产生:
Iterating through vector with for loop.
0 1 2 3 4
Iterating through set with for loop.
0 1 2 3 4
Iterating through vector with while loop.
1 2 3 4 0
Iterating through set with while loop.
1 2 3 4 5
for循环按预期工作,但不是while循环。由于我使用++
作为后缀,我不明白为什么while循环的行为与它们一样。另一个谜团是为什么while循环为集合5
打印s
,因为此数字未插入s
。
答案 0 :(得分:12)
您的while
循环不等同于for
循环。
for
循环等同于
itv = v.begin();
while(itv != v.end()) {
cout << *itv << ' ';
itv++;
}
请注意, cout
之后增量发生。在while
循环中,您在cout
之前执行测试中的增量。即使使用postincrement,增量也会在循环体执行之前生效。
像我在那里写的那样写while
循环,差异就会消失。
答案 1 :(得分:9)
使用for
循环进行迭代时,只有在计算主体后才增加迭代器。当您使用while
循环进行迭代时,在检查之后但在循环体之前递增迭代器。在while
循环的最后一次迭代中取消引用迭代器会导致未定义的行为。
答案 2 :(得分:1)
这可能是因为在评估表达式的其余部分之前,编译器首先评估while表达式中的its++
。
答案 3 :(得分:1)
由于我使用++作为后缀,我不明白为什么while循环的行为与它们一样。
那是因为首先评估while谓词,然后(如果谓词为真),while循环的主体。当您尝试访问正文中的值时,迭代器已经递增。
答案 4 :(得分:1)
只是一些“随机”样式提示,主要显示算法使用和现代C ++ 11功能。
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <iterator>
int main()
{
const std::vector<int> v { 0,1,2,3,4 };
const std::set<int> s { 0,1,2,3,4 };
for (auto element : v)
std::cout << element << ' ';
std::cout << '\n';
for (auto element : s)
std::cout << element << ' ';
std::cout << '\n';
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::copy(s.begin(), s.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}