logo search
Подбельский Фомин_Программирование на языке СИ_

"Матрица" со строками разной длины.

"Матрица" со строками разной длины. Массив в языке Си должен иметь элементы одного типа и, естественно, одного размера. В ряде случаев возникает необходимость обрабатывать, подобно элементам массива, объекты разного размера. Например, попытка оформить в виде двумерного массива строки чисел с разным количеством числовых значений при обычном подходе потребует определить двумерный массив с максимально допустимыми размерами. Наличие более коротких строк не может уменьшить общих размеров массива - излишние требования к памяти налицо. Использование массивов указателей и средств динамического выделения памяти позволяет обойти указанные затруднения и более рационально распределить память. Для иллюстрации этих возможностей рассмотрим следующую задачу, очень схожую с задачей, рассмотренной ранее.

Необходимо ввести и распечатать в обратном порядке набор строк числовых значений. Количество строк в наборе вводится в начале работы программы, а длина каждой строки (т.е. количество чисел - элементов в ней) вводится перед каждой последовательностью числовых значений элементов строки.

Программа для решения задачи может быть такой:

Результаты выполнения программы (Free BSD UNIX):

Приведенным результатам выполнения программы соответствует рис. 4.6, где условно изображены все массивы, динамически формируемые в процессе выполнения программы.

В программе использованы:

line - указатель на массив указателей типа double *, каждый из которых, т.е. line[i], адресует динамически выделяемый участок памяти длиной в m[i] элементов типа double.

m - указатель на массив целых (int), значение каждого элемента равно длине массива, на который указывает line[i].

Рис. 4.6. Схема "матрицы" со строками разной длины для случая: число строк n = 5, количество элементов в строках: 4, 3,1,4, 2

Для иллюстрации разных функций выделения памяти в программе использованы calloc( ) и malloc( ). Различие между ними заключается в количестве и смысле параметров (см. табл. 4.1), а также в том, что функция calloc( ) обнуляет содержимое выделенного блока памяти.

При выходе из программы все блоки динамически выделяемой памяти рекомендуется явным образом освобождать. Для этих целей используется несколько вызовов функции free( ). В цикле по i после печати очередной строки функция free (line[i]) освобождает участок памяти, адресуемой указателем line[i]. После окончания цикла освобождаются блоки, выделенные для массива указателей free(line) и массива целых free(m).