أساسيات البرمجة بلغة السي شارب · الفصل 8 — المصفوفة أحادية البُعدמערך חד-ממדי · יסודות התכנות בשפת C#‎⌂📚🏠
الفصل 8

المصفوفة أحادية البُعد

מערך חד-ממדי

8.1 مقدمة – הקדמה

المصفوفة هي عبارة عن مجموعة من المُتغيرات من نفس النوع مرتبه ترتيباً تسلسليا في الذاكرة. نستعمل المصفوفة للتعامل مع كمية كبيرة من البيانات التي نريد تخزينها.

عندما نريد تعريف مصفوفة يجب أن نحدد ما يلي:

يمكن اعتبار المصفوفة مجموعة من المتغيرات من نفس النوع مرتبه بسطر واحد كما يلي:

0000000000arr[0]arr[1]arr[2]arr[3]arr[4]arr[5]arr[6]arr[7]arr[8]arr[9]arr

في المثال بالصورة تظهر لدينا مصفوفة من النوع int واسمها arr ، المصفوفة ذات طول 10. كل خانة من خانات هذه المصفوفة هو مُتغير قائم بحد ذاته.

نلاحظ ما يلي:

8.2 تعريف المصفوفات والتعامل مع المصفوفات – הגדרת מערכים והטיפול בהם

التوجه للمصفوفة يتم بواسطة اسم المصفوفة ومؤشر الحد، ويجدر بنا الانتباه أن مؤشر المصفوفات بلغة السي شارب يبدأ من 0، أي أن arr[0] هو الحد الأول بالمصفوفة وأن arr[1] هو الحد الثاني بالمصفوفة وهكذا ....

قانون: اذا كان طول المصفوفة هو N فذلك يعني أن الحد الأخير بالمصفوفة يكون له مؤشر قيمته N-1 . أي أن الحد الأخير بالمصفوفة هو arr[N-1] .

لذلك للتوجه لخانة من الخانات (مُتغير من مُتغيرات المصفوفة) نكتب اسم المصفوفة والرقم التسلسلي ونتعامل مع كل خانة كأنها مُتغير قائم بحد ذاته.

مثال 8.1
اذا عرفنا مصفوفة اسمها marks وكانت من نوع أعداد صحيحة وطولها 7 وبنيناها (سنتعلم ذلك بعد قليل) فإننا سنحصل على:
المؤشر01234560000000marks[0]marks[1]marks[2]marks[3]marks[4]marks[5]marks[6]marksرقم المؤشر

لكي نغير قيمة الخانة ذات المؤشر 2 نتوجه لها ونتعامل معها باسم المصفوفة وبرقم المؤشر التابع لها ثم نستطيع أن نتعامل معها كما نتعامل مع المُتغير العادي الذي عهدناه سابقا، مثلا نضع القيمة 70 داخل الخانة المذكورة بواسطة:

marks[2] = 70 ;
المؤشر012345600700000marks[0]marks[1]marks[2]marks[3]marks[4]marks[5]marks[6]marksرقم المؤشر

وإذا نفذنا الأمر التالي:

marks[6] = marks[2] + 3 ;

فإننا نحصل على ما يلي:

المؤشر0123456007000073marks[0]marks[1]marks[2]marks[3]marks[4]marks[5]marks[6]marksرقم المؤشر

كيف نبني مصفوفة؟:

لكي نتعلم كيف نبني مصفوفة ننظر للمثال التالي:

int[] arr = new int[10];

في هذا المثال بنينا مصفوفة باسم arr ، طولها 10 خانات.

أولا عرفنا نوع المصفوفة وكانت int[ ] ، أي مصفوفة أعداد صحيحة، ثم أعطينا المصفوفة اسما وهو arr ثم بنينا المصفوفة بالذاكرة بواسطة الأمر new وحددنا طولها على أنه 10 خانات (من رقم مؤشر 0 حتى 9).

0000000000arr[0]arr[1]arr[2]arr[3]arr[4]arr[5]arr[6]arr[7]arr[8]arr[9]arr

