增加算子的目的更多?

时间:2013-03-02 12:33:49

标签: c++ syntax increment decrement

我想知道增量和减量运算符(++ - )是否比它的普通用途更有用,使代码更简单

也许:

i++;

比以下更有效:

i = i + 1;

9 个答案:

答案 0 :(得分:2)

在许多方面,运营商的主要目的是倒退 兼容性。在设计C ++时,一般规则 是做C做的,至少对于非班级类型;如果C没有 有++--,我怀疑C ++会有它们。

当然,这引出了一个问题。这是不可思议的 他们会在现代编译器中生成不同的代码,并且 委员会会介绍这是不可思议的 他们出于优化原因(尽管你从来没有 知道移动语义主要是为了介绍 优化原因)。但早在20世纪70年代中期,在 形成多年的C?人们普遍认为,当时 他们被介绍是因为他们对应机器 有关PDP-11的说明。另一方面,他们是 已经存在于B.C从B获得它们而B是一个 解释语言,所以没有问题 对应机器说明。我自己怀疑,哪个 适用于许多运营商(&,而不是and等) 他们是因为当时的发展而被引入的 很大程度上是关于teletypes(tty),以及你输出的每个角色 电传打字机发出很多令人不快的声音。所以越少 你需要的人物越多越好。

关于++ i;i += 1;i = i + 1;之间的选择: 没有必要重复i是一个明确的优势 (当然,这可能是一个或多或少复杂的表达),所以 你想要至少i += 1;。如果不是,Python停在那里 其他原因,而不是将作业视为陈述 而不是任意表达的副作用。随着结束 用C和C ++编程30年,我仍然觉得 在Python中编程时,++ i缺失,即使我 几乎把自己限制在C ++中以将赋值视为一种 声明(并且不要将++ i嵌入更复杂的内容中 表达式)。

答案 1 :(得分:1)

您提供的两个示例几乎肯定会编译为完全相同的机器代码。编译器非常聪明。理解编译器很少执行您实际编写的代码。它会扭曲并模塑它以提高性能。任何现代编译器都会知道i++;i = i + 1;是相同的(对于算术类型)并生成相同的输出。

然而,除了代码可读性之外,有充分的理由同时拥有这两者。从概念上讲,多次递增一个值并添加一个值是不同的操作 - 它们在这里只是相同,因为您要添加1.添加(例如x + 3)是单个操作,而执行{{1} }表示具有相同效果的三个单独操作。当然,智能编译器也会知道对于算术类型的对象++++++x,只需执行x就可以在恒定时间内增加N

但是,如果x + N属于具有重载xoperator+的类类型,则编译器无法做出此假设。这两个运营商可能完全不同。此外,将operator++实施为非恒定时间操作会给人留下错误的印象。

当我们处理迭代器时,让两者变得清晰的重要性。只有随机访问迭代器支持加法和减法。例如,标准原始指针是随机访问迭代器,因为您可以执行operator+并获取指向第5个对象的指针。但是,所有其他类型的迭代器(双向,前向,输入)都不支持这种情况 - 您只能递增它们(并递减双向迭代器)。要获得第5个元素以及双向迭代器,您需要执行ptr + 5五次。这是因为加法表示一个恒定的时间操作,但许多迭代器根本不能在恒定时间内遍历。强制多次递增表明它不是一个恒定的时间操作。

答案 2 :(得分:1)

效果取决于i的类型。

如果它是内置类型,那么优化器会“注意到”你的两个语句是相同的,并为两者发出相同的代码。

由于您使用了后增量(并忽略了分号),因此即使i是内置类型,这两个表达式也会有不同的值。 i++的值是旧值,i = i + 1的值是新值。所以,如果你写:

j = i++;
k = (i = i + 1);

然后两者现在不同了,两者都不会发出相同的代码。

由于后增量的后置条件与预增量相同,因此可以说后增量运算符的主要目的是它评估为不同的值。无论性能如何,它都会使语言更具表现力。

如果i具有带有重载运算符的类类型,那么它可能不那么简单。从理论上讲,两者可能甚至没有相同的结果,但假设“合理的”运算符i + 1返回类的新实例,然后进行移动分配(如果类型具有移动赋值,则在C ++ 11中)运算符)或复制分配(在C ++ 03中)到i。无法保证优化器能够像operator++那样有效,特别是如果在另一个翻译单元中关闭了运算符重载定义。

有些类型有operator++但有operator+,例如std::list<T>::iterator。这不是++存在的原因,因为它存在于C和C中没有++但没有+的类型。这是C ++利用它的一种方式。

答案 3 :(得分:0)

两者都会通过合适的编译器在优化代码中生成相同的机器指令。

如果编译器看到i++效率更高,那么它会将i=i+1转换为i++,反之亦然。无论你写什么,结果都是一样的。

我更喜欢++i。我从不i=i+1

答案 4 :(得分:0)

不,只是简单地打字,并使语法更简单。

当它们都被编译时,它们被缩减为相同的编译代码,并以相同的速度运行。

答案 5 :(得分:0)

  1. ++--运算符允许将其合并到其他语句而不是i=i+1。对于例如while (i++ < 10)允许while循环检查并在其后执行增量。使用i=i+1无法做到这一点。

  2. ++--运算符可以在其他类中重载以具有其他含义,或者通过其他操作执行增量和减量。有关详细信息,请参阅this page

答案 6 :(得分:0)

它们两者并不完全相同,但功能相同,优先级i++优先级(优先级更高)优于i=i+1

答案 7 :(得分:0)

尝试用更复杂的表达式替换++ i或i ++。你会对preincrement / postincrement功能有困难。您将需要将表达式拆分为多个表达式。这就像三元运算符。它是等效的,无论您输入代码的方式如何,编译器都可以执行一些优化,但是三元运算符和preincrement / postincrement语法只会节省代码的空间和可读性。

答案 8 :(得分:0)

i++i = i + 1之间的区别在于第一个表达式仅评估i一次,第二个表达式评估两次。考虑:

int& f() {
    static int value = 0;
    std::cout << "f() called\n";
    return value;

}

f()++;         // writes the message once
f() = f() + 1; // writes the message twice

如果f()在不同的调用中返回不同的引用,则这两个表达式具有截然不同的效果。当然不是说这是好的设计......