In this video, we'll learn about a really great feature that was added
in c++11, the range-based for loop.
This loop really makes c++ feel like a modern programming language.
The idea with the range based for loop is to loop through a collection of
elements and be able to easily access each element without having to worry
about the length of the collection or incrementing or decrementing looping
variables or subscripting indexes.
The syntax is very simple and elegant.
We have the keyword for followed by open and closed parentheses as usual.
Inside the parentheses, we provide the type and name for the variable
we want to use in the loop body.
This variable will be bound to each element of the collection.
So it should be of the same type as the collection elements.
Then we provide a colon and the collection or collection name.
That's it.
Now when we access the variable name in the body of the loop, it will have
a specific element in the collection.
Pretty cool.
Let's see an example.
In this example, our collection is an array of integers named scores, that
we've initialized to 100, 90 and 97.
And here's the code that iterates over that collection
using the range-based for loop.
Notice that in the parentheses, we provide the
type of each array element.
In this case, it's an integer.
And we provide the variable name that we can use in the body of
the loop, in this case, score.
Finally, we provide a colon and the name of the
collection which is scores.
That's it.
Now we can use score in the body of the loop.
The loop displays 100, 90 and 97, which are the elements in the array.
See how much cleaner and less error prone this is.
It was a great addition to c++.
We actually don't have to explicitly provide the type of the variable.
Instead, we can use the auto keyword this.
Tells the c++ compiler to deduce the type itself.
In other words, you're asking the c++ compiler to figure out the
type based on the declarations.
So in this case, the compiler sees that you're using a
collection scores in the loop.
So it looks it scores and it sees that it's an array of integers, so it uses
an integer for the score variable.
Pretty easy.
Actually, in this case, using auto versus int doesn't really,
buy us much but c++ can have very complex collections.
And sometimes defining the type of a collection variable can be quite long
and tricky, auto makes it dead simple.
In this example, we want to calculate the average temperature
from a vector that contains doubles that represent temperatures.
The vector in this case is called temps, and it contains 4 doubles.
In order to calculate the average temperature in this vector, we
need to iterate over the vector, access each temperature, add
them all up and divide by 4.
That's it.
Notice the for loop and how simple it is.
It's saying loop through the temps collection and each time through
assign a temperature from the vector to the loop variable temp, which
the compiler deduces to be a double.
We add this to our running sum then when the loop is done we perform a
simple division to get the average.
Notice that I'm using the vector's size method which returns the
number of elements in the vector.
In this case, it will return 4.
The range-based for loop can also use an initializer list as a collection.
Let's see that one.
This example also calculates the average before temperatures.
Notice how we can explicitly provide the collection right in the for loop.
This is sometimes handy when you know the elements of your collection
ahead of time, and they won't change.
The only downside is that you have to calculate the size as you go.
In this last example, we can use the range-based for loop
to iterate over a string which is a collection of characters.
In this case the string is the literal franc, but it could be a variable.
We're going to discuss strings in the next section of the course.
Well, that pretty much covers the basics of the range-based for loop.
Let's head over to the IDE and see some examples.
I'm in the CodeLite IDE in the section 9 workspace in the
range-based for loop project.
What I'd like to do in this example is go over a couple of
examples of using the range-based for loop with an array, with
a vector and with a string.
So the first thing we'll do is just use a simple array.
And you'll notice that I've already included vector right up here since
I'm going to use vector in a minute.
So let's create an array of integers, and we'll call it scores.
And we'll initialize it, let's just say 10, 20 and 30.
Okay, so what we want to do now is we want to iterate
through that collection.
It's an array in this case, using the range-based for loop.
It's as simple as can be.
We can say for int because we know we've got integers here.
And what do we want to call each int, we'll call it score because
that's what it is a single score.
Then we have the colon and then we provide the name of the
collection, in this case, scores.
So that's the loop header.
And then all we really need to do here is just say
cout and display the score.
That's it.Let's run this.
And that's exactly what we get 10, 20 and 30.
Now as I mentioned in the slides, we don't have to provide that in there.
We can simply use the auto keyword.
And what's going to happen here.
I mean it's pretty straightforward, but it's important that you
understand what's going on.
You're telling the compiler to figure out the type.
So the compiler is going to come in here and say, okay, what's going on.
The collection is scores, okay.
Scores is an array of integers.
So this must be an int.
So it's going to deduce that type right here to be an int.
Same as we did before.
As I mentioned, this is not a big deal, it's easy to type
in, it's easy to type auto.
But collections in c++, especially generic collections and templates
get really crazy syntax.
And sometimes it's very difficult to exactly the type that you want.
And this just makes it so easy.
You just type auto and the compiler will figure it out, which is great.
That's what we're doing here.
We just printed out the scores really, really easy.
Let me run this.
Using the auto keyword now, you can see the behavior is exactly the same.
All right, perfect.
Let me comment that out, and let's do another example.
In this case, we'll create a vector.
So let's create a vector of doubles.
And we'll just call it temperatures.
And we'll initialize these to let's say 87.9, 77.9 could be
really any numbers you like and 80.0 and how about 72.5.
So those are the 4 temperatures that I'm interested in.
Maybe their temperatures per week, per year, per month, it doesn't
really matter, it all depends on what you're trying to do.
Now what we want to do is we want to calculate the average of
the mean of those temperatures.
All right, so we're going to need the average itself.
So we'll just call it average temp, and it's a double.
We'll initialize that to 0.
And we also need a double that's going to be the running total
because we need to sum them all up and then divide them by
whatever size that vector is.
In this case, it happens to be 4 but it could be any size we want.
So there's my double.
I'll call it total, and I'll initialize that to 0.
All right, so now let's loop through that vector.
So we'll say for auto.
Let's create the variable temp, that'll be one of those
temperatures one at each iteration.
And the name of the collection is temperatures, right.
What do we do, we say total plus equals temp,
and I'll scroll up just a little bit give myself a little bit of room.
That's it.
Now we divide by the size of that temperatures vector.
But before we do that, always make sure that that size is
not equal to 0 because we don't want to divide by 0 error.
So we'll just say something like if temperatures.size, that's
the method for the vector, if that's equal to 0, then we don't
want to do the division, right.
So what do we want to do we want to make sure it's not equal to 0.
If it's not equal to 0, it's safe to divide and what I'll say
is as simple as average temp is equal to the total divided by the
temperatures.size again, number of elements in that vector.
That's it. Notice we don't have to do any casting here because total --
this is an unsigned integer right here it's going to return the size
which is an unsight integer but total we defined as a double so
it's going to do double division.
All right, so that's it we'll output now.
We'll say something like average temperature is average temp.
We'll put an endline at the end, and let's run this.
There's the average temperature, 79.575.
Now let me show you one of the io manipulators that you can use.
And as I said, I'll cover these later on in the course.
There's a whole bunch of them.
They're not all that important, but they'll they're important
to help us format our output.
What we can do is we can say -- first thing, we need to do is we need to
go up top here and include io manip.
That's the io manipulation operators.
And what we'll do here is right before we output, we can say cout, fixed and
then set precision to let's say 1.
That's 1 number after the decimal point, and it will round.
So in this case, let's run that and now you'll see this formatted as 79.6.
I think before, it was 79.575 or something like that I don't recall.
But it's going to round it up to 79.6.
It's always going to have one digit to the right of the decimal point.
If this is what you need, this is an easy way to do it.
Otherwise 79.575 works for me.
All right, so that'll take care of this example.
Let me show you a couple more examples.
And again I'll comment these out so they don't keep executing.
Let's put in an initializer list right into the loop.
This is not something you see very often.
But I wanted to show you in case you do see it, you know what's going on.
In this case, we'll say 4 again auto and the value it will be val.
Then right in here, we can put the initializer list.
So we can say 1, 2, 3, 4, 5.
Sometimes you see this when you know that these numbers are ahead of time.
And in this case, we could just say cout val and we can do endline here.
So what's going to happen is it's going to iterate
through that collection.
Remember, this is a collection and it's going
to display 1, 2, 3, 4 and 5.
And let's run that real quick.
And there you can see the 1 2 3 4 and 5.
Now the last example i want to show you is with a string.
Now there's two kinds of strings in c++.
There is a c style string, and there's a c++ style string.
I'm going to cover these in the next section.
What we're going to use here is just a c style string.
That's what we've been using all along.
That's a bunch of characters inside double quotes.
So what I want to do is I'm just going to say for again auto, in
this case, it's going to be a character type, I'll call it c.
And my collection is basically a bunch of characters, right,
a sequence of characters.
So this is a test.
That's it.
What can I do in here.
Well, I can output the character.
And I'm not going to put a new line because I don't want a new
line at the end of every character, that'll print them up and down.
In this case, it should just print that string right back out at me.
And there you see right up here, this is a test.
So it's printing it out directly out at me.
Suppose I wanted to skip the spaces.
How would I do that?
Well, I would just filter the spaces out.
I would say if the character I'm looking at c in this case,
right, is not equal to a space, then print the character.
So what's going to happen here.
Again, each iteration I'm looking at that character.
If it's not a space, I print it.
If it is a space, I'm not doing anything.
So I'm basically just getting rid of all the spaces inside that string.
So when I display that, you should see -- you see that right there, this
is the test all bunched up together.
Okay, now suppose I wanted to replace the -- and again, we're
not changing the string here, we're just printing out the
string, one character at a time.
Suppose what I wanted to do was every time there's a space I want
to replace it with a tab character, I want to display the tab.
So I'm going to spread these characters out a little bit.
Well, we can change the logic here a little bit.
And again, let me comment this out so it's available for you to play with.
And I'll do something like that just.
So I can just modify a little bit of code and get this to run, right.
Okay, so we're here in the same position.
I'm going to comment this out.
And so I'm reading the string again, I've got each character in c.
And I'm going to say if c is the space, then I don't
want to print out the space.
What I want to do is, I want to print out a tab.
And if you remember the tab is a /t.
Otherwise, I just want to print out the character, right, anything except
the space, something like that.
So let's try that out.
And there you go.
It says this then you see a tab is then a tab a and a
tab and test and so forth.
We can play all kinds of games.
You can replace one character with another.
You can create your own little cipher if you want that you can
send across to a friend and they can decipher it on the other side.
Anyway, that's pretty much the range-based for loop.
There's a couple of examples I've shown you here that hopefully
make it really, really easy.
I mean this is so much simpler.
Notice again, there's no int i.
There's no ++I.
We're not counting.
We're simply looping through a collection, and we don't even have to
worry about the type with the auto.
So it makes it really easy to think but a very high level to solve your
problems without getting bogged down with all the little details.
Okay, so, that's the end of this video.