In this video, we'll learn how to access the data that
a pointer is pointing to.
In order to access the data that a pointer is pointing
to, we need to follow the pointer to where it's pointing.
This is called dereferencing the pointer.
Let's say that score pointer is a pointer to an integer
and it has a valid address.
And in order to access the integer that score pointer is pointing to, we
use the dereferencing or indirection operator, which is the asterisk.
I know what you're thinking, the asterisk didn't we just use the
asterisk to declare the pointer?
Yes, and lots of people over the years have been critical of c++'s
choice to use the asterisk to both declare and dereference a pointer.
But it is what it is.
And once we understand how all this works, it isn't confusing at all.
Let's take a look at the example.
First, we declare score to be an integer and initialize it to a 100.
Then we declare score pointer to be a pointer to an integer
and initialize it to the address of score.
Now score pointer points to score.
If we want to get to score via the pointer, then we must
dereference the pointer.
Notice that in the first output statement, we're using the
dereference operator on score pointer.
This follows the pointer and gives us what it points to.
In this case, we display 100 since score pointer points to score.
When we dereference a pointer on the left hand side of an
assignment statement, this results in an l value or the address of
what score pointer is pointing to which in this case is score.
So we store 200 in that address, which is the address of score.
So now, we just change the value of score indirectly via the pointer.
Notice the syntax makes sense.
We use the asterisk to declare the pointer
and then once the pointer is declared, the asterisk
is used to dereference it.
Let's see another example.
In this example, we declare two doubles, high temp and low temp
and we initialize them to 100.7 and 37.4.
We also declare temp pointer as a pointer to a double and
initialize it to point to high temp.
So if we have a pointer and we want what it points to,
we dereference the pointer.
That's exactly what we're doing in the first output statement.
We're following or dereferencing temp pointer, which gives
us what it points to.
And in this case, we display 100.7.
Now in the assignment statement, we're storing the address
of low temp to temp pointer.
So now temp pointer is pointing to low temp.
And again, if we want the low temp, we dereference temp pointer and
that gets us to where it's pointing.
So far I've used instant doubles but the data type can be anything.
In this case, name is a c++ string object with the value Frank.
And string pointer is a pointer to a string, and we
initialize it to point to name.
If we dereference string pointer, as in the first output
statement, we display Frank.
If name then changes to James and we execute the same output
statement, then we display James.
Let's head over to the IDE, and we'll see some more examples of
dereferencing pointers in live code.
Okay, so I'm in the IDE, and I'm in the section 12 workspace
in the dereference project.
I'd like to go over some examples of dereferencing
pointers, so you're really clear as to what's going on here.
Let's start with a very simple example here.
And again, we'll draw it out, we'll work through it before we run it.
In this case, I've got an integer called score, and I'm
initializing it to a 1000.
So let's say that score is over here.
It has storage obviously.
We have a 100 in it.
And let's say that it's at location a 1000 again.
So that's my score variable.
Now I've got another variable right here, score pointer
is a pointer to an integer.
So here's score pointer, and it's a pointer to an integer that means
it can hold addresses of integers.
And I'm initializing it to the address of score.
The address of score is a 1000.
So we're putting a 1000 in this variable, which means
that that's my pointer.
So if you want to follow the pointer and get to what it's pointing to,
you need to dereference the pointer.
That's exactly what I'm doing right here.
I'm dereferencing score pointer.
So it's going to follow the pointer to where it's pointing.
And in this case, it's pointing to that memory address
right here which has a 100.
That's what displays.
In this case, I'm dereferencing the pointer again
but it's on the left hand side of an assignment statement.
Remember, the left-hand side of an assignment statement is an
address or a location that's where we want to store things, right.
After all, when we're assigning something we're
storing that value somewhere.
In this case, I'm dereferencing score pointer.
So if i dereference score pointer, I follow the pointer to
this address right here, right.
So I'm putting 200 in here now.
So now when I come back and display
the dereference score pointer,
it's going to go back over here.
But this time, it's going to see a 200.
And if I just display score all on its own since score
is that variable, right, it's going to print 200 as well.
Okay, so again play with these, and you can follow these pointers
around and see what's happening.
So let's run this, and we're expecting 100, 200 and 200.
So let's give this a run, and there you go, 100, 200 and
200, exactly what we expected.
All right, let's do a few more of these.
I'm going to comment out this code and then we'll walk through it together,
and I'll do some diagrams as well.
Okay, so in this case, what do we have?
We have two doubles.
We have a double called high temp, and I'll draw it over here.
So this double is called high temp.
And its value is 100.7.
And let's again say that this is at location 1000 in memory.
Then I've got another double right here called low temp.
And let's say that its location is at 2000 in memory, and its value
right now is initialized to 37.4.
Okay, pretty easy.
Now here we've got a pointer, called temperature pointer.
So there's my temperature pointer.
It's got storage associated with it, and we're initializing it to the
address of high temperature where the address of high temperature is a 1000.
And there's my pointer.
Okay, and when we're doing this, we always have to be sure that we got it -
we have our types correct.
Temp pointer can point to a double, high temp is a double.
So all looks good here.
Now if we dereference the pointer, right here, we're
going to follow that temperature pointer to where it's pointing.
It happens to be pointing here to high temp.
And we display 100.7.
Now what we're doing here is we're changing where
the pointer is pointing to.
So we're saying temp pointer now holds the address of low temp.
So what we're doing is we're changing that value right here.
We're breaking this link right here.
And we're now putting a 2000 in here, which is the value of low temp.
So this now points to low temp.
And when we dereference the pointer now, we follow the pointer to where
it's pointing, it's not pointing here.
So in this case, it'll print out 37.4.
Okay, so let's give that a run,
and we've got the 100.7 and the
37.4, just like we expected.
All right, now let's do a couple more complicated examples.
This example isn't more complicated, but it's a little bit different.
In this case, we've got a string object right here, called name.
And a string object is an object so I've got my object here, and
it's got a Frank string in it.
So that's kind of what name looks like.
Let's again say that it's an address a 1000, that way it's easy to follow.
Here I've got a string pointer.
So here's my string pointer.
Again, it's a variable that points to a string object.
So in this case, my string pointer holds the address of
name, which is a 1000, and there's my pointer, all set up.
Now if I want to follow the string pointer to where it's pointing
to, I de-reference it right there.
So in this case, I'm following the pointer to where it's pointing to
and I'm printing out what's there.
In this case, Frank right here.
Okay, but what if we change name, not through the pointer,
but just name itself, we can certainly do that, right.
In this case, we're changing name to James.
So we're changing this right here to James.
And now we're coming back here and dereferencing the pointer again.
We never change the pointer.
The pointer is still pointing to the same name, right, the
same memory address a 1000.
But this time we're going to see James there.
So it's going to print James instead of Frank.
This really shows you the difference between the pointer
and what it's pointing to.
In this case, we never modified that pointer, but the area we
were pointing to was modified.
So let's give this a run, and we expect Frank and James to display.
And there they are, Frank and James.
Okay, so let's do one last example.
And this one will really show you the difference between a
pointer and what it's pointing to.
And let's work through this one.
What we've got here is we've got -- and this is where it
starts, right here on line 41.
We've got a vector of string objects, called stooges.
And it's initialized to Larry Moe and Curly.
All right, so what does that look like?
Well, let's put it over here.
Let's say it's called stooges.
It's at a location a 1000 again.
And stooges is a vector.
So it's a vector of three items in this case.
And each one of those items is a string.
So here's Larry, here's Moe and here's Curly.
And these are strings.
I won't put the quotes around them just to save a
little writing time here.
So that's my stooges vector.
Now I've got a vector pointer.
All right, so it's right here, it's called vector
pointer, it's a variable.
And I'm initializing that to null pointer.
Right now it's pointing nowhere.
And that's perfectly fine because pointers are variables.
Here is where I'm initializing my vector pointer to point somewhere.
So at this point, I'm saying vector pointer is the address of stooges.
Well, the address of stooges is a 1000.
So I'm putting a thousand in here now.
So it's no longer a null pointer.
And I'm pointing there.
So now how do I work with that vector through the vector pointer.
It's really straightforward as long as you've got your syntax correct.
And you're - the way it works is, is very very logical.
So suppose I want to print out Larry, just Larry.
And I want to go through this pointer.
I don't just want to say stooges.
Obviously, I could say something like stooges.at0, right.
That'll definitely print out Larry inside an output statement.
That's basically what I want to do.
But I want to do it through the vector pointer.
So what do I do?
Here's the syntax right here, and I'll go over really carefully here.
So I take my vector pointer
and I dereference it.
That gives me the vector that I'm pointing to.
I put some parens around it because that's - I want the
the priority to be high here.
That gives me the vector.
So all I need to do now is say .at0.
Remember, if I follow my vector pointer, what do I get?
I get stooges.
So that's effectively the same as doing that.
So when I execute that code right there, it'll print out Larry.
Okay, hopefully, that makes sense.
It may take a little bit to understand, and these parens are
critical right here because we want to dereference that pointer
before we use a dot because the dot has higher precedence
than the dereference operator.
So it's important that you put those parens around there.
Suppose I want to print out all of the stooges through
the vector pointer? Same idea.
What we can do is we can use a range base for loop.
And what's the collection.
Well, the collection is not vector pointer.
It's what vector pointer is pointing to.
So if i dereference a vector pointer, then really what I'm
getting in here is stooges, right.
That's what I'm pointing to.
And now you can see the syntax is really straightforward.
For every stooge and stooges, print it out.
So it's going to print out Larry, Moe, and Curly.
Okay, again we're following that vector pointer.
We get the vector.
And then once we're at the vector, we can do whatever we want.
So here's an example, again, of really, really distinguishing between
the pointer and what it points to.
Remember, pointers are simple.
It's just a simple variable that holds addresses.
What it points to can be super complicated.
I mean we can have vectors of vectors of vectors.
And we could certainly get to them through the pointer by
dereferencing the pointer.
Once we have them, we could do whatever we want with them.
Okay, so that finishes up this video.