后增量和预增量概念?

时间:2010-12-15 00:36:18

标签: c++ conceptual post-increment pre-increment

我不理解后缀和前缀增量或减量的概念。谁能给出更好的解释呢?

14 个答案:

答案 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++ 
)