Заказ
  PHP скрипты   NEW
Правила написания
Студенту
Банк Рефератов
# A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я
Телефонные справочники
Выбор города:
А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

Онлайн телефонные справочники
Выбор города:
А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Х Ш Э Ю Я

скачай готовый реферат
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я

Object Pascal



Тема: Object Pascal
Вид реферата: реферат
Дисциплина: Информатика, программирование
Оценка: Отлично/Хорошо
Формат: Microsoft Word документ
Сжатие: ZIP архив
Создан: 7 января 2007 года
Уникальность: 100%


скачать реферат Object Pascal


Object Pascal

1. Основы языка Object Pascal

1.1. Алфавит языка

Основными символами языка Object Pascal являются:

символы _ + -

26 больших и 26 малых латинских букв A,B, …Y,Z, a,b, …, y,z

10 арабских цифр 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

специальные символы * / = ^ < > ( ) [ ] { } . , : ; ' # $ @

Буквы русского алфавита не входят в состав алфавита языка. Их использование допустимо только в строковых и символьных значениях.

Нет различий при использовании больших и малых букв в записи имен переменных, процедур, функций и меток. Их максимальная длина ограничена 126 символами.

1.2. Краткие сведения о структуре программы

Программа, написанная в среде Delphi при помощи языка Object Pascal, всегда состоит из нескольких модулей. Как минимум таких модулей должно быть два. Один модуль всегда является головной программой и имеет название program. Прочие модули играют вспомогательную и зависимую от головной программы или от других модулей роль и называются unit. Минимально структурированная программа имеет один модуль program и один модуль unit. Серьезные программы помимо модуля program могут содержать до нескольких десятков авторских модулей unit и большое количество ссылок на фирменные или разработанные как самим автором, так и другими разработчиками модули unit.

Программа всегда начинает работу с модуля program, активизируя функционирование одного или нескольких зависимых модулей unit. Те в свою очередь могут активизировать другие модули unit и т.д.

Исходный программный текст каждого модуля составляется на языке Object Pascal и помещается в отдельный файл, который всегда имеет расширение .pas. Текст модуля program имеет расширение .dpr.

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

1.3. Лексическая структура языка

Строительным материалом для конструирования программного текста модуля являются лексемы – особые языковые конструкции, имеющие самостоятельный смысл. Лексемы строятся при помощи символов алфавита языка. В Object Pascal различают следующие основные классы лексем:

Зарезервированные (служебные) слова. Этот класс состоит из слов, построенных только с помощью букв алфавита. Служебные слова можно использовать только по прямому назначению, т. е. так, как их назначение определил разработчик языка. Ни в каком другом виде, например в качестве имен переменных, их использовать нельзя.

Ниже представлен список таких слов:

And

asm

class

destructor

do

end

file

for

if

inherited

interface

library

not

or

procedure

raise

resource

shl

then

try

until

while

with

array

begin

const

dispose

downto

except

finalization

function

implementation

initialization

in

interface

is

mod

object

out

program

record

string

shr

threadvar

type

uses

as

case

constructor

div

else

exports

finally

goto

in

line

label

nil

of

packed

property

repeat

set

string

to

unit

var

xor

Кроме того, нельзя использовать следующие слова, не принадлежащие к этому классу: private, protected, public, published, automated, directives, on, virtual.

Идентификаторы (имена). Идентификаторы или имена предназна-чены для обозначения констант, переменных, типов, процедур, функций, меток. Они формируются из букв, цифр и символа "_" (подчеркивание). Длина имени может быть произвольной, однако компилятор учитывает име-на по его первым 63 символам. Внутри имени не должно быть пробелов.

Object Pascal в именах не различает больших и малых букв. Так следующие имена будут идентичны:

SaveToFile, SAVETOFILE, savetofile, sAVEtOfILE.

Среди программистов установилось хорошее правило, в соответствии с которым имена формируются таким образом, чтобы одновременно выпол-нять роль комментария, поясняющего назначение имени. Так, в приведенном примере имя переводится с английского как "сохранить в файле". Кроме того, с учетом невозможности вставки внутрь такого имени пробелов, первые буквы слов обычно пишут заглавными, а прочие строчными. Из приведенного примера хорошо видно, что именно такой способ записи наиболее нагляден для визуального восприятия имени. Нередко в качестве заменителя пробела используют символ "_". Однако это удлиняет и без того длинные имена. Преимущества длинных имен совсем не означают, что нельзя применять короткие имена. Понятно, что проще набрать с клавиатуры и использовать оператор

a := a + 1,

чем идентичный ему оператор

Disk_C_DirctoryCounter := Disk_C_DirctoryCounter +1.

Следует, однако, с большой осторожностью использовать короткие имена, т. к. это нередко приводит к путанице между глобальными и локальными переменными, обозначенными одинаковыми именами, и, как следствие, к ошибкам в работе программы. Наиболее удобным, безопасным и желательным можно считать локальное использование коротких имен, когда они описаны и использованы внутри какой-нибудь сравнительно небольшой по объему текста процедуры или функции и их действие ограничено пределами только этой алгоритмической единицы. При подозрении на путаницу, действие такой переменной легко проконтролировать визуально.

Изображения. К их числу относятся константы, символьные строки и некоторые другие значения.

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

