Regarding logical AND operator - c

int a=8, b=10,c=2,d;
d= ++a && ++b || ++b;
In the above code , how do I know if (++a), (++b) are true or false . I know true is 1 and false is 0. But I can’t understand how to determine if these expressions are true or false .
Please help.

0 is false, any non-zero value is true. So you just need to determine whether ++a and ++b are zero or not zero.
Since a is initially 8, ++a is 9, which is non-zero, so it's true.
Since b is initially 10, ++b is 11, which is non-zero, so it's true.
9 && 11 is true because both the operands are true.
|| only evaluates the second operand if the first operand is false. So the second ++b ie never executed. The value of true || anything is true.
Therefore, d will be set to true, which is 1.

In C, logical operators (&&, ||, !, etc.) assume that zero is false and all other values are true.
Based on the operator precedence (operator && precedence is higher than || operator), the expression will be evaluated as:
d = (++a && ++b) || ++b;
Note that logical AND operation expr1 && expr2 employs short-circuiting behaviour. With logical short-circuiting, the second operand, expr2, is evaluated only when the result is not fully determined by the first operand, expr1.
That is, expr2 is not evaluated if expr1 is logical 0 (false).
++a will result in 9, a non zero value, hence, results in true, so right hand side operand of && operator, which is ++b, will be evaluated.
++b will result in 11, a non zero value, hence, results in true.
true && true will result in true.
Logical OR operation expr1 || expr2 employs short-circuiting behaviour. That is, expr2 is not evaluated if expr1 is logical 1 (true).
So, in the given expression, the left hand side of || is evaluated as true hence the right hand side operand of || operator, which is ++b, will not be evaluated and the result of whole expression will be true. Hence, the value of d will be 1.

In C, C++ and many other programming languages, for integers, 0 is considered false and any other integer (including negative numbers) is true. So here d will be evaluated to true

In 'C' we know that the true is '1' and false is '0' so above expression will be true because both the expressions are non zero. and if you want to print actual values like true and false i think you should try out printf("%s", x?"true":"false");

Related

