مقدمة في المؤشرات — المؤشرات والذاكرة
مقدمة في المؤشرات
كل متغير في برنامجك يعيش في مكان في الذاكرة له عنوان (رقم يحدد موقعه). المؤشر متغير قيمته عنوان متغير آخر.
عاملان أساسيان
| العامل | الاسم | يعطي |
|---|---|---|
| &x | عامل العنوان | عنوان x |
| *p | عامل الإشارة (dereference) | القيمة الموجودة في العنوان الذي يحمله p |
int age = 30;
int* p = &age; // p يحمل عنوان age
cout << p; // عنوان مثل 0x7ffd...
cout << *p; // 30
*p = 31; // تعديل age عبر المؤشرقراءة التصريح
int* p تعني: "p مؤشر إلى int". نوع المؤشر مهم: double* يشير إلى double فقط، والمترجم يرفض double* d = &age;.
الرمز * له معنيان
- في التصريح int* p: "مؤشر إلى".
- في التعبير *p: "القيمة في العنوان".
هذا يربك المبتدئين؛ ركّز على السياق.
لاحظ: كل تصريح منفصل
int* a, b; تجعل a مؤشراً و b عدداً صحيحاً عادياً! صرّح بكل مؤشر في سطر.
المؤشر الفارغ
int* p = nullptr; يعني أن المؤشر لا يشير لأي شيء. الإشارة إلى nullptr (*p) خطأ يوقف البرنامج. افحص دائماً: if (p != nullptr) أو اختصاراً if (p). المؤشر غير المهيأ أسوأ: يحمل عنواناً عشوائياً.
المؤشرات والمراجع
تعلمت المراجع في دورة الأساسيات. الفرق:
| المرجع int& | المؤشر int* |
|---|---|
| يجب ربطه عند الإنشاء | يمكن إنشاؤه فارغاً (nullptr) |
| لا يُعاد ربطه | يمكن أن يشير لمتغير آخر لاحقاً |
| يُستخدم كالمتغير مباشرة | يحتاج * للوصول للقيمة |
| لا يوجد "مرجع فارغ" | يجب فحص nullptr |
القاعدة: استخدم المراجع عندما تستطيع، والمؤشرات عندما تحتاج "لا شيء" أو إعادة التوجيه أو الذاكرة الديناميكية.
لماذا نتعلمها؟
الذاكرة الديناميكية، هياكل البيانات (القوائم المترابطة، الأشجار)، التعامل مع مكتبات C، وفهم ما يحدث تحت أي لغة برمجة.
تمرين
أنشئ متغيرين int، ومؤشراً يشير للأول ثم للثاني، وعدّل كلاً منهما عبر المؤشر، واطبع القيم والعناوين قبل وبعد.
#include <iostream>
using namespace std;
int main() {
// متغير عادي
int num = 42;
// الحصول على العنوان
cout << "قيمة num: " << num << endl;
cout << "عنوان num: " << &num << endl;
// تصريح مؤشر وتهيئته
int* ptr = # // ptr يشير لـ num
cout << "\n=== معلومات المؤشر ===" << endl;
cout << "قيمة ptr (العنوان): " << ptr << endl;
cout << "قيمة *ptr (القيمة): " << *ptr << endl;
cout << "عنوان ptr نفسه: " << &ptr << endl;
// تعديل القيمة عبر المؤشر
*ptr = 100;
cout << "\nبعد *ptr = 100:" << endl;
cout << "num = " << num << endl; // 100!
// تغيير المؤشر ليشير لمتغير آخر
int other = 200;
ptr = &other;
cout << "\nبعد تغيير ptr:" << endl;
cout << "*ptr = " << *ptr << endl; // 200
cout << "num = " << num << endl; // 100 (لم يتغير)
// حجم المؤشر
cout << "\nحجم المؤشر: " << sizeof(ptr) << " bytes" << endl;
return 0;
}اختبر فهمك