++i 或 i++在 for 循环中?

发布于 2024-10-03 21:42:00 字数 284 浏览 9 评论 0原文

可能的重复:
i++ 和 ++ 之间是否存在性能差异我在 C++ 中?

是否有一些程序员在普通 for 循环中编写 ++i 而不是编写 i++ 的原因?

Possible Duplicate:
Is there a performance difference between i++ and ++i in C++?

Is there a reason some programmers write ++i in a normal for loop instead of writing i++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

紫南 2024-10-10 21:42:00

由于其语义,++i 的效率稍微高一些:

++i;  // Fetch i, increment it, and return it
i++;  // Fetch i, copy it, increment i, return copy

对于 int 类索引,效率增益是最小的(如果有的话)。对于迭代器和其他较重的对象,避免复制可能是一个真正的胜利(特别是如果循环体不包含太多工作)。

作为一个例子,考虑以下循环,使用提供任意精度整数的理论 BigInteger 类(从而提供某种类似向量的内部结构):

std::vector<BigInteger> vec;
for (BigInteger i = 0; i < 99999999L; i++) {
  vec.push_back(i);
}

i++ 操作包括复制构造(即运算符 new、逐位复制)和销毁(操作符删除)对于一个循环,除了本质上再制作一份索引对象的副本之外,不会执行任何其他操作。本质上,通过简单地使用前缀增量(其中前缀就足够了),您已经使要完成的工作加倍(并且很可能增加了内存碎片)。

++i is slightly more efficient due to its semantics:

++i;  // Fetch i, increment it, and return it
i++;  // Fetch i, copy it, increment i, return copy

