Programming Basics SQL HTML CSS JavaScript Python C++ Java JavaFX Swing Problem Solving English English Conversations Computer Fundamentals Learn Typing

C++المؤشرات

  • مفهوم المؤشرات C++
  • تعريف مؤشر في C++
  • تحديد الشيء الذي يتم الإشارة إليه في C++
  • تغيير قيمة الشيء الذي يشير إليه المؤشر في C++
  • أمثلة حول مزايا استخدام المؤشرات في C++

مفهوم المؤشرات C++

في الدرس السابق تعرفنا على المراجع ( References ) و تعلمنا كيف أنها تستخدم بهدف جعلنا قادرين على الوصول إلى الأشياء المعرفة في الذاكرة بشكل مباشر.
المؤشرات ( Pointers ) تستخدم أيضاً للوصول لأي شيء يتم تعريفه في الذاكرة و هي تعطينا المزيد من المزايا في التحكم.


الفرق بين المرجع و المؤشر

الفرق الأساسي بينهما هو أن المؤشر يقوم بحجز مساحة في الذاكرة لتخزين عنوان الشيء الذي يؤشر إليه.
بالإضافة إلى ذلك, فإن المؤشر يمكنه الإشارة لأي شيء موجود في الذاكرة في أي وقت و لست مجبراً على تحديد الشيء الذي يشير إليه لحظة إنشاءه.

في هذا الدرس ستفهم الفرق بين المراجع و المؤشرات بالنسبة للذاكرة و ستتعرف على المزايا الإضافية التي توفرها المؤشرات.

تعريف مؤشر في C++

لتعريف مؤشر جديد نستخدم الرمز * مع الإشارة إلى أن نوع المؤشر يجب أن يكون نفس نوع الشيء الذي سيشير له في الذاكرة.

إذا اردنا تعريف مؤشر نوعه int و إسمه x فعندنا ثلاث خيارات كالتالي.

// الأسلوب الأول و الذي يعتبر الأكثر استخداماً
int* x;
// الأسلوب الثاني
int *x;
// الأسلوب الثالث
int * x;
// الأسلوب الأول و الذي يعتبر الأكثر استخداماً int* x; // الأسلوب الثاني int *x; // الأسلوب الثالث int * x;


الآن, لتعريف مؤشر و جعله يشير لقيمة شيئ موجود في الذاكرة, يجب أن نقوم بتمرير عنوان هذا الشيء كقيمة للمؤشر و عندها سيصبح المؤشر قادر على الوصول لقيمته و عنوانه كما سنرى في المثال التالي.

مثال

main.cpp
#include <iostream>
using namespace std;
int main()
{
// "Arabic" و قيمته language هنا قمنا بتعريف متغير إسمه
string language = "Arabic";
// في الذاكرة language هنا قمنا بتعريف مؤشر لعنوان المتغير
string* ptr = &language;
// language هنا قمنا بطباعة قيمة المتغير
cout << "language = " << language << endl;
// في الذاكرة language هنا قمنا بطباعة عنوان المتغير
cout << "Address of language = " << &language << endl;
// في الذاكرة ptr هنا قمنا بطباعة عنوان المؤشر
cout << "Address of ptr in memory = " << &ptr << endl;
// language و التي هي عنوان المتغير ptr هنا قمنا بطباعة القيمة الموجودة في المؤشر
cout << "Value of ptr in memory = " << ptr << endl;
// language في الذاكرة و التي هي قيمة المتغير ptr هنا قمنا بطباعة القيمة التي يشير إليها عنوان المؤشر
cout << "Value that ptr point to = " << *ptr;
return 0;
}
#include <iostream> using namespace std; int main() { // "Arabic" و قيمته language هنا قمنا بتعريف متغير إسمه string language = "Arabic"; // في الذاكرة language هنا قمنا بتعريف مؤشر لعنوان المتغير string* ptr = &language; // language هنا قمنا بطباعة قيمة المتغير cout << "language = " << language << endl; // في الذاكرة language هنا قمنا بطباعة عنوان المتغير cout << "Address of language = " << &language << endl; // في الذاكرة ptr هنا قمنا بطباعة عنوان المؤشر cout << "Address of ptr in memory = " << &ptr << endl; // language و التي هي عنوان المتغير ptr هنا قمنا بطباعة القيمة الموجودة في المؤشر cout << "Value of ptr in memory = " << ptr << endl; // language في الذاكرة و التي هي قيمة المتغير ptr هنا قمنا بطباعة القيمة التي يشير إليها عنوان المؤشر cout << "Value that ptr point to = " << *ptr; return 0; }

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل.

language = Arabic
Address of language = 0x61fde0
Address of ptr in memory = 0x61fdd8
Value of ptr in memory = 0x61fde0
Value that ptr point to = Arabic
language = Arabic Address of language = 0x61fde0 Address of ptr in memory = 0x61fdd8 Value of ptr in memory = 0x61fde0 Value that ptr point to = Arabic

الصورة التالية تظهر كيف تم تخزين عنوان و قيمة المتغير language و المؤشر ptr في الذاكرة.


من المهم جداً أن تلاحظ الطريقة التي يتم فيها إنشاء المؤشر في الذاكرة حتى تعرف كيف تتعامل معه بسهولة.

  • المؤشر ptr تم تخصيص مساحة خاصة له في الذاكرة و هذه المساحة لها عنوان و قيمة أيضاً.
  • قيمة المؤشر ptr هي عنوان المتغير lanugage في الذاكرة, و هذا يعني أن قيمة المؤشر دائماً تكون عنوان الشيء الذي يشير إليه في الذاكرة.

بالنسبة للتعامل مع المؤشر فلاحظنا التالي:

  • نكتب إسم المؤشر فقط في حال أردنا الوصول لقيمته, كمثال ptr
  • نضع & قبل إسم المؤشر في حال أردنا الوصول لعنوانه في الذاكرة, كمثال &ptr
  • نضع * قبل إسم المؤشر في حال أردنا الوصول لقيمة الشيئ الذي يشير إليه, كمثال *ptr

تحديد الشيء الذي يتم الإشارة إليه في C++

في المثال السابق لاحظنا أن المؤشر في الذاكرة يشبه كثيراً الشيء الذي يشير إليه حيث يملك قيمة و عنوان خاص في الذاكرة.
و لاحظنا أيضاً أننا في المؤشر لا نضع قيم عادية, حيث أن قيمته تكون عنوان الشيء الذي يشير إليه في الذاكرة و الذي من خلاله يمكننا الوصول لقيمته.

الآن إذا أردت جعل المؤشر يشير إلى شيء آخر موجود في الذاكرة, فكل ما عليك فعله هو تمرير عنوان الشيء الآخر له كقيمة.


في المثال التالي قمنا بتعريف متغيرين إسمهما x و y.
بعدها قمنا بتعريف مؤشر إسمه ptr جعلناه يشير للمتغير x و عرضنا التي يشير إليها.
ثم جعلنا ptr يشير للمتغير y و عرضنا القيمة التي يشير إليها.

مثال

main.cpp
#include <iostream>
using namespace std;
int main()
{
// قيمته 2 y قيمته 1 و متغير x هنا قمنا بتعريف متغير
int x = 1;
int y = 2;
// ptr هنا قمنا بتعريف مؤشر إسمه
int* ptr;
// x يشير إلى عنوان المتغير ptr هنا قمنا بجعل المؤشر
ptr = &x;
// x و التي هي قيمة المتغير ptr هنا قمنا بطباعة قيمة المتغير الذي يشير إليه
cout << "*ptr = " << *ptr << endl;
// y يشير إلى عنوان المتغير ptr هنا قمنا بجعل المؤشر
ptr = &y;
// y من جديد و التي أصبحت قيمة المتغير ptr هنا قمنا بطباعة قيمة المتغير الذي يشير إليه
cout << "*ptr = " << *ptr << endl;
return 0;
}
#include <iostream> using namespace std; int main() { // قيمته 2 y قيمته 1 و متغير x هنا قمنا بتعريف متغير int x = 1; int y = 2; // ptr هنا قمنا بتعريف مؤشر إسمه int* ptr; // x يشير إلى عنوان المتغير ptr هنا قمنا بجعل المؤشر ptr = &x; // x و التي هي قيمة المتغير ptr هنا قمنا بطباعة قيمة المتغير الذي يشير إليه cout << "*ptr = " << *ptr << endl; // y يشير إلى عنوان المتغير ptr هنا قمنا بجعل المؤشر ptr = &y; // y من جديد و التي أصبحت قيمة المتغير ptr هنا قمنا بطباعة قيمة المتغير الذي يشير إليه cout << "*ptr = " << *ptr << endl; return 0; }

