简体   繁体   English

后增量和前增量的概念?

[英]Post-increment and Pre-increment concept?

I don't understand the concept of postfix and prefix increment or decrement.我不明白后缀和前缀递增或递减的概念。 Can anyone give a better explanation?谁能给出更好的解释?

All four answers so far are incorrect , in that they assert a specific order of events.到目前为止,所有四个答案都是不正确的,因为它们断言了特定的事件顺序。

Believing that "urban legend" has led many a novice (and professional) astray, to wit, the endless stream of questions about Undefined Behavior in expressions.相信“都市传说”让许多新手(和专业人士)误入歧途,也就是说,关于表达式中未定义行为的问题层出不穷。

So.所以。

For the built-in C++ prefix operator,对于内置的 C++ 前缀运算符,

++x

increments x and produces (as the expression's result) x as an lvalue, while递增x并产生(作为表达式的结果) x作为左值,而

x++

increments x and produces (as the expression's result) the original value of x .递增x并产生(作为表达式的结果) x的原始值。

In particular, for x++ there is no no time ordering implied for the increment and production of original value of x .特别是, x++没有隐含的原始值的增加和生产没有时间排序x The compiler is free to emit machine code that produces the original value of x , eg it might be present in some register, and that delays the increment until the end of the expression (next sequence point).编译器可以自由地发出产生x原始值的机器代码,例如它可能存在于某个寄存器中,并且将增量延迟到表达式结束(下一个序列点)。

Folks who incorrectly believe the increment must come first, and they are many, often conclude from that certain expressions must have well defined effect, when they actually have Undefined Behavior.错误地认为增量必须首先出现的人很多,他们经常从某些表达式必须具有明确定义的效果中得出结论,而实际上它们具有未定义的行为。

int i, x;

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

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

'Post' means after - that is, the increment is done after the variable is read. 'Post' 表示之后 - 即在读取变量后完成增量。 'Pre' means before - so the variable value is incremented first, then used in the expression. 'Pre' 表示之前 - 所以变量值首先增加,然后在表达式中使用。

The difference between the postfix increment, x++ , and the prefix increment, ++x , is precisely in how the two operators evaluate their operands.后缀增量x++前缀增量++x之间的区别恰恰在于两个运算符如何评估它们的操作数。 The postfix increment conceptually copies the operand in memory, increments the original operand and finally yields the value of the copy.后缀递增在概念上复制内存中的操作数,递增原始操作数并最终产生副本的值。 I think this is best illustrated by implementing the operator in code:我认为这最好通过在代码中实现运算符来说明:

int operator ++ (int& n)  // postfix increment
{
    int tmp = n;
    n = n + 1;
    return tmp;
}

The above code will not compile because you can't re-define operators for primitive types.上面的代码将无法编译,因为您无法为原始类型重新定义运算符。 The compiler also can't tell here we're defining a postfix operator rather than prefix , but let's pretend this is correct and valid C++.编译器也无法判断我们在这里定义的是后缀运算符而不是prefix ,但让我们假设这是正确且有效的 C++。 You can see that the postfix operator indeed acts on its operand, but it returns the old value prior to the increment, so the result of the expression x++ is the value prior to the increment.可以看到后缀运算符确实作用于它的操作数,但它返回的是增量之前的旧值,因此表达式x++的结果是增量之前的值。 x , however, is incremented.但是, x增加。

The prefix increment increments its operand as well, but it yields the value of the operand after the increment:前缀增量也增加其操作数,但它在增量产生操作数的值:

int& operator ++ (int& n)
{
    n = n + 1;
    return n;
}

This means that the expression ++x evaluates to the value of x after the increment.这意味着表达式++x在增量计算为x的值。

It's easy to think that the expression ++x is therefore equivalent to the assignmnet (x=x+1) .因此很容易认为表达式++x等价于assignmnet (x=x+1) This is not precisely so, however, because an increment is an operation that can mean different things in different contexts.然而,事实并非如此,因为增量是一种在不同上下文中可能意味着不同事物的操作。 In the case of a simple primitive integer, indeed ++x is substitutable for (x=x+1) .在一个简单的原始整数的情况下,确实++x可以替代(x=x+1) But in the case of a class-type, such as an iterator of a linked list, a prefix increment of the iterator most definitely does not mean "adding one to the object".但是在类类型的情况下,例如链表的迭代器,迭代器的前缀增量绝对不意味着“向对象添加一个”。

No one has answered the question: Why is this concept confusing?没有人回答这个问题:为什么这个概念令人困惑?

As an undergrad Computer Science major it took me awhile to understand this because of the way I read the code.作为一名本科计算机科学专业,由于我阅读代码的方式,我花了一段时间才理解这一点。

The following is not correct!以下说法不正确!


x = y++ x = y++

X is equal to y post increment. X 等于 y增量。 Which would logically seem to mean X is equal to the value of Y after the increment operation is done.这在逻辑上似乎意味着完成增量操作X 等于 Y 的值。 Post meaning after .发表的意思。

or或者

x = ++y x = ++y
X is equal to y pre -increment. X 等于 y增量。 Which would logically seem to mean X is equal to the value of Y before the increment operation is done.这在逻辑上似乎意味着完成增量操作之前X 等于 Y 的值。 Pre meaning before .意。


The way it works is actually the opposite.它的工作方式实际上是相反的。 This concept is confusing because the language is misleading.这个概念令人困惑,因为语言具有误导性。 In this case we cannot use the words to define the behavior.在这种情况下,我们不能用词来定义行为。
x=++y is actually read as X is equal to the value of Y after the increment. x=++y 实际上读作 X 等于增量的 Y 值。
x=y++ is actually read as X is equal to the value of Y before the increment. x=y++ 实际上读作 X 等于增量的 Y 值。

The words pre and post are backwards with respect to semantics of English . pre 和 post 这两个词在英语的语义上倒退的 They only mean where the ++ is in relation Y. Nothing more.它们仅表示 ++ 与 Y 的关系。仅此而已。

Personally, if I had the choice I would switch the meanings of ++y and y++.就我个人而言,如果我可以选择,我会转换 ++y 和 y++ 的含义。 This is just an example of a idiom that I had to learn.这只是我必须学习的一个习语的例子。

If there is a method to this madness I'd like to know in simple terms.如果有一种方法可以解决这种疯狂,我想用简单的术语来了解。

Thanks for reading.谢谢阅读。

It's pretty simple.这很简单。 Both will increment the value of a variable.两者都会增加变量的值。 The following two lines are equal:以下两行是相等的:

x++;
++x;

The difference is if you are using the value of a variable being incremented:不同之处在于,如果您使用的是递增的变量的值:

x = y++;
x = ++y;

Here, both lines increment the value of y by one.这里,两行都将 y 的值加一。 However, the first one assigns the value of y before the increment to x, and the second one assigns the value of y after the increment to x.但是,第一个将增量之前的 y 值赋给 x,第二个将增量之后的 y 值赋给 x。

So there's only a difference when the increment is also being used as an expression.所以只有当增量也被用作表达式时才有区别。 The post-increment increments after returning the value.后增量在返回值后递增。 The pre-increment increments before. pre-increment 增加之前。

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

Post increment implies the value i is incremented after it has been assigned to k .后增量意味着值i在分配给k后增加。 However, pre increment implies the value j is incremented before it is assigned to l .但是, pre increment 意味着值 j 在分配给l之前增加。

The same applies for decrement.这同样适用于递减。

Post-increment:后增量:

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.

Pre-increment:预增量:

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.

Since we now have inline javascript snippets I might as well add an interactive example of pre and pos increment.由于我们现在有内联 javascript 片段,我不妨添加一个 pre 和 pos 增量的交互式示例。 It's not C++ but the concept stays the same.它不是 C++,但概念保持不变。

 let A = 1; let B = 1; console.log('A++ === 2', A++ === 2); console.log('++B === 2', ++B === 2);

Post increment (a++)后增量(a++)

If int b = a++,then this means如果 int b = a++,那么这意味着

int b = a;

a = a+1;

Here we add 1 to the value.在这里,我们将值加 1。 The value is returned before the increment is made,在进行增量之前返回该值,

For eg a = 1;例如 a = 1; b = a++; b = a++;

Then b=1 and a=2然后 b=1 和 a=2

Pre-increment (++a)预增量(++a)

If int b = ++a;如果 int b = ++a; then this means那么这意味着

a=a+1;

int b=a ;

Pre-increment: This will add 1 to the main value.预增量:这会将主值加 1。 The value will be returned after the increment is made, For a = 1;递增后返回值, For a = 1; b = ++a; b = ++a; Then b=2 and a=2.然后 b=2 和 a=2。

Post-increment(x++) increament happens at next statement: 在下一条语句中发生后增量(x ++)中断:

Example for Post-increament: 后消音的示例:

  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

    }

Pre_increament(++x) increament happens at current statement 当前语句中发生Pre_increament(++ x)的increament

Example for Pre-increament: 预吸气的示例:

  static void Main(string[] args)
    {
        int x = 0;
        int y= Method(++x);//x=1
        Console.WriteLine(x);// now also  x=1
        Console.WriteLine(y);//y is 1
    }
    public static int  Method(int x)
    {

       //inside x=1;
        return x; //returns 1

    }
#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
}

