Jump to content

  • Log In with Google      Sign In   
  • Create Account

Logical OR operator


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
20 replies to this topic

#1 Boooke   Members   -  Reputation: 103

Like
0Likes
Like

Posted 21 February 2012 - 03:10 PM

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

#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;
}

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

Sponsor:

#2 BSt   Members   -  Reputation: 102

Like
3Likes
Like

Posted 21 February 2012 - 03:22 PM

It should be:
(ch == 'y' || ch == 'Y')

@Down: a few secs. Posted Image
(( I am learning English. ))

#3 Serapth   Crossbones+   -  Reputation: 5476

Like
0Likes
Like

Posted 21 February 2012 - 03:23 PM

Change it to:

if (ch == 'y' || ch == 'Y')

/EDIT: Too slow, too slow.

#4 Telastyn   Crossbones+   -  Reputation: 3726

Like
1Likes
Like

Posted 21 February 2012 - 03:26 PM

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.

#5 WavyVirus   Members   -  Reputation: 735

Like
1Likes
Like

Posted 21 February 2012 - 03:44 PM

ch == 'y'

In C++, this is an example of an "expression". This one evaluates to TRUE.

'Y'


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

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



ch == 'y' || 'Y'

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

#6 Boooke   Members   -  Reputation: 103

Like
0Likes
Like

Posted 21 February 2012 - 04:16 PM

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 :-(

#7 WavyVirus   Members   -  Reputation: 735

Like
2Likes
Like

Posted 21 February 2012 - 05:54 PM

Like ||, the == operator expects an expression on either side. a == b evaluates both expressions first, compares the values and returns TRUE if they are equal.

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

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.

#8 RulerOfNothing   Members   -  Reputation: 1160

Like
2Likes
Like

Posted 21 February 2012 - 08:55 PM

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 the toupper 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.

#9 LorenzoGatti   Crossbones+   -  Reputation: 2705

Like
0Likes
Like

Posted 22 February 2012 - 03:32 AM

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.
ch == 'y' || 'Y'
Deceptively symmetrical.
ch == ('y' || 'Y')
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.
(ch == 'y' )|| 'Y'
Logical OR of operator == and a char constant? No, I want operator == on both sides.
Produci, consuma, crepa

#10 haegarr   Crossbones+   -  Reputation: 4313

Like
0Likes
Like

Posted 22 February 2012 - 04:14 AM

Things are similar with the bit-wise OR. Because of
'y' in ASCII / UTF-8 is 79hex
'Y' in ASCII / UTF-8 is 59hex
the difference is just 20hex, 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, 22 February 2012 - 07:20 AM.


#11 Boooke   Members   -  Reputation: 103

Like
0Likes
Like

Posted 22 February 2012 - 04:21 AM

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.

Things are similar with the bit-wise OR. Because of
'y' in ASCII / UTF-8 is 79hex
'Y' in ASCII / UTF-8 is 59hex
the difference is just 20hex, 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 |.


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

#12 rip-off   Moderators   -  Reputation: 8224

Like
0Likes
Like

Posted 22 February 2012 - 04:34 AM

( 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 |.

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.

#13 BSt   Members   -  Reputation: 102

Like
-2Likes
Like

Posted 22 February 2012 - 10:10 AM

@Edited: I got wrong.
(( I am learning English. ))

#14 rip-off   Moderators   -  Reputation: 8224

Like
0Likes
Like

Posted 22 February 2012 - 10:35 AM

That does not work. It is interpreted as the expression 'y' or ('Y' == ch), which is always true.

#15 Cornstalks   Crossbones+   -  Reputation: 6994

Like
-1Likes
Like

Posted 22 February 2012 - 10:59 AM

Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

[edit]

Ignore this. I'd delete it but then SiCrane's post wouldn't make sense. Learn something new every day.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#16 SiCrane   Moderators   -  Reputation: 9599

Like
2Likes
Like

Posted 22 February 2012 - 11:01 AM

Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

or is an alternate token for || and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)

#17 Cornstalks   Crossbones+   -  Reputation: 6994

Like
0Likes
Like

Posted 22 February 2012 - 11:45 AM


Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

or is an alternate token for || and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)

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.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#18 Serapth   Crossbones+   -  Reputation: 5476

Like
0Likes
Like

Posted 22 February 2012 - 11:54 AM


Additionally, "or" is not a keyword in C++, so you'd get a compiler error anyway if you tried ('y' or 'Y' == ch).

or is an alternate token for || and has been since before the first standard. (See Section 2.5 ISO/IEC 14882:1998)



... learned something new.


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

#19 SiCrane   Moderators   -  Reputation: 9599

Like
0Likes
Like

Posted 22 February 2012 - 01:04 PM

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.

#20 Cornstalks   Crossbones+   -  Reputation: 6994

Like
0Likes
Like

Posted 22 February 2012 - 01:08 PM

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.

So that's why Bjarne Stroustrup included them...
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS