后增量和预增量概念?

Saa*_*ood 66 c++ conceptual pre-increment post-increment

我不明白后缀和前缀增量或减量的概念.谁能给出更好的解释?

Che*_*Alf 109

到目前为止,所有四个答案都是不正确的,因为它们声明了特定的事件顺序.

相信"都市传奇"已经导致许多新手(和专业人士)误入歧途,即表达式中关于未定义行为的无穷无尽的问题.

所以.

对于内置的C++前缀运算符,

++x
Run Code Online (Sandbox Code Playgroud)

递增x并产生表达式结果x作为左值,而

x++
Run Code Online (Sandbox Code Playgroud)

递增x并生成表达式结果的原始值x.

特别是,x++没有任何时间订货隐含的原始值的增加和生产x.编译器可以自由地发出产生原始值的机器代码x,例如它可能存在于某个寄存器中,并将增量延迟到表达式的结尾(下一个序列点).

不正确地相信增量的人必须首先出现,并且他们很多,通常得出结论,当某些表达式实际上具有未定义的行为时,它们必须具有明确定义的效果.

  • @ Sa'me Smd:"lvalue"本质上是对具有存储空间的对象的引用.它的术语源于早期的C,其中一项任务需要左侧*左侧的左值. (7认同)
  • 什么是左值?和代码示例可以帮助更好一点. (6认同)
  • @AJMansfield:在C++ 03术语中,内置的"&&"引入了一个序列点(C++03§1.9/ 18).在C++ 11术语中,内置"&&"的左手操作数表达式在右手操作数表达式之前排序(C++11§5.14/ 2).这意味着如果进行了调用,则使用"i"值6进行调用. (3认同)
  • 你对机制你是正确的,但我认为你说其他人在概念层面是错误的.机制只是尝试实现这一概念的实用性.'post'_means_ after - 概念上,增量完成_afterwards_."序列"中的"序列"的整个概念意味着一个顺序,而UB来自于对序列点如何工作的误解,而不是来自"误解""前"和"后"的含义. (2认同)
  • 那么像`(i ++> 0)&& someProperty(myArray [i])`这样的表达式会怎样?就像i = 5一样,它会用`myArray [5]`或`myArray [6]`来调用`someProperty`吗? (2认同)
  • @Cheers 和 hth。- 另外一个问题,其他运营商呢?`x++ + y(x)`?还是与`++x`等效?如果我现在可以访问 C++ 环境,我可能只是尝试一下看看,但不幸的是,我不... (2认同)
  • @AJMansfield:`&&`和`||`在提供短路评估(以及序列点)方面是独一无二的.三元选择运算符有点像这样,因为它保证不评估未采用的选择.但是对于算术运算符,当您修改并使用同一表达式中的变量时,您只会获得未定义行为.我认为,但不确定,对所有其他运营商来说也是如此.无论如何,它是最好的假设,并且编写依赖于某些微妙特殊情况的代码并不好,如果有任何程序员知道的话.;-) (2认同)

sje*_*397 27

int i, x;

i = 2;
x = ++i;
// now i = 3, x = 3

i = 2;
x = i++; 
// now i = 3, x = 2
Run Code Online (Sandbox Code Playgroud)

'Post'表示之后 - 也就是说,在读取变量之后完成增量.'Pre'表示之前 - 所以变量值首先递增,然后在表达式中使用.

  • "preincrement"和"postincrement"中的"pre"和"post"是指操作符相对于操作数的位置.它们并不暗示在读取变量时增量发生之间的任何时间顺序. (3认同)
  • @James:我理解你的观点——但为了说明这一点,想象一下如果运算符的功能颠倒过来会有多混乱。我知道从技术上讲,没有时间顺序的含义,但绝对有一个概念映射后增量到“增量_after_use”的想法。 (2认同)

mat*_*ens 17

没有人回答这个问题: 为什么这个概念令人困惑?