Post and Pre Increment with Pointers带指针的后和前增量

Already good answers here, but as usual there seems to be some general lack of clarity in simply remembering which way round these work.这里已经有了很好的答案,但像往常一样,简单地记住这些工作的方式似乎普遍缺乏清晰度。 I suppose this arises because semantically resolving the nomenclature is not entirely straightforward.我想这是因为从语义上解析命名法并不完全简单。 For example, you may be aware that "pre-" means "before".例如,您可能知道“pre-”的意思是“之前”。 But does the pre-increment ++i return the value of i before the increment, or does it increment i before returning a value?但是预自增++i是在自增前返回i的值,还是在返回值前先自增i?

I find it much easier to visually follow the expression through from left to right:我发现从左到右直观地跟随表达式要容易得多:

        ++                    i 
-------------------------------------------------->
    Increment i   Then supply the value of i


             i                      ++
-------------------------------------------------->
    Supply the value of i    Then increment i

Of course, as Alf points out in the accepted answer, this may not reflect when the 'real i' is updated, but it is a convenient way of thinking about what gets supplied to the expression.当然,正如 Alf 在接受的答案中指出的那样,这可能不会反映“真实 i”何时更新,但这是一种思考提供给表达式的内容的便捷方式。

From the C99 standard (C++ should be the same, barring strange overloading)来自 C99 标准(C++ 应该是相同的,除非出现奇怪的重载)

