المؤشرات والمصفوفات في ++C

المؤشرات والمصفوفات

توجد علاقة وثيقة بين المؤشرات والمصفوفات لقد رأينا كيف يمكن التعامل مع عناصر المصفوفة باستخدام دليل المصفوفة بين قوسين مربعين وإليك البرنامج التالي كمراجعه سريعة :

arrnote.cpp


 


// arrnote.cpp


// array accessed with array notation


#include <iostream.h>


#include <conio.h>


 


void main()


   {


   int intarray[5] = { 31, 54, 77, 52, 93 };  // array


 


   for(int j=0; j<5; j++)                  // for each element


      cout << endl << intarray[j];         // print value


   getche();


   }




فعندما يأخذ المتغير j – وهو المعبر عن دليل المصفوفة – رقما تطبع الدالة cout << قيمة الغنصر المقابل لهذا الدليل . والأن , سوف نعيد البرنامج بصياغة أخري نستخدم فيها أسلوب المؤشرات :






ptrnote.cpp


 


// ptrnote.cpp


// array accessed with pointer notation


#include <iostream.h>


#include <conio.h>


 


void main()


   {


   int intarray[5] = { 31, 54, 77, 52, 93 };  // array


 


   for(int j=0; j<5; j++)                  // for each element,


      cout << endl << *(intarray+j);       // print value


   getche();


   }




فالتعبير (intarray+j) في هذا البرنامج له نفس معني التعبير intarray[j] في البرنامج السابق وتفسير ذلك أن اسم المصفوفة يعبر دائما عن عنوان أول عنصر فيها , فالتعبير intarray[0] يعبر عنوان ذلك العنصر (العنصر ذو الدليل 0) . والرمز intarray يعب ر عن عنوان ذلك العنصر . قلنا أن نعتبر ان اسم المصوفة يلعب في نفس الوقت دور مؤشر لأول عنصر فيها , ومن ثم نترجم *intarrayعلي أنه يعني العنصر الأول من المصفوفة . وبنفس المنطق حينما رقما لهذا الاسم intarry+3 نقول أن هذا يشير للعنصر الرابع , وأن /*(intarray+3) يعبر عن قيمة هذا العنصر .



والمترجم من الذكاء بحيث يمكنه أن يحسب مكان كل عنصر , ففي مثالنا , المصفوفة لأعداد صحيحة كل عنصر يحتل 2 بايت فتتدرج العناوين بحسب هذا المقدار كما هو مبين بالشكل ففي مثالنا هذا يضرب الرقم المعبر عن دليل العنصر (3) في مساحة تخزين نوعه (2) , ويجمع الناتج علي عنوان أول عنصر , فيصل لعنوان العنصر المطلوب .



Object-Oriented Programming in C   _Page_0468_Image_0001



شكل حساب عناوين أعداد صحيحة



ومن هذا العرض تعرف لماذا يحتاج المترجم معرفة نوع البيان الذي يشير إليه المؤشر , لإجراء حسابات من هذا القبيل .



ثوابت المؤشرات ومتغيراتها



لنفرض أنك أردت عملية التزايد علي اسم المصفوفة , علي النحو التالي : *(intarray++) فهل يمكنك ذلك ؟ الجوال بالنفي . لأن intarray هي في الواقع مقدار ثابت , هو عنوان أو عنصر في المصفوفة , والمقدار الثابت لا يقبل التغيير في قيمته بأية وسيلة .



ولكن بينما لا يمكنك تغيير عنوان ما , فإن بإمكانك إجراء عملية التزايد علي المؤشر الذي يحتوي ذلك العنوان كما في المثال التالي :






ptrinc.cpp


 


// ptrinc.cpp


// array accessed with pointer


#include <iostream.h>


#include <conio.h>


 


void main()


   {


   int intarray[] = { 31, 54, 77, 52, 93 }; // array


   int* ptrint;                             // pointer to int


   ptrint = intarray;                       // points to intarray


 


   for(int j=0; j<5; j++)                   // for each element,


      cout << endl << *(ptrint++);          // print value


   getche();


   }




ففي هذا البرنامج حينما تكون قيمة المتغير j صفرا , تطبع دالة الإخراج قيمة العنصر الأول , وهي 31 ثم حين ينتقل المتغير للعدد التالي , تتزايد قيمة المؤشر ptrint لتشير للعنوان التالي فتطبع قيمة العنصر الذي به وهكذا .

التسميات: