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

Имя константы

Значение

_EndOfLine

строковая константа (перевод строки)

true, false

логические константы

Pi

вещественная константа, равная 3,14159265358979

MaxInt

целая константа, равная 2147483647

MaxDoubleValue

вещественная константа, равная по умолчанию 1.0Е+50

DefaultIntSkip

целая константа, заменяющая пустую основу целого типа, равная по умолчанию единице

DefaultDoubleSkip

вещественная константа, заменяющая пустую основу целого типа, равная по умолчанию нулю

Приведем пример использования строковой константы _EndOfLine для форматирования вывода. Оператор:

(X[i] on i from 1 to 10) dsply;

выводит 10 элементов массива Х подряд в одну строку окна вывода. Чтобы вывести каждый элемент массива на новую строку окна, можно вставить константу перевода строки:

((X[i], _EndOfLine) on i from 1 to 10) dsply;

или просто выводить каждый элемент массива отдельным оператором:

X[i] dsply on i from 1 to 10;

1.3.2. Описание и размещение в памяти переменных

Описание переменной включает: определение типа переменной (integer, real, boolean, string), задание имени переменной (массива) и задание границ по измерениям. Например, оператор:

real (A, B[10]);

описывает и размещает в памяти две вещественные переменные: скаляр A и массив B из 10 элементов, упорядоченных по одному индексу, который изменяется от 1 до 10. В отличие от большинства традиционных языков высокого уровня, описатель типа синтаксически является префиксной операцией. Поэтому переменные A и B, для которых этот описатель задает тип, должны быть перечислены в скобках, чтобы описатель real относился к ним всем.

Определение размера массива является инфиксной операцией. Между именем переменной (в примере переменной B) и квадратными скобками подразумевается инфикс индексации, который никак не изображается. Переменная B является левым аргументом операции, квадратные скобки – правым аргументом. Синтаксис языка «Ядро» допускает применение этой операции к списку переменных, который должен быть взят в круглые скобки, как в примере на рисунке 6. Возможны и более сложные варианты задания размеров массивов. Рассмотрим следующий пример, который иллюстрирует возможности описания переменных, отсутствующие в других языках.

((integer K, real X[10])[3], string S)[5];

Первая операция определения размерности [10] относится только к переменной X, вторая [3] – к переменным K и X, так, что K получает размер 3 по одному измерению, а X получает второе измерение длины 3. Наконец, третья операция [5] относится ко всем перечисленным переменным и к строковой переменной S, добавляя по одному измерению длины 5 к каждой из них. В результате будут описаны и размещены в памяти:

K[3,5] - целая  переменная размерности 2 длины 15,

S[5] - строковая  переменная размерности 1 длины 5,

X[10,3,5] - действительная  переменная размерности 3 длины 150.

Описание переменной действует в пределах блока памяти, т.е. до правой круглой скобки, закрывающей ближайшую открытую левую скобку. В следующем примере переменная I «видна» внутри внешних круглых скобок, в которых она описана, и «не видна» снаружи этих скобок.

K:=(integer I; I:=2; +I);

Остановимся на этом примере подробнее. Переменной K присваивается значение, изображенное выражением в скобках. Внутри этих скобок описана переменная I; таким образом, скобки ограничивают блок памяти. Оператор, который заканчивается точкой с запятой, никакого значения не изображает. Последнее (после всех точек с запятой) выражение в скобках – значение переменной I, которое и является значением, вырабатываемым скобками. Знак + в выражении I приводит к вычислению значения переменной (в противном случае вырабатывалось бы значение имени переменной, т.е. адреса в памяти, по которому она находится). Знак + в этом контексте не может быть опущен, т.к. переменная I недоступна снаружи блока памяти и поэтому не может использоваться в правой части оператора присваивания.

Приведём ещё один комментарий к этому примеру. Ранее описанная переменная в любом выражении означает последовательность адресов своих компонент (если их больше одной). К моменту выполнения разобранного оператора действует описание переменной K[3,5]. Этому массиву присваивается скалярное значение. В языке «Ядро» это означает присваивание скаляра каждой компоненте массива. В результате все 15 компонент массива K будут содержать число 2.

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

Как видно из рисунка, подмассив X[10,1,], состоящий из 5 компонент (с индексами от [10,1,1] до [10,1,5]), содержит значения, перечисленные (через запятую) в правой части оператора присваивания. Таких чисел ровно 5, по числу адресов левой части.

Рисунок 7. Описание и использование переменных

Здесь мы встретились ещё с одной особенностью языка «Ядро» - возможностью использовать в операторе часть массива, заданную фиксацией отдельных индексов переменной.

Другой удобной особенностью языка является возможность использования обобщенного индекса. Независимо от числа измерений, все компоненты массива считаются упорядоченными так, что самым первым меняется самый правый индекс. В приведенном примере компоненты массива X пронумерованы так: X[1,1,1], X[1,1,2], …, X[1,1,5], X[1,2,1], …, X[1,2,5], …, X[2,1,1], …, X[2,1,5], …, X[10,3,5]. Номер компоненты в этой последовательности является обобщенным индексом, который может использоваться при адресации компоненты. Вместо X[1,1,3] можно записать: X[3], а вместо X[1,2,1] использовать равносильную запись X[6].