كما نرى نحصل على المصفوفة "مُصفرة". (מאופסת).

ملاحظة: المصفوفة هي عبارة عن كائن من فئة مصفوفات لذلك يجب علينا بناء (انشاء) هذا الكائن بواسطة الأمر new .

فعلنا ذلك سابقا عند تعاملنا مع الفئة Random .

تذكير: إذا أردنا أن نُعرّف كائن يُعطي أرقاما عشوائية (הגרלה) اسمه dealer من فئة Random كتبنا ما يلي:
Random dealer = new Random( );

ثم استعملنا العملية Next للحصول على أرقام عشوائية مثلا:

int x = dealer.Next(1,7) ;

x يمكنه أن يحتوي على 1 أو 2 أو 3 أو 4 أو 5 أو 6 .

قانون: لأنشاء مصفوفة نكتب ما يلي:
النوع[ ]اسمالمصفوفة;اسمالمصفوفة= newالنوع[طولالمصفوفة];

ويمكن ذلك بسطر واحد على النحو التالي:

النوع[ ]اسمالمصفوفة= newالنوع[طولالمصفوفة];

المصفوفات هي فئات حسب النوع.
مصفوفة من نوع اعداد صحيحة هي من فئة int[ ] .
مصفوفة من نوع اعداد عشرية هي من فئة double[ ] .
مصفوفة من نوع رموز هي من فئة char[ ].
مصفوفة من نوع جمل نصية هي من فئة string[ ] .
مصفوفة من نوع بوليانية هي من فئة bool[ ] .

نستطيع بناء مصفوفات مع قيم بدائية وتعريفها على النحو التالي أيضا:

int[] a = new int[] { 100, 97, 92, 100, 100 };

في هذه الحالة نحصل على مصفوفة اسمها a وطولها 5 حدود (خانات) وفيها القيم المعطاة أعلاه.

012341009792100100aالمؤشر

نستطيع استقبال قيم الخانات في المصفوفة من المستخدم (كل خانة بمثابة مُتغير قائم بحد ذاته)، وذلك باستعمال اسم المصفوفة ورقم المؤشر للخانة فمثلا:

arr[0] = int.Parse(Console.ReadLine( ));

هذا يستقبل من المستخدم عدد صحيح ويضعه في الخانة الأولى من المصفوفة وهكذا نستطيع استقبال كل خانات المصفوفة (نستعين بأوامر التكرار).

5294321924arr[0]arr[1]arr[2]arr[3]arr[4]arr[5]arr[6]arr[7]arr[8]arr[9]arr

8.3 أهمية استعمال المصفوفات – חשיבות השימוש במערכים

تُستعمل المصفوفات لحفظ الكثير من البيانات والتعامل مع هذه البيانات بواسطة أوامر التكرار حيث لا يمكن ذلك دون استعمال المصفوفات. يمكن توضيح ذلك بالمثال التالي:

مثال 8.2
(حل بدون أن تستعمل المصفوفات).

كتب برنامج لاستقبال 10 حروف من المُستخدم وطباعتهن على النحو التالي:
(1) في سطر واحد الحرف بجانب الآخر بنفس ترتيب استقبال هذه الحروف من المُستخدم.
(2) في سطر واحد تحت السطر السابق ولكن نطبع هذه الحروف بترتيب معاكس لترتيب استقبالها من المُستخدم.
الحل:
 public static void Main (string[] args)
 {
   char a,b,c,d,e,f,g,h,i,j;

   Console.Write("Give me a letter: ");
   a=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   b=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   c=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   d=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   e=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   f=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   g=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   h=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   i=char.Parse(Console.ReadLine());

   Console.Write("Give me a letter: ");
   j=char.Parse(Console.ReadLine());
  Console.WriteLine("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}",a,b,c,d,e,f,g,h,i,j);
Console.WriteLine("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}",j,i,h,g,f,e,d,c,b,a);
 }

ولكن إذا كتبنا الحل بواسطة المصفوفات فانه على النحو التالي:

using System;