For int-like indices, the efficiency gain is minimal (if any). For iterators and other heavier-weight objects, avoiding that copy can be a real win (particularly if the loop body doesn't contain much work).

As an example, consider the following loop using a theoretical BigInteger class providing arbitrary precision integers (and thus some sort of vector-like internals):

std::vector<BigInteger> vec;
for (BigInteger i = 0; i < 99999999L; i++) {
  vec.push_back(i);
}

That i++ operation includes copy construction (i.e. operator new, digit-by-digit copy) and destruction (operator delete) for a loop that won't do anything more than essentially make one more copy of the index object. Essentially you've doubled the work to be done (and increased memory fragmentation most likely) by simply using the postfix increment where prefix would have been sufficient.

风筝在阴天搁浅。 2024-10-10 21:42:00

对于整数,前后自增没有区别。

如果i是一个非平凡类的对象,那么++i通常是首选,因为该对象被修改然后评估,而i++ 在评估后修改,因此需要制作副本。

For integers, there is no difference between pre- and post-increment.

If i is an object of a non-trivial class, then ++i is generally preferred, because the object is modified and then evaluated, whereas i++ modifies after evaluation, so requires a copy to be made.

羞稚 2024-10-10 21:42:00

++i 是预增量; i++ 是后增量。
后自增的缺点是它会产生额外的值;它在修改i时返回旧值的副本。因此,您应该尽可能避免它。

++i is a pre-increment; i++ is post-increment.
The downside of post-increment is that it generates an extra value; it returns a copy of the old value while modifying i. Thus, you should avoid it when possible.

冷情 2024-10-10 21:42:00

对于整数,这是首选。

如果循环变量是一个类/对象,它可能会产生影响(只有分析才能告诉您它是否有显着差异),因为后增量版本要求您创建该对象的副本并被丢弃。

如果创建该副本是一项昂贵的操作,那么每次执行循环时,您都会毫无理由地支付一次该费用。

如果您养成了在 for 循环中始终使用 ++i 的习惯,则无需停下来思考在这种特定情况下所做的事情是否有意义。你总是这样。

With integers, it's preference.

If the loop variable is a class/object, it can make a difference (only profiling can tell you if it's a significant difference), because the post-increment version requires that you create a copy of that object that gets discarded.

If creating that copy is an expensive operation, you're paying that expense once for every time you go through the loop, for no reason at all.

If you get into the habit of always using ++i in for loops, you don't need to stop and think about whether what you're doing in this particular situation makes sense. You just always are.

雨轻弹 2024-10-10 21:42:00

这是有原因的:性能。 i++ 会生成一个副本,如果立即丢弃它,那就太浪费了。当然,如果 i 是原语,编译器可以优化掉这个副本,但如果它不是原语,则不能。请参阅问题。

There is a reason for this: performance. i++ generates a copy, and that's a waste if you immediately discard it. Granted, the compiler can optimize away this copy if i is a primitive, but it can't if it isn't. See this question.

作死小能手 2024-10-10 21:42:00

任何编译器都不会在 ++i 和 i++ 之间以不同的方式运行,

for(int i=0; i<10; i++)

它们

for(int i=0;i<10;++i)

具有相同的成本。唯一不同的是 ++i 的返回值是 i+1,而 i++ 的返回值是 i。

因此,对于那些喜欢 ++i 的人来说,可能没有有效的理由,只是个人喜好。

编辑:这对于课程来说是错误的,正如其他所有帖子中所说的那样。如果 i 是一个类,i++ 将生成一个副本。

No compiler worth its weight in salt will run differently between

for(int i=0; i<10; i++)

and

for(int i=0;i<10;++i)

++i and i++ have the same cost. The only thing that differs is that the return value of ++i is i+1 whereas the return value of i++ is i.

So for those prefering ++i, there's probably no valid justification, just personal preference.

EDIT: This is wrong for classes, as said in about every other post. i++ will generate a copy if i is a class.

我一直都在从未离去 2024-10-10 21:42:00

正如其他人已经指出的那样,对于用户定义的类型,预增量通常比后增量更快。要理解为什么会这样,请查看实现两个运算符的典型代码模式:

Foo& operator++()
{
    some_member.increase();
    return *this;
}

Foo operator++(int dummy_parameter_indicating_postfix)
{
    Foo copy(*this);
    ++(*this);
    return copy;
}

如您所见,前缀版本只是修改对象并通过引用返回它。

另一方面,后缀版本必须在执行实际增量之前制作一个副本,然后将该副本按值复制回调用方。从源代码中可以明显看出,后缀版本必须做更多的工作,因为它包含对前缀版本的调用: ++(*this);

对于内置类型,它不会使只要您丢弃该值,即只要您不将 ++ii++ 嵌入较大的表达式(例如 a = ++)中,就没有任何区别ib = i++

As others have already noted, pre-increment is usually faster than post-increment for user-defined types. To understand why this is so, look at the typical code pattern to implement both operators:

Foo& operator++()
{
    some_member.increase();
    return *this;
}

Foo operator++(int dummy_parameter_indicating_postfix)
{
    Foo copy(*this);
    ++(*this);
    return copy;
}

As you can see, the prefix version simply modifies the object and returns it by reference.

The postfix version, on the other hand, must make a copy before the actual increment is performed, and then that copy is copied back to the caller by value. It is obvious from the source code that the postfix version must do more work, because it includes a call to the prefix version: ++(*this);

For built-in types, it does not make any difference as long as you discard the value, i.e. as long as you do not embed ++i or i++ in a larger expression such as a = ++i or b = i++.

酒中人 2024-10-10 21:42:00

当您使用 postfix 时,它会在内存中实例化更多对象。有人说for循环中使用后缀运算符比较好

when you use postfix it instantiates on more object in memory. Some people say that it is better to use suffix operator in for loop

烧了回忆取暖 2024-10-10 21:42:00

个人喜好。

通常。有时这很重要,但不要显得像个混蛋,但如果你必须问,它可能不会。

Personal preference.

Usually. Sometimes it matters but, not to seem like a jerk here, but if you have to ask, it probably doesn't.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文