Дмитрий Поляков - Программирование в среде Турбо Паскаль стр 18.

Шрифт
Фон

В этом примере имена X и Y - разные идентификаторы одного и того же значения. Изменение значения X равносильно изменению значения Y, ибо после объявления Y с указанием 'absolute X', ее значение будет располагаться в тех же ячейках памяти, что и X. Но для X до этого будет отведено место обычным путем - в сегменте данных. Можно совмещать разнотипные переменные, как это сделано с dim и rec. Запись с четырьмя полями вещественного типа совмещена со значением массива из четырех таких же чисел. После объявления 'absolute dim' становятся эквивалентными обращения

dim[1] и rec.x1,

dim[2] и rec.y1,

dim[3] и rec.x2,

dim[4] и rec.y2 .

Разрешение подобных совмещений открывает большие возможности для передачи значений между различными частями программ и их использования. Директива absolute - это подобие средств организации COMMON-блоков и оператора EQUIVALENCE в языке Фортран.

При совмещении переменных сложных типов (например, dim и rec) их типы не должны конструироваться по ходу объявления, а обязаны быть введены ранее в блоке TYPE. Нарушение этого правила компилятором практически не анализируется, а последствия его могут быть самыми неприятными, вплоть до "зависания" ПЭВМ (особенно при работе с сопроцессором).

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

| VAR

| St : String[30];

| StLen : Byte absolute St;

Здесь значение StLen совмещено со значением текущей длины строки St, которое хранится в элементе строки St[0]. Не рекомендуется совмещать большие по длине переменные с меньшими. Если в последнем примере запись значения в StLen может попортить лишь строку St, то в случае

- 82 -

| VAR

| StLen : Byte;

| St : String absolute StLen;

Другие объявления;

изменение St изменит не только байт StLen, но и значения тех переменных, которые будут объявлены после St.

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

Совмещение переменных - мощное, но очень опасное при неумелом обращении средство. Помните об этом!

5.2.2. Переменные со стартовым значением или типизированные константы

Когда программа начинает работать, места под значения переменных уже отведены, но не очищены. Это означает, что в ячейках памяти может быть что угодно (остатки предыдущей программы или ее следы). Поэтому в Паскале очень важно, чтобы каждая переменная перед использованием была бы заполнена имеющим смысл или хотя бы пустым (нулевым) значением.

Выполнить это требование можно, начиная программу со "скучной" переписи переменных

х := 0; у := 10;

ch := 'z';

Особенно неприятно задавать значения массивов и записей, так как это надо делать поэлементно.

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

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

Простые значения задаются переменным обычным приравниванием после описания типа:

- 83 -

| CONST

| R : Real = 1.1523;

| i : Integer = -10;

| S : String[10] = 'Привет!';

| P1 : Pointer = nil;

| P2 : Pointer = Ptr($A000:$1000);

| Done : Boolean = True;

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

Стартовые значения сложных переменных задаются по-разному для различных типов. Массивы задаются перечислением их элементов в круглых скобках. Если массив многомерный (массив массивов), то перечисляются элементы-массивы, состоящие из элементов-скаляров. Выглядит это следующим образом:

| TYPE

| Dim1x10 : Array [1..10] of Real;

| Dim4x3x2 : Array [1..4, 1..3, 1..2] of Word;

{** это то же самое, что и задание: **}

{**Array [1..4] of Array [1..3] of Array [1..2] of Word **}

| CONST

| D1x10 : Dim1x10 =

| (0, 2.1, 3, 4.5, 6, 7.70, 8., 9.0, 10, 3456.6);

| D4x3x2 : Dim4x3x2 = (((1,2), (11,22), (111,222)),

| ((3,4), (33,44), (333,444)),

| ((5,6), (55,66), (555,666)),

| ((7,8), (77,88), (777,888)));

Здесь самым глубоким по уровню вложенности в задании переменной D4x3x2 (многомерного массива) оказывается самый дальний в описании типа массив - двухэлементный массив значений Word. Более высокий уровень - это уже массив из трех двухэлементных массивов, а вся структура переменной D4x3x2 состоит из четырех наборов по три массива из двух чисел.

Тот же способ использования скобок применяется и при задании значений типа "запись". Только надо явно указывать имя поля перед его значением:

- 84 -

| TYPE

| RecType = RECORD { тип запись }

| x, y : LongInt;

| ch : Char;

| dim : Array [1..3] of Byte

| END;

| CONST

| Rec : RecType = ( x : 123654; у : -898; ch : 'A';

| dim : (10, 20, 30));

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

В принципе, можно конструировать тип прямо в описании переменной, например:

| CONST

| XSet : Set Of Char = [ 'а', 'б', 'в' ];

но предпочтительнее использовать введенное ранее имя этого типа.

При задании структур типа Array of Char, базирующихся на символах, можно не перечислять символы, а слить их в одну строку соответствующей длины:

| CONST

| CharArray : Array [1..5] of Char='abcde'; {пять символов}

Типизированные константы (переменные со стартовым значением) могут быть и глобальными, и локальными, как любые другие переменные. Но даже если объявляется переменная со значением внутри процедуры, т.е. заведомо локальная, то ее значение будет размещено не в стеке, а в сегменте данных. (Об этом подробнее см. разд. 6.9.6.2 "Статические локальные переменные".)

Особенностью компилятора Турбо Паскаль (точнее, его редактора связей - компоновщика) является то, что в выполнимый код программы не входят те переменные, которые объявлены, но не используются. То же самое имеет место и для типизированных констант. Но минимальным "отсекаемым" компоновщиком куском текста программы может быть лишь блок описания CONST или VAR. Поэтому, если заведомо известно, что не все объявляемые переменные будут использоваться одновременно, лучше разбивать их на различные блоки объявлений:

- 85 -

| VAR

| x1, х2, хЗ : Real;

| VAR

| y1, y2, y3 : Integer;

| CONST

| Dim1 : Array [4..8] of Char = '4567';

| CONST

| Dim10tladka : Array [1..10] of Char = '0123456789';

и т.д.

Смысл программы это не изменит, а компоновщик сможет доказать свою эффективность.

5.3. Операция присваивания и совместимость типов и значений

Если в программе объявлены переменные, то подразумевается, что они будут получать свои значения по ходу ее выполнения. Единственный способ поместить значение в переменную - это использовать операцию присваивания в программе:

Переменная := Значение;

Оператор присваивания - это составной символ ":=". Его можно читать как "становится равным". В операции присваивания слева всегда стоит имя переменной, а справа - то, что представляет собой ее значение (значение как таковое или выражение либо вызов функции, но может быть и другая переменная). После выполнения присваивания переменная слева получает новое значение.

Турбо Паскаль, являясь языком с сильной системой типов, требует соблюдения определенных правил совместимости типов переменных и значений справа и слева от оператора ":=".

Очевидно, что не может быть проблем с присваиванием, если типы переменной и значений идентичны (тождественны). Два типа Type1 и Туре2 считаются идентичными, если:

1. Типы Type1 и Туре2 описаны одним и тем же идентификатором типа, например:

| TYPE

| Тype1 = Boolean;

| Type2 = Boolean;

здесь Type1 и Type2 идентичны. Но в случае

- 86 -

| TYPE

| Type1 = Array [1..2] of Boolean;

| Type2 = Array [1..2] of Boolean;

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке