I have came across one type of usage of operator =. It was something like this:
A += B == 1;
where A and B are integers and this kind of usage I found in a function body.
I just kind of confused with the second == usage.
Of course I know the meaning of A = B = 1;
Can anybody explain me?
This code:
A += B == 1;
is logically equal to:
bool b = B == 1;
A += b;
Note: bool can be implicitly converted to int (true to 1 and false to 0)
== has higher precedence over +=, so it's executed first
B == 1 is a boolean expression, can be false or true
let's call that bool 'result'.
A += result is an addition + assignment (like A = A + result as you may already know).
Since A is an int in your case, the boolean result is implicitly converted to the number 1 if true, or 0 if false. (it would work similarily for other number types as well)
More on implicit conversions here : http://en.cppreference.com/w/cpp/language/implicit_conversion
So, at the end, this is logically equivalent to "increment A if and only if B is equal to 1" :
if (B == 1)
A += 1;
Related
I have some code in an old desktop app, which I inheritted from a colegue who left the company.
Here is a short similar example of the actual code I have:
#include <iostream>
int getType(int type)
{
return type;
}
int main()
{
int variable1 = 30;
int variable2 = 40;
int result = (getType(30) == (variable1 || variable2) ? 1 : 2);
std::cout << result << std::endl;
}
For the result I always receive 2, not 1 as I expected.
If I try:
int result = (getType(30) == (variable1) ? 1 : 2)
the result is true.
I can't figure out why this part:
int result = (getType(30) == (variable1 || variable2) ? 1 : 2)
is not true...
In the initializer expression of this declaration
int result = (getType(30) == (variable1 || variable2) ? 1 : 2);
the subexpression (variable1 || variable2) has the type bool and its value is true (variable1 isn't 0 so that is true) that is implicitly converted to the integer value 1 in the expression with the equality operator (getType(30) == (variable1 || variable2) .
From the C++17 Standard (7.6 Integral promotions)
6 A prvalue of type bool can be converted to a prvalue of type int,
with false becoming zero and true becoming one.
So as getType(30) is not equal to 1 the result of the initializer expression is 2.
To get the expected result you should rewrite the declaration like
int result = (getType(30) == variable1 || getType(30) == variable2) ? 1 : 2;
I think perhaps your understanding of the || operator is not quite right. The || operator is the or operator, and it will return a boolean result, false or true. In your code, you are doing this comparison: getType(30) == (variable1 || variable2). The parenthesis get evaluated first because of order of operations and you end up with getType(30) == true, since variable1 has a non-zero value. getType(30) evaluates and returns 30, so the expression is 30 == true. The true value then gets coerced to a 1 because of the rules of c++ and we evalate 30 == 1 which is false.
I think what you are asking for is why this doesn't do what you expect. And I see two problems, the one is that the getType function doesn't actually do what you might expect, it simply returns the variable. I'm not sure what you would expect in c++, but that's definitely a problem. The other expectation is probably that you want to compare the return of getType(30) with both variable1 and variable2 which would require a longer expression. The expression you want is probably getType(30) == variable1 || getType(30) == variable2. This is a common problem because in english we say 'if gettype equals var1 or var2`, but it doesn't translate into code like that unfortunately.
I have these lines of code:
int a = 10, b = 1;
a = --b ? b : (b = -99);
cout << "a= " << a << "b= " <<b<< endl;
the output gives me b=-99 as a is not equal to 0(which makes senses) but it also changes the value of a to a=-99 how?
Your code is the equivalent of:
int a = 10, b = 1;
b -= 1; // b == 0
int x;
if (b != 0) x = b;
else x = b = -99;
a = x;
// at this point a and b have the same value
The ternary operator works as follows:
if (--b != 0) { // b is not 0 means true
a = b;
} else { // b is 0 means false
a = (b = -99);
}
You assign the value to a, so --b is 0 which is considered as false. Then you assign to b value -99 and afterward, you assign b to a. So, both variables have their values -99 in the end. Hope it will help you.
According to ternary operator, The first argument is a comparison argument(condition), the second is the result upon a true comparison, and the third is the result upon a false comparison.
So In Your case, the condition is not True, So the false statement get executed.
so now b has -99.
In c, c++, java we've seen, assigns the value of the variable
a = b = -99
In this, the both a & b gets the same value. Like this, ternary operator also assigning the value of the variable from false statement .
(a = (b = -99 ))
I think what is confusing you here is that, in C, an expression (such as b = -99) has both consequences and a value. The consequence of b = -99 is that b is assigned the value of -99; but note also that the value of this expression is -99.
Thus, in a ternary expression, which takes the general form:
lhs = test ? v_if_true : v_if_false;
the expression test is first evaluated and lhs is assigned either v_if_true (if test evaluates to non-zero) or v_if_false (if test evaluates to zero).
In your case, test is --b. The consequence of this expression is that the value of b is decreased by one, and the value of the expression is the resulting (modified) value of b (which will be zero in your code).
So, your ternary expression assigns to a the value of the v_if_false expression which is b = -99 (the brackets you give add clarity to the expression, but don't change its evaluation). So, as mentioned above, this expression (as well as modifying b) also has a calculated value of -99, which is then given to a.
If you wanted to leave a unchanged in the case when the v_if_false expression is executed, then you could do this using the comma operator, as follows (though I would not recommend using such code):
a = --b ? b : ((b = -99), a); // If --b == 0, this becomes a = a
This works because the value of an expression containing the comma operator is the value of the sub-expression after (to the right of) the comma.
I have a loop going through an array trying to find which index is a string. It should solve for what that value should be.
I can't figure out why, but as soon as the if statements start i becomes 1 which gives my code an error.
I'm not very fluent in C++.
for(int i = 0; i < 4; i++) {
if(auto value = std::get_if<std::string>(&varArr[i])) {
solvedIndex = i;
auto value0 = std::get_if<float>(&varArr[0]);
auto value1 = std::get_if<float>(&varArr[1]);
auto value2 = std::get_if<float>(&varArr[2]);
auto value3 = std::get_if<float>(&varArr[3]);
//i changes to 1 when this if starts??
if(i = 0) {
solvedVar = (*value3 / *value1) * *value2;
} else if (i = 1) {
solvedVar = *value3 / (*value0 / *value2);
} else if (i = 2) {
solvedVar = *value0 / (*value3 / *value1);
} else {
solvedVar = *value1 * (*value0 / *value2);
}
break;
}
}
Note that these variables are declared above. Also, varArr is filled with values:
std::variant<std::string, float> varArr[4];
int solvedIndex;
float solvedVar;
As has been noted, in your if statements, you are using the assignment operator (=) but want the equality comparison operator (==). For your variable i the first if statement sets i equal to 0 and if(0) is the same as if(false). So your program goes to the first else-if which sets i equal to 1 and if(1) evaluates to true. Your code then finishes the block within else if (i = 1) {...} and then ends.
That's because operator= is the assignment operator in C++ (and most languages, actually). That changes the value of the variable to the value on the other side. So, for instance:
x = 0
will change the value of x to 0. Doesn't matter if it's in an if statement. It will always change the value to 0 (or whatever the right hand side value is).
What you are looking for is operator==, which is the comparison (aka relational) operator in C++/ That asks the question "Are these two things equal?" So, for instance:
x == 0
asks is x is equal to 0.
Following is the test code:
int main()
{
int a = 3;
int b = 4;
a = a + b - (b = a);
cout << "a :" << a << " " << "b :" << b << "\n";
return 0;
}
Compiling this gives the following warning:
> $ g++ -Wall -o test test.cpp test.cpp: In function ‘int main()’:
> test.cpp:11:21: warning: operation on ‘b’ may be undefined
> [-Wsequence-point]
Why can the operation be undefined?
According to my understanding, first the subexpression (b = a) should be evaluated because of higher precedence of (), thus setting b = a. Then, since '+' and '-' have same precedence, the expression would be evaluated left-associatively. Thus, a + b should be evaluated next, and finally the result of (b = a) should be subtracted from a + b. I can't see any sequence-point rule being violated here.
There is a difference between an expression being evaluated and completing its side effects.
The b = a assignment expression will be evaluated ahead of subtraction due to higher precedence of the parentheses. It will provide the value of a as the result of the evaluation. The writing of that value into b, however, may not complete until the next sequence point, which in this case is the end of the full expression. The end result of the overall expression is therefore undefined, because the subtraction may take the value of b before or after the assignment.
In C++, subexpressions in arithmetic expressions do not have temporal ordering.
a = x + y;
Is x evaluated first, or y? The compiler can choose either, or it can choose something completely different. The order of evaluation is not the same thing as operator precedence: operator precedence is strictly defined, and order of evaluation is only defined to the granularity that your program has sequence points.
In fact, on some architectures it is possible to emit code that evaluates both x and y at the same time -- for example, VLIW architectures.
To solve it separate them in two different statements.
PS: Don't forget that humans may make mistakes performing arithmetic operations. Therefore is better to make the operations clearer by separating them in different statements. I hope I helped.
int main()
{
int a = 3;
int b = 4;
/* Two different Statements*/
b = a;
/* or a = a + b - a */
a = a + b - b;
cout<<"a :"<<a<<" "<<"b :"<<b<<"\n";
return 0;
}
a = b + a - a;
is just written as
a = b + a - (b = a)------>> (exp 1)
The following three results same as (exp 1)
a = (b + a - (b = a));
a = ((b + a) - (b = a));
a = (b + a) - (b = a);
Observations
+, - operators has got same precedence and also left to right associativity
Hence 'b+a' gets executed first and then 'a' value gets assigned to 'b' before subtraction
Now observe the following
When a = 10 and b = 20;
a = (b = a) - b + a; =======> a = 10; b = 10
a = ((b = a) - b + a); =======> a = 10; b = 10
a = ((b = a) - (b + a)); =======> a = -10; b = 10
From the above expressions its clear that even if innermost parenthesis gets executed first the associativity is followed first and then the precedence
Note:
To avoid confusion between the precedence of outer and inner parenthesis
Consider the following expression
a = (b + a - (b = a)) =====> Actual Result => a = 20, b = 10;
would have been a = 10, b = 10; (if precedence is primary when compared to associativity)
Thus by the above example we can say that associativity is primary when compared to precedence
Is there a c++ operator that i could use for a for loop where it would add or subtract to variables based on whether one of the variables is less than or greater 0.
For instance
int a;
int b;
for(int i=0;i<some_number; i++)
result = a +< b
result = a-> b
No.
You can combine with the ?: operator.
int a;
int b;
for(int i=0;i<some_number; i++)
result = (a < b)? result+b:result-b;
That is if I understood your example correctly.
-> is an existing dereference operator.
Operator ?: is an equivalent to the if...else construct. If the statement before ? evaluates to true, the statement right after the ? gets executed, otherwise the statement after the : gets executed.
Do you want something like this?
result += a > 0 ? b : -b;
Note that this will subtract b if a == 0, which isn't quite what you asked for.
Not directly, but the ternary operator is close.
for(int i=0;i<some_number; i++)
result = (a > 0)?(a):(b);
This line will be equivalent to result = a when a is greater than 0, and result = b elsewise.
It could also be written as result = a?a:b;, but the longer form is more readable.
Not sure if this would be any help?
result = a + (b*(a < b));
result = a - (b*(a > b));
Basically, (a < b) is converted into a boolean, which is basically either 1 (true) or 0 (false). b multiplied by 0 is of course zero, so nothing is added, and b multiplied by 1 is exactly b's value.