Control flow. while and for loops

Control flow. while and for loops.

Repeating similar tasks

Ask the user to input 3 positive integers and print the largest of them.

#include <iostream>
using namespace std;
int main() {
  
  int x1 = 0, x2 = 0, x3 = 0;

  cout << "Enter a positive integer: ";
  cin >> x1;
  
  cout << "Enter a positive integer: ";
  cin >> x2;

  cout << "Enter a positive integer: ";
  cin >> x3;

  int ans = x1;

  // Can you prove that the following conditions are correct?
  if ((x1 >= x2) && (x1 >= x3)) {
    ans = x1;
  }
  else if (x2 >= x3) {
    ans = x2;
  }
  else {
    ans = x3;
  }

  cout << "The largest is " << ans << endl;
}
Enter a positive integer: 5
Enter a positive integer: 3
Enter a positive integer: 4
The largest is 5

while loop

As an introduction to the while loop, let’s write a program that that prints out the integers from 10 to 1.

#include <iostream>
using namespace std;
int main() {
  int n = 10;
  // count down from 10 to 1
  while (n > 0) {
    cout << "n = " << n << endl;
    n--;
  }
  return 0;
}
n = 10
n = 9
n = 8
n = 7
n = 6
n = 5
n = 4
n = 3
n = 2
n = 1

Now, let’s get back to the previous problem. We want to write a program that asks for 3 positive integers and outputs the largest of them. However, this time we are going to use the while loop.

#include <iostream>
using namespace std;
int main() {

  int n = 3;

  int x = 0;
  int largest = 0;

  // n = how many integers the user has to enter
  // we end the loop when n is zero
  while (n > 0) {
    cout << "Enter a positive integer: ";
    cin >> x;
    if (x > largest) { largest = x; }
    n--;
  }

  cout << "The largest is " << largest << endl;

  return 0;
}
Enter a positive integer: 4
Enter a positive integer: 6
Enter a positive integer: 3
The largest is 6

The problem with the program is that it does not check whether or not the input integers are positive! Can we fix that?

#include <iostream>
using namespace std;
int main() {

  int n = 3;

  int x = 0;
  int largest = 0;

  // n = how many integers the user has to enter
  // we end the loop when n is zero
  while (n > 0) {
    cout << "Enter a positive integer: ";
    cin >> x;

    // we add an extra condition here:
    // we want to compare this new integer x with the largest int so far 
    // only if the input integer was positive.
    if (x > 0) {
      if (x > largest) { largest = x; }
      n--; // we can decrement n
    }
    else {
      // otherwise we just print an error message:
      cout << "It's not positive." << endl;
    }
  }

  cout << "The largest is " << largest << endl;

  return 0;
}
Enter a positive integer: 5
Enter a positive integer: 0
It's not positive.
Enter a positive integer: -2
It's not positive.
Enter a positive integer: 15
Enter a positive integer: 12
The largest is 15

do while loop. “Please answer [y/n]?!”

Write a program that asks the user to answer y or n. If the input is something else, it should ask again, and keep asking until it gets a valid answer.

#include <iostream>
using namespace std;

int main (){
  
  char ans; // this initial value of `ans` is irrelevant.
           // To emphasize this fact, we don't initialize
           // this variable here, although this is generally
           // a bad idea, always initialize your variables.
  do {
    cout << "Please answer [y/n]?! ";
    cin >> ans;
  } while ( !(ans == 'y' || ans == 'n') );  
  // the condition (ans != 'y' && ans != 'n')
  // would also work (De Morgan's Law)

  cout << "Great!" << endl;

  return 0;
}
Please answer [y/n]?! 1
Please answer [y/n]?! 5
Please answer [y/n]?! Q
Please answer [y/n]?! =
Please answer [y/n]?! Y
Please answer [y/n]?! N
Please answer [y/n]?! n
Great!

Observe that do while loop is slightly different from the while loop: it checks the condition after executing the block, so the body is guaranteed to be executed at least once.

Sum of digits.

Write a program that asks the user to input a non-negative integer, and then computes the sum of the digits of that number.

#include <iostream>
using namespace std;

int main (){
  int n = 0; // this initial value for n is irrelevant

  do {
    cout << "Please enter a non-negative integer: ";
    cin >> n;
  } while (n < 0);

  int sum = 0;
  
  do {
    sum += n % 10;
    n = n / 10;
  } while (n > 0);

  cout << "The sum of digits is " << sum << endl;

  return 0;
}
Please enter a non-negative integer: 99
The sum of digits is 18

for loop

The while and do while loops are particularly useful when the number of iterations is not known in advance. However most of the time, you need a loop to simply iterate through a certain range of values, say from 0 to 100. For such regular tasks, for loops may be more suitable.

The for statement is ideal when we know exactly how many times we need to iterate the body of the loop.

Consider an example:

#include <iostream>
using namespace std;

int main() {

  int n = 5;

  // print all integers from 0 to n-1:
  for (int i = 0; i < n; ++i) {
    cout << i << ' ';
  }
 
  cout << endl << endl;

  // print a triangle
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j <= i; ++j) {
      cout << '*';
    }
    cout << endl;
  }

  return 0;
}
0 1 2 3 4 

*
**
***
****
*****

break and continue

Write a program that computes the first integer greater than 1000000 that is divisible by 51 and 117:

#include <iostream>
using namespace std;

int main() {

  int i = 1000000;

  while (true) {
    i++;
    if ((i % 51 == 0) && (i % 117 == 0)) 
      break; // we break the loop when the condition is satisfied
  }

  cout << i << endl;

  return 0;
}
1000467

About intervals: 0 <= k < n

Suggested reading: Why numbering should start at zero by E. W. Dijkstra.

This topic is quite subjective and there are many exceptions, but it’s worth mentioning: If you need to run a loop for n times, usually it’s better to do it as follows:

for(int i = 0; i < n; n++) {
  ...
}

rather than

for(int i = 1; i <= n; n++) {
  ...
}

Notice the difference in the bounds between the two cases.

The second variant often leads to unnecessary +1 or -1 terms in expressions, and in general the code tends to be a bit messier. This is why it’s also easier to get off-by-one errors.

So, if you have a choice, I would suggest using the first method of iteration rather than the second. It also works well with C and C++ arrays, in which the index of the first element is always 0.

Another reference: the article in Wikipedia.