我不理解后缀和前缀增量或减量的概念。谁能给出更好的解释呢?
答案 0 :(得分:103)
到目前为止,所有四个答案都不正确,因为它们声明了特定的事件顺序。
相信“都市传奇”已经导致许多新手(和专业人士)误入歧途,即表达中关于未定义行为的无穷无尽的问题。
所以
对于内置C ++前缀运算符,
++x
增加x
并生成表达式结果x
作为左值,而
x++
递增x
并生成x
的原始值作为表达式结果。
特别是,x++
对于x
的原始值的增量和生成,没有没有时间排序。编译器可以自由地发出产生x
原始值的机器代码,例如它可能存在于某个寄存器中,并将增量延迟到表达式结束(下一个序列点)。
错误地认为增量的人必须首先出现,并且他们很多,经常得出结论,当某些表达式实际上具有未定义的行为时,它们必须具有明确定义的效果。
答案 1 :(得分:26)
int i, x;
i = 2;
x = ++i;
// now i = 3, x = 3
i = 2;
x = i++;
// now i = 3, x = 2
'Post'表示之后 - 也就是说,在读取变量之后完成增量。 'Pre'表示之前 - 因此变量值首先递增,然后在表达式中使用。
答案 2 :(得分:17)
没有人回答这个问题: 为什么这个概念令人困惑?
作为一名本科计算机科学专业,我花了一些时间来理解这一点,因为我阅读代码的方式。
以下内容不正确!
x = y ++
X等于y post 增量。这在逻辑上似乎意味着X等于增强操作完成后<的值。 发布意味着之后。
或
x = ++ y
X等于y pre - 增量。从逻辑上看,这似乎意味着X在增量操作完成之前等于Y 的值。 预意味着之前。
它的工作方式实际上恰恰相反。这个概念令人困惑,因为这种语言具有误导性。在这种情况下,我们不能使用这些词来定义行为 实际上读取x = ++ y,因为X等于<<>>增量之后的值 x = y ++实际上是读取的,因为X等于增量之前的的值。
关于英语语义,前后单词后退。它们只表示++与Y相关的位置。仅此而已。
就个人而言,如果我有选择,我会改变++ y和y ++的含义。这只是我必须学习的成语的一个例子。
如果有一种解决这种疯狂的方法,我想简单地说一下。
感谢阅读。
答案 3 :(得分:13)
postfix 增量,x++
和前缀增量++x
之间的差异正好在如何两位运营商评估他们的操作数。后缀增量在概念上将操作数复制到内存中,递增原始操作数并最终生成副本的值。我认为通过在代码中实现运算符可以最好地说明这一点:
int operator ++ (int& n) // postfix increment
{
int tmp = n;
n = n + 1;
return tmp;
}
上述代码无法编译,因为您无法为原始类型重新定义运算符。编译器也无法告诉我们这里我们定义的是 postfix 运算符而不是前缀,但让我们假装这是正确且有效的C ++。您可以看到后缀运算符确实作用于其操作数,但它在递增之前返回旧值,因此表达式x++
的结果是递增之前的值。 x
但是, 递增。
前缀增量也会增加其操作数,但是在增量之后它会产生操作数的值:
int& operator ++ (int& n)
{
n = n + 1;
return n;
}
这意味着表达式++x
在增量之后计算为x
的值。
很容易认为表达式++x
因此等同于assignmnet (x=x+1)
。然而,这并非如此,因为增量是一种在不同情境中可能意味着不同事物的操作。在简单的原始整数的情况下,++x
确实可以替代(x=x+1)
。但是对于类类型的情况,例如链表的迭代器,迭代器的前缀增量绝对不是“向对象添加一个”。
答案 4 :(得分:6)
这很简单。两者都会增加变量的值。以下两行是相同的:
x++;
++x;
不同之处在于,如果您使用的是增量变量的值:
x = y++;
x = ++y;
这里,两行都将y的值递增1。但是,第一个在增量之前将y的值赋给x,第二个在增量之后将y的值赋给x。
因此,当增量也被用作表达式时,只有区别。返回值后的后增量递增。之前的增量前递增。
答案 5 :(得分:4)
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
之前递增。
同样适用于减量。
答案 6 :(得分:1)
发布增量(a ++)
如果 int b = a ++,则表示
int b = a;
a = a+1;
在这里,我们将值加1。值在增加之前返回,
例如a = 1; b = a ++;
然后b = 1和a = 2
预递增(++ a)
如果int b = ++ a;那么这意味着
a=a+1;
int b=a ;
预增量:这会将1加到主值。进行增量后,将返回该值,如果a = 1; b = ++ a; 然后b = 2和a = 2。
答案 7 :(得分:1)
后递增:
from patsy import dmatrices
预递增:
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.
答案 8 :(得分:0)
由于我们现在有了内联JavaScript代码段,因此我不妨添加一个交互式的pre和pos增量示例。它不是C ++,但概念保持不变。
curl_setopt_array
答案 9 :(得分:0)
在下一条语句中发生后递增(x ++)破坏:
后消音的示例:
df <- structure(list(licence = c(NA, 1L, NA, 0L), age.6.17 = c(1L,
0L, 0L, 1L)), class = "data.frame", row.names = c(NA, -4L))
Pre_increament(++ x)的不激怒发生在当前语句中
不含乳香的示例
static void Main(string[] args)
{
int x = 0;
int y= Method(x++);//x=0
Console.WriteLine(x);// now x=1
Console.WriteLine(y);// but y=0;
}
public static int Method(int x)
{
//when called value of x=0;
return x;//returns 0
}
答案 10 :(得分:0)
#include<stdio.h>
void main(){
char arr[] ="abcd";
char *p=arr,*q=arr;
char k,temp;
temp = *p++; /* here first it assigns value present in address which
is hold by p and then p points to next address.*/
k = ++*q;/*here increments the value present in address which is
hold by q and assigns to k and also stores the incremented value in the same
address location. that why *q will get 'h'.*/
printf("k is %c\n",k); //output: k is h
printf("temp is %c\n",temp);//output: temp is g
printf("*p is %c\n",*p);//output: *p is e
printf("*q is %c",*q);//output: *q is h
}
使用指针进行后和前增量
答案 11 :(得分:-1)
从C99标准(C ++应该是相同的,除非奇怪的重载)
6.5.2.4后缀增量和减量运算符
<强>约束强>
1后缀增量的操作数 或减少运营商应具备的 合格或不合格的真实或 指针类型,应该是可修改的 左值。
<强>语义强>
2后缀++的结果 operator是操作数的值。 获得结果后, 操作数的值递增。 (也就是说,值1 适当的类型被添加到它。)见 添加剂操作者的讨论 和复合赋值 关于约束,类型和的信息 转换和的影响 对指针的操作。旁边 更新存储值的效果 操作数应发生在 上一个和下一个序列点。
3后缀 - 运算符是类似的 到postfix ++运算符,除了 操作数的值是 递减(即,1的值) 减去适当的类型 从它)。
6.5.3.1前缀增量和减量运算符
<强>约束强>
1前缀增量的操作数 或减少运营商应具备的 合格或不合格的真实或 指针类型,应该是可修改的 左值。
<强>语义强>
2的操作数的值 前缀++运算符递增。该 result是操作数的新值 增量后。表达方式 ++ E相当于(E + = 1)。参见附加运算符的讨论和 关于信息的复合分配 约束,类型,副作用和 转换和的影响 对指针的操作。
3前缀 - 运算符是类似的 到前缀++运算符,除了 操作数的值是 递减。
答案 12 :(得分:-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
答案 13 :(得分:-6)
您还应该知道,在C / C ++和Java中,后增量/减量运算符的行为是不同的。
给出
int a=1;
在C / C ++中的表达式
a++ + a++ + a++
评估为3,而在Java中评估为6.猜猜为什么......
这个例子更令人困惑:
cout << a++ + a++ + a++ << "<->" << a++ + a++ ;
打印9&lt; - &gt; 2 !!这是因为上面的表达式相当于:
operator<<(
operator<<(
operator<<( cout, a++ + a++ ),
"<->"
),
a++ + a++ + a++
)