Pointers in Embedded C- Explained
In this article, we go over what pointers are and how we can code them in C for embedded applications.
What is a Pointer?
Pointers are variables that contain the address or location of a variable, constant, function, or data object.
So a pointer isn't the actual data. It simply represents the address or location of the data that is being referenced.
How to Code pointers in C
A variable is declared to be a pointer with the indirection or dereferencing operator, *:
char *p;
int *fp;
The pointer data type allocates an area in memory large enough to hold the machine address of the variable. For example, the address of a memory location in a typical microcontroller will be described in 16 bits. So in a typical microcontroller, a pointer to a character will be a 16-bit value, even though the character itself it only an 8-bit value.
Once a pointer is declared, you are now dealing with the address of the variable it is pointing to, not the value of the
variable itself. You must think in terms of locations and contents of locations. The address operator (&) is used ot gain access to the
address of a variable. This address may be assigned to the pointer and is the pointer's value. The indirection or deferencing operator
(*) is used to gain access to the data located at the address contained in the pointer.
char *p;
char a, b;
p = &a;
b= *p;
In this example, p is assigned to the address of a, so p is pointing to a. Now in order to get the value at this adress located
at a, the indirection operator (*) is used. In the following line, the value at address a is obtained and stored into b.
What Pointers Are Used For
Pointers are an excellent method of accessing a peripheral in a system, such as an I/I port. For instance, if we had
an 8-bit parallel output port located at 0x1010 in memory, that port could be accessed through indirection as follows:
unsigned char *out_port;
out_port= 0x1010;
*out_port= 0xaa;
So here we create a pointer called out_port. Then we assign the address of this out_port to be 0x1010. Then we assign an actual data value to this address, 0xaa.
Since pointers are effectively addresses, they offer the ability to move, copy, and change memory in all sorts of ways with very little instruction. So address arithmetic can be done pretty easily. When it comes to performing address arithmetic, the C compiler makes sure that the proper address is computed based on the type of variable or constant being addressed.
For example,
int *ptr;
long *lptr;
ptr= ptr+1;
lptr= lptr+1;
ptr and lptr are incremented by one location, which in reality is 2 bytes for ptr and 4 bytes for lptr, because of their
subsequent types. This is also true for the increment and decrement operations, shown below:
ptr++;
--lptr;
Since the indirection (*) and address (&) operators are unary operators and are at the highest precedence, they will always have priority over the other operations in an expression. Since increment and decrement are also unary operators and share the same priority, expressions containing these operators will be evaluated from left to right.