Алгоритмизация и программирование – семестр 2
Практическое занятие №3 «Динамические многомерные массивы»
Требования к заданию:
1.Размеры массива N, M задаются в виде констант в исходном коде программы.
2.Отдельно должны быть описаны функции заполнения, обработки и печати массивов.
3.Выполнение заданий организовать в формате интерфейс-меню с указанными функционалами.
Задание (2 балла):
Работа с прямоугольным двумерным динамическим массивом:
1.- создание массива с размерами, заданными пользователем;
2.- заполнение массива случайными числами в интервале 0-9;
3.- добавление 1 строки в указанное пользователем место массива;
4.- добавление 1 столбца в указанное пользователем место массива;
5.- удаление указанной пользователем строки;
6.- вывод массива на экран;
7.- выход.
Бонус (1 балл):
Задание сделать с помощью «гибридных» массивов, в которых «старший» массив указателей
— статический, а элементы этого массива уже указывают на области в динамической памяти (старшую размерность сделать константной, вторая размерность задается с клавиатуры);
«Гибридные» многомерные динамические массивы
В языке Си бывают массивы указателей:
int* arr[5]; |
// массив из 5 указателей на int |
Каждый из этих 5-ти указателей можно использовать по своему усмотрению. Например — выделить под каждый из них по блоку динамической памяти на 10 int’ов:
for(int i=0; i<5; i++){
arr[i] = (int*)malloc(10*sizeof(int));
}
Графически это выглядит следующим образом:
arr |
|
|
|
|
|
|
|
arr[0] |
|
|
|
|
|
|
|
arr[0][0] |
arr[0][1] |
… |
arr[0][9] |
|
|
arr[1] |
|
|
|
|
|
|
|
arr[1][0] |
arr[1][1] |
… |
arr[1][9] |
|
|
arr[2] |
|
|
|
|
|
|
|
arr[2][0] |
arr[2][1] |
… |
arr[2][9] |
|
|
arr[3] |
|
|
|
|
|
|
|
arr[3][0] |
arr[3][1] |
… |
arr[3][9] |
|
|
arr[4] |
|
|
|
|
|
|
|
arr[4][0] |
arr[4][1] |
… |
arr[4][9] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Работа с таким массивом осуществляется по общим правилам обращения с массивами и указателями. Например, обратимся двумя эквивалентными способами к 3-му (считая от 0) элементу второй (считая от 0) строки:
printf("%d\t", |
*(arr[2]+3)); |
// |
эквивалентно: |
arr[2][3] |
printf("%d\t", |
arr[2][3]); |
// |
эквивалентно: |
*(arr[2]+3) |
Просто arr — это то же самое, что &arr[0] (в силу эквивалентности массивов и указателей). Тогда это же обращение можно осуществить и третьим способом:
Практическоезанятие№2 |
Страница1 |
Алгоритмизация и программирование – семестр 2
printf("%d\t", *(*(arr+2)+3));
Когда такой массив больше не нужен — его аналогичным образом нужно удалить (вернуть память системе):
for(int i=0; i<5; i++){
free(arr[i]); // Освобождение памяти для элементов//
}
Настоящие многомерные динамические массивы
На практике описанный выше «гибридный» вариант используется редко. Гораздо чаще «главный» массив (массив указателей на массивы) также создается динамическим.
Поскольку в нем хранятся указатели (элементы типа int*), то указатель на этот массив должен иметь на одну звездочку больше (int** — указатель на указатель на int).
Обработка элементов такого массива полностью аналогична приведенному выше примеру с элементом arr[2][3].
А создание и удаление требуют дополнительно операцию выделения и освобождения памяти. Пример обработки динамического двумерного массива:
#include <conio.h> #include <stdio.h> #include <stdlib.h>
#define ROW_NUM 5 #define COL_NUM 10
int main() {
int** p |
= NULL; //создаем указатель на массив указателей на массив int'ов |
|
p = (int**)malloc(ROW_NUM *sizeof(int*)); |
// создаем 5 указателей |
|
for(int |
i=0; i< ROW_NUM; i++){ |
|
p[i] = (int*)malloc(COL_NUM *sizeof(int));//5 раз создаем 10 эл-тов
}
//Здесь некоторые операции с элементами массива: for(int i=0; i< ROW_NUM; i++){
for (int j = 0; j <COL_NUM; j++) { p[i][j] = i * j;
}
}
for(int i=0; i< ROW_NUM; i++){
for (int j = 0; j <COL_NUM; j++) { printf("%d\t", p[i][j]);
}
printf("\n");
}
//после работы с массивом освобождаем память – в обратном порядке: for(int i=0; i< ROW_NUM; i++){
free(p[i]); // Освобождение памяти для элементов (*(p+i))//
}
free(p); |
// Освобождение памяти для массива указателей// |
_getch(); |
|
}
Практическоезанятие№2 |
Страница2 |