What is the meaning of this operation [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
So we got this piece of code on a test and I had zero idea what is the meaning and how it works.
unsigned int a = 1, b = 2, c;
and then c = a&b || a&&b;
The question was: What is the value of c. Answer was 1.
Can somebody explain what is happening in initialization of c?

The unsigned int variables a and b hold some bit-pattern that represent 1 and 2. It won't be this, but for the sake of the description, let's say
a = 0b0001
b = 0b0010
That would be the numbers 1 and 2 in a 4-bit integer.
The & operator does bit-wise and, so bit by bit you evaluate (0,0)->0, (0,1)->0, (1,0)->0 and (1,1). So, for the two integers above
a = 0b0001
b = 0b0010
a&b = 0b0000
We see that a&b is zero, since they do not have any overlapping 1-bits.
The operator && does a logical and, which means that the result is 1 if both arguments are non-zero and zero otherwise. So a && b = 1 because neither a and b are zero.
a = 0b0001
b = 0b0010
a&&b = 0b0001
The || operator is logical or; it gives you 1 if any of the arguments are non-zero and only zero if both arguments are zero. So, since
a&b = 0b0000
a&&b = 0b0001
where a&&b is non-zero, you get c = (a&b) || (a&&b) = 1.

This assignment statement
c = a&b || a&&b;
may be rewritten for clarity the followinmg way
c = ( a&b ) || ( a&&b );
a & b is the bitwise AND operation. As a is equal to 1 and b is equal to 2 then the result of the operation is equal to 0 (I am using only 8 bits in the number representations for simplicity)
00000001
&
00000010
========
00000000
From the C Standard (6.5.10 Bitwise AND operator)
4 The result of the binary & operator is the bitwise AND of the
operands (that is, each bit in the result is set if and only if each
of the corresponding bits in the converted operands is set).
In this expression a && b there is the logical AND operation. It is equal to 1 when the both operands are unequal to 0. As a and b are unequal to 0 then the result of the operation is 1.
From the C Standard (6.5.13 Logical AND operator)
3 The && operator shall yield 1 if both of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
So you have
c = 0 || 1;
where the logical OR operation is used. It yields 1 if at least one operand is not equal to 0.
From the C Standard (6.5.14 Logical OR operator)
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
So the variable c will be assigned with the value 1.

I will explain it from another point of view.
a&b will give non zero only if both have at least one bit set at the same position
a&&b will give 1 only if both are not zero
a&b || a&&b will give be one only if both are not zero and have at least one bit set at the same position.
It can be reduced to:
int c = a&&b;

Related

Why does C have both logical and bitwise ‘or’ operators?

Why C has both || and | operators? As far I know, | operator can replace || in conditions because it will return true (nonzero) value when at least one of operands is nonzero.
I ask just out of my curiosity. I know I should use || for logical expressions.
Example
#include <stdio.h>
int main(void) {
int to_compare = 5;
/* Try with bitwise or */
if ((5 > to_compare) | (to_compare == 6)) {
printf("‘to_compare’ is less than or equal to 5 or equal to 6.\n");
}
/* Try with logical or */
if ((5 > to_compare) || (to_compare == 6)) {
printf("‘to_compare’ is less than or equal to 5 or equal to 6.\n");
}
return 0;
}
|| and | are very different beasts.
Aside from || having the short-circuting property (the right operand is only evaluted if the left one evaluates to 0), it's also a sequencing point.
The value of the expression can also be different: 1 || 2 for example is 1 whereas 1 | 2 is 3.
(Note that && and & have a more pernicious difference, for example 1 && 2 is 1 whereas 1 & 2 is 0.)
In addition to the fact that the || operator is short-circuiting, the result of the || operator is always either 0 or 1 based on its truth, whereas the result of the bitwise or | operator will be a combination of bits that were set in the operands, which is not necessarily 1 (i.e. 0x0A | 0xB0 = 0xBA, whereas 0x0A || 0xB0 = 1.
§6.5.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
§6.5.12 Bitwise inclusive OR operator
The result of the | operator is the bitwise inclusive OR of the operands (that is, each bit in
the result is set if and only if at least one of the corresponding bits in the converted
operands is set).
In BCPL and B -- C ancestors --, there is only | and &. But their interpretation is dependent on the context: in control structures like if, they behaved like the C logical operators, in other contexts, they behaved like the C binary operators. That was deemed too difficult to use and explain and thus additional operators where introduced so that the operator used indicated clearly if the operation was logical and short-circuiting, or binary and not short-circuiting. And that also explains the inconvenient relative priorities with comparison operators.

Using Logical AND 1 when setting a variable in C

While looking through some code today, I came across an interesting(unecessary?) method for setting a variable: Adding a logical AND to the value.
LED_GRN = (ivLEDGrnSequence & ivLEDSlot) && 1;
I looked around a bit more for some of these occurrences and found them throughout the code, but in different forms:
As an argument for a function:
isoAgCmdHideShow(iObjectID,( (ecu.l & sVar->mask) && 1), (uint8_t *)TxMsg.buf);
In a conditional:
if( (usbQueue.selection & USB_SELECTION_CAN_1) && 1 ) {return TRUE;}
Does this extra logical AND actually change anything about the code, or is it just superfluous? I tried searching for this online, but the closest I found to an answer is Short-Circuit Evaluation which doesn't seem to apply in these situations because short-circuiting a 1 is useless.
In short, what does Logical AND 1 do for variable declaration?
This appears to be a trick to force any non-zero number to 1, while keeping zeros - alongside a more common !!(expr) idiomatic construct.
The idea is to set LED_GRN to 1 or 0 based on the value of ivLEDGrnSequence & ivLEDSlot.
Other ways to do the same thing are as follows:
LED_GRN = !!(ivLEDGrnSequence & ivLEDSlot);
LED_GRN = (ivLEDGrnSequence & ivLEDSlot) != 0;
Doing x && 1 produces either 1 or 0, regardless of what non-zero value the left operand evaluates to.
From the C standard:
§6.5.13 Logical AND operator
The && operator shall yield 1 if both of its operands compare unequal
to 0; otherwise, it yields 0. The result has type int.
It's converting the result of the bitwise AND to either 0 or 1. The result of the bitwise AND can be 0 or any non-zero number. But after the logical AND, the result can only be 0 or 1.
So the first two examples may be useful. The third example with the if statement is definitely not useful, since if converts the expression to a boolean.
The result of logical operation (in this case &&) is either 0 or 1. The result of arithmetic or bitwise operation (& in this case) is 0 or non-0. If we want to convert any non-0 to 1 we perform a logical operation on it. The more common and idiomatic way to accomplish this is the double negation:
LED_GRN = !!(ivLEDGrnSequence & ivLEDSlot);

In C is & shorthand for logical and(&&)?

Sometimes I want to do something like this (with i and j being ints).
(if i==4 && j==9)
{
...
}
Where it'll go through the brackets if i equals 4 and j equals 9. I've been using a single ampersand (&) instead of a double one and my code's been compiling and running.
Is it doing the same thing as a double ampersand &&, and if not what has it been doing?
Edit: Oh and I've been doing the same thing with or, using '|' instead of '||'
Presumably you mean if (i==4 && j==9).
Under the circumstances, changing this from && to & shouldn't change much. The big thing that'll change is that with &&, the j==9 would only be evaluated if the i==4 part was true, but with &, they'll both be evaluated regardless.
When you have something like if (x != NULL && x->whatever ...) you want to ensure that the second part (that dereferences x) is only evaluated if x is not a null pointer. In your case, however, comparing what appear to be ints is unlikely to produce any problems.
It's also possible to run into a problem when you're dealing with something that may produce a value other than 1 to signal true. Again, it's not a problem here because == will always produce either 0 or 1. If (for example) you were using isalpha, islower, etc., from <ctype.h>, they're only required to produce 0 or non-zero values. If you combined those with a &, you'd get a bit-wise or which could produce 0 for two non-zero inputs (e.g., 1 & 2 == 0, but 1 && 2 == 1).
When you use bitwise and on the results from ==, you're going to get 0 & 0 or 0 & 1 or 1 & 0 or 1 & 1. 1 & 1 will yield 1 (true). All the others will yield 0 (false) --- just like && would have.
It's performing a bitwise AND.
What it's doing is the expression i == 4 is equivalent to 1 if i is 4 and the same for the RHS (with j and 9, obviously). The & operator returns the number where both operands have that bit on.
It works the same as && because 00000001 & 00000001 (slimmed down to a byte for example) is the same. If one is 0 (the condition was false), then the & won't see two bits turned on for both operands, and 00000000 is 0, which is falsey.
However, do not simply use & because it's one character shorter or similar. Use it because it expresses what you want to achieve. If it's a logical AND you want, use &&.
The same thing applies to |, except instead of a resulting bit if each operand has it turned on, it turns it on if either operand has that bit turned on.
A single ampersand does a bitwise AND. Every bit of the result is set only if both operands have a 1 in that position.
Since comparisons in C return 1 for true and 0 for false, & will give the same results as && as long as both operands are comparisons. But for arbitrary values, it will return seemingly random results. 1 && 2 is true, but 1 & 2 is false because the binary representations of 1 and 2 have no bits in common.
A single ampersand is called a bitwise and. It is a binary operator that 'ands' two numbers bit by bit.
For instance, if you have two binary numbers, 01100010 and 00011111, your bitwise and will result in 00000010
i==4 returns 1 (true), as does j==9. So, i==4 & j==9 is really just 1 & 1, which evaluates to 1 (true).
Try these examples to see the difference
1) int k = 4 & 6; vs int k = 4 && 6;
2) if(i==4 && 2) vs if(i==4 & 2)

