后增和前增概念?
我不明白后缀和前缀增量或减量的概念。 任何人都可以提供更好的解释?
到目前为止,所有四个答案都是不正确的 ,因为他们断言了特定的事件顺序。
相信“都市传奇”导致许多新手(和专业人士)误入歧途,关于expression式中未定义行为的问题层出不穷。
所以。
对于内置的C ++前缀运算符,
++x
递增x
并产生expression式x
作为左值,while
x++
增加x
并产生x
的原始值作为expression式结果。
特别是,对于x++
, x++
的原始值的增加和产生并不意味着没有时间顺序 。 编译器可以自由发出产生x
的原始值的机器代码,例如它可能出现在某个寄存器中,并且延迟增量直到expression式结束(下一个序列点)。
那些错误地相信增量的人必须先来,而且他们很多,通常是由于某些expression式实际上有未定义的行为时必定有明确的效果。
int i, x; i = 2; x = ++i; // now i = 3, x = 3 i = 2; x = i++; // now i = 3, x = 2
之后的“Post”意味着在读取variables之后完成增量。 'Pre'意味着之前 – 所以variables值先增加,然后在expression式中使用。
后缀增量x++
和前缀增量++x
之间的区别恰恰在于两个运算符如何评估它们的操作数。 后缀增量从概念上将操作数复制到内存中,增加原始操作数并最终生成副本的值。 我认为这是通过在代码中实现运算符来最好地说明的:
int operator ++ (int& n) // postfix increment { int tmp = n; n = n + 1; return tmp; }
上面的代码不会编译,因为您不能重新定义运算符的基本types。 编译器在这里也不能告诉我们正在定义一个后缀运算符而不是前缀 ,但让我们假装这是正确和有效的C ++。 你可以看到,后缀运算符确实作用于它的操作数,但它在返回之前返回了旧值,所以expression式x++
的结果是增量之前的值。 然而, x
增加了。
前缀增量也会增加其操作数,但是会在增量后得到操作数的值:
int& operator ++ (int& n) { n = n + 1; return n; }
这意味着expression式++x
在递增后计算为x
的值。
很容易认为expression式++x
因此等价于assignmnet (x=x+1)
。 然而,这并不完全如此,因为增量是一种在不同情况下可能意味着不同事物的操作。 在一个简单的基本整数的情况下,实际上++x
是可替代的(x=x+1)
。 但是在types的情况下,比如链表的迭代器,迭代器的前缀增量绝对不意味着“向对象添加一个”。
没有人回答这个问题: 为什么这个概念混乱?
作为一名本科计算机科学专业,由于阅读代码的方式,我花了一段时间才明白这一点。
以下是不正确的!
x = y ++
X等于y增量。 这在逻辑上似乎意味着X等于增量操作完成后的Y值。 之后的意思。
要么
x = ++ y
X等于y 前的增量。 这在逻辑上似乎意味着X在增量操作完成之前等于Y的值。 之前的含义。
它的工作方式实际上是相反的。 这个概念很混乱,因为这个语言是误导性的。 在这种情况下,我们不能用这个词来定义行为。
x = ++ y实际上读取为X等于增量后 Y的值。
x = y ++实际上是读取的,因为X等于增量之前的Y的值。
前后的词语是相对于英语的语义而言的倒退 。 它们只意味着++与Y的关系。仅此而已。
就个人而言,如果我有select,我会切换++ y和y ++的含义。 这只是我必须学习的一个习惯用法的例子。
如果有这样一个疯狂的方法,我想简单地说,
谢谢阅读。
这很简单。 两者都会增加一个variables的值。 以下两行是相等的:
x++; ++x;
不同之处在于,如果您正在使用正在递增的variables的值:
x = y++; x = ++y;
在这里,两行将y的值加1。 但是,第一个将y的值赋值给x之前,第二个将y的值赋值给x。
所以当增量也被用作expression式时,只有一个区别。 返回后递增递增。 前增加前增加。
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
后增量意味着值i
在被赋值给k
之后递增。 然而,预增量意味着值j在分配给l
之前递增。
这同样适用于递减。
从C99标准(C ++应该是相同的,除非奇怪的重载)
6.5.2.4后缀增量和减量运算符
约束
1后缀增量或减量运算符的操作数应具有限定的或不合格的实数或指针types,并应为可修改的左值。
语义
2后缀++运算符的结果是操作数的值。 获得结果后,操作数的值递增。 (也就是说,将相应types的值1添加到其中。)有关约束,types和转换的信息以及操作对指针的影响,请参阅加法运算符和复合赋值的讨论。 更新操作数的存储值的副作用应发生在前一个序列点和下一个序列点之间。
3后缀运算符类似于后缀++运算符,只是操作数的值递减(即从中减去适当types的值1)。
6.5.3.1前缀增量和减量运算符
约束
1前缀增量或减量运算符的操作数应具有限定的或不合格的实数或指针types,并应为可修改的左值。
语义
2前缀++运算符的操作数的值递增。 结果是增量后操作数的新值。 expression式++ E相当于(E + = 1)。 有关约束,types,副作用和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论。
3前缀 – 运算符类似于前缀++运算符,只不过操作数的值是递减的。
前增量在增量值++
之前,例如:
(++v) or 1 + v
增量后的值是递增值++
例如:
(rmv++) or rmv + 1
程序:
int rmv = 10, vivek = 10; cout << "rmv++ = " << rmv++ << endl; // the value is 10 cout << "++vivek = " << ++vivek; // the value is 11
你还应该知道,C / C ++和Java中postincrement / decrement操作符的行为是不同的。
特定
int a=1;
在C / C ++中的expression
a++ + a++ + a++
评估为3,而在Java中评估为6.猜猜为什么…
这个例子更令人困惑:
cout << a++ + a++ + a++ << "<->" << a++ + a++ ;
打印9 < – > 2! 这是因为上述expression式相当于:
operator<<( operator<<( operator<<( cout, a++ + a++ ), "<->" ), a++ + a++ + a++ )