</>
Skip to content
C lessons (21/28)

C — Pointers

What is a pointer

A pointer stores the memory address of another variable:

#include <stdio.h>

int main() {
    int x = 42;
    int *p = &x; // p holds the address of x

    printf("x value:   %d\n", x);    // 42
    printf("x address: %p\n", (void *)&x);
    printf("p value:   %p\n", (void *)p);  // Same address
    printf("p points to: %d\n", *p); // Dereference: 42

    *p = 100; // Modify x through the pointer
    printf("x is now: %d\n", x);    // 100

    return 0;
}

Pointer declarations

#include <stdio.h>

int main() {
    int a = 10;
    int *p1 = &a;    // Pointer to int
    int *p2, *p3;    // Two separate int pointers
    // int* p4, p5;   // COMMON MISTAKE: p4 is pointer, p5 is int!

    printf("*p1 = %d\n", *p1); // 10
    return 0;
}

Pointer arithmetic

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *p = arr; // Points to first element

    printf("*p = %d\n", *p);     // 10
    p++;                          // Move to next element
    printf("*p = %d\n", *p);     // 20
    p += 2;                       // Move forward 2 elements
    printf("*p = %d\n", *p);     // 40
    p--;                          // Move back 1 element
    printf("*p = %d\n", *p);     // 30

    // Pointer difference
    int *start = &arr[0];
    int *end = &arr[4];
    printf("Distance: %ld\n", end - start); // 4

    return 0;
}

Pointers and arrays

Arrays and pointers are closely related:

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;

    // These are equivalent:
    printf("arr[2] = %d\n", arr[2]);     // 3
    printf("*(p+2) = %d\n", *(p + 2));  // 3
    printf("p[2] = %d\n", p[2]);         // 3

    // Iterate with pointer
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(p + i));
    }
    printf("\n");

    return 0;
}

Pass by pointer

Modify the caller's variables:

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void increment(int *val) {
    (*val)++;
}

int main() {
    int x = 5, y = 10;
    swap(&x, &y);
    printf("x=%d, y=%d\n", x, y); // x=10, y=5

    increment(&x);
    printf("x=%d\n", x); // 11

    return 0;
}

Pointer to pointer

A pointer that holds the address of another pointer:

#include <stdio.h>

int main() {
    int x = 42;
    int *p = &x;
    int **pp = &p; // Pointer to pointer

    printf("x = %d\n", x);       // 42
    printf("*p = %d\n", *p);     // 42
    printf("**pp = %d\n", **pp); // 42

    **pp = 100;
    printf("x = %d\n", x);       // 100

    return 0;
}

const pointers

#include <stdio.h>

int main() {
    int x = 10, y = 20;

    // Pointer to const: can't modify the value
    const int *p1 = &x;
    // *p1 = 30;      // Error: can't modify through p1
    p1 = &y;          // OK: can change what p1 points to

    // Const pointer: can't change what it points to
    int *const p2 = &x;
    *p2 = 30;         // OK: can modify the value
    // p2 = &y;       // Error: can't change p2 itself

    // Const pointer to const: can't do either
    const int *const p3 = &x;
    // *p3 = 30;      // Error
    // p3 = &y;       // Error

    printf("x=%d, *p2=%d, *p3=%d\n", x, *p2, *p3);
    return 0;
}

Void pointer

Generic pointer that can point to any type:

#include <stdio.h>

void printValue(void *ptr, char type) {
    switch (type) {
        case 'i': printf("Integer: %d\n", *(int *)ptr); break;
        case 'f': printf("Float: %.2f\n", *(float *)ptr); break;
        case 'c': printf("Character: %c\n", *(char *)ptr); break;
    }
}

int main() {
    int i = 42;
    float f = 3.14;
    char c = 'A';

    printValue(&i, 'i');
    printValue(&f, 'f');
    printValue(&c, 'c');

    return 0;
}

Dynamic memory with pointers

#include <stdio.h>
#include <stdlib.h>

int main() {
    // Allocate single variable
    int *p = malloc(sizeof(int));
    if (p == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    *p = 42;
    printf("Value: %d\n", *p);
    free(p);

    // Allocate array
    int n = 5;
    int *arr = malloc(n * sizeof(int));
    if (arr == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        arr[i] = i * 10;
    }

    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n"); // 0 10 20 30 40

    free(arr);
    return 0;
}

Function pointers

#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }

int applyOperation(int a, int b, int (*op)(int, int)) {
    return op(a, b);
}

int main() {
    printf("Add: %d\n", applyOperation(5, 3, add));       // 8
    printf("Sub: %d\n", applyOperation(5, 3, subtract));   // 2
    printf("Mul: %d\n", applyOperation(5, 3, multiply));   // 15

    return 0;
}

Mini Practice

Write C code that:

  1. Swaps two integers using pointers
  2. Uses pointer arithmetic to iterate over an array
  3. Creates a dynamic array with malloc and fills it with user input
  4. Demonstrates the difference between const int * and int *const

Up Next

In the next lesson, you'll learn about Structures — grouping related data in C.

Related Topics

Frequently Asked Questions about Pointers

What is Pointers in C?

Pointers is a fundamental concept in C. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn Pointers?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Pointers.

Why is Pointers important in C?

Pointers is essential for C development. Understanding this concept will help you write better code and solve real-world problems more effectively.