Pointer vs Arrays
- Recap : Pointers refer to memory addresses
- Pointer arithmetic useful for array traversal
- Recap : Arrays are Contiguous memory blocks
- Array names decay to pointers to the first element
- Array name is constant referring to the address of array
- Array name behaves like a pointer in certain ways
- (arr + i) gives address of ith element of array
Pointer Arithmetic
ptr++
- Take me to next cell
- Useful for traversing arrays sequentially
ptr--
- Decrements the pointer to previous element
+
, +=
- Adding integer moves pointer ahead by that amount
- Helps jump around array without index
-
, -=
- Subtracting integer moves pointer backward
int arr[5] = {1,2,3,4,5};
int* ptr = arr; //ptr points to arr[0]
ptr++; //now points to arr[1] // not useful operation
ptr += 2; //points to arr[3]
ptr - 2; //points back to arr[1]
int offset = ptr - arr; //distance between pointers
- Incrementing pointer traverses array
- Adding/subtracting integers moves pointer
- Subtracting pointers gives distance/offset
Example:
#include<iostream>
using namespace std;
int main(){
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *ptr = arr; // Read only pointer
// Traverse
for(int i=0; i<4; i++){
cout << ptr << " Data " << *(ptr) << endl;
ptr = ptr + 1;
}
//reset to begining of the array
ptr = arr;
// Print
for(int i=0; i<10; i++){
cout << *(arr + i) << " , "; // arr[i] // using dereference operator
}
return 0;
}
NOTE
- ptr1 + ptr2 : doesnβt make any sense
- ptr1 - ptr2 : does makes sense for arrays
Pointers to Arrays
We can have pointers to individual elements or the entire array:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
// Pointer to single element
int* p1 = arr;
// Pointer to entire array
int (*ptr)[10] = &arr;
Pointer to Element
This points to the single element:
p1++; // Points to arr[1]
cout << p1 << endl;
cout << *p1 << endl;
Pointer to Array
This points to the whole array:
cout << "Address of Array: " << ptr << endl;
Can get next array address:
cout << ptr + 1 << endl;
Jumps by complete array size (not just 1 element).
Dereferencing
Gives access to array:
cout << (*ptr)[0] << endl; // Element arr[0]
Example:
#include<iostream>
using namespace std;
int main(){
int arr[10] = {1,2,3,4};
cout << arr << endl;
cout << &arr << endl;
cout << arr + 1 << endl;
// Pointer to 0th element of the array
int * p1 = arr;
p1++;
cout << p1 << endl;
cout << (*p1) << endl;
// Pointer to the entire array
int (*ptr)[5]; // Pointer to an array of 5 elements
ptr = &arr;
cout << "Pointer to Array " << ptr << endl;
cout << ptr << endl;
cout << ptr + 1 << endl; // location after the array
// address jump will be of 40 bytes
// int *ptr[5]; // Any array of pointer of size 5
return 0;
}
Dereferencing Pointers to Arrays
We can have a pointer to an individual element or the entire array:
int arr[5] = {1,2,3,4,5};
// Pointer to single element
int* ptr1 = arr;
// Pointer to entire array
int (*ptr2)[5] = &arr;
Dereferencing Element Pointer
This gives the element value:
cout << *ptr1; // Prints 1
Can access elements like array:
ptr1[0]; // 1
ptr1[1]; // 2
Dereferencing Array Pointer
This gives the array itself:
cout << (*ptr2)[0]; // Prints 1
cout << (*ptr2)[1]; // Prints 2
Essentially simplifies array syntax:
(*ptr2)[i]; // Same as arr[i]
We dereference array pointer and can use like a normal array.
The array pointer will increment by the size of array (not by 1 element).
Example:
#include<iostream>
using namespace std;
int main(){
int arr[10] = {1,2,3,4};
cout << arr << endl;
cout << &arr << endl;
cout << arr + 1 << endl;
// Pointer to 0th element of the array
int * p1 = arr;
p1++;
cout << p1 << endl;
cout << (*p1) << endl;
// Pointer to the entire array
int (*ptr)[5]; // Pointer to an array of 5 elements
ptr = &arr;
cout << "Pointer to Array " << ptr << endl;
cout << ptr << endl;
cout << ptr + 1 << endl; // location after the array
// address jump will be of 40 bytes
// int *ptr[5]; // Any array of pointer of size 5
// Dereferencing the pointer to an array
cout << (*p1) << endl // a[0]
cout << (*ptr) << endl; // arr
return 0;
}
Row Pointers in 2D Arrays
In a 2D array, each element is actually a 1D array representing a row. Rows are stored sequentially in memory(Row major form).
int arr[3][4]; // 3 rows, 4 cols
This can be visualized as an array of row pointers:
arr --> [row1] -> [row2] -> [row3]
Where:
arr
- Pointer to first rowrow1
,row2
,row3
- Pointers to each row array
The array name arr
itself acts as a pointer to the first row:
int (*row1)[4] = arr;
We can traverse rows by incrementing the array name:
cout << arr << endl; // Address of row1
cout << arr+1 << endl; // Address of row2
cout << arr+2 << endl; // Address of row3
Accessing Elements
To access any element arr[i][j]
:
1. Index row pointer to get row
2. Index into that row to get element
Example:
#include<iostream>
using namespace std;
int main(){
// Pointers and 2D Arrays (Multi-Dimension Arrays)
int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
cout << "Arr "<< arr << endl;
cout << "Address of the 0,0 element " << &arr[0][0] << endl;
cout << "Address of the 0,1 element " << &arr[0][1] << endl;
cout << "Arr + 1 " << arr + 1 << endl; // Row pointer which jumps to next row
cout << "Address of the 1,0 element " << &arr[1][0] << endl;
return 0;
}
2D Arrays and Pointer
In a 2D array, each element itself is a 1D array representing a row. 2D arrays are stored in row-major order in memory.
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
arr
Β - Pointer to first row arrayarr[0]
Β - Pointer to first element of first row
The array name decays into a pointer to the first row:
cout << arr; // Prints address of first row
Passing 2D Arrays to Functions
#include<iostream>
using namespace std;
// Method 1 - Using pointer to array
void accept2DArray(int (*ptr)[4]){
cout << "Address of Row 0 " << ptr << endl;
cout << "Address of Row 1 " << ptr + 1 << endl;
int i = 1;
int j = 2;
cout << "Row 1, Col 2: " << *(*(ptr+i) + j) << endl;
cout << "Row 1, Col 2: " << ptr[i][j] << endl;
}
// Method 2 - Using 2D array syntax
void printArray2(int arr[][4]) {
cout << "Row 2, Col 3: " << arr[2][3] << endl;
}
int main(){
// Pointers and 2D Arrays (Multi-Dimension Arrays)
int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
// Pass as pointer
accept2DArray(arr);
// Pass using array syntax
printArray2(arr);
return 0;
}
The output of this would be:
Row 1, Col 2: 7
Row 2, Col 3: 12
NOTE
arr
Β decays to a pointer to the first row- Both methods allow accessing any element
arr[i][j]