Can you explain HOW bool can control loops?

橙三吉。 提交于 2020-01-16 04:49:09

问题


I'm a beginner programmer in C++ (currently), and I've got a conceptual question.

I'm trying to filter a cin input to ensure that it is a one-or-two-digit integer between 01-04, and if it isn't, to produce an error and ask for a new input.

I'm also using map to give the user a list of options that, upon valid selection, routes inputs (integers) through any of several methods to produce a relevant result, but I'll ask a more specific version of this question elsewhere.

I found a snippet of code at http://www.cplusplus.com/forum/beginner/26821/ that is meant to validate an input. I sort of get it, except where the boolean condition is set inside the while loop. Because I don't understand it, it makes it very difficult to edit or make sure that I'm manipulating it right.

Here is the example code:

int main()
{
    int num;
    bool valid = false;

    while (!valid)
    {
        valid = true; //Assume the cin will be an integer.

        cout << "Enter an integer value: " << endl;
        cin >> num;

        if(cin.fail()) //cin.fail() checks to see if the value in the cin
                    //stream is the correct type, if not it returns true,
                    //false otherwise.
        {
            cin.clear(); //This corrects the stream.
            cin.ignore(); //This skips the left over stream data.
            cout << "Please enter an Integer only." << endl;
            valid = false; //The cin was not an integer so try again.
        }
    }

    cout << "You entered: " << num << endl;

    system("PAUSE");
    return 0;

And here is my code (the entire thing, to give context). I don't think it's complete, I just want to make sure I'm using the boolean right.

float _tmain(float argc, _TCHAR* argv[])
{
    bool validInput = !true;

    map<string,int> Operations;
    Operations.insert(pair<string, int>("Addition", 01));
    Operations.insert(pair<string, int>("Subtraction", 02));
    Operations.insert(pair<string, int>("Multiplication", 03));
    Operations.insert(pair<string, int>("Division", 04));

    cout << "Welcome to OneOpCalc, what operation would you like to perform?" << endl;

    for(map<string, int>::iterator ii=Operations.begin(); ii!=Operations.end(); ++ii)
    {
        cout << (*ii).second << ": " << (*ii).first << endl;
    }

    while (!validInput)
    {
        cin >> operatorSelection;

        if (cin.fail() || operatorSelection < 4 || operatorSelection > 1)
        {
            cout << "Error: Invalid selection. Please choose a valid number." << endl << endl;
            cin.clear();
            cin.ignore();
        }
    }
}

Does while (!valid) mean "While valid is false"? In my head, it's saying "While valid is !valid", which obviously, would always be false.

EDIT: Thanks for the answers guys, I'm looking through them all. One answer I keep getting goes too general; I understand that ! is NOT, and I understand the concept of flipping the bool using it. However the implicit logical implications are what confuse me. In any given statement, I am used to thinking of !valid as a way of flipping the valid value; Not testing a condition. It's the syntax of using it to test a condition that tricks me. In other words, writing while(!valid) reads literally to me as while(NOTvalid), not while(valid==false). I can't get myself to understand why in this case, !valid reads as a condition and not just a bit-flip.


回答1:


Loops (and ifs) are controled by an expression of type bool. In while ( !valid ), the expression is !valid, the operator not applied to the value of the variable valid. while ( !valid ) means (literally) while the expression !valid (which means "not valid") is true.

For the rest, the code you're copying is pretty bad. I wouldn't use it as an example if I were you.

As for your own code:

  • _tmain is very particular to Microsoft. You don't want to use it. If your writing a console application, just use main. (Same thing holds for _TCHAR, rather than char.)

  • Neither _tmain nor main can return a float. The return type of main should always be int. I'm less familiar with _tmain, but it's either int or void. (Probably int, if you're in a console mode program.)

  • !true is false. Always. (Programming is different than the real world. There are no maybes.) Why be more complicated than necessary?

  • There's no need for the flag variable at all. You can just write:

    cin >> operatorSelection; while ( !cin || operatorSelection > 4 || operatorSelection < 1 ) { // ... }

  • In case of error, you currently only ignore a single character. You probably want to ignore up to and including the end of line. (std::cin.ignore( std::numeric_limits<std::streamsize>::max() );.

  • And the condition in your if will always be true. (See my version above.) Where do you expect to find a number which is neither less than for nor greater than one?




回答2:


In your code, inside the loop, just add:

else
  validInput = true;

after the if closing bracket. You want to get out of it once the user has typed a correct value.




回答3:


You want to run the loop "while there is not a valid input". Remove the non-bold words, and translate to C++.

Of course, the second case is not working, because nothing changes validInput inside the loop, so it stays "invalid", and the loop continues forever (And if you want to set something to false then bool validInput = !true; is more convoluted than bool validInput = false; - the compiler will do the same thing, but someone reading the code will have to think to see what it does - it is a good thing to think when reading code, but it's not a good thing to write code that is more complicated than necessary...).




回答4:


A while loop has a condition and a body, the body is executed as long as the condition evaluates to true.

From the C++ standard:

6.5.1 The while statement

In the while statement the substatement is executed repeatedly until the value of the condition (6.4) becomes false. The test takes place before each execution of the substatement.

A while loop can have one of the following forms

while ( condition ) statement

while ( condition )
{
  statement(s)
}



回答5:


The ! operator is a logical not and this is how you should read it: while not valid. You could have also written that as:

while(valid == false)

or

while(valid != true)

Note that here, again, != is equivalent to not equal.




回答6:


nijansen forgot to add the most elegant one

while(!valid)

which is the same as the 2 others



来源:https://stackoverflow.com/questions/18129174/can-you-explain-how-bool-can-control-loops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!