class Hammam
 {
  public static void Main (string[] args)
  {
    char[] w = new char[10];
    int i;

    for(i=0;i<10;i++)
    {
    Console.Write("Give me a letter: ");
    w[i]=char.Parse(Console.ReadLine());
    }
    for(i=0;i<10;i++)
    Console.Write(w[i]);

    Console.WriteLine();

    for(i=9;i>=0;i--)
        Console.Write(w[i]);
    }
}

إذا استعمال المصفوفات يمكننا من استعمال أوامر التكرار لأننا ببساطة نستطيع تغيير المؤشر لكل خانة بينما في المُتغيرات لا يمكننا ارفاق مؤشر حيث أن من الخطأ فعل ذلك.

int n1, n2, n3;for (int i = 1; i <= 3; i++){ ni = int.Parse(Console.ReadLine()); n[i] = int.Parse(Console.ReadLine());}

8.4 العملية Length – הפעולה Length

العملية Length هي عملية تعمل على المصفوفات بعد وضع النقطة وهذه العملية تعيد لنا طول المصفوفة وهي تسهل علينا كتابة شرط التكرار حتى نصل آخر خانة بالمصفوفة.

مثال 8.3
int i;int[] arr = new int[10];for(i=0;i<arr.Length;i++)قيمته 10
سؤال 8.1: اكتب برنامج يعرف مصفوفة ذات 12 خانه ويملأ كل خانة بتربيع مؤشر هذه الخانة (تربيع الرقم التسلسلي للمؤشر لكل خانة) ثم يطبع هذه الخانات.
static void Main(string[] args)
{
    int i;
    int[] arr = new int[12]; //from 0 to 11

    for (i = 0; i < arr.Length; i++)
        arr[i] = (int)Math.Pow(i,2);

    for(i=0; i< arr.Length ; i++)
        Console.Write("{0}|",arr[i]);
}

عند تشغيل البرنامج نحصل على ما يلي:

Select Microsoft Visual Studio Debug Console
0|1|4|9|16|25|36|49|64|81|100|121|
سؤال 8.2: اكتب برنامج يستقبل من المُستخدم رقما طبيعياُ يمثل رقم الحد في متوالية فيبوناتشي، على البرنامج ان يطبع جميع الحدود من الحد الأول (مؤشر 0) حتى الحد الذي أدخل المُستخدم رقمه التسلسلي.

اطبع بين الحدود فاصلة (،) ولكن الحد الأخير يظهر بعده نقطة (.)
سؤال 8.3: اكتب برنامج يستقبل من مُستخدم 8 أعداد صحيحة ويُخزنها بمصفوفة اسمها arr ، على البرنامج أن يطبع الأعداد بترتيب عكسي من ترتيب إدخالها.
static void Main(string[] args)
{
    int i;
    int[] arr = new int[8];

    for(i=0;i<arr.Length;i++)
    {
        Console.Write("Insert a number: ");
        arr[i] = int.Parse(Console.ReadLine());
    }
    for(i=arr.Length-1; i>=0; i--)
        Console.Write("{0}|",arr[i]);
}

نتيجة تشغيل البرنامج:

Microsoft Visual Studio Debug Console
Insert a number: 70
Insert a number: 100
Insert a number: -90
Insert a number: 11
Insert a number: 48
Insert a number: 98
Insert a number: 500
Insert a number: -4
-4|500|98|48|11|-90|100|70|
سؤال 8.4: اكتب برنامج يستقبل من المُستخدم عشر أرقام صحيحة وموجبة (كونها موجبة يُسهل السؤال) ويُخزنها في مصفوفة اسمها arr . على البرنامج أن:
(أ) يبني مصفوفة جديدة تحتوي نفس أرقام المصفوفة السابقة ولكن مُرتبه بترتيب تصاعدي.
(ب) أن يرتب الأرقام المُخزنة في المصفوفة arr ترتيبا تصاعديا دون تعريف مصفوفة جديدة.

8.5 مصفوفة العدّادات – מערך מונים