6.5.2.4 Postfix increment and decrement operators 6.5.2.4 后缀自增和自减运算符

Constraints约束

1 The operand of the postfix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue. 1 后缀自增或自减运算符的操作数应具有合格或不合格的实数或指针类型,并且应是可修改的左值。

Semantics语义

2 The result of the postfix ++ operator is the value of the operand. 2 后缀++运算符的结果是操作数的值。 After the result is obtained, the value of the operand is incremented.得到结果后,操作数的值递增。 (That is, the value 1 of the appropriate type is added to it.) See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. (也就是说,将适当类型的值 1 添加到其中。)有关约束、类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论。 The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point.更新操作数的存储值的副作用将发生在前一个和下一个序列点之间。

3 The postfix -- operator is analogous to the postfix ++ operator, except that the value of the operand is decremented (that is, the value 1 of the appropriate type is subtracted from it). 3 后缀 -- 运算符类似于后缀 ++ 运算符,不同之处在于操作数的值是递减的(即从中减去相应类型的值 1)。

6.5.3.1 Prefix increment and decrement operators 6.5.3.1 前缀自增和自减运算符

Constraints约束

1 The operand of the prefix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue. 1 前缀自增或自减运算符的操作数应具有限定或非限定实型或指针类型,并且应为可修改的左值。

Semantics语义

2 The value of the operand of the prefix ++ operator is incremented. 2 前缀++运算符的操作数的值递增。 The result is the new value of the operand after incrementation.结果是递增后操作数的新值。 The expression ++E is equivalent to (E+=1).表达式++E 等价于(E+=1)。 See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers.有关约束、类型、副作用和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论。

3 The prefix -- operator is analogous to the prefix ++ operator, except that the value of the operand is decremented. 3 前缀 -- 运算符类似于前缀 ++ 运算符,只是操作数的值是递减的。

The pre increment is before increment value ++ eg:预增量在增量值++之前,例如:

(++v) or 1 + v

The post increment is after increment the value ++ eg:后增量是在增量值++例如:

(rmv++) or rmv + 1

Program:程序:

int rmv = 10, vivek = 10;
cout << "rmv++ = " << rmv++ << endl; // the value is 10
cout << "++vivek = " << ++vivek; // the value is 11

You should also be aware that the behaviour of postincrement/decrement operators is different in C/C++ and Java.您还应该知道,后递增/递减运算符的行为在 C/C++ 和 Java 中是不同的。

Given给定的

  int a=1;

in C/C++ the expression在 C/C++ 中的表达式

 a++ + a++ + a++

evaluates to 3, while in Java it evaluates to 6. Guess why...计算结果为 3,而在 Java 中计算结果为 6。猜猜为什么...

This example is even more confusing:这个例子更令人困惑:

cout << a++ + a++ + a++ << "<->" << a++ + a++ ;

prints 9<->2 !!打印 9<->2 !! This is because the above expression is equivalent to:这是因为上面的表达式等价于:

operator<<( 
  operator<<( 
    operator<<( cout, a++ + a++ ), 
    "<->"
  ), 
  a++ + a++ + a++ 
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM