مصفوفة الكائنات في ++C

مصفوفة الكائنات

رأينا في المثال السابق المصفوفة عنصرا لهيكل , ويمكننا عكس الأية , بأن نخلق مصفوفة من الكائنات , والمثالان التاليان تطبيق لذلك , الأول خاص بالمسافات , والثاني بأوراق اللعب .

مثال المسافات الإنجليزية

صنعنا في  مقالات سابقة كائنا يعبر عن المسافات الإنجليزية , وسوف نقدم في المثال التالي مصفوفة مكونة من هذا الكائن .

englaray.cpp


 


// englaray.cpp


// objects using English measurements


// UCS Laboratories


#include <iostream.h>


#include <conio.h>


 


const int MAX = 100;              // maximum number of elements


 


class Distance                    // English Distance class


   {


   private:


      int feet;


      float inches;


   public:


      void getdist()              // get length from user


     {


     cout << "\n   Enter feet: ";  cin >> feet;


     cout << "   Enter inches: ";  cin >> inches;


     }


      void showdist()             // display distance


     { cout << feet << "\'-" << inches << '\"'; }


   };


 


void main()


   {


   Distance dist[MAX];            // array of distances


   int n=0;                       // count the entries


   char ans;                      // user response ('y' or 'n')


 


   cout << endl;


   do                             // get distances from user


      {


      cout << "Enter distance number " << n+1;


      dist[n++].getdist();        // store distance in array


      cout << "Enter another (y/n)?: ";


      cin >> ans;


      }                           // quit if user types 'n'


   while( ans != 'n' );


 


   for(int j=0; j<n; j++)         // display all distances


      {


      cout << "\nDistance number " << j+1 << " is ";


      dist[j].showdist();


      }


   getche();


   }




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



الوصول لكائن في مصفوفة



عرفت المصفوفة dist[MAX] علي أن عناصرها من نوع الهيكل distance , وهي مصورة في الشكل .



ويكون الوصول لكائن في المصفوفة مماثلا للوصول لعنصر من عناصر الهيكل في برنامج partaray.cpp . وإليك كيفية استثارة الدالة showdist() المنتمية للعنصر j من المصفوفة :



Dist[j].showdist();



وقد استخدمنا لذلك مؤثر النقطة المعتاد .



كما أننا استخدمنا مؤثر التزايد لكي يتم الانتقال إلي الموضوع التالي من المصفوفة عند كل إدخال جديد , وذلك في الأمر :



Dist[n++].getdist();



حيث إننا نستخدم الدوارة do , وهي لا تتزايد تلقائيا كما تفعل الدوارة for .



Object-Oriented Programming in C   _Page_0312_Image_0001























شكل مصفوفة كائنات



تجاوز حجم المصفوفة



ماذا لو أدخلت عناصر أكثر من الحجم المحدد للمصفوفة ؟ للأسف , ليس هناك من وسيلة لمنع ذلك , ويترتب علي ذلك أن البيانات المخلة قد تكتب فوق بيانات أخري لبرنامج أخر , ويزداد الأمر سوءا لو كان البرنامج الأخر هو نظام التشغيل نفسه , فيعلم الله لتلاقي هذا الاحتمال , فيمكن مثلا إصدار رسالة تحذير عند امتلاء المصفوفة , تكون أوامرها في بداية الدوارة do , ومضاعفة علي النحو التالي :



If(n>MAX)



{



Cout << ''\nThe array is full!'';



Break;



}



ويكون الأمر break هو صمام الأمن ضد تجاوز حجم المصفوفة , حيث يأخذ البرنامج خارج الدوارة .



مثال ورق اللعب



سوف نستعير الفئة card من الفصل السابع ونصنع مصفوفة من 52 من كائناتها , وبذلك يكون لدينا مجموعة كاملة من ورق اللعب . وحيث إن هذا البرنامج سيستخدم المحارف الرسومية التي في الدوس لصور المجموعة , وذلك لتوفير المساحة المستغلة من الذاكرة , فإن هذا البرنامج يجب أن يشغل تحت الدوس مباشرة , وليس EasyWin .







cardaray.cpp


 


// cardaray.cpp


// cards as objects


// for IBM character set, build DOS target, not EasyWin


// UCS Laboratories


#include <iostream.h>


#include <stdlib.h>         // for randomize(), rand


