Skip to main content

Pointer Arithmetic in C: Increment, Decrement & Array Traversal πŸšΆβ€β™‚οΈ

Mentor's Note: Imagine walking down a street where houses have different widths. On a residential street, houses are 4 meters wide (like int variables). On a commercial street, buildings are 8 meters wide (like double variables). If you say "go to the next building," you step forward by 4 meters on the first street and 8 meters on the second. Pointer arithmetic works exactly like this! πŸ’‘

πŸ“š Educational Content: Understanding pointer arithmetic is a core syllabus requirement for CBSE Class 11/12, GSEB, and university BCA Sem 1 courses. Exams frequently require students to trace the output of arrays accessed via pointers and to calculate memory addresses manually.

What You'll Learn

By the end of this tutorial, you'll know:

  • Why pointer arithmetic depends on data type sizes (memory scaling).
  • How to apply increment (++), decrement (--), addition, and subtraction to pointers.
  • The fundamental relationship between array names and pointers.
  • How to traverse arrays efficiently using pointer arithmetic.
  • What double pointers (pointer-to-pointer) are and how they operate.

🌟 The Scenario: Stepping Stones in a River​

Imagine you are crossing a shallow river using stepping stones:

  • Each stone is a memory location.
  • Depending on the size of the stones, your steps will be short or long:
    • If they are char stones, each step is exactly 1 byte wide.
    • If they are int stones, each step is exactly 4 bytes wide.
    • If they are double stones, each step is exactly 8 bytes wide.

When you tell a pointer to move forward by 1 (ptr++), it does not move 1 byte. It takes one complete step to the next stone, scaling the step size automatically to match the stone's type size.


πŸ“– Concept Explanation​

In C, pointers are addresses. Since memory is byte-addressed, you might expect adding 1 to an address to point to the next byte. However, C uses Scaled Arithmetic to ensure pointers always step to the next logical variable of their type.

1. Pointer Increment (ptr++) and Decrement (ptr--)​

When you increment a pointer of type T, the address stored in the pointer increases by sizeof(T) bytes: New Address = Old Address + (1 * sizeof(Type))

For example, if an integer pointer ptr stores the address 1000:

  • ptr++ changes the address to 1004 (since sizeof(int) is 4 bytes).
  • ptr-- changes the address back to 1000.

2. Pointer Addition (ptr + n) and Subtraction (ptr - n)​

You can add or subtract an integer n from a pointer. The formula scales the offset: New Address = Old Address Β± (n * sizeof(Type))

3. Pointer Subtraction (ptr1 - ptr2)​

Subtracting two pointers of the same type returns the distance between them measured in the number of elements, not bytes.

