المصفوفات Arrays في لغة البرمجة C
ما هي المصفوفات Arrays في لغة البرمجة سي، كيفية الإعلان عن المصفوفة وتهيئة عناصرها بقيمة إفتراضية، كيفية الوصول إلى عناصر المصفوفة، أمثلة على المصفوفات بلغة السي
ما هي المصفوفة Array في لغة البرمجة C؟
المصفوفة أو المتراصة بالإنجليزية تسمى Array، هي مجموعة محددة من البيانات في غالب الأمر تكون بيانات ذات صلة ويجب أن تنتمي هذه البيانات الى نفس النوع Data-Type، تسمى هذه البيانات بـ عناصر المصفوفة أو Array Elements، ويتم تخزين هذه البيانات أو العناصر في الذاكرة بشكل متجاور أو متلاصق.
نوع البيانات الخاص بالمصفوفة قد ينتمي إلى أنواع البيانات الأساسية أو الأولية مثل int
و double
، أو قد ينتمي إلى أنواع البيانات المشتقة أو المركبة مثل struct
، كما تم شرحها في مقالة المتغيرات وأنواع البيانات في لغة البرمجة C.
قد تحتوي المصفوفة على مصفوفات أخرى من البيانات وفي هذه الحالة تعتبر مصفوفة متعددة الأبعاد أو Multi-Dimensional Array، وتعد المصفوفة ثنائية الأبعاد Two-Dimensional Array هي الأكثر إستخداما لحل مسائل المصفوفات الرياضية والمعروفة بـ Matrix.
تسمى المصفوفة بأحادية البعد أو One-Dimensional Array إذا ما كانت عناصر هذه المصفوفة مرتبة بشكل قائمة أو بمعنى أدق أن عناصر هذه المصفوفة ليست في حد ذاتها مصفوفات أخرى.
لكي تتمكن من إنشاء مصفوفة في لغة البرمجة السي فإنه يجب أن تمر عملية الإنشاء بعدة مراحل، قد يتم دمج بعض هذه المراحل سويا ولكن سوف نتعرف على مراحل إنشاء المصفوفة خطوة بخطوة
إعلان المصفوفة Declaration
في هذه الخطوة أو المرحلة يتم حجز المساحة المناسبة من الذاكرة لتخزين عناصر المصفوفة، ولا يتم وضع قيم إفتراضية لعناصر المصفوفة، فإذا قمت بطباعة عناصر المصفوفة بعد عملية الإعلان مباشرة سوف تظهر لك نتائج لقيم موجودة في الذاكرة، عادة ما تسمى بـ Garbage أو قمامة أي أنها قيم موجودة في هذا الجزء من الذاكرة ولا تمثل قيمة محددة لأي بيانات.
الشكل العام أو القاعدة العامة لإعلان المصفوفة في لغة البرمجة سي تكون كالتالي
Data-Type ArrayName[PositiveIntegerNumber];
حيث يتم أولا كتابة نوع البيانات الممثل لعناصر المصفوفة، ثم يتم إختيار إسم متغير للمصفوفة بحيث يتم إتباع القواعد الخاصة لإختيار إسم المتغير في لغة البرمجة سي كما تعرفنا عليها سابقا، ثم يتم إستخدام الأقواس المربعة أو Square Brackets وبداخلهم يتم كتابة رقم صحيح موجب أكبر من الصفر لكي يحدد عدد عناصر المصفوفة ويتم إنهاء الجملة بعلامة الفاصلة المنقوطة Semicolon.
هناك بعض القواعد التي يجب مراعاتها أثناء تحديد عدد عناصر المصفوفة، وهي كالتالي
- يجب أن يكون عدد عناصر المصفوفة رقم صحيح موجب أكبر من الصفر، وأن يكون رقم ثابت غير قابل للتغيير.
- لا يمكن إستخدام متغير من النوع
int
لتحديد عدد عناصر المصفوفة، حيث أن المتغيرات في لغة البرمجة C يمكن تغيير قيمتها أو كما يطلق عليها بأنها Mutable لذلك لا يمكن إستخدامها في تحديد عدد عناصر المصفوفة. - تحتوي لغة البرمجة C من أول الإصدار C99 على الكلمة
const
وإن كانت لديك أي خلفية برمجية فسوف تخمن بأن هذه الكلمة تعني أن قيمة المتغير ثابتة أو Immutable، ولكن هذه الكلمة في لغة البرمجة سي لا تعني قيمة ثابتة كما هو متعارف عليه في باقي لغات البرمجة، وبالتالي لا يمكن إستخدامها مع متغير من النوعint
لتحديد عدد عناصر المصفوفة. - عادة ما يستخدم المبرمجين المتعاملين مع لغة البرمجة سي الأمر أو التوجيه
#define
لتحديد قيمة عدد عناصر المصفوفة، وهو أمر تابع لـ Preprocessor الخاص بلغة البرمجة سي أو يتم تطبيقة قبل ترجمة الكود. - للتنويه فقط أنه يمكنك إستخدام متغير لتحديد عدد عناصر المصفوفة ولكن يتم إعلان المصفوفة عن طريق المؤشر أو الـ Pointer وفي هذه الحالة يتم التعامل مع الذاكرة بشكل مباشر، وهو أمر سوف نناقشه في مقالة مستقلة.
الأمثلة التالية توضح كيفية إعلان المصفوفة في لغة البرمجة سي، ويمكنك إستخدام أي بيئة عمل خاصة بلغة البرمجة C لكي تتمكن من تطبيق الأمثلة بنفسك
// PreProcessor directive#define ARRAY_SIZE 15// User structure to be used as arraystruct User {int ID;char name[100];};// Valid Declarationint arr[10];double dbl[ARRAY_SIZE];char str[101];struct User users[10];// Invalid Declarationint num = 10;int n_arr[num]; // Not Allowed
في بداية الأمثلة قمنا بتعريف ARRAY_SIZE مساوي لـ 15، حيث يتم إستبدال هذه الكلمة في الكود بالقيمة 15 قبل أن يتم ترجمة الكود بإستخدام الـ Compiler، وقمنا بتعريف نوع بيانات هيكلية مركبة لتوضيح كيفية إنشاء مصفوفة تحتوي على عناصر من نوع بيانات مركبة، ثم قمنا بإنشاء مجموعة من المصفوفات من أنواع مختلفة من البيانات لتوضيح الفكرة.
سوف تلاحظ من الأمثلة أنه يمكنك إستخدام رقم صحيح مباشرة للتعبير عن عدد عناصر المصفوفة أو يمكنك إستخدام الكلمة ARRAY_SIZE التي سبق تعريفها في الكود، وقد قمت بكتابة مثال خاطئ على إستخدام المتغير لتحديد عدد عناصر المصفوفة للتوضيح، فإذا قمت بتجربة هذا المثال لن يتم ترجمة الكود وسوف تحصل على Compilation Error.
الوصول إلى عناصر المصفوفة
كما تعرفنا أن المصفوفة هي عبارة عن مجموعة من البيانات يتم تخزينها في متغير واحد وفي مساحة متلاصقة، فإنه يجب معرفة كيفية الوصول إلى أي عنصر من عناصر هذه المصفوفة.
يجب معرفة أن كل عنصر من عناصر المصفوفة له معلومتين، المعلومة الأولى هي عنوان أو مكان هذا العنصر في المصفوفة ويعرف هذا العنوان بـ Index، والمعلومة الثانية هي قيمة العنصر نفسه.
يتم ترتيب أماكن أو عناوين العناصر لكل مصفوفة بأرقام صحيحة تبدأ من العنوان صفر، أي أن أول عنصر في المصفوفة عنوانه صفر، يليه واحد وهكذا حتى آخر عنصر في المصفوفة والذي يكون عنوانه مساوي لعدد عناصر المصفوفة مطروح منه واحد.
لكي تتمكن من الوصول إلى عنصر محدد في المصفوفة يتم كتابة إسم المتغير الخاص بالمصفوفة متبوعا بزوج من الأقواس المربعة وبداخل هذه الأقواس يتم كتابة الرقم الخاص بموقع العنصر في المصفوفة والمعروف بالـ index، وفي هذه الحالة يمكنك التعامل مع هذا العنصر على أنه متغير مستقل، حيث يمكنك قراءة قيمة العنصر (المتغير) أو تخزين قيمة جديدة للعنصر.
الأمثلة التالية توضح كيفية تخزين قيمة لبعض عناصر مصفوفة ثم طباعة قيمة أول وآخر عنصر في المصفوفة بإستخدام الدالة printf()
.
int arr[10];arr[0] = 100;arr[1] = 101;arr[9] = 107;printf("First Element = %d, Last Element = %d\n", arr[0], arr[9]);
تهيئة عناصر المصفوفة Initialization
يقصد بتهيئة عناصر المصفوفة، تحديد قيمة مبدئية أو إفتراضية لعناصر المصفوفة، فكما تعرفنا خلال هذا المقال أنه عند الإعلان عن مصفوفة جديدة فإنه يتم حجز مساحة في الذاكرة دون تغيير القيم الموجودة في هذه المساحة، وعادة ما تكون الذاكرة مليئة بقيم بيانات من أنواع مختلفة حيث عند الإنتهاء من أي متغير يتم إنهاء حجز المساحة المخصصة له ولكن لا يتم حذف القيمة الموجودة في هذه المساحة، ولذلك عند حجز المساحة لإنشاء مصفوفة جديدة يجب تهيئة عناصرها بقيمة إفتراضية مبدئية.
يمكنك دمج خطوة تهيئة عناصر المصفوفة مع خطوة الإعلان عن المصفوفة، وفي هذه الحالة يتم تحديد قيم عناصر المصفوفة أثناء الإعلان عنها، حيث يتم إعلان المصفوفة بالطريقة التي شرحناها سابقا وقبل كتابة رمز الفاصلة المنقوطة يتم إستخدام علامة التخصيص =
متبوعة بزوج من الأقواس المعقوفة { }
والتي تعرف بـ Curly Braces وبداخلهم يتم تحديد قيم عناصر المصفوفة ويفصل بين كل قيمة علامة الفاصلة ,
وتعرف بـ Comma، والأمثلة التالية توضح كيفية تطبيق هذه الطريقة
int i_arr[3] = {1, 2, 3};double d_arr[3] = {3.1, 3.2, 3.3};
يوجد بعض الإستخدامات الخاصة لتهيئة عناصر المصفوفة أثناء الإعلان عنها، حيث يمكن تجاهل تحديد عدد عناصر المصفوفة، وسوف يتم ذلك بشكل تلقائي كالمثال التالي
double arr[] = {0.1, 1.2, 0.3, 1.4, 0.5};
في هذا المثال تم إنشاء مصفوفة تحتوي على خمسة عناصر من النوع double
، وتم تحديد قيمة العنصر الأول arr[0]
بـ 0.1 والعنصر الثاني arr[1]
بـ 1.2 والعنصر الثالث arr[2]
بـ 0.3 والعنصر الرابع arr[3]
بـ 1.4 والعنصر الخامس والأخير arr[4]
بـ 0.5.
يمكن أيضا تحديد قيم محددة للعناصر الأولى للمصفوفة وتحديد القيمة صفر لباقي العناصر، كما في المثال التالي
int arr1[10] = {1, 2, 3};double arr2[10] = {1.1, 2.2};int arr3[25] = {101};
في الأمثلة السابقة قمنا بإنشاء المصفوفة arr1
من النوع int
وتم تحديد عدد عناصر المصفوفة بـ 10 عناصر، العنصر الأول قيمته تساوي 1 والعنصر الثاني قيمته تساوي 2 والثالث قيمته تساوي 3 وباقي عناصر المصفوفة قيمتها سوف تصبح 0، وكذلك المثال الثاني حيث قمنا بإنشاء مصفوفة arr2
تحتوي على 10 عناصر من النوع double
قيمة العنصر الأول تساوي 1.1 والعنصر الثاني 2.2 وباقي العناصر قيمتها تساوي 0.0 وهي قيمة الصفر في نوع البيانات double
، والمثال الثالث قمنا بإنشاء المصفوفة arr3
تحتوي على 25 عنصر من النوع int
قيمة العنصر الأول arr3[0]
تساوي 101 وباقي عناصر المصفوفة قيمتهم تساوي صفر.
كما تعرفنا سابقا أن لغة البرمجة سي لا تحتوي على نوع البيانات الخاص بالنصوص string
ولكن يتم التعامل مع النصوص على أنها مصفوفة من النوع char
، ويوجد بعض الإختصارات لإنشاء مصفوفة من الحروف، والأمثلة التالية توضح ذلك
char str1[11] = {'A', 'B', 'U', 'E', 'L', 'F', 'A', 'T', 'E', 'H', '\0'};char str2[11] = "ABUELFATEH";char str3[] = "ABUELFATEH";
في الأمثلة السابقة تم إنشاء مصفوفة تحتوي على الحروف المكونة للنص ABUELFATEH، في المثال الأول تم إنشاء المصفوفة str1
والتي تحتوي على 11 عنصر من النوع char
حيث يجب إنهاء مصفوفة الحروف بالرمز \0
والمعروف بـ NULL لتحديد نهاية النص، ثم قمنا بكتابة الحروف المكونه للنص بحيث يتم كتابة كل حرف بين علامة التنصيص المفردة Single Quotes، وفي المثال الثاني تم إنشاء المصفوفة str2
والتي تحتوي أيضا على 11 عنصر من النوع char
ولكن تم إستبدال الأقواس المعقوفة بعلامات التنصيص المزدوجة Double Quotes وتم كتابة النص دفعة واحدة دون فصل الحروف، مع ملاحظة أن الرمز الأخير NULL سوف يتم كتابته بشكل تلقائي فلم نقم بكتابته عند إستخدام هذه الطريقة، وكذلك الحال في المثال الثالث str3
حيث تجاهلنا تحديد عدد عناصر المصفوفة وسوف يتم تحديده بشكل تلقائي إلى 11 عنصر وهم عدد الحروف المكونة للنص بالإضافة إلى رمز الـ NULL.
يمكن إستخدام الحلقات التكرارية Loops لكي يتم تهيئة عناصر المصفوفة بقيمة إفتراضية والمثال التالي يوضح برنامج متكامل كما تم شرحه في مقالة الأكواد الأساسية لكتابة برنامج بلغة البرمجة سي، وتم إستخدام الحلقة التكرارية بالأمر for
من إجل إنشاء مصفوفة وتخصيص القيمة صفر لكل عناصر المصفوفة ثم طباعة عناصر هذه المصفوفة
#include <stdio.h>#include <stdlib.h>#define SIZE 10int main() {int i;// Declare Integer Array of size SIZEint arr[SIZE];// Initialize Array Elements values to 0for (i = 0; i < SIZE; i++)arr[i] = 0;// Display initialized Array Valuesfor (i = 0; i < SIZE; i++)printf("%d, ", arr[i]);system("pause");return 0;}