Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
3
Добавлен:
30.05.2020
Размер:
89.6 Кб
Скачать

Динамічне розміщення даних

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

Для роботи з динамічною пам'яттю використовуються стандартні функції бібліотеки alloc.h:

void *malloc(size) і void *calloc(n, size) - виділяють блок пам'яті розміром size і n(size байт відповідно; повертають покажчик на виділену область, при помилці - значення NULL;

void free(bf); - звільняє раніше виділену пам'ять з адресою bf.

Іншим, прийнятнішим підходом до динамічного розподілу пам'яті є використання операцій мови З++ new і delete.

Операція new повертає адресу ОП, відведеною під динамічно розміщений об'єкт, при помилці - NULL, а операція delete звільняє пам'ять.

Мінімальний набір дій, необхідних для динамічного розміщення одновимірного масиву дійсних чисел розміром n :

double *а;

. . .

а = new double[n]; // Захоплення пам'яті для n елементів

. . .

delete []а; // Звільнення пам'яті

Мінімальний набір дій, необхідних для динамічного розміщення двомірного масиву дійсних чисел розміром n(m :

int i, n, m; // n, m - розміри масиву

double **a;

a = new double *[n]; // Захоплення пам'яті під покажчики

for(i=0; i<n; i++) a[i] = new double [m]; // і під елементи

. . .

for(i=0; i<n; i++) delete []a[i]; // Звільнення пам'яті

delete []a;

Для сучасних компіляторів (версій старше «6») для звільнення пам'яті досить записати тільки delete []a;

6.2. Приклад виконання завдання

Розрахувати значення вектору _, де А - квадратна матриця розміром N(N, а Y і B - одновимірні масиви розміром N. Елементи вектору Y визначаються по формулі _.

6. 2.1. Приклад створення віконного застосування

Значення N вводити з Edit, А і B - з компонент StringGrid. Результат вивести в компоненту StringGrid.

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

Мал. 6.1

Налаштування компонент StringGrid

Для компоненти StringGrid1 значення ColCount і RowCount встановите рівними, наприклад, 3 - три стовпці і три рядки, а FixedCols і FixedRows - 1.

Оскільки компоненти StringGrid2 і StringGrid3 мають тільки один стовпець, то у них ColCount = 1, RowCount = 3, а FixedCols = 0 і FixedRows = 1.

У властивості Options рядок goEditing для компонент StringGrid1 і StringGrid2 встановите в положення true.

Для зміни розміру n використовується функція-обробник EditChange, отримана подвійним клацанням по компоненті Edit.

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

. . .

//---------------------- Глобальні змінні -------------------

int n = 3;

double **a, *b; // Декларації покажчиків

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

Edit1 ->Text=IntToStr(n);

StringGrid1 ->ColCount = n+1; StringGrid1 ->RowCount = n+1;

StringGrid2 ->RowCount = n+1; StringGrid3 ->RowCount = n+1;

// Введення в лівий верхній елемент таблиці назви масивів

StringGrid1 ->Cells[0][0] = "Матриця A";

StringGrid2 ->Cells[0][0] = "Масив B";

StringGrid3 ->Cells[0][0] = "Масив Y";

for(int i=1; i<=n;i++){

StringGrid1 ->Cells[0][i]="i="+IntToStr(i);

StringGrid1 ->Cells[i][0]="j="+IntToStr(i);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Edit1Change(TObject *Sender)

{

int i;

n=StrToInt(Edit1 ->Text);

StringGrid1 ->ColCount = n+1; StringGrid1 ->RowCount = n+1;

StringGrid2 ->RowCount = n+1; StringGrid3 ->RowCount = n+1;

for(i=1; i<=n;i++){

StringGrid1 ->Cells[0][i]="i="+IntToStr(i);

StringGrid1 ->Cells[i][0]="j="+IntToStr(i);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

double s;

int i, j;

a = new double*[n]; // Захоплення пам'яті під покажчики

for(i=0; i<n;i++) a[i] = new double[n]; // Захоплення пам'яті під елементи

b = new double[n];

// Заповнення масивів А і В елементами з таблиць StringGrid1 і StringGrid2

for(i=0; i<n;i++){

for(j=0; j<n;j++) a[i][j]=StrToFloat(StringGrid1 ->Cells[j+1][i+1]);

b[i]=StrToFloat(StringGrid2 ->Cells[0][i+1]);

}

// Множення рядка матриці А на вектор В і виведення результату s в StringGrid3

for(i=0; i<n;i++){

for(s=0, j=0; j<n;j++) s += a[i][j]*b[j];

StringGrid3 ->Cells[0][i+1] = FloatToStrF(s, ffFixed, 8,2);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

delete []a;

delete []b;

ShowMessage("Пам'ять звільнена"!);

Close();

}