
Рис. 10.2. Два метода инициализации массива
Поскольку массив rain содержит данные, которые не должны быть модифицированы, при объявлении массива в программе используется модификатор const.
Большее количество измерений
Все, что было сказано о двумерных массивах, можно распространить на трехмерные массивы и на массивы с большим числом измерений. Трехмерный массив объявляется следующим образом:
int box [10] [20] [30];
Одномерный массив можно представлять себе как строку данных, двумерный массив — как таблицу данных, а трехмерный массив — как стопку таблиц данных.
Массивы и указатели 381
Например, о массиве box можно думать как о 10 двумерных массивах (каждый размером 20x30), уложенных друг на друга.
Массив box можно по-другому представлять себе как массив массивов, состоящих из массивов. То есть это 10-элементный массив, элементами которого являются 20-эле- ментные массивы. Каждый 20-элементный массив содержит элементы, представляющие собой 30-элементные массивы. Либо же массивы можно просто рассматривать с точки зрения количества необходимых индексов.
Обычно для обработки трехмерного массива применяются три вложенных цикла, для обработки четырехмерного массива — четыре вложенных цикла и т.д. В своих примерах мы ограничимся двумерными массивами.
Указатели и массивы
Как объяснялось в главе 9, указатели предоставляют символический способ работы с адресами. Поскольку аппаратные инструкции вычислительных машин в большой степени полагаются на адреса, указатели позволяют выражать действия в манере, близкой к машинному представлению. Такое соответствие делает программы с указателями эффективными. В частности, указатели предлагают эффективный метод манипулирования массивами. На самом деле, как вы увидите далее, система обозначения массивов является просто замаскированным использованием указателей.
Примером такого замаскированного применения может служить тот факт, что имя массива представляет собой также и адрес его первого элемента. Это означает, что если flizny — массив, то следующее выражение будет истинным:
flizny == &flizny[0]; // имя массива является адресом его первого элемента
И flizny, и &flizny[0] представляют адрес в памяти, где находится первый элемент массива. (Вспомните, что & — операция взятия адреса.) Кроме того, это константы, т.к. они остаются фиксированными на протяжении всего времени действия программы. Тем не менее, их можно присваивать в качестве значений и временной типа указателя, значение которой можно изменять, как показано в листинге 10.8. Посмотрите, что происходит со значением указателя, когда вы прибавляете к нему число. (Как вы, возможно, помните, спецификатор %р для указателей обычно приводит к отображению их шестнадцатеричных значений.)
Листинг 10.8. Программа pnt add. с

382 Глава 10
Вот пример вывода:

Во второй строке выводятся начальные адреса двух массивов, в следующей после нее строке показан результат прибавления к адресу 1 и т.д. Имейте в виду, что адреса представлены в шестнадцатеричной форме, поэтому dd на 1 больше, чем dc, a al на 1 больше, чем аО. Что же мы здесь имеем?

Довольно глупо? Нет — хитро! В нашей системе реализована побайтная адресация, но тип short занимает 2 байта, а тип double — 8 байтов. В таком случае “добавление 1 к указателю” означает добавление одной единицы хранения. Для массивов данный факт означает, что адрес увеличивается до адреса следующего элемента, а не просто до следующего байта (рис. 10.3). Это одна из причин того, почему нужно объявлять вид объекта, на который указывает указатель. Одного лишь адреса недостаточно, т.к. компьютер должен знать, сколько байтов требуется для хранения объекта. (Это справедливо даже для указателей на скалярные переменные; иначе операция *pt, извлекающая значение, не будет корректно работать.)

Рис. 10,3. Массив и добавление к указателю
Читать дальше