سنحصل على النتيجة التالية عند التشغيل.

*ptr = 1
*ptr = 2
*ptr = 1 *ptr = 2

الفيديو التالي يظهر كيف تم تغيير قيمة المؤشر ptr حيث تم جعله يشير لعنوان المتغير x و من ثم يشير لعنوان المتغير y.

تغيير قيمة الشيء الذي يشير إليه المؤشر في C++

في المثال التالي قمنا بتعريف متغير إسمه x قيمته 1 و مؤشر إسمه ptr يشير للمتغير x.
من خلال المؤشر ptr قمنا بتغيير قيمة المتغير x و من بعدها قمنا بطباعة قيمته للتأكد.

مثال

main.cpp
#include <iostream>
using namespace std;
int main()
{
// و قيمته 1 x هنا قمنا بتعريف متغير إسمه
int x = 1;
// في الذاكرة x و جعلناه يشير لعنوان المتغير ptr هنا قمنا بتعريف مؤشر إسمه
int* ptr = &x;
// إلى 5 ptr هنا قمنا بتغير قيمة المتغير الذي يشير إليه المؤشر
*ptr = 5;
// للتأكد ما إن كانت قد تغيرت أم لا x هنا قمنا بطباعة قيمة المتغير
cout << "x = " << x << endl;
// x و التي هي نفسها قيمة المتغير ptr هنا قمنا بطباعة قيمة المتغير الذي يشير إليه
cout << "*ptr = " << *ptr;
return 0;
}
#include <iostream> using namespace std; int main() { // و قيمته 1 x هنا قمنا بتعريف متغير إسمه int x = 1; // في الذاكرة x و جعلناه يشير لعنوان المتغير ptr هنا قمنا بتعريف مؤشر إسمه int* ptr = &x; // إلى 5 ptr هنا قمنا بتغير قيمة المتغير الذي يشير إليه المؤشر *ptr = 5; // للتأكد ما إن كانت قد تغيرت أم لا x هنا قمنا بطباعة قيمة المتغير cout << "x = " << x << endl; // x و التي هي نفسها قيمة المتغير ptr هنا قمنا بطباعة قيمة المتغير الذي يشير إليه cout << "*ptr = " << *ptr; return 0; }

سنحصل على النتيجة التالية عند التشغيل.

x = 5
*ptr = 5
x = 5 *ptr = 5

أمثلة حول مزايا استخدام المؤشرات في C++


المثال الأول

هنا وضعنا مثال حول كيفية إنشاء مؤشر لا يملك قيمة ( Null Pointer ) بالإضافة إلى كيفية التشييك على المؤشر لمعرفة ما إن كان يملك قيمة أم لا.

شاهد الأمثلة



المثال الثاني

هنا وضعنا مثال حول كيفية جعل المؤشر يشير لقيم عناصر المصفوفة باستخدام العوامل الحسابية ( Arithmetic Operator ) الأربعة -, --, +, ++.

شاهد المثال



المثال الثالث

المثال التالي مهم جداً و منه ستتعلم كيف تنشئ دالة تأخذ باراميتر عبارة عن مؤشر و كيف نقوم بتمرير قيمة للبارامتير عند استدعاءها.

شاهد المثال