Having trouble understanding the logic of this infinite loop - c++

What makes this an infinite loop? Shouldn't n reach 5 and terminate the loop?
int main()
{
int n = 1;
while (n <= 5)
cout << n ;
n++;
}

There are no curly braces after the while condition.
That's why only cout << n; is executed over and over again. When you write while (something) doThis(); doThat(); or if (something) doThis(); doThat();, only doThis() gets executed while (or if) something is true.
If it was written like this
int n=1;
while (n<=5) {
cout << n;
++n;
}
Then it wouldn't be infinite

Because your code is equivalent to
int main()
{
int n = 1;
while (n <= 5)
{
cout << n ;
}
n++;
}
n++ will not be executed.

In your code, the value of n wouldn't get incremented (unless control is out of loop). This is because the n++; is not a part of the loop. This is the reason why it becomes an infinite loop.
Use { } to indicate block of code when there is more than one statement.
Make the following change:
while (n <= 5) {
cout << n;
n++;
}
In the above code, n++; is a part of the loop and the value of n increments with every iteration and finally the control moves out of the loop when n is 6.
Note: The loop does not terminate when n is 5. It terminates when n is 6 since you are asking the loop to run when n<=5. So it will run even when n is 5.

Related

Why the output of z variable is 19? How does that code works more clearly?

