循环两个范围的更好方法是 - 将它们相乘并一次循环,或者分别在每个范围上循环?

时间:2010-08-12 09:34:54

标签: c++ c loops

我无法决定如何循环范围。这样:

for (int i = 0; i < max_i; i++) {
    for (int j = 0; j < max_j; j++) {
        // first way - two loops
    }
}

或者这样:

for (int k = 0; k < max_i*max_j; k++) {
    // second way - one loop
}

谢谢,Boda Cydo。

10 个答案:

答案 0 :(得分:7)

这取决于你将对指数做些什么。如果您分别使用两个值(例如,您正在迭代两个循环中的值的所有排列),则两个循环解决方案更加清晰。如果你不关心个别价值而只关心他们的产品,那么单循环策略会更好。

无论哪种方式,选择更清楚地表达您意图的策略。与维护代码的简单性的重要性相比,性能影响是微不足道的。

答案 1 :(得分:4)

第一循环至少有两个原因:

  1. 可以让读者明确循环的嵌套特性(取决于需要的内容)
  2. 如果第二种选择中的max_i * max_j溢出会怎样?
  3. 另外请探索循环索引变量是否应为'int'或'size_t'。 size_t始终保证为正

答案 2 :(得分:3)

max_i或/和max_j足够大时,您无法使用第二种变体。请注意,int是签名类型。如果sizeof(int)等于4个字节,那么如果循环的max_i=32768max_j=65536将被执行零次。

如果没有特殊要求,我更喜欢第一个变体,因为它更具可读性。

答案 3 :(得分:2)

取决于你在循环中做了什么。你需要指数i和j吗?那我更喜欢第一种解决方案。

答案 4 :(得分:2)

如果您决定采用第一种方式,那么一切都很好,因为您拥有ij的值。在第二种方式中,您必须手动获取ij的值:

for (int k = 0; k < max_i*max_j; k++) {
    i = k / max_j;
    j = k % max_j;
    ....
}

所以,在你的情况下,第一种方式肯定更好。

答案 5 :(得分:2)

显然,如果你有选择的话,你在循环过程中不需要i和j的精确值。

所以第二个选项更好,更易读(更少缩进)。你可以做一点优化,(以免在每次循环迭代时进行乘法):

int iKMax = max_i*max_j;
for (int k = 0; k < iKMax ; ++k)  
{
    // second way - one loop
}

并且总是在循环(++ k)中使用前缀运算符导致迭代的对象,它会节省一次该对象的复制。 (参见C ++编码标准:Herb Sutter和Andrei Alexandrescu的101规则,指南和最佳实践)

答案 6 :(得分:0)

这取决于。 如果您想要单独索引,那么您可以使用第一个。 如果你只想要单一索引,那么第二个。

两个循环的复杂性是相同的。

答案 7 :(得分:0)

如果使用2D数组,则第一个数组的可读性要高得多。在过去,使用1D模拟2d数组有点不同,但在这种情况下,第一个更易读。

答案 8 :(得分:0)

如果有疑问,请假设编译器会优于您。

对于Android 1.0这样的东西来说绝对不是这样,但大多数C / C ++编译器都相当不错。一个好的编译器应该能够优化简单的二维数组访问(例如将数组的所有值相加)到一个循环中。

答案 9 :(得分:0)

这是你可以做到的另一种方式:

for(int i = 0,j = 0; i&lt; max_i,j