#include <time.h>           // for randomize()


#include <conio.h>          // for getche()


 


enum Suit { clubs, diamonds, hearts, spades };


 


const int jack = 11;        // from 2 to 10 are


const int queen = 12;       // integers without names


const int king = 13;


const int ace = 14;


 


class card


   {


   private:


      int number;        // 2 to 10, jack, queen, king, ace


      Suit suit;         // clubs, diamonds, hearts, spades


   public:


      card()                      // constructor


     { }


      void init(int n, Suit s)    // initialize card


     { suit = s; number = n; }


      void display();             // display card


   };


 


void card::display()              // display the card


   {


   if( number >= 2 && number <= 10 )


      cout << number;


   else


      switch(number)


     {


     case jack:  cout << "J"; break;


     case queen: cout << "Q"; break;


     case king:  cout << "K"; break;


     case ace:   cout << "A"; break;


     }


   switch(suit)


      {


      case clubs:    cout << char(5); break;  


      case diamonds: cout << char(4); break;  


      case hearts:   cout << char(3); break;  


      case spades:   cout << char(6); break;  


      }


   }


 


void main()


   {


   card deck[52];


 


   cout << endl;


   for(int j=0; j<52; j++)


      {


      int num = (j % 13) + 2;  // cycles through 2 to 14, 4 times


      Suit su = Suit(j / 13);  // cycles through 0 to 3, 13 times


      deck[j].init(num, su);   // set card


      }


 


   cout << "\nOrdered deck:\n";


   for(j=0; j<52; j++)         // display ordered deck


      {


      deck[j].display();


      cout << "  ";


      if( !( (j+1) % 13) )     // newline every 13 cards


     cout << endl;


      }


 


   randomize();                // seed random number generator


   for(j=0; j<52; j++)         // for each card in the deck,


      {


      int k = random(52);      // pick another card at random


      card temp = deck[j];     // and swap them


      deck[j] = deck[k];


      deck[k] = temp;


      }


 


   cout << "\nShuffled deck:\n";


   for(j=0; j<52; j++)         // display shuffled deck


      {


      deck[j].display();


      cout << ", ";


      if( !( (j+1) % 13) )     // newline every 13 cards


     cout << endl;


      }


   getch();                    // wait for keypress   


   }  // end main





بمجرد أن أنشأنا مجموعة الورق , لن نقاوم الرغبة في خلطها , ثم إظهرها بعد ذلك .



ويبين الشكل المجموعة قبل وبعد الخلط .



Object-Oriented Programming in C   _Page_0315_Image_0001









شكل مجموعة ورق اللعب



وقد استخدمت المحارف الرسومية في جدول الاسكي لصور المجموعة , فالأمر :



Chart(5)



مثلا يظهر المحرف المقابل في الجدول لعدد 5 , بدلا من إظهار العدد نفسه , حيث تحويل نوع العدد قسريا إلي النوع char .



إنتاج مجموعة أعداد عشوائية



أما عملية خلط الأوراق فتجري علي خطوتين , استدعاء الدالة المكتبية randomize() , وهي دالة تعتبر مولدا للأرقام العشوائية random-number generator . ويلزم لذلك تضمين الملف stdlib.h في البرنامج , وهو المحتوي علي الدوال المكتبية . وهذه الدالة تستخدم توقيت النظام , ومن ثم يلزم تضمين الملف time.h أيضا.



أما إنتاج المجموعة العشوائية فيكون عن طريق دالة تقوم بذلك , وهي دالة مكتبية تسمي random() فتكون الخطوة الثانية هي استدعاء هذه الدالة , وهي تأخذ معاملا واحدا , هو أكبر عدد لمجموعة الأرقام المطلوب خلطها , زائدا 1 , ففي حالتنا , نريد خلط أعداد بين 0 و 50 , فيكون المعامل 52 , والذي ظهر في البرنامج كالتالي :



Random(52);



وينتج عن هذه الدالة مجموعة أعداد عشوائية من 0 إلي 51 , يمثلها المتغير k , والذي يستخدم لتبديل أوضاع العناصر في المصفوفة .



ويمكن للقارئ استخدام هذا البرنامج في ألعاب أكثر تطورا .

تعليقات

المشاركات الشائعة من هذه المدونة

المؤثرات الحسابية في C++

الرسم Graphics

دوال النمط الرسومي في ++C