C Language | Pointers | Pointer Arithmetic

Pointer arithmetic changes the object referenced by a pointer. It is particularly useful when traversing arrays.

Calculating Addresses

A pointer stores a memory address and has a data type. Arithmetic is meaningful only within a valid contiguous memory region, such as an array. Dereferencing an unrelated address can crash a program or cause undefined behavior.

Code 1

#include <stdio.h>

int main() {
  char chStr[] = "Kitty on your lap";
  int iCount;

  for (iCount = 0; chStr[iCount]; ++iCount)
    printf("&chStr[%d] = %p\n", iCount, (void *)&chStr[iCount]);
  return 0;
}

The addresses of the elements increase in order because an array occupies contiguous memory. Since char occupies one byte, adding five to the address of chStr[0] produces the address of chStr[5].

Code 2

#include <stdio.h>

int main() {
  int iArray[] = { 10, 100, 1000 };
  int *iPo = &iArray[0] + 1;

  printf("*iPo = %d\n", *iPo);
  return 0;
}

Here, iPo points to iArray[1]. Pointer arithmetic advances in units of the pointed-to type, not always one byte.

Code 3

#include <stdio.h>

int main() {
  int iArray[] = { 2, 4 };

  printf("&iArray[0] = %p\n", (void *)&iArray[0]);
  printf("&iArray[1] = %p\n", (void *)&iArray[1]);
  return 0;
}

On a system where int occupies four bytes, the two displayed addresses differ by four bytes. The compiler performs this scaling automatically.

Code 4

#include <stdio.h>

int main() {
  int iArray[] = { 2, 4 };
  int *iPo = &iArray[0];

  printf("*iPo = %d : iPo = %p\n", *iPo, (void *)iPo);
  iPo += 1;
  printf("*iPo = %d : iPo = %p\n", *iPo, (void *)iPo);
  return 0;
}

After iPo += 1, iPo points to the second element. For an int *, adding one advances the address by sizeof(int) bytes.