Comparing three integer variables in one if condition (C) [duplicate] - c

This question already has answers here:
Why is a condition like (0 < a < 5) always true?
(4 answers)
Closed 9 years ago.
I have this question & in the answer it says that due to left to right associativity the result would be 1 that is true for this statement. This is the code.
#include<stdio.h>
int main ()
{
int i=0,x=10,y=10,z=5;
i=x<y<z;
printf("\n\n%d",i);
return 0;
}
But x is greater than z here so how is this happening ?

The expression x
(x < y) < z
so it becomes
(10 < 10) < 5
which further is evaluated into
0 < 5
which is true.
I think you wanted something like this:
x < y && y < z

Because of operator precedence and associativity
i = x < y < z;
is parsed as:
i = ((x < y) < z);
After substituting the variable values, this becomes:
i = ((10 < 10) < 5);
Since 10 < 10 is false, this becomes:
i = (0 < 5);
Since 0 < 5 is true, that becomes:
i = 1;

x<y<z is not a single valid expression. Instead it evaluates x<y first (operator precedence is done left to right here) as true/false (false in this case as they're equal), converts it to an int value of 0, and then compares this value with z.
Use (x < y && y < z) instead.

It first evaluates x < y which is false (0), then 0 < z which is true (1).

WHat C compiler does is, in x<y<z;
starts from left, so as x is not less than y therefore it replaces that expression with '0'
so it becomes 0<z and as that is true. it set the variable to 1.

Related

Printf even though it shouldn't

I have this part of an if statement and I'm getting a weird output.
int x = 10;
if(1 < x < 5){
printf("F\n");
}
Why does it print "F"? Logically isn't the if statement false because x is greater than 1 but not less than 5?
In C, you can't chain comparisons like that. The expression 1 < x < 5 is evaluated as (1 < x) < 5: so for x = 10, the expression is (1 < 10) < 5. (1 < 10) is true, which C represents as the value 1, so the expression reduces to 1 < 5. This is always true, and your printf() if executed.
As level-999999 says, in C you need to explicitly combine single comparisons with && and ||.
If you are using C, you should have broken down the condition into two arguments :
if ( x > 1 && x < 5) {
printf("F\n");
}

Why is this output of this basic C program?

Let me be judged as a Noob in programming, I have been learning obfuscated way of programming in c/c++, as the c compiler compiles a statement from the right hand side towards the left hand side.
I have the following code:
int main(){
int x=5, y=20, z=1;
int k = x > y < z;
printf("%d", k);
return 0;
}
The output returned is 1, Does this means that
x > y < z = (x>y) < z
or
x > y < z = x > (y<z)
I would love if someone would give me link to work on these skills.
Thanks and Regards.
Change z=-1 or x=0 and find out. Also change int main() to the more correct int main ( void )
Changing z = -1 will ouput 0, whereas k will be 1 if you assign it x > y == z if z = 0. So in short:
k = x > y < z;
is the same as writing
k = (x > y) < z;
left-to-right.
According to the C grammar (6.5.8 Relational operators)
1 relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
1 The relational operators group left-to-right (C++ Standard :) )
And
6 Each of the operators < (less than), > (greater than), <= (less than
or equal to), and >= (greater than or equal to) shall yield 1 if the
specified relation is true and 0 if it is false.107) The result has
type int.
Thus the initializer in this declaration
int k =x>y<z;
is equivalent to
int k = ( x > y ) < z;
As x is less than y then expression x > y yields 0 and as z is greater than 0 then the full expression yields 1.
The following operators have right-to-left-grouping:
unary operators
conditional operator
assignmnet and compound assignment operators
First you have to check operator precedence, which is easiest by looking at an operator precedence table. If such a table is decent, it will list the operators > and < in a group called relational operators. All operators in this group have the same operator precedence.
Since the operators > and < have the same precedence, the order in which the operands will get processed is determined by the associativity of that group of operators. For the relational operators, this is left-to-right. Therefore the expression is guaranteed to be processed as (x > y) < z
In C the boolean values are numerical values, so:
false -> 0
true -> != 0, hence any number that is not 0 will represent the boolean true.
So in case of your code:
int k = x > y < z;
can be split in the following way:
int k = (x > y) < z;
that will be:
int k = ( 5 > 20) < 1;
the first part evaluates to false (0 that is) then the equality will loook this way:
int k = 0 < 1;
which is true, hence
int k = 1;
k = ( 5 > 20 ) < 1= False (0)
k = (0 < 1) = True (1)
printf (%d, k) = 1
Maybe you should know the Operator precedence and associativity. You can google or see the book <<c++ primer>>. First the operator > and < have a same precedence. Then we should use the associativity, there the operator only have left associativity. So the answer is x> y< z= (x>y)<z). I hope this can help you. Remember: 1. precedence; 2. associativity.

If statement doesn't stop execution. C programming

