C Pointer Arithmetic
A C pointer is a numeric address. Therefore, you can perform arithmetic operations on pointers. There are four arithmetic operations that can be performed on pointers: ++, --, +, and -.
Assume ptr is an integer pointer pointing to address 1000, and it's a 32-bit integer. Let's perform the following arithmetic operation on this pointer:
ptr++
After executing the above operation, ptr will point to location 1004, because each increment of ptr makes it point to the next integer location β i.e., it moves forward by 4 bytes from its current position. This operation moves the pointer to the next memory location without affecting the actual value stored at that memory location. If ptr points to a character at address 1000, the above operation would cause the pointer to point to location 1001, because the next character location is at 1001.
We summarize as follows:
- Each increment of a pointer makes it point to the storage unit of the next element.
- Each decrement of a pointer makes it point to the storage unit of the previous element.
- The number of bytes skipped during pointer increment or decrement depends on the size (in bytes) of the data type the pointer points to β for example,
intis 4 bytes.
Incrementing a Pointer
Incrementing a pointer means making the pointer point to the next memory location.
The increment operation on a pointer performs appropriate memory offset based on the data type the pointer points to.
We prefer using pointers instead of arrays in programs because variable pointers can be incremented, whereas arrays cannot be incremented; arrays can be viewed as pointer constants. The following program increments a pointer variable to sequentially access each element in an array:
Example
#include<stdio.h>
const int MAX = 3;
int main(){
int var[] = {10, 100, 200};
int i, *ptr;
ptr = var;
for(i = 0; i<MAX; i++){
printf("Memory address: var[%d] = %pn", i, ptr);
printf("Stored value: var[%d] = %dn", i, *ptr);
ptr++;
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
Memory address: var = e4a298cc Stored value: var = 10
Memory address: var = e4a298d0 Stored value: var = 100
Memory address: var = e4a298d4 Stored value: var = 200
Incrementing a character pointer:
Example
#include <stdio.h>
int main(){
char str[]="Hello";
char*ptr = str;// pointer points to the first character of the string
printf("Initial character: %cn",*ptr);// outputs H
ptr++;// increment pointer to point to the next character
printf("Character after increment: %cn",*ptr);// outputs e
return 0;
}
In this example, ptr++ makes the pointer move from str to str. Since ptr is a char pointer, it moves by sizeof(char) bytes (i.e., 1 byte) upon increment.
When the above code is compiled and executed, it produces the following result:
Initial character: H Character after increment: e
Incrementing a structure pointer:
Example
#include <stdio.h>
struct Point {
int x;
int y;
};
int main(){
struct Point points[]={{1,2},{3,4},{5,6}};
struct Point *ptr = points;// pointer points to the first element of the structure array
printf("Initial point: (%d, %d)n", ptr->x, ptr->y);// outputs (1, 2)
ptr++;// increment pointer to point to the next structure
printf("Point after increment: (%d, %d)n", ptr->x, ptr->y);// outputs (3, 4)
return 0;
}
In this example, ptr++ makes the pointer move from points to points. Since ptr is a struct Point pointer, it moves by sizeof(struct Point) bytes upon increment.
When the above code is compiled and executed, it produces the following result:
Initial point: (1, 2)
Point after increment: (3, 4)
Decrementing a Pointer
Decrementing a pointer means making the pointer point to the previous memory location. Similar to pointer increment, pointer decrement also performs appropriate memory offset based on the data type the pointer points to.
Decrementing a pointer subtracts the number of bytes equal to the size of its data type, as shown below:
Example
#include<stdio.h>
int main(){
int arr[] = {10, 20, 30, 40, 50};
int *ptr = &arr;
printf("Initial value: %dn", *ptr);
ptr--;
printf("Value after decrement: %dn", *ptr);
ptr--;
printf("Value after second decrement: %dn", *ptr);
return 0;
}
When the above code is compiled and executed, it produces the following result:
Initial value: 50
Value after decrement: 40
Value after second decrement: 30
Decrementing a character pointer:
Example
#include <stdio.h>
int main(){
char str[]="Hello";
char*ptr = &str;// pointer points to the last character 'o' of the string
printf("Initial character: %cn",*ptr);// outputs o
ptr--;// decrement pointer to point to the previous character
printf("Character after decrement: %cn",*ptr);// outputs l
ptr--;// decrement pointer again
printf("Character after second decrement: %cn",*ptr);// outputs l
return 0;
}
When the above code is compiled and executed, it produces the following result:
Initial character: o Character after decrement: l Character after second decrement: l
Decrementing a structure pointer:
Example
#include <stdio.h>
struct Point {
int x;
int y;
};
int main(){
struct Point points[]={{1,2},{3,4},{5,6}};
struct Point *ptr = &points;// pointer points to the last element of the structure array
printf("Initial point: (%d, %d)n", ptr->x, ptr->y);// outputs (5, 6)
ptr--;// decrement pointer to point to the previous structure
printf("Point after decrement: (%d, %d)n", ptr->x, ptr->y);// outputs (3, 4)
ptr--;// decrement pointer again
printf("Point after second decrement: (%d, %d)n", ptr->x, ptr->y);// outputs (1, 2)
return 0;
}
When the above code is compiled and executed, it produces the following result:
Initial point: (5, 6)
Point after decrement: (3, 4)
Point after second decrement: (1, 2)
Pointer Comparison
In C, pointers can be compared to determine their relationship. Pointer comparison is mainly used to determine whether two pointers point to the same memory location, or to determine whether one pointer is before or after another pointer.
Pointers can be compared using relational operators such as ==, !=, <, >, <=, and >=. If p1 and p2 point to related variables β for example, different elements of the same array β then p1 and p2 can be compared.
Below are some example codes demonstrating how to compare pointers and output results.
Pointer Equality Comparison
Example
#include<stdio.h>
int main(){
int a = 5;
int b = 10;
int *ptr1 = &a;
int *ptr2 = &a;
int *ptr3 = &b;
if(ptr1 == ptr2){
printf("ptr1 and ptr2 point to the same memory addressn");
}else{
printf("ptr1 and ptr2 point to different memory addressesn");
}
if(ptr1 != ptr3){
printf("ptr1 and ptr3 point to different memory addressesn");
}else{
printf("ptr1 and ptr3 point to the same memory addressn");
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
ptr1 and ptr2 point to the same memory address
ptr1 and ptr3 point to different memory addresses
Pointer Magnitude Comparison
Example
#include <stdio.h>
int main(){
int arr[]={10,20,30,40,50};
int*ptr1 = &arr;// points to arr, value is 20
int*ptr2 = &arr;// points to arr, value is 40
if(ptr1 < ptr2){
printf("ptr1 is before ptr2n");// this line will be printed
}else{
printf("ptr1 is after or at the same position as ptr2n");
}
if(ptr1 > ptr2){
printf("ptr1 is after ptr2n");
}else{
printf("ptr1 is before or at the same position as ptr2n");// this line will be printed
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
ptr1 is before ptr2
ptr1 is before or at the same position as ptr2
Traversing an Array and Comparing Pointers
Example
#include <stdio.h>
int main(){
int arr[]={10,20,30,40,50};
int*start = arr;// points to the first element of the array
int*end = &arr;// points to the last element of the array
int*ptr;
for(ptr = start; ptr <= end; ptr++){
printf("Value pointed to by current pointer: %dn",*ptr);
}
return 0;
}
When the above code is compiled and executed, it produces the following result:
Value pointed to by current pointer: 10
Value pointed to by current pointer: 20
Value pointed to by current pointer: 30
Value pointed to by current pointer: 40
Value pointed to by current pointer: 50
Summary
- Equality comparison (
==and!=): Used to determine whether two pointers point to the same memory location. - Magnitude comparison (
<,>,<=,>=): Typically used when traversing arrays or memory blocks with pointers, to determine whether one pointer is before or after another pointer.
Note: Pointer comparisons are only meaningful when the pointers point to the same array or the same memory block; otherwise, the behavior is undefined.
YouTip