在 C++ 中递增 - 何时使用 x++ 或 ++x?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1812990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Incrementing in C++ - When to use x++ or ++x?
提问by Jesse Emond
I'm currently learning C++ and I've learned about the incrementation a while ago. I know that you can use "++x" to make the incrementation before and "x++" to do it after.
我目前正在学习 C++,不久前我已经了解了增量。我知道您可以使用“++x”在之前进行增量,并在之后使用“x++”进行增量。
Still, I really don't know when to use either of the two... I've never really used "++x" and things always worked fine so far - so, when should I use it?
尽管如此,我真的不知道什么时候使用这两者中的任何一个......我从来没有真正使用过“++x”,到目前为止一切都很好 - 那么,我应该什么时候使用它?
Example: In a for loop, when is it preferable to use "++x"?
示例:在 for 循环中,何时最好使用“++x”?
Also, could someone explain exactly how the different incrementations (or decrementations) work? I would really appreciate it.
另外,有人可以确切地解释不同的增量(或减量)是如何工作的吗?我真的很感激。
回答by Oliver Friedrich
It's not a question of preference, but of logic.
这不是偏好问题,而是逻辑问题。
x++
increments the value of variable x afterprocessing the current statement.
x++
在处理当前语句后增加变量 x 的值。
++x
increments the value of variable x beforeprocessing the current statement.
++x
在处理当前语句之前增加变量 x 的值。
So just decide on the logic you write.
因此,只需决定您编写的逻辑即可。
x += ++i
will increment i and add i+1 to x.
x += i++
will add i to x, then increment i.
x += ++i
将增加 i 并将 i+1 添加到 x。
x += i++
将 i 添加到 x,然后增加 i。
回答by duffymo
Scott Meyerstells you to prefer prefix except on those occasions where logic would dictate that postfix is appropriate.
Scott Meyers告诉您更喜欢前缀,除非在逻辑上规定后缀是合适的情况下。
"More Effective C++" item #6- that's sufficient authority for me.
“更有效的 C++”第 6 项——这对我来说已经足够了。
For those who don't own the book, here are the pertinent quotes. From page 32:
对于那些没有这本书的人,这里是相关的引语。从第 32 页:
From your days as a C programmer, you may recall that the prefix form of the increment operator is sometimes called "increment and fetch", while the postfix form is often known as "fetch and increment." The two phrases are important to remember, because they all but act as formal specifications...
在您作为 C 程序员的日子里,您可能还记得增量运算符的前缀形式有时称为“增量和提取”,而后缀形式通常称为“提取和增量”。记住这两个短语很重要,因为它们几乎都充当正式规范......
And on page 34:
在第 34 页:
If you're the kind who worries about efficiency, you probably broke into a sweat when you first saw the postfix increment function. That function has to create a temporary object for its return value and the implementation above also creates an explicit temporary object that has to be constructed and destructed. The prefix increment function has no such temporaries...
如果您是那种担心效率的人,那么您可能在第一次看到后缀增量功能时会大汗淋漓。该函数必须为其返回值创建一个临时对象,上面的实现还创建了一个必须构造和销毁的显式临时对象。前缀增量函数没有这样的临时...
回答by Phillip Ngan
From cppreferencewhen incrementing iterators:
从cppreference增加迭代器时:
You should prefer pre-increment operator (++iter) to post-increment operator (iter++) if you are not going to use the old value. Post-increment is generally implemented as follows:
如果您不打算使用旧值,您应该更喜欢前增量运算符 (++iter) 而不是后增量运算符 (iter++)。后增量一般是这样实现的:
Iter operator++(int) {
Iter tmp(*this); // store the old value in a temporary object
++*this; // call pre-increment
return tmp; // return the old value }
Obviously, it's less efficient than pre-increment.
显然,它比预增量效率低。
Pre-increment does not generate the temporary object. This can make a significant difference if your object is expensive to create.
预增量不生成临时对象。如果您的对象创建成本很高,这可能会产生重大影响。
回答by chub
I just want to notice that the geneated code is offen the same if you use pre/post incrementation where the semantic (of pre/post) doesn't matter.
我只想注意,如果您使用前/后增量,其中语义(前/后)无关紧要,则生成的代码是一样的。
example:
例子:
pre.cpp:
预.cpp:
#include <iostream>
int main()
{
int i = 13;
i++;
for (; i < 42; i++)
{
std::cout << i << std::endl;
}
}
post.cpp:
后.cpp:
#include <iostream>
int main()
{
int i = 13;
++i;
for (; i < 42; ++i)
{
std::cout << i << std::endl;
}
}
_
_
$> g++ -S pre.cpp
$> g++ -S post.cpp
$> diff pre.s post.s
1c1
< .file "pre.cpp"
---
> .file "post.cpp"
回答by rmn
The most important thing to keep in mind, imo, is that x++ needs to return the value before the increment actually took place -- therefore, it has to make a temporary copy of the object (pre increment). This is less effecient than ++x, which is incremented in-place and returned.
要记住的最重要的事情,imo,是 x++ 需要在增量实际发生之前返回值——因此,它必须制作对象的临时副本(预增量)。这比 ++x 效率低,++x 就地递增并返回。
Another thing worth mentioning, though, is that most compilers will be able to optimize such unnecessary things away when possible, for instance both options will lead to same code here:
不过,另一件值得一提的事情是,大多数编译器都能够在可能的情况下优化掉这些不必要的东西,例如,这两个选项都会在这里生成相同的代码:
for (int i(0);i<10;++i)
for (int i(0);i<10;i++)
回答by Bids
I agree with @BeowulfOF, though for clarity I would always advocate splitting the statements so that the logic is absolutely clear, i.e.:
我同意@BeowulfOF,但为了清楚起见,我始终主张拆分语句,以便逻辑绝对清晰,即:
i++;
x += i;
or
或者
x += i;
i++;
So my answer is if you write clear code then this should rarely matter (and if it matters then your code is probably not clear enough).
所以我的回答是,如果你编写了清晰的代码,那么这应该很少有关系(如果它很重要,那么你的代码可能不够清晰)。
回答by Shailesh Kumar
Just wanted to re-emphasize that ++x is expected to be fasterthan x++, (especially if x is an object of some arbitrary type), so unless required for logical reasons, ++x should be used.
只是想再次强调 ++x 预计比 x++更快,(特别是如果 x 是某种任意类型的对象),因此除非出于逻辑原因需要,否则应该使用 ++x。
回答by Bj?rn Pollex
You explained the difference correctly. It just depends on if you want x to increment before every run through a loop, or after that. It depends on your program logic, what is appropriate.
您正确解释了差异。这仅取决于您是否希望 x 在每次循环之前或之后递增。这取决于你的程序逻辑,什么是合适的。
An important difference when dealing with STL-Iterators (which also implement these operators) is, that it++ creates a copy of the object the iterator points to, then increments, and then returns the copy. ++it on the other hand does the increment first and then returns a reference to the object the iterator now points to. This is mostly just relevant when every bit of performance counts or when you implement your own STL-iterator.
处理 STL 迭代器(也实现这些运算符)时的一个重要区别是,it++ 创建迭代器指向的对象的副本,然后递增,然后返回副本。++it 另一方面,先进行增量,然后返回对迭代器现在指向的对象的引用。当每一点性能都很重要或当您实现自己的 STL 迭代器时,这主要是相关的。
Edit: fixed the mixup of prefix and suffix notation
编辑:修复了前缀和后缀符号的混淆
回答by Sunil Dhillon
Postfix form of ++,-- operator follows the rule use-then-change,
Prefix form (++x,--x) follows the rule change-then-use.
++,-- 运算符的后缀形式遵循use-then-change规则,
前缀形式 (++x,--x) 遵循change-then-use规则。
Example 1:
示例 1:
When multiple values are cascaded with << using coutthen calculations(if any) take place from right-to-left but printing takes place from left-to-right e.g., (if valif initially 10)
当多个值与 << 使用cout级联时,计算(如果有)从右到左进行,但打印从左到右进行,例如,(如果val最初是 10)
cout<< ++val<<" "<< val++<<" "<< val;
will result into
将导致
12 10 10
Example 2:
示例 2:
In Turbo C++, if multiple occurrences of ++ or (in any form) are found in an expression, then firstly all prefix forms are computed then expression is evaluated and finally postfix forms are computed e.g.,
在 Turbo C++ 中,如果在表达式中多次出现 ++ 或(以任何形式),则首先计算所有前缀形式,然后计算表达式,最后计算后缀形式,例如,
int a=10,b;
b=a++ + ++a + ++a + a;
cout<<b<<a<<endl;
It's output in Turbo C++ will be
它在 Turbo C++ 中的输出将是
48 13
Whereas it's output in modern day compiler will be (because they follow the rules strictly)
而现代编译器的输出将是(因为它们严格遵守规则)
45 13
- Note: Multiple use of increment/decrement operators on same variable
in one expression is not recommended. The handling/results of such
expressions vary from compiler to compiler.
- 注意:不建议在一个表达式中对同一变量多次使用递增/递减运算符。此类
表达式的处理/结果因编译器而异。
回答by shkeyser
Understanding the language syntax is important when considering clarity of code. Consider copying a character string, for example with post-increment:
在考虑代码的清晰度时,理解语言语法很重要。考虑复制一个字符串,例如使用后增量:
char a[256] = "Hello world!";
char b[256];
int i = 0;
do {
b[i] = a[i];
} while (a[i++]);
We want the loop to execute through encountering the zero character (which tests false) at the end of the string. That requires testing the value pre-increment and also incrementing the index. But not necessarily in that order - a way to code this with the pre-increment would be:
我们希望循环通过遇到字符串末尾的零字符(测试为 false)来执行。这需要测试值预增量并增加索引。但不一定按该顺序 - 使用预增量对其进行编码的方法是:
int i = -1;
do {
++i;
b[i] = a[i];
} while (a[i]);
It is a matter of taste which is clearer and if the machine has a handfull of registers both should have identical execution time, even if a[i] is a function that is expensive or has side-effects. A significant difference might be the exit value of the index.
这是一个更清晰的品味问题,如果机器有少量寄存器,它们都应该具有相同的执行时间,即使 a[i] 是一个昂贵或有副作用的函数。一个显着的差异可能是指数的退出价值。