如何最好地迭代C数组?用指针还是用索引?

如何最好地迭代C数组?用指针还是用索引?,c,performance,pointers,C,Performance,Pointers,我经常看到人们使用指针迭代C风格的数组,而我发现使用索引更具可读性。下面的例子说明了我思考的两种方式。它们不会导致相同的拆卸 我的问题是:使用“跑步者”而不是索引是否有利?顺便问一下,“跑步者”技术还有别的名字吗 它是否取决于基础类型,例如int、char或struct struct somestruct { float f; int i; }; const unsigned int uiSize = 10000; somestruct * myarray = new some

我经常看到人们使用指针迭代C风格的数组,而我发现使用索引更具可读性。下面的例子说明了我思考的两种方式。它们不会导致相同的拆卸

我的问题是:使用“跑步者”而不是索引是否有利?顺便问一下,“跑步者”技术还有别的名字吗

它是否取决于基础类型,例如int、char或struct

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;
}
struct somestruct
{
浮动f;
int i;
};
常量unsigned int uiSize=10000;
somestruct*myarray=newsomestruct[uiSize];
const somestruct*const pEnd=myarray+uiSize;
//方式一:跑步者
somestruct*pRunner=myarray;
while(pRunnerf+=5;
pRunner->i+=5;
++普朗纳;
}
//方式2:索引
无符号整数ui=0;
对于(ui=0;ui
无论是使用积分索引还是指针,这都无关紧要。但是,您提供的两个示例都没有遵循C(或C++)中的标准实践。这里有一个重写:

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

// way 2: index
for (size_t ui = 0; ui < uiSize; ++ui)
//方式1:跑步者
for(somestruct*pRunner=myarray;pRunner!=pEnd;++pRunner)
//方式2:索引
用于(大小\u t ui=0;ui
当简单地迭代容器的所有元素时,我们总是使用
进行
循环,而从不使用
进行
while
循环,因为它更简洁和惯用(这意味着每个人都这样做,所以每个人都可以快速阅读)

这与
*(数组+索引)
相同(在C中)。因此,除了增加
索引
,您还需要添加一些*以获得要取消引用的指针
数组+索引
。当您直接递增指针时,不需要额外添加

*)我希望任何一个好的编译器在每次迭代中都能将其简化为一次加法(并将结果缓存在某个寄存器或堆栈中)。从一个好的编译器中,我希望它能够识别这种模式,并生成与直接使用指针相同的代码


<强>最后的注释< /强>:除非你在一个非常紧凑的循环中使用C++,编译器不能生成正确的代码,而你的剖析器告诉你这是你的性能瓶颈,所以更喜欢更容易理解和阅读的解决方案。< /P>这是C++而不是C。我想你是说“数组”不是“向量”。不是两个都一样吗?好吧,是C++的。问题是一样的。@SouravGhosh No-array和vectors on不是一回事。C++具有这两种属性,它们的行为不同,“当你直接增加一个指针时,不需要HIS”。那么,如果不是加法(以1个项目为单位),那么你认为指针增量是什么?@ Lundin,指针增加一个“东西”,用索引增加索引,并将索引添加到基指针。因此,两个加法对一个加法。使用任何一种方法,都可以在索引寄存器中加载基址。不同之处在于,使用数组方法时,包含基址的索引寄存器会被保留,您可以使用值添加该基址,并将结果存储在不同的索引寄存器中。使用指针方法,可以通过将加法结果存储在同一寄存器中来更改索引寄存器。在普通计算机上,为什么一种形式比另一种形式更快,这并不明显。很可能没有区别,或者至少没有什么值得一提的。也就是说,编译器(希望)不会愚蠢到每次访问数组时都会从RAM中获取数组的基址。@Lundin当然这里的性能没有“真正的”区别(主要是由于智能编译器,我试图在回答的后半部分指出这一点)。不过,语义上存在差异。“没关系”——虽然我同意你的观点,但我认为你应该指出,两种方法在语义上并不等同。

array[index]