我目前正在学习C++,之前学过递增运算。我知道你可以使用"++x"来使递增在之前进行,而使用"x++"则是在之后进行。
不过,我真的不知道何时应该使用其中的任何一个...到目前为止,我从来没有真正使用过"++x",并且事情一直都很顺利 - 那么,在什么情况下应该使用它呢?
例如:在for循环中,何时最好使用"++x"?
另外,有人能够解释一下不同的递增(或递减)方式吗?我会非常感激。
我目前正在学习C++,之前学过递增运算。我知道你可以使用"++x"来使递增在之前进行,而使用"x++"则是在之后进行。
不过,我真的不知道何时应该使用其中的任何一个...到目前为止,我从来没有真正使用过"++x",并且事情一直都很顺利 - 那么,在什么情况下应该使用它呢?
例如:在for循环中,何时最好使用"++x"?
另外,有人能够解释一下不同的递增(或递减)方式吗?我会非常感激。
这不是偏好的问题,而是逻辑的问题。
x++
会在处理当前语句之后增加变量 x 的值。
++x
会在处理当前语句之前增加变量 x 的值。
因此,只需根据您编写的逻辑来决定。
x += ++i
将会增加 i 的值并将 i+1 加到 x 中。
x += i++
将会将 i 加到 x 中,然后再增加 i 的值。
Scott Meyers建议您在逻辑不需要后缀表达式的情况下,应该优先考虑前缀表达式。
《More Effective C++》第6条——对我来说这已经足够权威了。
对于那些没有拥有这本书的人,在这里摘录相关引用。 在第32页:
从您作为C程序员的日子起,您可能会想起增量运算符的前缀形式有时被称为“递增和获取”,而后缀形式则通常被称为“获取和递增”。 这两个短语很重要,因为它们几乎可以充当正式的规范……
在第34页上:
如果你是一个关注效率的人,你可能在第一次看到后缀递增函数时就开始出汗了。 那个函数必须为其返回值创建临时对象,而上面的实现还创建了一个显式的临时对象,必须构造和销毁。 前缀递增函数没有这样的临时变量……
++x
和x++
之间的任何性能差异都会对结果产生影响,那么更重要的是你应该使用一款完全且正确优化两个版本的编译器,而不论上下文环境如何。用“由于我只有这把旧钉子锤,所以只能以43.7度的角度将钉子钉进去”来为建造房屋辩护是一个荒谬的论据。使用更好的工具是正确的选择。 - Andrew Henle从cppreference获取,当增加迭代器时:
如果您不打算使用旧值,则应优先选择前置递增 运算符(++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 }
显然,它比前缀自增要低效。
前缀自增不会产生临时对象。如果你的对象创建开销很大,则这可能会产生重大影响。
我希望提醒您,在使用前/后增量时,如果语义不重要,则生成的代码通常是相同的。
例如:
pre.cpp:
#include <iostream>
int main()
{
int i = 13;
i++;
for (; i < 42; i++)
{
std::cout << i << std::endl;
}
}
post.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"
std::map :: iterator
这样的东西的差异是什么?当然,在那里,这两个运算符是不同的,但我很好奇如果结果没有被使用,编译器是否会将后缀优化为前缀。我认为它不允许这样做--因为后缀版本可能包含副作用。 - seh在我看来,需要记住的最重要的一点是,x++ 需要返回实际增量发生之前的值--因此,它必须制作一个对象的临时副本(前缀增量)。这比 ++x 更不有效率,++x 可以原地递增并返回。
另外值得一提的是,大多数编译器在可能的情况下都能够优化掉这种不必要的操作,例如以下两个选项将导致相同的代码:
for (int i(0);i<10;++i)
for (int i(0);i<10;i++)
int m=0; for (int i(0);i<10;++i) m++;
和int m=0; for (int i(0);i<10;++i) ++m;
之间的m
有什么区别吗? - Isin Altinkaya我同意@BeowulfOF的观点,不过为了更清晰明确,我总是建议将语句分开,这样逻辑就会非常清楚,例如:
i++;
x += i;
或者
x += i;
i++;
如果 count{5};
如果你使用 ++count,它将在语句之前被处理。
total = --count +6;
总数将等于10。
如果您使用count ++,则该语句之后将进行处理。
total = count-- +6;
总计将等于11
++,--操作符的后缀形式遵循先使用再修改的规则,
前缀形式(++x,--x)遵循先修改再使用的规则。
当使用cout级联多个值时,使用<<运算符进行计算(如果有),但打印是从左到右进行的。例如(如果val最初为10)
cout<< ++val<<" "<< val++<<" "<< val;
12 10 10
在Turbo C++中,如果在一个表达式中有多个++或(以任何形式出现),那么首先计算所有前缀形式,然后计算表达式,最后计算后缀形式。例如:
int a=10,b;
b=a++ + ++a + ++a + a;
cout<<b<<a<<endl;
48 13
45 13
想再强调一下,++x比x++更快,尤其是当x是任意类型的对象时,所以除非出于逻辑原因,应该使用++x。
您要求一个例子:
这个(order
是一个std::vector)将会在i == order.size()-1
时,在访问order[i].size()
时崩溃:
while(i++ < order.size() && order[i].size() > currLvl);
这段代码不会在 order[i].size()
处崩溃,因为 i
会被递增、检查并退出循环:
while(++i < order.size() && order[i].size() > currLvl);
x++
可能看起来很学究(因为它确实是 :)),但它实际上是一个右值,其值为增量前的x
,而++x
是一个左值,其值为增量后的x
。这两个表达式都不能保证何时实际的增量值被存回x
中,只能保证在下一个顺序点之前发生。“在处理当前语句之后”并不严格准确,因为某些表达式具有顺序点,而某些语句则是复合语句。 - CB Bailey