How Do Prefix (++X) and Postfix (X++) Operations Work

How do Prefix (++x) and Postfix (x++) operations work?

  • In C# the operands of + are evaulated in left-to-right order.
  • In C and C++ the order of evaluation for the operands of + is unspecifed.

For C# your examples work as follows:

 y = x + x++;
^ x is 1
^ x is increased to 2, but the postfix increment returns the old value (1)
y = 2

y = x++ + x;
^ x becomes 2, but postfix increment returns the old value (1)
^ x is now 2 here
y = 3

javascript Postfix and Prefix Increment in expression

It is evaluated left to right:

++x           : x is now 2
++x + : 2 +
++x + x : 2 + 2
++x + x++ : 2 + 2 and x is now 3
++x + x++ * : 2 + 2 *
++x + x++ * x : 2 + 2 * 3

Java: Prefix/postfix of increment/decrement operators?

i = 5;
System.out.println(++i); //6

This prints out "6" because it takes i, adds one to it, and returns the value: 5+1=6. This is prefixing, adding to the number before using it in the operation.

i = 6;
System.out.println(i++); //6 (i = 7, prints 6)

This prints out "6" because it takes i, stores a copy, adds 1 to the variable, and then returns the copy. So you get the value that i was, but also increment it at the same time. Therefore you print out the old value but it gets incremented. The beauty of a postfix increment.

Then when you print out i, it shows the real value of i because it had been incremented: 7.

How does postfix/prefix work when arrays are used

k = x[j] +++j;

is the same as

k = (x[j]++) +j;

Also, k = x[j] + ++j is undefined behavior, because the evaluation order of addition is not defined. Apart from the fact that the compiler is allowed to produce anything, both of these two snippets are equally sound interpretations of that line:

j++;
k = x[j] + j;

and

j++;
k = x[j-1] + j;

In general, avoid being "smart". If you're not 100% sure what you're doing, don't use ++ and -- in more complex statements. Do the increment or decrement on a separate line before or after. That will save you tons of trouble. For instance, can you without any doubt and without googling it say exactly what

while(*str++) { 
/* Do something */
}

means? IMHO it's clearer with

while(*str) { 
str++;
/* Do something */
}

Sure it costs a line, and reducing the number of lines can be a good thing, but in this case I think it's better to play it safe. In this particular case you can also make it clearer with parenthesis: *(str++) if you prefer, but I think you see my point.

I actually made an answer where this was the actual problem: https://stackoverflow.com/a/56522806/6699433

Unary-Operators postfix and prefix at the same time in java

The expression ++a++ consists of 3 pieces, highlighted by adding parenthesis: (++(a))++:

  • a variables reference
  • ++X Prefix Increment Operator (JLS §15.15.1)
  • X++ Postfix Increment Operator (JLS §15.14.2)

Javadoc says:

[X] must be a variable of a type that is convertible (§5.1.8) to a numeric type, or a compile-time error occurs. [...] The result of the [prefix/postfix] increment expression is not a variable, but a value.

So, in your expression ++a works, because a is a variable, but the result is a value, so (++a)++ doesn't work.


a+++++b doesn't work because it is parsed by the compiler as ((a++)++)+b, and as we just learned, X++ needs a variable.

It is parsed this way because the Java tokenizer will consume as many consecutive characters as possible to form a valid operator.

Now, if you add spaces or parenthesis, it can work, depending of what you intended that expression to do. The following are all the same:

(a++)+(++b)
a+++(++b)
a++ + ++b
a+++ ++b

The expression someObject.methodReturnsInteger().getClass() is known as "method chaining".

This works because . is a left-associative method invocation operator, and the value to the left of the . just has to be an object (or class for static method call, but let's skip that).

So the expression is parsed like this:

( someObject . methodReturnsInteger() ) . getClass()

The first . works because someObject is an object. The second . works because the result of the parenthesized expression is an object.

Method chaining is very common, and is very nice when using a builder pattern, e.g.

String s = new StringBuilder()
.append("Hello ")
.append(person.getFirstName())
.append(", please say hello to your father, ")
.append(person.getFather().getFirstName())
.append(".")
.toString();

POSTFIX and PREFIX increment/decrement precedence in JavaScript

Operator precedence is not the same thing as evaluation order.

Operator precedence tells you that

f() + g() * h()

is parsed as

f() + (g() * h())

(because * has higher precedence than +), but not which function is called first. That is controlled by evaluation order, which in JavaScript is always left-to-right.

Parentheses only override precedence (i.e. they affect how subexpressions are grouped), not order of evaluation:

(f() + g()) * h()

performs addition before multiplication, but in all cases f is called first and h last.

In your example

--a + a++

the relative precedence of prefix -- and postfix ++ doesn't matter because they're not attached to the same operand. Infix + has much lower precedence, so this expression parses as

(--a) + (a++)

As always, JS expressions are evaluated from left to right, so --a is done first.

If you had written

--a++

that would have been parsed as

--(a++)

(and not (--a)++) because postfix ++ has higher precedence, but the difference doesn't matter here because either version is an error: You can't increment/decrement the result of another increment/decrement operation.

However, in the operator precedence table you can see that all prefix operators have the same precedence, so we can show an alternative:

// ! has the same precedence as prefix ++
!a++

is valid code because it parses as !(a++) due to postfix ++ having higher precedence than !. If it didn't, it would be interpreted as (!a)++, which is an error.

When exactly does postfix unary operator happen?

At the line

x = x++ + x++;

Assuming x = 1, the first x++ returns "1" as the value, and then it increments x to 2. So basically, it's assigning the old value back to x.

The second x++ does the same; it returns the value of x, which is now 2, and only then increments its value to 3 - that value, is not used.

Your code is equivalent to:

tmp = x;
x = x + 1;

tmp2 = x;
x = x + 1; // not used

x = tmp + tmp2;

Links that may help you:

  • JSL - 15.14.2. Postfix Increment Operator ++
  • JLS - 15.15.1. Prefix Increment Operator ++
  • What is x after “x = x++”?

Increment and Decrement operators C#

Of course it's the opposite and it's also mentioned on MSDN:

++variable and variable++

  1. The first form is a prefix increment operation. The result of the operation is the value of the operand after it has been incremented.
  2. The second form is a postfix increment operation. The result of the operation is the value of the operand before it has been incremented.

I haven't read that book, but if it's mentioned there then it's a big mistake.

Prefix vs Postfix and table made of array?

The code doesn't seem to show any difference between postfix and prefix incrementation, anyway this is how it works:

POSTFIXED

int x = 10;
cout<< (x++); //output: 10
//now x is 11

PREFIXED

int x = 10;
cout<< (++x); //output: 11 (and x is already 11)

Basically, the postfixed increment will only show its effects after the operation where it is called. The prefixed increment will shot its effect immediatly, so that the incremented value is already used in the command where it is called.

If the increment is isolated, that is, not used inside an operation, it's basically the same thing:

for(int i = 0; i < 10; i++)   =   for(int i = 0; i < 10; ++i)

About your code, it just walks through all slots of the matrix in this order:

(0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2)

When j >= COLUMNS, it means that (0,0), (0,1), (0,2) were already visited, so you can go to the next row by doing i++ (i represents the row index) because all the columns of row i were already visited. Doing j = 0 resets the column to the beginning (j represents the column index).



Related Topics



Leave a reply



Submit