Broad Network


Pointers in the Computer language, C

Part 7 of Complete C Course

Foreword: How to create and use a pointer in C

By: Chrysanthus Date Published: 31 May 2024

Introduction

The memory of a computer is a long series of cells. The bit-width of each cell is 8-bits, called a byte. A byte is the space occupied by an English (Western European) character of the alphabet. A location is a consecutive group of memory cells, for storing a fundamental value. An object consists of one or more locations. Each cell for an object has an address, which is an integer, usually written in hexadecimal form. There are three ways of accessing an object in memory. An object can be accessed using an identifier, as illustrated in the previous tutorials of this course. An object can also be accessed using what is known as a pointer. It can still be accessed using what is known as a reference. The focus in this tutorial, is on the use of pointers and references. In the computer language, C, there is the pointed object and there is the pointer object. The pointed object has the value of interest. The pointer object has the start address to the pointed object, as its own value. The pointer object and the pointed object, each has its own identifier.

The Address-Of Operator, &
This is a unary operator. When followed by the identifier, it returns the address of the object of the identifier. Consider the following declaration:

    int ptdInt;

The following expression, using &, returns the address identified by ptdInt:

    &ptdInt

The programmer does not need to know the exact address (number), in order to code.

The Indirection Operator, *
This is also a unary operator, in the context of pointers. It is usually typed in front of an identifier. If used in a declaration of the identifier, then the identifier is the pointer object which holds only the address of the pointed object. It can also be used in front of a pointer object identifier, in order to return the value of the pointed object. The pointed object and the pointer object are two different distinct objects

Creating a Pointer
Take a look at the following code segment:

    float ptdFloat;
    float *ptrFloat;

    ptrFoat = &ptdFloat;

The segment begins with the declaration of the pointed object, ptdFloat, as an ordinary identifier declaration. ptdFloat is an identifier, which just identifies a float object. An actual object (value) could have been assigned (initialized) to it, but in this case, nothing has been assigned to it. Next in the segment, there is the declaration of the pointer object. The indirection operator in front of this identifier means, the object has to hold the address of the pointed object. The object type, float at the beginning of the statement, means the pointed object is a float. The pointer object is always declared, of the same type as the pointed object. ptrFoat is an identifier, which just identifies a pointer object. The value of the pointer object, will be the address of the pointed object.

In the last statement of the code segment, the address of the pointed object is assigned to the pointer object. Note the use of the address-of operator, &. Again, the programmer does not need to know the exact address (number), in order to code.

The last statement (line) above shows that, after declaring the pointer object without initialization, the indirection operator is not needed, to initialize it. In fact, it is a syntax error to use the indirection operator in the third (last) line. In the third line, the pointer object is initialized with the address of the pointed object.

The pointer object is normally declared and initialized with the pointed object in one statement, as follows:

    float ptdFloat;
    float *ptrFoat = &ptdFloat;

The first line of the previous code segment and the first line here, are the same. A value could have been assigned to ptdFloat. The second and third lines of the previous code segment, have been combined into one statement here.

Note in this code, that when declaring and initializing the pointer object, the indirection operator has to be used. However, it is not used if the initialization is to be done afterwards. The pointer object is initialized with the address of the pointed object.

In the following code segment, the indirection operator is used to return the content (value) of the pointed object.

        int ptdInt = 5;
        int *ptrInt = &ptdInt;
    
        printf("%i\n", *ptrInt);

The output is 5. The first ordinary statement, has the value, 5 assigned to ptdInt. In the last statement here, the indirection operator has been used to return the value of the pointed object, pointed to, by the pointer object identifier. So, when used in a declaration, the identifier for the indirection operator would hold the address of the pointed object. When the indirection operator is used in a return expression, in combination with the pointer identifier, the indirection operator returns the value of the pointed object. Note that the first argument in the printf() function, is that for the integer, as both the pointed and pointer objects are of type, int.

Note: in the declaration having the indirection operator, the indirection operator can be typed closer to the object type, or closer to the identifier, or exactly in-between.

Assigning Zero to a Pointer

When declaring the pointer object, the data type of the pointed object has to be used to make both pointer and pointed objects, the same type. However, the value of decimal zero can still be assigned to the pointer object, independent of whether the object type is int, as in the following code segments:

        float ptdFloat;
        float *ptrFloat;
        
        ptrFloat = 0;

or in the segment,

        int ptdInt = 5;
        int *ptrInt = 0;

or in the segment,

        char ptdChar = 'E';
        char *ptrChar;
        
        ptrChar = 0;

In any of the cases, the pointer (identifier) is called the null pointer: meaning, it points to nowhere. That is, it does not have the address of any pointed object. Note: it does not point to the first address in memory. Here, 0 is decimal zero and not hexadecimal zero. Hexadecimal zero would point to the first address of the computer memory.

Pointer to a Pointer

When dealing with pointers, there are normally two objects: the pointed object and the pointer object. The pointed object has the value (content) of interest, while the pointer object has just the address of the pointed object.

It is possible to have another object, that has just the address of the pointer object. That is, it is possible to have another object that has the address of some other object, whose content is an address (for the ultimate pointed object). This new third object is a pointer to a pointer. The following code segments show pointer-to-pointer of integer, and then of float and then of character. The segments also show, how a pointer-to-pointer is dereferenced (obtain value of ultimate pointed object).

        int ptdInt = 5;
        int *ptrInt = &ptdInt;
        int **ptrPtrInt = &ptrInt;
        printf("%i\n", **ptrPtrInt);
    
        float ptdFloat = 2.5;
        float *ptrFloat = &ptdFloat;
        float **ptrPtrFloat = &ptrFloat;
        printf("%f\n", **ptrPtrFloat);
    
        char ptdChar = 'E';
        char *ptrChar = &ptdChar;
        char **ptrPtrChar = &ptrChar;
        printf("%c\n", **ptrPtrChar);

The output is:

    5
    2.500000
    E

The third line of each code segment declares (defines) the pointer-to-pointer. The fourth line of each code segment does the dereferencing of each pointer-to-pointer. Note the use of the indirection operator, twice consecutively, in the third and fourth statements. Note the syntax of the first argument of the three different printf() statements.

Conclusion
When dealing with pointers, there are normally two objects: the pointed object and the pointer object. The pointed object has the value (content) of interest, while the pointer object has just the address of the pointed object.




Related Links

More Related Links

Cousins

BACK NEXT

Comments