在C及其许多衍生产品中,i++
增加i
并在i
递增之前评估++i
的值,并i
递增i
并在增加后评估#This...
x = i++;
#becomes this:
x = i;
++i;
的值。
我可以看到特定增量运算符的推理;当时许多处理器都有一个特殊的增量操作码,这个操作码比添加和概念上更快"增量"是一个不同的想法来自"添加,"理论上,如果使用不同的方式编写代码,可能会使代码更具可读性。
我不明白的是需要预增量运算符。没有任何实际用途可以这样写吗?
<img id="1234" src=".../blah.jpg"></img>
$( img ).click(function() {
// open (this) lightbox
// etc. etc.
});
是否有一个我不了解的历史原因,也许?如果你不能扔掉&#34; C的原始版本中运算符的返回值?
答案 0 :(得分:12)
一个原因是,如果程序员知道他(或她)正在做什么,它允许在编译器中没有任何花哨的优化阶段的情况下生成有效的代码。例如,将字符从一个缓冲区复制到另一个缓冲区时,可能有:
register char *ptr1;
register char *ptr2;
...
for ( ... ) {
*ptr1++ = *ptr2++; /* post-increment */
}
我曾经使用过的编译器(在专有小型机上)会为作业生成以下寄存器操作:
load $r1,*$a1++ // load $r1 from address in $a1 and increment $a1
store $r1,*$a2++ // store $r1 at address in $a2 and increment $a2
我忘记了实际的操作码。编译器不包含优化阶段,但它生成的代码非常紧凑,前提是您了解编译器和机器体系结构。它可以做到这一点,因为硬件架构具有地址寄存器和通用寄存器的预递减和后递增寻址模式。据我所知,没有预增量和后减量寻址模式,但没有这些模式你可以顺利完成。
我认为最初开发C的DEC小型机具有这样的寻址模式。我工作的机器不是由DEC制造的,但架构非常相似。
计划编译器的优化阶段。但是,它主要由系统程序员使用,当他们看到生成的代码有多好时,优化阶段的实现被悄然搁置。
C的设计的全部基本原理是允许创建简单且可移植的编译器,这些编译器将以最少(或没有)中间代码优化生成合理有效的代码。由于这个原因,递增和递减运算符以及复合赋值运算符在早期C编译器生成紧凑和高效代码中起到了重要作用。它们不仅仅是Niklaus Wirth等人提出的语法糖。
答案 1 :(得分:-2)
所以你可以,例如,这样做
While (++i < threshold) [do something];
这......
While (i++ < threshold) [do something];
或使用该值并在单个语句中递增它并获得预期的不同结果的其他任何一个特定实现