Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a trouble understanding what does this code do :
#include <iostream>
using namespace std;
int main()
{
int x = 0, y = 0;
if (x++ && y++)
y += 2;
cout << x + y << endl;
return 0;
}
The output is 1 by C++. But I think it should be 2?
Why? Because in the () of if statement, I think there should only check if it's true/false, so it doesn't increment/decrement any of the integers. And since that's true by default, it increases y for 2? And output should be 0+2 = 2, but it outputs only 1?
if (x++ && y++) will not do y++ because the condition to the left of the logical and operator (&&) is false since x++ will return 0 and increment x by 1.
Since false && expression will yield false for any expression, there is no need to evaluate the rest of it.
Hence, you end up with x = 1 and y = 0.
This is called Short-circuit Evaluation.
The post ++ operator has high priority and && operator is allowed to short circuit evaluation.
What happens in if (x++ && y++) is that first it evaluates x++. The result is 0 and increments x. Since 0 is false && will short circuit the evaluation of y++ (will not be executed). Also the if will evaluate to false and will not execute the y+=2.
So now you have x=1 and y=0.
So the result is 1.
it will first execute x++ and the compiler knows that because of that the expression x++ && y++ will be false and will ignore y++
as a result after that x = 1 and y = 0;
it is the same as writing if(false && do_something()) , in this case do_something() will never be called.
I advice you to take a look at the operator precedence chart : http://en.cppreference.com/w/cpp/language/operator_precedence
//in a statement, x++ will evaluate x then increment it by 1.
//in a statement, ++x will increment x by 1 then evaluate it.
If you have hard time to understand it then try the below code to better understand :
#include <iostream>
using namespace std;
int main()
{
int x = 0, y = 0;
if (++x && ++y) // in your case, with the previous code, it gives (0 && 0)
// instead of if statement you can try the following : cout << x++; then cout << ++x;
// and notice the difference
y += 2;
cout << x + y << endl;
return 0;
}
Related
This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed last month.
So here is the question I am given , I need to tell the output :
#include <iostream>
using namespace std;
int main()
{
int x = 10;
int y = 20;
if(x++ > 10 && ++y > 20 ){
cout << "Inside if ";
} else{
cout << "Inside else ";
}
cout << x << “ “ << y;
}
The ans given is Inside else 11 20 I checked with complier this is the correct answer but according to me the answer should be Inside else 11 21.
Why is this happening ? Why isn't the ++y part executing ?
I also tried y++ I still get same answer.
When you write x++, that means two things:
return current value
increment x
Since current value is 10 and 10 > 10 is false, the part after &&, including ++y, is not evaluated.
An alternative would be prefix increment, i.e., ++x.
If the first operand of the logical AND (&&) operator evaluates to false, the second operand is not evaluated, because the value of the expression is already known.
From the C++ 20 Standard (7.6.14 Logical AND operator)
1 The && operator groups left-to-right. The operands are both contextually converted to bool (7.3). 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.
Also, the value of an expression with the post-increment operator is the value of its operand before incrementing.
From the C++ 20 Standard (7.6.1.6 Increment and decrement_
1 The value of a postfix ++ expression is the value of its operand...
So, in this if statement:
if(x++ > 10 && ++y > 20 ){
the left operand of the logical AND operator x++ > 10 evaluates to false. However, the side effect of the post-increment operator is applied to the variable x. The second operand ++y > 20 is not evaluated.
So, the control will be passed to the else statement, and within its sub-statement x will be equal to 11 and y will keep its original value 20.
How does comma operator if it is used in a 'for loop' for writing multiple control statements?
i tried
#include <iostream>
using namespace std;
int main() {
for (int x = 0, y = 0; x < 3, y < 4; ++x, ++y) {
cout << x << " " << y << endl;
}
return 0;
}
and it seems like only the last expression is evaluated. Ty
This is how comma operator works. Its 1st operand x < 3 is evaluated, then the result is discarded; then the 2nd operand y < 4 is evaluated and the value is returned as the return value of the comma operator. x < 3 has not any effects here.
You might want to use operator&& or operator|| for this case, e.g. x < 3 && y < 4 or x < 3 || y < 4 based on your intent.
This was an exercise question from a C++ programming book. There's a flaw in this loop code. I am sure a lot of people would the answer straightaway. I am guessing is with the prefix increment operator.
int x = 0;
while (x)
{
++x;
cout << x << endl;
}
no, its x=0;
you need to assign x to a positive number like x=1 to get the loop running because x=0 evaluates to false, so loop will not run.
If x=0 the while loop will evaluate to false, and the body of the while loop will never be executed, since x will not be changed and always remain 0.
Nothing will be output, and the program will exit with a return code of 0, giving no clue to the lack of output.
The while loop will not execute at all since 0 is treated as false
while(false){
//will not execute; since (x=0 == false)
}
//skips above code and execute this directly.
if you want to run code inside loop you can just give a true value like x=1;
while(true){
//will execute (since x=1 === true)
}
while(1) is equivalent to while(x == 0), while(0) is equivalent to while(x)
The "semantic" is "while" running while .. and the variable "x" contains 0 so if it is added directly to the condition, as it is 0 = false
x == 0, return true if x == 0.
..
return (x == 0);
ref: https://www.tutorialcup.com/cplusplus/while-loop.htm
while(x) is evaluated as while(x!=0) so nothing will be output to the console. i.e. it is the same as:
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int x = 0;
while (x != 0)
{
++x;
cout << x << endl;
}
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I just came upon one problem. I wanted to compare whether my Eratostenes's Sieve contains prime numbers or not. In the code i have this line
if (sieve[2] == is_prime(2)) // returns false
printf ("true");
Now, sieve[2] is a boolean and it's value is true (I even checked in the array, so there's no doubt about it). is_prime(2) is a boolean aswell (I also checked).
Now my problem. The line presented above returns false. Yes - it returns false even though it's statement is:
if ( true == true ) // which normally returns true
printf ("true");
However, after removing one equation sign:
if ( sieve[2] = is_prime(2) ) // returns true
printf ("true");
This statement returns true.
Can someone briefly explain how does one equation mark work in this case in comparison to ==?
Thanks in advance
EDIT
is_prime:
bool is_prime(int x) {
unsigned int i,j,k;
if (x < 2) return false;
else {
for (i=2; i!=x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
}
}
sieve:
const int n = 10000;
bool sieve[n+1];
.
.
unsigned long int i;
sieve[0] = sieve[1] = false;
for (i=2; i<=n; i++) sieve[i] = true;
for (i=2; i*i<=n; i++) {
if (sieve[i]) {
unsigned tmp = 2*i;
while (tmp <= n) {
sieve[tmp] = false;
tmp += i;
}
}
}
[EDIT2]
The problem was with "is_prime(x)" Changed loop condition from "i!=x" to "i<=x"
Sorry for the trouble and thanks for the answers
UPDATE
bool is_prime(int x) {
unsigned int i,j,k;
if (x < 2) return false;
else {
for (i=2; i!=x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
}
}
Your is_prime() (above) is broken, with undefined behaviour, as when x is 2 (or indeed any actually prime number) it reaches the end of the function without having a return statement - the i!=x test means the x == i inside the loop can never be true.
is_prime(2) it's likely to return effectively random results (based on left over stack or register content / in your documented output it's seeming "returning" x itself, presumably because your ABI uses the same CPU register or stack address to pass in the argument and pass back the function's return value).
Specifically for 2, flow enters the first else clause, then with i=2 the first i!=x test fails and the for loop immediately exits... there's no return after the for's scope. Minimally corrected code (faster implementations are possible, but keeping the simplicity and intended logic):
bool is_prime(int x)
{
if (x < 2) return false;
for (int i = 2; i < x; ++i)
if (x % i == 0)
return false;
return true;
}
Equivality / ==
With sieve[2] == is_prime(2) it's checking they have the same value - possibly after converting one of the values to enable the comparison, but you say they're both booleans so that's not necessary. This would yield a "true" value for the if when they're both true or both false.
Now my problem. The line presented above returns false. Yes - it returns false even though...
That doesn't make any sense... I suggest you add the following before the if statement to check the variables' values:
std::cout << "sieve[2] " << sieve[2] << " (bool)" << (bool)sieve[2]
<< ", is_prime(2) " << is_prime(2) << std::endl;
I even checked in the array, so there's no doubt about it
Be wary of mistakes like seeing the array content displayed ala { true false true false } and thinking [2] is the second value... it's actually the third. as array indexing starts at 0.
Assignment / =
With sieve[2] = is_prime(2) you're assigning the value of is_prime(2) into sieve[2], and the if statement is deemed "true" if that value is deemed true in a boolean context (i.e. it's a boolean with value true, or a non-0 number or pointer etc.). For most data types, the execution flow of if (sieve[2] = is_prime(2)) ... is the same as simply if (is_prime(2)) ..., but of course it also modifies sieve[2].
It assigns the right hand operand to left, and returns the left operand.Since you are assigning true to your variable, it evaluates to true. If you set your variable to false, you don't get the output, e.g:
bool x;
if(x = false)
printf("this won't be printed");
Here the equal affect the left operator with the value of the right operator then test the value. So the result must be the value of the right operator.
Your loop in is_prime will never run for the check x == i will be true, because it runs as long as x != i. Those two conditions are mutually exclusive.
That means the function will end without a return statement, which leads to undefined behavior.
This
if ( sieve[2] = is_prime(2) )
contains an assignment, not a comparison.
As the value of an assignment is the value assigned, it is true whenever is_prime(2) is.
However, let's look at your is_prime and see what happens if we pass it a 2...
bool is_prime(int x) {
unsigned int i,j,k;
So far, so good, but j and k are never used, so they shouldn't really be here.
if (x < 2) return false;
2 isn't less than 2, so we'll continue...
else {
for (i=2; i!=x; i++) {
OK, set i = 2, and compare it to x which is 2, and... oops, i is equal to x, so we'll abandon the loop immediately...
if (x == i) return true;
else if (x % i == 0) return false;
}
}
... and fall through here, where we're not returning a value like we promised, and causing undefined behaviour.
}
So, your program is undefined (you really should switch on compiler warnings, or start listening to them).
And this happens on every number that is prime.
You can rewrite the loop like this:
for (i=2; i <= x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
or
for (i=2; i < x; i++) {
if (x % i == 0) return false;
}
return true;
Why does if (is_prime(2)) appear to work?
(Since this code is undefined, the following is largely speculation and should only be taken with suitable measures of salt.)
Often, when a function is supposed to return something but doesn't, the calling function will just grab whatever is stored in the place where the return value should have been and use that.
This value is in this case very likely not the same as the bit pattern that represents true, so will compare unequal to true, in if (is_prime(2) == true).
It will however, also very likely, not be the bit pattern that represents false either, so will be considered true in a conditional, if(is_prime(2)).
I'm curious about how c++ handles this nested conditional operator. I'm half sure that I understand how this works, but I'm curious, could anyone explain through a diagram how the loop would execute the nested conditional operator.
For example would the loop execute through the first expression of each conditional operator for each instance?
Also is this nested conditional operator structured as:
(i < 2) ? x[i] : y;
!i ? y : x[1];
I guess I'm just very curious about the nature of this. Please don't answer unless you are capable of giving me a thorough adequate explanation of how the loop executes this conditional operator.
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
const char x[2] [20] = {" Cloud "," at your service\n"};
const char * y = "Strife";
for (int i = 0; i < 7; i++)
cout << (( i < 2)? !i ? x [i] : y : x[1]);
cout << endl << endl << x[0] << endl << x[1] << endl;
cin.get();
cin.get();
return 0;
}
It seems you are asking how an expression like x ? y ? 1 : 2 : 3 is parsed.
If you think about it there is really only one possibility. Namely, the : furthest to the right must bind to the ? furthest to the left. Thus the expression parses as:
x ? (y ? 1 : 2) : 3
So, if x and y are true, then 1 is returned; if x but not y is true, then 2 is returned; and if x is false, then 3 is returned.
Sorry to not answer directly in the context of your problem but I felt like it would be easier to follow this way.
When in doubt, spell it out...
for (int i = 0; i < 7; i++)
{
if (i < 2) {
if (!i) { // technically, this is "if i == 1"
cout << x[i];
} else { // and this is "if i == 0"
cout <<y;
}
} else {
cout << x[1];
}
}
Simply go through the statement. Everything before a ? goes in an if, then just open a { until we see a :.
The operator is not structured as you write. Maybe it is clearer with parentheses:
cout << ((i < 2) ? (!i ? x [i] : y) : x[1]);
Some good analysis already of what the conditional means. Just wanted to contribute a couple suggestions:
consider writing or reordering such expressions such that the ? and : alternate,
consider breaking them on to multiple lines with indentation reflecting their processing.
Either or both of these should make it easier to keep track of what they do.
Consider:
i < 2 ? !i ? x[i] : y : x[1] # somewhat confusing...
Just indenting to reveal processing precedence:
i < 2 // if just put ? and : beneath related condition
? !i // then if
? x[i] // then
: y // else
: x[1] // else
Or to simplify while keeping one-liner concision, try:
i >= 2 ? x[1] : !i ? x[i] : y # equivalent but simpler to "grok" (see below)
Expression ordered to alternate ? and : work like a simple if / else if / else if / else chain, so you can process and eliminate possibilities steadily as you work your way through.
if (i >= 2)
(value is) x[1]
else if (!i)
x[i]
else
y;
I sometimes write alternating conditionals across lines too:
std::cout << (i >= 2 ? x[1] : // "if condition1 then value1 else
!i ? x[i] : // if condition2 then value2 else
y); // value3"
...or sometimes (depending on the line lengths and visual complexity) going the whole hog and lining up the : beneath ?...
std::cout << (i >= 2
? x[1]
: !i
? x[i]
: y);
As with many stylistic aspects of C++ source code, picking a nice layout is a bit of an art - but experimentation is a good way to get a feel for it.