Pointer Arithmetic

Introduction

Pointer arithmetic in C involves performing mathematical operations on pointer variables to navigate through memory addresses. Unlike regular arithmetic, pointer arithmetic takes into account the size of the data type being pointed to, making it possible to traverse arrays and manipulate memory addresses efficiently.

Key Concepts

Pointer Increment/Decrement: Moving pointer to next/previous memory location Pointer Addition/Subtraction: Moving pointer by specified number of elements Pointer Difference: Finding distance between two pointers Address Calculation: Determining memory addresses using arithmetic operations Scale Factor: Size of data type that affects arithmetic operations

Basic Pointer Arithmetic Operations

Increment and Decrement Operations

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;  // Points to first element
    
    printf("Initial pointer address: %p, value: %d\n", ptr, *ptr);
    
    // Increment pointer
    ptr++;  // Now points to arr[1]
    printf("After increment: %p, value: %d\n", ptr, *ptr);
    
    // Decrement pointer
    ptr--;  // Back to arr[0]
    printf("After decrement: %p, value: %d\n", ptr, *ptr);
    
    return 0;
}

Addition and Subtraction with Integers

#include <stdio.h>

int main() {
    int numbers[] = {100, 200, 300, 400, 500};
    int *ptr = numbers;
    
    printf("Array elements using pointer arithmetic:\n");
    
    for (int i = 0; i < 5; i++) {
        printf("ptr + %d: address %p, value %d\n", 
               i, ptr + i, *(ptr + i));
    }
    
    // Moving pointer by multiple positions
    ptr = ptr + 3;  // Now points to numbers[3]
    printf("\nAfter ptr = ptr + 3:\n");
    printf("Current: %d\n", *ptr);
    printf("Previous: %d\n", *(ptr - 1));
    printf("Next: %d\n", *(ptr + 1));
    
    return 0;
}

Pointer Arithmetic with Different Data Types

Understanding Scale Factor

#include <stdio.h>

int main() {
    int intArray[] = {1, 2, 3};
    float floatArray[] = {1.1, 2.2, 3.3};
    char charArray[] = {'A', 'B', 'C'};
    
    int *intPtr = intArray;
    float *floatPtr = floatArray;
    char *charPtr = charArray;
    
    printf("Address differences (scale factors):\n");
    printf("int pointer:   %p to %p (diff: %ld bytes)\n", 
           intPtr, intPtr + 1, (char*)(intPtr + 1) - (char*)intPtr);
    printf("float pointer: %p to %p (diff: %ld bytes)\n", 
           floatPtr, floatPtr + 1, (char*)(floatPtr + 1) - (char*)floatPtr);
    printf("char pointer:  %p to %p (diff: %ld bytes)\n", 
           charPtr, charPtr + 1, (char*)(charPtr + 1) - (char*)charPtr);
    
    return 0;
}

Array Traversal Using Pointer Arithmetic

Forward and Backward Traversal

#include <stdio.h>

int main() {
    int data[] = {5, 15, 25, 35, 45};
    int size = sizeof(data) / sizeof(data[0]);
    int *ptr;
    
    // Forward traversal
    printf("Forward traversal:\n");
    for (ptr = data; ptr < data + size; ptr++) {
        printf("%d ", *ptr);
    }
    printf("\n");
    
    // Backward traversal
    printf("Backward traversal:\n");
    for (ptr = data + size - 1; ptr >= data; ptr--) {
        printf("%d ", *ptr);
    }
    printf("\n");
    
    return 0;
}

Pointer Subtraction and Comparison

Finding Distance Between Pointers

#include <stdio.h>

int main() {
    int values[] = {10, 20, 30, 40, 50, 60};
    int *start = &values[1];
    int *end = &values[4];
    
    // Pointer subtraction gives number of elements
    ptrdiff_t distance = end - start;
    printf("Distance between pointers: %ld elements\n", distance);
    printf("Distance in bytes: %ld\n", distance * sizeof(int));
    
    // Pointer comparison
    if (start < end) {
        printf("start pointer comes before end pointer\n");
    }
    
    // Calculating array bounds
    int *arrayStart = values;
    int *arrayEnd = values + sizeof(values)/sizeof(values[0]);
    
    printf("Array spans %ld elements\n", arrayEnd - arrayStart);
    
    return 0;
}

