C#: المصفوفات

1. إعلان وتهيئة المصفوفة أحادية البعد

المصفوفات في لغة C# هي أنواع مرجعية يتم تخزينها في الـ«هياب». يُعلن عن المصفوفة باستخدام النوع متبوعًا بأقواس مربعة، مع ترقيم الفهرس بدءًا من الصفر.

▶ مثال

CSHARP
int[] nums1 = new int[5];
int[] nums2 = new int[5] { 10, 20, 30, 40, 50 };
int[] nums3 = { 1, 2, 3, 4, 5 };
string[] names = { "Alice", "Bob", "Carol" };

Console.WriteLine(nums1[0]);
Console.WriteLine(nums2[2]);
Console.WriteLine(nums3.Length);
Console.WriteLine(names[1]);
▶ جرّب الكود
TEXT 📖 للعرض فقط
0
30
5
Bob

تحذير: تقوم الدالة new int[5] بإنشاء مصفوفة يتم تهيئة عناصرها تلقائيًا بالقيم الافتراضية (0 لنوع int، وnull لنوع string).


2. الوصول إلى الفهرس والتحقق من الحدود

يتم الوصول إلى المصفوفات في لغة C# عن طريق الفهرس، ويقوم محرك التشغيل بفحص حدود المصفوفة. ويؤدي استخدام فهرس خارج النطاق إلى إثارة استثناء IndexOutOfRangeException، على عكس السلوك غير المحدد في لغة C.

▶ مثال

CSHARP
int[] nums = { 10, 20, 30, 40, 50 };

nums[0] = 99;
Console.WriteLine(nums[0]);
Console.WriteLine(nums[nums.Length - 1]);

try
{
    int val = nums[5];
}
catch (IndexOutOfRangeException)
{
    Console.WriteLine("Index out of range!");
}
▶ جرّب الكود
TEXT 📖 للعرض فقط
99
50
Index out of range!

نصيحة: استخدم الخاصية Length للحصول على طول المصفوفة، بدلاً من sizeof كما هو الحال في لغة C.


3. الطرق الشائعة لفئة المصفوفات

توفر فئة Array طرقًا ثابتة للفرز، والعكس، والبحث، والنسخ، وغيرها.

▶ مثال

CSHARP
int[] nums = { 5, 3, 8, 1, 9, 2 };

Array.Sort(nums);
Console.WriteLine(string.Join(", ", nums));

Array.Reverse(nums);
Console.WriteLine(string.Join(", ", nums));

int idx = Array.IndexOf(nums, 8);
Console.WriteLine(idx);

int[] copy = new int[3];
Array.Copy(nums, copy, 3);
Console.WriteLine(string.Join(", ", copy));

Array.Clear(nums, 0, 2);
Console.WriteLine(string.Join(", ", nums));

Array.Resize(ref nums, 8);
Console.WriteLine(nums.Length);
▶ جرّب الكود
TEXT 📖 للعرض فقط
1, 2, 3, 5, 8, 9
9, 8, 5, 3, 2, 1
1
9, 8, 5
0, 0, 5, 3, 2, 1
8

نصيحة: تعمل Clear على إعادة تعيين العناصر الموجودة في النطاق المحدد إلى قيمها الافتراضية بدلاً من إزالتها. أما Resize فتعمل على تغيير طول المصفوفة.


4. المصفوفات متعددة الأبعاد (المصفوفات المستطيلة)

تتميز المصفوفات متعددة الأبعاد، التي تُعرف أيضًا بالمصفوفات المستطيلة، بأن كل صف فيها له نفس الطول. استخدم الفواصل لفصل الأبعاد في الإعلان، على سبيل المثال int[,] لمصفوفة ثنائية الأبعاد.

▶ مثال

CSHARP
int[,] matrix = new int[3, 4];
matrix[0, 0] = 1;
matrix[1, 2] = 5;
matrix[2, 3] = 9;

int[,] grid = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

Console.WriteLine(grid[0, 1]);
Console.WriteLine(grid[2, 0]);
Console.WriteLine(grid.Length);
Console.WriteLine(grid.Rank);
▶ جرّب الكود
TEXT 📖 للعرض فقط
2
7
9
2

نصيحة: يُرجع Rank عدد الأبعاد، بينما يُرجع Length العدد الإجمالي للعناصر (حاصل ضرب جميع الأبعاد).


5. المصفوفات المتقطعة

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

▶ مثال

CSHARP
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 };
jagged[1] = new int[] { 3, 4, 5, 6 };
jagged[2] = new int[] { 7, 8, 9 };

Console.WriteLine(jagged[0].Length);
Console.WriteLine(jagged[1][2]);
Console.WriteLine(jagged[2][0]);

int[][] scores = {
    new int[] { 90, 85 },
    new int[] { 78, 92, 88 },
    new int[] { 95 }
};

Console.WriteLine(scores[1][1]);
▶ جرّب الكود
TEXT 📖 للعرض فقط
2
5
7
92

