🌟 أولًا: ما هو المؤشر (Pointer)؟
المؤشر هو متغير…
لكن مش مثل باقي المتغيرات اللي بتخزن قيمة مباشرة.
المؤشر يخزن عنوان متغير آخر في الذاكرة.
بمعنى آخر:
بدل ما تحمل “القيمة”، بتحمل “المكان” اللي فيه القيمة.
🎯 تشبيه لفهم المؤشرات
تخيّل عندك بيت اسمه “X”،
والوصف تبعه:
- في شارع كذا
- رقم البيت كذا
المؤشر هو ورقة مكتوب عليها عنوان البيت.
مش بيت، بل “مكان البيت”.
هيك بالضبط المؤشر في C++.
⚙️ ثانيًا: كيفية تعريف المؤشرات
تعريف المؤشر بسيط جدًا:
int* ptr;
هذا متغير اسمه ptr مهمته يخزن عنوان متغير من نوع int.
يمكنك أيضًا كتابة:
int *ptr;
int * ptr;
كلها صح.
📌 مثال عملي لفهم المؤشر:
#include <iostream>
using namespace std;
int main() {
int x = 10;
int* ptr = &x;
cout << "قيمة x: " << x << endl;
cout << "عنوان x: " << &x << endl;
cout << "قيمة ptr (عنوان x): " << ptr << endl;
cout << "قيمة x من خلال ptr: " << *ptr << endl;
}
📤 النتيجة المتوقعة:
قيمة x: 10
عنوان x: 0x7ffd1...
قيمة ptr: 0x7ffd1...
قيمة x من خلال ptr: 10
🧠 تفسير السطور المهمة:
&x→ يعني “هات عنوان متغير x”.ptr→ يخزن هذا العنوان.*ptr→ الوصول للقيمة الموجودة داخل هذا العنوان.
*في التعريف → pointer*في الاستخدام → dereference (الوصول للقيمة)
🧩 ثالثًا: مفهوم الـ Dereferencing
الدالة dereference تعني “حلّ العنوان” أو “الدخول للبيت اللي معنا مفتاحه”.
مثال بسيط:
int x = 20;
int* ptr = &x;
cout << *ptr; // يطبع 20
لكن الجميل إنك تقدر تغيّر القيمة من خلال المؤشر:
*ptr = 99;
cout << x; // 99
🔥 رابعًا: المؤشرات والذاكرة — Stack vs Heap
قبل ما ندخل للعمق، لازم نعرف نقطتين:
- الذاكرة لها منطقتين أساسيّتين:
- Stack: تخزن المتغيرات العادية.
- Heap: تخزن الأشياء اللي تُنشأ ديناميكيًا (new / malloc).
المؤشرات هي “المفتاح الرئيسي” للوصول إلى heap وتنظيم الذاكرة.
لكن هذا رح ندرسه في درس “الذاكرة الديناميكية” لاحقًا.
📦 خامسًا: المؤشرات وأنواع البيانات
1. مؤشر لـ int
int x = 5;
int* p = &x;
2. مؤشر لـ double
double d = 5.5;
double* p = &d;
3. مؤشر لـ char
char c = 'A';
char* p = &c;
القاعدة:
نوع المؤشر لازم يطابق نوع المتغير.
🧱 سادسًا: المؤشرات والمصفوفات
المصفوفات عبارة عن “عناوين متتالية”.
int arr[3] = {10, 20, 30};
int* p = arr; // arr == &arr[0]
🔹 الوصول للعناصر باستخدام المؤشر
cout << *p << endl; // 10
cout << *(p + 1) << endl; // 20
cout << *(p + 2) << endl; // 30
🔁 سابعًا: المؤشرات والدوال — Pass by Pointer
الآن نأتي لجزء مهم جدًا:
تمرير المؤشرات إلى الدوال.
ليش نحتاج نمرر المؤشر بدل القيمة؟
لأن المؤشر يعطي الدالة القدرة على:
- التعديل على المتغير الأصلي
- الوصول لمصفوفات
- تمرير بيانات كبيرة بسرعة
✨ مثال: تمرير المتغير بالقيمة vs بالمؤشر
🔹 التمرير بالقيمة:
void changeValue(int x) {
x = 100;
}
لا يغير شيئًا.
🔹 التمرير بالمؤشر:
void changeValue(int* p) {
*p = 100;
}
هذا يغير القيمة الحقيقية.
📘 مثال عملي كامل:
#include <iostream>
using namespace std;
void update(int* p) {
*p = 50;
}
int main() {
int x = 10;
update(&x);
cout << x; // 50
}
🧩 ثامنًا: المؤشرات كمعاملات لدوال تعمل على مصفوفات
مهم جدًا لأن:
- المصفوفات تُمرر تلقائيًا كمؤشرات.
void printArray(int* arr, int size) {
for(int i = 0; i < size; i++)
cout << arr[i] << " ";
}
الاستدعاء:
int a[5] = {1,2,3,4,5};
printArray(a, 5);
⚠️ تاسعًا: أخطاء المؤشرات الشائعة
1. مؤشر غير مهيأ (Wild Pointer)
int* ptr;
*ptr = 5; // كارثة!
2. الوصول لعنوان محذوف
int* p = new int(5);
delete p;
cout << *p; // خطير جدا
3. نسيان تحرير الذاكرة
يسبب Memory leak
ورح نشرحه في درس إدارة الذاكرة.
🛠️ عاشرًا: العلاقة بين المؤشرات والـ Reference
| الفرق | Pointer | Reference |
|---|---|---|
| يمكن تغييره ليشير لشيء آخر | نعم | لا |
| يقبل القيمة الفارغة NULL | نعم | لا |
| يحتاج dereferencing | نعم | لا |
| يستخدم للتعامل مع الذاكرة الديناميكية | نعم | لا |
🍀 أمثلة عملية تمزج كل شيء
1. تبادل قيم باستخدام المؤشر
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
2. مؤشر لمؤشر (Pointer to Pointer)
int x = 10;
int* p = &x;
int** pp = &p;
cout << **pp; // 10
🧠 مؤشرات الدوال (Function Pointers)
(موضوع متقدم لكنه مهم)
المؤشر مش بس يشير لمتغير…
ممكن يشير لدالة!
void hello() {
cout << "Hello!" << endl;
}
int main() {
void (*ptr)() = hello;
ptr();
}
🔥 مشروع تدريبي صغير:
برنامج يعكس عناصر مصفوفة باستخدام المؤشرات فقط:
void reverse(int* arr, int size) {
int* start = arr;
int* end = arr + size - 1;
while (start < end) {
int temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
}
🌍 روابط خارجية موثوقة
🔗 cppreference — Pointers
https://en.cppreference.com/w/cpp/language/pointer
🔗 Programiz — Pointers
https://www.programiz.com/cpp-programming/pointers
🎯 الخلاصة الكبرى
المؤشرات هي أكثر جزء “مرعب” في C++،
لكن لو فهمتها… مستواك يقفز قفزة هائلة.
✔ المؤشر = متغير يخزن عنوان
✔ *ptr للوصول للقيمة
✔ تمرير المؤشر للدوال يعطيك القدرة على تعديل الأصل
✔ المؤشرات أساسية للمصفوفات، السلاسل، الهياكل، الذاكرة الديناميكية
✔ هي الباب الحقيقي للبرمجة منخفضة المستوى
تعلّم المؤشرات يعني أنك تتجاوز مرحلة “مبرمج مبتدئ” إلى “مبرمج يفهم الآلة”.
اكتشاف المزيد من كود التطور
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.