I'm very new to this, and i'm trying to create a text based minesweeper.
I want the player to decide how big he want the grid to be.
My problem is, that the if-statement, that should make sure, the user types in a number from 1 to 10 doesn't work. Please have a look.
scanf ("%i/%i",&x,&y);
if (0 < x < 11 && 0 < y < 11)
{
printf ("you have selected %i by %i\n",x,y);
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
grid[x][y] = 'O';
printf ("%c ", grid[x][y]);
}
printf ("\n");
}
}
else
printf ("Wrong gridsize");
C does not support double comparisons like:
0 < x < 11
you should write instead
0 < x && x < 11.
It may be misleading, because the first statement is syntaxically correct (it compiles), but it does not do what you may believe: check both boundaries like in a mathematical expression (what python does for instance).
It's like if you had written
(0 < x) < 11
The first binary expression returns a boolean (well, really an int in C, a boolean in C++). This boolean once casted to int is 0 or 1, always below 11, henceforth the expression is always true.
Of course the same is true for checking y boundaries. Now you should be able to fix the problem by yourself.
The if statement has to be like
if ((x > 0 && x < 11) && (y > 0 && y < 11))
you have written wrong if statement.
Here is correct form.
if ((x > 0 && x < 11) && (y > 0 && y < 11))
Here are the relational operators
> greater than 5 > 4 is TRUE
< less than 4 < 5 is TRUE
>= greater than or equal 4 >= 4 is TRUE
<= less than or equal 3 <= 4 is TRUE
== equal to 5 == 5 is TRUE
!= not equal to 5 != 4 is TRUE
C does not support double comparisons.
In your scanf statement remove / operator change it to
scanf ("%i%i",&x,&y);
And what your if statement is doing is what you expect to do
if (0 < x < 11 && 0 < y < 11)
first when you enter the value x and y (x = 4 and y = 6)
It checks if x is greater than 0 (which is true ) so 1 is substituted in place of 0 < x
now its something like this for compiler 1 < 11
next it checks that which is also true
similarly for y whichever value you enter will always be true.
0 < x < 11
means
(0 < x)<11. If x is 5, 0 < x will be 1 (true). Next evaluation will be 1 < 11, that will be true so the result is true.
But, if x = 20, 0<20 is 1, 1<11 is true as well, but you would expect a false result.

if x=10 y=10 z=5 how is x<y<z=true? [duplicate]

This question already has answers here:
Why is a condition like (0 < a < 5) always true?
(4 answers)
Closed 9 years ago.
I have this question & in the answer it says that due to left to right associativity the result would be 1 that is true for this statement. This is the code.
#include<stdio.h>
int main ()
{
int i=0,x=10,y=10,z=5;
i=x<y<z;
printf("\n\n%d",i);
return 0;
}
But x is greater than z here so how is this happening ?
The expression x
(x < y) < z
so it becomes
(10 < 10) < 5
which further is evaluated into
0 < 5
which is true.
I think you wanted something like this:
x < y && y < z
Because of operator precedence and associativity
i = x < y < z;
is parsed as:
i = ((x < y) < z);
After substituting the variable values, this becomes:
i = ((10 < 10) < 5);
Since 10 < 10 is false, this becomes:
i = (0 < 5);
Since 0 < 5 is true, that becomes:
i = 1;
x<y<z is not a single valid expression. Instead it evaluates x<y first (operator precedence is done left to right here) as true/false (false in this case as they're equal), converts it to an int value of 0, and then compares this value with z.
Use (x < y && y < z) instead.
It first evaluates x < y which is false (0), then 0 < z which is true (1).
WHat C compiler does is, in x<y<z;
starts from left, so as x is not less than y therefore it replaces that expression with '0'
so it becomes 0<z and as that is true. it set the variable to 1.

Control Instructions in C

I am not understanding for loop statement and expression following it. Please do help me understand.
#include<stdio.h>
int main()
{
int x = 1;
int y = 1;
for( ; y ; printf("%d %d\n",x,y))
y = x++ <= 5;
return 0;
}
And the output I got
2 1
3 1
4 1
5 1
6 1
7 0
y = x++ <= 5; ==> y = (x++ <= 5); ==> first compare x with 5 to check whether x is small then or equals to 5 or not. Result of (x++ <= 5) is either 1, 0 assigned to y,
As x becomes > 5, (x++ <= 5) becomes 0 so y = 0 and condition false and loop break,
Basically the for syntax is:
for(StartCondition; Test; PostLoopOperation) DoWhileTestPasses;
In this case:
StartCondition == None
Test == (y != 0)
PostLoopOperation == do some printing
DoWhileTestPasses == set y to zero if x > 5 otherwise to non-zero THEN increment x.
Which is all rather bad practice because it is confusing.
Would be better written as:
int x=0;
int y=0;
for(y=0; y = (x <= 6); x++)
{
printff("%d %d\n",x,y);
}
return(0);
In y = x++ <= 5;, y stores the value that is output by the condition x++ <= 5 (here x++ is post increment). If the condition is true then y = 1 else y = 0.
for( ; y ; printf("%d %d\n",x,y))
In the for loop you are printing the values of x and y after executing the for loop body.
Initialize your variables:
int x = 1; int y = 1;
There are 3 statements for the for loop: -1. Initialize, 2. Condition, 3. Iteration:increment/decrement
In your case, you did not provide the initialize condition, however, you have the part of condition and incrementation. I do not think your for loop is used in the correct way.
You should swap the part of incrementation with your body like this:
for(; y; y = x++ <= 5;)
printf("%d %d\n", x, y)
First, you check whether the condition is true or not, y is true or not. Then, you print x and y out. Then, the part of incrementation is executed, x++ <= 5 or not. The result is assigned to y. It does so until your condition is false, y == false.
NOTE: For the good programming, you should enclose your body with a curly braces.
similar to this
int x = 1;
for( int y = 1; y!=0 ; )
{
if (x++ <= 5)
{
y = 1;
}
else
{
y = 0;
}
printf("%d %d\n",x,y);
}
Perhaps this slightly transformed (but functionally equal) code will help:
int x = 1;
int y = 1;
while (y) {
y = (x <= 5);
x = x + 1;
printf("%d %d\n", x, y)
}

Resources