How does this bool variable work exactly? - c++

I am new to programming, so please forgive me if my question is too basic.
For the following code, I don't know how exactly the bool variable "more" works. It says that while loop will do the content of the loop whenever the "more" is true, but
how does the computer know that the more is true? Is it smart enough to know that "more" literally means when the user inputs additional value through keyboard? Also, does it know that a negative input is not considered "more" but only positive input is considered "more"?
Inside the while loop, it says that the more is false when the input value is 0. However, it does not logically make sense that more is false when it already goes through the while loop, which only runs when the more is true!
I learned that we will get an infinite loop when "while is always true". It seems like the while loop will always be true since more = true.
Please help me out with this question!!
vector<double> salaries;
cout << "Please enter salaries, 0 to quit:" << endl;
bool more = true;
while (more)
{
double s;
cin >> s;
if (s == 0)
more = false;
else
salaries.push_back(s);
}

(1): The computer (or the compiler) is not smart enough to connect more to a literal meaning.
(2): more can be changed inside the loop, which is what happens when you enter 0. After changing more to false, the condition in while (more) is re-evaluated. As more is now false, the loop is exited.
(3): No, more is not always true, see (2).

Ok, so point by point:
1) The compiler knows that more is true because on line 3 it says:
bool more = true;
This creates the bool more and gives it the value true.
2) more is then set to false if s is equal to zero. Although more is true at the beginning of the loop there is nothing to say it can't be changed within the loop (this is called mutability).
3) Because more gets set to false within the loop, the loop will stop executing. This will only happen if someone enters 0 for the input. If this doesn't happen you are correct, the loop will get run forever.
This is a fairly common while loop construct which allows an arbitrary number of values to be added to the vector salaries. In your question you hint that positive numbers should not be allowed, it is worth noting that there is nothing in the code enforcing this. Perhaps it would be better to change the line:
if (s == 0)
to:
if (s <= 0.0)
This way the loop will stop executing if a 0 value is entered or if a negative value is entered.

In your code snippet variable more is explicitly set two times: before the loop and inside the loop if s is equal to zero
bool more = true;
while (more)
{
//...
if (s == 0)
more = false;
//..
}
Thus when more will be set to false within the body of the loop
if (s == 0)
more = false;
the loop stops its iterations because the condition in while will not true
while (more)
Take into account that the condition above is equivalent to
while (more == true)
Though there is no great sense to write such a way because variable more is already a boolean expression.
Also take into account that according to the C++ Standard
4.12 Boolean conversions
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer
to member type can be converted to a prvalue of type bool. A zero
value, null pointer value, or null member pointer value is converted
to false; any other value is converted to true. For
direct-initialization (8.5), a prvalue of type std::nullptr_t can be
converted to a prvalue of type bool; the resulting value is false.
You could rewrite your code snippet in other way without using variable more. For example
vector<double> salaries;
cout << "Please enter salaries, 0 to quit:" << endl;
double s;
while ( cin >> s && s != 0 )
{
salaries.push_back(s);
}
Or the condition in while could be written even like
while ( cin >> s && s )
So according to the quote of the C++ Standard if s is not equal to 0 then it is converted to bool true. As for expression cin >> s then class std::istream has explicit conversion operator that converts std::cin to boolean value if the stream is not in erroneous state.

The variable more is explicitly set to true before the loop is entered. In the loop's body, if more is set false, nothing else is executed in the loop's body afterwards. The flow of execution goes again to the beginning of the loop, where the loop's condition is evaluated. As more is false, the loop's body is not executed again.

No, the computer(compiler, more appropriate) does not know the intent behind your coding, specifics behind your variables and functions, It only working on set of instructions, which need to be syntactically correct.
in while(more) it's job is to run the loop for as long as more boolean is true and skip to next instruction when false.
while(condition),here condition is checked once for every iteration, and during the iteration, the compiler does not bother to check and skip the rest of the code upon more being false. the condition is checked only before beginning an iteration.
Absolutely, just assume while(true){set of instructions;} the condition is always true and therefore the block of code is always executed and we call this an Infinite Loop.

