Лабораторна робота 5

Використання масивів

1 Завдання на лабораторну роботу

1.1 Сума мінімального і максимального елементів

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

1.2 Перемноження матриць

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

1.3 Індивідуальне завдання

Створити програму, яка визначає та ініціалізує двовимірний масив цілих елементів, а потім реалізує такі дії:

  • перетворення вихідного масиву відповідно до завдання, наведеного в колонці "Перший крок"
  • створення та заповнення одновимірного масиву чисел типу double відповідно до завдання, наведеного в колонці "Другий крок"
  • виведення на екран елементів обох масивів

Треба передбачити виведення повідомлень про помилки, якщо перетворення або заповнення неможливі.

Номер варіанту
(номер студента у списку)
Перший крок
Правило перетворення елементів першого масиву:
Другий крок
Правило заповнення елементів другого масиву:
Кількість рядків
m
Кількість стовпців
n
1, 15
Усі елементи з непарними значеннями повинні бути збільшені в два рази Квадратні корені мінімальних додатних елементів рядків
4
3
2, 16
Усі елементи з парними значеннями повинні бути замінені їх квадратами Кубічні корені мінімальних елементів колонок
3
5
3, 17
Усі елементи з нульовим значенням слід замінити одиницями Натуральні логарифми максимальних додатних елементів рядків
3
4
4, 18
Усі елементи з парними значеннями повинні бути збільшені в два рази Натуральні логарифми мінімальних додатних елементів колонок
4
5
5, 19
Усі елементи повинні бути замінені їх абсолютними величинами Мінімальні елементи колонок
5
4
6, 20
Усі елементи з парними значеннями повинні бути збільшені в три рази Кубічні корені діагональних елементів
3
3
7, 21
Усі додатні елементи повинні бути замінені з цілими частинами їх десяткових логарифмів Суми від'ємних елементів колонок
4
5
8, 22
Усі від'ємні елементи повинні бути замінені їх квадратами Квадратні корені діагональних елементів
4
4
9, 23
Усі додатні елементи повинні бути замінені з цілими частинами їх натуральних логарифмів Добутки від'ємних елементів рядків
5
4
10, 24
Усі додатні елементи повинні бути замінені з цілими частинами їх квадратних коренів Максимальні додатні елементи рядків
3
5
11, 25
Всі додатні елементи з парними значеннями повинні бути збільшені в два рази Кубічні корені максимальних елементів колонок
5
4
12, 26
Усі від'ємні елементи з непарними значеннями повинні бути збільшені в три рази Квадратні корені мінімальних додатних елементів колонок
3
4
13, 27
Усі негативні елементи з непарними значеннями повинні бути збільшені в два рази Суми десяткових логарифмів додатних елементів рядків
4
3
14, 28
Усі додатні елементи з парними значеннями повинні бути збільшені в три рази Результати ділення максимальних додатних елементів колонок на їхні десяткові логарифми
3
5

Для виклику стандартних математичних функцій слід включити заголовний файл cmath.

1.4 Сортування масиву методом вибору (додаткове завдання)

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

2 Методичні вказівки

2.1 Визначення одновимірних масивів

2.1.1 Поняття масивів

Дуже вагома частина роботи програмістів пов'язана з так званими колекціями. Колекція – це структура даних одного чи різних типів, до яких можна звертатися як до одного цілого, а також працювати з окремими елементами (items). В більшості випадків у колекції зберігаються об'єкти одного типу. Існують різні методи зберігання і доступу до елементів.

Масив у широкому сенсі – це структура даних, яка забезпечує доступ до елемента через певний ключ. Наприклад, в так званих асоціативних масивах ключем може бути будь-який об'єкт, наприклад, число, літера, рядок, структура тощо.

Найпростіший варіант масиву – так званий індексований масив (indexed array). Це масив, який підтримує лише числові індекси – цілі числа певного діапазону. Елементи такого масиву розташовані послідовно в пам'яті. Далі під масивом ми розумітимо саме такий найпростіший варіант.

Масив фактично є найпростішою колекцією. Масив – це структура даних, яка відповідає таким ознакам:

  • масив містить елементи одного типу;
  • всі елементи масиву займають суцільний блок пам'яті;
  • доступ до елементів здійснюється через визначення індексу (номера) елементу в масиві.

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

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

