2009-02-12 67 views
0
for (int i = 0 ; i < stlVector.size() ; i++) 
{ 
    if (i == 10) 
    { 
     stlVector.erase(stlVector.begin() + 5) 
    } 
} 

終止條件部分「stlVector.size()」是否考慮到「stlVector.erase(...)」 ?換句話說,stlVector.size()是否爲每個循環迭代刷新? 我現在無法測試,所以我在這裏發佈了一個問題。在VC++ 6中刷新'for循環'的終止條件嗎?

Thx提前!

最好的問候,

zhengtonic

+0

幾乎令人反感的評論! – claf 2009-02-14 10:32:18

+0

嗨Ismael你是對的,我可以運行調試器,但我在一個航班,我沒有一臺PC上的VC + +。下載東西的機會非常昂貴,我不知道我的酒店是否可以上網。想要了解這一點,而我有互聯網接入,所以我可以睡得很好。 – zhengtonic 2010-07-21 19:17:57

回答

5

只是要清楚,不要認爲它在循環刷新任何東西方面。每次檢查條件(每次循環開始時),都會在stlVector變量上調用size()方法,並返回該向量的當前大小。

erase()方法減小了向量的大小,所以下一次調用size()時,返回的值會更小。

4

是它!

stlVector.size() // is called for evey iteration 

因此,對於每一個循環中,您將有測試「我< stlVector.size()」重新評估!

4

是的,測試是針對每個循環執行的,帶有副作用。

for循環僅僅是一個很好的約定 - 一個for循環很容易分解爲一個while循環:

for (int i = 0 ; i < stlVector.size() ; i++) 
{ 
    if (i == 10) 
    { 
     stlVector.erase(stlVector.begin() + 5) 
    } 
} 

變爲:

int i = 0 ; 

while(i < stlVector.size()) 
{ 
    if (i == 10) 
    { 
     stlVector.erase(stlVector.begin() + 5) 
    } 
    i++; 
} 

- 亞當

+0

這裏值得一提的是有一個小範圍的區別 - ```int i```在```while```例子中的循環之後是可用的,然而它被限制在```中的循環範圍for ```例子。 – Riot 2013-07-03 01:42:40

0

是它減少了尺寸。更多的信息是here

2

是的,它確實,但不要這樣做!如果您想從矢量中移除元素,請在另一個循環內執行。在這種情況下,您正在刪除i索引後的元素:沒有任何東西可以保證stlVector [i + 5]元素存在。如果您從矢量中移除第i個元素,則您的計數中斷,因爲您可以跳過元素而不檢查它們。

這樣做的最安全的方法是存儲stlVector上要刪除另一個向量上的元素的引用,然後遍歷此stlVector.erase(auxVector [i])的輔助向量。

+0

其實,如果你再讀一遍:他並沒有擦掉i + 5:th元素。 我相信檢查「if(i == 10)」(與循環條件一起)基本上保證元素begin()+ 5存在,不是?此外,不是使用迭代器類優於輔助矢量解決方案,你建議? – Reunanen 2009-02-12 20:16:19

+0

你是對的元素檢查和迭代器的使用。我認爲這個例子只是「幻想代碼」,只是想指出一個常見的錯誤(使用一個索引來指向一個在循環內被修改的向量中的元素)。 – jfsantos 2009-02-12 22:46:46

1

此外,澄清一點,因爲你問是否這樣做「在VC++ 6」。

在每個版本的C,C++,C#和Java的每個循環中,都會重新評估「繼續條件」。

如果任何編譯器不生成這樣做的代碼,它會被破壞,並且必須被避免。

1

正如其他人所說,是的條件是每次通過循環重新評估。這就是爲什麼一個常見的性能優化是:

int saveSize = someExpensiveComputation(); 

for (int i = 0 ; i < saveSize ; i++) 
{ 
    foo(i); 
} 

在循環條件是不是

for (int i = 0 ; i < someExpensiveComputation(); i++) 
{ 
    foo(i); 
} 

凡昂貴的計算是不必要通過循環中完成每一次迭代在所有昂貴的計算。

2

我希望你提供的代碼只是「幻想代碼」(正如一位評論者所說的)來給出你想要做的事情類型的具體例子。

但是以防萬一它不是:你給將跳過第12要素(即元素最初在stlVector[11]),因爲檢查stlVector[10]當你刪除一個較早的元素,導致所有後面的元素循環分流向前移動一個位置,但在循環結束時仍然增加i。所以下一次迭代將會看到stlVector[11]這實際上是最初在stlVector[12]中的元素。爲了解決這個問題,在撥打erase()後需要撥打--i