Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Please explain the output:
#include<iostream.h>
int main()
{
int i= -3, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
OUTPUT :
-2 2 0 1
Here's what I thought:
(++i || ++j) && (++k) //Considering the precedence order
++i becomes -2 so first part of OR true, so it won't check 2nd part.
(Thanks Joachim Pileborg for telling me the short circuit evaluation)
So overall, first part of AND is true.
But that is not enough for statement to be true, 2nd part must be true to.
So ++k makes k = 1
Here's where I get it wrong. Why is k not increasing?
whereas, in this case:
#include<iostream.h>
int main()
{
int i= -1, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
OUTPUT:
0 3 1 1
I got this one too considering short circuit evaluation.
Let's start with this code snippet
#include<iostream.h>
int main()
{
int i= -3, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
It is obvious that m will be have a boolean value converted to int. As ++i is equal to -2 that is unequal to zero then all other expressions will not be evaluated because it is already known that the whole expression is equal to true. So after statement
m = ++i || ++j && ++k;
m is equal to 1 and i is equal to -2 All other variables were not changed.
In this code snippet
#include<iostream.h>
int main()
{
int i= -1, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
++i will be equal to 0. So the right operand of operator || will be evaluated. This operand is
++j && ++k
As ++j will be equal to 3 and is not equal to 0 then ++k also will be evaluated and will be equal to 1. As the both operands of operator && is not equal to zero then the result is equal to true
Thus you will get i == 0, j == 3, k == 1, m == 1.
From the C++ Standard
5.14 Logical AND operator
1 The && operator groups left-to-right. The operands are both
contextually converted to bool (Clause 4). The result is true if both
operands are true and false otherwise. Unlike &, && guarantees
left-to-right evaluation: the second operand is not evaluated if the
first operand is false.
5.15 Logical OR operator
1 The || operator groups left-to-right. The operands are both
contextually converted to bool (Clause 4). It returns true if either
of its operands is true, and false otherwise. Unlike |, ||
guarantees left-to-right evaluation; moreover, the second operand is
not evaluated if the first operand evaluates to true.
In logical expressions, such as: ... || ... && ... C++ can omit executing statements that would not change the output value of expression. For example: if it computes first value and it's output is not equal to 0, then expression: true || ... && ... is always true, therefore execution of further expressions is not necessary
Below is your second case:-
int i= -1, j=2, k=0, m;
m = ++i || ++j && ++k;
In
( cond1 || cond2)
expression if cond1 is true then compiler does not go on to check for cond2. It will evaluate cond2 only if cond1 returns false.
So, in second ++i makes first expression to be false and forces compiler to go on to evaluate further whereas in first case first expression returns true.
Related
Code
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i < 10)
if (i++ % 2 == 0)
cout << i << endl;
return 0;
}
The output is
3
5
7
9
Since i is 1, I thought that the if statement satisfies 2% 2 == 0 and 2 should be output, but why 3?
if (i++ % 2 == 0) means evaluate i%2 and compare to 0, and increment i at some point after evaluating it but before cout << i
That's why you're seeing odd numbers printed. In every case, an even value of i caused the statement controlled by the if to be executed, and the increment changed the even value to an odd one.
You are using post-increment, which increments the variable and then returns the old value before the increment. You are then printing the incremented value.
So, lets look at your loop step-by-step:
On the 1st iteration, i is 1. i++ sets i to 2, but returns 1. So the if compares 1 % 2 == 0, which is false.
On the 2nd iteration, i is 2. i++ sets i to 3, but returns 2. So the if compares 2 % 2 == 0, which is true, so cout << i prints 3.
On the 3rd iteration, i is 3. i++ sets i to 4, but returns 3. So the if compares 3 % 2 == 0, which is false.
On the 4th iteration, i is 4. i++ sets i to 5, but returns 4. So the if compares 4 % 2 == 0, which is true, so cout << i prints 5.
And so on...
It sounds like perhaps you were expecting i++ to pre-increment instead, returning the new value rather than the old value. In which case, there is a slightly different syntax for that purpose:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i < 10)
if (++i % 2 == 0) // <-- ++i vs i++
cout << i << endl;
return 0;
}
Note the position of ++ in relation to i. Both syntaxes increment i, but positioning ++ to the left of i returns the new value after i is incremented, while positioning ++ to the right of i returns the old value before i was incremented.
Same with the decrement operator --, too. It has pre-decrement and post-decrement versions.
According to the C++ 14 Standard (5.2.6 Increment and decrement)
1 The value of a postfix ++ expression is the value of its
operand. [ Note: the value obtained is a copy of the original value
— end note ] The operand shall be a modifiable lvalue. The type of the
operand shall be an arithmetic type or a pointer to a complete object
type. The value of the operand object is modified by adding 1 to
it, unless the object is of type bool, in which case it is set to
true.
So for example in the second iteration of the while loop the variable i is indeed equal to 2 after incrementing it in the first iteration of the loop
while (i < 10)
if (i++ % 2 == 0)
cout << i << endl;
Thus the condition of the if statement
if (i++ % 2 == 0)
evaluates to true. But the value of the variable i after the evaluation of the condition was incremented. So this statement
cout << i << endl;
outputs the new value 3.
You can equivalently rewrite the while loop the following way
while (i < 10)
if (i % 2 == 0)
cout << ++i << endl;
else
++i;
In the following code:
#include<iostream>
using namespace std;
int main()
{
int x = 1 , y = 1, z = 1;
cout << ( ++x || ++y && ++z ) << endl; //outputs 1;
cout << x << " " << y << " " << z ; //x = 2 , y = 1 , z = 1;
return 0;
}
According to me, logical AND should evaluate first, followed by logical OR. However, the results seem to be contrasting my assumption. Can someone explain?
The operators || and && are short-circuit (if not overloaded).
Hence, for ||: if the first argument is true, the second is not evaluated.
For &&: if the first is false, the second is not evaluated.
If a in a || (b && c) is true, the second expression isn't evaluated whatever it contains.
(I set parentheses (which are actually not necessary) to emphasize what the 2nd argument of || is.)
operator&& has higher precedence than operator||, that means ++x || ++y && ++z will be interpreted as ++x || (++y && ++z), which doesn't mean (++y && ++z) gets evaluated firstly. ++x is still evaluated firstly, it gives a non-zero value which could convert to bool with value true, then (++y && ++z) won't be evaluated due to short-circuit evaluation.
You seem to be confusing the precedence of an operator with order of evaluation. Yes, && has higher precedence than ||, so ++x || ++y && ++z is evaluated as ++x || (++y && ++z), but it's still evaluated from left to right.
See also Order of evaluation:
Every value computation and side effect of the first (left) argument of the built-in logical AND operator && and the built-in logical OR operator || is sequenced before every value computation and side effect of the second (right) argument.
That is, the left argument of || will always be evaluated before the right argument. Thus ++x is evaluated first, this yields true and the condition short-circuits, so (++y && ++z) isn't evaluated at all.
I came accross this expression, and can't understand the meaning of line 3 in the following snippet:
int A=0, B=0;
std::cout << A << B << "\n"; // Prints 0, 0
A += B++ == 0; // how does this exp work exactly?
std::cout << A << B << "\n"; // Prints 1, 1
A adds B to it, and B is Post incremented by 1, what does the "==0" mean?
Edit:
Here's the actual code:
int lengthOfLongestSubstringKDistinct(string s, int k) {
int ctr[256] = {}, j = -1, distinct = 0, maxlen = 0;
for (int i=0; i<s.size(); ++i) {
distinct += ctr[s[i]]++ == 0; //
while (distinct > k)
distinct -= --ctr[s[++j]] == 0;
maxlen = max(maxlen, i - j);
}
return maxlen;
}
B++ == 0
This is a boolean expression resulting in true or false. In this case the result is true, true is then added to A. The value of true is 1 so the (rough) equivalent would be:
if(B == 0)
A += 1;
++B;
Note that this isn't particulary good or clear to read code and the person who wrote this should be thrown into the Gulags.
Lets break this expression into pieces: A += value, whereas value = B++ == 0. As later cout suggests, value == 1. Why is that? Here is why: value is result of comparison of B++ and 0, but ++ (increment) operation, when written after operand, is being processed after the comparison, i.e. if you write A += ++B == 0 the later cout should (and does) print 0, 1.
This question already has answers here:
Checking if a value is within a range in if statment [duplicate]
(2 answers)
Closed 6 years ago.
I have the following code.that demonstrates the problem I am having. How come the comparison is not evaluating to true? Is this a limitation of integer and floating point comparisons?
#include <iostream>
int main(){
double m = -0.625;
if((-1)<=m<=0){
std::cout << "Enter here" <<std::endl;
}
return 0;
}
You can't do three way comparison like that in C. Change it to the following and it'll work:
if((-1) <= m && m <= 0){
std::cout << "Enter here" <<std::endl;
}
The condition in this if statement
if( ( -1 ) <= m <= 0 ){
is equivalent to
if( ( -1 <= m ) < = 0 ){
as -1 is less than m then the subexpression ( -1 <= m ) yields 1 in C and true in C++ that then is converted to 1 and the subexpression 1 <= 0 yields 0 in C and false in C++..
To get the expected result you should write instead
if( -1 <= m && m <= 0 ){
In C++ -1 <= m <= 0 is equivalent to (-1 <= m) <= 0.
In this example, -1 is implicitly converted to a float in order to use the <= operator with m. The result of this expression is a bool. This result is then implicitly converted to an int in order to use the <= operator with 0. Since a bool is converted to either 0 or 1 (false or true), this conditional statement will only be true when m is less than -1.
It makes sense from a math standpoint to structure the if statement like that, however you must break it up explicitly so the compiler knows what you want.
Try this
-1 <= m && m <= 0
#include <iostream>
using namespace std;
int main()
{
int j=20;
int i=0;
for ( int k=0; i<10 && j>10; i++ && j--)
cout<< "i is " <<i<< " and j is " <<j<<endl;
}
So, this is how I see it, first i is 0 and j is 20, both follows the condition, hence the output is "0 20", then i is incremented and j is decremented, thus the output should be "1 19" but the next output is "1 20", as if the j hasn't been decremented!. Why?
When i==0, i++ && j-- short-circuits the first time it is called, so you end up with i==1 and j==20.
You can fix this by using the comma operator: i++, j--.
Remember, in C/C++, 0 is considered false, so 0 && x will never evaluate x since it knows the expression is false. See the above link for more detail.
The expression (i++ && j++) short circuits, and J is never incremented, because (i) holds a (false) initial value. I think you want it to look more like this:
for (int k=0; i<10 && j > 10; i++, j--)
The && operator checks the left side first for truth, and if it's false, (when i is 0, this is false) it doesn't even evaluate the right side. If the left side IS true, then and ONLY then will it check the right side of the &&.
The incremental part of the for-loop shouldn't be evaluating a boolean condition.