Even pointers have to do maths!
Understanding Pointer Arithmetic in C: A Hands-on Guide
Pointer arithmetic is a powerful feature in the C programming language that allows for efficient navigation through memory. It's a concept that often confuses beginners but is fundamental for tasks like array manipulation, dynamic memory allocation, and more. In this article, we'll explore the basics of pointer arithmetic through well-explained C code, using fake address values to illustrate the principles.
1. Basic Pointer Arithmetic:
Let's start with a simple example of pointer arithmetic using an integer array. We'll print the addresses and values to demonstrate how pointer arithmetic works.
#include <stdio.h>
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int *ptr = numbers; // Point to the first element of the array
printf("Address of ptr: %p\n", (void *)ptr); // Print the initial address of the pointer
for (int i = 0; i < 5; ++i) {
printf("Value at %p: %d\n", (void *)ptr, *ptr); // Print address and value
ptr++; // Move to the next element
}
return 0;
}
In this example, ptr
initially points to the first element of the numbers
array. The program then iterates through the array, printing the address and value at each step. The ptr++
operation increments the pointer to the next element in the array.
2. Pointer Arithmetic with Different Data Types:
Pointer arithmetic adjusts the address based on the size of the data type. Let's illustrate this by working with a character array.
#include <stdio.h>
int main() {
char characters[] = {'A', 'B', 'C', 'D', 'E'};
char *ptr = characters; // Point to the first element of the array
printf("Address of ptr: %p\n", (void *)ptr); // Print the initial address of the pointer
for (int i = 0; i < 5; ++i) {
printf("Value at %p: %c\n", (void *)ptr, *ptr); // Print address and value
ptr++; // Move to the next element
}
return 0;
}
In this example, ptr
points to the first element of the characters
array. As characters are one byte each, the address increments by one byte in each step of the loop.
3. Arithmetic Operations on Pointers:
You can perform arithmetic operations directly on pointers, such as addition and subtraction. The result is adjusted based on the size of the data type.
#include <stdio.h>
int main() {
double doubles[] = {1.1, 2.2, 3.3, 4.4, 5.5};
double *ptr = doubles; // Point to the first element of the array
printf("Address of ptr: %p\n", (void *)ptr); // Print the initial address of the pointer
for (int i = 0; i < 5; ++i) {
printf("Value at %p: %.1f\n", (void *)ptr, *ptr); // Print address and value
ptr += 2; // Move two elements forward (double size is 8 bytes)
}
return 0;
}
In this example, ptr
initially points to the first element of the doubles
array. The ptr += 2
operation moves the pointer two elements forward, effectively skipping one double-precision floating-point number.
4. Address Arithmetic with Void Pointers:
Void pointers (void *
) are generic pointers that can point to objects of any data type. While you can't directly dereference a void pointer, you can perform arithmetic operations on it.
#include <stdio.h>
int main() {
int value = 42;
void *genericPtr = &value; // Point to the address of 'value'
printf("Initial Address: %p\n", (void *)genericPtr);
genericPtr += 4; // Move the pointer forward by 4 bytes (int size is 4 bytes)
printf("Updated Address: %p\n", (void *)genericPtr);
return 0;
}
In this example, the genericPtr
initially points to the address of an integer. The genericPtr += 4
operation moves the pointer forward by 4 bytes, simulating the size of an integer.
Understanding pointer arithmetic is essential for working with arrays, structures, and dynamic memory in C. It provides a powerful tool for efficient memory manipulation and navigation within a program. Remember that proper use of pointer arithmetic is crucial to avoid memory-related issues and ensure the correctness and reliability of your C programs.
Subscribe to my newsletter
Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jyotiprakash Mishra
Jyotiprakash Mishra
I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.