Broad Network


Pointer and Array in C++

C++ Taking the Bull by the Horns – Part 12

Forward: In this part of the series we shall see the relationship between the array and the pointer.

By: Chrysanthus Date Published: 22 Aug 2012

Introduction

This is part 12 of my series, C++ Taking the Bull by the Horns. In the previous part we saw the meaning of an array. In this part of the series we shall see the relationship between the array and the pointer.

As I said, I present C++ to you in this series the way the inventors see it. I do the presentation in simple terms. I believe that in this way you would understand better. Remember, take things in this series as I give you. Do not try to add or subtract any idea in your mind to or from what I give you; that would be misleading. You can do any subtraction or addition after you complete the series.

Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.

Recall
An array is a set of consecutive objects of the same type in memory. When talking about pointers, two objects are involved: the pointer object and the object pointed to. While the object pointed to has an object type and would have a value, the pointer object has but the memory address of the pointed object. Remember: an object is a region in memory.

Constant Pointer
Consider the following array:

        int marks[10] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};

From one of the previous parts of the series, we saw that a constant pointer is a pointer object whose content (a memory address) cannot be changed. Of course this address is the address of the pointed object. In this case the content of the pointed object can be changed but the address of the pointed object, present in the pointer object, cannot be changed.

A similar thing happens with array. The array name (identifier) is a constant pointer to the first object of the array. This means that the memory address of the first object in the array is the content of the pointer object and it cannot be changed. In the above array, the value, 43 is an int and is in an int object. The address of this int object is in an object (pointer object) whose identifier is, marks. That is how the array is defined. You cannot change the address (pointer) in the object identified by an array name. You cannot change the address, which is the content in the pointer object identified by marks, above.

You can however, have another object whose content is a copy of the address in the object identified by the array name. This other object is of course a pointer, but it does not have to be a constant pointer.

Note that the constant pointer (marks) for the array is pointing to the first element of the array. This first element is an object of a particular type. So the constant pointer for the array needs to be of the same type as the first element. The rest of the elements (objects) are of the same type as the first element. When defining or initializing an array, the square brackets, makes the object with the address of the first element, a pointer object. The square brackets also make this pointer a constant pointer. C++ implementation takes care of all that for you.

A question you may ask is this: now that the array name is a constant pointer to the first object of the array, how can you access the other elements of the array using the array name. To do this, you make use of the square brackets and the element index, attached to the array name, as we saw in the previous chapter.

Copy from Constant Pointer
Consider the following code segment:

        int marks[10] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};
      
        int *copyPtr;
               copyPtr = marks;

The first line in this code segment is the initialization of an array. The next line is the declaration of a pointer. The third line copies the address of the first element of the array to the pointer object just defined. The object identified by marks, holds the address of the first element (43) in the array. The value of marks, which is a memory address is copied as content to the object identified by copyPtr. This object is a pointer object, which was declared in the second statement. The pointer copyPtr is not a constant pointer, because its definition was not of the form, “Type *const pointerIdentifier”.

Now that copyPtr is not a constant pointer, we can do anything we want with it. Precisely we can change the address it is holding, so that it should point to something else. When it is pointing to some other object, we can get the value of that other object.

Incrementing and Decrementing a Pointer
You can use the increment (++) or decrement (--) operator with a pointer like in the following code segment.

        int *myPtr;
               myPtr = &address;

               ++myPtr;
               --myPtr;

When a pointer is incremented, it points to the next object in memory, not the next byte. In my computer an int object occupies 4 bytes. So for the above int array, incrementing a copied pointer (e.g. copyPtr) will point 4 bytes away to the next object.
Decrementing a pointer points to the previous object (not the previous byte) in memory.

The constant pointer, e.g. marks in the above array cannot be incremented or decremented because it is constant (content address cannot be changed).

When a pointer has been incremented or decremented, getting the value of the pointer using the dereference operator, * yields the value of the new pointed object.

Read and try the following code, which illustrates this using the above integer array:

#include <iostream>
using namespace std;

int main()
    {
        int marks[10] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};
      
        int *copyPtr;
               copyPtr = marks;

                cout << *copyPtr; cout << "\n";

               ++copyPtr;
                cout << *copyPtr; cout << "\n";

               ++copyPtr;
                cout << *copyPtr; cout << "\n";

        return 0;
    }

The output should show the first three numbers in the array.

Adding and Subtracting Integers to Pointer
When you add an integer to a pointer, the pointer points that number of objects ahead, in memory. When you subtract an integer from a pointer, the pointer points that number of objects behind, in memory. So if you add 3 to a pointer, the pointer will point three objects ahead in the memory. Read and try the following code, which illustrates this using a char array.

#include <iostream>
using namespace std;

int main()
    {
        char arrChar[] = {'A', 'a', 'G', 'k', 'F', 'Y'};
    
        char *copyPtr;
             copyPtr = arrChar;

             copyPtr = copyPtr + 3;

                cout << *copyPtr; cout << "\n";

        return 0;
    }

The output of the code should be, k. Note, arrChar is already pointing to the first character, ‘A’. Adding 3 to the copied pointer, makes the copied pointer to point to k, which is 3 objects after.

Array of Pointers
As we said sometime ago in one of the previous series, a pointer does not have a type indicator. To have a pointer, you play around with * and sometimes &. When defining an array of a particular type, you precede the array name with the type indicator. If you want an array of integers, you will precede the array name in the definition or initialization with int. If you want an array of pointers, there is no type indicator for this. However, preceding the array name (identifier) in the definition or initialization with * will give you an array of pointers. * is an operator; it is not a type identifier. Its meaning depends on the context of use. In this case it is like a command that tells C++ to allow only pointers (addresses to memory objects) as values for the array elements. Read and try the following code that illustrates this:

#include <iostream>
using namespace std;

int main()
    {
        float flt1 = 10.1;
        float *ptrflt1 = &flt1;
        float flt2 = 13.2;
        float *ptrflt2 = &flt2;
        float flt3 = 25.6;
        float *ptrflt3 = &flt3;

        float *arr[] = {ptrflt1, ptrflt2, ptrflt3};
    
        cout << *arr[0]; cout << "\n";
        cout << *arr[1]; cout << "\n";
        cout << *arr[2]; cout << "\n";

        return 0;
    }

Even though the array has only pointers, the object pointed to by the pointers, must be of a particular type. In the definition or initialization of the array of pointers, the type of the objects pointed to is the first thing to type. The output should have extra zeros in its decimal places. Do not worry much about that for this basic tutorial.

Note how we have obtained the values of the pointers (addresses), which are elements of the array. We use the array name followed by square brackets. Inside the square brackets you have the index of the element. An example is arr[1]. For the array of pointers arr[1] returns a pointer (address). Preceding that should be *, meaning the value of what the pointer is pointing to. That is how you obtain the value of each pointer in the array.

Remember, the pointers that are values in the array should refer to objects that are of the type specified with the definition or initialization of the array.

Well, let us end here. We continue in the next part of the series.

Chrys

Related Courses

C++ Course
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
NEXT

Comments

Become the Writer's Fan
Send the Writer a Message