Робота з масивами реалізована практично в усіх мовах програмування. Існують синтаксичні відмінності в механізмах звернення до елементів. Зазвичай звернення до елементів здійснюється через визначення індексу в круглих або квадратних дужках. У C++ індекс вказується в квадратних дужках.

Елементи масивів у більшості мов нумеруються починаючи з нуля. Це спрощує отримання доступу до елементів. Елементи розташовані послідовно в пам'яті:

a[0]
a[1]
...
a[n - 1]

Якщо addr_0 – це адреса нульового (початкового) елемента масиву, а sizeof(item) – це кількість байтів для зберігання одного елемента масиву, адресу елемента з індексом i (addr_i) можна легко обчислити за формулою

addr_i = addr_0 + i * sizeof(item)

Як видно з цієї формули, звертатися до елементів можна майже так швидко, як до окремих змінних. В жодному разі для вибору елемента за індексом не треба здійснювати послідовне перебирання елементів.

2.1.2 Створення одновимірних масивів

Для створення одновимірного масиву в C++ застосовують такий синтаксис:

тип_елемента ім_я_масиву[кількість_елементів];

Ім'я масиву – це ідентифікатор, побудований за загальними правилами. Якщо важко визначити фізичний сенс масиву, для імен можна використовувати a, b, c, або arr. Кількість елементів визначається константою. Кількість елементів масиву називають його розміром, а також довжиною.

Наприклад, можна створити масив з десяти елементів типу double:

double a[10];

В нашому прикладі компілятор виділяє блок пам'яті, в якому можна розташувати 10 чисел типу double. Оскільки кожне таке число займає 8 байтів, компілятор резервує 80 послідовних байтів пам'яті.

У програмному коді для отримання окремого елемента масиву використовують операцію отримання індексу ([]). В нашому прикладі через вираз a[0] ми можемо звернутися до початкового елемента. Останній індекс повинен бути на одиницю менше кількості елементів. У нашому випадку останній елемент можна отримати так: a[9].

Для визначення розміру масиву можна вживати лише константи – явні або іменовані, такі які може обчислювати компілятор, а також константні вирази. Не можна використовувати константи, які не можна обчислити під час компіляції, а також змінні:

const int n = 10;      // явна константа
int firstArr[n];       // OK
const int n1 = n + 3;  // константний вираз
int secondArr[n1 + 2]; // OK: розмір може бути обчислений компілятором
// Наступна константа не може бути обчислена компілятором:
const int m = pow(3, 3) / 3;
int thirdArr[m];       // помилка компіляції
int m1 = 4;            // змінна
int fourthArr[m1];     // помилка компіляції

У C++ немає механізму зміни розмірів масиву, який вже було створено. Єдиний спосіб – створити новий масив іншої довжини і скопіювати туди наявні елементи.

2.1.3 Ініціалізація одновимірних масивів

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

int integerArray[5] = { 1, 2, 3, 4, 5 };

Ми визначили масив integerArray з п'яти цілих. Відповідні початкові значення присвоюються елементам масиву. Можна опустити розмір масиву. Тоді компілятор визначить кількість елементів зі списку початкових значень. Попереднє визначення можна було б переписати так:

int integerArray[] = { 1, 2, 3, 4, 5 };

Не можна ініціалізувати більше елементів, ніж оголошено під час його опису. Тому наведений нижче запис

int integerArray1[5] = { 1, 2, 3, 4, 5, 6 };

призведе до помилки компіляції. Але, навпаки, можна написати так:

int integerArray2[5] = { 1, 2 };

Решта елементів буде ініціалізована значеннями 0.

2.2 Використання одновимірних масивів

2.2.1 Робота з елементами масиву

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

int i = 0;
integerArray[i] = 11;
k = integerArray[2];
integerArray[k % 10 + 1] = 0;

Для виконання типових дій над елементами масиву зазвичай використовують цикл for. Якщо n – це кількість елементів масиву a, то для того, щоб обійти всі елементи, ми створюємо такий цикл:

const int n = 5;
int a[n];
for (int i = 0; i < n; i++)
    // робота з окремими елементами

Наприклад, в такий спосіб можна записати значення 0 в усі елементи масиву цілих чисел:

const int n = 5;
int a[n];
for (int i = 0; i < n; i++)
{
    a[i] = 0;
}

Типова помилка початківців – організовувати цикл до n включно:

const int n = 5;
int a[n];
for (int i = 0; i <= n; i++) // i не може дорівнювати n
{
    a[i] = 0; // помилка на останньому кроці циклу
}

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

