Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
15.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
98 Кб
Скачать
☆

15.2. Константы.

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

Константные значения могут быть заданы именами с использованием объявлений, как следующие:

CONST

LastCh = ‘#’;

FieldWidth = 4;

Max = 9999;

Min = -Max;

Name = ‘Blaise Pascal’;

Поскольку константный идентификатор, представленный объявлением константы, именует значение, он имеет тот же тип и может появляться везде, где могут встречаться значения этого типа. В следующем примере, использующем приведенное выше объявление констант, Min и Max используются для объявления диапазона, LastCh сравнивается с символьным значением, FieldWidth управляет размером поля в котором распечатываются значения типа SmallInt, Name используется в операторе Write.

TYPE

SmallInt = Min .. Max;

VAR

Value: SmallInt;

Ch: CHAR;

BEGIN

...

WHILE Ch <> LastCh

DO

...

READ(Value);

WRITELN(Value:FieldWidth);

WRITELN(Name);

...

END

Синтаксис для раздела объявлений констант представлен ниже.

<раздел объявлений констант> ::= CONST <объявления констант> |

<объявления констант> ::= <объявления констант> <объявление константы> |

<объявление константы>

<объявление константы> ::= <идентификатор> = <константа>;

<константа> ::= <знак> <беззнаковое число> | <беззнаковое число>

| <знак> <идентификатор константы> | <идентификатор константы>

| <строка символов>

<идентификатор константы> ::= <идентификатор>

Контекстное правило, которое сопровождает данные синтаксические правила утверждает, что только <идентификаторы> которые появляются в <объявлении констант> являются <константными идентификаторами>. Эти специальные идентификаторы не могут быть использованы как если бы они были переменными, потому что их значения фиксированы. Например, константный идентификатор не может появляться в левой части оператора присваивания или как фактический параметр, соответствующий формальному VAR параметру.

Константные идентификаторы помогаю документировать программы и облегчают последующие изменения программ. Объявление константы LastCh с фиксированным значением # и использование LastCh вместо литерала ‘#’ улучшает программу. Рассмотрим следующий фрагмент:

CONST

LastCh = ‘#’;

VAR

Ch: CHAR;

BEGIN

WHILE Ch <> LastCh

DO

...

