Wednesday, August 15, 2012

Basic Pointer Operations in ANSI C

Pointers are variables that hold a memory address. Usually that memory address is the first memory address of another variable or a dynamically allocated block. The type of the pointer indicates to what kind of variable it points to.
Example:
    /*A pointer to a int variable*/
    int   *myPointer;
    /*A pointer to a char variable*/
    char  *myCharPointer;
    /*A pointer to a double variable*/
    double *myDoublePointer;
    /*A pointer to a time_t struct*/
    time_t *myTime_tPointer;
Observation:
The size of a pointer is not correlated with the type of the pointer. All pointers have the same size and that size depends on your platform (more exactly your memory space). So, if your memory space is [0x00000000, 0xFFFFFFFF], the size of your pointers will be 4 bytes.
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    /*A pointer to a int variable*/
    int   *myPointer;
    /*A pointer to a char variable*/
    char  *myCharPointer;
    /*A pointer to a double variable*/
    double *myDoublePointer;
    /*A pointer to a time_t struct*/
    time_t *myTime_tPointer;

    printf("Size of an int pointer     : %d\n"
           "Size of an char pointer    : %d\n"
           "Size of an double pointer  : %d\n"
           "Size of an time_t pointer  : %d\n",
           sizeof(myPointer),
           sizeof(myCharPointer),
           sizeof(myDoublePointer),
           sizeof(myTime_tPointer));

    return 0;
}
/*Output:
Size of an int pointer     : 4
Size of an char pointer    : 4
Size of an double pointer  : 4
Size of an time_t pointer  : 4
 */
The main pointer operations are referencing and dereferencing and both have operators in ANSI C.

The referencing operator & is used for retrieving the memory address of a non-pointer variable, while the dereferencing operator * is used for retrieving the value that a pointer points to. 
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int myVariable = 3;
    int anotherVariable;
    /*A pointer is usually initialized to NULL. This means
     that pointer will not point to anything for now*/
    int *myPointer = NULL;

    /*This operation is called referencing. This means that the
    pointer will now point to the value of myVariable*/
    myPointer = &myVariable;

    /*This operation is called dereferencing. This means that
    a variable will take the value of the pointer*/
    anotherVariable = *myPointer;

    printf("The value of myVariable       : %d\n"
           "The address of myVariable     : %p\n"
           "The value of myPointer        : %d\n"
           "The address of myPointer      : %p\n"
           "The value of another variable : %d\n"
           "The address of anotherVariable: %p\n",
           myVariable,
           &myVariable,
           *myPointer,
           myPointer,
           anotherVariable,
           &anotherVariable);
    return 0;
}
/*Output:
The value of myVariable       : 3
The address of myVariable     : 0xbfb5e874
The value of myPointer        : 3
The address of myPointer      : 0xbfb5e874
The value of another variable : 3
The address of anotherVariable: 0xbfb5e878
 */
Observation: If not initialized with NULL or a valid memory address, a pointer will point to a random address. If you will try to access it, you may trigger a segmentation fault and your program will crash.

Assuming we have a variable v and a pointer p, we can establish empirically the following equivalencies:
v is the same as *p (Both indicate a value)
&v is the same as p (Both indicate to a memory address)
Going back to the example with the size of the pointers, we can now use the dereferencing to indicate the size of the types that the pointer points to:
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    /*A pointer to a int variable*/
    int   *myPointer;
    /*A pointer to a char variable*/
    char  *myCharPointer;
    /*A pointer to a double variable*/
    double *myDoublePointer;
    /*A pointer to a time_t struct*/
    time_t *myTime_tPointer;

    printf("Size of myPointer's type        : %d\n"
            "Size of myCharPointer's type    : %d\n"
            "Size of myDoublePointer's type  : %d\n"
            "Size of myTime_tPointer's type  : %d\n",
            sizeof(*myPointer),
            sizeof(*myCharPointer),
            sizeof(*myDoublePointer),
            sizeof(*myTime_tPointer));

    return 0;
}
/*Output:
Size of myPointer's type        : 4
Size of myCharPointer's type    : 1
Size of myDoublePointer's type  : 8
Size of myTime_tPointer's type  : 4
 */


No comments:

Post a Comment

Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!

Related Posts Plugin for WordPress, Blogger...
Recommended Post Slide Out For Blogger