Can't understand this if statement - c

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.

Related

What is the order of evaluation of the statements in this code?

I came across this question.
#include <stdio.h>
int main()
{
int k=8;
int x=0==1||k++;
printf("%d %d",x,k);
return 0;
}
The output is 1 9.
As this answer suggests that
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
I am unable to understand how the statement int x=0==1||k++ is evaluated,due to which the value of x and k becomes 1,9 respectively.
Can someone explain how such statements are evaluated by the compiler in c ?
"Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated."
yes it's true ...
to make it clear first make sure that you are aware of these basics
1) (1 || any_var) is 1
2) Operator precedence is as follows
++
then
==
then
||
NOW coming to your doubt of || vs |
note that | (single pipe) operator ..,will execute both LHS and RHS , no matter what)
whereas
|| (double pipe) evaluates LHS of || first and if it is 1 it need not evaluate RHS (for speed)
RHS of || operator will not be evaluted if LHS comes out to be true.
but here 0==1 is false i.e 0==1 returns 0
hence RHS will be evalauted
so the statement
k++ is executed
but 8 is used (as property of post increment operator says--> first use then increment)
so 0||8 is definitely true (1) so x evaluates to 1
and then k is incremented after sequence point ie k is made equal to 9
hence output x=1 and k=9
I hope it clears your doubt :)
The Operator || (OR) evaluates to true in the cases:
ex: A || B
A is true,
B is true,
Both are true
Because this operation uses Short-Circuit Evaluation if A is evaluated to true, it means that the statement is true already and it won't evaluate B.
In your case 0==1 (0 equals 1) is clearly false, so it will evaluate k++. k++ is a tricky one (in my opinion). In the world of C true/false evaluation is based on being 0 or not (except for the times false means less than 0...) but in true/false evaluation 0 is false, everything else is true.
K++ means evaluate K then increment, so, if K is 0 it will be false and become 1, if it is anything else, it will be true and then increment.
In your case k == 8 so the result of k++ is TRUE and k will become 9. K being true means x evaluation resulted in TRUE (it was FALSE OR TRUE).
So the output is 1(True) 9(8++)
x is 1 because the expression: 0==1||k++ turns out to be true (which is 1 in C land). Why you ask? There are two sequence points here: 0 == 1 and k++. Since the first sequence point evaluates to false (0 in C land), the second sequence point is evaluated (because the short circuit operator is ||). The second sequence returns true (or 1). So, you the entire expression breaks down to: 0 || 1. Hence x is 1.
k is 9 because of k++;
HTH.

Logical operator with Arithmetic operator in C

I came across a question and I wanted to verify whether my assumptions were correct.
Given the following codes:
1. int i = -2, j = 1, ans;
2. ans = i++ || ++j;
3. printf("%d %d %d", i,j, ans);
The output is: -1 1 1
In C language, it seems that only 0 will be treated as false, any other values will be treated as true when used with a logical operator. So I am not doubtful why ans derives to 1 (true || true gives us true(1) )
What I wanted to ask here is: Why is the value of j still 1 and not 2 despite ++j?
Can safely assume that any arithmetic operations after the logical operators || && will only be effective at the line it is used(in this case, line 2), and after which the variable still retain its original value?
|| operator wont do any operation on second operand when first operand is nonzero.
Because, any one of the operand is non-zero then, output will be true in || operator operation. In your code 1st operand is non-zero. Thats why operation on second operand is not performed.
As in Second Line of your Code i.e
ans = i++ || ++j;
first it will check i++ as it is not zero that means it is true.
And in OR Condition if first condition is true it will not check second condition i.e ++j.
Because if first condition is true is doesn't matter, Second condition is TRUE or FALSE it will return a true value. So if First Condition is true it will not check the other condition.
Logical operators short circuit. That is, in the following:
ans = i++ || ++j;
++j will never be evaluated if i++ evaluates to true (non-zero).

Little detail about using operator "or"

