What is !0 in C? - 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)

Related

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 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.

Can't understand this if statement

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.

What double negation does in C

I had a controversy about what compilers "think" about this:
a = 8;
b = !!a;
So, is b == 0x01 ? Is TRUE always 0x01 or it may be 0xFF, 0xFFFF, 0xFFFFFFFF etc..?
If I want to extract only 0x00 if (a == 0) and 0x01 if (a > 0) does this double negation approach works?
In other words: to obtain result only 0 or 1, what is better to use?
a) a>0?1:0;
b) !!a
I hope you understand my question.
You have not supplied enough information to tell whether !!a works for your purposes or not.
You stated that you really need the result of a > 0. However, this is not equivalent to !!a if a is signed and holds a negative value. If this is possible, then the answer is obviously "no".
!!a is equivalent to a != 0, not to a > 0.
Yes, b == 1. The result of any boolean operator is always 0 or 1. You can do better though...
I want to extract only 0x00 if (a == 0) and 0x01 if (a > 0)
b = a > 0; most accurately reflect your rule.
!!a will be either 0 or 1, and will be type int. It will be 0 for zero a, and 1 otherwise.
As for your choices (a) and (b), they are not equivalent, due to a possibility of a being negative. That aside, you could argue that a > 0 ? 1 : 0 is clearer but in performance-critical applications !!a may be better as it will not branch whereas a ternary conditional could dump the pipeline. But a good compiler will optimise out either way. I seldom use either since things like if (a) and if (!!a) are functionally equivalent.
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). C11 §6.5.3.3 5
b below will typical have the value of 1 (or possible -1, see below).
a = 8;
b = !!a;
So, is b == 0x01?
Yes (* see below)
Is TRUE always 0x01 or it may be 0xFF, 0xFFFF, 0xFFFFFFFF etc..?
In <stdbool.h>, true is a macro with the integer constant 1. TRUE is not defined by the C standard. Various implementations defines it with the value of 1. It might be have other values. It certainly should be non-zero.
what is better to use?
A) a>0?1:0
B) !!a
Both result in an int with the value of 0 or 1. A reasonable to good compiler would be expected to generate the same code for both (if a in not signed). Use the form that 1) adhere to your groups coding standard or else 2) best conveys the meaning of code at that point. A third option which results in type (bool):
C) (bool) a
If a is signed , then a>0?1:0 is not equivalent to !!a. a != 0 ? 1 :0 is equivalent of !!a.
* If b is a 1 bit signed bit field, b = !!8 will have the value of -1.
In teems of speed I think this is highly dependent on the compiler and processor you are using.
The longer expression would produce an executable 4 - 16 bytes larger.

Resources