Practical Applications

String Processing with Pointer Arithmetic

#include <stdio.h>

int stringLength(char *str) {
    char *start = str;
    while (*str != '\0') {
        str++;
    }
    return str - start;
}

void reverseString(char *str) {
    char *start = str;
    char *end = str;
    
    // Find end of string
    while (*end != '\0') {
        end++;
    }
    end--;  // Move back to last character
    
    // Swap characters
    while (start < end) {
        char temp = *start;
        *start = *end;
        *end = temp;
        start++;
        end--;
    }
}

int main() {
    char text[] = "Hello World";
    
    printf("Original: %s\n", text);
    printf("Length: %d\n", stringLength(text));
    
    reverseString(text);
    printf("Reversed: %s\n", text);
    
    return 0;
}

Matrix Operations

#include <stdio.h>

void printMatrix(int *matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            // Using pointer arithmetic: matrix[i][j] = *(matrix + i*cols + j)
            printf("%3d ", *(matrix + i * cols + j));
        }
        printf("\n");
    }
}

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    printf("Matrix using pointer arithmetic:\n");
    printMatrix((int*)matrix, 3, 4);
    
    return 0;
}

Advanced Pointer Arithmetic

Pointer Arithmetic with Structures

#include <stdio.h>

struct Point {
    int x, y;
};

int main() {
    struct Point points[] = {{1,2}, {3,4}, {5,6}, {7,8}};
    struct Point *ptr = points;
    
    printf("Accessing structures using pointer arithmetic:\n");
    for (int i = 0; i < 4; i++) {
        printf("Point %d: (%d, %d)\n", i, (ptr + i)->x, (ptr + i)->y);
    }
    
    // Alternative notation
    printf("\nUsing array notation with pointer:\n");
    for (int i = 0; i < 4; i++) {
        printf("Point %d: (%d, %d)\n", i, ptr[i].x, ptr[i].y);
    }
    
    return 0;
}

Memory Address Calculations

Understanding Memory Layout

#include <stdio.h>

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int *ptr = arr;
    
    printf("Memory address analysis:\n");
    printf("Array base address: %p\n", arr);
    
    for (int i = 0; i < 5; i++) {
        printf("arr[%d]: address %p, value %d\n", 
               i, &arr[i], arr[i]);
        printf("ptr+%d: address %p, value %d\n", 
               i, ptr + i, *(ptr + i));
        printf("Equivalent: &arr[%d] == arr + %d == ptr + %d\n\n", 
               i, i, i);
    }
    
    return 0;
}

Common Mistakes and Best Practices

Avoiding Common Pitfalls

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

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *ptr = arr;
    
    // CORRECT: Valid pointer arithmetic
    printf("Valid operations:\n");
    printf("ptr + 2: %d\n", *(ptr + 2));
    printf("ptr++: %d\n", *ptr++);
    
    // INCORRECT: Don't do these
    // ptr + 10;  // May access invalid memory
    // ptr * 2;   // Invalid operation
    // ptr / 2;   // Invalid operation
    
    // Safe bounds checking
    int size = sizeof(arr) / sizeof(arr[0]);
    ptr = arr;  // Reset pointer
    
    for (int i = 0; i < size; i++) {
        if (ptr + i >= arr && ptr + i < arr + size) {
            printf("Safe access: %d\n", *(ptr + i));
        }
    }
    
    return 0;
}

Summary

Pointer arithmetic is a powerful feature in C that enables efficient array traversal and memory manipulation. Key operations include increment/decrement, addition/subtraction with integers, and pointer comparison. The scale factor (size of data type) automatically adjusts arithmetic operations. Understanding pointer arithmetic is essential for efficient array processing, string manipulation, and dynamic memory management while requiring careful attention to memory bounds and valid operations.


Part of BCA Programming with C Course (UGCOA22J201)