Logical AND operator in c spitting out 1 - c

int a;
scanf("%i", &a);
printf("%i", a&&1);
In this program, no matter the input it spits out a 1, even when I try even numbers. The only exception is when a = 0. I might not be understanding the AND operator correctly, but for any even number shouldn't the output be 0?

Because the && operator returns a non zero value if both its operands are not zero. Maybe you mean &.
int a;
if (scanf("%i", &a) == 1)
printf("%i", a & 1);
&& is the logical AND operator.
& is the bitwise AND operator.

Operator && is the logical AND operator that returns true/false.
In C language false is 0 (zero) otherwise 1 (one) for true as C does not have boolean type.
So the result of your operator is correct and as expected.
If you insist on using bool type you can include definition for it as below
// standard way
#include <stdbool.h>
which is basically
#define bool _Bool
#define true 1
#define false 0

Related

C multiple assignments to same variable in short-circuited expression

I have three variables: a, b, c. Let's say they are integers. I want to find the first non-zero value among them, in that particular order, without looping. The following seems to work, but I am not sure if that is because I am lucky, or because the language guarantees it:
int main(int argc, char *argv[]) {
int a = 0;
int b = 3;
int c = 5;
int test;
if ((test = a) != 0 || (test = b) != 0 || (test = c) != 0) {
printf("First non-zero: %d\n", test);
} else {
printf("All zero!\n");
}
return 0;
}
Is the repeated assignment with short-circuiting shown here guaranteed to work as intended, or am I missing something?
This might be one place where a three-letter answer would be acceptable, but a two-letter answer might require more explanation.
It would!
Because of the nature of the OR operator if any of the condition is
true then the test stops.
Thus i think what you did was basically equivalent to:
test = a != 0 ? a : b != 0 ? b : c != 0 ? c : 0;
printf("%d\n",test);
but heck yours looks good.
[update]
As per what chqrlie mentioned it can be further simplified to:
test = a ? a : b ? b : c;
Yes, your expression is fully defined because there is a sequence point at each || operator and the short circuit evaluation guarantees that the first non zero value assigned to test completes the expression.
Here is a crazy alternative without sequence points that may produce branchless code:
int test = a + !!a * (b + !!b * c);
printf("%d\n", test);
The code is very bad practice but it is guaranteed to work fine.
This is because the || and && operators have special characteristics - unlike most operators in C, they guarantee that the evaluation of the left operand is sequenced (executed) before the evaluation of the right operand. This is the reason that the code works. There's also a guarantee that the right operand will not be evaluated if it is sufficient to evaluate the left one ("short circuit"). Summarized in C17 6.5.14/4:
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.
"Sequence point" being the key here, which is what gives the expression a deterministic outcome.
Had you used pretty much any other operator (like for example bitwise |), then the result would be undefined, because you have multiple side effects (assignments) on the same variable test in the same expression.
A more sound version of the same algorithm would involve storing the data in an array and loop through it.

Why does it print 1 at the end?

I don't understand why it prints 1 at the end.
#include <stdio.h>
int main(){
printf("%d\n", -2&&2);
return 0;
}
&& is a Boolean operator, not an integer operator. In C any non-zero value is interpreted as true when applied to a Boolean operation, while zero is the only integer value regarded as false when applied to a Boolean operation.
So:
(<non-zero> && <non-zero>) == true
then conversely when a true result is treated as an integer (as the %d format specifier dictates in this case), true is represented by 1, while false is zero. So in this case true becomes 1.
If you want to print a Boolean result, then:
printf( "%s\n", (-2 && 2) == 0 ? "false" : "true" ) ;
Strictly the expression:
-2 && 2
is equivalent to:
(-2 != 0) && (2 != 0)
Which has strict type agreement since != has a Boolean result from integer operands, and so && is presented with Boolean operands only with no implicit conversion.
Because -2&&2 is evaluated to true = 1 (when you AND two numbers together you will get true unless one or both of the numbers is 0).
Try changing -2&&2 to true && false; it will print 0.
The expression -2&&2 resumes to 1 or true (true is always != 0, while false == 0) based on the boolean arithmetic opration.
And here is how it resumes to 1:
&& represents the logical AND, not bitwise AND, which is &, in C. So you are logical ANDing the values of -2 and 2.
Let´s consider the following sentence as one of the statements for the Logical AND (&&)-operation:
If both the operands are non-zero, then the condition becomes true.
-2 is non-zero, equals 1.
2is also non-zero, equals 1.
So the result is also 1 (1AND 1 = 1) or true represents 1.
The && operator is for logical and, not bitwise and.
The expression in your program evaluates as
printf("%d\n", (-2 != 0) && (2 != 0));
Which is 1 because boolean expressions have value 0 for false and 1 for true in C.
Conversely, if you had written -2 & 2, you program would have implementation defined behavior, depending on the representation of negative integers used for the target system. On modern systems with two's complement representation, this bitwise and expression evaluates to 2. Same value for sign-magnitude representation, but on rare systems with ones' complement representation, the value would be 0.

