About Pointers in C

This topic was published by and viewed 1141 times since "". The last page revision was "".

Viewing 1 post (of 1 total)
  • Author
    Posts
  • DevynCJohnson
    DevynCJohnson
    Keymaster
    • Topics - 444
    • @devyncjohnson

    The C programming language (and similar languages) use a coding concept called "pointers". Pointers point to a memory address. The pointer itself does not contain the data. Rather, the pointer stores the memory address (like the index of a book). Many people may have problems understanding pointers and addressing, so I hope this helps.

    A pointer is a programming object that references a memory location. A pointer contains the memory address of a particular part of memory. A pointer is like a page number in the index of a book. The page number is the data stored by pointer. The words on the actual page is like the data in memory.

    NOTE: "Dereferencing" is the act of obtaining the data on memory pointed to by the pointer.

    A pointer must be of the same datatype as the data to which it points. Also, a pointer must be initialized before it can be used.

    To make a pointer that points to an integer in memory, use the below code.

    int int_in_mem = 32; // Initialize and declare integer
    int* int_ptr; // Declare
    int_ptr = &int_in_mem; // Initialize
    int* ptr2 = ptr; // Create a second pointer that points to the same data

    In the example, "int_in_mem" is an integer in memory. "int_ptr" only stores the memory address of the location of "int_in_mem". "int_in_mem" has the value "32" while "int_ptr" contains the value the indicates where in memory "int_in_mem" resides. "ptr2" points at the same memory location as "ptr". This is helpful when a particular memory location must be remembered when the other pointer will be changed to point to another location.

    The ampersand (&) means memory location. Therefore, "&int_in_mem" gives the memory address of the data "int_in_mem". The code &int_ptr would give the address in memory where "int_ptr" is stored. Thus, it is possible to have a pointer that points to a pointer. Also, the ampersand is helpful if code needs to know the literal memory address of a particular variable.

    In the example, "int_ptr" is the plain pointer. *int_ptr is the data at that memory location (in this case, "32"). *int_ptr++ reads the value of the memory location and then increments the pointer. This means that the pointer will point to the memory location that comes after the location that is storing the "32". (*int_ptr)++ will increment the data stored at that location. Thus, "32" will become "33", but the pointer itself remains unchanged. Below are various pointer notations and their meaning and effects.

    PointerMemory AddressData
    ptrAccess memory addressUnchanged
    *ptrUnchangedAccess data on memory
    *ptr++Increment address after readingUnchanged
    *(ptr++)Increment address after readingUnchanged
    (*ptr)++UnchangedIncrement data after reading
    *++ptrIncrement address before readingUnchanged
    *(++ptr)Increment address before readingUnchanged
    ++*ptrUnchangedIncrement data before reading
    ++(*ptr)UnchangedIncrement data before reading
    --*ptrUnchangedDecrement data before reading
    ptr*++InvalidInvalid
    ptr++*InvalidInvalid

    Be careful when declaring multiple pointers. For instance, int* ptr_a, ptr_b; is equivalent to int* ptr_a; int ptr_b;.

    Arrays notation is a special form of a pointer as seen in the table below.

    ArrayPointer Equivalent
    arrayptr*
    array[1]*(ptr + 1)
    array[2]*(ptr + 2)
    array[1]*(array + 1)

    An array is a collection of elements of data. Arrays are stored on memory and pointers are used to point and retrieve members/elements from the array. For instance, array[0] is a pointer to the first element on the array (computers start counting at zero). In many languages (such as C), strings are arrays of characters.

    If using two pointers, the length of an array can be measured. For instance, the below code creates a string (character array) and measures the length of the string.

    char ALPHABET[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\0";
    char* first_ptr = &ALPHABET[0];
    char* second_ptr = &ALPHABET[5];
    int distance = second_ptr - first_ptr;

    distance will contain the value "5" since the memory address pointed to by "second_ptr" minus the address "first_ptr" is five. Thus, there are five elements from the first element of the array/string ([0]) to the sixth element ([5]). Remember, computers start counting at zero.

    Now for another example.

    int int_in_mem = 32; // Initialize and declare integer
    int* int_ptr; // Declare
    int_ptr = &int_in_mem; // Initialize
    int* ptr2 = ptr; // Create a second pointer that points to the same data
    int our_num = *ptr2; // Access data at the memory location indicated by ptr2
    int num2 = (*int_ptr)++; // Access data at the memory location indicated by ptr2

    In the above example, int_in_mem stores "32" while both int_ptr and ptr2 store the location of int_in_mem. our_num contains "32" because the code retrieves the data stored at the pointed memory location. num2 will contain "33" because the code gets the data on memory and then increments the value before storing it in num2.

    To change the value of data in memory use the below code which changes "32" to "7". If the code were int_ptr = 7; instead of *int_ptr = 7;, then int_ptr would point to memory address 7.

    int int_in_mem = 32; // Initialize and declare integer
    int* int_ptr; // Declare
    int_ptr = &int_in_mem; // Initialize
    *int_ptr = 7; // Place "7" at the pointed memory address

    As for pointers to pointers, the below code, d points to the memory address that stores the "3" placed in a.

    int a = 3;
    int *b = &a;
    int **c = &b;
    int ***d = &c;

    A NULL pointer (such as int* ptr = 0;) is a pointer that pointers to zero. This means that it does not point to any data.

    A function pointer is a pointer to a function. Function pointers allow code to take functions as arguments which may be used to tell a function to use a particular function.

    void test_func(int x) { printf("%d\n", x); } // Function
    void (*func_ptr)(int); // Declare function pointer
    func_ptr = &test_func; // Initialize function pointer
    func_ptr(2); // Same as test_func(2)

    Further Reading

Viewing 1 post (of 1 total)