Consider this code:
int a = 5;
if (a == 5 || a == 10)
doSomething();
In this case a is 5 so the first condition is true. Will the program check if the second condition is true or it will start executing doSomething() immediately after it makes sure that a is really 5?
It will start executing immediately. This is known as short-circuit evaluation.
http://en.wikipedia.org/wiki/Short-circuit_evaluation
The second condition won't be checked. C short-circuits logical evaluations, so as soon as the truth or falsehood of the condition can be determined it stops.
Note that given the code as posted, the compiler might not even generate code to perform the first comparison as it can determine at compile time that the condition is satisfied and no intervening code could alter the value of a.
Share and enjoy.
int a = 5;
if (a == 5 || a == 10)
doSomething();
in this example the left operand operand of || is evaluated to 1 so the right operand will not evaluated.
The compiler is required to not evaluate the right operand of || operator when the left operand is evaluated to 1.
When it comes to the logical operations, the compiler will stop evaluating the expression as soon as its finds the truth or falsehood of the expression.
The truth-table for logical or (||) operation is as follows:
A B A||B A&&B
0 0 0 0
0 1 1 0
1 0 1 0
1 1 1 1
So for an expression like a == 5 || a == 10, when a is equal to 5, the expression will be evaluated to true when the compiler sees a == 5 part. So irrespective of whether the rest of the expression is evaluated to true or false, due to the logical or (||) operator (refer the above truth-table), this expression will be evaluated to true. So the compiler will discard executing the rest of the expression.
Any decent compiler will not even check the first condition since at compile time it knows at once that it should invoke your method. (but of course all comments about short circuit hold true - but not here ;-)

I am getting a strange output in C?

Here is a c program.I am getting a strange output.
When num1=10 and num2=20->
#include<stdio.h>
void main()
{
int num1=10,num2=20;
clrscr();
if(num1,num2)
{
printf("TRUE");
}
else
{
printf("FALSE");
}
getch();
}
Output:
TRUE
when num1=0 and num2=220
Output:
TRUE
But when num1=0 and num2=0:
Output:
FALSE
Why does this happen?
also,what does this given below code mean:
if(num1,num2)
Thanks in advance!
You're using the comma operator. That operator first evaluates its first operand, then drops the result on the floor and proceeds to evaluate and return its second operand.
That's why your program only prints FALSE if num2 evaluates to false in a boolean context (like e.g. 0, 0.0 or NULL).
In:
if(num1,num2)
the last expression overrides all preceeding ones so it's the same as:
if(num2)
since, num2 is 0, you get FALSE.
If you check this out,
http://msdn.microsoft.com/en-us/library/2bxt6kc4(v=vs.71).aspx
the , stands for sequential evaluation, meaning the expressions are evaluated one after another, the last being your num2.
Learn about comma operator in c http://en.wikipedia.org/wiki/Comma_operator.
i=(a,b) means store b in i.
Everything else than 0 in c is true.
so if(3) if (-3) all are true
only if(0) is false
if(num1,num2)
Is a use of the comma operator. The Comma operator calculates the first operand and discards the result then the second operand and returns the result. Thus (a, b) calculates a, calculates b and then returns b.
This should clear up your confusion for the logical cases, in each of them the statement has the effect of looking at the value of b.
if(num1,num2)
is not a syntax error, but it is a logic error. Basically, this will resolve to being only
if(num2)
Only the last variable is evaluated.
I assume what you want is 'if a and b are true'. The comma like you are using means to evaluate just the last variable.
What I think you want is:
if(num1 && num2) /* num1 AND num2 */
You need to use && (logical AND) not a single & (Which is bitwise AND)

What is !0 in C?

I know that in C, for if statements and comparisons FALSE = 0 and anything else equals true.
Hence,
int j = 40
int k = !j
k == 0 // this is true
My question handles the opposite. What does !0 become? 1?
int l = 0
int m = !l
m == ? // what is m?
Boolean/logical operators in C are required to yield either 0 or 1.
From section 6.5.3.3/5 of the ISO C99 standard:
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.
In fact, !!x is a common idiom for forcing a value to be either 0 or 1 (I personally prefer x != 0, though).
Also see Q9.2 from the comp.lang.c FAQ.
ยง6.5.3.3/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 other logical operators (e.g., &&, ||) always produce either 0 or 1 as well.
Generally, yes, it'll become 1. That said even if that is guaranteed behavior (which I'm not sure of) I'd consider code that relied on that to be pretty awful.
You can assume that it's a true value. I wouldn't assume anything more.
The Bang operator (!) is the logical not operator found commonly in C, C++ and C#, so
!0 == 1
!1 == 0
This is based on the language characteristic of what is interpreted to be either true or false... in more modern languages it would be like this
!false == true
!true == false
See DeMorgan Law concerning truth tables...
!x will be expand to (x==0) so:
if x=0 -> !x take value from (0==0) = TRUE (value 1)
if x!=0 -> !x take value from (x==0) = FALSE (value 0)

Resources