A few pointers part 3
The previous two posts (part 1 and part 2) have been exploring the fundamentals of using pointers from the basics of declaring a pointer to the more complex notation of manipulating pointers. An examination of how arrays and pointers behave in similar fashions and the types of operators that can be used to manipulate them was presented. It is now time to apply a combination of all these concepts into something known as pointer arrays.
Pointer arrays in concept are relatively straight forward. They are simply an array in which each element stores a pointer rather than a variable. They offer a unique method for organizing registers, variables or functions into an easily indexed format. This allows a simple loop counter to be used to access what would normally be a lengthy set of individual code operations.
Declaring a pointer array is the same as declaring any array except that the pointer symbol * is used in the declaration. For example, a pointer array to a type uint16 can be declared as follows
The declaration can be read in this case as “PArray is an array of pointers to a uint16”. The element list is then any number of pointers to variables, functions, etc. Using pointer arrays makes it much easier to manipulate any number of similar variables; For example, each of the variables in the above declaration can be set to 0 as follows
Each variable can still be set using standard pointer notation. For example, Var1 can be set to 15 by dereferencing the pointer at array index 0 as follows
The next post will closely examine how to use pointer arrays to map a peripheral’s register to a configuration table to set it up for operation. A quick look at function pointers will complete our brief look at the basics of pointers.
Function pointers often get a bad rap because like any other pointer they have the ability to wreak havoc on a system if they are not used properly. By definition a function pointer is a pointer that when dereferenced will execute a function. This allows the developer to create a dynamic list of functions that can be called based on a variety of circumstances. For example, a function pointer table could be used to schedule background tasks in a round robin fashion, to handle communication protocol commands or even to execute different states of a state machine. A generic look at how to define a function a pointer can be found below
For instance, a function pointer that takes no parameters and returns nothing can be declared as follows
It is also possible to declare function pointers that return a type or take parameters. For example, below is a function pointer declaration that takes a uint16 as a parameter and then returns a bool
The two concepts of function pointers and arrays of pointers can be tied together to create an array of function pointers. This can be done for complex state machines that have been broken up into multiple functions. For example, lets define an array of function pointers below
The current state of the state machine can be stored in a variable named SmState which varies from 1 to 3. When executing the state machine in code the function for that state can be called using the following notation
Pointers are an extremely useful and critical tool when developing embedded software. The previous posts have only scratched the surface of what is possible. Future posts will inspect additional applications for function pointers. However, in the next post how to map peripheral registers using the pointer techniques that were just reviewed will be presented.Also see: