|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Home : Math & Science : Computer Science Study Guides : Pointers : What Are Pointers? : Pointers and Arrays
Pointers and Arrays
They're the same!
Ok, that's not exactly true. Pointers and arrays are not
exactly the same entity, but they're very close. In fact, an
array is for all intents and purposes a constant pointer.
What?! How can an array be a pointer, and how can a pointer be
an array? Before we delve into that question, we first need to
discuss pointer arithmetic.
Pointer arithmetic
If you have an integer variable, you can add the number 1 to it
and the contents f that variable will increase by 1. You could
add an 'a' to a character variable and it would increase by the
value 'a'. With pointers, arithmetic is also possible, but a
little quirky. Once we understand how pointer arithmetic
works, however, it is an invaluable aid. In fact, as we'll
see, arrays work properly because of pointer arithmetic.
As we've seen, pointers store an address in memory. If we have
an integer pointer, it points to a memory location that can
hold an integer. If we have a character pointer, it points to
an address in memory that can hold a character. And so forth.
So all a pointer really holds is a big number, say, for
example, 0x4b14 (or in binary 0b0100101100010100). We might
expect that if we added a number to this, say the number 1,
that the pointer would then hold the number 0x4b15.
Fortunately, that is not always the case.
When you add numbers to pointers, the address stored in the
pointer isn't necessarily increased by that many bytes. That
would cause trouble, for example, with an integer pointer.
Let's say we had a series of integers in a row located at
addresses 0x4b14, 0x4b18, 0x4b1b, and 0x4b1f (remember that
integers on most modern machines, and the example machine we're
dealing with here, are a 4-byte data type, meaning they take up
4 bytes). Let's say that we have a pointer ptr that
currently holds the address 0x4b14. If we executed the
instruction: ptr = ptr + 1; without special arithmetic, if
ptr were just an integer variable, we would end up with the
value 0x4b15. But this number doesn't make any sense in
terms of memory addresses. A single integer resides at the
memory addresses 0x4b14 through 0x4b17, so accessing the memory
at address 0x4b15 would be accessing into the middle of an
integer. Fortunately, this is not how pointer arithmetic works.
When you add a number to a pointer, the computer knows what
type of data the pointer points to, and multiplies the number
you're adding by the size of the pointer's type before adding
it to the pointer. For example, taking the case from above, if
we have the following code:
ptr = ptr + 2and if ptr is a pointer to an integer and originally contained the value 0x4b14, then the computer really does the math: ptr = 0x4b14 + 4*2 = 0x4b1c meaning that it adds 4 bytes to the pointer for every 1 unit being added. If we were dealing with a character, normally a one byte data structure, then the math would be: ptr = 0x4b14 + 1*2 = 0x4b16 and if we were dealing with some big data structure that took up 200 bytes for every structure, then the math would be: ptr = 0x4b14 + 200*2 = 0x4ca4 ![]()
Figure 3.1: Adding 1 to an integer pointer
Another possible way to do pointer arithmetic is to subtract
one pointer from another. Again, let's go back to the example
where we have the four integers in a row at addresses 0x4b14,
0x4b18, 0x4b1b, and 0x4b1f. Let's say we have four pointers,
ptr1, ptr2, ptr3, and ptr4, each pointing at
the addresses in order. With normal arithmetic, ptr4 -
ptr1 would result in the number 12 meaning that there are
twelve bytes between them. However, with pointer arithmetic
the computer takes into account the size of the data type
involved, in this case an int. As such, ptr4 - ptr1
actually results in the value 3, meaning that the two values
are separated by 3 integers.
![]()
Figure 3.2: Subtracting integer pointers: ptr1 - ptr2 == 2
Enough stalling. What do you mean they're the same?
In the C/C++ language, pointers and arrays are closely
related. As it turns out, an array is just a series of
variables laid out in a sequence, one after the other. If you
were to declare an array of four integers, you would end up
with a situation very similar to the one described above.
![]()
Figure 3.3: An array of three characters, arr
As a starting example, let's declare a few variables:
int arr[4]; int *ptr;We know that to access individual elements of an array we use the [] operator. For example, to access the first element of the array arr we would do arr[0]; to access the next element, arr[1], and so forth.
Like any other integer, we can use the & operator to get
the address of an element in the array. For example, to get
the address of the first element in the array, we could do
&arr[0] and to get the address of the last element in the
array we could do &arr[3]. So let's say that we want
ptr to point to the first element of the array:
ptr = &arr[0];Easy enough. Now with that done, let's say we want ptr to point to the second element of the array. We could do this one of two ways. We could do it just as we did above, as in: ptr = &arr[1];or, we could use our knowledge of pointer arithmetic to increase the value of ptr by 1, as in: ptr += 1;Just like every other time we've seen a pointer to an integer, we can then dereference the pointer to get at the integer's memory. So in this case, we could do *ptr to access arr[1].
So, if pointer points to the beginning of the array, as it does
after executing the instruction ptr = &arr[0], then we now
have two ways to access each element of the array. The first
way is the one you already know, accessing the element in an
array at position n, by writing arr[n]. The second
method takes advantage of pointer arithmetic. We use pointer
arithmetic to move us to the nth place in the array, and then
dereference it to get the integer at that index. This means
that arr[n] and *(ptr + n) are synonymous.
We can take this one step further. As mentioned earlier,
arrays are basically pointers. In fact, the variable arr
is itself a pointer (a constant one, meaning we can't change
the address it points to, but nonetheless it points to
something). As arr is itself a pointer, we can do pointer
arithmetic on it like any other pointer, so we could access the
nth element of arr using *(arr + n). This is exactly
the same as doing arr[n], and the process of adding the
value n to the pointer arr and then dereferencing it is
most likely what is taking place behind the scenes in the
computer when you use arrays.
Similarly, we can use the [] operator on a pointer. If
ptr = arr, then it is perfectly valid syntax to do
ptr[0], ptr[1], etc.
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contact Us | Privacy Policy | Terms and Conditions | About
©2006 SparkNotes LLC, All Rights Reserved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||