Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lektsii_po_si.doc
Скачиваний:
13
Добавлен:
12.11.2018
Размер:
11.78 Mб
Скачать

Инициализация массивов.

Инициализация массивов. При определении массивов возможна их инициализация, т.е. присваивание начальных значений их элементам. По существу (точнее по результату), инициализация - это объединение определения объекта с одновременным присваиванием ему конкретного значения. Использование инициализации позволяет изменить формат определения массива. Например, можно явно не указывать количество элементов одномерного массива, а только перечислить их начальные значения в списке инициализации:

В данном примере длину массива компилятор вычисляет по количеству начальных значений, перечисленных в фигурных скобках. После такого определения элемент d[0] равен 1.0, d[l] равен 2.0 и т.д. до d[4], который равен 5.0.

Если в определении массива явно указан его размер, то количество начальных значений не может быть больше количества элементов в массиве. Если количество начальных значений меньше, чем объявленная длина массива, то начальные значения получат только первые элементы массива (с меньшими значениями индекса):

В данном примере определены значения только переменных М[0], М[1] и М[2], равные соответственно 8, 4 и 2. Элементы М[3],..., М[7] не инициализируются.

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

Эта запись эквивалентна последовательности операторов присваивания: А[0][0]=10; А[0][1]=20; А[1][0]=30; А[1][1]=40; А[2][0]=50; А[2][1]=60;. Тот же результат можно получить с одним списком инициализации:

С помощью инициализации можно присваивать значения не всем элементам многомерного массива. Например, чтобы инициализировать только элементы первого столбца матрицы, ее можно описать так:

Следующее описание формирует "треугольную" матрицу в целочисленном массиве из 5 строк и 4 столбцов:

В данном примере последняя пятая строка х[4] остается незаполненной. Первые три строки заполнены не до конца. Схема размещения элементов массива изображена на рис.2.5.

Рис. 2.5. Схема "треугольного" заполнения матрицы

Моделирование многомерных массивов.

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

1. Основным понятием в языке Си является одномерный массив, а возможности формирования многомерных массивов (особенно с переменными размерами) весьма ограниченны.

2. Нумерация элементов массивов в языке Си начинается с нуля, т.е. для обращения к начальному (первому) элементу массива требуется нулевое значение индекса.

При работе с матрицами обе указанные особенности массивов языка Си создают по крайней мере неудобства. Во-первых, при обращении к элементу матрицы нужно указывать два индекса - номер строки и номер столбца элемента матрицы. Во-вторых, нумерацию строк и столбцов матрицы принято начинать с 1.

Применение макросов для организации доступа к элементам массива позволяет программисту обойти оба указанных затруднения, правда, за счет нетрадиционных обозначений индексированных элементов. (Индексы в макросах, представляющих элементы массивов матриц, заключены в круглые, а не в квадратные скобки.) Рассмотрим следующую программу:

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

В программе определен одномерный массив х[ ], количество элементов в котором зависит от значений препроцессорных идентификаторов N и М.

Значения элементам массива х[ ] присваиваются в цикле с параметром k. Никаких новинок здесь нет. А вот далее для доступа к элементам того же массива х[ ] используются макровызовы вида A(i, j), причем i изменяется от 1 до N, а переменная j изменяется во внутреннем цикле от 1 до М. Переменная i соответствует номеру строки матрицы, а переменная j играет роль второго индекса, т.е. указывает номер столбца. При таком подходе программист оперирует с достаточно естественными обозначениями A(i, j) элементов матрицы, причем нумерация столбцов и строк начинается с 1, как и предполагается в матричном исчислении.

В тексте программы за счет макрорасширений в процессе препроцессорной обработки выполняются замены параметризованных обозначений A(i, j) на x[5*(i-l)+(j-l)], и далее действия выполняются над элементами одномерного массива х[ ]. Но этих преобразований программист не видит и может считать, что он работает с традиционными обозначениями матричных элементов. Использованный в программе оператор (вызов функции)

после макроподстановок будет иметь вид:

На рис. 3.1 приведена иллюстративная схема одномерного массива х[ ] и виртуальной (существующей только в воображении программиста, использующего макроопределения) матрицы для рассмотренной программы.