4

In the below given code, why the || logical doesn't work, instead the loop terminates specifically when && is used ?

int main() {
    char select {};
    do {
        cout<<"Continue the loop or else quit ? (Y/Q): ";
        cin>>select;
    } while (select != 'q' && select != 'Q'); // <--- why || (or) doesn't work here ??
    return 0;
}
Rishi K.
  • 111
  • 1
  • 8
  • `||` would make it always be true. Think about it. It must always be not equal to *one* of them. – Fred Larson Dec 10 '19 at 19:44
  • 1
    It works exactly as expected. – Eduardo Fernandes Dec 10 '19 at 19:44
  • 1
    Consider this simple question: Is `'q'` equivalent with `'Q'` ? No , it isn't Therefore, if `select != 'q'` were *false*, that means `select == 'q'` must be true. But then wouldn't `select != 'Q'` definitely be *true* (since `'q' != 'Q'`) ? And vice versa ? The result is, using `||` in that context guarantees an always-true overall expression. In fact, a decent compiler will *warn* you of as-much. – WhozCraig Dec 10 '19 at 19:45
  • @WhozCraig: I wasn't trying to be snarky. Did my comment come off that way? – Fred Larson Dec 10 '19 at 19:46
  • @FredLarson no, not at all. I'm admittedly the laureate of snarky, believe me. was actually trying not to be; you're fine. – WhozCraig Dec 10 '19 at 19:48
  • Read up on [DeMorgan's Law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). When I have trouble understanding a complicated loop condition, I find it sometimes helpful to calculate the converse so I can see what the conditions would have to be for the loop to end. – scohe001 Dec 10 '19 at 19:56

3 Answers3

5

This loop will go on while select is not q and it's not Q:

while (select != 'q' && select != 'Q'); 

This loop will go on while select is not q or it's not Q.

while (select != 'q' || select != 'Q'); 

Since one of them must be true, it'll go on forever.

Examples:

  1. The user inputs q

select != 'q' evaluates to false
select != 'Q' evaluates to true
false || true evaluates to true

  1. The user inputs Q

select != 'q' evaluates to true
select != 'Q' evaluates to false
true || false evaluates to true

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
2

You want to terminate the loop when select is equal either to 'q' or 'Q'.

The opposite condition can be written like

do {
    cout<<"Continue the loop or else quit ? (Y/Q): ";
    cin>>select;
} while ( not ( select == 'q' || select == 'Q' ) );

If to open the parentheses then you will get

do {
    cout<<"Continue the loop or else quit ? (Y/Q): ";
    cin>>select;
} while ( not( select == 'q' ) && not ( select == 'Q' ) );

that in turn is equivalent to

do {
    cout<<"Continue the loop or else quit ? (Y/Q): ";
    cin>>select;
} while ( select != 'q' && select != 'Q' );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

Consider the following diagrams:

enter image description here

The full ellipse are all characters. The white dots is q and Q respectively. The black filled area depicts characters that will make the expression true. First line is select != 'q' && select != 'Q', second line is select != 'q' || select != 'Q'.

&& means both conditions must be true. The resulting black area is the overlap of the two areas on the left.

|| means either of the conditions must be true. The resulting black area is the sum of the two areas on the left.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185