Pointers in C are directly addressing memory. Pointers enable programs to manage memory dynamically, and are used for that reason, are essential to many advanced programming techniques, particularly systems programming and memory management. However, managing pointers efficiently depends on a thorough knowledge of pointer arithmetic of addition, subtraction, and comparisons on pointers and addresses.
This article will describe the various pointer arithmetic in C, their examples, and how they differ from normal arithmetic operations with examples.
What is Pointer Arithmetic?
Pointer arithmetic in C contains the address of a variable in memory. Though the pointer is an integer (address), remember it is not similar to regular integer arithmetic. Pointer arithmetic considers the data type being pointed to by the pointer and thus allows us to move through memory locations efficiently.
Pointer arithmetic operations are:
- Increment and Decrement of a Pointer
- Addition and Subtraction of an Integer to/from a Pointer
- Subtraction of Two Pointers
- Comparison of Pointers
Each of these operations is described below.
1. Increment and Decrement of a Pointer
When we decrement or increment a pointer, we shift the pointer to the next or previous object of the type that the pointer is referring to. Suppose we have a pointer referring to an integer. When we increment the pointer by 1, we shift it to the next integer in memory (by adding the size of an integer, generally 4 bytes on most computers).
Example of Pointer Increment
#include <stdio.h>
int main() {
int x = 10;
int *y = &x;
printf("Value of y before increment: %p\n", y);
y++; // Pointer increments to the next memory address
printf("Value of y after increment: %p\n", y);
return 0;
}
Explanation
Here, y++ increases the pointer, and address is incremented by 4 bytes (integer size). This is how one pointer moves to the next element in an array or a block of adjacent memory.
Output
Value of y before increment: 0x7ffeeb2d9d10
Value of y after increment: 0x7ffeeb2d9d14
Example of Pointer Decrement
#include <stdio.h>
int main() {
double x = 10.0;
double *y = &x;
printf("Value of y before decrement: %p\n", y);
y--; // Pointer decrements to the previous memory address
printf("Value of y after decrement: %p\n", y);
return 0;
}
Explanation
This decreases a pointer y, to the prior memory location, and outputs the addresses both before and after.
Output
Value of y before decrement: 0x7ffeeb2d9d10
Value of y after decrement: 0x7ffeeb2d9d08
2. Addition and Subtraction of an Integer to/from a Pointer
In C, we can add or subtract an integer to/from a pointer. It is an operation if we want to traverse an array or shift a pointer some steps ahead or behind.
The address moves by the number of elements that the pointer references, multiplied by the size of the data type, when we add an integer to a pointer.
Example of Adding an Integer to a Pointer
#include <stdio.h>
int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = int_arr;
printf("Value at ptrArr: %d\n", *ptrArr);
// Adding 2 in ptrArr
ptrArr = ptrArr + 2;
printf("Value at ptrArr after adding 2: %d\n", *ptrArr);
return 0;
}
Explanation
In this example, ptrArr + 2 moves the pointer from the array's first element (12) to the third element (45).
Output
Value at ptrArr: 12
Value at ptrArr after adding 2: 45
Example of Subtracting an Integer from a Pointer
#include <stdio.h>
int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = &int_arr[4]; // points to last element
printf("Value at ptrArr: %d\n", *ptrArr);
// Subtracting 2 in ptrArr
ptrArr = ptrArr - 2;
printf("Value at ptrArr after subtracting 2: %d\n", *ptrArr);
return 0;
}
Here, ptrArr is decremented by 2, and it moves to the third position of the array, reversing the pointer position by 2.
Output
Value at ptrArr: 89
Value at ptrArr after subtracting 2: 45
3. Subtraction of Two Pointers
Decreasing two pointers is a valid operation in C. This is used to find the total number of elements between two pointers.
Note: Remember the result shown is the number of elements and not the difference between two pointers.
Example of Subtracting Two Pointers
#include <stdio.h>
int main() {
int a[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *x = &a[0]; // first element
int *y = &a[9]; // last element
printf("Subtraction of two pointers: %ld\n", y - x);
return 0;
}
Explanation
The above code subtracting x from y returns 9, indicating 9 elements between the two pointers.
Output
Subtraction of two pointers: 9
4. Comparison of Pointers
#include <stdio.h>
int main() {
int var[] = {10, 100, 200};
int *ptr1 = var;
int *ptr2 = &var[2];
while (ptr1 <= ptr2) {
printf("Address of ptr1: %p, Value: %d\n", ptr1, *ptr1);
ptr1++;
}
return 0;
}
Explanation
In this example, ptr1 is incremented if it is less than or equal to ptr2, allowing the program to traverse the array using pointer comparisons.
Output
Address of ptr1: 0x7ffeecb21d30, Value: 10
Address of ptr1: 0x7ffeecb21d34, Value: 100
Address of ptr1: 0x7ffeecb21d38, Value: 200
Illegal Arithmetic with Pointers in C
Here are the different operations illegal on pointers in C. Those operations, when executed, yield undefined behaviour, such as accessing illegal memory locations.
1. Address + Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer addition
// This will result in a compile-time error
int *ptr3 = ptr1 + ptr2;
printf("Pointer addition: %p\n", ptr3);
return 0;
}
Output
error: invalid operands to binary + (have 'int *' and 'int *')
Explanation
The error occurs because the C language does not allow adding two pointer types. Pointers can only be added to integers (which indicate the offset of the pointer), not other pointers.
2. Address * Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer multiplication
// This will result in a compile-time error
int *ptr3 = ptr1 * ptr2;
printf("Pointer multiplication: %p\n", ptr3);
return 0;
}
Explanation
Pointers are memory addresses; multiplying them doesn’t valid or meaningful result. Hence, the compiler rejects the operation.
Output
error: invalid operands to binary * (have 'int *' and 'int *')
3. Address % Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer modulus
// This will result in a compile-time error
int result = ptr1 % ptr2;
printf("Pointer modulus: %d\n", result);
return 0;
}
Explanation
The modulus operator is applied to calculate the remainder of division of integers, but pointers are addresses in memory, and it does not make sense to calculate the modulus of two addresses. Therefore, this operation is illegal.
Output
error: invalid operands to binary % (have 'int *' and 'int *')
4. Address / Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer division
// This will result in a compile-time error
int result = ptr1 / ptr2;
printf("Pointer division: %d\n", result);
return 0;
}
Explanation
The division operator is intended for numeric types, not pointers. Dividing two pointers in C is not helpful, so it is a compile-time error.
Output
error: invalid operands to binary / (have 'int *' and 'int *')
5. Address & Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer AND operation
// This will result in a compile-time error
int result = ptr1 & ptr2;
printf("Pointer AND: %d\n", result);
return 0;
}
Explanation
The bitwise AND operator is only valid for integer types, and using it on pointer types is illegal. It has no meaningful effect when applied to memory addresses.
Output
error: invalid operands to binary & (have 'int *' and 'int *')
6. Address ^ Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer XOR operation
// This will result in a compile-time error
int result = ptr1 ^ ptr2;
printf("Pointer XOR: %d\n", result);
return 0;
}
Explanation
The XOR operator is intended for integer operands, and applying it to pointers would result in an invalid operation. The compiler flags it as an error.
Output
error: invalid operands to binary ^ (have 'int *' and 'int *')
7. Address | Address = Illegal
#include <stdio.h>
int main() {
int a = 10, b = 20;
int *ptr1 = &a;
int *ptr2 = &b;
// Illegal pointer OR operation
// This will result in a compile-time error
int result = ptr1 | ptr2;
printf("Pointer OR: %d\n", result);
return 0;
}
Explanation
Similar to all the bitwise operators, the bitwise OR operator can be used only on integers. It cannot be used on pointers and will be an error at compile time.
Output
error: invalid operands to binary | (have 'int *' and 'int *')
8. ~Address = Illegal
#include <stdio.h>
int main() {
int a = 10;
int *ptr = &a;
// Illegal bitwise NOT operation on pointer
// This will result in a compile-time error
int result = ~ptr;
printf("Bitwise NOT of pointer: %d\n", result);
return 0;
}
Explanation
Bitwise NOT operator must be applied to integers and cannot be used for pointer types. Performing it on a pointer is invalid and triggers a compile-time error.
Output
error: invalid operands to unary ~ (have 'int *')
Conclusion
To conclude, in C programming, pointer arithmetic is a key concept which enables memory manipulation and access to data structures. With knowledge of pointer increments, decrements, addition, subtraction, and comparison operations, programmers can create more efficient and adaptable code.
Gain Industry-Relevant Skills and Secure a Tech Job Before College Ends!
Explore ProgramFrequently Asked Questions
1. What is pointer arithmetic in C?
Addition, subtraction, and incrementing/decrementing pointers, and modifying their memory addresses depending on data type is known as pointer arithmetic in C.
2. What is a pointer in C with example?
A pointer holds the memory address of another variable.
Example:
int x = 10;
int *ptr = &x; // Pointer to x
3. What do you mean by address arithmetic?
Address arithmetic is the manipulation of pointers (addresses) using operations such as addition and subtraction to move through memory locations.
4. Why is pointer arithmetic useful?
Pointer arithmetic makes it easy to travel through memory, particularly arrays, by directly accessing and changing memory locations.