2016-04-29 72 views
2

我經常看到有人用指針迭代C風格的數組,而我發現它更易於使用索引。下面的例子說明了我想到的兩種方式。他們不會導致相同的拆卸...如何最好地迭代C數組?用指針或索引?

我的問題:使用「跑步者」而不是索引是否有利?順便說一句,「跑步者」技術還有另一個名字嗎?

是否依賴於基礎類型,例如:整數,字符或結構?

struct somestruct 
{ 
    float f; 
    int i; 
}; 

const unsigned int uiSize = 10000; 
somestruct * myarray = new somestruct[uiSize]; 
const somestruct * const pEnd = myarray + uiSize; 

// way 1: runner 
somestruct * pRunner = myarray; 
while(pRunner < pEnd) 
{ 
    pRunner->f += 5; 
    pRunner->i += 5; 
    ++pRunner; 
} 

// way 2: index 
unsigned int ui = 0; 
for (ui = 0; ui < uiSize; ++ui) 
{ 
    myarray[ui].f += 6; 
    myarray[ui].i += 4; 
} 
+3

這是C++不是C.而我認爲你的意思是「數組」而不是「矢量」。 – kaylum

+0

http://stackoverflow.com/a/11625741/187690 – AnT

+0

難道兩個人都不一樣嗎? –

回答

5

無論您使用積分索引還是指針都沒關係。但是,您提供的兩個示例都不遵循C(或C++)中的標準慣例。下面是做了改寫:

// way 1: runner 
for (somestruct * pRunner = myarray; pRunner != pEnd; ++pRunner) 

// way 2: index 
for (size_t ui = 0; ui < uiSize; ++ui) 

如果簡單地遍歷一個容器中的所有元素,我們總是用for循環,永不while循環,因爲它更簡潔,地道的(意思是每個人都能這樣,那麼每個人都可以快速閱讀)。

+1

「這沒關係」 - 雖然我同意你的觀點國際海事組織你應該指出,這兩種方式都不是**在語義上相同。 –

0
array[index] 

這與*(array + index)相同(在C中)。因此,除了增加index之外,還有一些*添加以獲得您要解除引用的指針array + index。直接增加指針時不需要額外的添加。我期望從任何體面的編譯器,這可以減少到單一加法(並緩存結果在一些寄存器或堆棧)每次迭代。從一個好的編譯器中,我希望它能識別這個模式並生成等於直接使用指針的代碼。

最後一句話:除非你在非常緊密循環利用這一點,你的編譯器是能產生像樣的代碼和你的分析器告訴你,這是你的性能瓶頸,喜歡這就是解決方案更容易理解和閱讀。

+0

「當您直接增加指針時,不需要他。」那麼,如果不是增加(按1個項目的大小),你認爲指針增量是多少? – Lundin

+0

@Lundin用指針遞增一個「事物」,用索引增加索引並將索引添加到基指針。因此,兩個補充與一個。 –

+0

使用這兩種方法之一,您可以在索引寄存器中加載基址。不同的是,對於數組方法,保存包含基址的索引寄存器,並將其添加一個值並將結果存儲在另一個索引寄存器中。使用指針方法,可以通過將加法結果存儲在同一個寄存器中來更改索引寄存器。在通用計算機上,爲什麼一個表單比另一個表單更快並不明顯。很可能沒有區別,或者至少沒有任何區別。 – Lundin