我不了解后缀和前缀递增或递减的概念。谁能给出更好的解释?
我不了解后缀和前缀递增或递减的概念。谁能给出更好的解释?
Answers:
到目前为止,所有四个答案都是不正确的,因为它们断言了事件的特定顺序。
相信“城市传奇”已导致许多新手(和专业人士)误入歧途,涉及表达式中未定义行为的问题不断。
所以。
对于内置的C ++前缀运算符,
++x
递增x
并产生(作为表达式的结果)x
作为左值,而
x++
递增x
并产生(作为表达式的结果)的原始值x
。
特别x++
是因为没有时间顺序暗示的原始值的增加和产生x
。编译器可以自由发出机器代码,该机器代码生成的原始值x
,例如可能存在于某个寄存器中,并且将增量延迟到表达式的末尾(下一个序列点)。
人们错误地认为增量一定是第一位的,而且他们很多,他们常常得出这样的结论:某些表达式实际上具有未定义的行为时,必须具有定义明确的效果。
(i++ > 0) && someProperty(myArray[i])
做什么呢?就像i = 5一样,它将someProperty
使用myArray[5]
还是调用myArray[6]
?
&&
引入了一个序列点(C ++ 03§1.9/ 18)。在C ++ 11术语中,内置&&
函数的左手操作数表达式在右手操作数表达式之前排序(C ++ 11§5.14/ 2)。这意味着,如果在调用时,它与由i
值6
&&
和||
在提供短路评估(以及序列点)方面是独特的。三元选择运算符有点像这样,因为它保证不对未采取的选择进行评估。但是对于算术运算符,当您在同一表达式中修改并使用变量时,您只会得到未定义行为。我认为但不确定,所有其他运营商也是如此。无论如何,这是最好的假设,并且编写依赖于某些微妙的特殊情况(很少有程序员知道)的代码是不好的。;-)
int i, x;
i = 2;
x = ++i;
// now i = 3, x = 3
i = 2;
x = i++;
// now i = 3, x = 2
“发布”表示之后-即,在读取变量后完成增量。“ Pre”表示之前-因此变量值先增加,然后在表达式中使用。
后缀增量x++
和前缀增量之间的区别++x
恰好在于两个运算符如何评估其操作数。后缀增量在概念上将操作数复制到内存中,对原始操作数进行增量,最后产生副本的值。我认为最好通过在代码中实现运算符来说明这一点:
int operator ++ (int& n) // postfix increment
{
int tmp = n;
n = n + 1;
return tmp;
}
上面的代码无法编译,因为您无法为原始类型重新定义运算符。编译器在这里也不能告诉我们定义的是后缀运算符,而不是prefix,但让我们假设这是正确且有效的C ++。您可以看到后缀运算符确实作用于其操作数,但是它在递增之前返回了旧值,因此表达式的结果x++
是递增之前的值。x
但是,是递增的。
前缀增量也会递增其操作数,但在递增后会产生操作数的值:
int& operator ++ (int& n)
{
n = n + 1;
return n;
}
这意味着该表达式的++x
计算结果为x
after增量的。
容易想到该表达式++x
因此等同于assignmnet (x=x+1)
。但是,这并非完全如此,因为增量是一种在不同上下文中可能表示不同事物的操作。在简单的原始整数的情况下,确实++x
可以用代替(x=x+1)
。但是,在类类型的情况下(例如链表的迭代器),迭代器的前缀增量绝对绝对不意味着“向对象添加一个”。
没有人回答这个问题: 为什么这个概念令人困惑?
作为本科计算机科学专业的学生,由于我的阅读方式,我花了一些时间来理解它代码。
以下不正确!
x = y ++
X等于y后增量。从逻辑上看,这意味着增量操作完成后,X等于Y的值。在之后发表意思。
要么
x = ++ y
X等于y预递增。从逻辑上看,这意味着X等于增量操作完成之前的Y值。预意思之前。
它的工作方式实际上是相反的。这个概念令人困惑,因为该语言具有误导性。在这种情况下,我们不能使用单词来定义行为。
x = ++ y实际上是读取的,因为增量之后X等于Y的值。
实际上会读取x = y ++,因为X等于增量之前的Y值。
就英语的语义而言,“前”和“后”词是后退的。它们仅表示++在Y关系中的位置。仅此而已。
就个人而言,如果可以选择的话,我会切换++ y和y ++的含义。这只是我必须学习的一个成语的例子。
如果有办法解决这种疯狂问题,我想简单地说一下。
谢谢阅读。
++y
是pre递增,因为++
用作前缀;y++
是post递增,因为++
用作后缀(或“后缀”)。完全不违反英语。
很简单 两者都会增加变量的值。以下两行相等:
x++;
++x;
区别在于是否使用递增的变量的值:
x = y++;
x = ++y;
在此,两行都将y的值加1。但是,第一个将增量之前的y值分配给x,第二个将增量之后的y值分配给x。
因此,当增量也用作表达式时,只有一个区别。返回值后,后增量递增。预增量在之前递增。
x
?你有它。两条线不相等。我现在可以在讨论中添加任何内容吗?
x
是类类型的period,否则前两个语句具有相同的效果。
x++;
++x;
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
。
递减也是如此。
后增量:
int x, y, z;
x = 1;
y = x++; //this means: y is assigned the x value first, then increase the value of x by 1. Thus y is 1;
z = x; //the value of x in this line and the rest is 2 because it was increased by 1 in the above line. Thus z is 2.
预增:
int x, y, z;
x = 1;
y = ++x; //this means: increase the value of x by 1 first, then assign the value of x to y. The value of x in this line and the rest is 2. Thus y is 2.
z = x; //the value of x in this line is 2 as stated above. Thus z is 2.
从C99标准开始(C ++应该相同,除非出现奇怪的重载)
6.5.2.4 Postfix增减运算符
约束条件
1后缀递增或递减运算符的操作数应具有合格或不合格的实数或指针类型,并且应为可修改的左值。
语义学
2后缀++运算符的结果是操作数的值。获得结果后,操作数的值将递增。(即,将适当类型的值1添加到其中。)有关约束,类型和转换以及操作对指针的影响的信息,请参见加法运算符和复合赋值的讨论。更新操作数存储值的副作用将发生在上一个和下一个序列点之间。
3 postfix-运算符类似于postfix ++运算符,只是操作数的值减小(即从中减去适当类型的值1)。
6.5.3.1前缀递增和递减运算符
约束条件
1前缀递增或递减运算符的操作数应具有合格或不合格的实数或指针类型,并且应为可修改的左值。
语义学
2前缀++运算符的操作数的值增加。结果是递增后操作数的新值。表达式++ E等效于(E + = 1)。有关约束,类型,副作用和转换以及操作对指针的影响的信息,请参见加法运算符和复合赋值的讨论。
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中后递增/递减运算符的行为是不同的。
给定
int a=1;
在C / C ++中的表达式
a++ + a++ + a++
计算结果为3,而在Java中计算结果为6。
这个例子更加令人困惑:
cout << a++ + a++ + a++ << "<->" << a++ + a++ ;
打印9 <-> 2 !! 这是因为上面的表达式等效于:
operator<<(
operator<<(
operator<<( cout, a++ + a++ ),
"<->"
),
a++ + a++ + a++
)