Explanation of shortcuts in C

Can someone explain what exactly is happening in these two statements listed below:
1) int enabled = val == 0; //val is an int
2) int sync = param || (foo->delay == NULL); //param and delay is both int
int enabled = val == 0;
read as
int enabled = (val == 0);
and
(val == 0)
will be either 0 or non zero if val is 0 or not. enabled will then be initialized with that value
Equivalent to:
int enabled;
if(val == 0)
{
enabled = 1;
}
else
{
enabled = 0;
}
now you do that same analysis on the second one
You will set the variable enabled to 1 if val is equal to 0 and 0 otherwise.
sync will be equal to 1 if param is non-zero and in case it is 0 then it will be 1 if foo->delay is NULL else it will be 0.
From standard §6.5.9p3 backing up what I said:
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
Also in case || there is standard saying the evaluation logic: from §6.5.14
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.
Also in the same section the rule which dictates what will be the result if param is non-zero.
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
C only adopted a true boolean type from C++ with C99, though it named it _Bool so it wouldn't conflict with pre-existing code and provided the header <stdbool.h> to make it nicer.
The prior convention that only 0 is considered falsey (a literal zero, which in a pointer-context is a null-pointer), and anything else truthy was not changed. (That's the reverse to how command shells do it by the way.)
All boolean operators and conversion from _Bool use canonical values of 0 and 1.
That should be enough history and details to understand the code.

What happens when we arbitrarily use ==?

I tried running the following code in C:
#include <stdio.h>
int main() {
int a = 10, b = 5, c = 5;
int d;
d = b + c == a;
printf("%d", d);
}
I got the output as d = 1. Can someone please explain to me what happens when we use == like this?
§6.5.9 (== and !=)-http://c0x.coding-guidelines.com/6.5.9.html
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.)Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.
For any pair of operands, exactly one of the relations is true.
So here as b+c is equal to a as both has value 10 therefore it yields 1.
Because b + c is executed first, and after is evaluate comparison with == operator.
In c, addition has higher precedence than ==, so it adds b and c before comparing the result to a, since it is true it results in 1, if it was false it would result in 0.
== is the equal-to operator. It returns 1 if the two sides are equal and 0 otherwise.

Unusual behavior of ternary operator?

i was just playing around with the ternary operator in my c class today. And found this odd behavior.
#include <stdio.h>
#include <stdbool.h>
main()
{
int x='0' ? 1 : 2;
printf("%i",x);
}
returns 1 as expected.But
#include <stdio.h>
#include <stdbool.h>
main()
{
int x='0'==true ? 1 : 2;
printf("%i",x);
}
returns 2 while i expect it to return 1.
The value of '0' is not zero, it is whatever integer value encodes the digit '0' on your system. Typically 48 (in encodings borring from ASCII), which is then not equal to true when interpreted as an integer, which is 1.
So the first of your code lines is equivalent to
int x = (48 != 0) ? 1 : 2;
which clearly evaluates to 1. The second is
int x = (48 == 1) ? 1 : 2;
which just as clearly evaluates to 2.
Maybe you are confusing '\0' and '0'
The value of the character constant
'\0'
is always 0 in C.
The value of the character constant
'0'
is implementation defined and depends on the character set. For ASCII, it is 0x30.
Also note that the macro true is defined to the value 1 and not 0.
That's because (assuming ASCII) '0' represents the integer 0x30, i.e. 48, and true represents the integer 1. So they're not equal.
In C, any nonzero value is considered true, but true itself is 1, and 1 is what you get from any built-in Boolean test (for example, 0 == 0 is 1).
true is defined as 1. '0' in ASCII is 0x30 which is not equal to 1.
Therefore the condition '0'==true is not true.
That's because '0' != true. The boolean value gets promoted to an integer type and is equal to 1 whereas '0' is equal to 48
'0' does not equal true, so the result of '0'==true is 0 (false). This is assigned to x and passed to the ternary operator, giving the result you see.
If you intended something else, you should use brackets to clarify the order of precedence you want, or break your code up into multiple statements.

Resources