Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подбельский Фомин_Программирование на языке СИ_...doc
Скачиваний:
356
Добавлен:
10.08.2019
Размер:
53.81 Mб
Скачать

Массивы указателей и моделирование многомерных массивов.

Массивы указателей и моделирование многомерных массивов. Хотя синтаксисом языка Си массив определяется как одномерная совокупность его элементов, но каждый элемент может быть, в свою очередь, массивом. Именно так конструируются многомерные массивы. Язык Си не накладывает явных ограничений на размерность массива, однако каждая реализация обычно вводит такое ограничение. Максимальное значение размерности массивов определяет константа (препроцессорная), определенная в заголовочном файле стандартной библиотеки. Обычно это предельное значение размерности массивов устанавливается равным 12.

В главе 3 матрицы имитировались с применением одномерных массивов и макроопределений, обеспечивающих доступ к элементам с помощью двух индексов.

В главе 2 рассматривались двумерные массивы фиксированных размеров и приводились примеры их использования для представления матриц. Однако матрицы (двумерные массивы) имели фиксированные размеры. Очевидного способа прямого определения многомерных массивов с несколькими переменными размерами в языке Си не существует. Решение, как и для случая одномерных массивов динамической памяти, находится в области системных средств (библиотечных функций) для динамического управления памятью. Но прежде чем рассматривать их возможности для многомерных массивов, необходимо ввести массивы указателей.

Массив указателей фиксированных размеров вводится одним из следующих определений:

тип * имя_массива [размер];

тип * имя_массива[ ]инициализатор;

тип * имя_массива [размер]=инициалзатор;

где тип может быть как одним из базовых типов, так и производным типом;

имя_массива - свободно выбираемый идентификатор;

размер - константное выражение, вычисляемое в процессе трансляции;

инициализатор - список в фигурных скобках значений типа тип*.

Примеры:

};

Здесь каждый элемент массивов pd и pi является указателем на объекты типа int. Значением каждого элемента pd[j] и pi[k] может быть адрес объекта типа int. Все 6 элементов массива pd указателей типа int * не инициализированы. В массиве pi три элемента, которые инициализированы адресами конкретных элементов массива data.

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

В качестве простого примера рассмотрим программу одновременного упорядочения и по возрастанию, и по убыванию одномерного массива без перестановки его элементов.

Результаты выполнения программы:

В программе с помощью перестановки значений элементов массива указателей pmin[6] определяется последовательность "просмотра" элементов массива array[6] в порядке убывания их значений. Массив указателей рmах[6] решает такую же задачу, но для "просмотра" массива array[6] в порядке возрастания их значений. Рис. 4.5 иллюстрирует исходную и результирующую адресации элементов массива array[6] элементами массивов указателей. Для "обмена" значений элементов массивов pmax[6] и pmin[6] введен вспомогательный указатель float * e.

Рис. 4.5. Массивы указателей в задаче упорядочения: а - массивы до упорядочения; б - массивы после упорядочения