1-9-2 المصفوفات Arrays
المصفوفة هى نظام آخر للمراوغة indirection .
المصفوفة : هى مجموعة بيانات من النوع المعلن , مرتبة بالترتيب .
يتم إعلان المصفوفة مثل أى متغير أو ثابت آخر , فيما عدا العدد المطلوب لعناصر المصفوفة , كما يلى :
كود:
int digits[10] ; // this declares an array of 10 integer
char str[20] ; // this declares an array of 20 characters
يتم الإشارة لعنصر المصفوفة , لكى يتم التعامل معه , عن طريق دليل الترتيب (الرقم المسلسل )index . دليل الترتيب يمكن أن يكون فى المدى من الصفر "0" إلى طول المصفوفة المعلنة ناقص واحد كما يلى :
كود:
str[0] , str[1] , str[2] , ………………str[19]
إعلان المصفوفة يمكن أن يتضمن التهيئة . فى مصفوفة المتغيرات قيم التهيئة سوف توضع فى حيز ذاكرة البرنامج ويتم نسخها إلى المصفوفة الفعلية قبل تنفيذ الدالة الرئيسية main( ) . مصفوفة الثوابت تختلف فى أن القيم سوف توضع بذاكرة البرنامج , لتوفير ذاكرة المعطيات RAM , التى تكون عادة صغيرة الحجم .
شكل تهيئة المصفوفة كما يلى :
كود:
int array[5] = {12 , 15 , 27 , 56 , 94 } ;
فى هذه الحالة , العنصر الأول للمصفوفة هو array[0] = 12 والعنصر الثانى array[1] = 15 والعنصر الثالث array[2] = 27 والعنصر الرابع array[3] = 56 والعنصر الخامس array[4] = 94 .
لغة السى ليس لديها احتياط لاختبار حدود المصفوفة . إذا تم تخصيص قيمة لرتبة عنصر والتى تتعدى حدود المصفوفة , فيمكن للذاكرة أن تتغير بطريقة غير متوقعة مما يؤدى إلى نتائج غير مرغوب فيها . على سبيل المثال :
كود:
char digits[10] = {0,1,2,3,4,5,6,7,8,9}; // an array of characters
num = digits[12] ; // this reads outside the array .
يتم تخزين المصفوفات فى مواقع متتابعة بالذاكرة . قراءة العنصر digits[5] فى المثال أعلاه سوف تتسبب فى ذهاب المعالج إلى موقع أول رقم مسلسل index للمصفوفة ثم قراءة البيانات الموجودة هناك .
الفرق الأساسى فى استخدام المصفوفة واستتخدام المؤشر هو أنه فى حالة المصفوفة يوجد مساحة ذاكرة فعلية مخصصة من أجل البيانات . مع المؤشر , يتم فقط تخصيص عنوان مرجعى , ويترك للمبرمج إعلان وتعريف مساحة الذاكرة الفعلية ( المتغيرات) التى يتم الوصول إليها .
أكثر أنواع المصفوفات شيوعا هى مصفوفة الحروف . عادة يشار إليها باعتبارها سلسلة نصية string أو سلسلة حروف . متغير السلسلة النصية يعرف كمصفوفة حروف , فى حين أن ثابت السلسلة النصية يتم إعلانه عن طريق وضع سطر نصى بين قوسين "….". فى حالة ثابت السلسلة النصية , سوف يقوم المترجم بإضافة "صفر" عند نهاية السلسلة النصية .لذلك عندما تقوم بإعلان سلسلة نصية لحروف , ثابتة أو متغيرة , يجب أن يكون حجم المصفوفة المعلنة أكبر بواحد لما تحتاجه للسماح بصفر النهاية , كما فى المثال التالى :
كود:
char str[12] ; // variable string
printf("Hello World") ; // constant string in program memory
const cstr[16] = "Constant String" ;
// constant string in program memory
فى المثال السابق يتم تحديد cstr لتحتوى على 16 قيمة لأن السلسلة النصية نفسها تحتوى على 15 حرف ويجب إضافة مكان للسماح لصفر النهاية .
اسم المصفوفة متبوعا برقم مسلسل index يكون مرجع لعنصر منفرد للمصفوفة من أى نوع . من الممكن أيضا الإشارة للعنصر الأول فى أى مصفوفة باسمها فقط . عندما لا يتم تحديد للرقم المسلسل , فإن اسم المصفوفة يعالج كعنوان للعنصر الأول بالمصفوفة .
مثال :
إذا أعطيت الإعلانات التالية :
كود:
char stng[20] ;
char *p ;
فإن التخصيص :
كود:
p = stng ; // p is pointing to stng[0]
هو مثل :
كود:
p = &stng[0] ; // p is pointing to stng[0]
سلسلة الحروف النصية غالبا تحتاج إلى المعالجة على أساس " حرف تلو الحرف " . إرسال رسالة إلى جهاز تسلسلى أو إلى وحدة العرض LCD هى أمثلة لهذه المطالب .
المثال التالى يبين كيف أن ترتيب indexing المصفوفة و دالة المؤشر متبادلتين تقريبا . هذا المثال يستخدم دالة المكتبة putchar( ) لإرسال حرف واحد فى كل مرة إلى جهاز الخرج القياسى , مثل المنفذ التسلسلى الأكثر شيوعا :
كود:
#include <16F877.h> //register definition file for
#fuses HS,NOWDT //a Microchip PIC16F877
#use delay(clock=10000000 //setup the RS232 port for standard output
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,stream=RS232,bits=8)
#include <stdio>
const char s[15] = {"This is a test") ;
char i ;
char *p ;
void main(void)
{
for(i=0;i<15;i++) // print each character of the array
putchar(s[i]) ; // by using I as index
p = s ; // point to string as whole
for(i = 0 ; i<15 ; i++ ) // print each character of array
putchar(*p++); // and move to the next element
// by incrementing the pointer p
while(1)
;
}
الجزء الأول فى هذا البرنامج يستحدم حلقة for لإخراج كل حرف من المصفوفة منفردا (على حدة) . يستخدم عداد حلقة for كرقم مسلسل index لتكرار كل حرف بالمصفوفة بحيث يمكن تمريرها إلى الدالة
putchar( ) . الجزء الثانى يستخدم مؤشر للوصول إلى كل عنصر من المصفوفة . السطر "p = s " يحدد المؤشر لعنوان أول حرف بالمصفوفة . بعد ذلك تستخدم حلقة for المؤشر ( تزايد لاحق فى كل مرة ) لتكرار عناصر المصفوفة وتمريرها إلى الدالة putchar( ) .
1-9-3 المصفوفات متعددة الأبعاد Multidimensional Arrays :