Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»
Кафедра АПЕПС
Алгоритмізація та програмування - 2. Процедурне програмування
ЗВІТ
до лабораторної роботи № 2
«Динамічне виділення пам’яті для одно- та двовимірних масивів»
Варіант № 18
Дата «08» червня 2022
ЗАВДАННЯ:
1. Ознайомитись з особливостями роботи з динамічними одно- та двовимірними масивами.
2. Розробити Блок-схему програмного алгоритму.
3. Виконати індивідуальне завдання.
4. Оформити ЗВІТ до лабораторної роботи згідно вимог та методичних рекомендацій.
5. Вихідні дані (завдання) обрати згідно свого варіанта у Додатку B-2.
РЕЗУЛЬТАТ РОБОТИ:
1. Роздрукувати отримані результати (вивести на екран).
2. ЗВІТ до комп’ютерного практикуму для перевірки додати в Клас.
3. Програмний код розмістити на сайті Repl.it (посилання виключно через кнопку «+ Invite»).
Теоретичні відомості:
Використання масиву вказівників на рядки (вказівник на вказівник) для динамічного виділення пам’яті для двовимірного масиву
Динамічне виділення пам’яті під двовимірний масив, що базується на використанні масиву вказівників на рядки (вказівник на вказівник). Графічна схема виділення пам’яті під двовимірний масив показана на Рисунку 1.
Рядки (одновимірні масиви)
н
а
и
в
н
і
к
з
д
и
а
я
к
к
р
и
В
[0]
→
[0][0]
[0][1]
…
[0][M-1]
[1]
→
[1][0]
[1][1]
…
[1][M-1]
…
→
…
…
…
…
[N-1]
→
[N-1][0]
[N-1][1]
…
[N-1][M-1]
Рисунок 1 – Схема виділення пам’яті під двовимірний масив
Для виділення пам’яті необхідно виконати наступні кроки:
1. Об’явити масив вказівників (наприклад, int **parray;);
2. Виділити блоки оперативної пам’яті під одномірні масиви, що представляють собою рядки заданої матриці (наприклад, parray = (int**)malloc(N * sizeof(int*)););
3. записати адреси рядків в масив вказівників (наприклад, parray[i] = (int*)malloc(M * sizeof(int));).
Для звільнення пам’яті необхідно виконати такі кроки:
1. Видалити адреси рядків в масиві покажчиків (наприклад, for (i = 0; i < N; i++) {free(parray[i]);})
2. Видалити масив вказівників (наприклад, free(parray);)
При такому способі динамічного виділення пам’яті компілятору явно вказується кількість рядків і кількість стовпців в масиві.
Перерозподіл динамічно виділеної пам’яті
Функція realloc перерозподіляє пам’ять.
Синтаксис: #include <stdlib.h>
#include <alloc.h>
void * realloc(void *block, size_t size);
Опис: realloc намагається стиснути або збільшити попередньо виділений блок block до нового розміру в size байт. Аргумент block вказує на блок пам’яті, отриманий при виклику функцій malloc або realloc. Якщо block є нульовим покажчиком, realloc працює також як і malloc. realloc змінює розмір виділеного блоку пам’яті і при необхідності копіює його вміст в новий блок.
Варіант індивідуального завдання:
/
Опис програми:
Користувач може задати довжину масиву, який програма заповнює випадковими значеннями, а потім виводить масив, що складається з лише непарних елементів першого масиву. Також користувач може задати довжину і ширину матриці, а також кількість рядків, яких він хоче додати до матриці. Програма спочатку виводить матрицю заданого розміру, а потім ту ж саму матрицю, але з доданими рядками, які теж заповнені випадковими значеннями.
Результат програми:
/
Висновок: Було написано програму, в якій користувач може задати одновимірний масив, для якого виділиться необхідний об’єм пам’яті, після чого буде створений ще один масив, який буде містити лише непарні елементи першого масиву. Також користувач може задати довжину і ширину матриці і кількість рядків, яких він хоче додати до матриці. Програма виділяє пам’ять для матриці та виводить її, після чого створюється нова матриця, для якої теж виділяється пам’ять, в яку переписуються дані з першої, але ще додається задана кількість рядків. У результаті виконання лабораторної роботи було засвоєно принципи динамічне виділення пам’яті для одно- та двовимірних масивів.
Посилання на replit: https://replit.com/join/tsxvlpsezh-okseniait
Код:
//Черкас Оксана 08.06.2022 Лабораторна робота №2 Алгоритмізація та програмування 18 варіант
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int *parray1;
int **parray2;
int **parray2fin;
int a, n, m, k;
int i, j;
// Введення довжини масива
printf("Task 1 \n");
printf("Введіть довжину ряду: ");
scanf("%d", &a);
//Виділення пам'яті для масива
parray1=(int*)malloc(a * sizeof(int));
//Задання елементам рандомних значень
for (i=0; i<a; i++){
parray1[i]= rand()%20;
}
//Виведення початкового масиву
printf("\nПочатковий масив: ");
for (i=0; i<a; i++){
printf("%d, ", parray1[i]);
}
//Визначення кількості непарних елементів
int b=0;
for (i=0; i<a; i++){
if(parray1[i]%2!=0){
b++;
}
}
//Створення другого масиву
int *parray1fin[b];
//Виділення пам'яті для масива
*parray1fin=(int*)malloc(b * sizeof(int));
//Копіювання лише непарних елементів масиву
int c=0;
for (i=0; i<a; i++){
if(parray1[i]%2!=0){
parray1fin[c]= &parray1[i];
c++;
}
}
//Виведення масиву без парних елементів
printf("\nМасив без парних елементів: ");
for (i=0; i<c; i++){
printf("%d, ", *parray1fin[i]);
}
//Звільнення пам'яті
free(parray1);
//Завдання 2
printf("\n\nTask 2 \n");
//Введення розмірів матриці
printf("Введіть кількість рядків: ");
scanf("%d", &n);
printf("Введіть кількість стовпчиків: ");
scanf("%d", &m);
printf("Введіть кількість додаткових рядків: ");
scanf("%d", &k);
//Виділення пам'яті для матриці
parray2 = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++){
parray2[i] = (int*)malloc(m * sizeof(int));
}
//Виділення пам'яті для фінальної матриці
parray2fin = (int**)malloc(n+10 * sizeof(int*));
for (i = 0; i < n+k; i++){
parray2fin[i] = (int*)malloc(m * sizeof(int));
}
//Заповннення матриці рандомними значеннями
for (i = 0; i < n; i++){
for (j = 0; j < m; j++){
parray2[i][j]=rand()%10;
parray2fin[i][j]=parray2[i][j];
}
}
//Заповнення додаткових рядків рандомними значеннями
for (i = n; i < n+k; i++){
for (j = 0; j < m; j++){
parray2fin[i][j]=rand()%10;
}
}
//Виведення початкової матриці
printf("\nПочатковий масив: \n");
for (i = 0; i < n; i++){
for (j = 0; j < m; j++){
printf("%d ", parray2[i][j]);
}
printf("\n");
}
//Виведення матриці з додатковами рядками
printf("\nМасив з додатковами рядками: \n");
for (i = 0; i < n+k; i++){
for (j = 0; j < m; j++){
printf("%d ", parray2fin[i][j]);
}
printf("\n");
}
//Звільнення пам'яті
for (i = 0; i < n; i++){
free(parray2[i]);
}
free(parray2);
free(parray2fin);
return 0;
}