I am having the following program in c++;
#include <iostream>
int main() {
int i=1, j=1, k=1, z=0;
for (; i <= 10; i++)
while(j <= 10) {
j++;
do {
k++;
z++;
} while(k <= 10);
}
std::cout << z << " ";
}
The output is 19 when running and I cannot wrap my head why it is that.
I was expecting the return to be 10 because of the previous while(j<=10). I am missing something?
The do while loop that is a sub-statement of the while loop
while(j<=10) {
j++;
do {
k++;
z++;
} while(k<=10);
is executed 10 times due to the condition of the while loop
while(j<=10) {
In the first iteration of the loop within the inner do-while loop the variable z becomes equal to 10. On the other hand, the variable k will be equal to 11 due to the condition of the do-while loop
do {
k++;
z++;
} while(k<=10);
In the next 9 iterations of the outer while loop the inner do while loop will iterate only one time because after the first iteration of the while loop the variable k will be greater than 10.
So after the first iteration of the while loop the variable z will be equal to 10 and in the next 9 iteration of the while loop the variable z will be increased each time only once.
That is do-while loops always have at least one iteration because their conditions are checked after executing their sub-statements.

I want to know the error in my code. This is to print sum of all even numbers till 1 to N

#include<iostream>
using namespace std;
int main(){
int i = 1;
int sum;
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
cout << sum;
}
This is to print the sum of all even numbers till 1 to N.
As I try to run the code, I am being asked the value of N but nothing is being printed ahead.
For starters the variable sum is not initialized.
Secondly you need to increase the variable i also when it is an even number. So the loop should look at least like
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1;
}
In general it is always better to declare variables in minimum scopes where they are used.
So instead of the while loop it is better to use a for loop as for example
for ( int i = 1; i++ < N; ++i )
{
if ( i % 2 == 0 ) sum += i;
}
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
Let's step through this. Imagine we're on the loop where i = 2 and you've entered N = 5. In that case...
while(i <= N)
2 <= 5 is true, so we loop
if(i%2 == 0)
2 % 2 == 0 is true, so we enter this branch
sum = sum + i;
Update sum, then head back to the top of the loop
while(i <= N)
Neither i nor N have changed, so 2 <= 5 is still true. We still loop
if(i%2 == 0)
2 % 2 == 0 is still true, so we enter this branch again...
Do you see what's happening here? Since neither i nor N are updated, you'll continue entering the same branch and looping indefinitely. Can you think of a way to prevent this? What would need to change?
Also note that int sum; means that sum will have a garbage value (it's uninitialized). If you want it to start at 0, you'll need to change that to
int sum = 0;
You're looping infinitly when i is even because you don't increase it.
Better option would be this if you want to use that while loop :
while(i<=N)
{
if(i%2 == 0)
sum = sum + i;
i=i+1;
}
cout << sum;
If you don't need to do anything when the condition is false, just don't use an else.
No loops are necessary and sum can be evaluated at compile time if needed too
// use unsigned, the whole excercise is pointless for negative numbers
// use const parameter, is not intended to be changed
// constexpr is not needed, but allows for compile time evaluation (constexpr all the things)
// return type can be automatically deduced
constexpr auto sum_of_even_numbers_smaller_then(const unsigned int n)
{
unsigned int m = (n / 2);
return m * (m + 1);
}
int main()
{
// compile time checking of the function
static_assert(sum_of_even_numbers_smaller_then(0) == 0);
static_assert(sum_of_even_numbers_smaller_then(1) == 0);
static_assert(sum_of_even_numbers_smaller_then(2) == 2);
static_assert(sum_of_even_numbers_smaller_then(3) == 2);
static_assert(sum_of_even_numbers_smaller_then(7) == 12);
static_assert(sum_of_even_numbers_smaller_then(8) == 20);
return 0;
}
int main(){
int input; //stores the user entered number
int sum=0; //stroes the sum of all even numbers
repeat:
cout<<"Please enter any integer bigger than one: ";
cin>>input;
if(input<1) //this check the number to be bigger than one means must be positive integer.
goto repeat; // if the user enter the number less than one it is repeating the entry.
for(int i=input; i>0; i--){ // find all even number from your number till one and than totals it.
if(i%2==0){
sum=sum+i;
int j=0;
j=j+1;
cout<<"Number is: "<<i<<endl;
}
}
cout<<endl<<"The sum of all even numbers is: "<<sum<<endl;}
Copy this C++ code and run it, it will solve your problem.
There are 2 problems with your program.
Mistake 1
The variable sum has not been initialized. This means that it has(holds) an indeterminate value. And using this uninitialized variable like you did when you wrote sum = sum + i; is undefined behavior.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has undefined behavior.
This is why it is advised that:
always initialize built in types in local/block scope.
Mistake 2
The second problem is that you're not updating the value of variable i.
Solution
You can solve these problems as shown below:
int main(){
int i = 1;
int sum = 0; //INITIALIZE variable sum to 0
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1; //update(increase i)
}
cout << sum;
}
1For more reading(technical definition of) on undefined behavior you can refer to undefined behavior's documentation which mentions that: there are no restrictions on the behavior of the program.

Using ++ operator leads to unexpected results

I do not understand why the two codes below lead to the same result. Shouldn't the latter print from 6 to 10 since n is incremented first?
Edit: I used both Visual Studio 2019 and repl.it.
#include <iostream>
using namespace std;
int main() {
int n=5;
for (n; n<10; n++)
cout << n << endl;
return 0;
}
>>> 5
6
7
8
9
#include <iostream>
using namespace std;
int main() {
int n=5;
for (n; n<10; ++n)
cout << n << endl;
return 0;
}
>>> 5
6
7
8
9
From https://en.cppreference.com/w/cpp/language/for
attr(optional) for ( init-statement condition(optional) ; iteration_expression(optional) ) statement
The above syntax produces code equivalent to:
{
init_statement
while ( condition ) {
statement
iteration_expression ;
}
}
Your two for loops are therefore equivalent to
{
n;
while (n < 10) {
cout << n << endl;
n++;
}
}
and
{
n;
while (n < 10) {
cout << n << endl;
++n;
}
}
In a for loop:
The first statement is executed exactly once
The conditional is checked, and if true
The body is executed
Then the iteration expression is executed
Goto (2.)
If you want your loop to start at 6, you need to explicitly tell it to start at 6.
There's Nothing wrong here, its just how its supposed to work
Firstly, you should know a for loop works
for loop, without loss of generality can be written as:
for(exp1; exp2; exp3)
{
//body
}
here exp1 will be executed only when entering the loop first time, then exp2 will be evaluated, if true loop will continue, otherwise not.
exp3 is evaluated only after each iteration is complete.
also the only difference between i++ and ++i, is when you assign it to something.
say i is 5, then after statement
i++;
i will be 6
which is also true for this statement:
++i;
but say i=5,
but you try something like this:
a=i++;
after this statement, a will be 5, and i will be 6.
but after this statement, with same initial condition(i = 5):
a=++i;
both a and i will be 6.
The only difference is this:
for (n; n<10; n++)
vs. this:
for (n; n<10; ++n)
The first and third expressions in a for statement are evaluated only for their side effects, with any result discarded. (The second is evaluated and its result used to determine whether to continue the loop.) The only difference between n++ and ++n is their results; their side effects are identical. So in this context n++ and ++n are effectively identical.
I'll also mention that the first expression n has no side effects, so it might well be omitted:
for (; n<10; n++)
Or, better yet, you could incorporate the declaration and initialization into the loop, replacing the existing declaration int n=5;:
for (int n = 5; n < 10; n++)

Not sure where this infinite loop is coming from

I'm coming from C into C++, I might be missing something very basic.
I'm trying to make a program with the collatz conjecture.
Before the first iteration of the loop, i and j both correctly equal 1 and 10.
However, the value of i never seems to change although I have i++ in my loop.
I thought this would be a quick program to code but I'm getting hung up on this. Any help would be appreciated.
int n, j, i, count = 0;
cin >> n >> j;
for (i = n; i < j; i++){
while (i != 1){
if (i % 2 == 0)
i = i/2;
else
i = 3*i + 1;
}
count++;
cout << i << endl;
}
The problem in your code is that after you've run the while loop that tests whether the conjecture is true for i, i is by definition set back to 1 (since that's the condition to get out of the loop), so i++ keeps incrementing from 1 to 2 each time. You'll never get past 2.
If you're trying to test the Collatz Conjecture for all the numbers from n to j, you need to use a different variable in the while loop than you use for iteration.
And if count is supposed to tell you how many cycles are needed, you need to zero it before each while loop, and increment it inside the while loop.
int n, j, i;
cin >> n >> j;
for (i = n; i < j; i++){
int test = i;
int count = 0;
while (test != 1){
if (test % 2 == 0) {
test = test/2;
} else {
test = 3*test + 1;
}
count++;
}
cout << i << ' ' << count << endl;
}
Not sure what it's all about, but here's some quick observation:
your while(i != 1) loop means that it will either run indefinetely, or when this loop ends i will be equal to 1. Which means that your for (i = n; i < j; i++){ loops will always restart with i=1. No wonder it's a dead loop.
Before the first iteration of the loop, i and j both correctly equal 1 and 10.
The let's replay the second iteration of the outer loop.
Before it, at the end of the first iteration, i has been incremented to equal 2. Now,
i % 2 == 0 => i := i / 2, i.e. i := 1.
Now i == 1, inner loop ends.
i is incremented and now equals 2.
Repeat.
You can simply copy the loop variable to a new variable in every loop iteration i = k in this case, so that the for loop variable is not affected
#include <iostream>
int main(){
int min, max, count = 0;
std::cin >> min >> max;
for (int k = min; k <= max; ++k){
i = k;
while (i != 1)
{
if (i % 2 == 0)
i /= 2;
else
i = 3*i + 1;
count++;
std::cout << i << std::endl; //ONLY IF U WANT TO PRINT i EVERY ITERATION
}
std::cout << "Number of iterations needed: " << count << " for i = " << i << std:: endl;
}

Nested loops with C++ coin toss

I have to write a program that runs a loop for a coin toss. I am supported to enter a number into the console and have it run a loop of the coin toss for that many times. I need to use nested loops. I have been working on this for hours and cannot make it work.
The console i/o is supposed to look like below:
Enter the number of tosses to perform [0=exit]: 3
Heads
Tails
Heads
Enter the number of tosses to perform [0=exit]: 2
Tails
Tails
Enter the number of tosses to perform [0=exit]: 0
This is the code i have so far:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main ()
{
srand(time(0));rand();
int result = rand() % 2;
while (true)
{
int n; // this many tosses
cout << "How many tosses";
cin >> n;
cin.ignore (1000, 10);
if (n == 0)
break;
for (int i = 0; i < n; i++)
//random number generator
{
if (result == 0)
cout<< "Heads"<<endl;
else if (result == 1)
cout << "Tails"<<endl;
else if (result != 0 || result !=1)
return 0;
} //for
}//while
}//main
Your for loop doesn't have the part that you are actually trying to execute inside of {}. Try adding the braces around the part you want to loop and see if that fixes it for you.
I edited the indentation in your code to show you the only line that will actually be looping (the srand(time(0)))
You need brackets around the loop block, i.e.
for( int i = 0; i < n; i++ )
{
// Code goes here
}
As shown above, you need to initialize i.
Put the seeding of rand() before the while(...) loop.
You need to move int result = rand() % 2; inside your for loop! Otherwise you will get the same result every single time until you restart the application.
for (int i = 0; i < n; i++)
//random number generator
{
int result = rand() % 2;
if (result == 0)
cout<< "Heads"<<endl; /* to make your output look like your example you should removed the <<endl from here */
else if (result == 1)
cout << "Tails"<<endl; /* and here */
else if (result != 0 || result !=1)
return 0;
} //for
/* and put it here */
cout << endl;