Читати масиви з клавіатури та виводити на екран масив також можна тільки по одному елементу. Так можна здійснити читання елементів з клавіатури:

const int n = 6;
double a[n];
for (int i = 0; i < n; i++)
{
    cin >> a[i];
}

Так усі елементи можна вивести на екран:

for (int i = 0; i < n; i++)
{
    cout << a[i] << " ";
}
cout << endl;

У наведеному вище прикладі елементи, які виводяться, відокремлюються пропусками. Можна, якщо треба, також використовувати символи табуляції або нового рядка.

Не можна присвоїти один масив іншому для копіювання. Це синтаксична помилка.

const int n = 4;
double a[n]; 
double b[n] = { 11, 72, 4, 18 };
a = b; // Синтаксична помилка

Для копіювання елементів одного масиву в інший слід створити окремий цикл:

const int n = 4;
double a[n]; 
double b[n] = { 11, 72, 4, 18 };
for (int i = 0; i < n; i++)
{
    a[i] = b[i];
}

В межах блоку, в якому визначено масив, можна отримати його довжину за допомогою виразу sizeof(ім'я_масиву)/sizeof(тип_елемента). Наприклад:

const int n = 6;
double a[n];
for (int i = 0; i < sizeof(a)/sizeof(double); i++)
{
    cin >> a[i];
}

2.2.2 Використання циклів, побудованих на діапазоні

Не можна створити масив посилань, але можна визначити посилання на певний елемент масиву:

double a[] = { 1, 2, 4, 8 };
double& y = a[3];
y = 16; // a[3] = 16

Можна також створити посилання на весь масив і користуватися їм як масивом:

int (&b)[4] = a;
b[0] = 3;

Для перебору елементів масиву без застосування індексу нова версія C++ (починаючи з C++11) пропонує альтернативну конструкцію циклу forцикл, побудований на діапазоні ("range-based for"):

for (тип_елементу &змінна: масив)
    тіло_циклу

Всередині тіла циклу можна застосовувати змінну як поточний елемент масиву. Наприклад, так можна присвоїти одиниці всім елементам масиву:

int arr[4];
for (int& k : arr)
{
    k = 1;
}

Якщо в тілі циклу не передбачено модифікації елементів, краще описувати посилання на константний об'єкт:

for (const int &k : arr)
{
    std::cout << k << " ";
}

В тілі циклу не можна використовувати індекс або обійти частину масиву.

На жаль цикл for, побудований на діапазоні, можна використовувати для масивів тільки всередині блоків, в яких ці масиви визначено.

2.2.3 Приклади задач, пов'язаних з масивами

Типові дії з масивами чисел – це, наприклад, знаходження сум, добутків, елементів з найбільшим, найменшим значенням тощо. У наведеному нижче прикладі ми обчислюємо добуток елементів масиву:

#include <iostream>
using namespace std;

int main()
{
    double a[] = { 1, 2, 3, 4 };
    double product = 1;
    for (const double& elem : a)
    {
        product *= elem;
    }
    cout << product; // 24
    return 0;
}

Якщо дії не передбачають залучення всіх елементів, не слід використовувати цикл, побудований на діапазоні. Так можна знайти суму елементів масиву з парними індексами:

#include <iostream>
using namespace std;

int main()
{
    const int n = 6;
    double a[n] = { 1, 2, 3, 2, 1, 6 };
    double sum = 0;
    for (int i = 0; i < n; i += 2)
    {
        sum += a[i];
    }
    cout << sum; // 5
    return 0;
}

У прикладі 3.2 здійснюється пошук індексу максимального елемента масиву.

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

#include <iostream>
using namespace std;

void swap(int& x, int& y)
{
    int z = x;
    x = y;
    y = z;
}

int main()
{
    const int n = 5;
    int a[n] = { 1, 2, 3, 2, 10 };
    for (int i = 0; i < n - 1; i += 2)
    {
        swap(a[i], a[i + 1]);
    }
    for (const int& item : a)
    {
        cout << item << " "; // 2 1 2 3 10
    }
    return 0;
}

Останній елемент залишається на своєму місці, бо йому немає пари.

Програма, яка реалізує сортування методом бульбашки, наведена в прикладі 3.3.

2.3 Одновимірні масиви як параметри функцій

Імена масивів можуть бути використані як фактичні параметри функції. Ім'я масиву без квадратних дужок є адресою першого елемента масиву. Копія цієї адреси присвоюється відповідному параметру. Функція може використовувати цю адресу для доступу до елементів масиву. Наприклад, функція обчислює та повертає суму елементів масиву довжини n:

#include <iostream>
using namespace std;

const int n = 5;

double sum(double arr[])
{
    double result = 0;
    for (int i = 0; i < n; i++)
    {
        result += arr[i];
    }
    return result;
}

int main()
{
    double a[] = { 1, 2, 4, 8, 16 };
    double y = sum(a);
    cout << y << endl; // 31
    return 0;
}

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

Всередині функції немає можливості отримати реальну кількість елементів масиву. Тому, якщо ми хочемо розмір масиву передають окремим параметром:

#include <iostream>
using namespace std;

double sum(double arr[], int n)
{
    double result = 0;
    for (int i = 0; i < n; i++)
    {
        result += arr[i];
    }
    return result;
}

int main()
{
    double a[] = { 1, 2, 4, 8, 16 };
    double y = sum(a, 5);
    cout << y << endl; // 31
    return 0;
}

Оскільки у функції ми отримуємо адресу масиву ми працюємо з тим же масивом. Тому зміни, внесені в елементи, залишаються після завершення функції. Наприклад:

#include <iostream>

using namespace std;

void spoil(double arr[])
{
    arr[0] = 0;
}

int main()
{
    const int n = 4;
    double a[] = {1, 2, 4, 8};
    for (int i = 0; i < n; i++)
    {
        cout << a[i] << ' '; //1 2 4 8
    }
    cout << endl;
    spoil(a);
    for (int i = 0; i < n; i++)
    {
        cout << a[i] << ' '; //0 2 4 8
    }
    cout << endl;
    return 0;
}

Для того, щоб уникнути випадкової зміни значень елементів масиву в функції, параметр можна передавати з модифікатором const:

void f(const double arr[])
{
... // компілятор не дозволить змінювати значення елементів
}

2.4 Заповнення масивів випадковими числами

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

У наведеній нижче програмі масив з п'яти цілих заповнюється псевдовипадковими числами у діапазоні від 0 до 19 включно:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    const int n = 5;
    int randomArr[n];
    for (int& item : randomArr)
    {
        item = rand() % 20;
    }
    for (const int& item : randomArr)
    {
        cout << item << " "; // 1 7 14 0 9
    }
    return 0;
}