Well, it seems that you don't really understand the way your compiler works.
First of all, your computer is not smart or dumb, it's merely a machine and interprets whatever you give them to. So, it all comes to the way you have programmed your program. Having said that we move on:
The
while(condition) {
commands;
}
loop works basically as follows:
It checks the condition whatever that might be at the time it your
program flow enters the loop.
It continues to execute whatever commands are if and only if the previous checked condition was true.
If it wasn't true then your programs continues to execute whatever command follow your while loop.
When the execution of commands have finished it goes again to check the condition in while.
Again, if it's true it carries on with commands.
If not, then again it continues to the following your while commands.
So, to sum up, your compiler, computer or your digital friend does not check for logical flows in how you name your variables, if false does not make sense, etc. It merely checks if condition is true. That's it.
Finally an infinite loop will occur if the initial condition was true when entering the loop and when exiting the loop always continues to be true (not does not change inside the loop because it could change and also get a true values when exiting the loop).

You have some misunderstandings with how things work in C++. You can think of your program as an abstract machine. Each variable is a storage location that maintains some state. The more variable is an example of this state. You can think of the variable as a location in memory that maintains the value that you give it. The total program state is allowed to change throughout the duration of the runtime of the program.
Each assignment (the = operator) sets the state of the variable to the value on the right hand side of the assignment.
So when you say:
bool more = true;
The storage location named more is set to the value true. The storage location will remain true until you assign a new value to it.
Note that in C++ statements are evaluated sequentially. Since the values of the variables may change over time, the order of the statements matters.
Later on when you say:
while (more)
{
// ...
}
The first time that more is evaluated, it is true, but again, since more is a variable, that value may change over time.
Once you are inside the while loop, the more variable is conditionally assigned false when the variable s is equal to 0. Notice that the == is truly an equality check unlike the = operator.
if (s == 0)
more = false;
Note that you should be aware that s is of type double and the literal 0 is of type int. Fortunately for you, this will work since C++ will automatically promote the int to a double type to do the equality comparison. However, it probably makes since to use a literal 0.0 to be clear that you expect for s to be a double.
Since the value of s is dependent on the value that is read from cin, the equality condition will sometimes be true and sometimes false depending on what is entered by the user. But if more is assigned false, it when then cause the while loop to terminate on its next iteration. In other words, when you reach the close brace } the program will repeat back to the beginning of the while and try to re-evaluate more, at that point, when more is false the while loop will end.

vector<double> salaries;
cout << "Please enter salaries, 0 to quit:" << endl;
bool more = true;
while (more)
{
double s;
cin >> s;
if (s == 0)
more = false;
else
salaries.push_back(s);
}
A while loop will iterate over and over until the condition between the ()is not met. When you start the cycle you start with bool more = true; That way you're telling the while(more) loop to keep iterating while more is true. Inside the code you ask for input with cin >> s; and if the input is 0 the variable more will change to false, it will iterate again and since while(more) is awaiting for the morevariable to be true the condition won't be true and the cycle will end. If you input other value than 0 the cycle will store that value into the vector<double> salaries vector.
One way for getting the values that were stored in the vector is:
for(int i = 0; i<salaries.size(); i++){
cout<< salaries[i] << endl;
}
In which case you're telling the compiler to iterate with a variable called i starting from the value 0 until the value of i is < than the value of salaries.size(), for each iteration, i will increase and when the condition is no longer met, the cycle will end.
As a recomendation, use the std namespace for your types, it will be of help in future code to avoid bringing everything from the std namespace into your code.
std::vector<double> salaries;
std::cout << "Please enter salaries, 0 to quit:" << std::endl;
bool more = true;
while (more)
{
double s;
std::cin >> s;
if (s == 0)
more = false;
else
salaries.push_back(s);
}
and
for(int i = 0; i<salaries.size(); i++){
std::cout<< salaries[i] << std::endl;
}

Related

When to return from a function?

