ما بعضی وقتها در شرایطی قرار میگیریم که نیاز داریم تا چند متغیر از یک نوع را استفاده کنیم و یک عملیات یکسان را روی تک تک آنها اجرا کنیم. تصور کنید اگر به صدها متغیر یا حتی بیشتر نیاز داشته باشیم، می توانیم روی این واقعیت توافق کنیم که ایجاد صد متغیر از یک نوع، یک راه حل نیست.
خوشبختانه، #c یک نوع خاص به نام آرایه را در اختیار ما قرار میدهد.
این مقاله، سرفصلی از دوره آموزشی زیر میباشد:
- راه اندازی محیط توسعه
- Data Type ها، Declaration ها و تعریف متغیرها در #C
- عملگرها در #c
- تبدیل نوع های داده ای
- ورودی و خروجی در #c
- کار با رشته ها
- شرطها در #c
- حلقه ها (While، Do-While، For)
- مدیریت خطاها
- Access Modifier ها
- متدها
- کلمات کلیدی Ref و Out
- بازگشت و متدهای بازگشتی
- آرایه ها (آرایه های تک بعدی و چند بعدی)
- کار با فایلها، StreamWriter و StreamReader
- کار با فایلها، File و Directory
اگر می خواهید محتویات کامل این دوره را ببینید ، می توانید بر روی لینک مبانی #c کلیک کنید.
برای دانلود سورس، بر روی لینک سورس آرایه ها در #c کلیک کنید.
آرایه ها، نوع های داده ای reference هستند که شامل داده هایی از یک نوع میباشند و به ترتیب در یک مجموعه متوالی کنار یکدیگر قرار میگیرند. ما می توانیم با بیان نام آرایه و موقعیت داده ها در آرایه، به هر اطلاعاتی در داخل آرایه دسترسی داشته باشیم. به موقعیت داده ها در آرایه، Index گفته میشود. در آرایه ها، Index ها از صفر شروع میشوند. این به این معنی است که اولین المنت، در index صفر ذخیره میشود و آخرین المنت در index با موقعیت مکانی 1 واحد کمتر از طول آرایه (array Length – 1) ذخیره میشود. به فرض مثال، اگر آرایه ما 5 المنت داشته باشد در نتیجه، index ها از 0 تا 4 مورد خطاب قرار میگیرند.
این مقاله شامل عناوین زیر میباشد:
تعریف و مقداردهی آرایه
برای تعریف آرایه، ما نوع آرایه، سپس براکت مربعی و در آخر نام آرایه را بیان میکنیم:
1 2 |
int[] numbers; Pen[] pens; |
نکته ای که باید بدانید این است که مهم نیست که شما داخل آرایه، داده های reference type ذخیره میکنید یا value type. چرا که آرایه همیشه از نوع reference type است.
برای مقداردهی آرایه مان، ما باید از یک کلمه کلیدی new، سپس نوع داده ای مورد نظر و در آخر داخل براکت مربعی، ظرفیت آرایه را مشخص میکنیم:
1 2 |
numbers = new int[5]; pens = new Pen[5]; |
در اولین خط بالا، ما نوع int (value type) را داخل آرایه اعداد ذخیره میکنیم، بنابراین در حافظه، فضا را برای 5 integer رزرو میکنیم. اما در خط دوم، ما فضا را برای 5 آیتم از نوع pen (از نوع reference type) در حافظه مان رزرو میکنیم، بنابراین ما مقادیرشان را ذخیره نمیکنیم بلکه رفرنسهایشان را ذخیره میکنیم. تمام مقادیر Pen در حال حاضر اینجا برابر با null هستند.
تا به الان، ما حافظه را برای مقادیر موردنظرمان تخصیص دادیم اما در واقع هنوز آنها را به آرایه اضافه نکرده ایم. بنابراین برای پایان دادن به فرآیند مقداردهی، ما باید مقادیر را به آرایه هایمان اضافه کنیم. رایجترین شیوه، تعریف، تخصیص و مقداردهی آرایه در یک خط کد میباشد:
1 2 |
int[] arrayExample = new int[5] { 4, 5, 7, 8, 3}; Pen[] penArrayExample = new Pen[3] { new Pen(Color.Red), new Pen(Color.Green), new Pen(Color.Blue) }; |
ما همچنین از index ها میتوانیم برای پرکردن یک آرایه نیز استفاده کنیم:
1 2 |
int[] numbers = new int[2]; numbers[0] = 5; numbers[1] = 7; |
پیمایش آرایه
برای پیمایش یک آرایه، ما از یک حلقه for استفاده میکنیم. با یک حلقه for، ما از index ها برای دسترسی به هر المنت در آرایه استفاده میکنیم:
1 2 3 4 5 6 7 8 9 |
static void Main(string[] args) { int[] numbers = new int[5] { 4, 5, 7, 8, 3}; for(int i = 0; i < numbers.Length; i++) { Console.WriteLine(numbers[i]); } } |
ما همین کار را میتوانیم با حلقه foreach
انجام دهیم. تفاوت بین این دو رویکرد این است که در حلقه for، ما از index ها برای دستیابی به المنتها استفاده میکنیم (متغیر i). اما در حلقه foreach، ما از index ها استفاده نمیکنیم بلکه از مقادیر واقعی آیتمهای آرایه استفاده میکنیم:
1 2 3 4 5 6 7 8 9 |
static void Main(string[] args) { int[] numbers = new int[5] { 4, 5, 7, 8, 3}; foreach(int i in numbers) { Console.WriteLine(i); } } |
مثالها
یک برنامه بنویسید که در آن یک آرایه متشکل از n المنت را ایجاد کند، سپس آرایه را با اعداد صحیح تصادفی پر کند و در آخر تمام آن اعداد را به همراه جمع تمام آنها چاپ نماید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
class Program { //array is a reference type so every action in this method will affect original array public static void PopulateArray(int[] numbers) { Random r = new Random(); for(int i = 0; i < numbers.Length; i++) { numbers[i] = r.Next(1, 101); Console.WriteLine($"The {i+1}. element is {numbers[i]}"); } } public static void CalculateSum(int[] numbers) { int sum = 0; foreach (int i in numbers) { sum += i; } Console.WriteLine($"The sum of all the elements is {sum}"); } static void Main(string[] args) { Console.WriteLine("Enter an array capacity: "); int capacity = Convert.ToInt32(Console.ReadLine()); int[] numbers = new int[capacity]; PopulateArray(numbers); Console.WriteLine(); CalculateSum(numbers); Console.ReadKey(); } } |

آرایه های پارامتری
یک آرایه پارامتری، یک تعداد متغیری از آرگومانها را به متد پاس میدهد. برای ایجاد یک آرایه پارامتری، زمانیکه پارامترها را برای متدمان مشخص میکنیم باید کلمه کلیدی params را در آن قرار دهیم:
1 2 3 4 |
public static void TestMethod(params int[] numbers) { //method body } |
تاثیر کلمه params این است که اجازه میدهد بدون آنکه یک آرایه ایجاد کنیم بتوانیم هر تعداد آرگومان را که خواستیم به پارامتر متد بفرستیم:
1 2 3 4 |
static void Main(string[] args) { TestMethod(1, 2, 3); } |
اگرچه یک آرایه پارامتری خیلی مفید است، هنوز هم در حین کار با آنها، محدودیتهایی داریم:
- ما نمیتوانیم از کلمه کلیدی params برای تعریف آرایه دوبعدی استفاده کنیم.
- Method overloading منحصرا با کلمه params امکان پذیر نیست.
- ما نمیتوانیم کلمات کلیدی ref یا out را با آرایه های params به کار ببریم.
- یک آرایه پارامتری باید آخرین پارامتر در متدمان باشد.
- یک متد بدون params همیشه نسبت به متدهای شامل params اولویت دارند.
مثال 2: یک برنامه بنویسید که کوچکترین عدد بین اعداد ارسال شده به متد PrintMin را در خروجی چاپ کند:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Program { public static void PrintMin(params int[] numbers) { int min = numbers[0]; for(int i=1; i < numbers.Length; i++) { if(min > numbers[i]) { min = numbers[i]; } } Console.WriteLine(min); } static void Main(string[] args) { PrintMin(49, 58, 12, 98, 47, 13); Console.ReadKey(); } } |
آرایه چندبعدی
ما نحوه استفاده از آرایه های تک بعدی را یاد گرفتیم. اما #c از آرایه های چندبعدی نیز پشتیبانی میکند. در این قسمت، ما در مورد آرایه های دوبعدی صحبت میکنیم. چرا به آنها دوبعدی گفته میشود؟
خب به این دلیل که آنها دارای دوبعد هستند، سطرها و ستونها. برای تعریف آرایه 2d، ما از سینتکس زیر استفاده میکنیم:
1 |
int[,] numbersMultiDim = new int[3, 2] { { 1, 5 }, { 3, 8 }, { 6, 1 } }; |
با این سینتکس، ما یک آرایه دوبعدی با 3 سطر و 2 ستون ایجاد میکنیم. بنابراین در یک شکل گرافیکی، آن به صورت زیر میباشد:

برای دسترسی به هرعدد از این آرایه، ما میتوانیم از سینتکس نام آرایه به همراه موقعیت عددی بین جفت براکت استفاده کنیم. ما موقعیت را با استفاده از index ها مشخص میکنیم. بنابراین index اولین سطر، صفر است و index آخرین سطر، (تعداد سطر – 1) میباشد. همین قضیه در مورد ستونها هم صدق میکند:
1 |
int number = numbersMultiDim[2, 1]; // value 1 => third row on index 2 and second column on index 1 |
برای پیمایش کردن تمام داده ها، ما میتوانیم از حلقه for استفاده کنیم:
1 2 3 4 5 6 7 |
for(int i = 0; i < numbersMultiDim.GetLength(0); i++) { for(int j = 0; j < numbersMultiDim.GetLength(1); j++) { Console.WriteLine(numbersMultiDim[i,j]); } } |
همانطور که میببینید ما از دو حلقه برای پیمایش یک حلقه دوبعدی استفاده میکنیم. اولین حلقه، تمام سطرها را پیمایش میکند و دومین حلقه، تمام ستونهای موجود در سطر کنونی را.
ما از آرایه های چندبعدی، زمانیکه باید داده هایمان را در شکل چندبعدی ارائه دهیم استفاده میکنیم. به خصوص، ما از آرایه های دوبعدی برای کار با جداول که شامل سطر و ستون میباشند استفاده میکنیم.
نتیجه گیری
بسیار عالی. حالا ما تمام دانش لازم برای کار با آرایه ها و استفاده از آنها در فرآیند توسعه را داریم.
در قسمت بعدی از این سری آموزش، ما در مورد کلاسهای StreamWriter و StreamReader در #c صحبت میکنیم.