المبادئ الأساسية للمصفوفات في ++C
في حياتنا اليومية كثيرا ما نحتاج إلي تجميع وحدات متجانسة في مجموعات , فنحن نشتري البيض في كرتونات , والفاصوليا في معلبات . وكذلك في لغة البرمجة محتاج إلي مثل هذا التجميع للبيانات المتجانسة . والألية التي تمكننا من ذلك تعرف بإسم " المصفوفة array" . ويمكن أن تضم المضفوفة عددا قليلا أو ألافا من العناصر كما يمكن أن تكون العناصر المجمعة في المصفوفة من الأنواع الأولية مثل int, float أو من هياكل البيانات المتقدمة ؛ مثل الهياكل والكائنات .
وتشبه المصفوفات الهيكل في أنها تجمع عددا كبيرا من البيانات في وحدة واحدة , ولكنها تختلف عنه في كونها لا تضم إلا بيانات متجانسة . والأهم من ذلك أن العناصر الهيكل يتم التعامل معها بالأسم , ولكنها في المصفوفة عن طريق دليل يعبر عن الترتيب داخل المصفوفة . ويمكن هذا الأسلوب من الوصول إلي عدد كبير من العناصر بطريقة أيسر .
والمصفوفات موجودة في كل اللغات البرمجية تقريبا , وهي في السي ++ تشابه اللغات الأخري , ومتماثلة مع السي التقليدية .
وسوف نشرح في هذا الفصل مصفوفات العناصر الأولية أولا , ثم نعرض للمصفوفات كعناصر بيانات للفئات , والمصفوفات التي تجمع الكائنات . وعلي ذلك فالهدف من هذا المقال لا يقتصر علي توضيح المبادئ المتعلقة بالمصفوفات , بل يتضمن توسيع الفهم للبرمجة الكائنية أيضا . وننهي المقال بالعبارات النصية , وهي مصفوفات عناصرها المحارف , أي من نوع char .
المبادئ الأساسية للمصفوفات
سوف يوضح لنا بسيط مبادئ المصفوفات , وهو برنامج لتجميع أعمار أربعة من الأفراد . وهو يسأل المستخدم عن هذه الأعمار , ثم يظهرها علي الشاشة .
replay.cpp
// replay.cpp
// gets four ages from user, displays them
#include <iostream.h>
#include <conio.h>
void main()
{
int age[4]; // array 'age' of 4 ints
cout << endl;
for(int j=0; j<4; j++) // get 4 ages
{
cout << "Enter an age: ";
cin >> age[j]; // access array element
}
for(j=0; j<4; j++) // display 4 ages
cout << "\nYou entered " << age[j];
getche();
}
وتقوم الدوارة الأولي بإدخال الأعمار في المصفوفة , وتقوم الدوار الثانية بقراءتها من المصفوفة وإظهارها علي الشاشة .
تعريف المصفوفة
يجب تعريف المصفوفة قبل التعامل معها ,أسوة بكل المتغيرات الأخري . وكأي تعريف يجب أن يتضمن اسم المصفوفة ونوع البيانات التي يتضمنها . ولكن يلزم هنا تحديد خاصية أخري , وهي حجم المصفوفة , وهو رقم يعبر عن أقصي عدد ممكن أن تضمه المصفوفة , ويوضع بين قوسين مربعين بعد الإسم مباشرة . ويبين الشكل صيغة التعريف بالمصفوفة .
شكل تعريف المصفوفات
والمصفوفة في المثال تسمي age , وهو من نوع الأعداد الصحيحة int , وحجمها 4 .
عناصر المصفوفة
تسمي البيانات المخزنة في المصفوفة "عناصر elements " علي عكس عناصر الهيكل , والتي تسمي members , ] ولن نفرق في الترجمة بين المصطلحين , حيث لا أثر لهذه التفرقة [ ويبين الشكل وضع عناصر المصفوفة في الذاكرة .
والعرف المتبع في تخزين عناصر المصفوفة هو أن تختزن من أعلي إلي أسفل ( عدا في بعض الحالات ) . ويحتل كل عنصر في المصفوفة المبينة 2 بايت , بما أن العناصر من نوع الأعداد الصحيحة .
ويجب ملاحظة أن العنصر الأول يأخذ رقم 0 في الترتيب . ولذا فإن العنصر الأخير يأخذ رقم 3 وهو أمر يجدر الانتباه إليه , حيث يتبادر للذهن أن العنصر الرابع (الأخير ) في المصفوفة ذات الحجم 4 هو رقم 4 , وهو أمر يسبب الخطأ كثيرا .
شكل عناصر المصفوفة في الذاكرة
التعامل مع عناصر المصفوفة
قمنا في المثال بالوصول لعناصر المصفوفة مرتين , مرة للكتابة فيها , أي تخزين للقيم , وذلك بالأمر :
Cin >> age[j];
ومرة للقراءة منها , أي إخراج القيم , وذلك بالأمر :
Cout << ''\n You entered'' << age[j];
وفي الحالتين أشير للعنصر العام في المصفوفة بالقيمة age[j] . ويأخذ الرمز j قيما من 0 إلي 3 , ليشير إلي عناصر المصفوفة الفعلية عنصرا بعد الأخر , ويسمي الرقم بين القوسين "دليل index " المصفوفة .
متوسط عناصر المصفوفة
إليك مثالا أخر , وهو يطلب إدخال كمية المبيعات في أيام العمل الستة , ثم يحسب القيمة المتوسطة لها :
sales.cpp
// sales.cpp
// averages a weeks's widget sales (6 days)
#include <iostream.h>
#include <conio.h>
const int SIZE = 6; // number of array elements
void main()
{
float sales[SIZE]; // array of 6 variables
cout << "\nEnter widget sales for 6 days\n";
for(int j=0; j<SIZE; j++) // put figures in array
cin >> sales[j];
float total = 0;
for(j=0; j<SIZE; j++) // read figures from array
total += sales[j]; // to find total
float average = total / SIZE; // find average
cout << "Average = " << average;
getche();
}
والتجديد الذي تم في هذا البرنامج هو استخدام ثابت يرمز لحجم المصفوفة , ثم تحديد قيمته بالعدد المطلوب , وذلك بالصورة :
Cons int SIZE = 6;
ثم تعريف المصفوفة عن طريق الرمز لا العدد , بالأمر :
Float sales[size];
ويتم التعامل في كافة أوامر البرنامج المتعلقة بحجم المصفوفة بهذا الرمز . (مثلا :
(j<size .
والفائدة من ذلك هو تيسير التغيير في حجم المصفوفة مستقبلا , فمجرد تغيير العدد المخصص للمقدار الثابت (6) إلي عدد أخر (10مثلا) , يتغير حجم المصفوفة , ويسري التغير كل أوامر البرنامج دفعة واحدة , ودون الحاجة إلي التغيير الفعلي لها جميعا . والعرف الساري بالنسبة للقيم الثابتة هي كتابتها بالأحرف الكبيرة تمييزا لها عن المتغيرات .
استهلاك المصفوفات
البرنامج التالي يحسب عدد الأيام من بداية العام الي تاريخ معين فيها , فينشئ مصفوفة من 12 عنصرا , تعبر عن أشهر السنة . ويتطلب الأمر أن تملأ عناصر المصفوفة بأيام الأشهر عند بداية التعامل معها . وإليك البرنامج ( البرنامج مصمم للسنة البسيطة ) :
days.cpp
// days.cpp
// shows days from start of year to date specified
#include <iostream.h>
#include <conio.h>
void main()
{
int month, day, total_days;
int days_per_month[12] = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
cout << "\nEnter month (1 to 12): "; // get date
cin >> month;
cout << "Enter day (1 to 31): ";
cin >> day;
total_days = day; // separate days
for(int j=0; j<month-1; j++) // add days each month
total_days += days_per_month[j];
cout << "Total days from start of year is: " << total_days;
getche();
}
وإليك مثالا للحوار :
Enter month ( 1 to 12 ): 3
Enter day ( 1 to 31): 11
Total days from start of year is: 70
وقد تم تعريف المصفوفة مع استهلاك عناصرها علي الصورة التالية :
Int days_per_month[12] = { 31, 28, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31 };
ويبين الشكل طريقة استهلال المصفوفات
شكل استهلال المصفوفات
ما الذي يحدث لو أنك عرفت قيما استهلالية لا تتفق مع حجم المصفوفة ؟ إذا كان القيم الاستهلالية أقل , أخذت العناصر الباقية قيمة 0 , أما إذا كانت أكثر , ظهرت رسالة تحذيرية .
لو سمحت عندي سوال في المصفوفات
ردحذف