WRITELN(‘Инвентарный #:’)

END

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

CONST

LastCh = ‘$’;

Поиск и замена # на $ по всему телу программы одновременно и утомительно и чревато внесением ошибок. Например, мы по ошибке можем заменить # на $ в последнем операторе WRITE.

15.3. Типы

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

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

TYPE

CType = CHAR;

Ct = CType;

Month = (NoMonth, Jan, Feb, Mar, Apr, May, Jun,

Jul, Aug, Sep, Oct, Nov, Dec);

Summer = Jun .. Aug;

DayNum = 1 .. 31;

Letter = ‘A’ .. ‘Z’;

Идентификаторы как Letter могут встречаться везде, где встречаются в объявлениях списках формальных параметров. Идентификаторы типов – это удобное сокращение – именуя список констант, идентификаторы как Month могут легко повторяться в программе без опасности, что объявление тип может быть задано некорректно.

Синтаксис объявления типа приведен ниже:

<раздел объявлений типов> ::= TYPE <объявления типов> |

<объявления типов> ::= <объявления типов> <объявление типа>

| <объявление типа>

<объявление типа> ::= <идентификатор> = <обозначение типа>;

<обозначение типа> ::= <идентификатор типа> | <новый тип>

<новый тип> ::= <новый порядковый тип>

<новый порядковый тип> ::= <перечислимый тип> | <тип диапазон>

Одно из наиболее важных направлений использования идентификаторов типов – списки формальных параметров.

<список формальных параметров> ::= ( <формальные параметры> ) |

<формальные параметры> ::= <формальные параметры>; <формальный параметр>

| <формальный параметр>

<формальный параметр> ::= <параметр переменная>

<параметр переменная> ::= VAR <список идентификаторов> : <идентификатор типа>

Каждый формальный параметр должен быть объявлен с идентификатором типа.

Таким образом, ни один из формальных параметров не в следующем заголовке процедуры не объявлен корректно:

PROCEDURE Proc

(VAR Mo: (NoMonth, Jan, Feb, Mar, Apr, May

b Jun, Jul, Aug, Sep, Oct, Nov, Dec);

VAR Day: 1..31;

VAR Finitial, Linitial: ‘A’ .. ‘Z’);

поскольку они все объявлены не с помощью идентификаторов типа. Заголовок процедуры может быть записан корректно с помощью предшествующего введения объявлений типов.

TYPE

Month = (NoMonth, Jan, Feb, Mar, Apr, May, Jun,

Jul, Aug, Sep, Oct, Nov, Dec);

DayNum = 1 ..31;

Letter = ‘A’ .. ‘Z’;

PROCEDURE Proc (VAR Mo: Month; VAR Day: DayNum;

VAR Finitial, Linitial: Letter);

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

Контекстные правила, регулирующие согласование типов, следующие:

  1. Фактические параметры должны иметь одинаковые типы, что и соответствующие формальные параметры.

  2. Тип переменной в левой части присваивания должен быть совместим для присваивания с типом выражения в правой части.

  3. Операнды операций сравнения должны иметь совместимые типы.

В Паскале два типа являются одинаковыми, если они были определены как эквивалентные в объявлениях типов. Переменные имеют одинаковый тип если они объявлены с идентификаторами типов, которые являются одинаковыми, или одинаковый тип объявлен вместе с объявлением переменной. Например, рассмотрим объявления:

TYPE

T1 = INTEGER;

T2 = T1;

SmallInt = 0 .. 9;

Age = 0 .. 9;

VAR

W: SmallInt;

X: 0 ..9;

Y, Z: 0 .. 9;

Типы INTEGER, T1 и T2 в примере выше являются одинаковыми. SmallInt и Age не являются одинаковыми. Y и Z имеют одинаковый тип, но технически X имеет различный тип.

В следующем фрагменте программы на Паскале, используя выше приведенные объявления, только W может быть передано P, поскольку это единственная переменная тот же типа что и Parm.

PROCEDURE P (VAR Parm: SmallInt);

...

P(W); {допустимо – Parm и W имеют одинаковый тип SmallInt}

P(X); {недопустимо – Parm и X имеют разные типы}

P(Y); {недопустимо – Parm и Y имеют разные типы}

...

Два типа, T1 и T2, совместимы если справедливо следующее:

  • T1 и T2 имеют одинаковый тип.

  • T1 является диапазоном T2 или T2 является диапазоном T1 или оба типа являются диапазонами одного владеющего типа.

В примере выше, тип X совместим с Y, потому что оба являются диапазонами INTEGER. Переменные Letter и Digit в следующем примере имеют совместимые типы, потому что оба типа определяют диапазон одного владеющего типа CHAR.

VAR

Letter: ‘A’ .. ‘Z’;

Digit: ‘0’ .. ’9’;

BEGIN

...

IF (Digit <= ‘0’) OR (Digit = Letter)

...

END

Таким образом, Digit может быть сравнена с константой ‘0’ типа CHAR и с Letter.

Значение типа T2 совместимо для присваивания с типом T1. если выполняется одно из следующих условий:

  • T1 и T2 имеют одинаковый тип (но не файловый тип)

  • T1 и T2 совместимые порядковые типы и значение типа T2 лежит в интервале возможных значений T1.

В следующем примере только первые два оператора присваивания допустимы.

TYPE

SmallInt = 0 .. 99;

SmallerInt = 0 .. 9;

VAR

X: SmallInt;

Y: SmallerInt;

BEGIN

X := 0; {Тип X (SmallInt) совместим с типом 0 (INTEGER)

и 0 лежит в интервале возможных значений типа

SmallInt}

Y := X; {Тип Y (SmallerInt) совместим с типом X

(SmallInt) и значение X (0) лежит в интервале

возможных значений типа SmallerInt}

Y := X - 1; {Тип Y (SmallInt) совместим с типом 0 (INTEGER)

и 0 лежит в интервале возможных значений типа

SmallInt}

END

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]