使用预增量或后增量运算符的情况

时间:2014-03-02 03:28:51

标签: c

阅读关于增量后和增量前的几个问题我需要尝试解释一个新的程序员,在什么情况下我实际上需要一个或另一个。在什么类型的场景中,应用后增量运算符以及应用预增量运算符更好。

这是为了教授案例研究,在特定代码中,人们需要应用其中一个,以获得某些任务的特定值。

4 个答案:

答案 0 :(得分:6)

简短的回答是:你永远不需要它们!

长期的答案是,早期微型计算机的指令集具有这样的特征。在读取存储器单元时,您可以在读取时对该单元进行后递增或预递减。这样的机器级功能激发了C的前身,从而它甚至可以用于更新的语言。

要理解这一点,必须记住当时RAM非常稀缺。当你的程序有64k可寻址RAM时,你会发现编写非常紧凑的代码是值得的。当时的机器架构通过提供极其强大的指令反映了这种需求。因此,您可以表达如下代码:

s = s + a[j]
j = j + 1

只有一条指令,假设sj在寄存器中。

因此,我们在C语言中具有语言特性,允许编译器不费力地生成有效的代码行:

register int s = 0;           // clr r5
s += a[j++];                  // mov j+, r6   move j to r6 and increment j after
                              // add r5,a[r6]

+=-=*=等快捷操作也是如此。

他们是

  1. 一种节省打字的方法
  2. 编译器的帮助,必须适合小型RAM,并且无法承受太多优化
  3. 例如,

    a[i] *= 5
    

    的缩写
    a[i] = a[i] * 5
    

    实际上为编译器保存了一些常见的子表达式分析。

    然而,所有这些语言功能,总是可以被等效的,可能更长的代码替换,而不使用它们。现代编译器应该将它们转换为有效的代码,就像更短的形式一样。

    所以底线并回答您的问题:您不需要查找需要来应用这些运算符的情况。这种情况根本不会退出。

答案 1 :(得分:3)

好吧,像Douglas Crockford这样的人反对使用这些操作符,因为它们可以通过隐藏未经训练的眼睛的最终结果而导致意外行为。

但是,从I'm using JSHint开始,让我们在这里分享一个例子:

http://jsfiddle.net/coma/EB72c/

var List = function(values) {

    this.index = 0;
    this.values = values;
};

List.prototype.next = function() {

    return this.values[++this.index];
};

List.prototype.prev = function() {

    return this.values[--this.index];
};

List.prototype.current = function() {

    return this.values[this.index];
};

List.prototype.prefix = function(prefixes) {

    var i;

    for (i = 0; i < this.values.length; i++) {

        this.values[i] = prefixes[i] + this.values[i];
    }
};

var animals = new List(['dog', 'cat', 'parrot']);

console.log('current', animals.current());
console.log('next', animals.next());
console.log('next', animals.next());
console.log('current', animals.current());
console.log('prev', animals.prev());
console.log('prev', animals.prev());

animals.prefix(['Snoopy the ', 'Gartfield the ', 'A ']);

console.log('current', animals.current());

答案 2 :(得分:2)

正如其他人所说,你永远不会“需要”++--运算符。然后,有许多语言的功能,你永远不会“需要”,但有助于清楚地表达代码的意图。你不需要一个返回值的赋值,或者一元否定,因为你总是可以写(0-x) ...哎呀,如果你把它推到极限你根本不需要C,因为你总是可以用汇编语言编写,你不需要汇编程序,因为你总是可以设置位来手工构建指令......

弗兰克海耶斯的歌,当我还是男孩的时候。离开我的草坪,你的小孩!)

所以这里真正的答案是使用增量和减量运算符,它们在风格上有意义 - 其中被操纵的值在某种意义上是一个计数器,并且在哪里有意义推进计数“顺便”。循环控制是一个显而易见的地方,人们希望看到增量/减量,并且它比其他选择更清楚地读取。并且有许多C语言几乎成为语言中的元语句,因为它实际上是使用的 - 例如strcpy()的经典单行版本 - 并且经验丰富的C程序员将一目了然地识别能够在需要时重建;其中许多人都利用增量/减量作为副作用。

不幸的是,“风格上有意义的地方”并不是一个简单的教学规则。与编码风格的任何其他方面一样,它确实需要来自于接触其他人的代码以及对编程语言的“母语人士”如何思考代码的理解。

我知道这不是一个非常令人满意的答案。但我认为不存在更好的。

答案 3 :(得分:0)

通常,它取决于您在特定情况下的需求。如果你 需要 操作的结果,那只是在递增/递减之前或之后是否需要变量值的问题。因此,使用能够使代码更清晰的理解。

在某些语言(如C ++)中,如果 不需要 值,则使用预增量/预减量运算符被认为是一种好习惯,因为帖子运算符需要在操作期间将先前的值存储在临时值中,因此它们需要更多指令(附加副本),并且可能导致复杂类型的性能问题。

我不是C专家,但我不认为你在C中使用它真的很重要,因为大型结构没有增量/减量运算符。