الأحد، 6 سبتمبر 2015

المصفوفات في ++C

المصفوفة هي نوع من أنواع بنية البيانات، لها عدد محدود ومرتب من العناصر التي تكون جميعها من نفس النوع type، فمثلاً يمكن أن تكون جميعها صحيحة int أو عائمة float ولكن لا يمكن الجمع بين نوعين مختلفين في نفس المصفوفة .
الشكل التالي يبين مصفوفة C  تحتوى على 13 عنصر من النوع int، ويمكن الوصول إلي أي من هذه العناصر بذكر اسم المصفوفة متبوعاً برقم موقع العنصر في المصفوفة محاطاً بالأقواس [    ] .
يرمز لرقم العنصر في المصفوفة بفهرس العنصر index . فهرس العنصر الأول في المصفوفة هو 0 ولهذا يشار إلي العنصر الأول في المصفوفة C بـ C[0] والثاني C[1] والسابع C[6] وعموماً يحمل العنصر i في المصفوفة C الفهرس C[i-1]  .
تتبع تسمية المصفوفات نفس قواعد تسمية المتغيرات.

C[0]
-45
C[1]
6
C[2]
0
C[3]
72
C[4]
1543
C[5]
-89
C[6]
0
C[7]
62
C[8]
-3
C[9]
1
C[10]
6453
C[11]
78
C[12]
15

أحياناً يسمى فهرس العنصر برمز منخفض subcript ويجب أن يكون الفهرس integer أو تعبير جبري تكون نتيجته integer . فمثلاً إذا كانت a=5 وb=6 فالعبارة:
C[a+b]+=2;
¨ تقوم بإضافة 2 إلي العنصر الثاني عشر C[11] في المصفوفة C .
¨ يحمل العنصر 0 في المصفوفة C القيمة -45 والعنصر 1 القيمة 6.
   لطباعة مجموع الثلاثة عناصر الأولى في المصفوفة C  يمكن كتابة:
cout<<C[0]+C[1]+C[2]<<endl;



الإعلان عن المصفوفات:-
 تحتل المصفوفات حيزاً في الذاكرة لذا يجب على المبرمج تحديد نوع عناصر المصفوفة وعددها حتى يتسنى للمعرف تخصيص الحيز اللازم من الذاكرة لحفظ المصفوفة، وحتى تخبر المصرف بأن يخصص حيزاً لـ 12 عنصر من النوع int في مصفوفة C  ، استخدم الإعلان:
int C[12];
يمكن تخصيص الذاكرة لعدة مصفوفات باستخدام نفس الإعلان وذلك كالأتي:
int b[100], x[20];
أيضاً يمكن الإعلان عن مصفوفات من أي نوع بيانات آخر ، فمثلاً للإعلان عن مصفوفة عناصرها من النوع char نكتب:
char ch[20];
مثال عن استخدام المصفوفات:

يستخدم البرنامج التالي حلقة for لتمهيد عناصر المصفوفة  n عند 0 وطباعة عناصر المصفوفة.

//Program :
//initializing an array
#include <iostream.h>
#include <iomanip.h>
main( )
{
int n[10];
  for (int i=0; i<10;i++) // initialize array
n[i] = 0;  
cout << "Element” << setw(13) << " value” << endl;
for (i=0 ; i< 10; i++)   // print array
cout << setw(7) <<i<<setw(13) <<n[i]<<endl;
return 0;
}
في البرنامج السابق تم تضمين الملف iomanip.h وذلك لأننا استخدمنا المناور setw(13)  والذي يعني ضبط عرض الحقل عند 13  ( أي أن القيمة التي ستتم طباعتها ستكون على بعد 13 مسافة من القيمة التي تمت طباعتها قبلها ) .
يمكن تمهيد عناصر المصفوفة باتباع الإعلان عن المصفوفة بعلامة المساواة (=) تليها لائحة من القيم المطلوب تمهيد عناصر المصفوفة عندها، ويتم الفصل بين القيم بفواصل، وتحيط هذه اللائحة الأقواس الحاصرة {  }. البرنامج التالي يقوم بتمهيد عناصر من النوع integer  لتحتوي قيم محددة عند الإعلان عن المصفوفة، وطباعة هذه القيم.

