Video Coming Soon...

Created by Zed A. Shaw Updated 2024-10-28 08:02:26

17: Classic for-loops

You are now going to learn about using for-loops in C++ to process lists of items. You should have the documentation for vector open while you do this exercise for reference.

Problems With while-loops

The while-loop has a problem because you can get it wrong very easily. You can forget the initializer, forget to increment, or maybe you make the incrementer too complex. You can also get the test wrong. Because of this it's difficult to reason about when a while-loop will end. This becomes even more of a problem when the while-loop gets more complicated over time.

Classic for-loop as Solution

To solve the problems with while-loops there's three general solutions:

The Code

This code is exactly the same as the previous code but it uses a for-loop instead of a while-loop to iterate through the age vector:

View Source file ex17a.cpp Only

#include <fmt/core.h>
#include <vector>

using namespace fmt;
using std::vector;

int main() {
  vector<int> ages = {10,34,25,19,87,5};

  println("I have {} cousins of different ages:", ages.size());

  for(size_t i = 0; i < ages.size(); i++) {
    int cousin_age = ages.at(i);
    println("cousin #{} is {} years old.", i, cousin_age);
  }
}

Code Walkthrough

I'll skip the usual starting code you have to write, as it's similar to the previous exercise and will only focus on the part with the for-loop. You should open both ex16.cpp and this ex17a.cpp file to compare them side-by-side:

12
This starts the for-loop and consists of three parts separated by ; (semi-colon) characters. First is the initializer which is size_t i = 0; then there's the test which is i < ages.size(); and finally the incrementer which is i++. This matches my comments from ex16.cpp for the while-loop but all on one line.
13
This line gets a cousin's age from ages using ages.at(i) just like in the while-loop version.
14
Then just print it out like normal using println().

The way to think about a for-loop's initialization is it's like three lines of code every while-loop needs smashed onto a single line with ; characters. You can actually do this with any C++ code. Imagine I want to create an integer, add a number to it, and print it:

int i = 0;
i += 10;
println("i={}", i);

I could simply put all those on one line like this:

int i = 0; i += 10; println("i={}", i);

That's because C++ doesn't care as long as you have ; separating things. That's effectively what a for-loop does. It just takes those three lines you'd normally have to write for a while-loop and pulls them up to the top on one line (separated by ;).

Challenge Mode

Here's another example that's more complicated and shows a ffew more features of both for-loops and vector:

View Source file ex17.cpp Only

#include <fmt/core.h>
#include <vector>

using std::string, std::vector;
using namespace fmt;

int main() {
  vector<string> fruit = {
    "Apple", "Orange", "Pear",
    "Grape", "Durian", "Mango"
  };

  // loop through fruit
  for(size_t i = 0; i < fruit.size(); i++) {
    println("Fruit #{} is {}", i, fruit[i]);
  }

  // another way to get it using at()
  for(size_t i = 0; i < fruit.size(); i++) {
    println("Fruit #{} is {}", i, fruit.at(i));
  }

  // set them all to something else
  vector<string> guitars = {
    "Stratocaster", "Telecaster", "Bass VI",
    "P-Bass", "ASAT Special", "G&L S500"
  };

  for(size_t i = 0; i < guitars.size(); i++) {
    println("Changing fruit #{} to guitar {}", i, guitars[i]);
    fruit[i] = guitars[i];
  }

  for(size_t i = 0; i < fruit.size(); i++) {
    println("Fruit...I mean Guitar #{} is {}", i, fruit.at(i));
  }

}

As usual do not blast all this code in one session the try to fix it. Get this working a little bit at a time, compiling and running constantly as you work.

Once you get this working I then want you to take everything you know about vector and use for-loops to work with them. You can start with the documentation for vector and study each operation possible. Try to get as many to work as you possibly can with what you know, and any take notes on any that you don't understand.

WARNING: Remember that challenge sections like this are meant to push your understanding, not to make you feel like a failure. You can't fail these because I'm not grading you and I don't care how well you do. You won't impress me or disappoint me. Your only goal is to learn what you can and come back when you learn more.

Breaking It

Breaking classic for-loops is harder but not impossible:

Further Study

Look at other data structures you can use. Try some of these:

Again, try to use them but don't worry if they don't make sense yet. In the great words of a Jedi Master:

"There is only try, no fail." -- Gandalf

I think that's what he said. It's been a while since I've seen Fight Club.

Previous Lesson Next Lesson

Register for Learn C++ the Hard Way

Register to gain access to additional videos which demonstrate each exercise. Videos are priced to cover the cost of hosting.