【问题标题】:postfix and prefix increment operator in a for loop [duplicate]for循环中的后缀和前缀增量运算符[重复]
【发布时间】:2010-08-22 12:04:01
【问题描述】:

可能重复:
Difference between i++ and ++i in a loop?

谁能解释一下它们之间的区别:

for(unsigned col = 0; col < n; ++col, num_to_fill >>= 1U)
{

    for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2))
    {
        std::fill_n(&output[col][row], num_to_fill, 1);
    }
}

for(unsigned col = 0; col < n; col++, num_to_fill >>= 1U)
{

    for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2))
    {
        std::fill_n(&output[col][row], num_to_fill, 1);
    }
}

col=0 时,在 ex.1 中 Output[col][row] 将是 output[1][row] 并且在 ex.2 Output[col][row] 中将是 output[0][row] 。我说的对吗?

问题 2:使用 &gt;&gt;= 1U 代替 /= 2 会有什么不同吗?

【问题讨论】:

  • 如果我没记错的话,在这种情况下它没有任何区别。将变量用作R-Value 时确实会有所不同,如下所示:a = b++;a = ++b;
  • 格雷格,这个问题的答案大多不正确。他们回答什么是后增量和预增量,不是它们如何在循环中工作 - 实际上,其中许多具有误导性,因为它们应用它确实会产生影响,因为它们在循环中使用了误导性语法( int i = 0; foreach(randomOtherThing in randomOtherThings)...)
  • 好的。第二个问题呢?
  • @Stephen:这不是重复的问题。问题是这个问题以前被问过。如果他只有第二个问题,那么它就不会重复。
  • @0A0D 然而,给 OP 一个指向那个问题的链接,其中 wrong 答案被标记为正确的答案,是否足以提高他的理解?我认为 SO 是关于学习和帮助他人学习的。很可能有人可能会被链接的问题误导,认为 in the loop 之前或之后递增确实会影响循环内计数器的值。声称这是该特定问题的重复并不鼓励学习,它只是表明 SO 用户有时过于迂腐。

标签: c++ loops


【解决方案1】:

它对循环内的col 的值没有任何影响——假设col 是一个原始值。如果col 是一个类,则前缀和后缀“++”运算符可能会被重载以执行两种不同的操作,尽管我认为这是不好的做法。考虑以下示例:

#include <iostream>

using namespace std;

int main() {
    for(int i = 0; i < 10; i++) {
        cout << i << endl;
    }

    cout << endl;

    for(int i = 0; i < 10; ++i) {
        cout << i << endl;
    }

}

这两个都只打印出 0 到 9,尽管您在一个中预先递增,而在另一个中进行后递增。 i 的增量发生在每次循环运行结束时,无论您使用的是前增量还是后增量。我相信预递增更有效,因为 - 我可能在这里错了 - 编译器不需要使用临时变量1.,但这只有在你循环 for很长一段时间(当然还有'More computing sins are committed in the name of efficiency than for any other single reason'。)

关于问题2:

问题 2:会使用 >>= 1U 而不是 =/2 有什么不同吗?

不太可能。如果编译器未进行优化,位移会更快,但您的编译器可能会将其优化为位移。

作为旁注,我通常发现做unsigned variableName(即删除int)是不好的做法——尽管C++ 会在任何缺少的地方插入int,但它对我来说不太可读。

1.:cmets 中的 Stephen(一个 不同 Stephen ;))指出 - “预增量对于标准库容器迭代器来说更有效,但它不是原始类型不同,因为复制整数比复制更大的迭代器(特别是 std::set 和 std::map 迭代器)便宜。"

【讨论】:

  • 这很全面。
  • 预增量对于标准库容器迭代器来说更有效,但对于原始类型来说没有什么不同,因为复制一个整数比复制一个更大的迭代器便宜(特别是 std::set 和 std::映射迭代器)。 p.s.我不是产生这个答案的“斯蒂芬”
  • @Stephen 谢谢你,其他斯蒂芬。我将包括你的答案。然后当然是归功于“斯蒂芬”:p。
  • 我认为乘法会导致与溢出相关的问题,而
  • 使用现代编译器,您无需担心所有这些“更高效”的东西,优化器可能比您更聪明。在任何情况下,如果您尝试优化效率 - 进行配置以首先确保您需要优化,其次您正在使事情变得更好。编写可读代码而不是“最佳”代码,你以后会感谢自己的。
【解决方案2】:

unsigned 没有区别。但是,重载operator++ 的类会有所不同,因为它会调用不同的重载(通常,后缀运算符会创建类的副本,这意味着它可能会更慢)。

使用 >>= 1U 代替 /=2 会有什么不同吗?

可能不会。其语义对于无符号是相同的,编译器通常会平等对待它们,如果速度更快,可以将它们转换为另一种。

【讨论】:

  • 不知道为什么代码编写者使用它。
  • 它可以更好地描述整体操作。例如,如果被除(或移位)的变量是某种位向量,其中算术除法是一个没有意义的概念,但移位是有意义的。
猜你喜欢
  • 2014-08-11
  • 2011-03-12
  • 1970-01-01
  • 2021-04-22
  • 2014-05-15
  • 2012-10-03
  • 1970-01-01
  • 2013-12-06
相关资源
最近更新 更多