How this logical operator works? [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 1 year ago.
#include<stdio.h>
int main()
{
int a=-10,b=3,c=0,d;
d= a++||++b &&c++;
printf("%d %d %d %d ",a,b,c,d);
}
How above expression is evaluates. I have read preceedence but still i am getting confused. Kindly give me the right solution of this in step by step.
In case of || and && operators the order of evaluation is indeed defined as left-to-right.So, operator precedence rules tell you that the grouping should be
(a++) || ((++b) && (c++))
Now, order-of-evaluation rules tell you that first we evaluate a++, then (if necessary) we evaluate ++b, then (if necessary) we evaluate c++, then we evaluate && and finally we evaluate ||.
I have a feeling this is a homework question, so I'll try to give extra explanation. There are actually a lot of concepts going on here!
Here are the main concepts:
Pre- and post- increment and decrement. ++a increments a before the value is used in an expression, while a++ increments a after the value is used in the expression.
Operator precedence. Specifically, && has higher precedence than ||, which means that the assignment of d should be should be read as d = (a++) || (++b && c++);
Expression evaluation order. The link shows a whole list of evaluation rules for C. In particular, item 2 says (paraphrasing) that for operators || and &&, the entire left side is always fully evaluated before any evaluation of the right-hand side begins. This is important because of...
Short-circuit boolean evaluation, which says that, for operators && and ||, if the value of the left-hand term is enough to determine the result of the expression, then the right-hand term is not evaluated at all.
Behaviour of boolean operators in C. There is no inbuilt boolean type in C, and operators && and || work on integer values. In short, an argument is 'true' if it is nonzero, and false if it equals zero. The return value is 1 for true and 0 for false.
Putting this all together, here is what happens:
After the first line, a is -10, b is 3, c is 0 and d is unset.
Next, the variable d needs to be assigned. To determine the value assigned to d, the left hand term of (a++) || (++b && c++) is evaluated, which is a++. The value USED in the expression is 10, however the value of a after this expression is -9 due to the post-increment.
For the purposes of the boolean operator, the value 10 is true, and therefore value of the || expression is 1. Because of short-circuit evaluation, this means that ++b && c++ is not evaluated at all, so the increments do not happen. Thus we have d = 1.
At the end, the values are: a = -9, b = 3, c = 0, d = 1.
So the program prints out -9 3 0 1.

confusing behaviour of logical and (&&) and logic or (||) operators in c programming

Can anybody explain why the output is 'a' only, if && has higher priority than ||. Below is the code snippet.
#include<stdio.h>
int main(){
int a = printf("a")||printf("b")&&printf("c");
return 0;
}
This is a feature called "Short Circuit Evaluation".
The code is trying to determine if the expression X || Y && Z is True or False so it can assign a value to variable a.
Because of short-circuit evaluation, once the first part, printf("a"), is True (non-zero), it does not matter what the 2nd half of the expression is, so it does not get evaluated.
True || (*anything*) will result in true, so why bother evaluating the 2nd half of the code?
The entire 2nd part of the expression: printf("b")&&printf("c") gets skipped completely, because its not needed.
As your code demonstrates very well, when part of an expression is skipped due to Short Circuiting, any side-effects of that code (such as printing to the console) get skipped as well, sometimes leading to confusing and non-obvious bugs.
Not all languages have short-circuit evaluation, but it is commonly found in most languages.
&& has higher precedence, according to conventional terminology. "Priority" gives a potentially (more) misleading impression.
Whatever you call it, it is not about order of operations, but rather about correctly identifying the operands of each operator. That && has higher precedence means that your declaration of a is equivalent to
int a = printf("a") || (printf("b")&&printf("c")); // THIS
, as opposed to
int a = (printf("a")||(printf("b")) && printf("c"); // NOT THIS
Furthermore, the printf("a") is executed first either way, because the left-hand operand of && and || is always evaluated before the right-hand one, and the right-hand operand is only evaluated at all if that is necessary to determine the result of the operation.
In your case, each printf call will return 1 on success (if it is executed at all). The printf("a") is executed first, per the rule for the operands of an || operator. Its result is enough to determine the overall result of that operation, so no part of the other operand is evaluated.
If you used parentheses to override the default grouping then the short-circuiting would be more narrowly scoped, with the result that ac would be printed.
Precedence only affects which operators are grouped with which operands, not the order in which subexpressions are evaluated.
Both && and || force left-to-right evaluation. Due to precedence rules, the expression x || y && z is parsed as x || (y && z), however it is evaluated as follows:
x is evaluated and all side effects are applied;
if x evaluates to 0, then
y is evaluated and all side effects applied
if y evaluates to non-zero, then
z is evaluated
if z is non-zero, then
the result of y && z is 1, and
the result of x || y && z is 1
else
fhe result of y && z is 0, and
the result of x || y && z is 0
end if
else
z is *not* evaluated
the result of y && z is 0, and
the result of x || y && z is 0
end if
else
y && z is *not* evaluated
x || y && z evaluates to 1
end if
Remember that both && and || short-circuit - depending on the value of the left operand, the right operand will not be evaluated. If a is 0, then a && b evaluates to 0 regardless of the value of b, so b is not evaluated at all.
Similarly, if a is non-zero, then a || b evaluates to 1 regardless of the value of b, so b is not evaluated.
1) Sequence Point
A sequence point defines any point in a computer program's execution
at which it is guaranteed that all side effects of previous
evaluations will have been performed, and no side effects from
subsequent evaluations have yet been performed.
At a sequence point, it is guaranteed that evaluation of all previous sub-expressions are complete.
2) From Microsoft article:
Only the sequential-evaluation (,), logical-AND (&&), logical-OR (||),
conditional-expression (? :), and function-call operators constitute
sequence points, and therefore guarantee a particular order of
evaluation for their operands.
So, there exists a sequence point between left operand and right operand of logical OR || and logical AND &&. Hence, logical operators guarantee evaluation of their operands from left to right.
3) From C Sequence Points
The left operand of the
logical-AND operator is completely evaluated and all side effects
complete before continuing. If the left operand evaluates to false
(0), the other operand is not evaluated.
The left operand of the
logical-OR operator is completely evaluated and all side effects
complete before continuing. If the left operand evaluates to true
(nonzero), the other operand is not evaluated.
4) Reason:
int a = printf("a") || printf("b") && printf("c");
So, there is a sequence point between printf("a") and (printf("b") && printf("c")).
That's why first printf("a") is evaluated. Since, the left operand result is non-zero, the right operand is not evaluated (short-circuit evaluation).
printf() is a function that always returns the number of written characters (for printf("a"); it returns 1).
The logical operators (|| and &&) in C evaluate their arguments from left to right in a way that they cut the evaluation at the point on which there's security on the final result. As the first argument to || is true (because 1 is different than 0), the right operand to || doesn't need to be evaluated, as the result will be true anyway, and this is why the right expression (printf("b") && printf("c")) is not evaluated at all.
For || if the left operand evaluation gives true, there's no need to evaluate the right argument. For && if the left operand evaluates false, then the result will be false, and there's no need to evaluate the right argument.

