In part one of this series the basics of what a pointer is and how to declare one was examined in detail. It is now time to examine how pointers work when dealing with slightly more complex variables such as arrays and structures. It is far more efficient to pass the memory location around an application than the entire set of data.
Arrays offer a unique behavior in which they are able to decay from a variable to a pointer. Array decay occurs when the  operator is removed from an array. The result is a pointer to the starting location of the array. For example, a three element array can be declared as follows:
The value 14 in the array might be allocated to location 0x100, the value 28 to 0x102, etc. In order to access the elements of the array, use the simple notation array to access the first element of the array then array for the next element, etc. If there is a function that will use the array data, the function would be defined and used as listed below:
In this form the address to the first element of the array is passed to the function(0x100). Additional notation could be used to access another portion of the array. For example, the address of the second element in the array(0x102) can be passed to the function using the following notation
This is passing the address (&) of the array (array) for the second element (). It is important to keep in mind these different methods to access the array but also to note how similar the notation is to pointer notation. The simularity isn’t just one way either. One of the interesting notations of pointers that have not yet been discussed is accessing pointer variables using array notation. For example, a pointer can be declared to point to an array as follows
The pointer can be used to access the second element of the array as follows
In this case  acts as a method for dereferencing the address. This notation makes the pointer look a lot like the array that is being indexed. If the * symbol had been used before intPtr, the compiler would have thrown an error.
Pointers to structures are a common usage within the C language. Structures are often used to group similar data together, allowing member variables to be accessed through the structure variable. In future posts, structures will be used to define configuration elements for peripherals within a driver. It is therefore pivotal to understand how to use pointers to access structures. A pointer can be declared to a structure just like any other variable as follows
From previous experience using pointers, it is possible to access the pointer using the standard notation for say the size member of the structure as follows
In this case the symbol . is used to access the size member of the config structure. While this is acceptable, there is a far better way to access the size member by using the pointer-to-member operator ->. By doing this, the code becomes easier to read as follows
From these observations, it can be said in general that using the *, ->, and  operators are used to balance or access the uses of the & operator. They all act as operators to dereference the pointer and get access to the data stored there. Now that the reader has a fundamental understanding of pointers and the various operators associated with them, the next post will examine arrays of pointers. Arrays of pointers will be used as the fundamental method for memory mapping to device peripherals.