2016-04-29 35 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