Associativity and Precedence in C

i) What does if(0) mean?
Everytime I use it to test what output i will get, it returns the false part.
Is it equivalent to if(0 == 0), incase of which the true part is evaluated.
ii) Associativity of logical NOT ! is right to left.
Link: http://www.liv.ac.uk/HPC/HTMLF90Course/HTMLF90CourseNotesnode94.html
The second example in the link of logical operators:
But as per the line "the two subexpressions containing the monadic .NOT. are effectively evaluated first, as there are two of these the leftmost, .NOT.A is done first followed by .NOT.E.", the left NOT is evaluated first, but the first one to be evaluated should be the one on the right...???
I) In C, 0 is false and everything else is true. So with if (0), the condition will always be false and the body will never be executed because 0 is always false.
if (0 == 0) is completely different because 0 does in fact equal zero, and the expression 0 == 0 evaluates to true, so the body of the if is executed.
II) The associativity of operators determines what happens when you have ambiguities from multiple operators of the same precedence. For instance, what should happen in a - b - c? Should the b - c be evaluated first or the a - b? It does matter what order you do them in, because if a = 1, b = 2, and c = 3, a - (b - c) is 2, but (a - b) - c is -4. But because subtraction is left-associative, we can know that a - b will be evaluated first, so the answer to a - b - c is -4 when a = 1, b = 2, c = 3.
All that being said, I can't think of a case where the associativity of the logical not operator would matter, and the associativity of an operator does not determine what order it will be executed in when it is seperated by operators of different precedence.
i) in C, 0 mean false, so if(0) will always jump to the else (if there).
it is the opposite of if(0==0), (or simply if(1)), which will do the true part.
if (0) evaluates the predicate 0 as a binary value. Binary values in C use integers, where zero means false and non-zero means true. Therefore, 0 will always evaluate to false.
For binary operators, being right- or left-associative determines the order that otherwise equally important operators will be processed. Consider the subtraction operator:
37 - 10 - 4
Both - are equal precedence so which should we evaluate first? Well, - is left-associative so we do:
(37 - 10) - 4 ==> (27) - 4 ==> 23
If the - operator were right-associative, we would do:
37 - (10 - 4) ==> 37 - 6 ==> 31
Equality (=) is right-associative because we might chain equalities together. So, if we see
// a and b are initialized to 0
a = b = 45
Both = are equal precedence so we evaluate right to left and do:
a = (b = 45) // b receives 45
a = 45 // a receives 45
If we were to go left-right, we'd get an unexpected result:
(a = b) = 45 // a receives 0
b = 45 // b receives 45
For unary operators, however, ordering can only matter when multiple unary operators affect the same value. For example, let's do:
char x = 0xFF
bool y = !~x
These unary operators are right-associative, so we do:
!(~0xFF) ==> !(0x0) ==> true
In the example you showed, the negation operators affecting A and E didn't have "equal precedence" because they didn't have the same operand. So, associativity doesn't apply.

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