C by K&R - numeric value of a relational or logical expression

In section 2.6 "Relational and Logical Operators" on page 42 in "The C Programming Language" 2nd by K&R, the authors said:
By definition, the numeric value of a relational or logical expression
is 1 if the relation is true, and 0 if the relation is false.
I'm confused by that wording. For example, in the logical expression
x && y
there is no relation which can be true or false. Isn't the wording supposed to be:
By definition, the numeric value of a relational or logical expression
is 1 if the expression is true, and 0 if the expression is false.
x && y
Since x and y are being used in conjuntion with && the compiler needs logical (boolean)values
In c 0 is false and not 0 is true. Hence the statement you posted from the standard that a logical expression evaluates to 0 or not zero (in fact 1, but in testing any non zero value is treated as true).
Thus this code is interpreted as
(x != 0) && (y != 0)
the depending of the current values of x and y this becomes, say
1 && 0
THis is
true && false
by the rule that 0 == false and !0 == true. This expression is thus false, and therefore evaluates to 0 by the statment you posted.
Note that much of this confusion comes form the fact the c originally had no boolean type. Hence the convention that 0 = false and !0 = true. This has the beneficial side effect of allowing numbers and in particular pointers to be tested directly as in
while(ptr--)
{
}
Which is equivalent to
while(ptr-- != 0)
{
}
A relational or logical expression is the result of an operator such as &&, ||, ==, '>=,<=, etc. In this context,x && y` is a logical expression which will evaluate to either 0 or 1.
The arguments to && need not be logical expressions. When evaluated in a boolean context, a numeric value of 0 evaluates to false while a non-zero value evaluates to true. So in the case of x && y the expression will evaluate to 1 (i.e. true) if both x and y are non-zero.
This is not relational operator.(You shouldn't take the word relation on that context also). This is logical AND. The wording is correct.
Here each of the variable's value x and y if non zero will evaluate to truthy value. And if both of them are true then it will be true - the whole expression would be true.
And here by relation it means the relation of each subexpression being truthy or not which in turn decides whether whole expression is true or false. In your case the relation is simply whether x is nonzero or not AND y is nonzero or not.
The wording is correct. Relation is a mathematical term.
Every operator in C returning a boolean can be considered a relation.

diffrence in working of post increment operator with and & or operator

This post-increment operator usage is confusing.
{int a=0,b=1,c=2,d;
d=a++||b++||c++
printf("%d %d %d %d",a,b,c,d);}
output is
1,2,2,1
value of c did not increase but if I replace it with && operator it increases. Why?
Quoting C11, chapter §6.5.14, (emphasis mine)
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the
second operand is evaluated, there is a sequence point between the evaluations of the first
and second operands. If the first operand compares unequal to 0, the second operand is
not evaluated.
So, in your case,
d=a++||b++||c++
is the same as
d= ( (a++ || b++) || c++)
Then, the statement inside the first parenthesis is evaluated, first a++ (post-increment) evaluates to 0 (side-effect pending), so the RHS of the first || is evaluated, b++, producing 1 and the result of the || operation is TRUE, yields 1.
That result, 1, is the LHS of the second ||. Hence, the RHS of the second || (c++) is not evaluated anymore and the final result becomes TRUE, again yielding 1, which gets stored in d.
So, finally,
a++ is evaluated, becomes 1
b++ is evaluated, becomes 2
c++ is not evaluated, remains 2
the result of || is stored in d, that is TRUE, so stores 1.
On the other hand, for logical AND && operator,
[...] If the first operand compares equal to 0, the second
operand is not evaluated.
So, if you replace the last || with &&, then for the outer statement, the LHS becomes 1 and the RHS evaluates, making c++ to be evaluated and incremented, as a side effect.

&& and || operators [duplicate]

This question already has answers here:
Why does "++x || ++y && ++z" calculate "++x" first, even though operator "&&" has higher precedence than "||"
(11 answers)
Closed 4 years ago.
I came across this code:
int main()
{
int i=1,j=2,k=0,m=0;
m = ++i || ++j && ++k;
printf("%d %d %d %d %d",i,j,k,m);
}
The program returns 2 2 0 1.... Why?
&& has a higher priority than || so ++j && ++k should be evaluated first. Hence I would expect j=3 and k=1. It will return true hence || becomes true so ++i shouldn't be evaluated. But it works other way around.
I would like others to explain to me.
Having higher precedence does not mean it gets evaluated first. It just means it binds tighter. In that example, that expression is equivalent to: ++i || (++j && ++k). What gets evaluated first is ++i because || evaluates left to right. Only if that evaluates to false will ++j && ++k be evaluated because || is short-circuiting.
Actually ++i will be evaluated first. Only if it's false will the right side be evaluated (and in your case it's not).
The fact that "&& has higher priority" relates to precedence (how tightly its operands stick to it) not "whose operands get evaluated first".
Because && is indeed above || in the table, the expression will be interpreted like this:
m = ++i || (++j && ++k)
Short circuit evaluation. If, the left-side of the && is non-zero, only then will the right-hand side be evaluated. Likewise, only if the left-hand side of the || is zero, will the right-hand side be evaluated.
"Higher operator precedence" is not the same as "evaluated first". When you use the short-circuiting operators, they are evaluated left-to-right. The results of any arithmetic will be affected by operator precedence, but that doesn't change the left-t0-right ordering of short circuiting.
The complexity of your example is a good reason for not doing this sort of thing. Even if you figure out the rules and know exactly what it will do, the next programmer to come along and look at the code probably won't.
Basically, || means, "if you have received something which is true, return that, otherwise, return whatever happens afterwards." So, the only thing which is evaluated there is m = (++i != 0). That means "increment i, assign m to the value of i compared to 0, break."
To be more specific, this is what is happening:
i = 1;
i = i + 1;
if( i ) {
m = 1;
}
else { // who cares, this will never happen.
j = j + 1;
if( j ) {
k = k + 1;
m = (k != 0); // 1
}
else {
m = 0;
}
}
In the C language, there are two different issues you need to be aware of: operator precedence and order of evaluation.
Operator precedence determines which operator that gets its operands evaluated first, and also which operands that belong to which operator. For example in the expression a + b * c, the operator * has higher operator precedence than +. Therefore the expression will be evaluated as
a + (b * c)
All operators in the C language have deterministic precedence and they are the same on any compiler.
Order of evaluation determines which operand that gets evaluated first. Note that a sub-expression is also an operand. Order of evaluation is applied after the operator precedence has been determined. If the above a+b*c example has left-to-right order of evaluation, then the operands themselves get evaluated in the order a, b, c. If the operands were for example function calls, then the functions a(), b() and c() would have been executed in that order. All operands in this example need to be evaluated since they are all used. If the compiler can determine that some operands need not be evaluated, it can optimize them away, regardless of whether those operands contain side-effects (such as function calls) or not.
The problem is that order of evaluation of operands is most often unspecified behaviour, meaning that the compiler is free to evaluate either left-to-right or right-to-left, and we cannot know or assume anything about it. This is true for most operands in C, save for a few exceptions where the order of evaluation is always deterministic. Those are the operands of the operators || && ?: ,, where the order of evaluation is guaranteed to be left-to-right. (When using formal C language semantics, one says that there is a sequence point between the evaluation of the left and the right operator.)
So for the specific example m = ++i || ++j && ++k.
The unary prefix ++ operators have the highest precedence, binding the operators i, j and k to them. This syntax is pretty intuitive.
The binary && operator has 2nd highest precedence, binding the operators ++j and ++k to it. So the expression is equivalent to m = ++i || (++j && ++k).
The binary || operator has 3rd highest precedence, binding the operators i++ and (j++ && ++k)= to it.
The assignment operator = has the lowest precedence, binding the operators m and ++i || (++j && ++k) to it.
Further, we can see that both the || and the && operators are among those operators where the order of evaluation is guaranteed to be left to right. In other words, if the left operand of the || operator is evaluated as true, the compiler does not need to evaluate the right operand. In the specific example, ++i is always positive, so the compiler can perform quite an optimization, effectively remaking the expression to m = ++i;
If the value of i wasn't known at compile time, the compiler would have been forced to evaluate the whole expression. Then the expression would have been evaluated in this order:
&& has higher precedence than ||, so start evaluating the && operator.
&& operator is guaranteed to have order of evaluation of operands left-to-right, so perform ++j first.
If the result of ++j is true (larger than zero), and only then, then evaluate the right operator: perform ++k.
Store the result of ++j && ++k in a temporary variable. I'll call it j_and_k here. If both ++j and ++k were positive, then j_and_k will contain value 1 (true), otherwise 0 (false).
|| operator is guaranteed to have order of evaluation of operands left-to-right, so perform ++i first.
If ++i is false (zero), and only then, evaluate the right operator "j_and_k". If one or both of them are positive, the result of the || operator is 1 (true), otherwise it is 0 (false).
m gets assigned the value 1 or 0 depending on the result.
You're seeing logical operator short-circuiting here. If the first part of an || condition is true, then it never evaluates the rest of the expression (because if the first part is a pointer-not-null check you wouldn't want to dereference the pointer in the second part if it's null). Further, since it's in a boolean-result expression the result of ++i is converted back to bool value 1 before being assigned into m.
Avoid this kind of code like the plague, it will only give you debugging nightmares in the short and long term.
Shortcut operators will cause the unnecessary expression components not to be evaluated. Since && has a higher precedence, it would need to be evaluated last if you want to allow the || operator to be able to shortcut the whole expression when ++i evaluates to true. Since this is the case, ++i is the only variable evaluated after the "=".
Precedence and order of evaluation are two different things. Both || and && evaluate their operands left-to-right; precedence doesn't change that.
Given the expression a || b && c, a will be evaluated first. If the result is 0, then b && c will be evaluated.
The order of comparison operators (|| and &&) is more important.
That's why you'd better placed your most important test first.
because || and && short circuit and therefore specify sequence points
Note: this was originally tagged C++ as well, and you get a slightly different answer there as overloaded operators || or && do not short circuit just inbuilt ones

Resources