Программирование на языке «Ядро»: Руководство пользователя, страница 5

Кроме того, в языке «Ядро» допускается использование частично обобщенного индекса, когда указываются не все индексы. При этом самый левый из указанных индексов считается обобщенным, а остальные – обычными. Так, для указания компоненты массива X можно использовать три, один или два индекса. В первом случае все будут обычными (их диапазон указан при описании массива), во втором единственный индекс – обобщенный (его диапазон – от 1 до длины массива, т.е. до 150). В последнем случае первый индекс будет обобщенным, а второй – обычным; тогда диапазон изменения второго индекса берется из описания переменной (от 1 до 5), а первого – от 1 до 30. Нетрудно увидеть, что X[2,1,i], X[4,i] и X[(4-1)*5+i] – это одна и та же компонента массива X.

Важной особенностью правил индексации массивов в языке «Ядро» является возможность выборки подмассивов путем задания последовательностей значений индексов. В любой индексной позиции можно задать произвольную последовательность значений индекса; например, следующая запись изображает часть двумерного массива K[3,5] из примера на рисунке 7, которая получается выборкой 1-го, 2-го и 4-го столбцов из первых двух строк этого массива: K[(1,2), (1,2,4)]. Если мы хотим использовать значения индекса, которые предварительно записаны в другой массив, то можем задать этот массив в индексной позиции: K[N,] – это последовательность строк массива K, номера которых заданы в массиве N. Кроме того, в индексной позиции можно задать произвольное выражение, значением которого является последовательность, по правилам, которые будут описаны в разделе «Выражения».

1.3.3. Операции запроса размера массива и границ индексов

В программе на языке «Ядро» доступна информация о размере описанных массивов, числе измерений и границах индексов.

Префиксная операция sizearr возвращает значение длины массива. Её аргументом должно быть имя переменной. Например, в примере на рисунке 7 sizearr X равно 150.

Префиксная операция dimension возвращает число измерений массива: в этом же примере dimension Х равно 3.

Префиксная операция bounds возвращает последовательность индексных границ: bounds Х вернет последовательность из трёх чисел (10, 3, 5).

Префиксная операция lastbound возвращает границу по последнему измерению: lastbound Х равно 5.

Инфиксная операция bound возвращает значение границы по заданному измерению: 1 bound X равно 10, 2 bound X равно 3, 3 bound X равно 5.

Использование этих операций позволяет программировать вывод массивов в текст независимо от фактических значений границ. Покажем, как можно вывести все строки массива Х:

X[i,] dsply on i from 1 to (sizearr X/lastbound X);

Этот оператор выведет таблицу из 5 столбцов, содержащую все строки массива Х. Число строк определяется делением размера массива на длину строки массива. Как уже указывалось, левый индекс при этом считается обобщенным и пробегает значения от 1 до 30, независимо от того, что фактически массив Х описан как трехмерный.

1.3.4. Операции, изменяющие размеры массива

Массивы могут изменять размеры при выполнении программы на языке «Ядро».

Инфиксная операция realloc позволяет переопределить размерность ранее описанной переменной (массива), задав ему новые границы.

Синтаксис операции:

<идентификатор_переменной> realloc <целочисленная последовательность>

Левый аргумент задает переменную, которая должна быть переопределена.

Правый аргумент задает новые границы этой переменной по измерениям.

При этом переменной заново распределяется память, и старое содержимое копируется в новый участок памяти в порядке возрастания обобщенного индекса. Если новая длина больше старой, то содержимое «лишних» компонент массива не определено. Если новая длина меньше старой, часть данных, не поместившихся в новый массив, теряется.

Пусть массив ХYZ, определенный в примере на рисунке 6, содержит координаты узлов разностной сетки. В этом примере памяти в массиве хватает для размещения координат только одного узла. Если мы хотим поместить в него координаты 5 узлов, то память массива надо перераспределить:

ХYZ realloc (5, 3);

Теперь массив стал двумерным и содержит 5 строк по 3 элемента.

Если нам нужна двумерная сетка – N узлов в одном направлении и M узлов в другом, то массив можно перераспределить так:

ХYZ realloc (N, M, 3);

Часто бывает затруднительно подсчитать число компонент последовательности, которая должна быть помещена в массив, и поэтому неудобно определять размерность массива явно. Тогда можно использовать инфиксную операцию: set_value (установить), которая переопределяет массив как одномерный и заносит в него значения из правой части. Новая длина массива равна числу значений в правом аргументе. Например, после выполнения оператора:

X set_value (0 to 30) repscal 3;

массив Х содержит 93 компоненты, в которых трижды подряд повторяется каждое число из последовательности от 0 до 30. (Операция repscal и другие операции над последовательностями описаны ниже, в разделе «Выражения»). Если теперь переопределить размерность:

X realloc (sizearr X/3, 3);

то массив X, не теряя данных, становится двумерным размера 31х3; будем считать, что в каждой его строке записаны координаты очередного узла разностной сетки.

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

В качестве примера добавим в массив Х координаты ещё одного узла:

X add_value (100,0,102); X realloc (sizearr X/3, 3);

теперь массив Х имеет размерность 32х3.

Инфиксная операция excl_value переопределяет массив как одномерный и исключает из него значения аргумента, заданные в правой части. Длина массива соответственно уменьшается. Пусть, например, в массиве S из примера на рисунке 7 содержатся строки:

S:=’’, ‘F’, ‘G’, ‘’, ‘2’;

Тогда оператор S excl_value ‘’; исключает из S все пустые строки; в результате длина массива S становится равной трём, а значение – последовательность из трёх строк: ‘F’, ‘G’, ‘2’.

Во всех случаях требуется согласованность типов массива в левой части и значений в правой части оператора.