Part 3 — Chapter 13

Chapter 13: Pointers

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

Syntax
C
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

How Pointers Point to Variables in Memory
int age = 25;
int *ptr = &age; // ptr stores address of age (0x4000)
pointer [ptr]
0x4000
Memory Address:
0x4004
*ptr → 25
variable [age]
25
Memory Address:
0x4000
Example Program
pointer_demo.c
C
#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 ptr is initialized to store the address of value (using the address-of operator &value).
  • Address Matching: Printing both &value and the variable ptr reveals they contain the exact same physical memory address (0x4000).
  • Pointer's Own Address: Printing &ptr shows that ptr itself 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 inside ptr (0x4000) and read the data residing there, returning 10.
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.

hardware_register.c
C
// 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.

← Chapter 12: Strings Chapter 14: Structures →