In the following code
#include <iostream>
using namespace std;
int main(void){
double *x, *y;
unsigned long long int n=2;
x = new double [2];
y = new double [2];
for(int i=0; i<2; i++){
x[i] = 1.0;
y[i] = 1.0;
//what is the following line doing exaclty?
x[i] = y[i]/=((double)n);
cout << "\n" << x[i] << "\t" << y[i];
}
delete [] x;
delete [] y;
printf("\n");
return 0;
}
I do not understand what the combination of = and /= is doing exactly, and why this is allowed (the code compiles and runs correctly under Valgrind).
This code
x[i] = y[i]/=((double)n);
is logically equivalent to this 2 lines:
y[i]/=((double)n);
x[i] = y[i];
and first line is logically equal to:
y[i] = y[i] / n;
note typecasting here is completely redundant.
The following 2 symbols: = and /= are assignment operators. They are used to set the variable on the right to the value or variable on the right. The = operator is simple; it does no operation on the value on the left. So, if we have a statement like:
int x = 5;
The equality assignment operator here simply sets x to 5.
The second operator in the line of code you are confused about is a part of the compound assignment operator group. This operator does 2 operations: it first takes the value stored in the variable on the left side of the operator, divides it by the value on the right side of the operator, and stores it again in the variable on the left side of the operator. Therefore, if we take this simple piece of code:
int y = 25;
y /= 5;
This piece of code declares a variable of type int, initialized to 25. The second line divides the value of y by 5, ad updates the variable y with the resulting value of the mathematical operation.
Now, we are not restricted to having a fixed value, a variable, or a function's return value as a statement on the right side of the assignment operator. We can very well evaluate an expression (like here we do y[i] /= ((double)/n), and then assign the updated value of y[i] to x[i]. The compiler merely evaluates the expression on the right first, and then moves on to assign it to the left-hand variable.
Now, having this explaination, we can summarize this line very easily:
x[i] = y[i]/=((double)n);
The compiler divides the value of y[i] by the value n, casted as a double (unrequired here as y itself is of type double), assigns the new value to y[i], and then assigns x[i] the updated value of y[i].
Both are assignment operators and assignment operators are evaluated from right to left. Therefore (assuming that n != 0) the combined assignment does the same as this:
y[i] /= ((double)n);
x[i] = y[i];
And of course the first statement can also be written as:
y[i] = y[i] / ((double)n);
Related
I am not able to understand, why the output of the code is not what I was expecting.
#include <iostream>
using namespace std;
int main()
{
int m = 2, n = 6;
int &x = m;
int &y = n;
m = x++;
x = m++;
n = y++;
y = n++;
cout<< m << " " << n;
return 0;
}
I was expecting 4 8
This line:
m = x++;
is equivalent to:
x = x++;
since m is a reference to x.
From c++17, the right hand side is evaluated first, resulting in 2. Then x is incremented to 3. Then the assignment of the right hand side value to the left hand side is done. But this uses the old value of the right hand side, which is 2. So the above statement effectively does nothing.
Before c++17,
m = x++;
is undefined behavior.
Notice how the operators are post-increment and not pre-increment... You're basically doing nothing.
m = x++; means that increment x (i.e. m) but return the old value of x (i.e. m). Assignment takes place after the increment and return of old value and the old value is what ends up getting assigned. So, you end up essentially with a bunch of self-assignments.
Can someone please explain what is happening in the following code? (Taken from GeeksForGeeks)
int main(){
int a = 10;
++a = 20; // works
printf("a = %d", a);
getchar();
return 0;
}
What exactly is happening when the statement ++a = 20 is executed? Also, please clarify why this code fails in execution?
int main(){
int a = 10;
a++ = 20; // error
printf("a = %d", a);
getchar();
return 0;
}
Code Taken From: http://www.geeksforgeeks.org/g-fact-40/
When you do
++a = 20;
it's roughly equivalent to
a = a + 1;
a = 20;
But when you do
a++ = 20;
it's roughly equivalent to
int temp = a;
a = a + 1;
temp = 20;
But the variable temp doesn't really exist. The result of a++ is something called an rvalue and those can't be assigned to. Rvalues are supposed to be on the right hand side of an assignment, not left hand side. (That's basically what the l and r in lvalue and rvalue comes from.)
See e.g. this values category reference for more information about lvalues and rvalues.
This is the difference between r and l values. If you would have compiled the 2nd code snippet with gcc you would have seen this:
lvalue required as left operand of assignment
meaning, that a++ is rvalue and not a lvalue as it should be if you want to assign something to it
int main(){
int a = 10;
++a = 20; // works
printf("a = %d", a);
getchar();
return 0;
}
This is a c Language.
Explaining Line by line
int main() THIS line define an entry function called main which is expected to return a type integer(int)
int a = 10 declares a variable integer whose value is 10;
++a = 20; AT this point your code is incrementing the value of a by 1 before any operation is performed on a.
This means that, the value of a is incremented by 1 bfore a is assign the value of 20;....
the statement ++a = 20 is incorect in the sense that, a is 10 initially, and you increment it to 11 . Is like saying 11 = 20; this may not throw an error because the code line is not useful.
printf() is a c-method to print file to screen, passing a string "a = %d" tells the compiler to print a to a decimal number(%d).
getchar() is use to terminate the running program and return 0 is to forcefully tell the operating system that the code run successfully and return integer value 0.
int main(){
int a = 10;
a++ = 20; // error
printf("a = %d", a);
getchar();
return 0;
}
This didn't at a++ = 20 because , right value increment perform the operation before it increment unlike ++a who increment before performing operation.
So this isn't possible and it never works because a is already 10, and you are saying the value ++ and assign 20, you can't assign a value to it, it should be the one calculating its own value. So the compiler will want to interprete is as variable a++ = 20, and ++ can not be a vaiable name. That's why it never work.
What is the essence of incrementation and decrementation in c....its useful for creating conditional statement e.g for loop, while statement etc. for example:
for(int i = 0; i < 4; i++)
{
printf('THis is c-language');
}
or
int i = 0;
while(i < 4){
printf('THis is c-Language');
i++;
}
so therefore, following the programming rules and regulations, you are not allow to assign value to either a++ or ++a
they are for the compilers to manipulate, so never assign value to them.
Thank you.
The left operand of the assignment operator should be an lvalue.
The expression ++a is an lvalue while a++ is not and therefore it can't be the left operand of the assignment operator.
n3797-ยง 5.3.3(p1):
[...] The result is the updated operand; it is an lvalue [...]
I've been trying to understand how post and pre increments work lately and I've been over thinking it too much.
Does "Product" become 25 after one iteration?
Product *=5++
And does "Quotient" become 5/6 after one iteration?
Quotient /= ++x
5++ is just incorrect.
Quotient /= ++x; is the same as x = x + 1; Quotient = Quotient / x; (assuming these are just plain numbers).
Your code isn't valid C++, since the built-in post-increment operator may only be applied to lvalues, but literal integers are rvalues.
Beside that, the value of a (built-in) pre-increment expression is the incremented value, while the value of a post-increment expression is the original value.
Pre-increment modifies the variable and evaluates to the modified value.
Post-increment evaluates to the value of the variable and then increments the variable.
int a = 5;
int b = ++a; // a = a + 1; b = a
int c = a++; // c = a; a = a + 1
Consider these simple implementations of ++ for int
int& int::preincrement()
{
this->m_value += 1;
return *this;
}
int int::postincrement()
{
int before = this->m_value;
this->m_value += 1;
return before;
}
I am trying to implement a simple compiler using flex & bison, and got stuck in the postfix notation.
(The compiler should behave like the C++ compiler)
Here is the problem:
Given the following code:
int x = 0;
int y = x++ || x++ ; //y=1 , x = 2 this is understandable
int z = x++ + x++ ; // z = 0 , x=2
the first line is fine because of the following grammar:
expression = expression || expression; // x=0
expression = 0 || expression // x= 1
expression = 0 || 1 //x=2
expression = 1 // x=2
y = 1
However, I don't understand why z=0.
When my bison grammar sees 'variable' ++ it first returns the variables value, and only then increments it by 1. I used to think thats how C++ works, but it won't work for the 'z' variable.
Any advice on how to solve this case?
int z = x++ + x++;
Although z may appear to be 0, it is not, it could in fact be any value and will depend entirely upon the compiler you are using. This is because the assignment of z has undefined behaviour.
The undefined behaviour comes from the value of x being changed more than once between sequence points. In C++, the || operator is a sequence point which is why the assignment of y is working as expected, however the + operator is not a sequence point.
There are of course various other sequence points in C++, the ; being a more prominent example.
I should also point out that the ++ operator returns the previous value of the variable, that is in this example
#include <iostream>
using namespace std;
int main() {
int x = 0;
int y = x++;
cout << y << endl;
return 0;
}
The value printed out for y is 0.
Saying the same thing another way. A C compiler is free to implement
int z = x++ + x++;
as either
z = x + x
incr x
incr x
or as
int r1 = x;
incr x
z = r1 + x
incr x
Your compiler appears to be using the first plan.
Help me to resolve this please. The steps that follows that expressions are:
//Expression
offSpring1[m1++] = temp1;
//Steps:
1.- increment m1
2.- assign temp1 to offSpring
I have always thought that the expression inside the brackets was the first to be done. But now I am confuse. So if a write this:
//Expression
offSpring1[++m1] = temp1;
//Steps would be:
1.- assign temp1 to offSpring
2.- increment m1
If the steps would be the same as first ones, what is the difference between i++ and ++i?
int i = 0;
std::cout << i++ << std::endl;
std::cout << i << "\nreset" << std::endl;
i = 0;
std::cout << ++i << std::endl;
std::cout << i << std::endl;
output:
0
1
reset
1
1
i++ returns the value as it currently stands in the expression, then increments the variable.
++i will increment the variable, then return the value to use in the current expression.
offSpring1[m1++] = temp1;
is
offSpring1[m1] = temp1;
m1 += 1;
and
offSpring1[++m1] = temp1;
is
m1 += 1;
offSpring1[m1] = temp1;
j = ++i is the same as i = i+1; j = i;
j = i++ is the same as j = i; i = i+1;
Just run these two different test programs to understand the difference between the post-increment and the pre-increment operators
For ++i (pre-increment)
int main()
{
int* offSpring = calloc(20,sizeof(int));
int m1 =1;
offSpring[++m1] = 10;
printf("%d,%d",offSpring[m1],m1);
}
In the first one you will get 10 as the value of offSpring[m1].
Why? Because this is the pre-increment operator which means that first m1 gets incremented and the the rest gets evaluated.
For i++(post-increment)
int main()
{
int* offSpring = calloc(20,sizeof(int));
int m1 =1;
offSpring[m1++] = 10;
printf("%d,%d",offSpring[m1],m1);
}
In the second because the post-increment operator is used you will get a 0 value since you are first assigning 10 to offSpring[m1] and then m1 gets incremented.
offSpring1[m1++] = temp1; doesn't do what you said.
assign temp_m1 = m1.
increment m1.
index offSpring1[temp_m1]
assign temp1 into indexed value.
On the other hand offSpring1[++m1] = temp1; works like this:
increment m1.
index offSpring1[m1]
assign temp1 into indexed value.
Even though postfix increment is the first to be evaluated in your first example, its value is the original value of the variable being incremented.
offSpring1[m1++] = temp1;
So even though m1 is incremented before array idexing, the value of temp1 is assigned at position m1 - 1.
There are two aspects to an expression (or sub-expression): its value,
and its side effects. The value of i ++ is the value of i; the
value of ++ i is the value i + 1, converted to the type of i.
This is the value used in the expression. The side effects of both is
to increment the variable i. This may occur at any time after the
preceding sequence point and before the next. Supposing i is a global
variable, and you write something like:
i = 0;
f()[i ++] = g();
f()[++ i] = g();
The standard says nothing about whether the value of i seen in f()
or g() is that before the incrementation, or after. In neither case.
All the standard says is that the effects of the incrementation will
take place after the start of the full expression (but perhaps as the
first thing in the full expression) and before the end of it. (And that
they won't be interleaved with a function call, so that if f()
reads i twice, it is guaranteed to see the same value.)
Unfortunately, in those 2 code snippets you've posted there, there's no guaranteed order of evaluation. If your expressions are inappropriate, more or less anything could happen.
To start with the difference between a++ and ++a:
a++ will increment a but the expression using it will see the value of a before the increment
++a will increment a, and the expression using it will see the incremented value.
List item
with
buffer[a++] = b;
the compiler can decide to do the ++ at any point within the expression. Thus if 'b' is actually an expression involving a, you can get different results on different compilers. Both of the following would be valid:
get the value of a;
increment a
work out where buffer[old value] points to
evaluate b
store b
or this
evaluate b;
work out where buffer[a] points to
store b
increment a
if 'b' should happen to involve a, those 2 implementations would produce different results. Both are valid.
It works precisely the opposite of what you described:
offSpring1[m1++] = temp1 is the same as
offSpring[m1] = temp1; m1 = m1 + 1;
OffSpring1[++m1] = temp1 is the same as
m1 = m1 + 1; OffSpring1[m1] = temp1;
Prefix notation increments before evaluating the expression
Postfix notation increments after evaluating the expression
The description of the first is the correct description for the second. The correct description of the first is very similar, you just need a "copy current value of m1" step added before the others.
But you do have a distinct lack of sequence points here, if m1 has a primitive type. The rules change somewhat between C++03 and C++11.
If m1 has a user-defined type, then there are function calls involved which influence sequencing.
This code
offSpring1[m1++] = temp1;
performs the following (if m1 is a primitive type):
auto const old_m1(m1);
auto const new_m1(old_m1 + 1);
auto& lhs(offSpring[old_m1]);
parallel { lhs = temp1; m1 = new_m1; }
This code
offSpring1[++m1] = temp1;
is exactly the same except that lhs is bound using new_m1 instead of old_m1.
In either case, it is unspecified whether lhs is written to before or after m1.
If m1 is not a primitive type, it looks more like:
auto const& index = m1.operator++(0); // one argument
auto& lhs = offSpring.operator[](index);
lhs = temp1;
vs
auto const& index = m1.operator++(); // no arguments
auto& lhs = offSpring.operator[](index);
lhs = temp1;
In both these cases, the change to m1 is definitely made before the write to lhs.