Sorry in advance if the question sounds naive. I am writing a simple bool function to check if all digits of a number are same. The following works, however the one after, gives me an error of
17:1: warning: control reaches end of non-void function [-Wreturn-type]
What I am doing wrong with the second one?
Working:
# include <iostream>
# include <string>
using namespace std;
bool samedigits (int number){
bool result = true;
std::string snumber = to_string (number);
for (int i=0; i < snumber.size(); i++){
if (snumber[i] != snumber[0]){
result = result and false;
break;
}
}
return result;
}
int main()
{
cout << samedigits (666);
return 0;
}
Non working:
# include <iostream>
# include <string>
using namespace std;
bool samedigits (int number){
std::string snumber = to_string (number);
for (int i=0; i < snumber.size(); i++){
if (snumber[i] != snumber[0]){
return false;
break;
}
return true;
}
}
int main()
{
cout << samedigits (666);
return 0;
}
Your algorithm is incorrect, you are only checking if the first character is equal to itself, and returning true for every input. Instead, you should move the return true outside the loop, so that you check all the characters first.
Unfortunately, the warning is a false positive. The compiler fails to realize that std::to_string is guaranteed to return a non-empty string when passed an int. This means that the for loop body will be entered, and the function will return a value.
The compiler is right. There is a code path in your second snippet that won't return.
for (int i=0; i < snumber.size(); i++){
Here, the std::string size function can return 0 according to its contract. When it does happen, then your function won't enter the loop. After that, you exit the function without returning.
The second version of your function (combined with some information obtained via comments) indicates a misunderstanding of what return does. The second version would work (here is the misunderstanding) if a return statement were to simply store the indicated value for use when the function eventually ends. However, this is not how return works. A return statement stores the indicated value for use when the function ends and immediately ends the function. In the second version of your function, the for statement might as well be an if and the break is never executed as it comes right after a return.
To demonstrate, let's do a code walk-through for a call to samedigits(123).
bool samedigits (int number){
As we enter the function, number is set to 123.
std::string snumber = to_string (number);
The string snumber is set to "123".
for (int i=0; i < snumber.size(); i++){
The loop initializes by setting i to 0 then checks if 0 < 3 (the size of snumber is 3). This is true, so we enter the loop. Note that the result of entering the loop depends only on snumber not being empty.
if (snumber[i] != snumber[0]){
We check to see if snumber[0] does not equal snumber[0]. This is a bit trivial, but the computer is willing to do it. The result, of course, is false (independent of what the input was – this part might be more interesting if the loop started at 1 instead of 0). So skip to the statement after the if.
return true;
The function immediately ends, returning true.
And that's it. There is no second iteration of the loop. No other code is executed during this function call. Since to_string never returns an empty string, the second version of your function is functionally equivalent to the following:
bool samedigits (int /*number*/){
return true;
// Execution ends with the return statement, so nothing after
// this comment ever executes.
std::cout << "This is dead code. It will never execute.\n";
std::cout << "You will never see this output.\n";
}
To fix the second version, you need to return inside the loop only when the if condition is true. Move return true; to be after the loop so that the loop can iterate multiple times. You do not want to end the function and tell the caller that all the digits are the same (which is what return true; does) until after you've checked all the digits. (If your loop finds a mismatch, execution will reach the return false; inside the loop. At that point, the function ends, so code after the loop has no effect on that function call.)
A smaller (cosmetic) fix is to get rid of the break. Suppose the loop did iterate enough times to find a mismatch. Execution would go into the if statement body and encounter return false. At that point, not only is the loop stopped, but the function as a whole ends, before the break statement is seen. The break statement is dead code, meaning code that can never be executed. In order to get to the break, execution has to go through a return. Execution may arrive at a return statement, but it never goes through one.
Also, be sure to thank your compiler for finding this error, as it does point to a bug in your code. It's not the exact bug the compiler reported, but then again, compilers are not exactly the best thinkers in the world. :)

Difference in while and do-while loops

Can someone explain the purpose of having two different types of while loops? I am new to programming. Also supply example situations with the proper while loop if possible.
I understand how to use a while loop. This is what I made:
bool myBool = true;
int i = 0;
while (myBool) {
if (i > 10) {
myBool = false;
}
i = i + 1;
}
A while loop will only execute when the boolean condition is true.
while (true) {
// INSERT CODE HERE
std::cout << "boolean condition is true - inside my while loop";
}
A do while whill check the boolean condition after the loop executes once.
do {
// INSERT CODE HERE
std::cout << "inside my while loop regardless of boolean condition";
} while (true);
Explicitly: the do while loop is guaranteed to execute at least once, whereas the while loop is not guaranteed to execute at all.
Similarly,
while (false) {
// INSERT CODE HERE
std::cout << "this will never execute";
}
will never execute and
do {
// INSERT CODE HERE
std::cout << "this will execute only once";
} while (false);
will execute once.
The do while loops are control flow statements, they execute a block of code at least once and then the iteration of loops depends on the condition which is checked at the bottom of the loop, They are best to use when you want at least once the loop to be executed, for ex
#include <stdio.h>
int main () {
int c = 50;
/* The do will be executed */
do {
printf("value of c: %d\n", c);
c = c + 1;
}while( c < 20 );//It will depend on the condition
printf("any string");
return 0;
}
Here is a Flow diagram of do while loop
Simple answer is while loop will execute only if condition inside of while statement is true.
do while loop will execute once regardless of the while statement condition.
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
int i = 1;
while( i < 1){ // this loop will never execute as 1 is not smaller then 1
i++; // if the loop was working we would get print 2 here
cout << i << endl;
}
cout << i << endl; // this one will print outside of loop value 1
do{
i++; // increase i to 2
cout << i << endl; // this will print 2
} while (i < 1); // This loop will execute at least once and as the condition of 2 is not smaller then 1 it will exit after one execution
return 0;
}
The difference between while and do-while is that in
while (<condition>)
{
//statements
}
we can control whether to enter the loop by using the test condition.
Whereas in
do
{
//statements
} while (<condition>);
the code has to enter the loop at least once before it can exit by using the condition.
So if we want to enter the loop at least once we should use do-while whereas if we want to test and decide whether to enter the loop or not, we have to use while.
To explicitly answer your first question:
Why does C++ have different kinds of loops? -> Legacy. Other languages (in particular, C) before C++ had this feature, so C++ chose to have it.
Why did other languages have it? -> This gets muddy, but a good explanation is that early languages often did not have optimizing compilers, so your code mapped quite directly to machine code. Providing various loop syntaxes allowed programmers to write structured code that still generates good machine code for their particular case.
In practice, it is rare to see a true do {} while () loop. This may be because for (or range-based for) and while () {} have strictly greater capabilities than do {} while (): An unconditional first loop iteration is possible with every loop, but the reverse is not true. In the very common case of iterating over a (possibly empty) sequence, having a guaranteed loop body execution like do {} while () is actually wrong.
There are plenty of answers with examples and explanations about the loops, so I won't bother repeating this here. I will add though that the most that I personally have seen do {} while () used is, ironically, not for looping but for this.
do-while loop performs the task before the condition in while(). It is for situations when you are trying to prompt the same thing for every wrong action (i.e., user authentication, wrong menu entry). On the other hand, a simple while loop performs till a condition is true (Note: In most cases people use for loops instead of while to define counter, initialize, set condition and increment/decrement - all in the same line).

While function doesn't work like I want it to

Had a new problem with the while function. As easy as it sounds, I still can't wrap my head around it.
Like my last program, this one closes unexpectedly after the correct and wrong messages.
I want this to loop after entering a number, so that the program won't stop.
Thanks for the help, if any.
#include <iostream>
using namespace std;
int main()
{
int X = 0; //setting the first variable
int num; //setting the second
while (X == 0) //this should happen whenever X is equal to 0
{
cout << "Type a number bigger than 3. "; //output
X++; //This should increase X, so that the next while function can happen
}
while (X == 1) //again, since I increased x by one, (0+1=1 obviously) this should happen
{
cin >> num; //standard input
if (num > 3) //if function: if num is bigger than three, then this should happen
{
cout << "Correct! Try again!" <<endl; //output
X--; //Here I'm decreasing x by one, since it was 1 before, now it becomes 0. This should make the "while (X == 0)" part happen again, so that another number bigger than three can be entered
}
if (num <= 3) //if function: if num is lesser than or equal to 3, this should happen
{
cout << "Wrong! Try again!" <<endl; //output
X--; //This is supposed to work like the "X--;" before, repeating the code from "while (X==0)"
}
}
}
now it becomes 0. This should make the "while (X == 0)" part happen again
Nope. While loops don't magically take effect at any point during execution of the program. You only enter a while loop when you've reached it from code above. Programs are executed top-to-bottom, generally.
You would need a loop around the entire program if you want to keep going round and round. Those whiles you have now should probably be ifs.
Merge the two while loops into one, while(true).
Put each previous while body into an if state with the clause from the old while in it.
while(true) {
if (X==0) {
// the X==0- case
} else if (X==1) {
// the X==1 case
}
}
in order to end your loop, do a break;.
You have to think of C++ programs as a sequence of instructions, like a recipe. while just means a loop: you check the condition. If true, you run the body. After running the body, you check only that condition again, and run the body if true. Whenever the condition is false at the start or end of the body of the while (the {} enclosed code after it), you end the loop and proceed to the next one.
The first loop runs, finishes, then the second loop runs in your code. Once the first loop exits, you do not go back into it just because the condition becomes true.
Understanding flow control is one of the "hard" steps of learning to program, so it is ok if you find this tricky.
There are many improvements you can do your code beyond getting it working -- there is, actually, little need for X at all. But baby steps! Once you get it working, you can ponder "how could I remove the variable X?".
Before making such fundamental changes to your program, you should get it working, and save a copy of it so you can "go back" to the last working version.
You want to wrap all that code in it's own while loop:
while (true /* or something */)
{
while (X == 0) //this should happen whenever X is equal to 0
{
// ...
}
At least put your second while loop inside the first one to get it working as intended. Otherwise your program has no reason to go back again.
Nevertheless it's not a good design.

Confused at the following code

So I am currently learning how to code using C++. I came across the following code below.
// =======================
// Lesson 2.4.3 - Do while
// =======================
#include<iostream>
using namespace std;
int main()
{
bool condition = false;
do
{
cout << "Enter a 0 to quit or 1 to continue: ";
cin >> condition;
}
while (condition);
}
Why is it that C++ automatically knows that 0 breaks the loop and that 1 continues the loop? Is it to do with a command knowing that 0 = false and that anything above is true?
Thanks to those who can help.
That's just how boolean logic works. 0 is false, anything non-0 is true.
The variable condition has type bool, so it's values can be true or false. When it's false the loop terminates. On input and output for a bool, 0 is false and 1 is true.
It's because while (0) evaluates to false therefore terminating the loop.
A bool variable can have one two conditions i.e true or false. 0 is considered as false and any value other than 0 is considered as true. So the condition you have written is (when condition=true.
while(!0) // body opf while will execute
and when the condition=false it, c++ will interpret it like this
while(0) // and body of do while will not execute.
because after the input is read the condition is checked while (condition);
while (condition = true);
the first code gets set to the above by default
This means the code in the body of the do while loop will loop while the condition value is true (1)

My while loop exits prematurely

thanks for reading this.
I am writing a code to read a big data file. And I try to use a while loop to read it one piece at a time.
But when I write
while(TimeStep++)
it will exit at the first loop.
if I write,
while(TimeStep+=1)
it will be just fine.
Also, if I initialize
int TimeStep=-1;
it will exit at the first loop. But if I initialize
int TimeStep=0;
it will be fine. The magic of while() confuse me. Please help me understand while loop.
Here is all my code.
//get diffusion of all the particles in the 256Coordinate.txt file and diffusion of a single particle.
using namespace std;
typedef vector<double> vec;
int ReadStructure(vec & Coordinate,int size,ifstream & TrajectoryFile){
double a;
for(int i=0;i<size*3;i++){
if(!(TrajectoryFile.eof())){
TrajectoryFile>>a;
Coordinate[i]=a;
}
}
//cout<<Coordinate[1]<<endl;
if(TrajectoryFile.eof()){
return 1;
} else {
return 0;
}
}
int main(){
int ContinueFlag=0,i,j,k;
double a,b,c;
vec Coordinate;
string filename= ("../256Coordinate.txt"); // a file that contains 256*5000*3 numbers
int size=256;
Coordinate.resize(size*3);
int TimeStep=0;
ifstream TrajectoryFile(filename.c_str());//open the .txt file and begin the read data
//TrajectoryFile>>a;
//cout<<a<<endl;
while(TimeStep+=1){//keep looping untils breaks.
ContinueFlag=ReadStructure(Coordinate,size,TrajectoryFile);//read the .txt file and store the values in the vector Coordinate[3*256]. Read 3
*256 numbers at a time.
// cout<<"ContinueFlag= "<<ContinueFlag<<endl;
if(ContinueFlag==1) break;//if we reach the end of the file, exit.
// cout<<Coordinate[1]<<endl;
}
cout<<"total number of timesteps= "<<TimeStep-1<<endl;
}
the body of while loop will execute when the loop condition under
while(loop condition)
is true.
So if you set TimeStep =0 to start with. It will test whether TimeStep ==0 before executing the while loop. Any non-zero value is treated as True. If it is 0, loop body will not execute.
If you initialize as int TimeStep=-1;, TimeStep+=1 will set TimeStep =0, which is equivalent to false, so loop body will not execute.
If you do not know the loop termination condition beforehand, simply use
while (true)
is better than using such a TimeStep variable.
Try:
while(true){
ContinueFlag=ReadStructure(Coordinate,size,TrajectoryFile);
if(ContinueFlag==1)
break;
}
In C++ the integer value 0 is False, any other value including negative integer is True. While loop exits when false.
I think your main problem is not understanding the while loop, it's understanding the increment operator ++.
Let's work with an example:
int x = 5;
int y = x++;
Here, x will have a value of 6 (because you made ++), but which value will y have? Actually, it will be 5. This is a so-called 'postincrement' operator: see, you assign first, and increment later.
If you wrote this
int x = 5;
int y = (x += 1);
Then you would have x = 6 as before, but this time y = 6 also, so you first increment x and only then assign it to y.
This should make your while loop misunderstanding go away:
int TimeStep = 0;
while(TimeStep++)
Here, TimeStep will get the value of 1, but only after it was used by while to test for exit, but while will see the old value (as y in the example above), and the old value is 0, so while exits immediately.
int TimeStep = 0;
while(TimeStep+=1)
In this case the loop goes on because you first increment the TimeStep and then let while test if it's nonzero.
I would really suggest you write a simple loop, why are you testing if TimeStep is nonzero anyway? Just do it like this:
while(true) { // Infinite cycle, until brake is encountered
TimeStep++;
}
The while loop expects a true/false value, according to that, TimeStep++ if TimeStep = -1 is false, because TimeStep++add 1 to TimeStep , so == 0, if TimeStep = 0and you add 1 then is ALWAYS true, because true is every value != 0...
I think you may need to get a better understanding of boolean algebra.
Here's a link to a tutorial http://www.electronics-tutorials.ws/boolean/bool_7.html.
A while loop is based around a boolean expression. If the expression within the while loop parentheses is true it will enter the loop and stop until that expression evaluates to false.
It works when the integer that you are using is set to 0 or 1 because 0 represents false and 1 represents true. You can't use an integer as a boolean expression if it is not 0 or 1.
It looks like you want the loop to break when ContinueFlag==1. So just use that as the while loop parameter. An alternative way would be to just change that code to while (true).
Since you want ContinueFlag to be set at least once (so you know when to break) I would suggest using a do while loop which executes at least once and then repeats if the expression is true.
USE THIS:
do {
ContinueFlag=ReadStructure(Coordinate,size,TrajectoryFile);
TimeStep++; //This allows for TimeStep to increment
} while (ContinueFlag!=1); //It will loop while ContinueFlag!=1 which will cause
//the loop to end when ContinueFlag==1
This is a better way of writing your code (as opposed to while (true)). This allows you to easily see what the purpose of the loop is.