Sign in to follow this  
Boooke

Logical OR operator

Recommended Posts

Boooke    104
Hello. I'm currently reading the Primer Plus 5th Edition. I'm currently stuck at the listing 6.4. It goes something like this,

[CODE]
#include <iostream>
int main()
{
using namespace std;
cout << "This program may reformat your hard disk\n"
"and destroy all your data.\n"
"Do you wish to continue? <y/n> ";
char ch;
cin >> ch;
if (ch == 'y' || 'Y')
cout << "You were warned!\a\a\n";
else if (ch == 'n' || 'N')
cout << "A wise choice ... bye\n";
else
cout << "That wasn't a y or n, so I guess I'll "
"trash your disk anyway.\a\a\a\n";
return 0;
}
[/CODE]

The problem is, no matter what the input will be, the program will always execute the first if-loop. So an input of 'n' or 'a' will result in the output "You were warned!". I have encountered this problem with the or operator in my own programs (On two different computers actually), and often thought I was just misusing it, but somehow I wonder if it's not me, and maybe some kind of bug? I suspect the OR operator since, if I remove it in all of the loops and leave only one char for each loop ('y' and 'N' for instance), the problem will disappear.

I am using Code::Blocks 10.05 (rev 6283) with the GNU GCC version 0.99 compiler (Which came with the Code::Blocks bundle). Hope someone can explain what is happening here.

Best regards,
Boooke

Share this post


Link to post
Share on other sites
client    102
It should be:
[code](ch == 'y' || ch == 'Y')[/code]

@Down: a few secs. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Share this post


Link to post
Share on other sites
Telastyn    3777
C++ sucks.

'Y' is a simple ascii character, value of 89. Since that's not zero, C++ allows implicit conversion of 89 into 'true'. So no matter what ch == 'y' is, the other side of the operator is true, thus the conditional is always true.

Share this post


