C Programming/Pointers

= Objective = This lecture will give you knowledge on:
 * Pass by value, pass by reference
 * Definition of reference and pointer, why using pointer is necessary ?
 * Declaring pointers, dereferencing pointers
 * Application of pointers

= Lesson =

Pass by value vs Pass by reference; why we need to use pointer ?
In this example, we want the function  to change the value of the variable   we passed to it, i.e change from 6 to 7. Function  returns the newly changed variable   to indicate the changing variable's process:

From the result, we can see that variable  hasn't been changed, although the return of function   states that the passed in variable   has been changed.

The operation above is called pass-by value. What is sent to the function  is the value of variable  , not the variable number, the variable number in   is just "the clone" of the "genuine variable". Due to the value being copied, any changes made to the variable within the function are not permanent, they end with the function return. So the value of  remains unchanged.

For function  to be able to change the value of the parameter, i.e   in this case, to it, we need a type of variable which is able to hold the "memory location" of that parameter so that function   can perform the change directly in that memory location in order to "take effect" on that parameter. That's how we come to the definition of reference and pointer.

In both C and C++, a reference is defined as a value to stores the address of an object, e.g a variable, function, class object,... that is located elsewhere in memory. Pointers are the most primitive type of reference.

The parameter to a function can be a copy of a value that is represented by a variable, which is known as pass-by value, or can be a reference to a memory space that stores value of variable, which is known as pass-by reference.

What is pointer ?
A pointer is a variable holding a specific memory location. Most often, this memory location is that of a variable or array and it can also be the location of a function.

Pointers refer to memory addresses, as opposed to specific values. They are denoted by the use of an asterisk (*). Consider the following piece of code:

In this code,  is set to the address of , where   is set to the value of. When  is incremented, the change is shown in , since they both refer to the same memory address. stays the same, however, since it took the value once, and stored it in a separate memory location.

In the brackets can also be seen the memory address of the variable, which shows that  and   refer to the same memory address, while   refers to a different memory address. Note that in the example, the following are true:


 * We used  to declare a pointer to an integer
 * We used  to get the memory address of
 * We used  to get the value stored in the address referred to by the pointer  . This is known as dereferencing pointer

Back to the introduction example, when we want a function to be able to change the value of a variable as parameter passed to this function. With the knowledge of pointers and pass-by reference, we have the solutions for that:

Using pass-by reference

Assign pointer to the variable

Pointers as array iterators
When pointers are learned, we can use then for manipulating arrays effectively. Note that due to alignment, an array will require a memory alignment equal to the  the type of the array's elements.

Pointers can be incremented, which makes them a natural choice for iterating an array. Consider the following piece of code:

initially refers to the first item in the array,. When  is incremented, the memory address is incremented by. The value at the address referred to by  is therefore then the next value in the array, accessed by.

Accessing address  accesses the (i+1)th element of the array.

Also note that arrays are always allocated with offset going upwards in RAM locations, your stack doesn't need to grow upwards for this.

Must not set value at an arbitrary memory location
Based on the pointer concept, a pointer stores the value of another variable so directly setting the value for its dereferencing is a useless act and results in Segmentation fault

Modern computer systems use virtual memory techniques so that physical register addresses can't be set arbitrarily. The following example is to arbitrarily setting value at a specific register address is the wrong implementation and must not be done in real-life applications:

To work with the program above with an address like ``6295624``, the address ``6295624`` must be the GCC allowable address. User must find the allowable address first with ``&`` for a dummy variable. E.g:

Function Pointers
Before we start with function pointers, it's worth mentioning that functions do have address: In addition to other ways that pointers can be used, they can also reference a function. While this may not seem very useful at first, it can be used to either embed a function in to a struct that uses it exclusively, or to allow a function to return a function or use a function as input to another function.

This is a very complex sub-topic and can create a lot of bugs in your program if poorly implemented.

= Assignments =

Assignment for pointers

 * Creating, initializing and assigning simple pointer
 * Pointer as function argument

Linked Lists
A linked list is a list of data, comprised of nodes which specify their data, and the address of the next node, or NULL to specify the last node. We will use our knowledge on pointer to build a linked list. Consider the following code:

In this code, we defined a  for a node in the linked list. We initialize the first node, and then add some data, by creating a new node, setting it to be after the current node, and then moving the current node to the next place. We do a similar process to iterate through the list.

A linked list is a good visualisation of pointers, but is also an effective data type for Last in First Out structures, such as stacks. Adding to a linked list is simply a matter of creating a new node, and setting its  to be the head. Removing is equally simple, get the value, deallocate the memory, and set the second node to be the head.


 * Previous Lesson: Arrays
 * Next Lesson: Strings
 * Course Home Page

= Reference =