يمكن استخدام المصفوفات كعدّادات (counters) حيث تكون كل خانة في المصفوفة هي عدّ عدّاد لمقدار مُعين، ويمكننا تقسيم الحالات الى قسمين:

  1. عدّاد: عدّادات تتقدم بواحد كل مرة. (מונים)
  2. جمّاع: عدّادات تتقدم بمقدار مُعين ممكن أن يكون ثابت أو غير ثابت. (צוברים – عدادات تراكمية).
سؤال 8.5: يخوض الطالب محمد والطالب عبد والطالبة مريم تنافسا على رئاسة الصف. عدد المصوتين هو عدد الطلاب في الصف. أكتب برنامج يُعرف مصفوفة فيها عدد أصوات كل مرشح بعد عملية فرز الأصوات. على البرنامج أن يطبع النتائج على الشاشة.
const int Mohammad = 0 ;
const int Abd = 1 ;
const int Mriam = 2 ;
MohammadAbdMriam012000Votesالمؤشر

أمثلة: مصفوفة عدادات (تتقدم بواحد):

مثال 8.4
اكتب برنامج يتابع حضور طلاب الجامعة في موضوع البرمجة في الفصل التعليمي الأول، حيث أنه يوجد 14 أسبوع تعليمي في الفصل ويتعلم الطلاب محاضرة واحدة أسبوعيا في هذا الموضوع.

عدد الطلاب هو 33 طالب أرقامهم التسلسلية من 1 الى 33.

معلوم أن الحضور للمحاضرات اجباري ومهم ولا يستطيع الطالب أن يتقدم للامتحان النهائي اذا كنت نسبة حضوره للمحاضرات أقل من 80% .

على البرنامج أن يسجل عدد مرات الغياب لكل طالب خلال الفصل في هذا الموضوع، وعليه أن يطبع على الشاشة من هم الطلاب الذين لا يمكنهم التقدم للامتحان النهائي وعليهم إعادة الموضوع مرة أخرى بالفصل القادم لأن حضورهم كان أقل من 80% .

شرح وتوضيح لاستراتيجية الحل:

الطالب 1الطالب 2الطالب 3....الطالب 32الطالب 330000000std[0]std[1]std[2]....std[31]std[32]طريقة 1
غير مستعملةالطالب 1الطالب 2....الطالب 31الطالب 32الطالب 330000000std[0]std[1]std[2]....std[31]std[32]std[33]طريقة 2
مثال 8.5
(مصفوفة عدادات تراكمية)

اكتب برنامج يتتبع عدد النقاط لفرق دوري كأس الصيف لكرة القدم. افرض أن عدد الفرق هو 4 فرق، لذلك يوجد لدينا 6 دورات. على البرنامج أن يسأل عن كل الفرق ما هي الإضافة للنقاط في كل دورة ويحتلن المصفوفة الملائمة التي تحوي نقاط كل فرقة.

في نهائية البرنامج علينا أن نطبع من هو الفريق الفائز الذي حصل على أكثر نقاط، ومن هو الفريق الخاسر الذي حصل على اقل عدد من النقاط.

النقاط تحتسب حسب ما يلي:
الفوز (w) = 3 نقاط.
التعادل (d) = 1 نقطة.
الخسارة (l) = 0 نقاط.

كل دورة نسأل عن كل فريق ما هي نتيجة مباراته خلال هذه الدورة (أي تكرار 6 مرات (دورات)).

بعد أن نملأ النتائج في كل الدورات علينا أن نبحث عن الفائز والخاسر (البحث عن أكبر قيمة في المصفوفة وأقل قيمة بالمصفوفة)، وأن نطبع الرقم التسلسلي للفائز وعدد نقاطه والرقم التسلسلي للخاسر وعدد نقاطه.
همام عبد اللطيف وتد — جميع حقوق هذا الكتاب محفوظة للمؤلف. النسخة الإلكترونية منشورة في fahed-lab.com بإذنه، مع تصحيحات وافق عليها. للتواصل مع المؤلف: hammam4112@gmail.com