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

Семестр 2 / Алгоритмизация Практика 3 язык С

.pdf
Скачиваний:
87
Добавлен:
12.04.2020
Размер:
216.6 Кб
Скачать

Алгоритмизация и программирование – семестр 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