int arr[5] = {10, 20, 30, 40, 50};
int *p1 = &arr[1]; // Address of 20
int *p2 = &arr[4]; // Address of 50
int distance = p2 - p1; // Returns 3 (elements between them)
Illegal Operations
  • Adding two pointers (e.g. p1 + p2) is illegal and causes a compile error. Adding two memory addresses is meaningless (like adding your street address to your neighbor's).
  • Multiplying, dividing, or modulo operations on pointers are also strictly prohibited.

πŸ”— Arrays vs. Pointers​

In C, an array name is actually a constant pointer to the first element of the array.

int arr[5] = {10, 20, 30, 40, 50};
// The following are identical:
// arr <--> &arr[0] (constant pointer to the first element)

Because of this relationship, indexing arr[i] is internally evaluated by the compiler as: arr[i] == *(arr + i)

This equivalence allows you to traverse arrays using pointer variables instead of loop counters.


πŸ‘₯ Double Pointers (Pointer-to-Pointer)​

A double pointer is a variable that stores the address of another pointer. It is declared using two asterisks **.

  • Analogy: A treasure hunt where Map A points to the location of Map B, and Map B points to the actual chest.
int x = 42;
int *ptr = &x; // Pointer to int
int **pptr = &ptr; // Pointer to pointer to int

🧠 Algorithm & Step-by-Step Logic​

Traced array traversal using pointer arithmetic:

  1. Start 🏁
  2. Declare an array arr of size 3 and initialize it.
  3. Declare pointer ptr and set it to point to the array name arr (starts at index 0).
  4. Loop 3 times:
    • Access and print the value pointed to by ptr using *ptr.
    • Increment the pointer using ptr++ to point to the next element.
  5. End 🏁

πŸ’» Implementation (C99)​

The following program shows scaling in pointer arithmetic, array traversal, and double pointer manipulation.

#include <stdio.h>

// πŸ›’ Scenario: Array Traversal Engine
// πŸš€ Action: Showcase pointer scaling, address differences, and double pointers

int main() {
int arr[] = {10, 20, 30, 40, 50};
int size = sizeof(arr) / sizeof(arr[0]);

// 1. Showcase Pointer Scaling
int *int_ptr = &arr[0];
printf("1. Pointer Scaling Check:\n");
printf(" Initial Address (int_ptr): %p\n", (void*)int_ptr);
printf(" Incremented Address (int_ptr+1): %p\n", (void*)(int_ptr + 1));
printf(" Size of int on this machine: %zu bytes\n\n", sizeof(int));

// 2. Array Traversal using Pointer Arithmetic
printf("2. Traversing array using *ptr and ptr++:\n");
int *ptr = arr; // points to &arr[0]
for (int i = 0; i < size; i++) {
printf(" Element %d: Value = %d, Address = %p\n", i, *ptr, (void*)ptr);
ptr++; // Shift pointer to next integer location
}
printf("\n");

// 3. Pointer Subtraction
int *start = &arr[0];
int *end = &arr[3];
printf("3. Pointer Subtraction:\n");
printf(" Elements between start and end: %td\n\n", end - start);

// 4. Double Pointers (Pointer-to-Pointer)
int value = 999;
int *p = &value;
int **pp = &p;

printf("4. Double Pointer Tracking:\n");
printf(" value = %d\n", value);
printf(" Accessing value via *p: %d\n", *p);
printf(" Accessing value via **pp: %d\n", **pp);
printf(" Address of p: %p, Value of pp: %p\n", (void*)&p, (void*)pp);

return 0;
}

// Output:
// 1. Pointer Scaling Check:
// Initial Address (int_ptr): 0x7ffeefbff480
// Incremented Address (int_ptr+1): 0x7ffeefbff484
// Size of int on this machine: 4 bytes
//
// 2. Traversing array using *ptr and ptr++:
// Element 0: Value = 10, Address = 0x7ffeefbff480
// Element 1: Value = 20, Address = 0x7ffeefbff484
// Element 2: Value = 30, Address = 0x7ffeefbff488
// Element 3: Value = 40, Address = 0x7ffeefbff48c
// Element 4: Value = 50, Address = 0x7ffeefbff490
//
// 3. Pointer Subtraction:
// Elements between start and end: 3
//
// 4. Double Pointer Tracking:
// value = 999
// Accessing value via *p: 999
// Accessing value via **pp: 999
// Address of p: 0x7ffeefbff478, Value of pp: 0x7ffeefbff478

πŸ“Š Sample Dry Run​

Let's trace address and index relations on an integer array starting at address 1000.

ExpressionEvaluated IndexAddress ValueValue ObtainedDescription
arrarr[0]100010Base address of the array.
arr + 1arr[1]100420Incremented address (base + 4 bytes).
*(arr + 2)arr[2]100830Dereferencing the offset pointer.
*(arr) + 5N/A100015Fetch value of arr[0] (10) and add integer 5.

πŸ“‰ Complexity Analysis​

Time Complexity ⏱️​

  • Pointer Arithmetic Operations: $O(1)$ time. Address offsets are calculated directly in the CPU registers with a single instruction cycle, making it highly efficient.

Space Complexity πŸ’Ύβ€‹

  • Auxiliary Space: $O(1)$ auxiliary space. Pointer calculations do not allocate new memory; they only repurpose existing pointer registers.

🎨 Visual Logic & Diagrams​

The flowchart shows how the pointer advances through memory blocks:


🎯 Practice Problems​

Easy Level πŸŸ’β€‹

  • Problem 1: Write a program to print a user-entered array in reverse order using pointer decrement operations.
  • Problem 2: Print the memory offset difference of a character pointer when incremented once.

Medium Level πŸŸ‘β€‹

  • Problem 3: Write a custom function that returns the length of a string using pointer subtraction (without using any library functions like strlen).
  • Problem 4: Write a function that uses a pointer to modify every second element of an array to 0.

Hard Level πŸ”΄β€‹

  • Problem 5: Create a matrix printer that accepts a 2D array and traverses its columns using a double pointer interface, printing elements row-by-row.

❓ Frequently Asked Questions​

Details

Q: What happens if I write (*ptr)++ instead of *ptr++? The difference lies in operator precedence:

  • *ptr++ reads the value at ptr, then increments the pointer address itself to point to the next element.
  • (*ptr)++ reads the value at ptr and increments that value in place. The pointer address does not change.
Details

Q: Can we increment the array name variable directly (e.g. arr++)? No. An array name is a constant pointer to the start of the array. Its target address cannot be reassigned or modified. Therefore, arr++ is invalid and will cause a compilation error.

Details

Q: What is pointer comparison used for? Comparing pointers using relational operators (<, >, ==) helps determine the relative ordering of elements in an array. For example, ptr1 < ptr2 is true if ptr1 points to an earlier index than ptr2.


βœ… Summary​

In this tutorial, you've learned:

  • βœ… Pointer arithmetic operates in units of the underlying type size, not bytes.
  • βœ… ptr++ and ptr-- step forwards and backwards through consecutive elements in RAM.
  • βœ… The array name arr is a constant pointer to the first element (&arr[0]).
  • βœ… Accessing arr[i] is completely identical to dereferencing *(arr + i).
  • βœ… Double pointers (type**) store the address of another pointer variable.

πŸ’‘ Interview Tips & Board Focus πŸ‘”β€‹

Common Questions​

  • "Why is adding two pointers invalid?"
  • "Explain the difference between *(ptr + i) and *ptr + i."
  • "What does sizeof(arr) evaluate to when passed as a function argument?"

Answering Strategy​

  • Clarify that *(ptr + i) dereferences the value at the $i$-th offset, while *ptr + i dereferences the first value and adds i to that value. This is a common exam trace question.
  • Emphasize that adding two pointers is mathematically meaningless and is blocked by the compiler to prevent logic errors.

πŸ“š Best Practices & Common Mistakes​

βœ… Best Practices​

  • Keep pointer offsets within the valid boundaries of the allocated array.
  • Use pointer subtraction only on elements of the same array to calculate element counts.
  • Parenthesize dereference operations carefully to preserve operator precedence.

❌ Common Mistakes βš οΈβ€‹

  • Array out-of-bounds traversal: Iterating pointers past the last array element. C does not perform boundary checks, resulting in undefined behavior.
  • Modifying base array labels: Attempting arr++ instead of using a temporary pointer variable.
  • Incorrect pointer subtraction type: Subtracting pointers of different data types, which leads to compilation errors.

πŸ“š Further Reading​

Continue your learning path:


Guide Version: 2.0
Purpose: Educational content creation standards for VD Computer Tuition


---

πŸ“ Visit Us

🏫 VD Computer Tuition Surat

VD Computer Tuition
πŸ“ Address
2/66 Faram Street, Rustompura
Surat – 395002, Gujarat, India
πŸ“ž Phone / WhatsApp
+91 84604 41384
🌐 Website

Computer Classes & Tuition β€” Areas We Serve in Surat

Adajanβ€’Althanβ€’Amroliβ€’Athwaβ€’Athwalinesβ€’Bhagalβ€’Bhatarβ€’Bhestanβ€’Canal Roadβ€’Chowkβ€’Citylightβ€’Dumasβ€’Gaurav Pathβ€’Ghod Dod Roadβ€’Haziraβ€’Jahangirpuraβ€’Kamrejβ€’Kapodraβ€’Katargamβ€’Limbayatβ€’Magdallaβ€’Majura Gateβ€’Mota Varachhaβ€’Nanpuraβ€’New Citylightβ€’Olpadβ€’Palβ€’Pandesaraβ€’Parle Pointβ€’Piplodβ€’Punaβ€’Randerβ€’Ring Roadβ€’Rustampuraβ€’Sachinβ€’Salabatpuraβ€’Sarthanaβ€’Sosyo Circleβ€’Udhnaβ€’Varachhaβ€’Ved Roadβ€’Vesuβ€’VIP Road
πŸ“ž Call SirπŸ’¬ WhatsApp Sir