This question already has answers here:
What is the difference between prefix and postfix operators?
(13 answers)
Closed 12 months ago.
The community reviewed whether to reopen this question 12 months ago and left it closed:
Original close reason(s) were not resolved
I was working with my practicals and my tutor taught us the increment and decrement operators but I cannot understand a few things in code. The code is as follows :
#include < iostream >
using namespace std;
int main() {
int a = 10 , b = 100 , result_a , result_b ;
// Prefix Example
// Printing the value given by increment Operator on A
result_a = ++a;
cout << "Prefix Increment A : " << result_a << endl;
// Printing the value given by decrement Operator on B
result_b = --b;
cout << "Prefix Decrement B : " << result_b << endl;
cout << a << endl << b << endl;
// Postfix Example
// Printing the value given by increment Operator on A
result_a = a++;
cout << "Postfix Increment A : " << result_a << endl;
// Printing the value given by decrement Operator on B
result_b = b--;
cout << "Postfix Decrement B : " << result_b << endl;
cout << a << endl << b << endl;
cout << result_a << endl << result_b;
system("pause>0");
return 0;
}
And the output is as follows :
PS D:\Burhan\My coding projects\C++\WalletTerminal> if ( $? ) { g++
main.cpp -o main } ; if ( $? ) { .\main }
Prefix Increment A : 11
Prefix Decrement B : 99
11
99
Postfix Increment A : 11
Postfix Decrement B : 99
12
98
11
99
I don't understand why is the Postfix Increment A: 11 and Postfix Decrement B: 99 as my calculations say that it should be 12 and 98 which are the value of A and B. We are actually adding +1 to A and B but as far as I know, that happens after the line of code is executed but still, it doesn't work as intended. Can you please tell me how that works? I look on the internet but couldn't find any issues related to this.
You can look at it this way, when you use pre-increment or pre-decrement (++a, --b ) , what really happens is that for instance here
result_a = ++a;
What really happens is,( since ++ is a short-hand operator for incrementing)
a=a+1;
result_a=a;
Similarly for post-increment or post-decrement (a++,b--)
result_b = b--;
what really happens is
result_b=b;
b=b-1;
++a (Prefix) means firstly incrementing a and then using the value of a. a++ (Postfix) means firstly using the value of a and then incrementing a.
For example:
int a = 10;
std::cout << a++; // Will print out 10
// a == 11
int a = 10;
std::cout << ++a; // Will print out 11
// a == 11
Related
I'm just a beginner at C++ and I came across this instance.
#include <iostream>
using namespace std;
int main(){
int c = 3;
int d = c++;
if (c++ == 4 && d == 3)
cout << "1: " << c << " " << d << endl;
if (++c == 5 && d-- == 3)
cout << "2: " << c-- << " " << d << endl;
cout << "3: " << c << " " << d << endl;
}
So in this case, the output would be:
1: 5 3
3: 6 3
And what I understand from this is that the variables would still be updated even if they are being called for an increment in the if statement.
Now I came across this:
#include <iostream>
using namespace std:
int main(){
for (int i= 1; i <= 10; ++i){
cout << i ;
break
}
}
And even though its being incremented it's only returning 1. So I thought that maybe the 2nd time it goes through the loop (after removing the break of course) it would return 3, cause then it would have passed through ++i twice, but it's still 2. I don't understand. So my question is why would there be an instant increment in the if statement but there is none when ++i exists in the for loop ?
EDIT: just fixed a typo. I was supposed to type semicolon but put a comma instead :b
EDIT: added a more straightforward question as some are wondering what I am asking.
A for statement has 4 parts, they are not in the order they are executed.
for ( init-statement condition; iteration_expression) statement
Is defined as equivalent to
{
init_statement
while ( condition ) {
statement
iteration_expression ;
}
}
Except that
Names declared by the init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope (which is also the scope of statement).
continue in the statement will execute iteration_expression
Empty condition is equivalent to while(true)
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 years ago.
I understand the basic differences between prefix/postfix notation for decrement/increment operators in C++. However, there is something going on in the next example that stumps me.
The code I shared below prints the following.
5*4**3***4****2*****1
But I would have guessed it would print this.
5*4**4***3****2*****1
How is this happening? Is something going on with pushing/popping to/from the stack?
int var = 5;
cout << var-- << '*'; //prints 5 and then decrements to 4.
cout << var << "**"; //The value of var (now 4)
//is printed to the console.
//The next line prints 3***4****.
//I would have guessed it prints 4***3****.
cout << var-- << "***" << var-- << "****";
//No matter what the above line prints,
//the value of var after the above lines is 2, so...
cout << var-- << "*****" << var << endl; //...Print 2, decrement to 1
//and then 1 is finally printed.
Welcome to the strange world of undefined behaviour. Calling an increment or decrement operator twice on the same variable, in the same statement, is undefined behaviour, so don't do it :)
#include <iostream>
int main()
{
int i = 1;
// should this print 9, 10, or 12? Compilers will vary...
std::cout << (++i + ++i + ++i) << std::endl;
return 0;
}
The problem in this line:
cout << var-- << "***" << var-- << "****";
is undefined behaviour because you using post-decrement twice in a single statement.
This question already has answers here:
Swapping two variable value without using third variable
(31 answers)
Closed 6 years ago.
we usually use the
a=a+b;
b=a-b;
a=a-b;
logic to solve this code, however, if we work with int, then after say 30000 the code fails, if we take long, it fails after say 1000000 or so. My objective is, not to increase the length of the code yet, do the same operation. I have already tried using a BIT wise XOR,
a = a ^ b;
b = a ^ b;
a = a ^ b;
Still it didn't help, any ideas?
To swap a variable a and a variable b: std::swap(a, b);
Example:
int a = 10;
int b = 20;
std::cout << "Before swap\n";
std::cout << "Value of a: " << a << '\n';
std::cout << "Value of b: " << b << '\n';
std::swap(a, b);
std::cout << "After swap\n";
std::cout << "Value of a: " << a << '\n';
std::cout << "Value of b: " << b << '\n';
Output using GCC 4.9.2:
Before swap
Value of a: 10
Value of b: 20
After swap
Value of a: 20
Value of b: 10
This way of doing it uses rvalues internally, so it has next to zero overhead for other use cases and won't overflow for any primitive type ever
Decrementation / Incrementation is a basic operation but it's precendence on - -- and + ++ confused me. I'll use decrementation for illustration:
I have a set here of different styles of operating between a and b: See it working here
#include <iostream>
using namespace std;
int a=10, b=7;
int main() {
// - and -- opearator // Results: Details:
a = 10, b = 7; cout << a---b << endl; // 3 a post-decrement
a = 10, b = 7; cout << a ---b << endl; // 3 a post-decrement
a = 10, b = 7; cout << a- --b << endl; // 4 b pre-decrement
a = 10, b = 7; cout << a-- -b << endl; // 3 a post-decrement
a = 10, b = 7; cout << a--- b << endl; // 3 a post-decrement
return 0;
}
I understand that the 4 output came from the decremented b which is 7 that turned to 6 and is subtracted from a which is 10.
Also, because of the other four statements, I thought the compiler treats all of them as --- but behold, here comes the confusion of - -- results. See it working here
Parsing follows the maximal munch rule, so all statements minus the third are interpreted as (a--)-b which decrements a and returns its previous value (which was 10).
The third one is a-(--b) which is a pre-decrement on b, so the new decremented value is returned.
I think this is because of the Maximal Munch Rule. From Wiki:
In computer programming and computer science, "maximal munch" or
"longest match" is the principle that when creating some construct, as
much of the available input as possible should be consumed.
From Expert C Programming:
The ANSI standard specifies a convention that has come to be known as
the maximal munch strategy. Maximal munch says that if there's more
than one possibility for the next token, the compiler will prefer to
bite off the one involving the longest sequence of characters.
But why didn't it decremented after it's statement?
Because the --X operator:
first performs the decrement
then returns the result of decrementing
So, there's no way that --b will 'decrement afterwards'. It always does it "before".
Confusion
Look carefully at code and results: Everytime where --- is written without spaces, the result is the same: three. Three is also the result for -- - case. Even with a pure guess, you could say that compiler parses it as -- -. In fact, it actually does it like that, because the C++ Standard requires it to do so. See comments about 'maximum munch' rule. Same follows for other multi-character operators, like ++.
In the other case where you have split that into - --, the compiler had no other option: it had to treat it literally as - -- because of the space in the middle. Just as -- -, this case is obvious and it's perfectly visible which part forms the -- operator and the compiler must obey that.
That statement is equivalent to 10-6 = 4,
rest are equivalent to 9-7 = 3.
#include <iostream>
using namespace std;
int a=10, b=7;
int main() {
// - and -- opearator // Results: Details after a statement:
cout << (a--)-b << endl; a=10, b=7; // 3 Both a and b decremented
cout << (a --)-b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a- (--b) << endl; a=10, b=7; // 4 Neither a or b decremented
cout << (a--) -b << endl; a=10, b=7; // 3 Both a and b decremented
cout << (a--)- b << endl; a=10, b=7; // 3 Both a and b decremented
return 0;
}
In this series of statements
cout << a---b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a ---b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a- --b << endl; a=10, b=7; // 4 Neither a or b decremented
cout << a-- -b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a--- b << endl; a=10, b=7; // 3 Both a and b decremented
you forgot to include one more statement:)
cout << a --- b << endl; a=10, b=7; // 3 Both a and b decremented
In all these statements
cout << a---b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a ---b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a--- b << endl; a=10, b=7; // 3 Both a and b decremented
cout << a --- b << endl; a=10, b=7; // 3 Both a and b decremented
The compiler parses outputed expression as
a-- -b
that is it tries to extract the longest valid token.
The value of the postdecrement operator as for example a-- is the value of its operand before decrementing. So in expression
a-- -b
the value of a-- is 10 and the value of b is 7. The difference is equal to 3.
And you have the only expression with the predecrement operator
cout << a- --b << endl; a=10, b=7; // 4 Neither a or b decremented
There the value of --b is the value of b after decrementing that is 6. So you have 10 - 6 that is equal to 4.
If you will substitute minus to plus in all these statements you will get the same effect
17
17
18
17
17
17 // this corresponds to my added statement a +++ b
So these operations - -- and + ++ behave in essense the same way.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
I'm having trouble understanding the order of actions when overloading the postfix operator. Let's examine the two small examples below:
int i = 0;
std::cout << std::endl << "i: " << i;
i = ++i;
std::cout << std::endl << "i: " << i;
i = i++;
std::cout << std::endl << "i: " << i;
MyClass myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = ++myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = myObject++;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
Two very different behaviors emerge. The output is as follows:
i: 0
i: 1
i: 2
myObject: 0
myObject: 1
myObject: 1
Different behavior, you see. Here's the outline of my overloaded-operator methods.
MyClass & MyClass::operator++ ()
{
++myValue;
return *this;
}
MyClass MyClass::operator++ (int postfixFlag)
{
MyClass myTemp(*this);
++myValue;
return myTemp;
}
Alright. Prefix makes sense. You increment whatever you need to, then return the same object, now modified, in case of assignment. But postfix is what's tripping me up. It's supposed to assign, then increment. Here we're self assigning. So with the built-in integer type, it makes sense. I assign i's value to itself, then i gets incremented. Fair enough. But let's say MyClass is a recreation of the int. It starts out at 0, gets prefix-incremented, and becomes 1. Then, the key line. myObject = myObject++. That's the same thing as myObject = myObject.operator++(int postfixFlag). It gets called. myTemp gets initialized with the value 1. It's incremented to 2. Then we return the temp. That works, if we're assigning to another object. But here I'm self-assigning, so after the increment to 2, myObject is set equal to the returned temp object initialized with the initial value, and we're back to 1! That makes sense. But it's a fundamentally different behavior.
How do I work around it? How does int do it? How is this method generally written? Do you have any comments about C++ behavior and design relating to this? Etc. I'm a little perplexed right now, since books and online examples always seem to use a variant on the method above.
Thanks for reading, and any input will be appreciated!
As others have said, with int the behaviour is undefined. But I thought I'd try to explain why for your MyClass it is not ever getting to 2.
The trick is that you are taking the following three steps in the postfix version:
Making a copy of this called myTemp (with myValue == 1).
Incrementing this->myValue (so myTemp.myValue == 1; this->myValue == 2).
Returning myTemp (with myValue == 1).
So you are modifying this, but the code that calls myObject++ is never going to see this again. It's only going to look at the value returned, which is a copy of the old myObject.
The code for operator++ is fine. The problem is how you are using it -- you shouldn't be writing the result of a pre-increment or post-increment back to the same variable (behaviour is undefined). Here is some code that might be more instructive:
int i = 0;
std::cout << "i: " << i << std::endl;
int j = ++i;
std::cout << "i: " << i << ", j: " << j << std::endl;
int k = i++;
std::cout << "i: " << i << ", k: " << k << std::endl;
MyClass myObject;
std::cout << "myObject: " << myObject.getMyValue() << std::endl;
MyClass myObject1 = ++myObject;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject1: " << myObject1.getMyValue() << std::endl;
MyClass myObject2 = myObject++;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject2: " << myObject2.getMyValue() << std::endl;
This prints:
i: 0
i: 1, j: 1
i: 2, k: 1
myObject: 0
myObject: 1, myObject1: 1
myObject: 2, myObject2: 1
I changed your code so that rather than assigning back to itself, it assigns to a fresh variable each time. Note that in both the int and the MyClass cases, the main variable (i/myObject) is incremented both times. However, in the pre-increment case, the fresh variable (j/myObject1) takes on the new value, while in the post-increment case, the fresh variable (k/myObject2) takes on the old value.
Edit: Just answering another part of the question, "How does int do it?" I assume this question means "what does the pre-increment and post-increment code look like in the int class, and how can I make mine the same?" The answer is, there is no "int class". int is a special built-in type in C++ and the compiler treats it specially. These types aren't defined with ordinary C++ code, they are hard-coded into the compiler.
Note: For anyone who wants to try this themselves, here is the code for MyClass that the question didn't include:
class MyClass
{
private:
int myValue;
public:
MyClass() : myValue(0) {}
int getMyValue() { return myValue; }
MyClass& operator++();
MyClass operator++(int postfixFlag);
};