Pointers and arrays are closely related in C. The name of an array usually converts to a pointer to its first element when used in an expression. Because of this relationship, pointers can be used to access and process array elements efficiently.
int arr[5], the expression
arr usually represents a pointer to arr[0].
An array stores multiple elements of the same type in contiguous memory. A pointer can store the address of one of those elements.
int arr[] = {10, 20, 30};
int *ptr = arr;
Here, ptr points to the first element of the array.
In most expressions, the array name is converted to a pointer to its first element.
int arr[] = {10, 20, 30};
printf("%d", *arr);
The output is:
10
The first array element can be accessed using either array notation or pointer dereferencing.
int arr[] = {10, 20, 30};
printf("%d\n", arr[0]);
printf("%d\n", *arr);
Both statements print 10.
Pointer arithmetic allows a pointer to move from one array element to another.
int arr[] = {10, 20, 30};
int *ptr = arr;
printf("%d\n", *ptr);
ptr++;
printf("%d\n", *ptr);
After ptr++, the pointer points to the next integer element.
Array elements can be accessed using pointer arithmetic.
int arr[] = {10, 20, 30, 40};
int *ptr = arr;
printf("%d\n", *(ptr + 0));
printf("%d\n", *(ptr + 1));
printf("%d\n", *(ptr + 2));
printf("%d\n", *(ptr + 3));
For an array expression, these two forms access the same element:
arr[i]
*(arr + i)
For example:
int arr[] = {10, 20, 30};
printf("%d", *(arr + 1));
The output is 20.
Incrementing a pointer moves it to the next element of its pointed-to type.
int arr[] = {10, 20, 30};
int *ptr = arr;
printf("%d\n", *ptr);
ptr++;
printf("%d\n", *ptr);
The output is 10 followed by 20.
A pointer can be decremented to move to the previous array element.
int arr[] = {10, 20, 30};
int *ptr = &arr[2];
printf("%d\n", *ptr);
ptr--;
printf("%d\n", *ptr);
The pointer moves from arr[2] to arr[1].
A pointer can be used with a loop to traverse an array.
int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;
for(int i = 0; i < 5; i++)
{
printf("%d ", *(ptr + i));
}
Instead of using an index, the pointer itself can be moved through the array.
int arr[] = {10, 20, 30, 40};
int *ptr = arr;
for(int i = 0; i < 4; i++)
{
printf("%d ", *ptr);
ptr++;
}
Each increment moves the pointer to the next element.
The address of the first array element can be stored in a pointer.
int arr[] = {10, 20, 30};
int *ptr = &arr[0];
printf("%p", (void *)ptr);
This pointer points directly to the first element.
A pointer can point to any valid element of an array.
int arr[] = {10, 20, 30, 40};
int *ptr = &arr[2];
printf("%d", *ptr);
The output is 30.
A pointer can modify an array element.
int arr[] = {10, 20, 30};
int *ptr = arr;
*(ptr + 1) = 100;
printf("%d", arr[1]);
The second element becomes 100.
When two pointers point into the same array, their difference can represent the number of array elements between them.
int arr[] = {10, 20, 30, 40, 50};
int *p1 = &arr[1];
int *p2 = &arr[4];
printf("%td", p2 - p1);
The result is 3.
Pointers that point into the same array can be compared to determine their relative positions.
int arr[] = {10, 20, 30};
int *p1 = &arr[0];
int *p2 = &arr[2];
if(p1 < p2)
{
printf("p1 comes before p2");
}
When an array is passed to a function, the parameter is adjusted to a pointer to the first element.
void display(int arr[], int size)
{
for(int i = 0; i < size; i++)
{
printf("%d ", arr[i]);
}
}
This function receives access to the original array elements.
A pointer can also be explicitly used as the function parameter.
void display(int *ptr, int size)
{
for(int i = 0; i < size; i++)
{
printf("%d ", *(ptr + i));
}
}
The pointer points to the first element of the array.
A function can modify the original array through a pointer parameter.
void update(int *ptr, int size)
{
for(int i = 0; i < size; i++)
{
ptr[i] = ptr[i] * 2;
}
}
The changes affect the original array because the function receives access to its elements.
int arr[] = {10, 20, 30, 40};
int *ptr = arr;
int sum = 0;
for(int i = 0; i < 4; i++)
{
sum += *(ptr + i);
}
printf("Sum = %d", sum);
int arr[] = {15, 40, 25, 60, 10};
int *ptr = arr;
int largest = *ptr;
for(int i = 1; i < 5; i++)
{
if(*(ptr + i) > largest)
{
largest = *(ptr + i);
}
}
printf("Largest = %d", largest);
int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;
int search = 30;
int found = 0;
for(int i = 0; i < 5; i++)
{
if(*(ptr + i) == search)
{
found = 1;
break;
}
}
if(found)
{
printf("Element found");
}
else
{
printf("Element not found");
}
A character pointer can be used to traverse a null-terminated character array.
char name[] = "Computer";
char *ptr = name;
while(*ptr != '\0')
{
printf("%c", *ptr);
ptr++;
}
A pointer to const data can be used when the pointed-to characters or values should not be modified through that pointer.
const int arr[] = {10, 20, 30};
const int *ptr = arr;
printf("%d", *ptr);
The pointer can be moved, but the array elements cannot be modified through this pointer.
| Array | Pointer |
|---|---|
| Stores a collection of elements | Stores an address |
| Array name cannot be assigned a new address | Pointer can be assigned a different address |
sizeof(arr) gives total array size when arr is an actual array |
sizeof(ptr) gives pointer size |
| Elements are accessed using indexes | Elements can be accessed using dereferencing and pointer arithmetic |
When an array is passed to a function, the parameter behaves as a pointer.
Therefore, sizeof on that parameter gives the pointer size, not
the total size of the original array.
void display(int arr[])
{
printf("%zu", sizeof(arr));
}
Pass the array size separately when the function needs to know the number of elements.
A pointer should not be dereferenced outside the valid range of an array.
int arr[3] = {10, 20, 30};
int *ptr = arr;
printf("%d", *(ptr + 3));
The pointer may form a one-past-the-end position for certain pointer operations, but it must not be dereferenced there.
#include <stdio.h>
int main()
{
int arr[5];
int *ptr = arr;
int sum = 0;
printf("Enter 5 numbers:\n");
for(int i = 0; i < 5; i++)
{
scanf("%d", ptr + i);
}
printf("Array elements:\n");
for(int i = 0; i < 5; i++)
{
printf("%d ", *(ptr + i));
sum += *(ptr + i);
}
printf("\nSum = %d", sum);
return 0;
}
This program uses a pointer to take input into an array and then display and calculate the sum of its elements.
#include <stdio.h>
int main()
{
int arr[] = {10, 20, 30, 40, 50};
int *start = arr;
int *end = arr + 4;
while(start < end)
{
int temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
for(int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
Two pointers are used here: one starts at the first element and the other starts at the last element.
Pointers and arrays are commonly used together in:
Create a C program that:
Practice both forms:
arr[i]
and
*(ptr + i)
arr[i] and *(arr + i) access the same array element.ptr++ moves a pointer to the next element of its pointed-to type.sizeof on an actual array gives its total size, while a pointer gives the pointer size.Question: Which expression accesses the same element as arr[i]?