يخزن المتغير العادي -مثل int x- قيمةً ما، ويضع البرنامج هذه القيمة في مكان ما داخل الذاكرة. يُعد الاسم x تسميةً مريحة يتيح لك المترجم (compiler) استخدامها لقراءة القيمة المخزنة وكتابتها دون الحاجة للتفكير في الموقع المادي الفعلي لتلك القيمة.
ومع ذلك، يظل الموقع المادي مهماً؛ لأن وحدة المعالجة المركزية (CPU) تقوم في النهاية بعمليات التحميل والتخزين باستخدام العناوين. فحتى عند كتابة x = 5;، يستخدم الكود المترجَم عنواناً في الخلفية لتحديد البايتات (bytes) الخاصة بـ x والكتابة فوقها.
من الطرق المفيدة لتصور الذاكرة اعتبارها مصفوفة طويلة من البايتات، حيث يمتلك كل بايت فهرساً يُعرف بـ “العنوان”. عندما ينشئ المترجم المتغير x، فإنه يختار نطاقاً من العناوين يكفي لتخزين قيمة من النوع int، ثم يجعل أي استخدام للاسم x يشير إلى ذلك النطاق.
ينتج عن هذا النموذج نتيجتان:
x، فإنك تقوم بالكتابة فوق البايتات الموجودة في نطاق العناوين نفسه.y = x، فستحصل عادةً على نطاق عناوين منفصل يحتوي على نسخة من القيمة؛ وبالتالي، فإن التغييرات اللاحقة على x لا تؤثر على y.المؤشر (Pointer) هو متغير تكون قيمته عبارة عن عنوان. إنه لا يخزن قيمة int بحد ذاتها، بل يخزن موقع وجود int في الذاكرة، مما يتيح لك تتبع ذلك العنوان للوصول إلى قيمة int.
في لغة C++، هناك عاملان (operators) يوضحان هذا المفهوم عملياً:
&x // عامل العنوان (address-of): يُنتج العنوان الذي تُخزن فيه x
*p // عامل إلغاء المرجع (dereference): يصل إلى القيمة المخزنة في العنوان الموجود داخل p
تأمل آلية عمل “خانات” الذاكرة وكيف يمكن للقيمة أن تتغير بينما يظل العنوان ثابتاً.
ثابت جوهري إذا كان
pيساوي&x، فإن*pيشير إلى نفس القيمة المخزنة فيx.
بمجرد القدرة على تخزين عنوان ما، يصبح بالإمكان مشاركة الوصول إلى كائن (object) واحد بدلاً من نسخه. ويتجلى ذلك في عدة حالات شائعة:
nullptr للدلالة على عدم وجود كائن، مما يجعل حالة الغياب واضحة وصريحة في نوع البيانات (type).قارن بين سيناريوهات النسخ والمشاركة، ولاحظ كيف تختلف عمليات التعديل والتكلفة بينهما.