This question already has answers here:
How does logical negation work in C?
(5 answers)
Closed 9 years ago.
#include <stdio.h>
int main()
{
int i;
i=1;
printf("%d ",!i);
i=5;
printf("%d ",!i);
i=0;
printf("%d\n",!i);
return 0;
}
I got the following output in C: 0 0 1
What is the logic behind the output?
In C, any non zero value is considered to be a true value. So taking the logical negation with ! converts it to 0. The logical negation of 0 is 1.
In C booleans are integers where 0 is false and any other value is true.
! is NOT (as you know) so it turns any value that is not 0 into 0 and it turns 0 into 1.
What do you mean by "logic"?
The specific behavior of ! operator? It is defined by the language standard. It produces 0 for non-zero argument. And 1 for zero argument. That's the way it is defined.
The rationale behind such definition? Well, it is supposed to implement the logical-not behavior. Historically, in C language logical "false" is represented by zero integer values, while everything non-zero is interpreted as logical "true". So, that's what you observe in your experiment. When ! operator (or any other logical operator in C) has to generate a "true" result, it uses 1 to represent it, not just some arbitrary non-zero value.
i is used like a boolean value:
If i != 0, then !i == 0.
If i == 0, then !i == 1.
You are performing a Boolean operation. The '!' is NOT an inverter as one would normally think of it. If you are looking for the inverter, use the '~'.
! is a boolean operator that inverts the given input, from true to false and false to true.
True is anything that is not zero. False is zero. So, when you notted 1 or 5, you invert a true value, which prints the integer value of false, 0. Next when you invert a false value, it prints the integer value of true (default 1)
Related
We know that any numbers that are not equal to 0 are viewed as true in C, so we can write:
int a = 16;
while (a--)
printf("%d\n", a); // prints numbers from 15 to 0
However, I was wondering whether true / false are defined as 1/0 in C, so I tried the code below:
printf("True = %d, False = %d\n", (0 == 0), (0 != 0)); // prints: True = 1, False = 0
Does C standard explicitly indicate the truth values of true and false as 1 and 0 respectively?
Does the C standard explicitly indicate the truth values of true and false as 0 and 1 respectively?
The C standard defines true and false as macros in stdbool.h which expand to 1 and 0 respectively.
C11-§7.18:
The remaining three macros are suitable for use in #if preprocessing directives. They are
true
which expands to the integer constant 1,
false
which expands to the integer constant 0 [...]
For the operators == and != , standard says
C11-§6.5.9/3:
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.
It is not explicitly indicated in C11. All language-level operations will return 1 as truthy (and accept any nonzero including NaN as true).
If you concern about _Bool, then true must be 1 because the standard only require it to hold 0 and 1. (§6.2.5/2).
Also in <stdbool.h> the macro true expands to 1 (§7.18/3)
==, !=, <, >, <= and >= return 0 or 1 (§6.5.8/6, §6.5.9/3).
!, && and || return 0 or 1 (§6.5.3.3/5, §6.5.13/3, §6.5.14/3)
defined expands to 0 or 1 (§6.10.1/1)
But all standard library functions e.g. islower just say "nonzero" for truthy (e.g. §7.4.1/1, §7.17.5.1/3, §7.30.2.1/1, §7.30.2.2.1/4).
§6.2.5/2: An object declared as type _Bool is large enough to store the values 0 and 1.
§6.5.5.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. …
§6.5.8/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) …
§6.5.9/3: 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. …
§6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; …
§6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; …
§6.10.1/1: … it may contain unary operator expressions of the form — defined identifier — or — defined ( identifier ) — which evaluate to 1 if …
§7.4.1 (Character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.18/3: The remaining three macros are suitable for use in #if preprocessing directives. They are — true — which expands to the integer constant 1, …
§7.17.5.1/3: The atomic_is_lock_free generic function returns nonzero (true) if and only if the object’s operations are lock-free. …
§7.30.2.1 (Wide character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.30.2.2.1/4: The iswctype function returns nonzero (true) if and only if …
There are two areas of the standard you need to be aware with when dealing with Boolean values (by which I mean true/false values rather than the specific C bool/_Bool type) in C.
The first has to do with the result of expressions and can be found in various portions of C11 6.5 Expressions (relational and equality operators, for example) . The bottom line is that, whenever a Boolean value is generated by an expression, it ...
... yields 1 if the specified relation is true and 0 if it is false. The result has type int.
So, yes, the result of any Boolean-generating expression will be one for true, or zero for false. This matches what you will find in stdbool.h where the standard macros true and false are defined the same way.
Keep in mind however that, following the robustness principle of "be conservative in what you send, liberal in what you accept", the interpretation of integers in the Boolean context is somewhat more relaxed.
Again, from various parts of 6.5, you'll see language like:
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
From that (and other parts), it's obvious that zero is considered false and any other value is true.
As an aside, the language specifying what value are used for Boolean generation and interpretation also appear back in C99 and C89 so they've been around for quite some time. Even K&R (ANSI-C second edition and the first edition) specified that, with text segments such as:
Relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true, and 0 if false.
In the test part of if, while, for, etc, "true" just means "non-zero".
The && operator ... returns 1 if both its operands compare unequal to zero, 0 otherwise.
The || operator ... returns 1 if either its operands compare unequal to zero, and 0 otherwise.
The macros in stdbool.h appear back in C99 as well, but not in C89 or K&R since that header file did not exist at that point.
You are mixing up a lot of different things: control statements, operators and boolean types. Each have their own rules.
Control statements work like for example the if statement, C11 6.4.8.1:
In both forms, the first substatement is executed if the expression
compares unequal to 0.
while, for etc have the same rule. This has nothing to do with "true" or "false".
As for operators that are supposedly yielding a boolean result, they are actually yielding an int with value 1 or 0. For example the equality operators, C11 6.5.9:
Each of the operators yields 1 if the specified relation is true and 0
if it is false
All of the above is because C did not have a boolean type until the year 1999, and even when it did get one, the above rules weren't changed. So unlike most other programming languages where statements and operators yield a boolean type (like C++ and Java), they just yield an int, with a value zero or not zero. For example, sizeof(1==1) will give 4 in C but 1 in C++.
The actual boolean type in C is named _Bool and requires a modern compiler. The header stdbool.h defines macros bool, true and false, that expand to _Bool, 1 and 0 respectively (for compatibility with C++).
It is however considered good programming practice to treat control statements and operators as if they actually required/yielded a boolean type. Certain coding standards like MISRA-C recommend such practice. That is:
if(ptr == NULL) instead of if(ptr).
if((data & mask) != 0) instead of if(data & mask).
The aim of such style is to increase type safety with the aid of static analysis tools, which in turn reduces bugs. Arguably, this style is only meaningful if you do use static analysers. Though in some cases it leads to more readable, self-documenting code, for example
if(c == '\0')
Good, the intent is clear, the code is self-documenting.
versus
if(c)
Bad. Could mean anything, and we have to go look for the type of c to understand the code. Is it an integer, a pointer or a character?
I've programmed in many languages. I've seen true be 1 or -1 depending on the language. The logic behind true being 1 was that a bit was either a 0 or 1. The logic behind true being -1 was that the ! operator was a one's complement. It changed all the 1's to 0's and all the 0's to 1's in an int. So, for an int, !0 = -1 and !(-1) = 0. This has tripped me up enough that I don't compare something to be == true, but instead compare it to be != false. That way, my programming style works in every language. So my answer is to not worry about it, but program so that your code works correctly either way.
This answer needs to be looked at a bit more closely.
The actual definition in C++ is that anything not 0 is treated as true. Why is this relevant? Because C++ doesn't know what an integer is by how we think about it--we create that meaning, all it holds is the shell and rules for what that means. It knows what bits are though, that which make up an integer.
1 as an integer is loosely represented in bits, say an 8-bit signed int as 0000 0001. Many times what we see visually is a bit of a lie, -1 is a much more common way to represent it because of the signed nature of 'integer'. 1 really can't mean true proper, why? Because it's NOT operation is 1111 1110. That's a really major issue for a boolean. When we talk about a boolean, it's just 1 bit--it's really simple, 0 is false and 1 is true. All the logic operations hold as trivial. This is why '-1' should be designated as 'true' for integers (signed). 1111 1111 NOT'ed becomes 0000 0000---the logic holds and we're good. Unsigned ints is a little bit tricky and were a lot more commonly used in the past--where 1 means true because it's easy to imply the logic that 'anything not 0 is true'.
That's the explanation. I say the accepted answer here is wrong--there is no clear definition in the C/C++ definition. A boolean is a boolean, you can treat an integer as a boolean, but the fact the output is an integer says nothing about the operation actually being done is bitwise.
It happened because of the Relational Operators in your printf statement.
Operator == and operator !=
Since (0 == 0) holds true so, it gives a value 1
whereas, (0 != 0) doesn't hold true so, gives a value 0 .
I think I might have found the perfect solution to your problem.
Yes, 0 and any non-zero number are False and True respectively. Though there is no boolean data type in C.
But this is not the problem, the actual problem is how you are dealing with the modification of variable a in the your code :
int a = 16;
while (a--){
printf("%d\n", a);
}
When the compiler comes to the while (condition) statement, first the value of a is read by the compiler for the condition, then the arithmetic operation takes place, in this case,
a = a - 1 / a -= 1. So in the end there will be a case when a = 1 and the condition satisfies and after the arithmetic operation a-- which leads to a = 0, the print statement prints a as 0.
The above scenario depends on whether you use --a or a--. These two statements are read by the compiler in the order they are written.
For --a first the operation is performed on a then its value is read and vice-versa for the other.
So for case --a when a = 1 first the operation is done i.e a = a - 1 / a -= 1 and then a is evaluated for the condition, which then comes out to be Falsy as a = 0. Try the code below :
int a = 16;
while (--a){
printf("%d\n", a); // prints numbers from 15 to 1 as intended
}
OR deal with the modification of a inside the while loop block.
int a = 16;
while(a){
a = a - 1; // or a -= 1
printf("%d\n", a); // also prints numbers from 15 to 1 as intended
}
I have come across an answer and I can't seem to figure out why it's right.
So there are two int variables x and y and they represent 0x66 and 0x39 respectively.
The question asked what is the result value based on the expression.
x && y is apparently 0x01 (1)
x || y is 1
!x || !y is 0
x && ~y is 1
From what I was thinking, I thought as long as an argument was not zero it was considered true. So as long as x and y were some non-zero value then && operator would produce a 1, and of course as long as one of them is true the || operator would produce a 1.
So why is the third question 0? Is the ! different from the bitwise ~ operator? So originally x is 0101 0101 in binary since it's non zero it is true in the logical sense, but the ! of it would be false or would it do the one's complement of the number so its 1010 1010?
A boolean result is always true or false, and in C true is represented by 1 and false by 0.
The logical not operator ! gives a boolean result, i.e. 1 or 0. So if an expression is "true" (i.e. non-zero) then applying ! on that expression will make it false, i.e. 0.
In your example you have !x || !y. First !x is evaluated, and it evaluates to false, leading to !y being evaluated, and it also evaluates to false, so the while expression becomes false, i.e. 0.
From what I was thinking, I thought as long as an argument was not
zero it was considered true. So as long as x and y were some non-zero
value then && operator would produce a 1, and of course as long as one
of them is true the || operator would produce a 1.
This is all correct.
So why is the third question 0? Is the ! different from the bitwise ~ operator?
Yes. It is logical NOT. Just like the other logical operators && and ||, it only cares about if a variable has a non-zero value or not.
!0 will yield 1.
!non_zero will yield 0.
Note that all logical operators in C yield type int rather than bool, as an ugly, backwards-compatibility remain from the time before C had a boolean type. In C++ and other C-like languages, logical operators always yield type bool.
Similarly, true and false in C are actually just macros that expand to the integers 1 and 0. In other languages they are keywords and boolean constants.
Yes, ! is different from the bitwise not ~. It's a logical not. It yields either 0 or 1.
~(0x01) will 0x10 and
!(0x01) will 0x00
'~' is a bitwise operator.
'!' is a logical operator.
This question already has answers here:
!! c operator, is a two NOT?
(4 answers)
What is "!!" in C? [duplicate]
(7 answers)
Closed 8 years ago.
doing some exam prep and this is a past question.
Describe what the following pieces of C do and re write in a simple programming style with the same functionality.
(The bad indentation was the intention of the question).
With regards to section A i'm not sure what unsigned cast is doing to a. I have tested it a few times and can't seem to get a result that makes sense.
Similarly In B im not sure what how the while loop is working with the long cast and the !! being another problem
The Code :
//code section A
int f(int a,int b){
return(((unsigned) a)>b);}
//code section B
int h(int *x, int y){
int * z= x-- +y;
w=0;
while( (long) z-- ^(long) x) w += !!(*z);
return w;}
Any help would be appreciated, Thank you.
!! negates a boolean expression twice, essentially converting an expressions value to 0 or 1.
As in C all values other than zero mean true, and zero means false, !! can be used to convert it into 0 or 1, in the case you need to use it later in a function or expression which doesn't accept any value for true, only the number 1.
About the rest: unsigned interprets the internal representation of your int a from your function argument to unsigned int, so for example -1 becomes 4294967295 if your compiler uses two's complement and 4 byte ints.
About the casting to long : I strongly recommend against in similar situations unless you absolutely know what you are doing. In your example, it does some pointer arithmetic, in interpreting your pointer as numeric values, essentially working with the addresses of your variables as if they were just numbers. They have probably chosen long because on their system it had the exact same size as a pointer. This is not guaranteed to be so on all systems.
So, to give a very short answer to your question: The code does undefined behavior with those expressions, except for the !! which just give 0 if the expression was zero, and 1 otherwise.
The operator ! is the logical negation.
!true is false (0), and !false is true (1).
When a value is used as a boolean value, anyhting other than 0 (0 in a large sense) is true; 0 is false.
So, !!(*z) has either the value 0 or 1.
It will be 0 if *z was NULL to begin with
It will be 1 if *z was not NULL.
! is the boolean operator for not.
false is 0, and true is 1 in C.
So when you take any int, which is not 0- and you run ! on it, you'll get 0 (true becomes false), and zero will become one .
So the action of !! is changing each non-zero value to 1 , and leaving each 0 a 0.
I have come across a problem involving exclamation marks and integers whilst reading a code in my reference book.
Let us say I have declared an integer variable named number - int number = 0;
I then use a while function involving an exclamation mark and number
while(!number)
{
...
}
I am confused with this because I do not know what does !number mean and what would be possible returned results? I am not sure if this can be used, but as I said, I saw it in my book.
Therefore, it would be great if someone could tell me what does !number mean and what does it evaluate?
Thank you in advance.
We can treat ! as not.
So if a number is non-zero (either positive or negative) it returns Zero.
If it is zero, it returns 1.
int i = 13;
printf("i = %d, !i = %d\n", i, !i);
printf("!0 = %d\n", !(0));
In C, !number will evaluate to 1 if number == 0 and to 0 if number != 0. And in C, 1 is true and 0 is false.
Using an explicit comparison like number == 0 have the same effect but you might find it easier to read.
It's a negation or "not" operator. In practice !number means "true if number == 0, false otherwise." Google "unary operators" to learn more.
It is used for Negation of a number.It is a Unary Operator.
For Example:-
If we are using it with zero :- !0 then it will become 1
with one !1 = 0
The negation operator (!) simply just reverses the meaning of its operand.
The operand or the expression must be of arithmetic or pointer type. But the operand/result of expression is implicitly converted to data type bool (boolean 0 means false, Non zero means True).
The result is true if the converted operand is false; the result is false if the converted operand is true. The result is of type bool.
so
while(!number)
{
...
}
since variable number is 0 , while(!number) ie, !0 which is 'negation of 0' which is 'TRUE' then it code enters the while loop()
My understanding of this is as follows. In C, the ! operator returns 0 if it is given a nonzero value and returns a nonzero value if it is given 0.
Say you have this little snippet of C code:
int y = 0;
int z = !y;
What value will go into z? Does it simply take !0 to be 1? Is it system dependent? Does the C standard dictate what is supposed to happen? I ran into these questions while doing some homework earlier tonight dealing with bitwise 2's-complement integer manipulation. I got a certain problem to work, but I'm sort of scratching my head as to why it works. Thanks a lot for any info!
Truth values "generated by" C are always 0 or 1.
It is true (heh) that a non-zero expression is generally considered "true" in if and so on, but when the language itself needs to generate a truth value it uses 0 for false and 1 for true.
Since the ! operator is a logical operator, it will always result in 0 or 1.
So in your case, z will be set to 1.
Update: See this FAQ entry for more discussion, that's what I had in mind with the "generated by" wording. Amazingly, it even has the same pun (I did not look this entry up before writing my answer). Not sure if this is an indication of me having a good sense of humor, or not.
The result of an unary-expression with the ! operator is an int with value 0 or 1.
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).
From The C Standard (n1124) section 6.5.3.3.