Масиви та цикл foreach, Доступне для всіх програмування

Ну ось ми і підбираємося до фундаменту C#. Сьогодні ми поговоримо з вами про таку структуру даних, як масив і завершимо серію уроків за циклами останнім їх представником — цикломдля кожного (foreach).

Якщо ви практикувалися в програмуванні, то, напевно, могли звернути увагу на те, що часом кілька змінних одного типу набагато зручніше було б об'єднати в деяку кількість. Наприклад, у програмі потрібно обробляти прізвища класу, групи чи колег по роботі.

Безперечно, можна спокійно оголошувати змінні в такій кількості, скільки вони знадобляться. У вас є тридцять співробітників? Зробимо тридцять змінних, що нам це варте. 300 співробітників? Важко, але не біда. 3000? Якого хрону я прийшов на цю безглузду роботу, скажете ви і кинете цей код :).

Я не випадково випередив тему про масиви циклами. Зараз ви зрозумієте, для чого я це зробив.

Отже, повернемося до нашого багатостраждального завдання про співробітників. Припустимо, нам потрібно буде вести список усіх співробітників на прізвища. Знаючи про цикли, ми можемо легко автоматизувати введення цих прізвищ. Нам просто потрібно буде оголошувати змінні для їхнього зберігання. Але тут ми зіткнемося з одним але. Цикл лише автоматизує ділянку коду, а нам потрібно буде зробити так, щоб прізвища зберігалися в різних змінних, інакше ми ризикуємо переписувати їх багаторазово і не впорається із завданням. Ми могли б зробити так:

Як бачите, цикл сам напрошується собою. Ми могли б занести в тіло циклу введення прізвища і виведення напису про те, що потрібно ввести це прізвище. Однак у нашому прикладі ми маємо п'ять змінних. Якщо ми ставитимемо одну з цих змінних у цикл, то нічого в нас не вийде (спробуйте самі).

Чи не здаєтьсявам, що набагато простіше буде зробити абстрактну змінну, припустимо sotr, і прирощувати до неї по одиниці? Адже в нас питання одразу вирішиться.

На жаль, тими засобами, що ми зараз знаємо, це не можна зробити. І тут нам доведеться скористатисямасивами.

Що таке масив? Це набір елементів одного типу, що має спільне ім'я. Так як це набір елементів, то до кожного елемента, що входить до масиву можна звернутися за його індексом.

Синтаксис масиву C# трохи відрізняється від C або C++. Справа в тому, що на C # потрібно не тільки оголосити масив, але і виділити для нього пам'ять.

Давайте поясню, що це означає. Пам'ятайте, я казав, що змінні в C# зберігаються в стеку, а об'єкти — у купі (або хіпі, хто звик). Стек зручний та швидкий, але за цю зручність потрібно розплачуватися. Такою платою є обмежений розмір стека. Якщо ми запхнемо в стек великі структури даних, ми отримаємо улюблений хакерами stack overflow або переповнення стека. Щоб цього не сталося, масиви та об'єкти поміщають у купу, що є чимось іншим як оперативною пам'яттю комп'ютера.

У C++ (як і в C) масив майже те саме, як і покажчик. Це означає, що масив автоматично розміщується в купі, хоча там також можна створювати динамічні масиви.

У C# покажчики хоч і є, але код з ними вважається небезпечним і пов'язаний з деякими труднощами компіляції (потрібно буде "переконати" ваше середовище розробки в тому, що код можна запускати. Про це ми поговоримо в окремому уроці). Тому для масиву із зазначених вище причин необхідно виділяти пам'ять.

тип_даних [] ім'я_масиву;

Зверніть увагу на квадратні дужки - вони якраз і вказують C # про те, що це масив. Як типи даних можутьвиступати і користувальницькі, такі як структури та об'єкти, але про них поговоримо в інших уроках.

Ми оголосили масив, але користуватися ним ще не можемо. Щоб почати його використовувати нам потрібно виділити пам'ять. Робиться це так:

new string [розмір_масиву];

Не хочу цей урок робити надто довгим, тому можу сказати, що це одномірний масив. Є ще й двовимірний, і тривимірний, і так званий зубчастий масив, розріджений масив і т. д. Про деякі ми поговоримо в іншому уроці. Але зазвичай застосовуються максимум двовимірні масиви.

Доступ до елементів масиву здійснюється за індексом, причому його відлік починається з 0. Однак, перш ніж звернутися до елемента масиву, його потрібно туди помістити. Зробити це можна двома способами: при ініціалізації та при явному присвоєнні елементу масиву потрібного значення. Погляньмо, як це робиться.

Масив можна оголошувати під час ініціалізації. Цей спосіб дуже зручний, коли ми знаємо наперед кількість елементів масиву та його склад. Наприклад, наш список співробітників виглядатиме приблизно таким чином:

Ми отримаємо масив із п'яти елементів, що містять прізвища співробітників. Таким чином часто корисно створювати масиви при написанні методів перетворення чисел на малі еквіваленти (особливо це актуально при написанні бухгалтерських програм) і т.п.

Проте досить часто масиви бувають просто величезними за своєю структурою. Уявіть собі ініціалізацію масиву, який потрібно внести 1000 або 10000 прізвищ. Уявляєте розмір коду?

Набагато простіше буде вносити дані до масиву традиційним способом – поелементно. У цьому випадку нам потрібно буде створити масив та вносити до нього потрібні дані.

Добре, скажете ви, але в чому вигода масиву? Адже ми могли10 разів написати різні змінні з потрібними прізвищами і завдання було б виконано. Крім того, забігаючи кілька вперед, скажу, що попередній фрагмент можна назватикитайським кодом. Звичайні програмісти так не пишуть.

Що дає нам масив? Тепер ми можемо маніпулювати його елементами у циклі, звертаючись за індексом. А це означає, що тепер ми можемо відсортувати вміст масиву і т.д.

Дивіться, як тепер можна ввести дані про співробітників масив, використовуючи цикл.

Вставте цей код у метод Main та запустіть його на компіляцію. Бачите, наскільки гнучкіший цей підхід? Ми перекладаємо завдання щодо наповнення масиву вже на користувача програми і він може вносити туди буквально все (особливо, в нашій програмі, в якій геть відсутні перевірки введення даних :)) Потім ми можемо написати метод, який запише наш масив у файл і потім вже з його зчитувати при запуску програми. Але про це в інших уроках.