مضى على الشبكة و يوم من العطاء.

اللغة البرمجية c++ ( pointer with array)

Sadell_AliSadell_Ali is verified member.

الرقابة والتنظيم
.:: الرقابة والتنظيم ::.
.:: طاقم المشرفين ::.

السمعة:

تم بحمد الله شرح المواضيع التالية arrays ,function, pointers بشكل مفصل في السابق إلا أنه سيتم ربطهم حتى نزيد من فعالية وسهولة التعامل مع البرمجية سنأخذ الأن جزء ال pointer with array
كما تحدثنا في السابق ينبغي التصريح عن المؤشرات قبل استخدامها بصورةٍ مماثلة لأي متغير آخر تعاملنا معه مسبقًا. يتشابه التصريح عن المؤشر مع أي تصريح آخر، ولكن هناك نقطة مهمّة، إذ تدلّ الكلمة المفتاحية عند التصريح عن المؤشر في البداية، مثل int أوchar وغيرها عن نوع المتغير الذي سيشير المؤشر إليه، وليس نوع المؤشر بذات نفسه، ويشير المؤشّر على قيمة واحدة كل مرة من ذلك النوع وليس جميع القيم من النوع ذاته. إليك مثالًا يوضح التصريح عن مصفوفة ومؤشر:
كود:
int ar[5], *ip;
حيث يصبح لدينا بعد التصريح مصفوفة ومؤشر، كما يوضح الشكل التالي 👇
1702738094976.png
يوضح الرمز * الموجود أمام ip أن هذا مؤشر، وليس متغيرًا اعتياديًا، وهو مؤشرٌ من النوع pointer to int، أي يشير إلى قيمة من نوع int فقط، لكن لم تُسند له قيمة أوليّة بعد، ولا يمكننا استخدامه في هذه الحالة قبل أن نجعله يؤشّر على قيمةٍ ما. لاحظ أنه لا يمكنك تعيين قيمةٍ من نوع int فورًا، لأن القيم الصحيحة لها النوع int ونحن نريد هنا قيمةً من نوع "مؤشر إلى نوع صحيح pointer to int". لكن، ما الذي سيشير إليه ip في هذه الحالة إذا كانت التعليمة التالية صحيحة ؟
كود:
ip = 6;
قد تختلف الإجابة هنا، ولا يوجد إجابةً واحدةً عمّا قد يشير إليه ip، ولكن خلاصة الأمر أن هذا النوع من الإسناد غير صحيح في لغة سي.
أما هذه هي الطريقة الصحيحة لإسناد قيمة أولية لمؤشر ما:​
كود:
int ar[5], *ip;
ip = &ar[3];
يؤشّر المؤشر في هذا المثال إلى عنصرٍ من المصفوفة ar بدليل 3 (أي العنصر الرابع من المصفوفة)
تحذير هام: يمكنك إسناد القيم إلى المؤشرات كما في أي متغير اعتدت عليه، ولكن تكمن الأهمية في نوع هذه القيمة وما الذي تعنيه. يدل الشكل التالي 👇على قيم المتغيرات الموجودة بعد التصريح، ويدل ?? على كون المتغير غير مُسند لقيمة أولية أي غير مهيَّأ.
1702739097827.png
هنا نلاحظ أن قيمة المتغير ip مساوية لقيمة التعبير ‎&ar[3]‎، ويشير السهم إلى أن المؤشر ip يشير إلى المتغير [ar[3‏
كما تعرفنا في السابق أن هذه الإشارة & تدل على "عنوان المتغير"، إذ أن المؤشرات تخزّن عنوان المتغير الذي تؤشّر عليه في معظم الأنظمة. ربّما ستواجه صعوبةً بخصوص هذا الأمر👈👉 إذا كنت تفهم ما نعني هنا بالعنوان مقارنةً بالأشخاص الذين لا يفهمون هذا الأمر، إذ أن التفكير بالمؤشرات كونها عناوينًا يؤدي إلى كثيرٍ من المشاكل في الفهم.
حيث ان عناصر المصفوفة تملك عناوينًا مثل أي متغير اعتيادي آخر
كود:
int ar[20], *ip;

ip = &ar[5];
*ip = 0;       // ‫يكافئ التعبير ar[5] = 0;‎


في المثال السابق، يُخزَّن عنوان العنصر ar[5]‎ في المؤشر ip، ثم تُسند القيمة صفر إلى موضع المؤشر في السطر الذي يليه. هذا الشيء غير مثير للإعجاب بحد ذاته، بل إن طريقة عمل العمليات الحسابية والمؤشر سويًّا هي التي تستدعي الاهتمام، فعلى الرغم من بساطة هذا الأمر، إلا أنه يُعد واحدًا من أساسات لغة سي المميزة.

نحصل على مؤشر إذا أضفنا قيمة عدد صحيح إلى مؤشر ما، ويكون للمؤشر الذي حصلنا عليه نفس نوع المؤشر الأصلي؛ فبإضافة العدد "n" إلى مؤشر ما يشير إلى عنصر في مصفوفة، سنحصل على عنصر يشير إلى العنصر الذي يلي العنصر السابق بمقدار "n" داخل المصفوفة ذاتها، ويمكن تطبيق حالة الطرح بما أن العدد "n" يمكن أن يكون سالبًا. بالرجوع إلى المثال السابق، ينتج عن التعبير التالي:
كود:
*(ip+1) = 0;
حيث هنا قمنا بتغيير قيمة ar[6]‎ إلى صفر، وهكذا. لا تعدّ هذه الطريقة تحسينًا على طرق الوصول إلى عناصر المصفوفة الاعتيادية، إليك مثالًا عن ذلك بدلًا من السابق:
كود:
int ar[20], *ip;

for(ip = &ar[0]; ip < &ar[20]; ip++)
      *ip = 0;
يوضّح المثال السابق ميزةً كلاسيكيةً للغة سي، إذ يشير المؤشر إلى بداية المصفوفة، وبينما يشير المؤشر إلى المصفوفة يمكن الوصول إلى عناصر المصفوفة واحدًا تلو الآخر بزيادة المؤشر بمقدار واحد كلّ مرة. يدعم معيار سي بعض الممارسات الموجودة وذلك بالسماح لاستخدام عنوان العنصر ar[20]‎ على الرغم من عدم وجود هذا العنصر، ويسمح لك هذا باستخدام المؤشرات لاختبار حدود المصفوفة ضمن الحلقات التكرارية كما هو الحال في المثال السابق، إذ أن ضمان عمله يمتد لعنصر واحد فقط خارج نهاية المصفوفة وليس أكثر من ذلك.

لكن ما المميز في هذه الطريقة مقارنةً باستخدام دليل المصفوفة للوصول إلى العنصر بالطريقة الاعتيادية؟ يمكن الوصول إلى عناصر المصفوفات في معظم الحالات بالتعاقب، واستعرضت القليل من الأمثلة البرمجية السابقة خيار الوصول إلى العناصر "عشوائيًا". إذا أردت الوصول إلى عناصر المصفوفة بالتعاقب فسيقدّم استخدام المؤشرات تنفيذًا أسرع، إذ يتطلب الأمر على معظم معماريات الحاسوب عملية ضرب وجمع واحدةً للوصول إلى عنصر ضمن مصفوفة أحادية البعد باستخدام دليله، بينما لا يتطلب الأمر باستخدام المؤشرات إجراء أي عمليات حسابية إطلاقًا، إذ يخزن المؤشر العنوان الدقيق للكائن (عنصر المصفوفة في هذه الحالة). العملية الحسابية الوحيدة المُجراة في المثال السابق هي ضمن حلقة for التكرارية، إذ تحدث عملية إضافة ومقارنة كل دورة داخل الحلقة. إذا أردنا استخدام طريقة الوصول لعناصر المصفوفة باستخدام الأدلة، نكتب:
كود:
nt ar[20], i;
for(i = 0; i < 20; i++)
ar[i] = 0;
تحدث العمليات الحسابية ذاتها في الحلقة التكرارية كما في المثال السابق، لكن بإضافة حسابات العنوان المُجراة كل دورة في الحلقة

🌸يعطيكم العافية 🌸

فهرس الدروس
دروس البرمجة الكائنية
 
التعديل الأخير بواسطة المشرف:
يعطيكِ العافية سديل❤️
 
ماشاء الله تبارك الله، شرح رهيب يا سديل، استمري 🔥
 
تم بحمد الله شرح المواضيع التالية arrays ,function, pointers بشكل مفصل في السابق إلا أنه سيتم ربطهم حتى نزيد من فعالية وسهولة التعامل مع البرمجية سنأخذ الأن جزء ال pointer with array
كما تحدثنا في السابق ينبغي التصريح عن المؤشرات قبل استخدامها بصورةٍ مماثلة لأي متغير آخر تعاملنا معه مسبقًا. يتشابه التصريح عن المؤشر مع أي تصريح آخر، ولكن هناك نقطة مهمّة، إذ تدلّ الكلمة المفتاحية عند التصريح عن المؤشر في البداية، مثل int أوchar وغيرها عن نوع المتغير الذي سيشير المؤشر إليه، وليس نوع المؤشر بذات نفسه، ويشير المؤشّر على قيمة واحدة كل مرة من ذلك النوع وليس جميع القيم من النوع ذاته. إليك مثالًا يوضح التصريح عن مصفوفة ومؤشر:
كود:
int ar[5], *ip;
حيث يصبح لدينا بعد التصريح مصفوفة ومؤشر، كما يوضح الشكل التالي 👇
يوضح الرمز * الموجود أمام ip أن هذا مؤشر، وليس متغيرًا اعتياديًا، وهو مؤشرٌ من النوع pointer to int، أي يشير إلى قيمة من نوع int فقط، لكن لم تُسند له قيمة أوليّة بعد، ولا يمكننا استخدامه في هذه الحالة قبل أن نجعله يؤشّر على قيمةٍ ما. لاحظ أنه لا يمكنك تعيين قيمةٍ من نوع int فورًا، لأن القيم الصحيحة لها النوع int ونحن نريد هنا قيمةً من نوع "مؤشر إلى نوع صحيح pointer to int". لكن، ما الذي سيشير إليه ip في هذه الحالة إذا كانت التعليمة التالية صحيحة ؟
كود:
ip = 6;
قد تختلف الإجابة هنا، ولا يوجد إجابةً واحدةً عمّا قد يشير إليه ip، ولكن خلاصة الأمر أن هذا النوع من الإسناد غير صحيح في لغة سي.
أما هذه هي الطريقة الصحيحة لإسناد قيمة أولية لمؤشر ما:​
كود:
int ar[5], *ip;
ip = &ar[3];
يؤشّر المؤشر في هذا المثال إلى عنصرٍ من المصفوفة ar بدليل 3 (أي العنصر الرابع من المصفوفة)
تحذير هام: يمكنك إسناد القيم إلى المؤشرات كما في أي متغير اعتدت عليه، ولكن تكمن الأهمية في نوع هذه القيمة وما الذي تعنيه. يدل الشكل التالي 👇على قيم المتغيرات الموجودة بعد التصريح، ويدل ?? على كون المتغير غير مُسند لقيمة أولية أي غير مهيَّأ.
هنا نلاحظ أن قيمة المتغير ip مساوية لقيمة التعبير ‎&ar[3]‎، ويشير السهم إلى أن المؤشر ip يشير إلى المتغير [ar[3‏
كما تعرفنا في السابق أن هذه الإشارة & تدل على "عنوان المتغير"، إذ أن المؤشرات تخزّن عنوان المتغير الذي تؤشّر عليه في معظم الأنظمة. ربّما ستواجه صعوبةً بخصوص هذا الأمر👈👉 إذا كنت تفهم ما نعني هنا بالعنوان مقارنةً بالأشخاص الذين لا يفهمون هذا الأمر، إذ أن التفكير بالمؤشرات كونها عناوينًا يؤدي إلى كثيرٍ من المشاكل في الفهم.
حيث ان عناصر المصفوفة تملك عناوينًا مثل أي متغير اعتيادي آخر
كود:
int ar[20], *ip;

ip = &ar[5];
*ip = 0;       // ‫يكافئ التعبير ar[5] = 0;‎


في المثال السابق، يُخزَّن عنوان العنصر ar[5]‎ في المؤشر ip، ثم تُسند القيمة صفر إلى موضع المؤشر في السطر الذي يليه. هذا الشيء غير مثير للإعجاب بحد ذاته، بل إن طريقة عمل العمليات الحسابية والمؤشر سويًّا هي التي تستدعي الاهتمام، فعلى الرغم من بساطة هذا الأمر، إلا أنه يُعد واحدًا من أساسات لغة سي المميزة.

نحصل على مؤشر إذا أضفنا قيمة عدد صحيح إلى مؤشر ما، ويكون للمؤشر الذي حصلنا عليه نفس نوع المؤشر الأصلي؛ فبإضافة العدد "n" إلى مؤشر ما يشير إلى عنصر في مصفوفة، سنحصل على عنصر يشير إلى العنصر الذي يلي العنصر السابق بمقدار "n" داخل المصفوفة ذاتها، ويمكن تطبيق حالة الطرح بما أن العدد "n" يمكن أن يكون سالبًا. بالرجوع إلى المثال السابق، ينتج عن التعبير التالي:
كود:
*(ip+1) = 0;
حيث هنا قمنا بتغيير قيمة ar[6]‎ إلى صفر، وهكذا. لا تعدّ هذه الطريقة تحسينًا على طرق الوصول إلى عناصر المصفوفة الاعتيادية، إليك مثالًا عن ذلك بدلًا من السابق:
كود:
int ar[20], *ip;

for(ip = &ar[0]; ip < &ar[20]; ip++)
      *ip = 0;
يوضّح المثال السابق ميزةً كلاسيكيةً للغة سي، إذ يشير المؤشر إلى بداية المصفوفة، وبينما يشير المؤشر إلى المصفوفة يمكن الوصول إلى عناصر المصفوفة واحدًا تلو الآخر بزيادة المؤشر بمقدار واحد كلّ مرة. يدعم معيار سي بعض الممارسات الموجودة وذلك بالسماح لاستخدام عنوان العنصر ar[20]‎ على الرغم من عدم وجود هذا العنصر، ويسمح لك هذا باستخدام المؤشرات لاختبار حدود المصفوفة ضمن الحلقات التكرارية كما هو الحال في المثال السابق، إذ أن ضمان عمله يمتد لعنصر واحد فقط خارج نهاية المصفوفة وليس أكثر من ذلك.

لكن ما المميز في هذه الطريقة مقارنةً باستخدام دليل المصفوفة للوصول إلى العنصر بالطريقة الاعتيادية؟ يمكن الوصول إلى عناصر المصفوفات في معظم الحالات بالتعاقب، واستعرضت القليل من الأمثلة البرمجية السابقة خيار الوصول إلى العناصر "عشوائيًا". إذا أردت الوصول إلى عناصر المصفوفة بالتعاقب فسيقدّم استخدام المؤشرات تنفيذًا أسرع، إذ يتطلب الأمر على معظم معماريات الحاسوب عملية ضرب وجمع واحدةً للوصول إلى عنصر ضمن مصفوفة أحادية البعد باستخدام دليله، بينما لا يتطلب الأمر باستخدام المؤشرات إجراء أي عمليات حسابية إطلاقًا، إذ يخزن المؤشر العنوان الدقيق للكائن (عنصر المصفوفة في هذه الحالة). العملية الحسابية الوحيدة المُجراة في المثال السابق هي ضمن حلقة for التكرارية، إذ تحدث عملية إضافة ومقارنة كل دورة داخل الحلقة. إذا أردنا استخدام طريقة الوصول لعناصر المصفوفة باستخدام الأدلة، نكتب:
كود:
nt ar[20], i;
for(i = 0; i < 20; i++)
ar[i] = 0;
تحدث العمليات الحسابية ذاتها في الحلقة التكرارية كما في المثال السابق، لكن بإضافة حسابات العنوان المُجراة كل دورة في الحلقة

🌸يعطيكم العافية 🌸
جزاك الله كل خير يا سديل، اسطورة في الc++ ننتظر جديدك دائماً بإذن الله
 

آخر المشاركات

عودة
أعلى