Після кожного запуску результати будуть однаковими.

Для отримання випадкових чисел застосовуємо функцію time(0) (заголовний файл ctime). Тепер програма буде такою:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    const int n = 5;
    int randomArr[n];
    srand(time(0));
    for (int& item : randomArr)
    {
        item = rand() % 20;
    }
    for (const int& item : randomArr)
    {
        cout << item << " "; // випадкові числа від 0 до 19 включно
    }
    return 0;
}

Випадкові числа слід використовувати для тестування, а не для зневадження.

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

Мова C++ дозволяє створювати масиви з більш ніж одним виміром. Кожен вимір представлено як окремий індекс масиву. Масиви можуть мати будь-яке число вимірів, однак найчастіше створюють одновимірні і двовимірні масиви. Двовимірний масив можна представити як прямокутну таблицю. Тоді перший індекс найчастіше пов'язують з номером рядка, а другий – з номером стовпця.

Якщо в програмі буде таке визначення,

// Раніше були визначені цілі константи m і n
double a[m][n];

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

a[0][0]
a[0][1]
...
a[0][n - 1]
a[1][0]
a[1][1]
...
a[1][n - 1]
...
...
...
...
a[m - 1][0]
a[m - 1][1]
...
a[m - 1][n - 1]

Фізично такий масив буде розташовано в m × n послідовно розташованих комірках пам'яті:

a[0][0]
a[0][1]
...
a[0][n - 1]
a[1][0]
a[1][1]
...
a[1][n - 1]
...
a[m - 1][0]
a[m - 1][1]
...
a[m - 1][n - 1]

Фактично в пам'яті ми працюємо з одновимірним масивом. Такий масив можна створити явно:

double b[m * n];
b[i * n + j] = 0; // для двовимірного масиву a[i][j] = 0;

Використання двовимірного масиву більш зручне для програміста.

Багатовимірні масиви також можна ініціалізувати. Наприклад:

int theArray[5][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

Це означає, що перші три елементи записують в рядок з індексом 0, наступні 3 – в рядок з індексом 1 тощо.

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

int theArray[5][3] = { { 1,  2,  3 },
                       { 4,  5,  6 },
                       { 7,  8,  9 },
                       {10, 11, 12 },
                       {13, 14, 15 } };

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

Тільки перша пара дужок може бути порожньою:

int theArray[][3] = { { 1,  2,  3 },
                      { 4,  5,  6 },
                      { 7,  8,  9 },
                      {10, 11, 12 },
                      {13, 14, 15 } };

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

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

const int m = 4;
const int n = 3;
int arr[m][n] = { };

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

for (int i = 0; i < m; i++)
{
    for (int j = 0; j < n; j++)
    {
        arr[i][j] = i + j;
    }
}

Використання індексу i для номера рядка та індексу j для номера стовпця не є обов'язковим, але є традиційним для роботи з двовимірними масивами.

Для багатовимірних масивів можна застосовувати цикли, побудовані на діапазоні. Наприклад, так можна записати одиниці в усі елементи масиву:

for (auto& row : arr)
{
    for (int& item : row)
    {
        item = 1;
    }
    cout << endl;
}

Так можна вивести на екран елементи двовимірного масиву рядок за рядком:

for (const auto &row : arr)
{
    for (const int &item : row)
    {
        cout << item << "\t";
    }
    cout << endl;
}

Використання auto тут цілком виправдане, оскільки інакше заголовок циклу був би більш складним:

for (const int(&row)[n] : arr)

Існує проблема з передачею в функції багатовимірних масивів. Фактично необхідно створювати окремі функції, явно вказуючи другу, третю та інші розмірності (окрім першої), наприклад:

double f(double a[][3])
{
    return a[1][1];
}

Цю функцію можна викликати:

int main()
{
    double arr[][3] = { { 1, 2, 3 },
                        { 4, 5, 6 } };
    cout << f(arr);
    return 0;
}

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

3 Приклади програм

3.1 Сума елементів

Припустимо, необхідно знайти суму елементів одновимірного масиву цілих чисел. Програма може бути такою:

#include <iostream>
using namespace std;

int main()
{
    double a[] = { 1, 2, 3, 4 };
    double s = 0;
    for (int i = 0; i < sizeof(a)/sizeof(double); i++)
    {
        s += a[i];
    }
    cout << s << endl; // 10;
    return 0;
}

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

#include <iostream>
using namespace std;

double sum(double arr[], int n)
{
    double s = 0;
    for (int i = 0; i < n; i++)
    {
        s += arr[i];
    }
    return s;
}

int main()
{
    double a[] = { 1, 2, 3, 4 };
    cout << sum(a, 4) << endl; // 10;
    cout << sum(a, 3) << endl; // 6;
    return 0;
}

3.2 Максимальний елемент

Наведена нижче програма знаходить максимальний елемент масиву цілих.

#include <iostream>

using namespace std;

int main()
{
    const int n = 4;
    int a[] = { 1, 2, 4, 8 };
    int indexOfMax = 0;
    for (int i = 1; i < n; i++) 
    {
        if (a[i] > a[indexOfMax])
        {
            indexOfMax = i;
        }
    }
    cout << indexOfMax << ' ' << a[indexOfMax];
    return 0;
} 

3.3 Сортування

Наведена нижче програма сортує елементи масиву в порядку зростання, використовуючи алгоритм сортування бульбашкою.

#include<iostream>
using namespace std;

void sort(double a[], int size)
{
    bool mustSort; // повторюємо сортування 
                   // якщо mustSort дорівнює true
    do
    {
        mustSort = false;
        for (int i = 0; i < size - 1; i++)
        {
            if (a[i] > a[i + 1])
                // Обмінюємо елементи
            {
                double temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
                mustSort = true;
            }
        }
    } while (mustSort);
}

int main()
{
    const int n = 5;
    double a[] = { 11, 2.5, 4, 3, 5 };
    sort(a, n);
    for (double &item : a)
    {
        cout << item << ' ';
    }
    return 0;
}

3.4 Знаходження суми матриць

Двовимірні масиви часто застосовують для виконання дій над математичними матрицями. Наведена нижче програма демонструє знаходження суми матриць. Вихідні матриці заповнюються псевдовипадковими числами.

#include <cstdio>
#include <iostream>
using namespace std;

// Функція повертає дійсне значення в діапазоні від 0 до 100
double nextRandom()
{
    return (rand() % 10000) / 100.;
}

int main()
{
    const int m = 3;
    const int n = 4;
// Створюємо і заповнюємо масив a:
    double a[m][n] = {};
    for (auto& row : a)
    {
        for (double& item : row)
        {
            item = nextRandom();
        }
    }
    for (const auto& row : a)
    {
        for (const double& item : row)
        {
            cout << item << "\t";
        }
        cout << endl;
    }
    cout << endl;
// Створюємо і заповнюємо масив b:
    double b[m][n] = {};
    for (auto& row : b)
    {
        for (double& item : row)
        {
            item = nextRandom();
        }
    }
    for (const auto& row : b)
    {
        for (const double& item : row)
        {
            cout << item << "\t";
        }
        cout << endl;
    }
    cout << endl;
// Обчислюємо та виводимо суму матриць:
    double c[m][n] = {}; 
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            c[i][j] = a[i][j] + b[i][j];
        }
    }
    for (const auto& row : c)
    {
        for (const double& item : row)
        {
            cout << item << "\t";
        }
        cout << endl;
    }
    return 0;
}

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

