预自增运算符在C语言中有什么用途?

What purpose does the pre-increment operator serve in C?

本文关键字:什么 语言 运算符      更新时间:2023-10-16

在C和它的许多衍生物中,i++增加i并求值为i加前的值,++i增加i并求值为i 加后的值。

我可以看到一个特定的自增操作符的原因;当时的许多处理器都有一个特殊的增量操作码,它比加法更快,概念上"增量"与"加法"是不同的概念,理论上把它们写成不同的方式可能会使代码更具可读性。

我不明白的是需要前置自增操作符。就不能这样写它的实际用途吗?

#This...
x = i++;
#becomes this:
x = i; 
++i;

是不是有我不知道的历史原因?在原始版本的C语言中,您是否无法"丢弃"操作符的返回值?

一个原因是它允许生成高效的代码,而无需在编译器中进行任何花哨的优化阶段,只要程序员知道他(或她)在做什么。例如,当将字符从一个缓冲区复制到另一个缓冲区时,您可以使用:

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等人认为的语法糖。

例如,你可以这样做

While (++i < threshold) [do something];

这…

While (i++ < threshold) [do something];

或其他上千种特定的实现,这些实现既使用该值,又在单个语句中增加该值,并得到预期的不同结果