嵌套循环中迭代器的行为与C ++中的随机访问

时间:2013-02-21 22:42:30

标签: c++ stl iterator

为什么以下代码段会提供不同的输出? (见下面的输出)

摘录1:

vector<int> v;
v.push_back(1);
v.push_back(2);
vector<int>::const_iterator iterv1=v.begin();
vector<int>::const_iterator iterv2=v.begin();
for(;iterv1!=v.end();++iterv1){
    for(;iterv2!=v.end();++iterv2){
        cout << "*iterv1 = " << *iterv1 << " *iterv2 = " << *iterv2 << endl;
    }
}

Ouptut:

*iterv1 = 1 *iterv2 = 1
*iterv1 = 1 *iterv2 = 2

代码段2:

vector<int> v;
v.push_back(1);
v.push_back(2);
for(int i=0;i<2;++i){
    for(int j=0;j<2;++j){
        cout << "v[i] = " << v[i] << " v[j] = " << v[j] << endl;
    }
}

输出:

v[i] = 1 v[j] = 1
v[i] = 1 v[j] = 2
v[i] = 2 v[j] = 1
v[i] = 2 v[j] = 2

我本来期望的(数字输出。显然有一些我不理解迭代器。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:3)

好吧,你不要将iterv2重置为内循环中的开头。您应该将初始化代码放在它所属的位置:在for-initialization。

只需在for-initialization中移动赋值:

vector<int>::const_iterator iterv1;
vector<int>::const_iterator iterv2;
for(iterv1=v.begin();iterv1!=v.end();++iterv1){
    for(iterv2=v.begin();iterv2!=v.end();++iterv2){
        cout << "*iterv1 = " << *iterv1 << " *iterv2 = " << *iterv2 << endl;
    }
}

如果之后不需要变量,甚至可以将变量放在循环中:

for(vector<int>::const_iterator iterv1=v.begin();iterv1!=v.end();++iterv1){
    for(vector<int>::const_iterator iterv2=v.begin();iterv2!=v.end();++iterv2){
        cout << "*iterv1 = " << *iterv1 << " *iterv2 = " << *iterv2 << endl;
    }
}

顺便说一句,如果你使用C ++ 11,你可以使用以下两个新的语言特性:auto关键字可以用来省略类型规范(不要混淆动态类型,因为这仍然是静态类型,这意味着编译器计算出类型并以与显式写入类型相同的方式编译它:

for(auto iterv1=v.begin();iterv1!=v.end();++iterv1){
    for(auto iterv2=v.begin();iterv2!=v.end();++iterv2){
        cout << "*iterv1 = " << *iterv1 << " *iterv2 = " << *iterv2 << endl;
    }
}

基于范围的for循环的新语法(类似于Java)将使写入和(更重要的)阅读更容易:

for(auto iterv1 : v){
    for(auto iterv2 : v){
        cout << "*iterv1 = " << *iterv1 << " *iterv2 = " << *iterv2 << endl;
    }
}

P.S。如果在基于索引的版本中将初始化移到循环之外,则会发生同样的错误:

// WRONG - SAME ERROR
int i = 0;
int j = 0;
for(;i<2;++i){
    for(;j<2;++j){
        cout << "v[i] = " << v[i] << " v[j] = " << v[j] << endl;
    }
}

PP.S。在运算符周围添加空格,使您的代码更具可读性。大多数代码风格指南要求。