Shiklo Tools
PDF40
Image20
Calculators & Converters25
Text & Writing13
Developer26
Video14
Audio14
Document14
Data & Spreadsheet12
Web & SEO9
OCR & Scanning5
Archive & File12
Security & Privacy23
Health & Medical29
QR & Barcode5

C Pointers

A pointer is a variable that stores a memory address. With a pointer, code can reach a variable that lives somewhere else: a function can change its caller's variables, a loop can walk through an array, and a program can build lists that grow.

Declaring and using a pointer

A star in the declaration makes a pointer: int *p is "a pointer to an int". &x gives the address of x. A star in front of a pointer, *p, reaches the value it points at; this is called dereferencing.

#include <stdio.h>

int main(void) {
    int x = 10;
    int *p = &x;          // p holds the address of x
    printf("x = %d\n", x);
    printf("*p = %d\n", *p);
    *p = 25;              // change x through p
    printf("x = %d\n", x);
    return 0;
}
Output
x = 10
*p = 10
x = 25

Keep the two meanings of the star apart: in a declaration it says "this is a pointer"; in an expression it means "the value at this address".

Changing a caller's variables

Arguments are copied into functions, so a function cannot change the caller's variables directly. Passing their addresses solves that. This is the classic swap:

#include <stdio.h>

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

int main(void) {
    int a = 4, b = 9;
    swap(&a, &b);
    printf("a = %d, b = %d\n", a, b);
    return 0;
}
Output
a = 9, b = 4

Pointers and arrays

An array's name is the address of its first element. Adding 1 to a pointer moves it to the next element, whatever the element's size. This is pointer arithmetic:

#include <stdio.h>

int main(void) {
    int nums[5] = {1, 2, 3, 4, 5};
    int sum = 0;
    for (int *q = nums; q < nums + 5; q++) {
        sum += *q;
    }
    printf("Sum: %d\n", sum);
    printf("nums[2] = %d, *(nums + 2) = %d\n", nums[2], *(nums + 2));
    printf("A pointer uses %zu bytes here.\n", sizeof(int *));
    return 0;
}
Output
Sum: 15
nums[2] = 3, *(nums + 2) = 3
A pointer uses 4 bytes here.

nums[2] and *(nums + 2) mean exactly the same thing: indexing is pointer arithmetic in disguise. When an array is passed to a function, the function receives a pointer to the first element, so it does not know the array's size; pass the size as another parameter.

NULL

A pointer that points nowhere is set to NULL. Dereferencing NULL, or a pointer that was never set, crashes the program or worse, so check before using a pointer that may be empty: if (p != NULL). Functions such as malloc, fopen and strchr return NULL when they fail or find nothing.

Practice exercises

  1. Write a function that takes the address of an int and doubles the value.
  2. Write a function that finds both the smallest and the largest value of an array and gives them back through two pointer parameters.
  3. Print the elements of an array by moving a pointer instead of using an index.
  4. Print a string one character at a time using a char * that moves until it reaches '\0'.