作为一门本科计算机科学专业,由于我阅读代码的方式,我花了一些时间来理解这一点.

以下是不正确的!


x = y ++

X等于y post增量.这在逻辑上似乎意味着X 在增量操作完成等于Y的值.帖子的意思.

要么

x = ++ y
X等于y pre -increment.这在逻辑上似乎意味着X 在增量操作完成之前等于Y的值.含义之前.


它的工作方式实际上恰恰相反.这个概念令人困惑,因为这种语言具有误导性.在这种情况下,我们不能使用这些词来定义行为.
实际读取x = ++ y,因为X等于增量的Y值.
实际上读取x = y ++,因为X等于增量的Y值.

关于英语的语义,前后词是倒退的.它们只表示++与Y相关的位置.仅此而已.

就个人而言,如果我有选择,我会改变++ y和y ++的含义.这只是我必须学习的成语的一个例子.

如果有一种解决这种疯狂的方法,我想简单地说一下.

谢谢阅读.

  • "如果有一种解决这种疯狂的方法,我想简单地说一下." - 我认为它是这样的:PRE增量(y = ++ x):增量x首先THEN赋值给y.对于POST增量(y = x ++):分配给y THEN增量x.因此,将pre和post视为"x何时增加",而不是"x的x版本".这是我的"疯狂方法",它很有道理,IMO ;-) (13认同)

wil*_*ell 14

后缀增量x++前缀增量之间的差异++x恰恰在于两个运算符如何评估其操作数.后缀增量在概念上将操作数复制到内存中,递增原始操作数并最终生成副本的值.我认为最好通过在代码中实现运算符来说明:

int operator ++ (int& n)  // postfix increment
{
    int tmp = n;
    n = n + 1;
    return tmp;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将无法编译,因为您无法为原始类型重新定义运算符.编译器也不能告诉我们这里我们定义的是一个后缀运算符而不是前缀,但让我们假装这是正确有效的C++.您可以看到后缀运算符确实作用于其操作数,但它在递增之前返回旧值,因此表达式的结果x++是递增之前的值.x然而,递增.

前缀增量也会增加其操作数,但它会在增量产生操作数的值:

int& operator ++ (int& n)
{
    n = n + 1;
    return n;
}
Run Code Online (Sandbox Code Playgroud)

这意味着表达式++x计算增量x 的值.

很容易认为表达式++x等同于assignmnet (x=x+1).然而,这并非如此,因为增量是一种在不同环境中可能意味着不同事物的操作.在简单的原始整数的情况下,确实++x可以替代(x=x+1).但是在类类型的情况下,例如链表的迭代器,迭代器的前缀增量绝对不意味着"向对象添加一个".


Jon*_*ood 6

这很简单.两者都会增加变量的值.以下两行相同:

x++;
++x;
Run Code Online (Sandbox Code Playgroud)

不同之处在于,如果您使用的是增量变量的值:

x = y++;
x = ++y;
Run Code Online (Sandbox Code Playgroud)

这里,两条线都将y的值递增1.但是,第一个在增量之前将y的值赋给x,第二个在增量之后将y的值赋给x.

因此,当增量也被用作表达式时,只有区别.返回值后的后增量递增.之前的增量前递增.

  • 这两条线根本不相等.-1 (4认同)
  • wilhemtell:感谢您在讨论中不加任何补充.做得好. (4认同)
  • @wilhelmtell:如果重载是一致的(它们应该是),那么语句`x ++;`和`++ x;`的_effect_是相同的.是的,你调用不同的功能,但他们应该做同样的事情.这就是我想要达到的目标. (4认同)

Set*_*eth 5

int i = 1;
int j = 1;

int k = i++; // post increment
int l = ++j; // pre increment

std::cout << k; // prints 1
std::cout << l; // prints 2
Run Code Online (Sandbox Code Playgroud)

后递增意味着该值i在分配给 后递增k。然而,预递增意味着值 j 在分配给 之前先递增l

这同样适用于减量。