So at this point, you may be wondering how we can allocate an entire array
of integers and store its address into a pointer to an integer.
That's a good question, and it's critical that you understand
the relationship between arrays and pointers in c++.
Remember that the value of an array name is the location or the address
of the first element of the array, and the value of a pointer is an address.
So if a pointer points to the same type of data, as the array
elements, then the pointer and the array name are the same
as far as c++ is concerned.
The only difference is that the array name is not a variable,
so you can't change it.
But otherwise, all the calculations done to access array elements
can be done with the array name or the pointer name.
In this example, we have scores as an array of three integers.
If you display scores, then the value of the array name is the address
of the first element of the array.
What if I dereference scores?
Wait a minute scores is an array, how can I dereference that?
Sure, scores is the address of the first array element.
So if i go to that address, which is what dereferencing
is, I get the integer.
So the output statement for dereferencing scores displays
100, the first array element.
Now if I declare score pointer as a pointer to an integer and I initialize
it to scores, notice that the value of score pointer is the same as scores.
So when I dereference score pointer, we get the same results,
the value of the element at that location which is 100, in this case.
I know this can be a bit confusing.
And when we head over to the IDE, I'll draw it out visually so you
can see exactly what's happening.
So if we can pretty much use an array name and a pointer name
interchangeably, that means we should be able to use array
subscripting on a pointer, right, and that's absolutely correct.
If score pointer points to the first element of the score's
array as it does in this example, then when we display score
pointer sub-0, we get a 100.
Score pointer sub-1 is 95.
And score pointer sub-2 is 89.
That's weird, right.
Well not really if you understand that c++ doesn't really have true
arrays, and that arrays are just the address of the first element in a
chunk of memory then this makes sense.
So does that mean that we can add the offset to the pointer variable then we
can make a point to any array element.
And again, yes, it does.
Let me show you how.
We're using the same example here.
Notice that when we display score pointer, we get back an address.
If we add one to score pointer, then you can see that the value of score
pointer has increased by 4 not by 1.
Why?
Because we're not adding 1 to the pointer value, we're adding the size
of 1 integer to the pointer value.
The pointer doesn't hold integers.
It holds addresses of integers.
So when we add 1, we're adding the address of the next
integer, which is 4 bytes away.
If we add 2, we increment score pointer by 8 which is 2 integers away.
This is the basis of pointer arithmetic, which we'll talk
about in the next video.
Once we have score pointer pointing to the integer that we want,
we can simply dereference the pointer to get to the integer.
Let me show you how that works.
Here's the same example except that I'm dereferencing the expression.
Notice that how we follow the pointer and display the
integer that we point to.
In this case, we're moving along the array using the pointer.
That's pretty cool.
Let's see this all together so it makes more sense.
This table shows the equivalence between arrays and pointers.
Notice that we can access array elements using array subscript
or pointer subscript notation, using either the name of the
array or the name of the pointer.
You can also see we can use array offset or pointer offset
notation also, using either the array name or the pointer name.
Take your time with this.
I know it can be confusing, but when it clicks, you'll be able to
easily understand more advanced memory allocation principles.
Let's head over to the IDE.
And we'll go over some of the examples in this video.
Okay, so I'm in the IDE.
I'm in the section 12 workspace in the arrays and pointers project.
I've gone ahead and written some code that uses array subscript
notation, pointer subscript notation, pointer offset notation and array
offset notation just so that we can walk through this and you can
really understand the equivalence of pointers and arrays in c++.
So let's get started here.
First of all, I've created a scores array of integers right here.
And I've initialized it to 100 95 and 89.
And that's it over here in this little box over here.
So this is 100, this is 95 and this is 89, and it's scores.
And let's assume that this is at location 1000.
So what that means is that this integer 100 is at location 1000.
This integer 95 is at location 1004, assuming that we've got 4 byte
integers which I do on my machine.
And this 89 is at location 1008 in memory.
Okay, we know they're contiguous because it's an array.
Perfect, so when we display scores here, the name of an array is the address
of the first element in the array.
So in this case, it's a 1000.
So we expect this to print a 1000.
Now obviously, when i run this on my machine, I'm going to get a
different value, but that's okay, now I've created another variable
right here, called score pointer.
Okay, so I'm going to put this guy -- actually, I'm going to put
them right here score pointer.
And score pointer, we're assigning two score pointer scores.
Scores is the array name, which is the address of the
first element in the array.
So score pointers have a 1000 in it right now, and there's my pointer.
Okay, there's no need to put the ampersand here, ampersand
score since score the name of the array already is an address.
So now we print out the value of score pointer.
Well, it's a 1000.
So these two values will print the same because they are the same,
the name of the array and we just stored the name of the array, which
is the address into score pointer.
So now let's do array subscript notation.
This is what we've been doing all along.
Scores is an array, so score is sub-0 now look at what
the compiler is doing here.
The compiler is saying scores sub-0 is really 1000, right, that's what
scores is plus 0 integers away.
So that's gonna be a 1000.
So it's gonna grab whatever is at location 1000 and display
it, which is in this case 100.
What about scores sub-1.
So in the case of score sub-1, it's going to have scores,
again, which is a 1000.
And it's going to go 1 away from that.
And it's not going to be a 1001, it's going to be 1 integer away
from it because it knows its scores is an array of integers.
So in this case, it's going to be a 1004.
So it's going to go to a 1004.
It sees the 95 and displays that.
Then the same thing with score sub-2 will display the 89.
Okay, that's using array subscript notation.
Now take a look at pointer subscript notation.
It's exactly the same.
The only difference is that I replaced scores with score pointer, right.
Therefore, we've got pointer and subscript.
So again, score
pointer sub-0.
What is score pointer?
A 1000, in this case, right, it's right here plus 0 away.
So it's going to go to location 1000 and grab what's there,
which is going to be 100.
Remember, when we use subscript notation, we're basically
grabbing what's at that address.
Same thing with score pointers sub-1.
It's going to go to a 1000 plus 1 integer away which is a 1004.
And there's the 95, and here's the 89.
Okay, so hopefully, that makes sense.
Now here we've got pointer offset notation.
We don't have any square brackets, so we're using the offset.
Now let's start right here.
What happens if I dereference score pointer, follow the
pointer to where it's pointing.
Score pointer is a 1000.
I'm going to dereference it, which means I'm going
to go to that location.
Now I'm here, and what do I do, I display 100.
Now what about this line right here.
Let's go over that one carefully.
We're going to say score pointer plus 1.
Now notice parentheses, and then we dereference.
So what happens first, what's in the parentheses.
What score pointer?
1000, it hasn't changed.
Plus 1 what?
Plus 1 whatever score pointer is pointing to, integer in this case.
So 1004, I'm dereferencing 1004 which means I'm going to
1004 and getting what's there.
That's the 95.
Same thing here, I'm going to 1008, and getting what's
there which is an 89.
Okay, so there's pointer offset.
And then the last one is array offset.
Notice here, I'm using scores.
Well, what is an array name.
Well, an array name is the address of the first element in the array, right.
So dereference scores is the same as saying score sub-0 here.
So in this case, scores is a 1000.
So go to a 1000 and grab what's there, display a 100.
Okay, here we've got scores plus 1 dereferenced, right.
What's scores? The name of the array is the value of the address
of that first element, right, there a 1000 plus 4, right.
And I'm dereferencing that again.
So you can see it's exactly like what we did with pointer offset.
So we've got 95 and 89.
So the output from this program is going to be exactly the same,
array subscript, pointer subscript, pointer offset and array offset.
They're equivalent as far as c++ is concerned.
Now, why is this important?
This is important because when we allocate arrays dynamically
on the heap, we can -- we have to be able to walk them right, use
them, display them, change them, do whatever we like with them.
Well, we have a pointer to them.
And that's what we got back when we mute that storage.
That pointer to that array, it's going to be a pointer, so we can use
pointer subscript notation if we want.
We could use pointer offset notation if we want, right.
Either one we can use and we're able to get to that array and those array
elements really, really easily.
All right, so let me run this and we'll be sure that
we get the correct values.
And you can see here, this is the important piece.
The value of scores is that hex address right there.
And the value of score pointer is the same hex address.
Makes sense, right, because we assign scores to score pointer.
And scores is the address of that first element in that array, 100.
Then we go through array subscript notation.
We print out 100 95 89.
You can see pointer subscript, pointer offset and array offset, it
seems all exactly the same thing.
Okay, take your time, understand this, walk through it, play around with
it, change a few things if you like.
It's really important.
Once you understand the equivalence of arrays and pointers in c++,
it really opens up the world of power.