//Program :
//initializing an array with a declaration
#include <iostream.h>
#include <iomanip.h>
main( )
{
int n[10] = {32,27,64,18,95,14,90,70,60,37};
cout << "Element” << setw(13) << " value” << endl;
for (i=0 ; i< 10; i++)   // print array
cout << setw(7) <<i<<setw(13) <<n[i]<<endl;
return 0;

}

السلاسل في المصفوفات 
كما ذكرنا أنه يمكن تعريف مصفوفات من أي نوع بيانات آخر، سنقوم الآن بتخزين سلسلة حروف في مصفوفة من النوع char.
يتم تمهيد المصفوفة من النوع char باستخدام ما يسمى بالثابت السلسلي (string literal)
char string1[  ]="first";
حجم المصفوفة string1 هنا يتم تحديده بواسطة المصرف بناءاً على طول الثابت السلسلي "first".
من المهم هنا أن نذكر أن السلسلة "first" تحتوى على خمسة عناصر زائداً حرفاً خامداً يشير إلى نهاية السلسلة ويسمى الحرف الخامد null character ويتم تمثيله باستخدام تتابع الهروب '\o' وتنتهي كل السلاسل بهذا الحرف الخامد وعليه فإن المصفوفة string1 تحتوى على ستة عناصر. 
يمكن أيضاً تمهيد السلسلة "first" باستخدام لائحة قيم تفصلها فواصل لذا الإعلان:-
char string1[  ]="first";
يكافئ:
char string1[  ]={'f','i','r','s','t','\o'}
وبما أن السلسلة في الواقع هي مصفوفة أحرف ، عليه يمكن الوصول إلى أي حرف من حروف السلسلة مباشرة باستخدام الفهرس واسم المصفوفة ،فمثلاً string1[0]='f'. ومثلما يمكن تمهيد السلسلة عند الإعلان عنها، يمكن أيضاً إدخال السلاسل عن طريق لوحة المفاتيح باستعمال cin و>> فمثلاً الإعلان :-
char string2[20];
ينشئ مصفوفة أحرف تسمح بتخزين 19 حرفاً إضافة إلى الحرف الخامد والعبارة
cin>>string2;
تقوم بتخزين السلسلة المدخلة عن طريق لوحة المفاتيح وتخزينها في المصفوفة string2.
يمكن خرج السلسلة المخزنة في مصفوفة الأحرف باستخدام cout و<< وعليه يمكن طباعة المصفوفة string2   باستخدام العبارة:-
cout << string2 << endl;


ملاحظة :
عند استعمال cin  مع السلاسل  يتم فقط ذكر اسم المصفوفة التي سيتم فيها تخزين حروف السلسلة المدخلة دون ذكر حجمها هنا تأتى مسئولية المبرمج في أمثلة المصفوفة التي سيتم تعريفها لتخزين السلسلة يجب أن تكون كبيرة لما يكفى تخزين السلسلة التي يدخلها المستخدم عن طريق لوحة المفاتيح ويجب أن نذكر هنا أن cin  حالما يجد فراغاً يتوقف عن قراءة الدخل ويقوم بتخزين السلسلة المدخلة في المصفوفة المعلن عنها لتخزينها.
cout مثل cin لا تهتم بحجم المصفوفة حيث تقوم بطباعة حروف السلسلة حتى تصل إلى الحرف الخامد الذي يحدد نهاية السلسلة.
البرنامج التالي يقوم بتمهيد مصفوفة أحرف عند ثابت سلسلي ويقوم باستعمال حلقة التكرار for للوصول إلى عناصر المصفوفة وطباعتها .

//Program :
//Treating character arrays as strings
#include<iostream.h>
main( )
{
char string1[20], string2[ ] = " stringliteral” ;
cout << "Enter a string: ";
cin>> string1;
cout << "string1 is : " << string1<<endl
        << "string2 is : " << string2<<endl
        << "string1 with spaces between characters is: "
        << endl;
for (int i= 0; string1[i] != '\0' ; i++)
   cout << string1[i]<< "  ";
cout << endl;
//Continued
return 0;
}

الخرج من البرنامج:
بافتراض أن المستخدم قد أدخل السلسلة  Hello there
Enter a string: Hello there
string1 is : Hello
string2 is : string Literal
string1 with spaces between characters is : H  e  l  l  o

