This question already has answers here:
Short circuit evaluation and side effects [duplicate]
(3 answers)
Closed 8 years ago.
int i=-1,j=-1,k=0,l=2,m;
m=l++||i++ && j++ && k++;
printf("%d %d %d %d %d",i,j,k,l,m);
Output of the code is: -1 -1 0 3 -1
My question is why i++ j++ and k++ is not being evaluated even when && has a higher priority over || ?
See
Short-circuit evaluation.
Essentially what's happening is that as l++=3 which is not 0, it evaluates to True (only 0 would be False). Thus, the second part of the expression after || is not evaluated.
Think
m=l++||i++ && j++ && k++;
as
m = ( (l++)|| ( (i++ && j++) && (k++) ) );
As you know && has higher operator precedence, therefore i++ && j++ && k++ will be grouped as (i++ && j++) && k++ and then ( (i++ && j++) && (k++) ).
Because of the short-circuit behavior of ||, after evaluating l++, which is true and therefore the right operand ( (i++ && j++) && (k++) ) of || is not evaluated.
Related
I understand the basic concept of short-circuiting with operators, but why does
int i = 0, j = -1, k = 1, m;
m = !(i++ && ++j) || ++k;
printf("%d %d %d %d", i, j, k, m);
have 1 -1 1 1 as an output? Specifically, why is j == -1 instead of 0?
I know similar questions have been already asked, but I don't understand this specific example which I didn't find anywhere.
i = -1;
i++; // value of expression is -1
// side effect is changing i to 0
if (i++) ; // value of `i++` is zero; the if will not "trigger"
i = 0;
if (i++ && foo) ; // i++ has value of zero (false)
// so false && <anything> is false
// so foo is not evaluated
int i = 0, j = -1, k = 1, m;
!(i++ && ++j) || ++k; ==> only i++ will be evaluated, j and k will not be evaluated
lets just say we are substituting the values of variables, then the expression becomes as below.
!(0 && ++ -1) || ++1
step 1:
!(0 && ++ -1) ==> for && operator if left side operand is False then we dont need to check for right side operand, so -1 wont be incremented, so value of j will be -1 itself.
and hence the left side expression before || becomes !(0)
step 2:
!(0) || ++1
now !(0) will be 1 , so for || operator if left side operand is TRUE , then no need to go for right side operand, then ++k will not be executed.
m = 1 || ++1 ==> 1
since only i++ is evaluated , it will change its value to 1
so the out put is : 1 -1 1 1
The value of the postfix increment operator is the value of its operand before incrementing.
So the value of the expression i++ is equal to 0 because the variable i was initialized by 0.
So as the value of the sub-expression i++ is 0 then the sub-expression ++j in this expression
(i++ && ++j)
is not evaluated and the value of the expression itself is 0.
Applying the negation operator
!(i++ && ++j)
you will get 1 (logical true). So the sub-expression ++k of the expression
!(i++ && ++j) || ++k
will not be evaluated.
As a result the value of the whole expression is equal to 1 that is assigned to the variable m.
m = !(i++ && ++j) || ++k;
On the other hand as it was pointed out in the beginning the expression i++ was evaluated. So after this statement i will be equal to 1.
This question already has answers here:
Chaining multiple greater than/less than operators
(6 answers)
Closed 6 years ago.
im having trouble using multiple operators while programing a simple FizzBuz in C
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
if (0 < n < 10000){
for (int i = 1; i <= n; i ++) {
if (i % 15 == 0) {
puts("TikTak");
}
else if (i % 3 == 0) {
puts("Tik");
}
else if (i % 5 == 0) {
puts("Tak");
}
else {
printf("%d\n", i);
}
}
}else{
printf("-1");
}
}
Now the "if (0 < n < 10000)" comparison operators is ignored for some reason, but if I rewrite it as:
if (n < 10000 && n > 0){
it will work as intended.
Am I missing something? Ill be honest Im newbie in C programing. haha
EDIT: Thanks everybody, haha that was quite simple. I thought that might be the issue I just waned to make surebecause "0 < n < 10000" is litteraly how the assigment says it should look like.
Again, thanks!
Rewrite this condition
if (0 < n < 10000){
like
if (0 < n && n < 10000){
Otherwise the original condition looks like
if (( 0 < n ) < 10000){
and the result of the expression 0 < n is either 1 or 0. So in fact you are comparing 0 or 1 with 10000.
From the C Standard (6.5.8 Relational operators)
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.
The expression 0 < n < 10000 is equivalent to (0 < n) < 10000 which means you check if 0 < n is less than 10000, which it will always be (the result of a comparison like 0 < n will be zero or one).
I was solving some problems related to "or" operators in C.
The body of the program was like what mentioned below:
#include<stdio.h>
main() {
int i = 4, j = -1, k = 0, w, x, y, z;
w = i || j || k ;
x = i && j && k ;
z = i && j || k ;
printf("\n w=%d , x = %d", w, x);
printf("\n y=%d , z = %d", y, z);
}
Can someone please tell me the mechanism of these statements?
These are binary operators, they take two arguments. When confronted with a more complicated expression you can break it down into sets of binary operations.
For example, z = i && j || k; could be written as z = ( (i && j) || k ). Or in pictorial form:
z
=
||
/ \
&& k
/ \
i j
To know that the tree has this layout we look up operator precedence (or language grammar rules), the rule is that to choose between && and ||, the || is the 'outer' operation (i.e. lower precedence).
These operators also do short-circuiting, although that is not relevant in this particular example.
So, looking at the above table, i && j gives 1 because both i and j are non-zero. The 1 || k gives 1 because at least one of the operands is non-zero. Finaly 1 is assigned to z.
You can find the right values for w and x in a similar way, using the precedence rule that the left-most && is the inner one, when the situation is a && b && c, and similarly for ||.
the || and && operators are logical operators, which means they evaluate the numbers as either 'true' or 'false'
In that sense, i and j are 'true' and k is 'false'. So, calculating the outcome:
w = 'true' or 'true' or 'false' = true = 1
x = 'true' and 'true' and 'false' = false = 0
z = 'true' and 'true' or 'false' = true = 1
y isn't defined and will contain 0 or garbage
--edit--
note that && and || are left to right operators, therefore the first operator is always evaluated first.
PROGRAM
#include <stdio.h>
int main(void)
{
int i, j, k;
i = 1; j = 1; k = 1;
printf("%d ", ++i || ++j && ++k);
printf("%d %d %d", i, j, k);
return 0;
}
OUTCOME
1 2 1 1
I was expecting 1 1 2 2. Why? Because the && has precedence over ||. So I followed these steps:
1) j added 1, so j now values 2...
2) k added 1, so k now values 2...
3) 2 && 2, evaluates to 1...
4) No need of further evaluation as the right operand of || is true, so the whole expression must be true because of short circuit behavior of logical expressions...
Why am I wrong?
Precedence affects only the grouping. && has a higher precedence than || means:
++i || ++j && ++k
is equivalent to:
++i || (++j && ++k)
But that doesn't mean ++j && ++k is evaluated first. It's still evaluated left to right, and according to the short circuit rule of ||, ++i is true, so ++j && ++k is never evaluated.
I have to write if statement for structure for person which:
Is older or equal 16 and younger or equal 20
First letter of name and surname must be 's' or 'n'
My code:
if(x.name[0]=='s' ||
x.name[0]=='n' &&
x.surname[0]=='s' ||
x.surname[0]=='n' &&
(x.age>=16 && x.age<=20))
{
/* print person */
}
I want just to print out these persons, but code prints non-compliant ages.
What is wrong with the condition?
Enclose each || section in brackets. Keep in mind && has higher priority than ||. Like so:
if((x.name[0]=='s' || x.name[0]=='n') &&
(x.surname[0]=='s' || x.surname[0]=='n') &&
(x.age>=16 && x.age<=20))
Splitting the code on several lines is not needed it just makes the code more readable.
This should work:
(x.name[0]=='s' || x.name[0]=='n') && (x.surname[0]=='s' || x.surname[0]=='n') && (x.age>=16 && x.age<=20)
Additional pair of () added. Also, You know that such a cumbersome statements are considered to be a really bad practice?
Your missing parenthesis around the name and surname conditions
if((x.name[0]=='s' || x.name[0]=='n') && (x.surname[0]=='s' || x.surname[0]=='n') && (x.age>=16 && x.age<=20))
On seeing the statement
if(x.name[0]=='s' ||
x.name[0]=='n' &&
x.surname[0]=='s' ||
x.surname[0]=='n' &&
(x.age>=16 && x.age<=20))
compiler interpret it as
if(x.name[0]=='s' || (x.name[0]=='n' && x.surname[0]=='s') ||
(x.surname[0]=='n' && x.age>=16) && x.age<=20))
The reason behind this is, logical operator && has higher precedence than that of logical || operator. What does it mean then?
It means that the expression (sub-expression) get bound more closely to && than that of ||.
Take a small example to understand this
#include <stdio.h>
int main(void)
{
int i = 1, j = 1, k = 1;
printf("%d ", i++ || ++j && ++k);
printf("%d %d %d", i, j, k);
return 0;
}
The output of this program is:
1
2 1 1
On first look a novice may think that the output is wrong and it should be
1
2 1 2
by thinking that i++ || ++j && ++k is same as (i++ || ++j) && ++k but this is not true. Because of the higher precedence of && over ||, sub-expressions j++ and k++ bound to && and it will be interpreted by the compiler as i++ || (++j && ++k)