Разделители используются с целью большего структурирования модуля, с тем чтобы повысить визуальное восприятие длинных текстов. К их числу можно отнести ; := ( .

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

Примеры комментариев:

{ Функция вычисления количества дней между двумя датами }

(* Функция вычисления количества дней между двумя датами *)

// Неправильный ответ

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

1.4. Некоторые важные понятия

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

Ячейка. Этот несколько устаревший, но весьма удобный термин обозначает фрагмент памяти, который можно представить как некий контейнер для хранения данных определенной структуры. Ячейка всегда имеет свое уникальное имя, которое служит адресом, по которому расположены находящиеся в ней данные. Примером ячейки могут служить любые разрешенные имена, например a1, Imk12, Count и т. д. Термин "ячейка" не является языковым термином Object Pascal и используется здесь только для большей наглядности при описании основ языка.

Значение – это постоянная величина или структурный комплекс постоянных величин, выраженных в явном виде. Значение не имеет имени.

Примеры значений:

-55.455051 { обыкновенное вещественное число},

'Расчет посадки с натягом' {строка символов}.

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

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

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

Тип – это структура и описание множества значений, которые могут быть присвоены переменной.

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

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

x := y; { читается "x присвоить y" }

Здесь x – переменная, y – выражение. Выражением могут быть, в частности, переменная, константа или значение. Последовательность символов ":=" обозначает операцию присваивания, в соответствии с которой сначала вычисляется выражение y, затем получившийся результат в виде значения записывается в переменную x (см. подробнее гл. 9).

Примеры:

d := 5; { значение 5 записывается в переменную D },

h := d + 12.5; { выч. 5+12.5, рез. 17.5 записывается в переменную h }.

2. Система типов

В языке Object Pascal все переменные, т. е. ячейки памяти, предназначенные для записи, чтения и хранения значений, должны быть предварительно описаны. Это означает, что всякая переменная должна быть явно отнесена к какому-либо типу.

Тип – это одновременно структура и описание множества значений, которые могут быть присвоены такой переменной.

Язык Object Pascal имеет множество разнообразных типов. Более того он позволяет самому пользователю конструировать самые разнообразные типы, которые могут быть ему необходимы. Конструирование таких типов производится из сравнительно ограниченного количества стандартных типов.

Типы имеют свою иерархию. На верхнем этаже иерархии расположены следующие типы: простые, составные, ссылочные и процедурные.

3. Стандартные простые типы

Основными типами языка являются стандартные простые типы и стандартные структурные типы.

Простые типы делятся на скалярные и ограниченные типы. Cкалярные типы делятся на стандартные и перечислимые. Стандартные скалярные типы делятся на пять видов:

целые [Integer],

вещественные [Real],

логический (булевский) [Boolean],

символьные [Char],

строковые [String].

К ним примыкает особый вариантный тип [Variant].

3.1. Целые типы

Эта группа типов охватывает множество целочисленных значений. Они отличаются друг от друга диапазоном допустимых значений и количеством занимаемой памяти.

Целыми типами являются ShortInt, SmallInt, LongInt, Int64, Byte, Word и LongWord, характеристики которых приведены в табл. 1.

Таблица 1

Тип

Диапазон значений

Размер памяти

1.

2.

3.

4.

5.

6.

7.

ShortInt

SmallInt

LongInt

Int64

Byte

Word

LongWord

–128 .. 127

–32768 .. 32767

–2147483648 .. 2147483647

–2^63 .. 2^63–1

0...255

0...65535

0 .. 4294967295

1 байт

2 байта

4 байта

8 байтов

1 байт

2 байта

4 байта

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

Так если значения переменной будут только положительными, то можно ее отнести к одному из типов Byte, Word, LongWord. Если известно также, что ее значения никогда не выйдут за 255 (например, если переменная предназначена для хранения номера месяца текущего года), то лучше использовать тип Byte. При этом память будет расходоваться наиболее экономно.

Не следует, однако, стремиться к излишней экономии памяти на переменных. Нередко экономно описанная переменная может привести к ситуации, когда программа попытается записать в нее такую константу, которая превышает допустимый диапазон значений. Это приведет к немедленному аварийному завершению программы с сообщением "Range check error" (выход за допустимые границы диапазона). Сообщения такого рода могут генерироваться самыми разными операциями и в самых разных местах программы. По этой причине поиск ошибки в программе, особенно если она многомодульна и сложна, может надолго затянуться.

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

Примеры:

Var

A, A_Par: Integer;

T1, T2, T3: LongInt;

CircleCounter: byte;

Значения целых типов изображаются в обычном десятичном или в шестнадцатеричном видах. Они отличаются тем, что при изображении шестнадцатеричных значений в его начале ставится символ $ и сами значения формируются из шестнадцатеричных цифр 0 .. 9, A ... F.

Максимально допустимый диапазон значений определяется их типом.

Примеры:

0 9877 -56 $F1 ( то же, что 241)

Над целыми значениями можно выполнять четыре обыкновенных арифметических действия: сложение (+), вычитание (-), умножение (*), деление (/) и два дополнительных действия: деление нацело (div) и взятие остатка от деления (mod). При выполнении деления результатом будет вещественное значение, во всех остальных операциях – целое.

3.2. Вещественные типы

Эта группа типов охватывает вещественные значения.

Вещественные типы не могут быть использованы:

в качестве индексов массивов;

в операторах For и Case;

в качестве базисного типа при определении множеств;

при определении подтипов.

При описании вместо Real48 можно указывать Real.

Ниже в табл. 2 приведен список типов и их характеристики.

Таблица 2

Тип

Диапазон значений

Значащих цифр в мантиссе

Размер памяти

1.

2.

3.

4.

5.

6.

Real48

Single

Double

Extended

Comp

Currency

2.9 x 10^–39 ... 1.7 x 10^38

1.5 x 10^–45 ... 3.4 x 10^38

5.0 x 10^–324 ... 1.7 x 10^30

3.6 x 10^–4951 ... 1.1 x 10^4932

-2^63+1 ... 2^63 -1

-922337203685477.5808 ... 922337203685477.5807

11 – 12

7 – 8

15 – 16

19 – 20

19 – 20

19 – 20

6 байтов

4 байта

8 байтов

10 байтов

8 байтов

8 байтов

Примеры:

Var

rA, rA_Par: Real;

T: Integer;

Вещественные значения можно изобразить:

в форме с фиксированной десятичной точкой;

в форме с плавающей десятичной точкой.

Первая форма представления вещественного значения представляет привычное число, в котором целая и дробная части разделены десятичной точкой, например

12.455

-988.45

-8.0

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

E

Примеры:

-45.2E6 ( то же, что -45,2 106)

5.245E-12 ( то же, что 5,24 10-12)

Порядок таких чисел должен быть всегда целым числом.

3.3. Логический (булевский) тип

Логические переменные имеют тип boolean. Такая переменная занимает один байт памяти и может иметь одно из двух возможных значений – True (истина) или False (ложь).

Примеры:

Var

b : boolean;

b1, Ti : boolean;

3.4. Символьный тип

Типы AnsiChar и WideChar описывают множество отдельных символов языка, включая буквы русского алфавита. AnsiChar описывает множество из 256 ASCII-кодов и занимает один байт памяти, WideChar описывает мно-жество Unicode – универсальное множество кодов и занимает два байта памя-ти. Тип AnsiChar эквивалентен базовому типу Char прежних версий языка.

Примеры:

Var

Ch, k : AnsiChar;

Char_Massivr: array[1..100] of Char;

Символьное значение представляют в виде символа, заключенного с обеих сторон в апострофы. Для изображения самого апострофа его удваивают (последний пример), например:

'h' 'X' '#' '$' ''''

3.5. Строковые типы

Этот тип во многом схож с типом Array of Char, т. е. массивом символов. Отличие состоит в том, что переменная этого типа может иметь динамическое количество символов (от нуля до верхней границы), в то время как массив символов всегда статичен и имеет одинаковое количество символов.

Таблица 3

Тип

Длина строки

Занимаемая память

1.

2.

3.

ShortString

AnsiString

WideString

0 – 256 символов

0 – 2 Гб символов

0 – 2 Гб символов

(Кол-во символов) х 1 байт

(Кол-во символов) х 1 байт

(Кол-во символов) х 2 байта

Максимальная длина строковой переменной должна быть указана явно. Размер строки на единицу больше ее объявленной длины, т. к. в ее нулевом байте содержится фактическая длина строки. Длину в нулевом байте можно принудительно менять.

Особо следует выделить тип String. Если длина String-строки не объявлена, то при действии директивы компилятора {$H+} или без ее указания такое объявление равносильно AnsiStrig. Если установлена директива {$H-}, то тип String равносилен типу ShortString.

Строковое значение изображают в виде последовательности символов, заключенной в апострофы. Пустую строку изображают двойным апострофом.

Примеры значений строковых типов:

'Иванов И.И.' '' 'Газета"ИЗВЕСТИЯ"' 'Строка символов'

Примеры описания переменных строковых типов:

Var

s1, s2 : ShortString [12];

st1, st2 : AnsiString [580];

ChMassiv: array [1..15] of String;

3.6. Строковый тип PChar

Для связи с функциями Windows в язык Object Pascal введен новый тип строк – PChar-строки с завершающим нулем. В обычной и привычной для прежних версий языка String-строке нулевой байт отведен для хранения реального количества символов этой строки, а сами символы последовательно располагаются начиная с первого байта. В PChar-строке, наоборот, символы располагаются начиная с нулевого байта, а их последовательность заканчивается завершающим нулем.

Строки PChar можно объявлять как обычные символьные массивы. Например, строку длины 3000 плюс один байт, зарезервированный под завершающий нуль, можно определить следующим образом:

Var

s: array[1 .. 3000] of Char;

П р и м е ч а н и е. Без необходимости не используйте PChar-строки. Строковые String-типы и функции для обработки таких строк хорошо отлажены, они легче в использовании, и, как правило, надежнее PChar-строк.

3.7. Динамические PString-строки

Этот тип строк так же, как PChar, введен в язык для обращения к функциям Windows. Подробнее PString-строки описаны далее.

3.8. Перечислимые типы

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

Примеры перечислимых типов:

Type

MaleNames = (Ivan, Peter, Serge);

SwithOpts = (On, Off);

SostTypes = (Active, Passive, Waiting);

Sides = (Left, Right, Top, Down);

В первом примере переменная объявленного типа может принимать значение одного из трех мужских имен. Во втором – одно из двух значений – On (включено) или Off (выключено) и т. д.

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

Например, описания вида

Type

Days1 = (Monday, Wednesday, Friday);

Days2 = (Tuesday, Wednesday, Saturday, Sunday);

содержат ошибку, т. к. константа Wednesday используется дважды.

3.9. Ограниченные типы

Этот тип формируется самим пользователем посредством сужения значений ранее определенного или стандартного типов.

Примеры:

Type

Diapason = 1 .. 30;

Letters = 'a' .. 'v';

TList = (t1, t2, t3, t4, t5, t6,t7, t8, t9, t10);

TlistSmall = (t2 .. t8);

3.10. Вариантный тип (Variant)

Тип Variant – особый тип языка Object Pascal. Значение этого типа наперед неизвестно, однако может быть определено через присваиваемое значение одним из следующих типов: все целые, вещественные, строковые, символьные и логические типы, за исключением Int64.

Следующие примеры демонстрируют использование типа Variant и механизм конверсии типов при смешивании его с другими типами. Сопроводи-тельные комментарии поясняют правила, при помощи которых операторы присваивания меняют тип Variant-переменных в зависимости от принятого ими значения.

Var

V1, V2, V3, V4, V5: Variant; {описание Variant-переменных }

I: Integer;

D: Double;

S: string;

...

begin

V1 := 1; { integer-значение }

V2 := 1234.5678; { real-значение }

V3 := 'Иванов'; { string-значение }

V4 := '1000'; { string-значение }

V5 := V1 + V2 + V4; { real-значение 2235.5678}

I := V1; { I = 1 (integer-значение) }

D := V2; { D = 1234.5678 (real-значение) }

S := V3; { S = ' Иванов' (string-значение) }

I := V4; { I = 1000 (integer-значение) }

S := V5; { S = '2235.5678' (string-значение) }

end;

3.11. Тип "дата – время"

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

Type

TDateTime = Double;

TDate = TDateTime;

TTimeStamp = Record

Time: Integer; { время в миллисекундах от полуночи }

Date: Integer; { единица + число дней с 01.01.0001 г.}

end;

Тип TDateTime предназначен для хранения даты и времени.

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

Описание переменной или группы переменных начинается словом Var. Область видимости переменной будет подробно описана ниже.

Общий вид описания переменных одного типа:

: ;

Пример:

Var

t_s1, t_q1: String[255];

rt1, rt2: (Opened, Closed, Unknown);

Re1, Re2, Re3: Real;

i: Integer;

В этом примере переменные t_s1 и t_q1 описаны как строковые переменные типа String[255]. При работе программа выделит под каждую из них с учетом нулевого байта по 256 байтов памяти для хранения символьных значений. Переменные rt1, rt2 объявлены как переменные, которые могут принимать в определенный момент времени одно из перечисленных значений: Opened, Closed, Unknown. Переменные Re1, Re2, Re3 объявлены вещественными, а переменная i – целочисленной типа Integer.

Переменными могут быть объявлены не только переменные простых типов. Ниже будут рассмотрены переменные более сложных – структурных – типов. Более того, переменными могут быть объявлены структуры структур, примером которых являются классы. Например:

type

TKdnClass = class(TObject)

End;

Var

Ts: Record

A, N: Integer;

End;

Cl: TKdnClass;

5. Описание констант

В Object Pascal различается два вида констант – обыкновенные и типизованные. Описание констант следует после слова Const.

5.1. Обыкновенные константы

Описание константы строится по правилу

= ;

Примеры:

Const

T_Par = 12899;

M_ArrayCount = 16;

Middle_M_Array = M_ArrayCount div 2;

RealMax = 1.7e38;

StarString = '* * * * * * * * * * * * *';

Log10 = 2.302585;

Log10_Invert = 1/Log10;

LeftArrayBound = -M_ArrayCount;

Тип константы определяется автоматически по виду ее значения.

Существует несколько констант, которые заранее предопределены и не требуют описания:

Pi = 3.1415926536E+00 (тип Real)

False, True ( Boolean)

MaxInt = 32767 ( Integer)

MaxLongInt = 2147483647 ( LongInt)

Nil ( Pointer).

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

Const

ArrMax = 100;

nSt = 46;

Var

IntArr: Array[1..ArrMax] of Integer;

StrArrr: Array[1..ArrMax] of String[nSt];

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

Типизованные константы

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

Простые типизованные константы. Общий вид константы:

: = ;

Примеры:

Const

CurrentPosition: Word = 11000;

LastLetter: Char = 'z';

HeadOfModule: String[26] = 'Начало программного модуля';

Типизованные константы нельзя использовать для описания динамических структур. Следующий пример демонстрирует недопустимое описание динамического массива Arr через типизованную константу ArrMax:

Const

ArrMax: Integer = 100;

Var

IntArr: Array [1..ArrMax] of Integer; { Ошибка }

Значение типизованных констант можно изменять в ходе выполнения программы, и они могут быть использованы в качестве Var-параметра процедуры или функции. В этой связи типизованные константы по сути являются переменными с начальным значением.

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

Type

tVotes = (Yes, No, UnDef);

tVoteArr = array [tVotes] of String [7];

Const

Votes : tVoteArr = ( 'Да', 'Нет', 'Не знаю' );

Var

V: tVoteArr;

S: String[20];

V:= Votes;

S:=V[UnDef];

Здесь в секции Type сначала описан перечислимый тип tVote из трех значений Yes, No, Undef. Затем через этот тип определен новый тип tVoteArr как тип-массив из трех элементов, каждый из которых является строкой длины 7. Далее в секции Const определена типизованная константа Votes, которая определена как массив трех строковых значений ('Да', 'Нет', 'Не знаю'). Затем в секции Var описаны переменные V и S разных типов. Предпоследняя и последняя строки являются исполняемыми операторами присваивания. Сначала переменной V присвоено начальное значение – константа Votes. Затем переменной S присвоено значение третьего элемента массива V. В результате значением строковой переменной S будет 'Не знаю'.

Типизованные константы типа "запись". Это комбинированный тип констант, основанный на конструкциях типа Record (см. параграф 7.1), которые состоят из полей. Константы такого типа определяются по правилу "имя поля : значение поля".

Пример:

Type

tDayOfYear = Record {день года}

Week : (Mon,Tue,Wed,Thu,Fri,Sat,Sun); {день недели}

Num : 1 .. 31; {день месяца}

Month : 1 ..12; {месяц }

Year : 1951 .. 2050; {год}

End;

Const

D1 : (Week : Sun; Num : 26; Month : 10; Year : 2001 D1, которая представляет конкретную дату "Воскресенье, 26, октябрь);

Здесь в секции Type описана запись, состоящая из четырех полей и характеризующая день года. Назначения этих полей понятно из сопроводительных комментариев. Затем в секции Const описана типизованная константа (Sun; 26; 12; 2001), т. е. " Воскресенье, 26 октября 2001 года".

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

Примеры:

Type

tChildNameSet = set of ['Таня', 'Валя', 'Володя', 'Гена'];

Const

Girls2Set : tGirlsNamesSet = ['Валя', 'Гена'];

Indexes: set of integer = [300 .. 500, 1777,3700];

Здесь в секции Type описано множество из четырех имен детей. Ниже в секции Const описано две константы, каждая из которых представляет подмножества. Первая – подмножество имен, объявленных ранее в tChildNameSet, вторая – подмножество целых чисел типа Integer.

6. Описание типов

Ранее уже приводились примеры описания переменных, в которых их тип указывался в Var-секции явно или на основе ранее объявленного пользовательского типа.

Описание секции типов начинается словом Type.

В табл. 4 дан пример двух идентичных способов описания переменных t, u, n.

Таблица 4

Явный способ описания

переменных

Описание переменных с предварительным описанием их типа

Var

t,u,n:(Mon, Tue,Wed, Thu,Fri,Sat,Sun);

Type

DaysOfWeek = (Mon, Tue,Wed, Thu,Fri,Sat,Sun);

Var t,u,n: DaysOfWeek;

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

а) конкретизировать тип;

б) четко выделить множество переменных этого типа;/P>

в) повысить уровень структурированности программы;

г) снизить вероятность путаницы в типах, когда переменные фактически того же типа объявлены разными способами;

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

В этой связи важно подчеркнуть, что даже при совпадении базовых типов различие в пользовательских типах может привести к непредсказуемому поведению программы. Например, в нижеследующей секции Type два производных типа t1 и t2 имеют одинаковый базовый тип byte. Однако объявленные ниже в Var-секции переменные p1 и p2 будут расценены системой как переменные разных типов. Это обстоятельство может послужить причиной недоразумений в ходе составления и/или выполнения программы.

Type

t1 = byte;

t2 = byte;

Var

p1: t1;

p2: t2;

Корректным можно считать следующий аналог:

Type

t1 = byte;

Var

p1,p2: t1;

7. Структурные типы

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

К числу структурных относятся следующие типы:

множественные типы [Set],

регулярные типы (массивы) [Array],

комбинированные типы (записи) [Record],

файловые типы [File],

классы [Class],

классовые ссылки [Class reference],

интерфейсы [Interface].

Ниже будут подробно описаны первых четыре структурных типа – регулярный, комбинированный, множественный и файловый.

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

7.1. Регулярные типы (массивы)

Массив – это структура языка Object Pascal, представляющая собой упорядоченную совокупность элементов одного типа.

Следует различать два вида массивов: массив-тип и массив-переменную.

Массив-тип. Синтаксис маcсива-типа:

= Array [, , …, ]

Of ;

Всякий массив имеет размерность. Размерность определяется количеством типов индексов, которые заключены в квадратные скобки [ .. ].

Массив-тип предназначен для описания:

структуры массива как типа;

размерности массива;

типов индексов массива;

типа каждого элемента массива.

Так, в следующем примере

Type

tA1: array [1 .. 10] of Real;

описана структура одномерного массива вещественных элементов (Real), в котором индекс может изменяться в диапазоне целых значений от 1 до 10. Его элементами являются вещественные типы tA1[1], tA1[2], tA1[3], …, tA1[9], tA1[10].

Другой пример:

Type

Color: (Red, Green); { перечислимый тип }

Z: array [1 .. 3, Color ] of Boolean; { массив }

В нем сначала описан простой перечислимый тип Color. Ниже на его основе описан двумерный массив Z логических (Boolean) элементов. Первый индекс массива имеет целый тип, а второй – тип Color. Таким образом, массив состоит из шести элементов – логических типов:

Z [1, Red], Z [1, Green], Z[2, Red], Z[2, Green], Z[3, Red], Z[3, Green].

Массив-переменная. Синтаксис маcсива-переменной:

: Array [,, …, ]

Of ;

Массив-переменная отличается от массива-типа тем, что все его элементы – это отдельные независимые переменные, которые могут содержать различные значения одного типа.

Массив-переменная может быть описан явно или с помощью ранее определенного в секции Type типа.

В следующем примере массивы y, Z описаны идентично, причем y – явно, Z – на основе ранее определенного типа в секции Type, т. е. неявно.

Type

tA1: array [1 .. 10] of Real;

Var

y : array [1 .. 10] of Real; {массив}

Z : tA1; {массив}

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

В этой связи корректным будет любой из вариантов, приведенных в табл. 5.

Таблица 5

Корректный неявный способ

Корректный явный способ

Type tA1: array [1 .. 10] of Real;

Var Y, Z: tA1;

Var y, Z: array [1 .. 10] of Real;

Многомерные массивы содержат два и более индексов, например:

Var h: array[1 ..3, boolean, -7 .. 7] of Word;

что эквивалентно

Var h: array[1 ..3] of array[boolean] of array[-7 .. 7] of Word;

Для упакованных массивов

Var packed array[Boolean,1..10,TShoeSize] of Char;

что эквивалентно

Var

packed array[Boolean] of packed array[1..10]

of packed array[TShoeSize] of Char;

Манипуляции с отдельными элементами массивов. Обращение к отдельному элементу массива возможно через его индексы. В следующем примере в секции Var описаны простая переменная i и два одномерных массива A и V как целые переменные типа Integer. Затем в блоке begin … end расположены три вычислительных оператора.

Var

i: Integer;

A, V: array[1..100] of Integer;

begin

i:= 5;

V[8]:= i+9;

A[45]:= V[i+3]*2;

end;

При выполнении первого из них переменная i примет значение 5. При выполнении второго – восьмой элемент массива V примет значение 14. В третьем операторе сначала будет вычислен индекс i + 3 = 8, затем значение восьмого элемента массива V (значение 14) будет умножено на 2 и полученный результат – значение 28 – будет присвоено 45-му элементу массива A.

Манипуляции с массивами. Язык допускает с помощью одного оператора присваивания выполнить операцию над массивом в целом. Пусть, например, массивы A, V объявлены как квадратные матрицы. Тогда оператор

V:= A;

выполнит копирование значений всех элементов массива A в массив V, а после выполнения оператора

V:= A * V;

будет выполнено умножение матрицы А на матрицу V и результат будет помещен в матрицу V с предварительным затиранием старых значений.

Упакованные массивы. Элементы упакованного массива хранятся в памяти максимально плотно. При записи он предварительно упаковывается с целью экономии памяти. При чтении, наоборот, распаковывается. Операции упаковки и распаковки требуют дополнительного времени. Поэтому использование упакованных массивов несколько замедляет работу программы. От обычного массива Array описание упакованного массива отличается тем, что перед этим словом добавляется слово Pаcked, например:

Var W: packed array [1..100] of Integer;

7.2. Комбинированные типы (записи)

Запись – это объединение элементов разных типов. Как и в массивах, следует различать запись-тип и запись-переменную. Один элемент записи называется полем.

Запись-тип. Синтаксис записи-типа:

= Record

: ;

: ;

...

: ;

End;

Записи очень удобны для описания и хранения разнотипных данных о каких-либо однотипных структурах.

Примером могут служить сведения о студентах. Сведения о любом из них могут включать поля: Фамилия, Имя, Отчество, Год рождения, Группа, Год поступления в вуз, Курс. Такие структуры являются однотипными и могут быть описаны следующим типом:

Type

TStud = Record { Сведения о студенте как запись }

Fio : String[40]; { ФИО как строка из 40 символов }

Name : String[20]; { Имя как строка из 20 символов }

Otch : String[30]; { Отчество как строка из 30 символов }

BirthYear : Word; { Год рождения как целое типа Word }

Group : String[8]; { Группа как строка из 8 символов }

ElectYear : Word; { Год поступления как целое типа Word }

Curs : Byte; { Курс как целое типа Byte }

End;

В этом примере типы полей записи типа tStud назначены с учетом максимально возможных значений этих полей. Так, структура может хранить фамилию из не более чем 40 символов. Полю Curs назначен тип Byte, который имеет диапазон значений 0 .. 255, т. к. значением этого поля может быть одно из значений 1 .. 6, которые полностью охватываются диапазоном типа Byte. Этому полю можно было бы назначить любой другой целый тип, например Word. Однако, в целях экономии памяти, повышения скорости чтения и записи данных, следует назначить именно тип Byte, который занимает всего 1 байт памяти, а не тип Word, который требует 2 байта памяти. В то же время, например, для поля ElectYear (год поступления) тип Byte непригоден, т. к. имеет недостаточный диапазон значений.

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

Type

tPensioner = Record { пенсионер }

FioIO : String[100]; { Фамилия, имя, отчество одной строкой }

Age : Byte; { Возраст }

Case Citizen: boolean of {Горожанин ли ?}

TRUE : (Town : String[30];) {Город, в котором проживает}

FALSE: (Address : String[100]; {Полный адрес одной строкой}

Transport : String[200];) {Транспорт, которым можно добраться до города}

End;

В этом примере запись tPensioner содержит понятные поля FioIO и Age, а также поле нового вида – логическое поле Citizen вариантного типа. От значения этого поля зависит появление и непоявление некоторых потенциальных полей записи. Так если значение этого поля TRUE (истина), то в записи появляется (становится доступным) поле Town (город), при значении FALSE (ложь) – поля Address и Transport.

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

Вариантная часть должна начинаться со строки, в начале которой располагается слово Case, а в ее конце – слово Of. Между ними располагается поле-признак.

Запись должна содержать только один вариант, который должен располагаться в конце всех описанных полей непосредствено перед словом End.

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

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

Запись-переменная. Синтаксис записи-переменной:

: Record

: ;

: ;

...

: ;

End;

т.е. синтаксисы переменной и типа отличаются одним символом (":" и "=").

Пример:

Type

tMass : Array [1 .. 2, 1 .. 50] of Real;

tRec: Record

Name : String [10];

Mass2: tMass;

End;

Var

J: Integer;

S: String[70];

F,Gri : Record

a,b,c: Integer;

k: Array [1..10] of String [60];

z: tMass;

r: tRec;

End;

В секции Var описаны две простые переменные J и S и две записи F и Gri, имеющих одинаковую, но достаточно сложную структуру:

первых три поля записей F и Gri имеют имена a,b,c и тип Integer;

поле k представляет собой одномерный строковый массив из 10 элементов;

поле z имеет тип, описанный в секции Type как двумерный вещественный массив, в котором первый индекс может изменяться в диапазоне 1 .. 2, а второй индекс – в диапазоне 1 .. 50;

поле r в свою очередь само является записью, поля которой описаны типом tRec в секции Type.

Доступ к полям записей. Переменная, представляющая поле, конструируется из имени записи и поля, отделенного друг от друга десятичной точкой. Такая составная переменная называется квалификационной.

Примеры квалификационных полей вышеприведенных записей:

F.a Gri.a F.k[6] Gri.z [2, 34] F.r.Name F.r.Mass2[1, 50]

Примеры операторов присваивания с участием полей записей:

S := 'Иванов Иван Петрович';

J := 123;

F.a := J + 9;

Gri.a := ( F.a + J ) * ( F.c + F.b - Gri.c);

Gri.a := ( F.a + J ) * ( F.c + F.b - Gri.c);

F.k [1] := F.z [2,30];

Gri.r.Name := 'Студент ' + F.k [8];

Gri.a := 12 * (Gri.a + Gri.b + Gri.c);

Доступ к полям записей с помощью оператора With. Для упрощения обращения к полям одной и той же записи можно использовать оператор With.

Пример:

With Gri do

Begin

a:= 12 * (a + b + c + F.a);

b:= 64 * ( b - c);

End;

Эти операторы выполняют те же операции, что и операторы

Gri.a:= 12 * (Gri.a + Gri.b + Gri.c + F.a);

Gri.b:= 64 * (Gri.b - Gri.c);

7.3. Множественные типы

Множество – это совокупность однотипных элементов. Во многом оно похоже на типизованную константу, однако имеет от него принципиальное отличие. Это отличие состоит в том, что значениями множества являются все его допустимые подмножества.

Как и в массивах, следует различать множество-тип и множество-переменную.

Множество-тип. Синтаксис множества-типа:

= Set of ;

Пример:

Type

TSomeInts = 1..250;

TIntSet = set of TSomeInts;

создает тип множества с именем TIintSet, которое содержит множество целых чисел в диапазоне от 1 до 250. Это же множество могло быть описано явно:

type TIntSet = set of 1..250;

Множество-переменная. Синтаксис множества-переменной:

: Set of ;

В соответствии с вышеописанными типами можно объявить множества:

Var Set1, Set2: TIntSet;

а затем в операторной части задать эти множества:

...

Set1 := [1, 3, 5, 7, 9];

Set2 := [2, 4, 6, 8, 10];

Можно объявить множество явно, перечислив его элементы:

Var

MySet1 : set of 'a' .. 'z';

MySet2 : set of Byte

MySet3 : set of (Club, Diamond, Heart, Spade)

MySet4 : set of Char;

...

MySet 1:= ['a','b','c']; {оператор определения множества}

Операции над множествами. Допустимые операции над множествами приведены в следующей табл. 6:

Таблица 6

Опера-ция

Наименование операции

Тип операндов

Тип результата

Пример

+

*

=

=

in

Объединение

Вычитание

Пересечение

Не меньше

Не больше

Равенство

Неравенство

Принадлежание

set

set

set

set

set

set

set

элемент set

set

set

set

boolean

boolean

boolean

boolean

boolean

Set1 + Set2

S - T

S * T

Q = S2

S2 = MySet

MySet S1

A in Set1

Объединение, вычитание и пересечение множеств.

Результатом любой из операций будет также множество.

Пример:

Var

S1, S2,S3 : set of Byte;

...

S1:= [1, 2 , 3, 4]; {оператор определения множества}

S2:= [3, 4, 5, 6, 78]; {оператор определения множества}

S3:= S1 + S2; {объединение множеств}

{результат S3 = [1, 2, 3, 4, 5, 6, 78] }

S3:= S2 - S1; {вычитание множеств}

{результат S3 = [1, 2, 5, 6, 78] }

S3:= S2 * S1; {пересечение множеств}

{результат S3 = [3, 4] }

Операции сравнения множеств.

Результатом любой из операций будет логическая константа True (истина) или False (ложь).

Пример:

Var

S1, S2, S3 : set of Byte;

B: boolean;

...

S1:= [3, 4]; {оператор определения множества}

S2:= [1, 3, 4]; {оператор определения множества}

S3:= [3, 4, 5, 6, 78]; {оператор определения множества}

B:= S1 = S2; {False, т. к. S2 не является подмножеством S2}

B:= S3 = S2; {False, т. к. мн-ва S2 и S3 не равны друг другу }

B:= S3 S2; {True, т. к. мн-ва S2 и S3 не равны друг другу }

Проверка вхождения элемента во множество. Результатом операции in будет логическая константа True (истина) или False (ложь). Пример:

Var

S1 : set of Integer;

B: boolean;

...

S1:= [3, 4, 18 .. 178, 3101, 4427]; {оператор определения множества}

B:= ( 4 in S1); {True, т. к. 4 является элементом множества S1}

B:= (200 in S1); {False, т. к. 200 не является элементом S1}

7.4. Файловые типы

В языке Object Pascal есть три типа файлов:

текстовые файлы,

файлы с типом,

файлы без типа.

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

Текстовой файл – это последовательность символьных строк перемен-ной длины. Всякая такая строка завершается маркером конца строки CR/LF. Текстовые файлы можно обрабатывать только последовательно. Ввод и вывод нельзя производить для открытого файла, используя одну файловую переменную. Текстовой файл имеет тип TextFile, или просто Text. Пример описания файловой переменной текстового типа:

Var Fi: TextFile;

Файлы без типа состоят из компонент одинакового размера, структура которых не известна или не имеет значения. Допустим прямой доступ к любой компоненте файла. Пример объявления файловой переменной файла без типа:

Var F: File;

Файлы c типом состоят из однотипных компонент известной структуры. Допустим прямой доступ к любой компоненте файла. Пример объявления файловых переменных для файлов с типом:

Type

TRec = Record

A: Real;

B: Integer;

C: Char;

End;

Var

F : File of Real;

Q : File of String[100];

Fr: File of TRec;

В этом примере F объявлена как файловая переменная вещественного типа. Это означает, что компонентами файла могут быть только вещественные значения. Файловая переменная Q предназначена для доступа к файлам, которые состоят из символьных строк длины 100. Файловая переменная Fr предназначена для работы с файлами, которые состоят из записей типа TRec, объявленного в секции Type.

8. Совместимость типов

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

Суть совместимости типов удобнее пояснить на примере простейших выражений, которые состоят из одного (для одноместных операций) или двух (для двухместных операций) компонент (операндов) и одной операции.

8.1. Совместимость по вычислению

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

Типы операций и операндов эквивалентны.

Например, нельзя применять арифметические операции к логическим переменным и, наоборот, логические операции – к арифметическим переменным:

Type

R1, R2 : Real;

L1, L2 : Integer;

B1, B2: boolean;

...

Not (R1 + R2) B1 + B2 'Иванов' + ' ' + 'Петр' {недопустимые выражения}

Типы операндов эквивалентны.

Типы операндов целые или вещественные, например:

R1 + R2 L1 + R2 L2 / R1 / L1 {допустимые выражения}

Один тип является базовым, а второй – ограниченным типом этого же базового типа.

Type

L11, L12 : Integer;

K : -199 .. 199;

Типы являются множествами, причем их базовые типы совместимы.

Type

L : set of 21 .. 2141;

K : set of -199 .. 199;

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

Type

L : String [34]; Q : String [23]; K: Char;

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

Оба типа являются упакованными символьными массивами с одинаковым числом элементов.

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

Один имеет тип Variant, а другой – тип integer, real, string, character или Boolean.

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

8.2. Совместимость по присваиванию

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

Оба типа T1 и Т2 идентичны. Недопустимо присваивание файловых типов или структур, содержащих файловые типы (о файловых типах подробнее см. гл. 17).

T1 и Т2 имеют совместимые простые типы.

T1 и Т2 имеют вещественные типы.

T1 и Т2 имеют целые типы.

T1 и Т2 имеет тип PChar или другой строковый тип, и выражение представляет строковую константу.

T1 и Т2 имеют строковые типы.

T1 имеет строковый тип, а Т2 – символ или упакованная строка.

T1 – длинная строка, а Т2 имеет тип PChar.

T1 и Т2 имеют совместимые типы упакованных строк.

.T1 и Т2 имеют совместимые множественные типы.

.T1 и Т2 имеют совместимые Pointer-типы.

.T1 имеет тип PChar или PWideChar, а T2 есть символьный массив вида array[0 .. n] of Char.

.T1 и T2 имеют совместимые процедурные типы.

.T1 имеет тип Variant, а T2 – один из типов integer, real, string, character или Boolean.

.T1 имеет тип integer, real, string, character или Boolean, а Т2 – тип Variant.

9. Выражения

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

9.1. Арифметические выражения

При описании арифметических выражений для простоты типом Integer обозначен любой целый тип, а типом Real – любой вещественный тип. Выражение строится с помощью арифметических значений, констант, переменных, функций, арифметических операций. В выражениях можно применять круглые открывающие и закрывающие скобки. При этом количество открывающих скобок должно быть равно количеству закрывающих скобок.

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

В языке Object Pascal существует шесть арифметических операций. Учитывая, что арифметические операции образуют подмножество множества всех операций языка, в табл. 7 показано абсолютное значение приоритета каждой операции.

Таблица 7

Операция

Наименование

Приоритет

+

-

*

/

div

mod

Сложение

Вычитание

Умножение

Деление

Деление нацело

Остаток от деления

2

2

1

1

1

1

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

Таблица 8

Операция

Тип операндов

Тип результата

Пример

+

*

/

div

mod

Integer, real

Integer, real

Integer, real

Integer, real

Integer

Integer

integer, real

integer, real

integer, real

real

integer

integer

X + Y

Result - 1

P * InterestRate

X / 2

Total div UnitSize

Y mod 6

Примеры:

4*5 = 20, 6/5 = 1.2, 8+7 = 15, 7-3 = 4, 16 div 5 = 3, 16 mod 5 = 2.

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

Пример:

Выражение:

15 * ((25/5-5*9 + (j-8) * 7.55) / 8.67)

Порядок выполнения операций:

8 2 5 3 6 1 4 7

9.2. Логические выражения

Результатом вычисления логического выражения может быть одно из двух логических значений: True (истина ) или False (ложь).

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

В языке существует четыре логических операций. Приоритет операций показан в табл. 9.

Таблица 9

Операция

Наименование

Приоритет

Not

And

Or

Xor

Отрицание

Конъюнкция

Дизъюнкция

Спец. дизъюнкция

3

4

5

6

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

Таблица 10

A

B

not A

A and B

A or B

A xor B

True

True

False

False

True

False

True

False

False

False

True

True

True

False

False

False

True

True

True

False

False

True

True

False

В табл. 11 представлены логические отношения.

Таблица 11

Отношение

Наименование

>

<

>=

8

(5 < 3) and (z = 0)

((4 + 8) < 0) or not (y = 0)

not ((x < y) and (z > y))

('ab' = 'ac') and (x=z)

(4 in [ 2 .. 23 ])

True

False

True

True

False

True

Пример, демонстрирующий порядок выполнения операций при вычислении логического выражения:

Выражение:

Not ((x > 6 + 8 * 2) and (y < 7) or (z > 7)) and (x y)

Порядок:

9 3 2 1 6 4 7 5 10 8

9.3. Строковые выражения

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

Пример:

Выражение:

'Object '+'Pascal '+' для Delphi'

Результат:

'Object Pascal для Delphi'

10. Операторы

Оператор – языковая конструкция, представляющая описание команды или комплекса команд по обработке и преобразованию данных.

Все операторы делятся на две части – простые операторы и структурные операторы.

11. Простые операторы

К их числу относятся: оператор присваивания, оператор безусловного перехода, составной оператор, оператор процедур, специальные операторы.

11.1. Оператор присваивания

В параграфе 1.4 было дано краткое определение этого оператора – одного самых простых и наиболее часто используемых операторов. Напомним, что его синтаксис имеет вид

x := y;

где x – имя переменной или функции; y – совместимое по типу выражение (о совместимости типов см. гл. 8). Символы ":=" обозначают операцию присваивания, в соответствии с которой вычисленное значение выражения y присваивается переменной x.

Примеры операторов присваивания (комментарии показывают присвоенные значения):

Var

Ch: Char;

S: String[5];

Q: String[18];

L, J: Integer;

P: Byte;

R: Real;

B: Boolean;

Rec: Record

A: Word;

B: String[20];

End;

Таблица 13

Оператор присваивания

Значение

Q:= 'd:Dir1Worda.txt';

S:= Q;

Q:= S+'r';

Ch:=Q[2];

L:= 450;

P:= L;

J:= 100;

R:= -L / J;

J:=-L / J; J:=-L - 200;

B:= J > L;

B:= (J < L) and (Q[5] = 'i');

Rec.A:= J-20;

Rec.B:= 20;

Rec.B:= S[1]+S[3]+'d';

'd:Dir1Worda.txt'

'd:Di'

'd:Dir'

':'

450

Ошибка, т. к. max P = 255

100

-4.5

Ошибка. Несоответствие типов

250

False

True

230

Ошибка. Несоответствие типов

'dd'

11.2. Оператор безусловного перехода

Этот оператор выполняет передачу управления оператору, которому предшествует метка. Синтаксис оператора:

Goto Метка;

Язык допускает в качестве меток использовать имя или значение целого типа из диапазона 1 .. 9999.

При использовании операторов перехода необходимо придерживаться следующих правил:

Все метки, используемые в блоке, должны быть описаны словом Label.

Пример оператора описания меток:

Label 1, 2, Met1, Met2, Met3;

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

Недопустим переход к метке внутрь структурного оператора (например, внутрь цикла, минуя его заголовок). Компилятор не реагирует на эту ситуацию, однако поведение программы может быть непредсказуемо. Недопустимы также вход или выход по метке в процедурах или функциях.

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

11.3. Оператор обращения к процедуре

Этот оператор вызывает активизацию операторов, расположенных в теле процедуры (см. параграф 15.1). После выполнения процедуры управление передается к оператору, расположенному вслед за оператором процедуры.

При вызове процедуры её формальным параметрам должны строго соответствовать по совместимости типов и количеству фактические параметры.

Примеры обращения к процедурам:

Val (s, r, Code);

Sort (a, n * 2);

SaveParameters;

11.4. Обращение к функции

Следует подчеркнуть, что не существует специального оператора обращения к функции (см. параграф 15.1). Обычно такое обращение производится посредством другого оператора, часто оператора присваивания.

Обращение к функции активизирует ее внутренние операторы точно так же, как это происходит в процедурах. Принципиальное отличие между выполнением процедуры и функции состоит в следующем:

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

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

Поясним это на примере оператора присваивания, содержащего обращение к функции Func8:

G:= 2 * Pi * Func8(m, n, a) / Sqr (z);

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

12. Стандартные процедуры и функции

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

12.1. Строковые процедуры и функции

Function Length (St): LongInt;

Возвращает длину строки символов St, т. е. количество символов в ней (не путать с размером строки).

St:= '1234abc';

L:= Length(St); {L= 7}

Procedure Delete (St, Pos, Num);

Удаляет Num символов из строки St начиная с позиции Pos, если PosLength (Target), то результат Target + Obj.

St1:= '***';

St2:= '1234abc';

Insert (St1, St2, 3) { St2= '12***34abc'}

Procedure Str (Value, St);

Преобразует значение Value числового типа в строку символов St. Value может сопровождаться форматом.

L:=19;

Str (L, g); {g= '19'}

R:= 2.123155;

Str (R: 8:3, h); {h= ' 2.123' (длина 8, в дробной части 3}

Procedure Val (St, Vr, Code);

Преобразует строку символов St в числовую величину Vr целого или вещественного типа. Code = 0, если преобразование прошло успешно, иначе в Code будет записан номер первого ошибочного символа конвертируемой строки, при этом значение Vr не определено.

St:='319';

Val (St, k, Cod); {k= 319, Cod = 0}

St:='81yy9';

Val (St, k, Cod); {k= ?, Cod = 3}

Function Copy (St, Pos, Num): String;

Выделяет из строки St подстроку символов длиной Num начиная с позиции Pos. Если Pos>Length, то возвращает пустую строку.

St1:='АБВГДЕ';

St2:= Copy(St1, 2, 3); {St2= 'БВГ'}

St2:= Copy(St1, 2, 27); {St2= 'БВГДЕ'}

St2:= Copy(St1, 44, 2); {возвращает пустую строку St2= ''}

Function Concat (St1, St2{, …, StN}): String;

Объединяет строки в одну строку.

St:='abc';

St1:=Concat( 'sss', St, '1234'); {St1= 'sssabc1234'}

St1:=Concat( St, '123'); {St1= 'abc123'}

Function Pos (Obj, Target): Integer;

Возвращает номер символа, начиная с которого строка Obj первый раз входит в строку Target. Если строка Obj отсутствует в строке Target, то Pos = 0.

Q:= 'Иванов Сергей Петрович';

H:= Pos ('Сергей', Q); {H= 7}

H:= Pos ('Игорь', Q); {H= 0}

Function SizeOf (Obj): Integer;

Возвращает размер переменной Obj.

Function FormatFloat(const Format: string; Value: Extended): string;

Возвращает форматированное вещественное значение в виде строки. Format – формат числа, Value – число. В табл. 14 даны форматы функции FormatFloat.

Таблица 14

Формат

Описание

0

#

.

,

E+, E-

;

Поле для цифры. Недостающие позиции заменяются нулями

Поле для цифры. Если в позиции имеется значащая цифра, то оно выводится. Нули не выводятся

Разделитель целой и дробной частей

Поле разделителя тысяч, миллионов

Формат представления чисел с плавающей точкой. Если "+" указан, то перед порядком выводится знак. Если указан "-", то минус выводится только для отрицательных порядков

Разделитель форматов

Примеры действия форматов при конвертации числа в строку представлены в табл. 15.

Таблица 15

Формат

Число 1

Число 2

Число 3

Число 4

0

0.00

#.##

#,##0.00

#,##0.00;(#,##0.00)

#,##0.00;;Zero

0.000E+00

#.###E-0

1234

1234

1234.00

1234

1,234.00

1,234.00

1,234.00

.234E+03

1.234E3

-1234

-1234

-1234.00

-1234

-1,234.00

(1,234.00)

-1,234.00

-1.234E+03

-1.234E3

0.5

1

0.50

.5

0.50

0.50

0.50

5.000E-01

5E-1

0

0

0.00

0.00

0.00

Zero

0.000E+00

0E0

12.2. Стандартные функции

Function Char (X: byte): Char;

Возвращает символ с номером X.

Ch:= Char(74); {Ch= 'J'}

Function Ord (X): LongInt;

Возвращает порядковый номер скалярного аргумента.

j:= Ord('J'); {j= 74}

Function Round (X: Real): LongInt;

Возвращает округленное до целого значение вещественного аргумента.

j:= Round(12.8235); {j= 13}

Function Trunc (X: Real): LongInt;

Возвращает целое путем отбрасывания дробной части вещественного аргумента.

j:= Round(12.8235); {j= 12}

12.3. Арифметические процедуры и функции

Function Frac (X: Extended): Extended;

Возвращает дробную часть аргумента, например:

r:= Frac(-12.82); {r = -0.82, Frac(12.82)=0.82 }

Function Abs (X: Extended): Extended;

Возвращает абсолютное значение аргумента, например:

r:= Abs(-12.82); {r = 12.82}

Function ArcTan (X: Extended): Extended;

Возвращает арктангенс аргумента.

Function Cos (X: Extended): Extended;

Возвращает косинус аргумента.

Function Sin (X: Real): Real;

Возвращает синус аргумента.

Function ArcCos(X: Extended): Extended;

Возвращает арккосинус аргумента, значение которого должно принадле-жать отрезку [-1, 1]. Возвращает значение из отрезка [0, Pi].

Function ArcSin(X: Extended): Extended;

Возвращает арксинус аргумента, значение которого должно принадле-жать отрезку [-1, 1]. Возвращает значение из отрезка [-Pi/2, Pi/2].

Function ArcTan2(Y, X: Extended): Extended;

Возвращает арктангенс аргументов, вычисляя ArcTan(Y/X) в соответ-ствии с квадрантами координатной плоскости xOy. Возвращает значение из отрезка [-Pi, Pi].

Function Exp (X: Real): Real;

Возвращает экспоненту аргумента.

Function Sinh(X: Extended): Extended;

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

Function Cosh(X: Extended): Extended;

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

Function Tanh(X: Extended): Extended;

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

Function ArcSinh(X: Extended): Extended;

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

Function ArcCosh(X: Extended): Extended;

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

Function ArcTanh(X: Extended): Extended;

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

Function Ln (X: Real): Real;

Возвращает натуральный логарифм аргумента.

Function Sqr (X: Real): Real;

Возвращает квадрат аргумента.

Function Sqrt (X: Real): Real;

Возвращает квадратный корень аргумента.

Function Ceil(X: Extended):Integer;

Возвращает наибольшее целое аргумента.

Сeil(-2.8) = -2

Ceil(2.8) = 3

Ceil(-1.0) = -1

Function Floor(X: Extended): Integer;

Возвращает наименьшее целое аргумента.

Ceil(-2.8) = -3

Ceil(2.8) = 2

Ceil(-1.0) = -1

Function Dec (X, [n]: LongInt): LongInt;

Уменьшает значение аргумента на величину второго параметра. Если он отсутствует, то уменьшает на 1.

J:=67;

K:=Dec(J); {j= 66}

K:=Dec(J, 13); {j= 53}

Function Inc (X, [n]: LongInt): LongInt;

Увеличивает значение аргумента на величину второго параметра. Если он отсутствует, то увеличивает на 1.

J:=67;

K:=Inc(J); {j= 68}

K:=Inc(J, 13); {j= 81}

12.4. Скалярные функции

Function Odd (X: LongInt): Boolean;

Возвращает True, если аргумент четный.

J:=67;

K:=Odd(J); {K= False}

Function Pred (X);

Возвращает предшествующее значение типа аргумента.

Function Succ (X);

Возвращает последующее значение типа аргумента.

12.5. Процедуры завершения

Procedure Exit; Выход из процедуры.

Procedure Halt([Code:Word]);

Выход в операционную систему с кодом возврата, если он указан.

12.6. Процедуры и функции для работы с типами "дата/время"

Типы TDateTime и TTimeStamp, а также производные от них типы предназначены для хранения даты и времени. Эти типы используются в ряде весьма полезных и необходимых процедур и функций для работы с датами и временем.

Function Now: TDateTime;

Возвращает текущую дату и время.

Function Date: TDateTime;

Возвращает текущую дату.

Function Time: TDateTime;

Возвращает текущее время.

Function DateToStr (D: TDateTime): String;

Преобразует дату в строку символов, например:

S:= DateTimeToStr(Date); {текущая дата '26.10.99'}

Function TimeToStr(T: TDateTime): String;

Преобразует время в строку символов, например:

S:= TimeToStr(Time); { текущее время '13.58.13'}

Function DateTimeToStr(DateTime: TDateTime): String;

Преобразует дату/время в строку символов, например:

S:= DateTimeToStr(Now); { текущие дата и время '26.10.99 14.01.51'}

Function DateTimeToTimeStamp(DateTime: TDateTime): TTimeStamp;

Конвертирует TDateTime в TTimeStamp, например:

TS:= DateTimeToTimeStamp(Now); {type TS = TTimeStamp}

s:= IntToStr(Ts.Date) + ' ' + IntToStr(Ts.Time); {'730053 51095810' – (прошло дней с 00.00.0000 г. и миллисекунд от полуночи текущего дня}

Function TimeStampToDateTime(const TimeStamp: TTimeStamp): TDateTime;

Конвертирует TTimeStamp в TDateTime.

Procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word);

Раскладывет дату Date на год, месяц и день, например:

DecodeDate(Now, Y, M, D);

s:= IntToStr(Y) + ' ' + IntToStr(M) + ' ' + IntToStr(M); {'1999 10 26'}

.Procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word);

Раскладывет время Time на час, минуты, секунды и миллисекунды, например:

DecodeTime(Now, H, M, S, MS);

ss:= IntToStr(H) + ' ' + IntToStr(M) + ' ' + IntToStr(S) + ' ' + IntToStr(MS);

{'14 22 34 567', т. е. 14 ч 22 мин 34 с 567 мс}

.Function EncodeDate(Year, Month, Day: Word): TDateTime;

Противоположна DecodeDate;

.Function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;

Противоположна DecodeTime;

.Function FormatDateTime(const Frmt: string; DateTime: TDateTime): string;

Преобразует DateTime в строку с заданным форматом. Если формат пуст, то функция возвращает строку в формате "c". Следующий оператор присвоит строковой переменной s значение 'Встреча состоится: пятница, 6 Ноябрь, 1999, в 10:30 AM'.

s:= FormatDateTime('"Встреча состоится:" dddd, mmmm d, yyyy, ' +'"в" hh:mm AM/PM', StrToDateTime('6.11.99 10:30am'));

Виды форматов даны в табл. 16.

12.7. Прочие процедуры и функции

Function Hi(X): byte;

Возвращает старший байт своего целочисленного аргумента.

Function Lo(X) : byte;

Возвращает младший байт своего целочисленного аргумента.

Procedure Swap(X);

Меняет старший и младший байты целочисленного аргумента местами.

Procedure Randomize;

Инициализирует генератор случайных чисел.

Function Random(N: Integer): Integer;

Возвращает случайное число из интервала (0, N).

Function SizeOf(X) : Integer;

Возвращает число байт, занимаемых аргументом.

Procedure Move(Var Source, Dest; Count: Integer);

Копирует Count байт из переменной Source в переменную Dest. В случае перекрытия областей памяти пересылка в перекрывающуюся область не производится.

Function ParamCount: Word;

Возвращает число параметров, переданных в командной строке.

Procedure Break;

Оператор безусловного завершения цикла, процедуры или функции.

. Procedure Continue;

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

Таблица 16

Формат

Описание

C

D

Dd

Ddd

Dddd

Ddddd

Dddddd

M

Mm

Mmm

Mmmm

Yy

Yyyy

h

hh

n

nn

s

ss

t

tt

am/pm

ampm

a/p

/

:

Показывает сначала дату в формате дд.мм.гг, затем время в формате чч.мм.сс. Не показывает время, если дробная часть DateTime равна нулю

Показывает день без лидирующего нуля (1 – 31)

Показывает день с лидирующим нулём (01 – 31)

Показывает день недели в укороченном формате (Вос – Суб)

Показывает день недели в полном формате (Воскресенье – Суббота)

Показывает дату в формате дд.мм.гг.

Показывает дату в формате д Месяц год

Показывает месяц без лидирующего нуля (1 – 12)

Показывает месяц с лидирующим нулём (01 – 12)

Показывает месяц в сокращенном виде (Янв – Дек)

Показывает месяц в полном формате (Январь – Декабрь)

Показывает год в виде двух последних цифр (00 – 99)

Показывает год в виде четырех цифр (00000 – 9999)

Показывает час без лидирующего нуля (0 – 23)

Показывает час с лидирующим нулем (00 – 23)

Показывает минуту без лидирующего нуля (0 – 59)

Показывает минуту с лидирующим нулем (00 – 59)

Показывает секунду без лидирующего нуля (0 – 59)

Показывает секунду с лидирующим нулем (00 – 59)

Показывает время в формате чч:мм

Показывает время в формате чч:мм:сс

Показывает время в 12-часовом формате (am – до полудня, pm – после полудня)

Показывает время в 12-часовом формате без указателя до/после полудня

Использует Windows-разделитель даты.

Использует Windows-разделитель времени

. procedure Abort;

Используется в контексте с другим оператором; отменяет "задним числом" оператор в случае его аварийного завершения, блокирует выдачу сообщения об ошибке, удобен к использованию в блоке try … finally.

13. Структурные операторы

К их числу относятся:

составной оператор,

условный оператор If,

оператор варианта Case,

оператор цикла For – Do,

оператор цикла While – Do,

оператор цикла Repeat – Until,

оператор записи With,

оператор Try – Except – End,

оператор Try – Finally – End,

оператор On – Do,

оператор Try – Finally – End.

13.1. Составной оператор

Это простая структура следующих друг за другом операторов, заключенных в операторные скобки begin … end.

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

Begin

Оператор1

Оператор2

ОператорN

End;

Составной оператор применяется в тех случаях, когда какое-либо действие необходимо применить не к одному, а сразу к нескольким операторам.

Пример:

Begin

R:= X;

X:= Y;

Y:= R;

End;

13.2. Условный оператор If

Синтаксис допускает два вида оператора:

if логическое выражение then оператор1 else оператор2;

и его усеченный вариант:

if логическое выражение then оператор1;

Оператор работает следующим образом. Сначала вычисляется логичес-кое выражение. Если оно истинно, то выполняется оператор1, иначе – оператор2. Усеченный оператор выполняет оператор1 только в случае истинного значения логического выражения и не производит никаких действий в случае его ложности.

Примеры:

if (x < 10.7) then a[4]:= 5 else a[4]:= 6;

if (x < 10.7) then a[4]:= 5;

Допустима вложенность условных операторов внутри составного условного оператора. Например, оператору

if L1 then if L2 then St1 else St2 else St3;

эквивалентен оператор

if L1 then

begin

if L2 then St1 else St2;

end

else St3;

В этом операторе для повышения структурированности использованы операторные скобки begin … end. При конструировании сложного условного оператора во избежание логических ошибок следует отдавать предпочтение структурному способу записи такого оператора.

13.3. Оператор варианта Case

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

Case Selector of

Const1: Оператор1;

Const2: Оператор2;

ConstN: ОператорN

[else Оператор];

End;

Selector может быть любой простой тип кроме Real. Каждая из Const1 … ConstN может быть значение, несколько перечисленных через запятую значений или отрезок типа. Оператор Else, как видно из описания, может отсутствовать. В том случае, если он присутствует, то действует общее правило: перед словом Else не должно быть символа ";" (точка с запятой). Поясним работу оператора Case на примере:

Case i of

0 : x := 0;

1,3 : x := 1;

10 .. 15: x := 2

else x := 3;

End;

При выполнении оператора Case управление будет передано тому оператору, который помечен константой, являющейся значением переменной i. Например, если к моменту выполнения Case-оператора i = 0, то будет выполнен оператор x := 0. Иначе, если i = 1 или i = 3, то будет выполнен оператор x := 1; иначе, если значение i в диапазоне 10 .. 15, то будет выполнен оператор x := 2; наконец, если i не равно ни одной из вышеперечисленных констант, то будет выполнен оператор x := 3, следующий за словом else (иначе).

13.4. Оператор цикла For – Do

Синтаксис оператора имеет две разновидности:

For счетчик цикла:=нач.знач. To конеч.знач. Do оператор

For счетчик цикла:=нач.знач. Downto конеч.знач. Do оператор

Здесь конструкция For .. Do называется заголовком цикла, оператор – телом цикла.

Для циклов должны соблюдаться следующие правила и ограничения:

начальное и конечное значения счетчика цикла должны быть одинаковых простых типов, кроме Real;

в теле цикла счетчик не должен менять значение;

вход в цикл минуя заголовок запрещен;

для первой разновидности начальное значение не должно быть больше конечного;

для второй разновидности начальное значение не должно быть меньше конечного.

Первая разновидность оператора цикла For работает следующим образом. Сначала счетчик цикла принимает нач.знач. и выполняется оператор, расположенный вслед за словом Do. Затем значение счетчика будет увеличено на шаг счетчика 1 и вновь будет выполнен оператор и т. д., пока счетчик не переберет все значения от нач.знач. до конеч.знач.

Пример.

s:= 0;

For i:=1 to 44 do s:= s + z[i];

В результате в переменной s будет накоплена сумма первых 44 элементов массива z.

Другая разновидность оператора For отличается лишь отрицательным шагом –1 счетчика.

Пример.

s:= 0;

For i:=44 Downto 1 do s:= s + z[i];

Будет получен тот же результат.

13.5. Оператор цикла While – Do

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

While логическое выражение Do оператор;

Цикл выполняет оператор, расположенный вслед за словом Do до тех пор, пока истинно логическое выражение, расположенное за словом While ("выполняй, пока истинно").

Пример.

x:= 0;

i:=0;

While (x < 101.667) do

Begin

Inc (i);

X:= X + 5.617;

Y[i]:= Func (i + 6, 9 * i, X);

End;

В этом примере цикл будет выполняться до тех пор, пока не выполнится условие x < 101.667. В теле цикла переменная X с каждым шагом цикла увеличивает свое значение на 5.617 так, что на определенном шаге условие x < 101.667 впервые не будет выполнено. В этот момент без входа в тело цикл закончит работу.

13.6. Оператор цикла Repeat – Until

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

Repeat

Оператор1;

Оператор2;

ОператорN;

Until логическое выражение;

Цикл работает, пока логическое выражение ложно ("повторяй, пока не выполнится").

Пример.

s:= 0;

i:=0;

Repeat

Inc (i);

s:= s + z[i];

Until (i = 44);

В этом примере цикл будет выполняться до тех пор, пока не выполнится условие i = 44. Результат будет тот же, что в примере для For-цикла.

13.7. Операторы Break и Continue

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

Пример.

s:= 0;

i:=0;

Repeat

Inc (i);

s:= s + z[i];

if (s > 14) then Break;

Until (i = 44);

В этом примере цикл будет выполняться до тех пор, пока не выполнится условие i = 44 или если в операторе if переменная s превысит значение 14.

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

Пример.

s:= 0;

i:=0;

Repeat

Inc (i);

s:= s + z[i];

if (s > 20) then Continue;

if (s > 14) then Break;

Until (i = 44);

В этом примере если в первом операторе if выполнится условие s > 20, то сработает оператор Continue. Он сразу передаст управление на первый оператор в теле цикла – Inc (i), предотвратив тем самым выполнение ниже-следующих операторов – второго if и Until.

13.8. Вложенные циклы

В теле оператора цикла могут быть размещены другие операторы цикла. Такие структуры называются вложенными циклами. Язык допускает любую глубину вложенности циклов. При использовании вложенных циклов необходимо иметь в виду следующее:

все вложенные циклы For – Do должны иметь различные счетчики (иначе это противоречило бы требованию на запрет изменения значения счетчика внутри цикла);

нет никаких ограничений на досрочный выход из внутреннего цикла наружу;

недопустим вход во внутренний цикл For – Do, минуя его заголовок, что соответствует общему требованию о корректном входе в цикл.

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

Пример.

Const

n = 15;

m = 24;

Var

i,j: Byte;

R,Tau,s: Real;

z: array[1..n, 1..m] of Real;

{заполнение массива z с использованием вложенных циклов}

Tau:= Pi/m;

For i:=1 to n do begin

R:=4.0*Pi*Sin(i*Tau); {первый оператор в теле цикла по i}

For j:=1 to m do z[i, j] := R+j; {второй оператор в теле цикла по i}

end {i};

{вычисление суммы положительных элементов массива z с использованием вложенных циклов }

s:=0;

For i:=1 to n do

For j:=1 to m do

if ( z[i, j] > 0) then s:= s + z [i, j];

Приведенный пример содержит две структуры вложенных циклов. Первая структура предназначена для заполнения элементов двумерного массива z с помощью математической формулы



© Все права защищены. © All right reserved.