استخدمت حلقة التكرار for  لوصول إلى حروف السلسلة string1 وطباعتها مع طباعة مسافة بين كل حرف والآخر حتى تصل إلى الحرف الخامد '\o( string1[i] != '\o'; )والذي يحدد نهاية السلسلة.

مكتبة دالات السلاسل
توجد عدة دالات تعمل على السلاسل، إذا أردنا استعمال أي من هذه الدوال في برنامج يجب أن نقوم بتضمين ملف الترويسة string.h . من هذه الدالات :
1-strlen( )
 تعيد الدالة strlen( )  طول السلسلة الممررة كوسيطة لها ،البرنامج  التالي يوضح ذلك :-

//Program :
// using strlen
#include<iostream.h>
#include<string.h>
main (  )
{
char *string1= " abcdefghijklmnopqrstuvwxyz”;
//Continued
char *string2 = "four”;
char *string3 = "Boston”;
cout << " The length of \ "  " << string1
        << " \” is  << strlen (string1) <<endl
        << " The length of \” << string2
        <<” \” is << strlen (string2) << endl
        << "The length of\ "  "<< string3
       << " \” is << strlen( string3) <<endl;
return 0;
}


2- strcpy( )
تستعمل الدالة strcpy لنسخ سلسلة إلى سلسلة أخرى
 //Program 
// using strcpy
#include<iostream.h>
#include<string.h>
main (  )
{
char x[  ] = "Happy Birthday to you”;
//Continued
char y[25];
cout<<” The string in array x is : "<< x << endl;
cout<<” The string in array y is : "<< strcpy(y, x)
<< endl;
return 0;
}
بعد تنفيذ العبارة strcpy(y, x) ستحتوى السلسلة y  على Happy Birthday to you. لاحظ هنا أن الدالة strcpy تنسخ السلسلة الممررة كالوسيطة الثانية إلى السلسلة الممررة كالوسيطة الأولى.

وعليه الخرج من البرنامج:

The string in array x is : Happy Birthday to you
The string in array y is : Happy Birthday to you
3- strcat( )
تقوم الدالة strcat( ) بإلحاق السلاسل ، الذي يمكن أن يسمى جمع السلاسل فمثلاً إذا ألحقنا السلسلة science بالسلسلة computer ستكون نتيجة السلسلة computer science:-
//Program :
// using strcat
#include<iostream.h>
#include<string.h>
int main (  )
{
char s1[20]=”computer” ;
char s2[  ]=”science” ;
cout<<”s1= " <<s1 << endl << "s2= " << s2 <<endl;
cout<< "strcat(s1, s2) = " << strcat (s1, s2) << endl;
//Continued
return 0;
}
الخرج من البرنامج:
s1= computer
s2 = science
strcat(s1, s2)= computerscience
4- strcmp( )
الدالة strcmp تقارن السلسلة الممرة إليها كوسيطة أولى مع السلسلة الممرة إليها كوسيطة ثانية، وترجع  0 إذا كانتا متطابقتين وقيمة سالبة إذا كانت السلسلة الأولى أصغر من السلسلة الثانية وقيمة موجبة إذا كانت السلسلة الأولى أكبر من السلسلة الثانية.
البرنامج التالي يوضح ذلك:
//Program :
// using strcmp
#include<iostream.h>
#include<string.h>
int main (  )
{
char  *s1 = " Happy New Year”;
char  *s2 = " Happy New Year”;
char  *s3 = " Happy Holidays”;
cout << "s1= " << s1<< endl<< "s2= " <<s2<<endl
        << "s3= " << s3<< endl<< endl<< ”strcmp(s1, s2)= "
        << strcmp(s1, s2) <<endl<< ”strcmp(s1, s3)= "
        << strcmp(s1, s3) <<endl<< ”strcmp(s3, s1)= "
        << strcmp(s3, s1) <<endl<< endl;
return 0;

}
الخرج من البرنامج:
s1=   Happy New Year
s2=   Happy New Year
s3 =  Happy Holidays

strcmp (s1, s2) = 0
strcmp (s1, s3) = 6
strcmp (s3, s1) = 6