简体   繁体   English

为什么在语句中的其他地方没有使用值的情况下使用++ i而不是i ++?

[英]Why use ++i instead of i++ in cases where the value is not used anywhere else in the statement?

I'm well aware that in C++ 我很清楚在C ++中

int someValue = i++;
array[i++] = otherValue;

has different effect compared to 与...相比有不同的效果

int someValue = ++i;
array[++i] = otherValue;

but every once in a while I see statements with prefix increment in for-loops or just by their own: 但每隔一段时间我就会在for循环中看到带有前缀增量的语句,或者仅仅是它们自己的语句:

for( int i = 0; i < count; ++i ) {
     //do stuff
}

or 要么

for( int i = 0; i < count; ) {
    //do some stuff;
    if( condition ) {
        ++i;
    } else {
        i += 4;
    }
}

In the latter two cases the ++i looks like an attempt to produce smarty-looking code. 在后两种情况下, ++i看起来像是试图生成外观漂亮的代码。 Am I overseeing something? 我在监督什么吗? Is there a reason to use ++i instead of i++ in the latter two cases? 在后两种情况下,是否有理由使用++i而不是i++

Look at possible implementations of the two operators in own code: 在自己的代码中查看两个运算符的可能实现:

// Pre-increment
T*& operator ++() {
    // Perform increment operation.
    return *this;
}

// Post-increment
T operator ++(int) {
    T copy = *this;
    ++*this;
    return copy;
}

The postfix operator invokes the prefix operator to perform its own operation: by design and in principle the prefix version will always be faster than the postfix version, although the compiler can optimize this in many cases (and especially for builtin types). 后缀运算符调用前缀运算符来执行自己的操作:通过设计原则上前缀版本将始终比后缀版本更快,尽管编译器可以在许多情况下(尤其是对于内置类型)优化它。

The preference for the prefix operator is therefore natural; 因此,对前缀运算符的偏好是自然的; it's the other that needs explanation: why are so many people intrigued by the use of the prefix operator in situations where it doesn't matter – yet nobody is ever astonished by the use of the postfix operator. 另一个需要解释的是:为什么有这么多人在无关紧要的情况下使用前缀运算符引起了兴趣 - 但是没有人对使用后缀运算符感到惊讶。

If we ignore force of habit, '++i' is a simpler operation conceptually : It simply adds one to the value of i, and then uses it. 如果我们忽略习惯的力量,'++ i'在概念上是一个更简单的操作:它只是在i的值上加一,然后使用它。

i++ on the other hand, is "take the original value of i , store it as a temporary, add one to i , and then return the temporary". 另一方面, i++是“取i的原始值,将其存储为临时值,将其添加到i ,然后返回临时值”。 It requires us to keep the old value around even after i has been updated. 即使在i更新之后,它也要求我们保持旧的价值。

And as Konrad Rudolph showed, there can be performance costs to using i++ with user-defined types. 正如Konrad Rudolph所示,将i++与用户定义的类型一起使用可能会产生性能成本。

So the question is, why not always just default to ++i ? 所以问题是,为什么不总是默认为++i

If you have no reason to use `i++´, why do it? 如果你没有理由使用`i ++',为什么呢? Why would you default to the operation which is more complicated to reason about, and may be slower to execute? 为什么你会默认执行更复杂的操作,并且可能执行速度较慢?

As you noted - it does not matter to the result. 如你所知 - 结果并不重要。

There is a performance consideration for non-primitive types. 非原始类型存在性能考虑因素。

Also semantically using pre-increment is usually clearer in showing the intention of a test when the return value is used, so its better to use it habitually than post-increment to avoid accidentally testing the old value. 在使用返回值时,语义上使用预增量通常更清楚地显示测试的意图,因此最好习惯性地使用它而不是后增量以避免意外测试旧值。

There is one reason, and it has to do with overloaded operators. 有一个原因,它与重载运算符有关。 In an overloaded postincrement function, the function must remember the previous value of the object, increment it, and then return the previous value. 在重载的postincrement函数中,函数必须记住对象的先前值,递增它,然后返回先前的值。 In a preincrement function, the function can simply increment the object and then return a reference to itself (its new value). 在preincrement函数中,函数可以简单地递增对象,然后返回对自身的引用(它的新值)。

In the case of an integer, the above probably won't apply because the compiler knows the context in which the increment is being done, and will generate appropriate increment code in either case. 在整数的情况下,上述可能不适用,因为编译器知道正在进行增量的上下文,并且在任何一种情况下都将生成适当的增量代码。

Yes, for performance reasons. 是的,出于性能原因。 In case of post increment a copy of the variable i needs to be made before incrementing so that the old value can be returned (eventhough you are not using the return value). 在增加后的情况下,需要在递增之前创建变量i的副本,以便可以返回旧值(尽管您没有使用返回值)。 In case of pre-increment this copy is not required. 如果是预增量,则不需要此副本。

There is little reason to favour pre-increment over post-increment when you are talking about natural types like integers. 当你谈论像整数这样的自然类型时,几乎没有理由支持预增量超过后增量。 The compiler is typically able to generate the same code in both cases anyway, assuming you don't use the return value. 假设您不使用返回值,编译器通常能够在两种情况下生成相同的代码。 This is not true for more complex types, such as iterators. 对于更复杂的类型(例如迭代器),情况并非如此。

The C++ FAQ Lite has a nice discussion of i++ vs. ++i here: C ++ FAQ Lite在这里对i++++i了很好的讨论:

[13.15] Which is more efficient: i++ or ++i? [13.15]哪个更有效:i ++或++ i?

In particular, with respect to which form to use within a for loop, the FAQ expresses a preference for ++i . 特别是,关于在for循环中使用哪种形式,FAQ表示对++i的偏好。 Here's the text: 这是文字:

So if you're writing i++ as a statement rather than as part of a larger expression, why not just write ++i instead? 因此,如果您将i++作为一个语句而不是作为一个更大的表达式的一部分来编写,为什么不编写++i呢? You never lose anything, and you sometimes gain something. 你永远不会失去任何东西,你有时会获得一些东西 Old line C programmers are used to writing i++ instead of ++i . 旧的C语言程序员习惯于编写i++而不是++i Eg, they'll say, for (i = 0; i <10; i++) .... Since this uses i++ as a statement, not as a part of a larger expression, then you might want to use ++i instead. 例如,他们会说, for (i = 0; i <10; i++) ....因为它使用i++作为语句,而不是作为更大表达式的一部分,那么你可能想要使用++i代替。 For symmetry, I personally advocate that style even when it doesn't improve speed, eg, for intrinsic types and for class types with postfix operators that return void. 对于对称性,我个人提倡这种风格,即使它没有提高速度,例如,对于内部类型和具有返回void的后缀运算符的类类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM