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

В основній пам’яті дані можуть зберігатися двома способами

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

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

Динамічна пам’ять — це вільна пам’ять, у якій під час ви­конання програми можна виділяти місце залежно від потреб користувача. Доступ до виділених ділянок динамічної пам’я­ті, що називаються динамічними змінними, здійснюєть­ся тільки через покажчики. Час існування динамічних змін­них — від початку створення до кінця програми або до явного звільнення пам’яті. У мові C++ застосовують два способи ро­боти з динамічною пам’яттю. Перший з них дістався в спад­щину від мови С і використовує сукупність функцій malloc(), другий — працює з операціями new та delete, які здійснюють динамічний розподіл і скасування з вищим пріоритетом, ніж інші функції.

Оператор new виділяє пам’ять і повертає її адресу. За допо­могою оператора delete відбувається звільнення пам’яті, на яку вказує змінна-покажчик.

Загальна форма запису оператора new:

змінна-покажчик = new тип змінної;.

Оператор delete має вигляд:

delete [ ] змінна-покажчик; .

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

int n = 100;

float *р = new float[n]; — змінна-покажчик на float виділяє у динамічній пам’яті ділянку для розміщення 100 елементів дійсного типу.

Слід пам’ятати, що динамічні масиви при створенні не можна ні ініціювати, ні обнуляти.

Приклад 6.16. З використанням динамічної пам’яті обробити вiдомість успішності групи студентів з дисципліни “Програмування” підрахувавши середній бал групи і кількість відмінників.

/* P6_16.CPP использование динамической памяти при обработке одномерного массива */
#include <iostream.h>
#include <conio.h>
#include <math.h>
main ( )
{ const int n = 14;                // количество студентов
  int *mas;                         // объявление указателя на массив
  int і, k = 0;                      // k — количество отличников
  float s = 0;                      // s — сумма оценок группы
  mas = new int [n];             //выделение динамической памяти
cout << " Ввод оценок " << endl;
  for (і = 0; і < n; і++)  
  сіn >> mas[i];
//---------------- подсчет суммы оценок и количества отличников
  for (і = 0; і < n; і++)
  { s = s + mas[i];
    if (mas[i] == 5) 
    k = k+1; }
  cout << endl; 
  cout.precision(3);
  cout << "Средний балл = " << s/n << endl;
  cout << "Количество отличников = " << k << endl;
  getch (); 
  delete[ ]mas;       // освобождение динамической памяти
}

Результати обчислень:
Ввод оценок
33345343245333
Средний балл = 3.43
Количество отличников = 2

У цій програмі змінна s служить для обчислення суми oцiнок групи, а змінна k — для підрахунку кількості відмінників. Перед обчисленням треба надати цим змінним початкове нульове значення (накопичення суми і кількості пояснено у прикладах 1.1-1.2).

При створенні динамічного багатовимірного масиву необхiдно в операції new вказати всі його розмірності (перший може бути змінною), наприклад:
int n = 5; // n — количество строк
int **m = (int **) new int [n][5];.

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

int n, m;
cout << ” Введите количество строк и столбцов: “;
cin >> n >> m;
int **a = new int *[n]; — оголошення змінної тип «покажчи на покажчик на int» і виділення пам’яті для масиву покажчиків на рядки матриці;
for (int і = 0; і < n; і++)
a[і] = new int [m]; — кожному елементу масиву покажчиків на ряд­ки присвоюється адреса початку ділянки пам’яті, виділеної для ряд­ка матриці.

Наочно це представлено на рис. 6.10.

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

Приклад 6.17. З використанням динамічної пам’яті створити про­граму обчислення матриці С за формулою:

С [n][q] = A[n][m] * B[m][q].

Згідно з умовою, елемент матриці C[n][q] дорівнює сумі добутків елементів відповідного рядка матриці A[n][m] на елементи відповідного стовпця матриці

У запропонованій програмі для обчислення елементів добутку матриць організовано три вкладених цикли: цикл переборі рядків матриці А, цикл перебору стовпців матриці В, а також цикл накопичення суми для одержання елемента матриці С. Для виділення динамічної пам’яті під двовимірні масиви A[n][m], B[m][q] і С [n][q] скористаємося розглянутим вищі способом.

/* Р6_17.СРР — использование динамической памяти при работе с матрицами */
#include <iostream.h>
#include <math.h>
#include <conio.h>
main ( )
{ int і, j, k; 
  int n, m, q;
  cout << " Введите размерности матриц: \n";
  cout << " n = " ; 
  cin >> n;
  cout << " m = " ; 
  cin >> m;
  cout << " q = " ; 
  cin >> q;
//----------------- создание динамических массивов
/* выделение динамической памяти под массивы указателей и инициализация массивов указателей */
  int **С = new int *[n];
  for (int і = 0; і < n; і++)
  C[i] = new int [q];
  int **A = new int *[n];
  for (int і = 0; і < n; i++)
  A[i] = new int [m];
  int **B = new int *[m];
  for (int і = 0; і < m; i++)
  B[i] = new int [q];
//------------------------------ ввод матриц A[n][m] и B[m][q]
 cout<<"\n Ввод матрицы A[n][m] \n";
  for (і = 0; і < n; і++)
    for (j = 0; j < m; j++) 
    сіn >> *(А[i] + j);
    cout << "\n Ввод матрицы B[m][q] \n”;
  for (i = 0; і < m; i++) 
    for (j = 0; j < q; j++) 
    cin >> *(B[i] + j);
//----------------------- вычисление матрицы C[n][q] = A[n][m]*B[m][q]
  for = 0; і < n; i++)  // перебор строк матрицы A[n][m]
    for (k = 0; k<q; k++) //перебор столбцов матрицы B[m][q]
    { C[i][k] = 0; 
      for (j = 0; j < m; j++)
      C[i][k] += (A[i][j]* B[j][k]); // определение элемента C[i][k]
    }//-------------------- вывод на экран матрицы С[n][q]
  cout << "\n Матрица C[n][q] = A[n][m] * B[m][q] \n";
  for (і = 0; і < n; i++)
  { for (j = 0; j < q; j++)  
    cout << *(C[i] + j) << " ";
    cout << endl;}
  delete [ ]A; 
  delete [ ]B; 
  delete [ ]C;   // освобождение памяти
 getch (); 
}

Результати обчислень:
Введите размерности матриц:
n = 4
m = З
q = 5
Ввод матрицы A[n][m]
1 1 1
3 3 3
2 2 2
4 4 4
Ввод матрицы B[m][q]
8  8  8  8  8
7  7  7  7  7
5  5  5  5  5
Матрица C[n][q] = A[n][m] * B[m][q]
20 20 20 20 20
60 60 60 60 60
40 40 40 40 40
80 80 80 80 80

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *