На практиці часто виникає необхідність в обробці даних у вигляді довільного набору значень, тобто масивів. Масив являє собою кінцеву іменовану послідовність величин одного типу, які розрізняються за порядковим номером. Опис масивiв у програмі відрізняється від опису простої змінної наявністю після імені квадратних дужок «[ ]», в яких задається кількість елементів масиву (розмірність). Слід нагадати, що у мові C++ нумерація елементів масиву починається з 0.
Розглянемо одновимірні масиви, оголошення яких допускае одну з таких форм запису:
<тип> <ім’я> [n]; <тип> <ім’я> [n] = {значення}; <тип> <ім’я> [ ] = {значення};
При оголошенні одновимірного масиву, коли масив відразу iніціюється, можна не вказувати його розмір. Якщо ж ініціювання не здійснюється під час оголошення масиву, то кількість індексів слід задати обов’язково константним виразом. Наприклад:
float m [6];
float m [6] = {3.4, 4.5, 5.6, 6.7, 8.9, 10.3};
float m [ ] = {3.45, 4.56, 5.67, 6.78);
Зрозуміло, що надалі кількість елементів змінити неможливо. Для того щоб обнулити елементи оголошеного масиву, достатньо ініціювати його перший елемент: int mas[0]={0};.
За замовчуванням, якщо в оголошеному масиві ініціюється тільки декілька перших елементів, то його інші елементи ініціюються нулями. Так, у випадку, коли float mas[10]= {2.2,34.56};, останні вісім елементів масиву одержать значення 0.
Проiлюструємо використання одновимірних масивів на конкретних прикладах.
Приклад 6.1. Обчислити функцію у = axi2 – sinxi аргументи якої xj – елементи одновимірного масиву, що мають значення:
х0 = -0,81; x1 = -0,58; х2 = -0,11; х3 = 0,2; х4 = 0,91; x5 = 1,83.
Схему алгоритму і програмну реалізацію цієї задачі наведе по на рис. 6.1. Алгоритм передбачає введення значень одновимірного масиву xi (і = 0…n-l), n = 6 та подальше застосування їx для обчислення функції.
У програмі спочатку описується масив дійсних значень : float х[n]. Введення елементів масиву здійснюється у циклі:
[medium]http://cpp.dp.ua/uploads/posts/2015-12/1450709122_6_1.png[/medium]
Цей цикл містить операцію потокового введення cin >> x[i];, перед якою знаходиться пiдказка cout << “х[ ” << і << “] =”; для вказiвки номера елемента x[i]. Особливість виконання операцii введення cin >> x[i]; полягає в такому: зустрiвши її у програмi, комп’ютер призупинить виконання програми, поки не буде введене значення елемента х[і] і натиснута клавіша Enter, пiсля чого робота програми буде продовжена. Зазначена операцiя введення повторюється n разiв для забезпечення введення всiх елементiв масиву.
Оскільки у С++ індексація елементiв масиву починается з нуля, то масив float x[6] (n = 6) iз шести елементiв включае идексованi елементи x[0], x[1], x[2], …, x[5]. Програма (див.P6_1_1.CPP) використовуе два цикли: один – для введення масиву, інший — для обчислення функції. Операцii введення елементів масиву та обчислення значень функції можна здiйсніити в одному циклi(див. P6_1_2.СРР).
/* Р6_1_2.СРР — ввод элементов одномерного массива и вычисление функции осуществляется в одном цикле */ #include <iostream.h> #include <math.h> #include <conio.h> main ( ) { const int n = 7; float x[n], y, a(10.5); int i; for (i = 0;i< n;i++) { cin >> x[i]; //ввод елемента массива y = a * x[i] * x[i] - sin(x[i]); //--------------------------------------- вывод результата cout << " x["<<i<<"] ="<<x[i]<<" y = " << y << endl; } getch (); }
Результати обчислень:
-0.81 -0.58 -0.11 0.2 0.91 1.83
x[0] = -0.81 у = 7.61334
х[1] = -0.58 у = 4.08022
х[2] = -0.11 у = 0.236828
x[3] = 0.2 у = 0.221331
x[4] = 0.91 у = 7.90555
х[5] = 1.83 у = 34.1969
У цьому випадку передбачено введення елементів масиву в рядок, і клавішу Enter слід натиснути в кiнцi процесу введення.
Приклад 6.2. Сформувати масив сk, який містить однакові елементи двох масивів аі (і = 0…n-1), n = 7 та bj (j = 0…m-1), m = 10. Масиви а і b не мають елементів, що повторюються.
Схему алгоритму і програмну реалізацію задачі наведено на рис. 6.2.
[medium]http://cpp.dp.ua/uploads/posts/2015-12/1450709815_6_1_1.png[/medium]
Цей приклад розв’язується з використанням вкладених циклів. Процес порівняння елементів відбувається немов у “три руки”. Одна рука за параметром і вибирає елемент з масиву аі, друга за параметром j вибирає елемент з масиву bj, а третя за параметром k розташовує вибраний елемент у масив сk.
Спочатку і = 0 (відбувається порівняння з а0), a j змінюється від 0 до m-1.
У циклі за параметром j кожний елемент bj порівнюється з ai доти, поки не знайдеться ai = bj та не буде переглянутий весь масив bj. Якщо ai = bj, то bj заноситься до поточного елемента масиву ск.
Далі повторюються аналогічні порівняння для і (і = 1, 2,…, n-l), тобто здійснюється порівняння елементів масиву bj з наступним елементом масиву ai.
Приклад 6.3. За один перегляд масиву cі(і = 0…n-l), n = 15 визначити значення, а також положення максимального і мінімального його елементів та поміняти їх місцями.
Схему алгоритму розв’язання задачі та пояснення до неї наведено у прикладі 1.3 (див. рис. 1.3).
/* Р6_3.СРР — определение максимального и минимального элементов массива c[n] и перестановка их местами */ #include <iostream.h> #include <conio.h> const n=15; void main () { //описание массива с[n] и его инициализация float с[n] = {6.4, 1.5, -5.6, 3.7, 18.9, 10.3, -0.6, 44.5,-0.2, 8.9, 55.3, 6.9, 4.3, 7.7, 10.9}; float max, min; // максим, (max) и миним. (min) элементы int imax, imin; // индексы искомых элементов //--------------------------вывод заданного массива с[n] cout << " ***** massiv c[n] ***** n= " << n << endl; for (int і = 0; і < n; і++) cout << с[і] << " "; /* определение максимального и минимального элементов массива и их индексов — imax, imin */ max = min = c[0]; imax = imin = 0; for (int i =1; i<n; i++) { if (c[i] >max) { max = c[i]; imax = i; } else if (с[і] < min) { min = с[і]; іmin = і; } } //------------------------------ перестановка max и min элементов c[imin] = max; c[imax] = min; //-------------------------------- вывод max, min, imax, imin cout << ”\n\t max= " << max << " min= " << min << endl; cout << "\t imax= " << imax+1 << " imin= " << imin+1 << endl; //-------------------------------- вывод преобразованного массива c[n] cout << " **** Rezult massiv ****” << endl; for (int і = 0; і < n; i++) cout << c[i] << " " ; getch (); // задержка экрана }
Результати обчислень:
***** massiv c[n] ***** n= 15
6.4 1.5 -5.6 3.7 18.9 10.3 -0.6 44.5 -0.2 8.9 55.3 6.9 4.3 7.7 2.1
max= 55.3 min= -5.6 imax= 11 іmin= 3
**** Rezult massiv ****
6.5 1.5 55.3 3.7 18.9 10.3 -0.6 44.5 -0.2 8.9 -5.6 6.9 4.3 7.7 2.1
Крім одновимірних масивів, тобто таких, де позиція елемента визначається за допомогою одного індексу, у практиці розв’язання задач часто застосовуються багатовимірні масиви. У них позиція елемента визначається записом декількох індексів. Найбільш розповсюджені двовимірні масиви або матриці. Матриці являють собою порядковий запис декількох одновимірних масивів. Місце розташування кожного елемента визначається за допомогою двох індексів — номера рядка і номера стовпця, тобто порядкового номера в рядку. Індекси двовимірних масивів записуються в квадратних дужках і нумерація індексів починається з нуля (0).
Наприклад, двовимірний масив цілих чисел int а[3][4], що має три рядки та чотири стовпці, представлений на рис. 6.3
а[0][0] | а[0][1] | а[0][2] | а[0][3] |
а[1][0] | а[1][1] | а[1][2] | а[1][3] |
а[2][0] | а[2][1] | а[2][2] | а[2][З] |
Рис. 6.3. Вигляд двовимірного масиву (матриці) int а[3][4]
У пам’яті комп’ютера масив розташовується безперервно за рядками:
а [0][0], а [0][1], а [0][2], а [0][3], а [1][0], а [1][1], а [1][2], а [1][3], … а [2][3].
Двовимірні (і багатовимірні) масиви оголошуються так:
int mas [2][5] ={ 1, 5, 3, 7, 4,10, 11, ІЗ, 14, 25 };
int mas [ ][5] ={ 1, 5, 3, 7, 4, 10, 11, 13, 14, 25 };
int mas [ ][5] ={ { 1, 5, 3, 7, 4 },{10, 11, 13, 14, 25} };,
тобто масив задається або списком елементів у тому порядку, и якому вони розташовані у пам’яті, або подається як масив масивів, кожний з яких поміщається в свої фігурні дужки«{}». При оголошенні і одночасному ініціюванні багатовимірних масивів можна опускати кількість індексів тільки першого виміру. Якщо ініціювання не здійснюється під час оголошення масиву, то кількість індексів треба вказувати явно.
Для здійснення введення-виведення, а також для обробки елементів двовимірного масиву у програмі слід передбачати організацію двох циклів: один — для задання значень індексу рядків, другий — індексу стовпців.
Приклад 6.4. Кожний елемент матриці М(3,4) збільшити на задане число.
// Р6_4. СРР — увеличение элементов матрицы на заданное число #include <iostream.h> #include <conio.h> main() { const int n = 3, m = 4; /* n и m - количество строк и столбцов матрицы */ float М [n][m], z = 10; // z — заданное число int і, j; //-------ввод элементов матрицы и увеличение их значений на z cout << "**** Vvod matrix " << endl; for (і = 0; і<n; i++) for (j = 0; j<m; j++) { cout << " M [" << і << "]" << "[" << j << "]="; cin >> M [i][j]; M [i][j] += z; // M [i][j]= M [i][j] + z; } //-------вывод полученной матрицы в естественном виде cout << "\n\n***** Rezult matrix: "; for (і = 0; і < n; і++) { cout << endl; for (j = 0; j < m; j++) cout << M [i][j] << " “;} getch(); // задержка экрана }
Результати виконання програми:
***** Vvod matrix
М [0][0]=4.5
М [0][1]=6.7
М [0][2]=4.8
М [0][3]=23.6
М [1][0]=5.7
М [1][1]=3.7
М [1][2]=2.9
М [1][3]=6.1
М [2][0]=1.2
М [2][1]=4.5
М [2][2]=4.6
М [2][3]=2.7
***** Rezult matrix:
14.5 16.7 14.8 33.6
15.7 13.7 12.9 16.1
11.2 14.5 14.6 12.7
У програмі при описі матриці float M[n][m]; вказується діапазон змiни двох iндексiв, перший з яких призначений для iндексування рядків (і), другий — для індексування стовпців (j). Введення, обробка і виведення елементів матриці здійснюються за допомогою двох циклів, один з яких є вкладеним в іншій. Це дозволяє при кожному значенні змінної і перебирати всі значення змінної j. Розглянута програма може бути скорочена шляхом об’єднання всіх трьох блоків циклу в один, але в таксму випадку вона буде менш наочною.
Приклад 6.5. Елементи головної та побічної діагоналей матриці С(4,4) поміняти місцями. Визначити максимальний елемент перетвореної матриці, а також номери рядка та стовпця, на перетині яких він знаходиться.
Схему алгоритму до прикладу наведено на рис. 6.4.
[medium]http://cpp.dp.ua/uploads/posts/2015-12/1450812241_6_1_2.png[/medium]
Програму розроблено з використанням алгоритму знаходження максимального елемента масиву та його індексів (див. приклад 1.3).
//P65.CPP — перестановка элементов главной и побочной диагоналей //--------- определение максимального элемента матрицы и его индексов #include <iostream.h> #include <conio.h> void main () { const int n = 4; int і, j, imax, jmax; float max, C[ ][n] = { {3.6, 8.9, 1.9, 5.8}, {8.8, 4.1, 1.2, 6.3}, {2.5, 6.4, 0.1, 5.5}, {8.8, 4.1, 1.2, 6.3} }; //инициализация С[n][n] //-------------------------------- вывод исходной матрицы в естественном виде cout << " ***** massiv C[n][n] *****"; for (i = 0; i < n; i++) { cout << endl; for (j = 0; j < n; j++) cout << C[i][j] << " "; } //--------------------------- перестановка элементов главной и побочной диагоналей float rab; // вспомогательная переменная для перестановки for (i = 0; i < n; i++) // for (i = 0, j = n-1; i < n; i++, j--) { j = n-1-i; // { rab = C[i][i]; rab = C[i][i]; //C[i][i]=C[i][j]; C[i]|i] =C[i][j]; //C[i][j] = rab; } C[i][j] = rab; } //----------------------------- вывод преобразованной матрицы cout<<"\n\n ***** REZULT massiv ***** "; for (i = 0; i < n; i++) { cout << endl; for (j = 0; j < n; j++) cout << C[i]|j] << " "; } // определение max элемента матрицы его индексов — imax, jmax max = С[0][0]; imax = jmax = 0; for (i = 0; i < n; i++) for (j = 0; j < n; j++) if (С[i][j] > max) { max = C[i][j]; imax = i; jmax = j; } cout << "\n\n max= " << max << " index stroki = " << imax+1 << “ index stolbca = “<< jmax+1; getch(); }
Результати обчислень:
***** massiv C[n][n] *****
3.6 8.9 1.9 5.8
8.8 4.1 1.2 6.3
2.5 6.4 0.1 5.5
8.8 4.1 1.2 6.3
***** REZULT massiv *****
5.8 8.9 1.9 3.6
8.8 1.2 4.1 6.3
2.5 0.1 6.4 5.5
6.3 4.1 1.2 8.8
max = 8.9 index stroki = 1 index stolbca = 2 .