Pointer Arithmetic
Pointer arithmetic ka meaning hai:
Pointer mein stored address ko increment, decrement, add ya subtract karke memory ke doosre elements tak pahunchna.
Pointer arithmetic ko samajhne ka sabse accha example array hai, kyunki array ke elements memory mein continuously store hote hain.
1. Array memory mein kaise store hota hai?
int arr[5] = {10, 20, 30, 40, 50};
Maan lo ek int ka size 4 bytes hai aur arr[0] address 1000 par hai:
| Element | Value | Hypothetical address |
|---|---|---|
arr[0] |
10 | 1000 |
arr[1] |
20 | 1004 |
arr[2] |
30 | 1008 |
arr[3] |
40 | 1012 |
arr[4] |
50 | 1016 |
Har next integer ka address 4 bytes aage hai.
Array ka naam first element ka address represent karta hai:
arr == &arr[0]
Pointer bana sakte hain:
int* ptr = arr;
Yeh same hai:
int* ptr = &arr[0];
Ab:
ptr // arr[0] ka address
*ptr // arr[0] ki value, yani 10
2. Pointer increment: ptr++
int* ptr = arr;
ptr++;
Bahut important:
ptr++address mein sirf1 byteadd nahi karta. Yeh pointer ko next element par le jata hai.
Agar int ka size 4 bytes hai:
ptr pehle = 1000
ptr++ ke baad = 1004
Example:
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40};
int* ptr = arr;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
return 0;
}
Output:
10
20
30
Flow:
ptr → 10
ptr++ → 20
ptr++ → 30
Pointer data type ka effect
char* charPtr;
int* intPtr;
double* doublePtr;
Assume:
| Pointer type | Typical element size | ptr++ ka effect |
|---|---|---|
char* |
1 byte | 1 byte aage |
int* |
4 bytes | 4 bytes aage |
double* |
8 bytes | 8 bytes aage |
Exact size system par depend kar sakta hai. sizeof() se check kar sakte hain:
cout << sizeof(char) << endl;
cout << sizeof(int) << endl;
cout << sizeof(double) << endl;
Conceptually:
New address = Old address + sizeof(pointed data type)
3. Pointer decrement: ptr--
ptr-- pointer ko previous element par le jata hai.
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40};
int* ptr = &arr[3];
cout << *ptr << endl;
ptr--;
cout << *ptr << endl;
ptr--;
cout << *ptr << endl;
return 0;
}
Output:
40
30
20
Flow:
ptr → arr[3]
ptr-- → arr[2]
ptr-- → arr[1]
4. Pointer mein number add karna: ptr + n
int* ptr = arr;
Expressions:
ptr + 0 // arr[0] ka address
ptr + 1 // arr[1] ka address
ptr + 2 // arr[2] ka address
ptr + 3 // arr[3] ka address
Value chahiye toh dereference karenge:
*(ptr + 0) // 10
*(ptr + 1) // 20
*(ptr + 2) // 30
*(ptr + 3) // 40
Example:
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = arr;
cout << *(ptr + 0) << endl;
cout << *(ptr + 1) << endl;
cout << *(ptr + 2) << endl;
cout << *(ptr + 3) << endl;
cout << *(ptr + 4) << endl;
return 0;
}
Output:
10
20
30
40
50
ptr + 2 ka exact meaning
Maan lo:
ptr ka address = 1000
sizeof(int) = 4 bytes
Tab:
ptr + 2
= 1000 + 2 × sizeof(int)
= 1000 + 2 × 4
= 1008
Address 1008 par arr[2] stored hai.
Formula:
ptr + n = current address + n × sizeof(data type)
5. Pointer mein number subtract karna: ptr - n
int* ptr = &arr[4];
Ab:
*(ptr - 0) // arr[4] = 50
*(ptr - 1) // arr[3] = 40
*(ptr - 2) // arr[2] = 30
Example:
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = &arr[4];
cout << *(ptr - 0) << endl;
cout << *(ptr - 1) << endl;
cout << *(ptr - 2) << endl;
return 0;
}
Output:
50
40
30
Formula:
ptr - n = current address - n × sizeof(data type)
6. Array indexing aur pointer arithmetic ka connection
Yeh bahut important relation hai:
arr[i] == *(arr + i)
Example:
arr[2]
Compiler ise conceptually aise process kar sakta hai:
*(arr + 2)
Steps:
arrfirst element ka address hai.arr + 2third element ka address hai.*(arr + 2)third element ki value deta hai.
#include <iostream>
using namespace std;
int main() {
int arr[] = {100, 200, 300, 400};
cout << arr[2] << endl;
cout << *(arr + 2) << endl;
return 0;
}
Output:
300
300
General relations:
arr[0] == *(arr + 0)
arr[1] == *(arr + 1)
arr[2] == *(arr + 2)
arr[3] == *(arr + 3)
7. Array ko pointer se traverse karna
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int size = 5;
int* ptr = arr;
for (int i = 0; i < size; i++) {
cout << *(ptr + i) << " ";
}
return 0;
}
Output:
10 20 30 40 50
Pointer increment se bhi traverse kar sakte hain:
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = arr;
for (int i = 0; i < 5; i++) {
cout << *ptr << " ";
ptr++;
}
return 0;
}
8. *ptr++, (*ptr)++ aur *++ptr
Ye teen expressions same nahi hain.
Case 1: *ptr++
Operator precedence ki wajah se:
*ptr++
ka meaning hai:
*(ptr++)
Pehle current pointer ki value access hoti hai, phir pointer next element par chala jata hai.
int arr[] = {10, 20, 30};
int* ptr = arr;
cout << *ptr++ << endl;
cout << *ptr << endl;
Output:
10
20
Case 2: (*ptr)++
Yahan parentheses ki wajah se pointer move nahi hota. Pointed value increment hoti hai.
int arr[] = {10, 20, 30};
int* ptr = arr;
(*ptr)++;
cout << arr[0] << endl;
cout << *ptr << endl;
Output:
11
11
Pointer abhi bhi arr[0] ko hi point kar raha hai.
Case 3: *++ptr
Iska meaning hai:
*(++ptr)
Pehle pointer next element par jayega, phir uski value access hogi.
int arr[] = {10, 20, 30};
int* ptr = arr;
cout << *++ptr;
Output:
20
Comparison:
| Expression | Kya hota hai? |
|---|---|
*ptr++ |
Current value use, phir pointer next par |
(*ptr)++ |
Current element ki value increment |
*++ptr |
Pointer pehle next par, phir value use |
++(*ptr) |
Current element increment, updated value use |
Readable code ke liye complex expressions ko alag statements mein likhna better hota hai.
9. Do pointers ko subtract karna
Same array ke do pointers ko subtract karke unke beech elements ki distance mil sakti hai.
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* first = &arr[1];
int* second = &arr[4];
cout << second - first;
return 0;
}
Output:
3
Addresses ka byte difference maan lo:
arr[1] address = 1004
arr[4] address = 1016
Byte difference = 1016 - 1004 = 12
Element size = 4 bytes
Pointer difference = 12 / 4 = 3 elements
Pointer subtraction ka result bytes mein nahi, number of elements mein milta hai.
Standard type:
ptrdiff_t distance = second - first;
Iske liye:
#include <cstddef>
use kiya ja sakta hai.
10. Kya do pointers ko add kar sakte hain?
int* p1 = &arr[0];
int* p2 = &arr[2];
p1 + p2; // Invalid
Do memory addresses ko add karne ka meaningful result nahi hota.
Allowed forms:
p1 + 2
p2 - 1
p2 - p1
Invalid forms:
p1 + p2
p1 * p2
p1 / p2
11. Pointer comparison
Same array ke pointers ko compare kiya ja sakta hai:
int arr[] = {10, 20, 30, 40};
int* p1 = &arr[1];
int* p2 = &arr[3];
cout << (p1 < p2);
Output:
1
Kyunki arr[1], arr[3] se pehle memory mein stored hai.
Comparisons:
p1 == p2
p1 != p2
p1 < p2
p1 > p2
p1 <= p2
p1 >= p2
Ordering comparisons ko same array ke elements ke pointers ke saath hi use karna meaningful aur safe hai.
12. Array name aur pointer mein important difference
int arr[] = {10, 20, 30};
int* ptr = arr;
Dono first element ka address represent kar sakte hain:
cout << arr;
cout << ptr;
Lekin dono exactly same cheez nahi hain.
Pointer ko move kar sakte hain:
ptr++;
Array name ko move nahi kar sakte:
arr++; // Error
Pointer ko kisi doosre address par point kara sakte hain:
ptr = &arr[2];
Array name fixed hota hai:
arr = &arr[2]; // Error
| Array name | Pointer variable |
|---|---|
| First element ka address represent karta hai | Address store karta hai |
| Change/reassign nahi kar sakte | Reassign kar sakte hain |
arr++ invalid |
ptr++ valid ho sakta hai |
| Array ki fixed identity hai | Separate pointer variable hai |
13. One-past-the-end pointer
Array ke last element ke just baad wala address calculate karna allowed hai:
int arr[] = {10, 20, 30};
int* end = arr + 3;
end kisi valid array element ko point nahi karta. Isko loop stopping condition ke liye use kar sakte hain:
for (int* ptr = arr; ptr != arr + 3; ptr++) {
cout << *ptr << " ";
}
Output:
10 20 30
Lekin end ko dereference nahi karna:
cout << *(arr + 3); // Undefined behaviour
Valid elements:
arr + 0
arr + 1
arr + 2
Stopping position:
arr + 3
14. Out-of-bounds pointer access
int arr[] = {10, 20, 30};
cout << *(arr + 5);
Array mein index 5 exist nahi karta. Program:
garbage value de sakta hai,
crash kar sakta hai,
ya apparently chal sakta hai, lekin result reliable nahi hai.
Isse undefined behaviour kehte hain.
C++ automatically array bounds check nahi karta:
arr[5]
aur:
*(arr + 5)
dono unsafe hain.
15. Standalone variables par arithmetic kyon avoid karein?
int number = 10;
int* ptr = &number;
ptr++;
cout << *ptr; // Invalid access/undefined behaviour
number kisi array ka element nahi hai. ptr++ ke baad pointer next integer-sized memory location par toh chala gaya, lekin wahan koi valid related object available nahi hai.
Pointer arithmetic ka safe practical use mostly:
Arrays
Dynamic arrays
Contiguous memory containers
Low-level memory processing
ke saath hota hai.
16. void* par pointer arithmetic
Standard C++ mein:
void* ptr;
ptr++; // Invalid
Kyunki compiler ko void ka size pata nahi hai:
ptr + 1 ka meaning kitne bytes?
int* + 1→ next integerdouble* + 1→ next doublevoid* + 1→ next kya?
Isi reason se standard C++ mein void* arithmetic allowed nahi hai.
Pehle correct typed pointer mein cast karna hoga:
int arr[] = {10, 20, 30};
void* ptr = arr;
int* intPtr = static_cast<int*>(ptr);
cout << *(intPtr + 1);
Output:
20
17. Practical example: Array ka sum using pointer
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int size = 5;
int sum = 0;
int* ptr = arr;
for (int i = 0; i < size; i++) {
sum += *(ptr + i);
}
cout << "Sum = " << sum;
return 0;
}
Output:
Sum = 150
18. Practical example: Pointer se array update karna
#include <iostream>
using namespace std;
int main() {
int marks[] = {50, 60, 70, 80};
int size = 4;
int* ptr = marks;
for (int i = 0; i < size; i++) {
*(ptr + i) += 5;
}
for (int i = 0; i < size; i++) {
cout << marks[i] << " ";
}
return 0;
}
Output:
55 65 75 85
*(ptr + i) actual array element ko represent karta hai, isliye original array modify hota hai.
19. Practical example: Maximum value
#include <iostream>
using namespace std;
int main() {
int arr[] = {18, 42, 13, 91, 35};
int size = 5;
int* ptr = arr;
int maximum = *ptr;
for (int i = 1; i < size; i++) {
if (*(ptr + i) > maximum) {
maximum = *(ptr + i);
}
}
cout << "Maximum = " << maximum;
return 0;
}
Output:
Maximum = 91
20. Reverse traversal using pointers
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = &arr[4];
for (int i = 0; i < 5; i++) {
cout << *ptr << " ";
ptr--;
}
return 0;
}
Output:
50 40 30 20 10
A subtle safety point: last iteration ke baad ptr-- pointer ko array ke start se pehle le ja sakta hai. A safer version index-based hai:
for (int i = 4; i >= 0; i--) {
cout << *(arr + i) << " ";
}
Important rules
| Operation | Valid? | Meaning |
|---|---|---|
ptr++ |
Yes, array boundary ke andar | Next element |
ptr-- |
Yes, array boundary ke andar | Previous element |
ptr + n |
Yes, valid range tak | n elements aage |
ptr - n |
Yes, valid range tak | n elements peeche |
p2 - p1 |
Same array mein valid | Element distance |
p1 + p2 |
No | Do addresses add nahi hote |
p1 * p2 |
No | Invalid |
p1 / p2 |
No | Invalid |
ptr + 0.5 |
No | Integer offset required |
voidPtr++ |
Standard C++ mein no | void ka size unknown |
| Out-of-bounds dereference | No | Undefined behaviour |
Core formulas
int arr[] = {10, 20, 30, 40};
int* ptr = arr;
Yaad rakho:
ptr == &arr[0]
ptr + i == &arr[i]
*(ptr + i) == arr[i]
ptr++ == next element ka address
ptr-- == previous element ka address
Address calculation:
ptr + n
= current address + n × sizeof(data type)
Do pointers ka difference:
p2 - p1
= unke beech elements ki sankhya
Practice questions
Question 1: Output batao
int arr[] = {5, 10, 15, 20};
int* ptr = arr;
cout << *(ptr + 2);
Output:
15
Question 2: Output batao
int arr[] = {10, 20, 30};
int* ptr = arr;
cout << *ptr++ << " ";
cout << *ptr;
Output:
10 20
Question 3: Output batao
int arr[] = {10, 20, 30};
int* ptr = arr;
(*ptr)++;
cout << arr[0];
Output:
11
Question 4: Output batao
int arr[] = {10, 20, 30, 40, 50};
int* p1 = &arr[1];
int* p2 = &arr[4];
cout << p2 - p1;
Output:
3
Question 5: Error identify karo
int arr[] = {10, 20, 30};
int* ptr = arr;
cout << *(ptr + 3);
ptr + 3 one-past-the-end address hai. Isko calculate kar sakte hain, lekin dereference nahi kar sakte. Valid last element:
cout << *(ptr + 2);
One-line feeling
Pointer arithmetic raw bytes count karne ke bajay pointed data type ke elements count karti hai.