مقدمه

در برنامه‌نویسی، گاهی اوقات نیاز داریم مجموعه‌ای از داده‌های مرتبط را ذخیره کنیم. در چنین شرایطی بهتر است به‌جای تعریف تعداد زیادی از متغیرها، از ساختارهای کالکشنال استفاده کنیم که به ما امکان می‌دهند چندین مقدار را در قالب فقط یک متغیر ععریف و ذخیره کنیم. آرایه‌ها (Arrays) مرسوم‌ترین و پرکاربردترین ساختار کالکشنال در زبان‌های برنامه‌نویسی هستند. در C# یک آرایه می‌تواند چندین مقدار هم‌نوع را ذخیره کند. در این درس به جزئیات مربوط به آرایه‌ها در C# می‌پردازیم.

تعریف آرایه در C#

یک آرایه در زبان C# ساختاری است که می‌تواند تعداد مشخص و ثابتی از مقادیر هم‌نوع را ذخیره کند. فرض کنید بخواهیم نمرات 5 دانش‌آموز را ذخیره کنیم. به‌جای تعریف 5 متغیر، می‌توانیم یک آرایه تعریف کنیم که 5 مقدار از نوع double را نگه دارد.

Copy Icon Program.cs
double[] scores = new double[5];

اینجا ما یک آرایه با نام scores داریم که می‌تواند 5 مقدار از نوع double را ذخیره کند. اگر بخواهیم این مقادیر را در زمان تعریف آرایه به آن اختصاص دهیم، مانند زیر عمل می‌کنیم.

Copy Icon Program.cs
double[] scores = new double[] { 10.5, 8.0, 9.5, 7.0, 6.5 };

البته این کار را به فرم خلاصه‌تری که در زیر می‌بینید هم می‌توان انجام داد.

Copy Icon Program.cs
double[] scores = { 10.5, 8.0, 9.5, 7.0, 6.5 };

دسترسی به عناصر آرایه

برای دسترسی به عناصر آرایه از اندیس (index) عناصر استفاده می‌شود. عناصر آرایه با شروع از صفر اندیس‌گذاری می‌شوند. ینابراین برای دسترسی به عنصر n-ام باید از اندیس n - 1 استفاده کرد. به مثال زیر توجه کنید.

Copy Icon Program.cs
double[] scores = {10.5, 8.0, 9.5, 7.0, 6.5};

Console.WriteLine(scores[0]); // 10.5
Console.WriteLine(scores[1]); // 8.0

scores[2] = 11.0; 
Console.WriteLine(scores[2]); // 11.0

پیمایش آرایه با حلقه

از آنجایی که آرایه‌ها مجموعه‌ای از عناصر هستند، برای پردازش تمام عناصر می‌توان از حلقه استفاده کرد. در C# متداول‌ترین روش استفاده از for یا foreach است. حلقه‌ی for زمانی مناسب است که به شماره‌ی اندیس نیاز داشته باشید. اما اگر فقط می‌خواهید روی عناصر آرایه حرکت کنید بدون اینکه اندیس آن‌ها مهم باشد، حلقه‌ی foreach خواناتر است.

Copy Icon Program.cs
double[] scores = {10.5, 8.0, 9.5, 7.0, 6.5};

for (int i = 0; i < scores.Length; i++)
{
    Console.WriteLine($"score {i + 1}: {scores[i]}");
}

foreach (double score in scores)
{
    Console.WriteLine($"score: {score}");
}

ویژگی‌های آرایه‌ها

آرایه‌ها در C# ویژگی‌های خاصی دارند که باید حتماً به آن‌ها توجه داشته باشید. اولین ویژگی این است که طول آرایه ثابت است، یعنی پس از تعریف، نمی‌توان به آن عنصر جدید اضافه کرد یا از آن کم کرد. ویژگی دوم، نوع یکنواخت است. یعنی اگر آرایه‌ای از نوع string تعریف کرده باشید، نمی‌توانید مقدار int یا bool در آن قرار دهید. این محدودیت‌ها باعث می‌شود که آرایه‌ها سریع و بهینه باشند، اما در عین حال انعطاف‌پذیری محدودتری نسبت به ساختارهایی مثل List داشته باشند که دز آینده با آنها آشنا خواهیم شد.

یک مثال عملی: محاسبه میانگین نمرات

در این مثال عملی، آرایه‌ای از نمرات تعریف می‌کنیم، سپس با استفاده از یک حلقه‌ی for، مجموع آن‌ها را محاسبه کرده و در پایان میانگین را چاپ می‌کنیم. این مثال ساده و کاربردی نشان می‌دهد که چگونه می‌توان با آرایه‌ها عملیات آماری انجام داد.

Copy Icon Program.cs

int[] grades = {85, 90, 78, 92, 88};
int sum = 0;

int i = 0; i < grades.Length; i++)
{
    sum += grades[i];
}

double average = (double)sum / grades.Length;
Console.WriteLine($"average : {average}");
                    

کلاس System.Array

در C# آرایه‌ها یک ساختار داده‌ی ساده نیستند، بلکه اشیائی از نوع System.Array هستند. این کلاس، مجموعه‌ای از متدها (methods) و پراپرتی‌ها (properties) را فراهم می‌کند که به شما امکان می‌دهد تا عملیات مختلفی مثل مرتب‌سازی، جستجو، کپی‌کردن، معکوس‌کردن و غیره را روی آرایه‌ها انجام دهید.

