What does this warning mean (i and j are not constants):
I have been trying to Google this but it does not give me any results.
warning: comparison of constant 10 with boolean expression is
always true [-Wtautological-constant-out-of-range-compare]
if ((0<=i<=10)&&(0<=j<=10)){
In my program, i and j are not constant values and they do change.
In C, chaining of relational operators like this are not valid design. Thus,
(0<=i<=10)
is not doing what you think it should be doing. it is getting evaluated as
((0<=i) <= 10 )
which is basically either
0 < = 10, producing 1 (considered TRUE value)
1 < = 10, also producing 1 (considered TRUE value)
sadly, both of which are way out than the expected path.
Solution: you need to break down your condtion check like
(0 <= i) && ( i<=10)
The other answers have already explained the core problem. You can use:
if ( ( ( 0 <= i) && (i <= 10)) && ( ( 0 <= i) && (i <= 10)) )
to resolve your problem.
My recommendation will be to wrap that logic in a function.
int isInRange(int x, int lower, int upper)
{
return (lower <= x && x <= upper);
}
and use
if ( isInRange(i, 0, 10) && isInRange(j, 0, 10) )
I believe you need to understand what's going on in your statement at a deeper level.
0<=i is a boolean expression, it will become true or false.
The result of that expression is then compared with 10.
So you end up with true <= 10 or false <= 10.
I think you meant to write
if ( ( 0 <= i ) && ( i <= 10 ) )
You cannot connect clauses together the way you did.
It means that the expression can be evaluated at compile time, and that the evaluation will not be compiled because it's true (ie. non-zero) at compile time.
Usually this happened to me when I accidentally used && instead of &. Which is not the case here of course, but it gives the same error message.
Also note that gcc makes a distinction between logical and bitwise:
Logical means bool which is either 0 meaning false or non-zero meaning true and the operator that yields these is && with keyword and.
Bitwise means boolean logic and the operator is & with keyword bitand.
&& Always yields a bool, which is true unless it's 0. If operating on bools they're equivalent, but on anything else & and && test different things ie. "Is it nonzero" vs "return only the matching bits".
Related
According to my limited knowledge logical operators have left-right order of evaluation. By that rule it should evaluate x && y which is 1 and then it should evaluate == 1 in the if statement. But that is what not happening. Could anyone help me with this.
int main()
{
int x = 1, y = 2;
if (x && y == 1)
printf("true\n");
else
printf("false\n");
}
The order of operations is different than what you think.
Your expression is equivalent to
x && (y==1)
which is false in your case.
try this.
because of https://en.cppreference.com/w/c/language/operator_precedence
int main()
{
int x = 1, y = 2;
if ((x && y) == 1)
printf("true\n");
else
printf("false\n");
}
Try not to think about order of evaluation too much. It will often confuse you. The more important things to focus on is how the operators are grouped together and what the expression means.
The && operator has relatively low precedence. Almost any time you use it, it will have the form
if( condition_1 && condition_b )
and the interpretation is the obvious: "if condition_a is true and condition_b is true".
In your case, condition_a is just x, and condition_b is y == 1. So the interpretation is "if x is true and y equals 1".
What does it mean for x to be true? Simply that it's not zero. So we could expand this further: it's as if you had written
if ( x != 0 && y == 1 )
and the interpretation is "if x is not equal to 0 and y is equal to 1".
Remember, precedence says how the operators are grouped together. In your case, it's as if you had written
if ( x && ( y == 1 ) )
The == 1 part goes with the y. == binds more tightly than &&.
In terms of "order of evaluation", you can say that, yes, the compiler emits code that figures out whether x is true, and code that figures out whether y is equal to 1, before it uses && to determine whether they're both true. In the case of &&, we also know that it will decide whether x is true before it decides whether y is equal to 1. (But this is a rather special property of the && and || operators. It does not apply to most of the rest of the more ordinary operators like + and /.)
Because y == 1 is false as y = 2, written before if statement.
It does not evaluate they way you think. It evaluates x and then y == 1 and then &&, which is in your case in 1 && 0 and you have false result.
Here
if (x && y == 1)
above statement is equivalent to
if(x && (y==1) ) /* y==1 performed first, which is false */
As you can see here https://en.cppreference.com/w/cpp/language/operator_precedence
You want to get true as output, then first perform x&&y by keeping ().
if ( (x && y) == 1) { /* now () has higher precedence, so it perform x&&y first which results in true(1) and then 1==1 results in true */
}
else {
}
This is because of operator precedence.
Because of operator precedence the expression if (x && y == 1) results in if (x && (y == 1)).
So, the whole expression results to false because y==1 is false.
Use parenthesis and change it to if ((x && y) == 1) to get desired result.
I've a C university exam coming up next week and i was looking at old exam papers a one of the questions gives this fragmented bit of code.
int a=2, b=-1, c=0;
if (a-2||b&&c||a){
printf("True\n");
} else {
printf("False\n");
}
We have to determine what the output of this code will be but the if statement makes no sense to me any if statement I've come across has been very specific like saying
if( x == 0)
I don't know what this is looking for my only assumption is that its going to be always true. Am I right or is there more to it then that?
This assignment has two goals:
to show what booleans are in C: Essentially they evaluate to ints with false mapping to 0 and true mapping to 1. In turn, any numeric or pointer value can be used in an integer context, with the respective zero value (0, 0.0, NULL (pointer), 0.0f, 0L etc.) evaluating as false and all others as true.
to show the precedence of operators
&& has a higher precedence than ||, so this statement is equivalent to
a-2 || (b&&c) || a
which will evaluate to true if any of the values is true.
As a==2, a-2 is 0. c is 0, so b && c is 0 as well.
So we have 0 || 0 || a, which is true as a is 2.
Most languages interprets non-zero integers as true and zero as false, so here you would have to calculate each one of the terms. Without any parenthesis, I would suggest that the && statement is taken in account first. So we have:
if (2-2 // gives zero
|| // OR
-1 && 0 // -1 AND 0 gives false
|| // OR
a) // Which is 2, which is true
So you're right, this statement is always true. This exercice was about showing predecence orders, and the fact that everything is numerical, even in boolean logic.
This is really important for you to understand.
If the predecence was the other way around (|| > &&), you must understand that it would have been false instead. I think this example's whole point is here.
(a-2 || b) && (c || a)
false && true
--> false
You need to understand that truth and falsity in C is always numerical.
https://www.le.ac.uk/users/rjm1/cotter/page_37.htm
Namely, anything that evaluates to numerical zero is false, and anything that evaluates to numerical non-zero is true.
In c language integers 0 is treated as false and any non-zero integer value is true but it should be noted that it is language specific and the sme statement will show compilation error in java as java is more strict and integers are not converted to booleans.
Talking about the above assignment problem the expression inside if statement will evaluate to true as
(a-2||b&&c||a) is same as
(2-2||-1&&0||2) which is same as
(0||0||2) which is evaluated as
(false||false||true) and hence the entire expression evaluates to
true.
hope it helps.
int a=2, b=-1, c=0;
int first=a-2; //0 -> false
bool second= b&& c; // nonZero&&zero -> true&&false -> false
int third = 2; // nonZero -> true
// false|| false|| true -> true
if (first || second || third ){
printf("True\n");
} else {
printf("False\n");
}
you need to understand two things before solving this problem that is
operator precedence and
associativity of operators
operator precedence tells c compiler that which operation to perform first.
and if two operators have same precedence than associativity tells evaluate left to right or right to left in you expression
int a=2, b=-1, c=0;
if (a-2||b&&c||a){
you can think it as
if((a-2)||(b&&c)||a){}
means - has top precedence so it will solved first
reduced to if(0||(b&&c)||a){}
then && has higher precedence so
reduced to if(0||false||a)
then the associativity is left to right so
reduced to if(false||a)
that is(false||2)
return true
In almost every programming language as far as I know 0 means false and 1 means true.
So coming up to your question: you have used && and || operators. Both of these are called Logical operators.
Now first block of yours is a-2||b :-
2-2||-1 so 0||-1. Now since the right expression of || is -1 the or operator will return 1 i.e. True because one of the values of 0 and -1 is non-zero 0 i.e. -1.
Therefore the expression resolves to 1&&c||a :-
Now c=0, therefore 1&&0 returns a 0 because && will only return 1 if both the expressions right and left of it are non zero.
So expression becomes 0||2 :-
Now since || (or operator) requires only one of operands either on right or left side to be non zero hence 0||2 returns 1.
Now your if (a-2||b&&c||a) statement resolves to
if (1)
{
printf("True\n"); }
else......
Therefore since 1 means TRUE the if statement will execute and you will get output as True.
Can anyone help me?
Is there any difference between
if (!n / 10)
return;
and
if (n / 10 == 0)
return;
Yes, the two statements are different. !n / 10 is equivalent to (!n) / 10 and n / 10 == 0 is equivalent to !(n / 10).
Operator ! has higher precedence than that of / operator and therefore n will bind to ! first in !n / 10.
As #Kerrek SB pointed in his comment, !n will evaluated either to 0 or 1 so, the expression will always be false.
This statement
if (!n / 10)
return;
is equivalent to
if ( ( !n ) / 10)
return;
According to the description of the operatpr (6.5.3.3 Unary arithmetic operators)
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0. The result has type int. The expression !E is
equivalent to (0==E).
Thus if n is equal to 0 then expression ( !n ) / 10 equal to expression 1 / 10 and as the both operands are integers then the result is equal to 0.
If n is not equal to 0 then expression ( !n ) / 10 equal to 0 / 10 and its result again equal equal to 0.
So the original expression is equivalent to
if ( 0 ) return;
It means that the return statement will be executed never.
As for the second statement
if (n / 10 == 0)
return;
when n is less than 10 then result of n / 10 (provided that n is integer) will be equal to 0 and you will get
if ( 0 == 0 ) return;
So the return statement in the second if statement will be executed when n is less than 10.
You're asking this because maybe you are not clear about how if statement works. So, let me explain it first.
The syntax of if statement is
if( expression )
{ procedure to follow }
Here expression to be used should be a logical one that it should result in true or false. Whenever the expression will result in true, the if statement is executed and vice-versa.
Another concept is that if the expression will result in 0 (false), the if statement will not get executed.
Now when you use if( n/10 ) , for n = 123, n/10 will result in 12 (the statement uses integers hence the result). Since it is not 0, it is treated as a true and the if statement will execute and n will be returned according to your code. Now n/10 doesn't change n, hence n(=123) will be returned and printed.
Now let's see about if( n/10 == 0 ) . For the first time when n=123 is n/10 will be 12 which is not equal to 0. So, here a false is generated and the if statement is not executed unlike the previous one.
According to your desired logic you should use if( n/10==0 ).
#include <stdio.h>
#include <string.h>
main()
{
int i=-1, j=-1, k=0, l=2,m;
m = i++&&j++&&k++||l++;
printf("%d%d%d%d%d", i, j, k, l, m);
}
Output:
00131
I am confused how the expression is getting evaluated.
All that really matters here is the ||. Since l++ evaluates to the boolean 1 (true), the entire statement is true. So m is 1, and the rest are just their original values plus one for the post increment after they are evaluated.
You're evaluating the boolean expression:
((-1 && -1) && 0) || 2
As an aside, your definition of main should be:
int main(void)
I presume your question is about which increments will actually occur.
&& and || (logical and and logical or) are "short-circuit" operations. They evaluate only enough of their arguments to determine whether they're true or false. Effectively, x && y can be treated as x ? y : 0 and x || y can be treated as x ? 1 : y
&& takes precedence over ||, so start by looking at i++ && j++ && k++. This starts by evaluating i++, returning -1 and setting i to 0. Since the returned value is true (nonzero), we continue by evaluating j++, which once again returns -1 (true) and increments j to 0. We still haven't proven the value of the &&, so we evaluate k++, which returns 0 (false) and increments k to 1. That false gives us a final anded value of false.
Now we proceed to the ||. Effectively, you now have false || l++. The false is not enough to determine the result of the or, so we evaluate l++. That returns 2 (true), while setting l to 3. That true forces the value of the ||, and the final value of the expression, to be true.
Note that if i, j, or k had started as 0 (false), the later increments would not have occurred, since short-circuit evaluation would have decided they weren't needed in order to produce a result. In general, mixing && or || with side effects is a bad idea for exactly this reason -- it produces logic that is needlessly hard to understand. The ?: versions -- or a real if/then/else statement -- would make this interaction much, much clearer. You should understand how to read this sort of mess, because you will run into it in other programmers' C code -- but you should almost never write it. And if you must, you should document it to death. The sanity you save may be your own.
use this rules:
i++ =post increments the value of i, k++ =post increments the value of k, l++ =post increments the value of l, j++ =post increments the value of j
&& - if values compared are both nonzero true(1) otherwise false(0)
|| - if values compared are both zero false(0) otherwise true(1)
then apply towards expression m (also read on operator precedence in c)
I understand a condition is supposed to be for example y==3, but y-3 is totally confusing to me. I can't understand this code. If y-3 is true it prints 1. How can y-3 be true or false?
The expression y - 3 results in a value which can be tested for truthness. In C 0 is false and any non-zero value is true. Saying if (y - 3) is essentially saying if (y - 3 != 0) or even more succinctly if (y != 3)
In C, everything what's 0 is false and everything what's non-zero is true.
When tested directly into a boolean context, integers can be evaluated like this.
0 is equivalent to false and all the other values are considered true.
In your code y - 3 will be equivalent to false only if y - 3 == 0, that is if y is 3.
A better style would be to write:
if (y - 3 != 0)
Or even:
if (y != 3)
if (E)
where E is an expression is equivalent to
if (E != 0)
In an if statement (or any statement with a condition), the condition is considered true if it's unequal to zero, false otherwise.
So this:
if (y - 3)
is equivalent to this:
if ((y -3 ) != 0)
which can (and should!) be re-written as:
if (y != 3)
The == operator, for example, yields an int value of either 1 or 0.
C does have a built-in Boolean type (called _Bool, introduced by the 1999 standard), but it didn't always exist, and it's not used in conditions. Of course you can use a _Bool value as a condition, but it's still tested (at least conceptually) for inequality to zero.
First, the expression 'y-3' will be evaluated. If the result is 0 (a.k.a, the value of y is 3), then the expression will evaluate to false, and the value "2" will be printed. If y is equal to any value other then 3, the condition will evaluate to true, and the value "1" will be printed
This would mean exactly the same
if ((y - 3) != 0)
printf("1");
else
printf("2");
So that's going to be true if it's not zero.