Pointers are one of the most powerful and fundamental concepts in C programming. A pointer is a variable that stores the memory address of another variable instead of storing a direct value.
Pointers provide direct access to hardware memory locations, making C the language of choice for system-level programming and embedded systems development.
1. What is a Pointer?
A pointer is declared with an asterisk symbol (*) placed before its variable name. It must match the data type of the variable whose address it will store.
Pointer Declaration Syntax
data_type *pointer_name;
Example
int *ptr; // Declares a pointer capable of storing the address of an integer variable
Address-Of Operator (&)
The ampersand (&) is the unary address-of operator. It retrieves the physical memory address where a variable is allocated in RAM.
int age = 25;
printf("%p", &age); // Outputs the hexadecimal address of 'age' (e.g. 0x4000)
2. Memory & Dereferencing
Pointers are initialized by assigning them the address of a variable. The dereference operator (*) allows you to directly access or modify the value stored at the address contained within the pointer.
Pointer Memory Representation
int *ptr = &age; // ptr stores address of age (0x4000)
0x4004
0x4000
Example Program
#include <stdio.h>
int main()
{
int value = 10;
int *ptr = &value;
printf("Value: %d\n", value);
printf("Address of value (&value): %p\n", (void*)&value);
printf("Address stored in ptr (ptr): %p\n", (void*)ptr);
printf("Address of pointer itself (&ptr): %p\n", (void*)&ptr);
printf("Pointer Value (Dereferenced): %d\n", *ptr);
return 0;
}
How It Works
This program demonstrates the core mechanics of pointers in four clear phases:
- Pointer Assignment: The pointer
ptris initialized to store the address ofvalue(using the address-of operator&value). - Address Matching: Printing both
&valueand the variableptrreveals they contain the exact same physical memory address (0x4000). - Pointer's Own Address: Printing
&ptrshows thatptritself is also a variable in memory residing at its own distinct address (0x4004). - Dereferencing: Using the dereference operator (
*ptr) instructs the CPU to look up the address stored insideptr(0x4000) and read the data residing there, returning10.
Console Output
Value: 10
Address of value (&value): 0x4000
Address stored in ptr (ptr): 0x4000
Address of pointer itself (&ptr): 0x4004
Pointer Value (Dereferenced): 10
Important Points
Keep these critical rules in mind when programming with pointers in C:
- Store Addresses: Pointers never store direct values; they exclusively hold memory addresses.
- Unary Operators: Use
&to fetch the address of a variable, and*to fetch the value stored at an address. - Type Safety: A pointer's data type must always match the data type of the variable it points to.
- Wild Pointers: Always initialize pointers. Uninitialized pointers (wild pointers) contain random addresses and can cause system crashes or undefined behavior.
Embedded Focus
In low-level embedded hardware, pointers are essential for direct hardware access and register-level control. Microcontroller peripherals (like GPIO ports, timers, and ADCs) are mapped directly to specific memory addresses. Embedded engineers use pointers to read from or write to these registers directly.
// Point directly to GPIO Port A Output Register address
volatile int *gpio_porta = (int *)0x40020014;
*gpio_porta = 0x01; // Turn on LED connected to pin 0 by writing to register address
The volatile keyword tells the compiler that the value at this address can change outside of the program's control (e.g., by hardware changes), preventing the compiler from optimizing away essential read/write cycles.