why did K&R make &&, || logical and &, | bitwise, not the other way around?
c, language-design
Solution
From the horse's mouth:
Rapid changes continued after the language had been named, for example the introduction of the `&&` and `||` operators. In BCPL and B, the evaluation of expressions depends on context: within if and other conditional statements that compare an expression's value with zero, these languages place a special interpretation on the and (`&`) and or (`|`) operators. In ordinary contexts, they operate bitwise, but in the B statement
if (e1 & e2) ...
the compiler must evaluate `e1` and if it is non-zero, evaluate `e2`, and if it too is non-zero, elaborate the statement dependent on the if. The requirement descends recursively on `&` and | operators within `e1` and `e2`. The short-circuit semantics of the Boolean operators in such `truth-value' context seemed desirable, but the overloading of the operators was difficult to explain and use. At the suggestion of Alan Snyder, I introduced the `&&` and `||` operators to make the mechanism more explicit.
Remember that C wasn't created in a vacuum; much of its weirdness can be traced to BCPL and B.
Problem
I know that `==` was chosen for equality and `=` for assignment because they thought that people did more assignment than checking for equality---but surely they didn't think that there would be more bit fiddling than boolean logic? Why not go the other way around, with `&` and `|` being logical operators?