Pointer Arithmetic

Back

Loading concept...

🚀 Pointer Arithmetic: Navigating Memory Like a Pro

The Story of Memory Street 🏘️

Imagine a long street with houses numbered 100, 104, 108, 112… Each house holds one piece of data. A pointer is like knowing a house’s address. Pointer arithmetic is how we walk up and down this street, visiting neighbors!


🎯 What You’ll Learn

  1. Pointer Arithmetic Basics
  2. Pointer Increment & Decrement
  3. Pointer Comparison
  4. Passing Arrays to Functions

1️⃣ Pointer Arithmetic Basics

The Magic Rule 🪄

When you add 1 to a pointer, it doesn’t just add 1 to the address. It jumps to the next item of that type!

Think of it like this:

  • If houses are 4 meters apart (int = 4 bytes)
  • Adding 1 means “go to next house” (address + 4)
  • Adding 2 means “skip one house” (address + 8)
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;

// p points to arr[0] at address 1000
// p + 1 points to arr[1] at address 1004
// p + 2 points to arr[2] at address 1008

Visual: Memory Street

graph TD A["📍 p → 10<br>Address: 1000"] --> B["p+1 → 20<br>Address: 1004"] B --> C["p+2 → 30<br>Address: 1008"] C --> D["p+3 → 40<br>Address: 1012"] D --> E["p+4 → 50<br>Address: 1016"]

The Formula 📐

New Address = Original + (N × sizeof(type))

Example with char (1 byte):

char letters[3] = {'A', 'B', 'C'};
char *cp = letters;  // Address 500

// cp + 1 = 500 + (1 × 1) = 501
// cp + 2 = 500 + (2 × 1) = 502

Example with double (8 bytes):

double prices[3] = {9.99, 19.99, 29.99};
double *dp = prices;  // Address 800

// dp + 1 = 800 + (1 × 8) = 808
// dp + 2 = 800 + (2 × 8) = 816

🧠 Key Insight: The compiler knows the size of the data type. You just say “next” and it figures out the exact bytes to jump!


2️⃣ Pointer Increment & Decrement

Moving Forward and Backward 🚶‍♂️

Just like i++ adds 1 to a number, p++ moves a pointer to the next element.

The Operators

Operator What It Does Example
p++ Move to next, return old Use old, then move
++p Move to next, return new Move, then use new
p-- Move back, return old Use old, then move back
--p Move back, return new Move back, then use new

See It In Action 🎬

int nums[4] = {100, 200, 300, 400};
int *p = nums;  // p → 100

printf("%d\n", *p);    // 100
p++;                    // Move forward
printf("%d\n", *p);    // 200
p++;                    // Move forward
printf("%d\n", *p);    // 300
p--;                    // Move backward
printf("%d\n", *p);    // 200

The Tricky Part: Pre vs Post

int arr[3] = {5, 10, 15};
int *p = arr;

// *p++ means: get value at p, THEN move p
int a = *p++;  // a = 5, p now → 10

// *++p means: move p first, THEN get value
int b = *++p;  // p moves to 15, b = 15
graph LR A["*p++ = 5"] -->|"Then p moves"| B["p → 10"] C["*++p"] -->|"First move"| D["p → 15"] D -->|"Then get"| E["= 15"]

Walking Through an Array 🚶

int scores[5] = {85, 90, 78, 92, 88};
int *p = scores;

// Print all scores using pointer
for(int i = 0; i < 5; i++) {
    printf("Score: %d\n", *p);
    p++;  // Move to next score
}

⚠️ Warning: Don’t go past the array! Going beyond the last element causes undefined behavior (crashes or weird values).


3️⃣ Pointer Comparison

Comparing Addresses 🏁

Pointers hold addresses (numbers), so we can compare them!

What We Can Compare

Comparison Meaning
p1 == p2 Same address?
p1 != p2 Different addresses?
p1 < p2 p1 before p2 in memory?
p1 > p2 p1 after p2 in memory?
p1 <= p2 p1 at or before p2?
p1 >= p2 p1 at or after p2?

