Масиви в C

Статті про IT, програмування, політику, економіку, життя та вивчення наукових дисциплін

Масиви в C++

У разі використання простих змінних кожної області пам'яті для зберігання даних відповідає своє ім'я. Якщо з групою величин однакового типу потрібно виконувати однакові дії, їм дають одне ім'я, а розрізняють за порядковим номером. Це дозволяє компактно записувати безліч операцій із допомогою циклів.Кінцева іменована послідовність однотипних величин називається масивом.

Опис масиву в програмі відрізняється від опису простою змінною наявністю після імені квадратних дужок, в яких задається кількість елементів масиву (розмірність):

float а [10]; // Опис масиву з 10 дійсних чисел

Елементи масиву нумеруються з нуля. При описі масиву використовуються самі модифікатори (клас пам'яті, const і ініціалізатор), що й у простих змінних. Ініціалізують значення для масивів записуються у фігурних дужках. Значення елементам надаються по порядку. Якщо елементів у масиві більше, ніж ініціалізаторів, елементи, для яких значення не вказані, обнуляються:

int b [5] = < 3, 2, 1 >; // b [0] = 3, b [l] = 2, b [2] = l, b [3] = 0, b [4] = 0

Розмірність масиву разом з типом його елементів визначає обсяг пам'яті, необхідний для розміщення масиву, яке виконується на етапі компіляції, тому розмірність може бути задана цілою позитивною константою або константним виразом. Якщо при описі масиву не вказано розмірність, повинен бути ініціалізатор, у цьому випадку компілятор виділить пам'ять за кількістю значень, що ініціалізують. Надалі ми побачимо, що розмірність може бути опущена також усписок формальних параметрів.

Для доступу до елемента масиву після його імені вказується номер елемента (індекс) у квадратних дужках. У наступному прикладі підраховується сума елементів масиву.

#include int main ( ) < const int n = 10; int i,. sum; int marks [n] = < 3, 4, 5, 4, 4 >; for (i = 0, sum = 0; i n; i ++) sum + = marks [1]; cout "Сума елементів:" sum; return 0; >

Розмірність масивів краще задавати за допомогою іменованих констант, як це зроблено в прикладі, оскільки при такому підході для її зміни достатньо скоригувати значення константи лише в одному місці програми. Зверніть увагу, що останній елемент масиву має номер, на одиницю менший від заданої при його описі розмірності.

приклад. Сортування цілого масиву шляхом вибору. Алгоритм полягає в тому, що вибирається найменший елемент масиву і змінюється місцями з першим елементом, потім розглядаються елементи, починаючи з другого, і найменший з них змінюється місцями з другим елементом, і так далі n-1 раз (при останньому циклі проходу при необхідності змінюються місцями передостанній та останній елементи масиву).

int а [100], b [100]: int * ра = а; // або int *р = &а[0]; int * pb = b; for ( int i = 0 ; i 100 ; i ++ ) * pb ++ => * pa ++; // чи pb[1] = pa[1];

Динамічні масиви

Динамічні масиви створюють за допомогою операції new, при цьому необхідно вказати тип та розмірність, наприклад:

int п = 100: float * р = new float [n];

Перевага динамічних масивів у тому, що розмірність то, можливо змінної, тобто обсяг пам'яті, виділеної під масив, визначається етапі виконання програми. Доступ доелементам динамічного масиву здійснюється точно так, як до статичних, наприклад, до елемента номер 5 наведеного вище масиву можна звернутися як р[5] або *(р+5).

Альтернативний спосіб створення динамічного масиву - використання функції mallос бібліотеки С:

int n = 100; float * q = (float *) malloc (n * sizeof (float));

Операція перетворення типу, записана перед зверненням до функції mallос, потрібна тому, що функція повертає значення вказівника тину void*, а ініціалізується покажчик на float.

Пам'ять, що зарезервована під динамічний масив за допомогою new [], повинна звільнятися оператором delete [], а пам'ять, виділена функцією mallос - за допомогою функції free, наприклад:

delete [] р; free (q);

При невідповідності способів виділення та звільнення пам'яті результат не визначено. Розмір масива в операції delete не вказується, але квадратні дужки обов'язкові.

Багатовимірні масиви

Багатовимірні масиви задаються вказівкою кожного вимірювання у квадратних дужках, наприклад, оператор

int matr [6] [8];

При ініціалізації багатовимірного масиву він представляється або як масив з масивів, при цьому кожен масив полягає у свої фігурні дужки (у цьому випадку ліву розмірність при описі можна не вказувати), або задається загальний список елементів у тому порядку, в якому елементи знаходяться в пам'яті:

int mass2 [] [2] = < < 1 , 1 >, < 0 , 2 >, < 1 , 0 >> : int mass2 [3] [2] =

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

Для створення динамічного багатовимірного масиву необхідно вказати в операції все йогорозмірності (найліва розмірність може бути змінною), наприклад:

int nstr = 5 : int ** m = ( int ** ) new int [ nstr ] [ 10 ] ;

Більш універсальний та безпечний спосіб виділення пам'яті під двомірний масив, коли обидві його розмірності задаються на етапі виконання програми, наведено нижче:

int nstr, nstb; cout "Введіть кількість рядків і стовпців:"; cin >> nstr >> nstb; int ** a = new int * [nstr]; // 1 for (int i = 0; i nstr; i ++) // 2 a [i] = new int [nstb]; // 3 .

елементів
Звільнення пам'яті з-під масиву з будь-якою кількістю вимірювань виконується за допомогою операції delete [ ] . Покажчик на константу видалити не можна.

Рядки як масиви символів

Рядок є масивом символів, що закінчується нуль-символом. Нуль-символ - це символ з кодом, що дорівнює О, що записується у вигляді керуючої послідовності '\0'. За положенням нуль-символу визначається фактична довжина рядка. Рядок можна ініціалізувати рядковим літералом.

char str [10] = "Vasia"; // виділено 10 елементів з номерами від 0 до 9 // перші елементи - 'V', 'а', 's', 'i', 'а', '\0'

У цьому прикладі під рядок виділяється 10 байт, 5 із яких зайнято під символи рядка, а шостий - під нуль-символ. Якщо рядок при визначенні ініціалізується, його розмір можна опускати (компілятор сам виділить відповідну кількість байт):

char str[] = "Vasia"; // виділено та заповнено 6 байт

char * str = "Vasia"

створює не рядкову змінну, а покажчик на рядкову константу, змінити яку неможливо (наприклад, оператор str[l]='o' не допускається). Знак рівності перед рядковим літералом означає ініціалізацію, а чи не привласнення. Операція присвоєнняодного рядка іншого не визначено (оскільки рядок є масивом) і може виконуватися за допомогою циклу або функції стандартної бібліотеки. Бібліотека надає можливості копіювання, порівняння, об'єднання рядків, пошуку підрядка, визначення довжини рядка і т.д., а також містить спеціальні функції введення рядків та окремих символів з клавіатури та файлу.

Під час роботи з рядками часто використовуються покажчики.

Існує кілька способів роботи з рядками (через масиви чи покажчики) і вони мають свої плюси та мінуси, але в загальному випадку краще не винаходити велосипед, а користуватися функціями бібліотеки або визначеним у стандартній бібліотеці C++ класом string, який забезпечує індексацію, привласнення, порівняння, додавання, об'єднання рядків і пошук підрядків, а також перетворення з С-рядків, тобто масивів типу char, string, і навпаки.

За матеріалами книги Т.А. Павловській «С++++. Програмування мовою високого рівня».