Link to post
Share on other sites
WavyVirus    884
[color=#000000]ch [/color][color=#666600]==[/color][color=#000000] [/color][color=#008800]'y'[/color]

[color=#000000]In C++, this is an example of an "expression". This one evaluates to TRUE.[/color]

[color=#008800][size=2][left]'Y'[/left][/size][/color]
Even a literal value can be considered an expression. This one evaluates to the character 'Y', which has the value TRUE if converted to a boolean (which is the case for anything non-zero converted to a boolean).

The[b] ||[/b] operator expects an expression on either side: [b]a || b[/b] , where [b]a [/b]and [b]b [/b]are both expressions which are to be evaluated. The values of [b]a[/b] and [b]b[/b] are considered as booleans. If either are TRUE then the value of [b]a || b[/b] is also TRUE. C++ will check [b]a[/b] first and not actually go to the trouble of working out the value of [b]b[/b] if [b]a[/b] is TRUE.

[b]a || b[/b] is also an expression - they are like Russian dolls stacked inside each other.



[color=#000000]ch [/color][color=#666600]==[/color][color=#000000] [/color][color=#008800]'y'[/color][color=#000000] [/color][color=#666600]||[/color][color=#000000] [/color][color=#008800]'Y'[/color]

This expression from inside your 'if' is therefore equivalent to [b](ch == 'y') || ('Y')[/b], or [b](expression which may be TRUE) || (TRUE)[/b].

Share this post


Link to post
Share on other sites
Boooke    104
Ah, I understand now. Seems logical enough, though. Thank you for all the replies. It really helped clear a lot of trouble :-) Could you say something like ch == ('y' || 'Y') in such a loop? Gonna try it out when I get near an IDE.

Edit: Nope you can not :-(

Share this post


Link to post
Share on other sites
WavyVirus    884
Like [b]||,[/b] the [b]==[/b] operator expects an expression on either side. [b]a[/b] [b]==[/b] [b]b[/b] [i]evaluates both expressions first[/i], compares the values and returns TRUE if they are equal.

You cannot use [b]||[/b] to chain together values into a list of possible options like this. [b](a || b)[/b] does not mean of "[b]a value which is either a or b[/b]", instead think of [b](a || b)[/b] as a true/false question which has to be answered before moving on: [b]if (a is equal to TRUE) or (b is equal to TRUE) then the answer is TRUE else it's FALSE[/b].

Generally the computer has to work out the values of things one by one - the various sub-expressions which make up a larger expression have to be evaluated (literally given a value and stored somewhere) in a particular order, just like a person would when working through a maths problem with lots of brackets etc.

Share this post


Link to post
Share on other sites
RulerOfNothing    1466
While what has been said above is true and useful, if you want to have an option be activated by both lowercase and uppercase letters, you can use [url=http://www.cplusplus.com/reference/clibrary/cctype/toupper/]the toupper[/url] function to avoid having to compare against both lowercase and uppercase letters. This is useful if you have a lot of options, as it eliminates the possibility of you (or someone else working on a program you wrote) forgetting to put in a test for either the lowercase or uppercase.

Share this post


Link to post
Share on other sites
LorenzoGatti    4443
An interesting newbie-friendly heuristic could be applied: there is no way to add parentheses in a way that makes any sense, so the expression must also be wrong without them.
[CODE]ch == 'y' || 'Y'[/CODE]
Deceptively symmetrical.
[CODE]ch == ('y' || 'Y')[/CODE]
Logical OR of two char constants? Whatever it does, it's not something I want to compare ch with; "at best" it is 'y' or 'Y', and I'm making only one of the two comparisons.
[CODE](ch == 'y' )|| 'Y'[/CODE]
Logical OR of operator == and a char constant? No, I want operator == on both sides.

Share this post


Link to post
Share on other sites
haegarr    7372
Things are similar with the bit-wise OR. Because of
'y' in ASCII / UTF-8 is 79[sub]hex[/sub]
'Y' in ASCII / UTF-8 is 59[sub]hex[/sub]
the difference is just 20[sub]hex[/sub], what is typical for all latin letters. Hence
( ch | 0x20 ) == 'y'
can be used to check for both 'y' and 'Y'. However, also here the parentheses are required, or else the == would be evaluated before the |.


EDIT: Well, I'm aware of the above being not a direct answer to the OP, also IMHO previous posts have given ample answers already. The above stuff came to my mind during reading RulerOfNothing's post about using toupper, because the above code is a kind of tolower-operator (although working for latin letters in said encodings only). So feel free to ignore it. Edited by haegarr

Share this post


Link to post
Share on other sites
Boooke    104
Hey again. I understand then. I really liked the idea of the toupper (and similar) function. I have used similar in before, but not in C++. It has quite some uses. Could help eliminate lines of code.

[quote name='haegarr' timestamp='1329905686' post='4915451']
Things are similar with the bit-wise OR. Because of
'y' in ASCII / UTF-8 is 79[sub]hex[/sub]
'Y' in ASCII / UTF-8 is 59[sub]hex[/sub]
the difference is just 20[sub]hex[/sub], what is typical for all latin letters. Hence
( ch | 0x20 ) == 'y'
can be used to check for both 'y' and 'Y'. However, also here the parentheses are required, or else the == would be evaluated before the |.
[/quote]

I haven't worked with the bit-wise operators before, so I wouldn't know why it would work, and how it compares, though.

Share this post


Link to post
Share on other sites
rip-off    10976
[quote]

( ch | 0x20 ) == 'y'
can be used to check for both 'y' and 'Y'. However, also here the parentheses are required, or else the == would be evaluated before the |.
[/quote]
This is "for beginners". And even if it were not - if I saw code like that, I wouldn't have a clue what it was trying to do at first glance.

Share this post


Link to post
Share on other sites
Cornstalks    7030
[s]Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried [font=courier new,courier,monospace]('y' or 'Y' == ch)[/font].[/s]

[edit]

Ignore this. I'd delete it but then SiCrane's post wouldn't make sense. Learn something new every day.

Share this post


Link to post
Share on other sites
SiCrane    11839
[quote name='Cornstalks' timestamp='1329929945' post='4915555']
Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried [font=courier new,courier,monospace]('y' or 'Y' == ch)[/font].
[/quote]
[tt]or[/tt] is an alternate token for [tt]||[/tt] and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)

Share this post


Link to post
Share on other sites
Cornstalks    7030
[quote name='SiCrane' timestamp='1329930112' post='4915557']
[quote name='Cornstalks' timestamp='1329929945' post='4915555']
Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried [font=courier new,courier,monospace]('y' or 'Y' == ch)[/font].
[/quote]
[tt]or[/tt] is an alternate token for [tt]||[/tt] and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)
[/quote]
I, good sir, am a moron. Thanks for the correction. I get so used to using the symbols that I forget that keywords like and, or, xor, etc. even exist.

Share this post


Link to post
Share on other sites
Serapth    6671
[quote name='SiCrane' timestamp='1329930112' post='4915557']
[quote name='Cornstalks' timestamp='1329929945' post='4915555']
Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried [font=courier new,courier,monospace]('y' or 'Y' == ch)[/font].
[/quote]
[tt]or[/tt] is an alternate token for [tt]||[/tt] and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)
[/quote]


... learned something new.


Oddly enough, I don't think I have ever encountered it in use.

Share this post


Link to post
Share on other sites
SiCrane    11839
It's only really used by people who's keyboards don't have a convenient key for |. So like code written by Danish people ten or more years ago.

Share this post


Link to post
Share on other sites
Cornstalks    7030
[quote name='SiCrane' timestamp='1329937487' post='4915601']
It's only really used by people who's keyboards don't have a convenient key for |. So like code written by Danish people ten or more years ago.
[/quote]
So that's why Bjarne Stroustrup included them...

Share this post


Link to post
Share on other sites
Boooke    104
[quote name='SiCrane' timestamp='1329937487' post='4915601']
It's only really used by people who's keyboards don't have a convenient key for |. So like code written by Danish people ten or more years ago.
[/quote]

I am danish, and I can do the || just fine ;-)

Thanks for the help, btw, helped clear up a lot.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this