16

What is the difference between & and && in C?

My teacher gave me this example:

int a = 8;
int b = 4;
printf("a & b = %d\n", a & b);
printf("a && b = %d\n", a && b);

Output:

a & b = 0;
a && b = 1;

I'm not sure why this would return true in one scenario and false in another.

klutt
  • 30,332
  • 17
  • 55
  • 95
sadsa dadasd
  • 203
  • 1
  • 2
  • 4
  • 4
    `&` is *bitwise and*, `&&` is *logical and*. – Fred Larson Apr 02 '18 at 19:02
  • 11
    If you did not find the specification of both operators, you **definitively** need to work on your searching skills! – too honest for this site Apr 02 '18 at 19:03
  • @FredLarson I know that much but i've only ever used these in scenarios like (if y > 3 && x < 69) or something, not like this. – sadsa dadasd Apr 02 '18 at 19:05
  • The dupe fails to capture one C thing: there is no proper boolean in C. 0 is false, other intergers are true, and "boolean" operators produce 0 or 1 for false or true. – hyde Apr 02 '18 at 19:09
  • 1
    @hyde C99 added `_Bool` type and `stdbool.h` with a typedef of `bool` to `_Bool` – Christian Gibbons Apr 02 '18 at 19:12
  • @rcgldr I should have added some provision that there may be some differences. I'll be happy to delete the comment (as it can no longer be edited) once a proper dupe replaces the C# one. – Christian Gibbons Apr 02 '18 at 19:13
  • `&` is an integer operator, not a Boolean operator (it is Boolean at the bit level, but the result is an integer). So `a & b` is not returning `false`, but integer value zero - because no two corresponding bits are the same. – Clifford Apr 02 '18 at 19:16
  • @ChristianGibbons There does not have to be a dupe for this to be closed. We could just un-dupe it and close it as too broad. – machine_1 Apr 02 '18 at 19:17
  • 4
    I don't believe it's too broad. It's easily answerable. If there's not suitable duplicate, we should just answer it. – Fred Larson Apr 02 '18 at 19:19
  • @FredLarson Well, the question has been reopened. Have at it :) – machine_1 Apr 02 '18 at 19:20
  • The closest I've found is this: https://stackoverflow.com/questions/16338928/difference-between-similar-bitwise-operators/16338961#16338961 , but I don't think any of the answers are in-depth enough to warrant closing this as a dupe. – Christian Gibbons Apr 02 '18 at 19:22
  • Here's another one that might be a suitable dup: https://stackoverflow.com/q/32300522/1275169 – P.P Apr 02 '18 at 19:24
  • @ChristianGibbons But aren't `_Bool` "true" and "false" still integers 1 and 0? – hyde Apr 02 '18 at 19:26
  • I previously closed this as a dupe of https://stackoverflow.com/questions/49617159/difference-between-and-in-c?noredirect=1, unclear what that doesn't cover here (there are no booleans in the OP's code). – Oliver Charlesworth Apr 02 '18 at 19:36
  • @OliverCharlesworth Well, there's the fact that you linked to this question in the comment, not the one you marked it as a dupe of. – Daniel H Apr 02 '18 at 19:40
  • @DanielH - Hmm, that's embarrassing. Oh well :/ – Oliver Charlesworth Apr 02 '18 at 19:42
  • @OliverCharlesworth I'm not sure what question you did mark this as a dupe of, but based on the other comments apparently C++ and C# have some differences between `&` and `&&`. Not just `bool`, but precedence. – Daniel H Apr 02 '18 at 19:45
  • @cyclaminist - correct, I deleted my prior comment and will delete this comment later. – rcgldr Apr 03 '18 at 00:24

5 Answers5

22

& is bitwise and and && is logical and.

The expression x && y will return 1 if both x and y is non-zero, and 0 otherwise. Note that if x is zero, then y will not be evaluated at all. This will matter if y is an expression with side effects. This behviour is called short circuiting.

The expression x & y will perform a bitwise operation on each individual bit in x and y. So if x is 1010 in binary and y is 1100 then x & y will evaluate to 1000. Note that the return value of x & y should NOT be interpreted as a Boolean value, even if it's possible. In early C, the operator && did not exist, and because of that & was used for this purpose.

One way to explain it is that you could imagine that & is the same thing as applying && on each individual bit in the operands.

Also note that & has lower precedence than &&, even though intuition says that it should be the other way around. This also goes for comparison operators, like <, <=, ==, !=, >=, >. This goes back to the time when C did not have the operators && and || and the bitwise versions was used instead. At this time, it made sense, but when the logical operators were added, it did not anymore. Kernighan and Ritchie admitted that it would have made more sense, but they did not fix it because this would break existing code.

I'm not sure why this would return true in one scenario and false in another.

The return value from x & y should not be treated as a Boolean value at all. However, it can (depending on how the code is written) be treated as a Boolean array. If you have two integers, flags1 and flags2 then the result of flags1 & flags2 will denote which flags that are toggled in both flags1 and flags2.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • Should be `if both x and y are non-zero,`. Optionally `& is the same as a bitwise multiply or bitwise binary and on pairs of corresponding bits in x and y`. – rcgldr Apr 02 '18 at 19:38
  • Should be: `&` has lower precedence than the comparison operators `<`, `<=`, `==`, `!=`, `>=`, `>`. See cyclaminist's comment to the original question with the example `a & b == 1` is treated as `a & (b == 1)` . Initially C didn't have logical operators and the binary operators were used as a substitute. When the logical operators such as `&&` and `||` were added to the C language, the precedence of binary operators `&`, `|`, and `^` should have been elevated, but Kernighan and Ritchie were concerned about backwards compatibility. – rcgldr Apr 03 '18 at 00:36
6

The & operator performs a bit-wise and operation on its integer operands, producing an integer result. Thus (8 & 4) is (0b00001000 bitand 0b00000100) (using a binary notation that does not exist in standard C, for clarity), which results in 0b00000000 or 0.

The && operator performs a logical and operation on its boolean operands, producing a boolean result. Thus (8 && 4) is equivalent to ((8 != 0) and (4 != 0)), or (true and true), which results in true.

David R Tribble
  • 11,918
  • 5
  • 42
  • 52
3

&& (logical and operator) - The left and right operands are boolean expressions. If both the operands are non-zero, then the condition becomes true.

>

& (bitwise and operator) - The left and right operands are integral types. Binary AND Operator copies a bit to the result if it exists in both operands.

In your teacher's example a && b, the left operand 4 and the right operand 8 are both non-zero. So the condition will become true.

In your teacher's other example a & b, the left operand 4 or 0100 and the right operand 8 or 01000 copies no bits to the result. This is because there are no common set bits in either operand.

MrPickles
  • 1,255
  • 1
  • 16
  • 31
0

I am surprised the teacher didn't show additional examples employing larger numbers:

Statements:

printf("14 & 18 = %d\n", 14 & 18);
printf("14 && 18 = %d", 14 && 18);

Output:

14 & 18 = 2
14 && 18 = 1

Statements:

printf("300 & 400 = %d\n", 300 & 400);
printf("300 && 400 = %d", 300 && 400);

Output:

300 & 400 = 256
300 && 400 = 1
-1

& is bitwise operator and, && is logical for example if you use two number and you want to use bitwise operator you can write & . if you want to use to phrase and you want to treat them logically you can use && .

saj
  • 1
  • 2
  • 1
    Welcome to Stack Overflow. This question already has two very good answers. Does this new answer provide any information that is not already covered? Please read [answer]. – ChrisGPT was on strike Nov 27 '21 at 15:47