Real Example: Find the Bigger Address

int arr[5] = {1, 2, 3, 4, 5};
int *start = arr;       // Points to arr[0]
int *end = &arr[4];     // Points to arr[4]

if (start < end) {
    printf("start comes before end\n");
}
// Output: start comes before end

Looping with Pointer Comparison

Instead of counting, we can check if we’ve reached the end:

int data[4] = {10, 20, 30, 40};
int *p = data;
int *end = data + 4;  // One past last element

while (p < end) {
    printf("%d ", *p);
    p++;
}
// Output: 10 20 30 40
graph TD A["p starts at data[0]"] --> B{"p < end?"} B -->|Yes| C["Print *p"] C --> D["p++"] D --> B B -->|No| E["Done!"]

Pointer Subtraction 🧮

Subtracting two pointers tells you how many elements between them:

int arr[6] = {5, 10, 15, 20, 25, 30};
int *p1 = &arr[1];  // Points to 10
int *p2 = &arr[4];  // Points to 25

int diff = p2 - p1;  // = 3 elements apart
printf("Difference: %d\n", diff);
// Output: Difference: 3

💡 Remember: Pointer subtraction gives element count, not byte count!


4️⃣ Passing Arrays to Functions

The Big Secret 🤫

When you pass an array to a function, C actually passes a pointer to the first element!

void printFirst(int arr[]) {
    printf("%d", arr[0]);
}

// This is EXACTLY the same as:
void printFirst(int *arr) {
    printf("%d", *arr);
}

Why This Matters

  1. No copying - The function works with the original array
  2. Changes persist - Modifying elements changes the original
  3. Need the size - Functions can’t know array length!

Example: Modify Array in Function

void doubleAll(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        arr[i] = arr[i] * 2;  // Changes original!
    }
}

int main() {
    int nums[4] = {1, 2, 3, 4};
    doubleAll(nums, 4);
    // nums is now {2, 4, 6, 8}
}

Using Pointer Arithmetic in Functions

int sumArray(int *arr, int size) {
    int total = 0;
    int *end = arr + size;

    while (arr < end) {
        total += *arr;
        arr++;  // Move to next element
    }
    return total;
}

int main() {
    int values[5] = {10, 20, 30, 40, 50};
    int sum = sumArray(values, 5);
    printf("Sum: %d\n", sum);  // Sum: 150
}
graph TD A["Function receives&lt;br&gt;pointer to arr[0]"] --> B["Loop: arr &lt; end?"] B -->|Yes| C["Add *arr to total"] C --> D["arr++ &#35;40;move pointer&#35;41;"] D --> B B -->|No| E["Return total"]

Three Ways to Access Elements

Inside a function, these are all equivalent:

void showWays(int *arr, int n) {
    // Way 1: Array notation
    printf("%d\n", arr[2]);

    // Way 2: Pointer arithmetic
    printf("%d\n", *(arr + 2));

    // Way 3: Move pointer
    arr = arr + 2;
    printf("%d\n", *arr);
}

All three print the same value - the 3rd element!


🎯 Quick Summary

Concept Key Point Example
Arithmetic Basics Adding N skips N elements p + 2 = 2 elements ahead
Increment/Decrement p++ moves to next element *p++ = get value, then move
Comparison Compare addresses, not values p1 < p2 = p1 before p2
Arrays to Functions Array name = pointer to first func(arr) = func(&arr[0])

💪 You’ve Got This!

Pointer arithmetic is like learning to navigate a new city. At first, the addresses seem confusing. But once you understand that:

  1. Every data type has a size (int = 4 bytes, char = 1 byte)
  2. Pointers jump by that size automatically
  3. Arrays are just continuous memory with pointers to the start

…you’ll be navigating memory like a local! 🗺️

Remember: The computer handles the byte math. You just think in terms of “next item” and “previous item.” Simple! 🚀

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.