Reputation: 15
This is a really simple one, that I can't find an answer for.
I'm trying to write function that returns a bool when passed two chars of which the left has higher precedence.
I can achieve the required functionality with the following:
bool Precedence(char lhs, char rhs) {
if ((lhs == '*' || lhs == '/') && (rhs == '+' || rhs == '-'))
return true;
return false;
}
which is fine and dandy but why how isn't the following exactly the same:
bool Precedence(char lhs, char rhs) {
if ((lhs == ('*' || '/')) && (rhs == ('+' || '-')))
return true;
return false;
}
I know it is wrong, but why? To me they both read indentically. Sorry I know this is stupid but it's driving me mad.
Upvotes: 0
Views: 161
Reputation: 13354
In C++, the ||
and &&
operators treat their operands as boolean values. In other words, you'll get unexpected results if you use anything but boolean values as operands for either of those operators. Think of it this way: if you were to evaluate this expression:
(lhs == ('*' || '/')) && (rhs == ('+' || '-'))
what would you get? Let's go through it the way C++ would. First, you need to evaluate within parentheses, so we need to evaluate these two expressions:
'*' || '/'
'+' || '-'
What do these expressions mean? They don't really make much logical sense. You can't ask "Is lhs
equal to '*'
or '/'
?" because there is no notion of "'*'
or '/'
" in C++, at least not in the sense you're probably thinking.
When you ask C++ whether the expression '*' || '/'
is true, it simply converts both characters to their bit representations and determines whether those bit representations contain any 1's. Since neither '*'
nor '/'
is the null character, both contain 1's in their binary representations, so the expression always evaluates to true
.
Upvotes: 0
Reputation: 1977
In the correct version, you are checking first to see if (lhs == '*'), which evaluates to either true or false. The other similar comparisons likewise evaluate to true or false. Then your || and && operators compare true/false values.
If you do ('' || '+') you are not comparing true/false values, though since C/C++ are very flexible when it comes to using data in ways it may not have been intended, it is still using the data for '' and for '+' as if they were true/false values. In C and C++, 0 (and other values that are represented by a 0 or leading 0 such as null, false, "") are false, and other values are true, so '*' is a true value.
So doing (character || character) (where neither character is a null character) is like doing (true || true), which will always evaluate to true no matter which character you use. So you are basically doing lhs == (true || true) which again is the same as lhs==true. So you are just checking to see if lhs is true.
Upvotes: 0
Reputation: 65720
C++ doesn't define logical operators like that.
lhs == ('*' || '/')
does not mean lhs equals * or /
, it returns true
if lhs
is 1
.
The ('*' || '/')
subexpression evaluates to true
unconditionally, because boolean logic on char
s is analogous to checking if they are 0
or not. Now your expression looks like lhs == true
, or lhs == 1
.
Upvotes: 5
Reputation: 234825
'*'
is a char
literal with non-zero value. '/'
similarly.
'*' || '/'
is therefore non-zero, and not likely to equal lhs
. In fact, due to short-circutting of ||
, '/'
will not be evaluated.
So (lhs == ('*' || '/')) && (rhs == ('+' || '-'))
is very different to ((lhs == '*' || lhs == '/') && (rhs == '+' || rhs == '-'))
.
Upvotes: 1
Reputation: 908
The meaning of (lhs == ('*' || '/'))
(and the equivalent one with rhs) it's not what you may think in an intuitive way.
What happens is the following:
The part between the parenthesis gets evaluated: ('*' || '/')
is a boolean condition which evaluates to true
(since at least one of the two char -in this case both- it's not 0).
Then the lhs==true
gets evaluated, which has not the meaning that you want it to have.
The same holds for (rhs == ('+' || '-'))
Upvotes: 4
Reputation: 8805
('*' || '/')
and ('+' || '-')
always return true
because they are non-zero char
values, which is why the following code doesn't work.
Upvotes: 1