在编程语言中扩展预增量运算符

use*_*693 -1 c c# c++ java

例如,i++可以写成i=i+1.同样,如何++i以如上所示的形式书写i++

是否与以下相同:i++如果没有,请++i在表格中指定正确的方式,如上所示i++

gri*_*fin 6

你实际上有错误的方法:

i=i+1更接近++ii++

这样做的原因是它无论如何只会对周围的表达产生影响,例如:

j=++i给j j=(i+=1)和和的值相同j=(i=i+1)


尽管如此,这个故事还有很多:

1)为了在同一个基础上,让我们看一下预增量和后增量的区别:

j=i++ VS j=++i

第一个是后递增(返回值,"post"=后续递增),后一个是预递增(值为"pre"=递增之前,然后返回)

因此,(多语句)等价物将分别为: j=i; i=i+1;i=i+1; j=i;

这使得整个事情非常有趣(像(理论上的)表达式j=++i++(虽然在标准C中是非法的,因为你可能不会多次在单个语句中更改一个变量)

关于内存栅栏,它也很有趣,因为现代处理器可以这样做,称为乱序执行,这意味着,您可能按特定顺序编码,并且可能以完全不同的顺序执行(但是,有一些规则要这当然).编译器也可能会对您的代码进行重新排序,因此2个语句实际上最终会相同.

-

2)根据你的编译器,在编译/优化等之后表达式很可能是真的相同.

如果你有一个独立的表达i++;++i;编译器将最有可能转换为中间"ADD" ASM命令.您可以自己尝试使用大多数编译器,例如使用gcc -s来获取中间asm输出.

此外,多年来,编译器倾向于优化非常常见的构造

for (int i = 0; i < whatever; i++)

因为i++在这种情况下直接翻译会破坏额外的寄存器(并可能导致寄存器溢出)并导致不必要的指令(我们在这里谈论的东西,这是非常小的,除非循环运行万亿,否则它真的无关紧要使用单个asm指令等的时间)

-

3)回到原来的问题,整个问题是一个优先问题,因为2个语句可以表示为(这个时间比上面的解释更精确):

something = i++ => temp = i; i = i + 1; something = temp

something = ++i => i = i + 1; something = i

(这里你也可以看到为什么第一个变体理论上会导致更多的寄存器溢出和更多指令)

正如你在这里看到的那样,第一个表达式不能以我认为能满足你的问题的方式轻易改变,因为不可能使用优先符号来表达它,例如括号,或者,更容易理解,一个块).对于第二个,这很容易:

++i=> (++i)=> { i = i + 1; return i }(伪代码)

对于第一个将是

i++=> { return i; i = i + 1 }(伪代码)

如您所见,这不起作用.


希望我帮助你澄清你的问题,如果有什么需要澄清或我犯了错误,请随时指出.