تحذير: تختلف المصفوفات غير المتجاورة عن المصفوفات المستطيلة: فـ int[,] هي مصفوفة ثنائية الأبعاد متجاورة في الذاكرة، بينما int[][] هي مصفوفة أحادية البعد تتكون عناصرها من مصفوفات مستقلة.


6. تكرار المصفوفات باستخدام foreach

يعمل البيان foreach على تبسيط عملية مسح المصفوفة من خلال التخلص من الحاجة إلى إدارة الفهارس يدويًّا. وهو مناسب للتكرار في وضع القراءة فقط.

▶ مثال

CSHARP
string[] fruits = { "Apple", "Banana", "Orange", "Grape" };

foreach (string fruit in fruits)
{
    Console.WriteLine(fruit);
}

int[,] matrix = {
    { 1, 2, 3 },
    { 4, 5, 6 }
};

foreach (int val in matrix)
{
    Console.Write(val + " ");
}
Console.WriteLine();
▶ جرّب الكود
TEXT 📖 للعرض فقط
Apple
Banana
Orange
Grape
1 2 3 4 5 6

نصيحة: لا يمكنك تعديل عناصر المصفوفة داخل حلقة foreach. استخدم حلقة for إذا كنت بحاجة إلى تغيير القيم.


7. المصفوفات كمعلمات للطرق

المصفوفات هي أنواع مرجعية، لذا فإن تمرير مصفوفة إلى دالة يعني تمرير المرجع. وتؤثر التعديلات التي تُجرى على عناصر المصفوفة داخل الدالة على المصفوفة الأصلية.

▶ مثال

CSHARP
void PrintArray(int[] arr)
{
    foreach (int n in arr)
    {
        Console.Write(n + " ");
    }
    Console.WriteLine();
}

void DoubleValues(int[] arr)
{
    for (int i = 0; i < arr.Length; i++)
    {
        arr[i] *= 2;
    }
}

int[] nums = { 1, 2, 3, 4, 5 };
PrintArray(nums);
DoubleValues(nums);
PrintArray(nums);

int Sum(int[] arr)
{
    int total = 0;
    foreach (int n in arr)
    {
        total += n;
    }
    return total;
}

Console.WriteLine(Sum(nums));
▶ جرّب الكود
TEXT 📖 للعرض فقط
1 2 3 4 5
2 4 6 8 10
30

تحذير: نظرًا لأن المصفوفات تُمرَّر بالرجوع، فإن التغييرات التي أجراها DoubleValues تنعكس مباشرةً على مصفوفة المُستدعي.


❓ أسئلة شائعة

س كيف تختلف المصفوفات في لغة C# عن المصفوفات في لغة C؟
ج المصفوفات في لغة C# هي أنواع مرجعية مزودة بآلية مدمجة للتحقق من الحدود، والتي تُطلق استثناءات عند الوصول إلى قيم خارج النطاق؛ أما المصفوفات في لغة C فتستخدم صيغة المؤشرات، ويُعتبر الوصول إلى قيم خارج النطاق سلوكًا غير مُعرَّف.
س ما الذي ترجعه خاصيتا «Length» و«Rank»؟
ج ترجع خاصية «Length» العدد الإجمالي للعناصر، بينما ترجع خاصية «Rank» عدد الأبعاد.
س متى ينبغي عليّ استخدام المصفوفة المتقطعة (jagged array) مقابل المصفوفة متعددة الأبعاد؟
ج استخدم المصفوفات متعددة الأبعاد عندما يكون طول كل صف واحدًا للحصول على تخطيط أكثر إيجازًا؛ واستخدم المصفوفات المتقطعة عندما تكون أطوال الصفوف مختلفة.
س هل يمكن لـ foreach تعديل عناصر المصفوفة؟
ج لا، فـ foreach هي عملية تكرار للقراءة فقط. استخدم حلقة for إذا كنت بحاجة إلى تعديل قيم العناصر.
س هل تؤدي دالة Array.Resize إلى إنشاء مصفوفة جديدة؟
ج نعم، تؤدي دالة Resize إلى إنشاء مصفوفة جديدة ونسخ العناصر إليها، مما يؤدي إلى استبدال مرجع المصفوفة الأصلية.

📖 ملخص

📝 تمارين

  1. قم بتعريف مصفوفة مكونة من 10 أعداد صحيحة، وقم بتعيين القيم من 1 إلى 10 باستخدام حلقة، ثم اطبع جميع العناصر بترتيب عكسي
  2. استخدم Array.Sort لترتيب مصفوفة سلاسل أبجديًّا، ثم اطبع النتيجة
  3. أنشئ مصفوفة ثنائية الأبعاد من الأعداد الصحيحة بحجم 3×3، واحسب مجموع العناصر الموجودة على القطر واطبع النتيجة
  4. أنشئ مصفوفة غير منتظمة تخزن درجات 3 طلاب (لكل منهم عدد مختلف من المواد)، ثم احسب متوسط الدرجات لكل طالب
  5. اكتب دالة int FindMax(int[] arr) تقبل مصفوفة وتُرجع القيمة الأقصى
Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%