2013-02-21 70 views
0

爲什麼下面的代碼片段給出不同的輸出? (見下面的輸出)嵌套循環中迭代器的行爲與C++中的隨機訪問

片段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 

我會期待相同的(數字輸出。很顯然,我不瞭解迭代器。有人可以幫忙嗎?

回答

3

那麼,你不會重置iterv2到內部循環的開始。您應該將初始化代碼放在它所屬的位置: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可用於省略類型說明(不要與動態類型混淆,因爲它仍然是靜態類型,意爲編譯器會計算出類型和comp爾斯它作爲你明確寫的類型相同):

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; 
    } 
} 

PS如果您將基於索引的版本的循環外部的初始化移動,則會發生同樣的錯誤:

// 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.在運算符周圍添加空格,使代碼更具可讀性。大多數代碼風格指南都要求這樣

+0

重新考慮你的PPS:這取決於文化。我在法國學習編程,而且我傾向於使用很多空間---普通的法語版式也使用比大多數空間更多的空間。 (即:之前的空間;,:,!或?)。當我在德國工作時,除必要時外,該公約實際上沒有空間;正常的德語版式使用很少的白色空間,通常甚至在文字之間省略。人們習慣於習慣於自己的習慣。 – 2013-02-21 23:05:50

+0

@JamesKanze我是德國人,如果你忽略了兩個單詞之間的空格,那麼它是有區別的,那麼它就是一個單詞。我認爲這是一種國際印刷規則,在(,。!?:等)之後放置一個空格。二元運算符(+ - * /等)前後的空格小於文本中的空格。但我強烈建議在他們周圍放一些空間。當然,這只是一個建議,但我知道的大多數代碼風格指南(例如Google)都需要它們。 – leemes 2013-02-22 10:00:53

+0

對於單詞的循環定義(即一個單詞是由空格開始的)。對於大多數「邏輯」定義,「qu'est-ce」是法語中的一個詞(儘管它看起來像三個),「Schadenfreude」是兩個詞(儘管它看起來像一個詞)。法國人在標點符號之前放置空間,而不僅僅是之後,例如「C'est你好嗎?」,而不是「C'est你好嗎?」。 (有些人,比如「;」,在非固定寬度的字體中獲得較窄的空間。)總的來說,與英語相比,德語的空間更少,法語的空間更多。編碼準則經常反映這一點。 – 2013-02-22 10:36:10