3.5 Сума добутків

У наведеній нижче програмі визначено двовимірний масив і здійснюється знаходження суми добутків його рядків.

#include<iostream>
using namespace std;

int main()
{
    const int  m = 4;
    const int  n = 3;
    int a[m][n] = { { 1, 2, 3 },
                    { 2, 3, 4 },
                    { 0, 1, 2 },
                    { 1, 1, 12} };
    int sum = 0;
    for (const auto &row : a)
    {
        int product = 1;
        for (const int &item : row)
        {
            product *= item;
        }
        sum += product;
    }
    cout << sum;
    return 0;
}

3.6 Заміна

У наведеній нижче програмі здійснюється заміна від'ємних елементів двовимірного масиву нулями.

#include<iostream>
using namespace std;

int main()
{
    const int m = 3;
    const int n = 3;
    double a[][n] = { { 1,  -2,  3 },
                      { 2.1, 3, -4 },
                      { 0,-0.5, 11 } };
    for (auto& row : a)
    {
        for (double& item : row)
        {
            if (item < 0)
            {
                item = 0;
            }
        }
    }
    for (const auto& row : a)
    {
        for (const double& item : row)
        {
            cout << '\t' << item;
        }
        cout << endl;
    }
    return 0;
}

4 Вправи для контролю

  1. Написати програму, яка читає короткі цілі числа без знака та виводить їх двійкове представлення у зворотному порядку.
  2. Написати програму, яка обчислює суму додатних елементів масиву дійсних чисел.
  3. Написати програму, яка визначає масив дійсних чисел і обчислює суму елементів з непарними індексами.
  4. Написати програму, яка визначає масив цілих чисел і обчислює суму парних елементів.
  5. Написати програму, яка визначає двовимірний масив і обчислює добуток максимальних елементів його стовпців.

5 Контрольні запитання

  1. Що таке масив? Де використовують масиви?
  2. Завдяки чому забезпечується ефективність доступу до елементів масиву?
  3. Що таке оператор індексування?
  4. Яким є початковий індекс масиву?
  5. Чи можна використовувати змінні для визначення довжини масиву?
  6. Як змінити розмір масиву після створення?
  7. Як додати новий елемент в кінець масиву?
  8. Як увести елементи масиву з клавіатури?
  9. Як вивести елементи масиву в консольне вікно?
  10. Як скопіювати значення елементів з одного масиву в інший?
  11. Як отримати довжину масиву під час виконання програми?
  12. Як створити масив посилань і посилання на масив?
  13. Що таке цикл, побудований на діапазоні?
  14. Які обмеження накладені на використання циклів, побудованих на діапазоні?
  15. Як здійснюється передача масивів у функції?
  16. Як отримати довжину масиву всередині функції, куди цей масив передано?
  17. Як заповнити масив випадковими числами?
  18. Для чого використовують багатовимірні масиви?
  19. Як визначити кількість стовпців у двовимірному масиві?
  20. Як ініціалізувати двовимірний масив?
  21. Як застосувати цикл, побудований на діапазоні для двовимірних масивів?
  22. Як передати багатовимірний масив у функцію?

 

up