هر آرایه فارغ از اینکه از نوع int[] یا string[] یا هر نوع دیگری باشد، یک شیء از کلاس System.Array محسوب می‌شود. به همین دلیل است که کد زیر مجاز محسوب می‌شود.

Copy Icon Program.cs
int[] numbers = {10, 20, 30, 40, 50};
Array array = numbers;

اما موضوع مهم‌تر این است که ما می‌توانیم از متدها و پراپرتی‌های کلاس System.Array استفاده کنیم. در ادامه، تعداادی از مهمترین متدهای این کلاس را بررسی می‌کنیم.

متد Array.Sort()

متد Array.Sort() برای مرتب‌سازی عناصر یک آرایه استفاده می‌شود. این متد به صورت پیش‌فرض عناصر را به ترتیب صعودی مرتب می‌کند. در زیر یک مثال از استفاده از این متد آورده شده است.

Copy Icon Program.cs
int[] numbers = {5, 2, 8, 1, 4};
Array.Sort(numbers);
foreach (int number in numbers)
{
    Console.WriteLine(number);
}

در این مثال، آرایه‌ای از اعداد تعریف شده و سپس با استفاده از متد Array.Sort() مرتب‌سازی می‌شود. در نهایت، با استفاده از حلقه‌ی foreach، عناصر مرتب‌شده چاپ می‌شوند.

متد Array.Reverse()

متد Array.Reverse() برای معکوس کردن عناصر یک آرایه استفاده می‌شود. این متد به سادگی ترتیب عناصر آرایه را معکوس می‌کند. در زیر یک مثال از استفاده از این متد آورده شده است.

Copy Icon Program.cs
int[] numbers = {1, 2, 3, 4, 5};
Array.Reverse(numbers);
foreach (int number in numbers)
{
    Console.WriteLine(number);
}

در این مثال، آرایه‌ای از اعداد تعریف شده و سپس با استفاده از متد Array.Reverse() معکوس می‌شود. در نهایت، با استفاده از حلقه‌ی foreach، عناصر معکوس‌شده چاپ می‌شوند.

با استفاده از ترکیبی از دو متد Sort() و Reverse() می‌توانیم ترتیبی دهیم که عناصر آرایه به صورت نزولی مرتب شوند.

متد Array.IndexOf()

متد Array.IndexOf() برای پیدا کردن اندیس یک عنصر خاص در آرایه استفاده می‌شود. این متد اولین اندیس را که عنصر مورد نظر در آن قرار دارد، برمی‌گرداند. اگر عنصر در آرایه وجود نداشته باشد، مقدار -1 برمی‌گرداند. در زیر یک مثال از استفاده از این متد آورده شده است.

Copy Icon Program.cs
int[] numbers = {1, 2, 3, 4, 5};
int index = Array.IndexOf(numbers, 3);
Console.WriteLine(index); // 2
Console.WriteLine(Array.IndexOf(numbers, 6)); // -1

در اینجا دستور چاپ اول منجر به نمایش عدد 2 می‌شود، چون مقدار 3 برای اولین بار در اندیس 2 قرار دارد. اما دستور چاپ دوم باعث نمایش عدد -1 می‌شود، چون مقدار 6 در آرایه وجود ندارد.

آرایه‌های چند بعدی

آرایه‌های یک بعدی برای ذخیره لیستی از مقادیر کافی هستند اما اگر بخواهیم داده‌های ماتریسی، جدولی یا هر داده‌ای که ماهیت چند بعدی دارد، ذخیره کنیم، به آرایه‌های چند بعدی نیاز پیدا می‌کنیم. در زیر یک آرایه دو بعدی ایجاد شده که شامل سه سطر و چهار ستون است و می‌تواند 12 عدد صحیح را در ساختار ماتریسی ذخیره کند.

Copy Icon Program.cs
int[,] matrix = new int[3, 4];

اگر بخوایهم هنگام تعریف آرایه، آن را مقدادهی هم بکنیم، به صورت زیر عمل می‌کنیم.و

Copy Icon Program.cs
int[,] matrix = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };

در یک ماتریس، هر عنصر دارای دو اندیس است که اولی نمایانگر سطر و دومی نمایانگر ستونی است که عنصر به آن تعلق دارد. بنابراین، برای دسترسی به عناصر یک آرایه دو بعدی به صورت زیر عمل می‌کنیم.

Copy Icon Program.cs
int[,] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
Console.WriteLine(matrix[0, 0]);  // 1
Console.WriteLine(matrix[1, 2]);  // 7
Console.WriteLine(matrix[2, 3]);  // 12

پیمایش روی آرایه‌های چند بعدی

برای پیمایش روی عناصر |آرایه‌های یک بعدی از حلقه‌ها استفاده کردیم. به همین ترتیب، برای پیمایش روی آرایه‌های چند بعدی باید از حلقه‌های تودرتو شده استفاده کنیم. مثال زیر را ببینید.

Copy Icon Program.cs
int[,] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };

for (int i = 0; i < matrix.GetLength(0); i++)
    {
        for (int j = 0; j < matrix.GetLength(1); j++)
        {
            Console.Write(matrix[i, j] + " ");
        }
        Console.WriteLine();
    }

متد GetLength(n) طول بعد n-ام را برمی‌گرداند. یعنی GetLength(0) طول بعد صفرم یا همان تعداد سطرها را برمی‌گرداند و GetLength(1) طول بعد یکم یا همان تعداد ستون‌هار را برمی‌گرداند.