ГЛАВА I. Введение в язык программирования TURBO Pascal. ───────────────────────────────────────────── Так называемые арабские цифры 1,2,3,4,5,6,7,8,9 - одно из прекраснейших открытий, состоящее в том, чтобы записывать, пользуясь ими, самые большие числа с помощью нуля и указания определенного мес- та, пришло через арабов в Европу в 10-м или 11-м столетии. К.Маркс 1. А л ф а в и т я з ы к а Pascal ───────────────────────────────── В языке TURBO Pascal используются цифры, буквы и специальные символы. 1. Цифры: 0,1,2,...,9 (цифра 0 перечеркивается). 2. Все латинские буквы (от 'A' до 'Z', от 'a' до 'z' и '_' -символ под- черкивания). Обрадуем Вас тем,что использование строчных и прописных букв одинаково! 3. Буквы русского алфавита (допустимо использовать только в текстовых константах!). 4. Специальные символы: + - * / = ^ < > ( ) [ ] { } . , : ; ' # $ Пробел обязателен между подряд стоящими синтаксическими словами, имена- ми, числами в любых сочетаниях; в этих случаях пробел служит р а з д е - л и т е л е м. Внутри строковой константы пробел воспринимается не как разделитель, а как часть константы. В остальных местах пробелы можно употреблять произвольно. Везде, где может стоять пробел (кроме строковых констант), разрешены также: последовательность пробелов, переход на новую строку, комментарий, а также любое их сочетание. Можно уверждать, что п р о б е л - это самый важный символ. У Вас возникли бы определенные трудности при попытке прочитать эту страницу, если бы наборщик не позаботился о внесении в нее пробелов. О п е р а т о р ы и р а з д е л и т е л и , с о с т о я щ и е и з д в у х с п е ц и а л ь н ы х с и м в о л о в := <> <= >= (* *) (. .) Причем символы (..) применяются вместо [ ] , а символы (* *) - вместо { }. Между специальными символами пробелы недопустимы! К л ю ч е в ы е ( с л у ж е б н ы е с л о в а ) С л у ж е б н о е (ключевое) слово - это слово,которое в языке Pascal имеет определенное смысловое значение. Онo используются только в том зна- чении, которое заранее установлено в языке. * absolute downto goto of * shl while and else if or * shr with array end in packed * string * xor begin * external * inline procedure then overlay case file label program to const for mod record type div forward nil repeat until do function not set var Звездочкой отмечены ключевые слова, не зарезервированные в стандарте языка Pascal. Внутри служебных слов пробелы недопустимы! С т а н д а р т н ы е и м е н а ( и д е н т и ф и к а т о р ы ) И м я (иногда говорят, идентификатор) служит для обозначения каких- либо объектов. В языке Pascal различают два вида имен: стандартные имена и имена, даваемые пользователем. С т а н д а р т н ы е идентификаторы используются в языке для обозна- чения стандартных объектов (типов, констант, процедур и функций). Полный перечень стандартных имен приведен ниже. SeekEoln Addr SeekEof ArcTan ConInPtr FilePos Length Port Sqr Assign ConOutPtr FileChar Ln Pos Sqrt Aux Concat FileSize Lo Pred Str AuxInPtr ConstPtr Flush LowVideo Ptr Succ AuxOutPtr Copy Frac Lst Random Swap BlockRead Cos GetMem LstOutPtr Randomize Text BlockWrite CrtExit GotoXY Mark Read Trm Boolean CrtInit HeapPtr MaxInt Readln True BufLen DelLine Hi Mem Real Trunc Byte Delay IOresult MemAvail Release UpCase Chain Delete Input Move Rename Usr Char EOF InsLine New Reset UsrInPtr Chr EOLN Insert NormVideo Rewrite UsrOutPtr Close Erase Int Odd Round Val ClrEol Execute Integer Ord Seek Write ClrScr Exp Kbd Output Sin Writeln Con False KeyPressed Pi SizeOf В языке TURBO Pascal введены стандартные идентификаторы: Stackptr , Recurptr , BIOS , BDOS , BIOSHL , BDOSHL Рассмотрим имена, даваемые пользователем. Следует отметить, что в каче- стве имени нельзя использовать служебные слова и стандартные имена. И д е н т и ф и к а т о р - это последовательность латинских букв и цифр, начинающаяся с буквы. Значащими являются первые 127 символов. Но для мнемоники программисту иногда бывает удобно использовать и более длинный идентификатор. Заметим, что в языке Pascal пробелы в идентификаторах не допускаются, т.к. любой символ разрядки (пробел или тире) не является бук- вой или цифрой языка и не должен входить в состав имени. Отличие от стандарта языка Pascal: допускаются идентификаторы любой дли- ны, в которых все символы являются значимыми. Элементы языка отделяются друг от друга о г р а н и ч и т е л я м и: пробел, конец строки, комментарий. 2. С о с т а в н ы е ч а с т и п р о г р а м м ы ─────────────────────────────────────────────── Программа на языке Pascal состоит из заголовка, раздела описаний и раз- дела операторов. З а г о л о в о к PROGRAM имя (INPUT,OUTPUT); label - раздел меток; Р а з д е л const - раздел констант; о п и с а н и й type - раздел типов; var - раздел переменных; procedure - раздел процедур и function функций BEGIN оператор 1; Р а з д е л оператор 2; о п е р а т о р о в ■■■ оператор n END. З а г о л о в о к содержит служебное слово PROGRAM, имя программы, за- даваемое пользователем-программистом, и в круглых скобках имена стандарт- ных процедур INPUT, OUTPUT для связи программы с внешними устройствами ввода-вывода. Заканчивается заголовок символом ";" (точка с запятой). Р а з д е л о п и с а н и й предназначен для объявления всех встречаю- щихся в программе данных и их характеристик (имена данных, их тип, возмож- ные значения и др.). Этот раздел, в свою очередь, содержит следующие разделы: объявление ме- ток, констант, типов, переменных, объявление процедур и функций. ┌─────────────────────────────────────────┐ │ Порядок расположения разделов неважен! │ └─────────────────────────────────────────┘ ┌─────────────────────────────────┐ │ Описания могут повторяться! │ └─────────────────────────────────┘ Объявление процедур и функций является одним разделом.Следует заметить, что не все перечисленные разделы обязательны в программе. В простых про- граммах могут потребоваться, например, только разделы объявления констант и переменных. После каждого описания ставится символ ";". Р а з д е л о п е р а т о р о в заключается в операторные скобки вида: BEGIN ("начать") и END ("окончить"), при этом после служебного слова END ставится т о ч к а . Удобно записывать слова PROGRAM, BEGIN, END с одинаковой позиции строки. По отошению к ним описания и операторы сдвигаются в п р а в о. Желательно сдвиг делать на одинаковое число позиций от края или по отношению к преды- дущему сдвигу. В разделе операторов записывается последовательность исполняемых опера- торов. Каждый оператор выражает действие, которое необходимо выполнить. Исполняемые операторы отделяются друг от друга символом ";". В отличие от представленной выше структуры программы сама программа за писывается в свободной форме, операторы не привязаны к определенной позиции строки. В одной строке можно указывать несколько описаний или операторов. Допус- кается перенос с одной строки на другую частей описаний или операторов. В то же время рекомендуется программу записывать в такой внешней форме,что- бы ее можно было легко читать и понимать. Для этого широко используются пробелы, пустые строки и комментарии. К о м м е н т а р и й служит для пояснения программы или отдельных ее частей. Наличие комментариев делает программу более понятной и удобной для чтения. Комментарий языка Pascal - это последовательность символов, ограничен- ная слева парой символов "(*" и справа парой символов "*)", или же слева символом "{", а справа - символом "}". Например: (* Определение минимального элемента*) При выполнении программы комментарии игнорируются. Их можно свободно распределять по всей программе, вставлять в любое место, где допускается пробел. Комментарии играют очень важную роль при написании программ. Их цель - дать исчерпывающее объяснение использования всех объектов в программе и действий над ними. Комментарии бывают нескольких видов. 1. После заголовка программы, процедуры или функции указывается общая информация, включающая в себя описание функции программы, входные данные и результаты, фамилию программиста, дату написания программы, версию программы и т.д. 2. Комментарии, касающиеся объяснения используемых в программе переменных. Понимание данных - это ключ к пониманию всей программы. Поэтому каждое описание данных следует сопровождать комментарием, поясня- ющим смысл их употребления. 3. Если программа состоит из нескольких логически связанных частей, выполняемых последовательно, то необходимо дать комментарий для каждой из них. Они явно показывают завершение одной части и начало другой. 4. Комментарии, касающиеся объяснения наиболее трудных участков программы. Особую ценность представляют инварианты циклов. Явное ука- зание инварианта цикла способно с лихвой заменить многословное поясне- ние того, что же делает данный цикл. Отметим, что существуют две крйности при использовании комментариев в программе. Некоторые программисты считают (впрочем, не без основания), что наилучший комментрий - это ясный и понятный текст программы. Другие дают так много комментариев, что текст исходной программы за ними почти не виден. Наилучший способ комментирования программы заключается в том, что программист как бы отвечает на вопросы потенциального читателя про- граммы. программа первоначально пишется без комментариев. Затем в те точки программы, где у читателя могут возникнуть вопросы, вставляются пояснения. При написании комментариев не следует стремитьс к созданию литературных шедевров. Достаточно будет коротких, ясных и точных фраз, однозначно поясняющих ту или иную конструкцию. "1. Если программа неправильная,то неважно,что говориться в документации. 2. Если документация не согласуется с программой, то она немного стоит. 3. Следовательно, текст программы в большей степени документирует сам себя. Если это не обеспечивается, от лучше переписать программу, чем уве- личивать ее документацию. Хорошая программа требует гораздо меньше комментариев, чем плохая. Комментарии должны привносить дополнительную информацию к самому тексту. Они не должны просто повторять программу. Мнемонические имена переменных и меток, а также размещение текста, вы- деляющие логическую структуру программы, способствуют самодокументированию программы." Керниган Б., Плоджер Ф. 3. Д а н н ы е ─────────── Программа, написанная на языке Pascal, предназначена для обработки дан- ных. Эти данные могут быть различной природы (числа, тексты, последователь- ности двоичных цифр и т.п.). В зависимости от способа хранения в компьюте- ре данные можно разбить на две группы: константы и переменные. 3.1. К о н с т а н т ы ───────────────── К о н с т а н т ы - это данные, значения которых не изменяются в про- цессе работы программы. Константы "узнаются" компьютером по форме их за- писи. В языке Pascal используются константы трех видов: ч и с л о в ы е, б у л е в с к и е и с и м в о л ь н ы е. Первые предназначены для представления числовых данных (целых и вещест- венных). Булевские константы используются для представления данных,имеющих смысл логических высказываний (да-нет, истина-ложь). Символьные константы представляют данные, являющиеся последовательностями символов. Именование констант и переменных в программировании похоже на использо- вание символических выражений в алгебре, однако, для того, чтобы компиля- тор смог их обрабатывать, нужно снабдить его некоторой дополнительной ин- формацией. В этой информации сообщается о "т и п е" каждой именованной величины. Человек, решающий какую-нибудь задачу "вручную", обладает интуи- тивной способностью быстро разобраться в типах данных и тех операциях, ко- торые для каждого типа справедливы; известно, например,что нельзя извлечь квадратный корень из слова или написать число с заглавной буквы. Одна из причин, позволяющих легко провести такое распознавание, состоит в том,что слова, числа и другие обозначения выглядят по-разному. Однако для компью- тера все типы данных сводятся в конечном счете в последовательности битов, поэтому различие в типах следует делать явным. 3.1.1. Ч и с л о в ы е к о н с т а н т ы ────────────────────────────────── Внутри числовых констант пробелы недопустимы! Числовые константы могут быть целыми и вещественными. 1. Ц е л ы е к о н с т а н т ы (типа Integer) Целая десятичная константа представляет собой последовательность деся- тичных цифр, которой может предшествовать знак "-" (минус). ┌─────────────────────────────────────────────────────────────────────┐ │ Диапазон допустимых целых чисел в десятичной записи [-32768,32767]. │ │ Переполнение в целых числах не регистрируется! │ └─────────────────────────────────────────────────────────────────────┘ Целые константы могут также быть представлены в шестнадцатеричном виде с префиксом "$". Допустимый диапазон данных констант - от $0000 до $FFFF. Существуют две т.н. предопределенные константы: 1) PI 2) MAXINT 2. Ц е л ы е к о н с т а н т ы (типа Byte) Тип Byte - ограничение стандартного типа Integer. Диапазон допустимых чисел: от 0 до 255. Числа этого типа занимают один байт памяти. 3. В е щ е с т в е н н ы е к о н с т а н т ы (типа Real) Представление вещественных констант имеет две формы: в виде десятичной дроби, где вместо запятой используется точка (напри- мер, число 3.2), и в виде числа, содержащего указание на степень десяти (например, число 2.5E9). (Мантисса занимает не более 11 разрядов). З а м е ч а н и е. Константа, записанная в виде десятичной дроби, обя- ───────────────── зательно должна содержать как целую часть, так и дробную, т.е. нельзя писать 2. и .5, а следует писать 2.0 и 0.5 . Вещественные константы не должны по абсолютной величине превосходить 1Е+38. Если вещественная константа по модулю меньше некоторого определен- ного числа, то компьютером она воспринимается как н у л ь ("машинный нуль"). Для компьютера каждого типа эта наименьшая вещественная константа своя, в частности для изучаемой нами версии TURBO Pascal эта константа равна 1Е-38. Забегая далеко вперед, заметим, что для типа Real не допускается исполь- зование в качестве: 1) границ в описании ограниченного типа; 2) аргумента функций Pred и Succ; 3) индексов; 4) базового типа множеств; 5) счетчика цикла for и в качестве селектора меток в операторе case. 3.1.5. Б у л е в с к и е к о н с т а н т ы (типа Boolean) ───────────────────────────────────────────────────── Имеются две булевские константы: TRUE и FALSE; причем, данные значения упорядочены, т.е. TRUE > FALSE. 3.1.6. С и м в о л ь н ы е к о н с т а н т ы (типа Char) ──────────────────────────────────────────────────── С и м в о л ь н а я константа есть любой символ алфавита языка, заклю- ченный в апострофы. Например: 'A', '+', '9', ' ', ':', ' '' ' (представление апострофа). Заметим, что символы упорядочены по кодам ASCII, т.е.,например,'А'<'В'. Коды символов расположены в диапазоне от 0 до 255. Буквы русского алфавита не упорядочены по кодам ASCII! 3.1.7. С т р о к о в ы е к о н с т а н т ы (типа String) ──────────────────────────────────────────────────── Последовательность символов, заключенная в апострофы, есть строковая константа. Если среди символов строки есть апостроф, то он изображается двумя апострофами. Например, константу 'A'B'C'D' следует набрать как 'A''B''C''D'. Д л и н о й строки называется количество символов в ней. Максималь- ная длина строки - 255 символов. Символы внутри строки нумеруются от 1 до значения, равного длине строки. ┌─────────────────┬────────────────────┐ │ Т и п │ Размер оперативной │ │ к о н с т а н т │ памяти (в байтах) │ ├─────────────────┼────────────────────┤ │ Integer │ 2 │ │ Byte │ 1 │ │ Real │ 6 │ │ Boolean │ 1 │ │ Char │ 1 │ │ String │ Длина строковой │ │ │ константы + 1 │ └─────────────────┴────────────────────┘ TURBO Pascal позволяет включать в строки у п р а в л я ю щ и е с и м в о л ы. Предусмотрены две формы записи управляющих символов: 1) символ #, за которым следует целочисленная константа из диапазона 0..255, которая обозначает символ с соответствующим значением кода ASCII; 2) символ ^, за которым следует символ, обозначающий нужный управляющий символ. П р и м е р ы. #10 Код ASCII символа "Перевод строки" ────────────── ^G Код символа "Звонок" Последовательность управляющих символов может быть записана в строке без разделителей между отдельными символами, например #13#10 #27^U#20 Управляющие символы могут смешиваться в строках с символами текста, например: 'Waiting for input! '^G^G^G 'Please wake up' 'This is another line of text '^M^J Т и п и з и р о в а н н ы е к о н с т а н т ы ─────────────────────────────────────────────── Тольков данной версии языка Pascal введен способ присвоения начальных значений переменным с помощью так называемых т и п и з и р о в а н н ы х констант. Эти константы могут использоваться как переменные того же типа. Типизированные константы определяются также, как и обычные, но кроме их значения определяется также и тип. Н е с т р у к т у р и р о в а н н ы е т и п и з и р о в а н н ы е к о н с т а н т ы Неструктурированные константы - это константы одного из скалярных ти- пов: П р и м е р. const ─────────── Numbercars: Integer=1267; Interest : Real=12.67; Head : String[7]='SECTION'; Hon : Char=^Q; Так как типизированные неструктурированные константы - это фактически переменные, имеющие постоянное значение, то они не могут быть использова- ны в определении других констант, переменных или типов. Используйте типизированные константы, ибо они экономят память! 3.2. П е р е м е н н ы е ─────────────────── Значения п е р е м е н н ы х , в отличие от констант, могут изменять- ся во время выполнения программы. Переменные "узнаются" компьютером по именам (идентификаторам). Р а з л и ч и е между именем и идентификатором !!! С каждой переменной программы связывается один и только один определен- ный тип. Т и п - это множество значений переменной плюс множество опера- ций, которые можно выполнять над этим значением. Таким образом,приписывая переменной некоторый тип, мы тем самым явно определяем множество значений, которые можно присвоить этой переменной, а так же операции, с помощью ко- торых можно манипулировать ее значениями. О языке Pascal говорят, что он строго т и п и з и р о в а н . Програм- мист должен описать все объекты, указывая их типы, и использовать объекты только в соответствии с их типами. Может показаться, что такая дисциплина языка Pascal сдерживает творчество и изобретательность, ограничивая деяте- льность программистов достаточно жесткими рамками. Представим себе,однако, язык, который накладывает мало или вообще не накладывает никакой дисципли- ны. Написав несколько нетривиальных программ, программист сразу же оценит смысл введения этих ограничений, поймет, что их цель - нахождение как мож- но большего числа ошибок и как можно раньше. А это в свою очередь, приво- дит к написанию более надежных и качественых программ. Рассмотрим, принадлежащее Хоару [ ] определение т и п а данных: "1. Тип определяет класс значений, которые могут принимать переменная или выражение. 2. Каждое значение принадлежит одному и только одному типу. 3. Тип значения константы, переменной или выражения можно вывести ли- бо из контекста, либо из самого операнда, не обращаясь к значениям, вы- числяемым во время работы программы. 4. Каждой операции соответствует некоторый фиксированный тип ее опе- рандов и некоторый фиксированный тип результата... 5. Для каждого типа свойства значений и элементарных операций над значениями задаются с помощью аксиом. 6. при работе с языком высокого уровня знание типа позволяет обнару- живать в программе бессмысленные конструкции и решать вопрос о методе представления данных и преобразования их в вычислительной машине. 7. Интересующие нас типы - это типы, хорошо знакомые математикам: прямые произведения, размеченные объединения, множества, функции, по- следовательности и рекурсивные структуры". Такая интерпретация типов данных была реализована Виртом в языке Pascal. Она обеспечила абстрагирование от специфики конкретных ЭВМ, пре- доставила богатый выбор готовых типов данных и стандартных конструк- торов типов данных (массивы, записи и т.д.), полезных для решения задач. Предусмотренная определением возможность контроля использования данных облегчает обнаружение ошибок до начала выполнения программ. Типы в языке Pascal описываются в разделе описания типов. Каждая переменная (например, А,В,С), используемая в программе, должна быть описана следующим образом: ┌────────────────────────────┐ │ var A: TYPE1; │ │ C,B: TYPE2;... │ └────────────────────────────┘ Здесь: var ("VAReable"-"переменная") - служебное слово; А,B,C - идентификаторы переменных; TYPE1, TYPE2 - типы переменных. 3.2.1. П е р е м е н н ы е ц е л о г о т и п а (типа Integer) ───────────────────────────────────────────────────────── Переменные типа Integer могут принимать только ц е л ы е значения. Такие переменные описывается следующим образом: var A,B,C: Integer; Здесь Integer ("целый") - служебное слово; A,B,C - имена переменных. Компилятор, встретив такое описание переменных A,B,C, и т.д., запоми- нает, что эти переменные могут принимать только целые значения и формиру- ет соответственно этому команды программы. Есть возможность назначать абсолютные адреса переменным без резервиро- вания памяти < Описание > ABSOLUTE < Адрес > Например, var PRIM: Integer ABSOLUTE $CAFA; П р и м е р. ─────────── Описание переменных ц е л о г о типа (типа Byte): var A,B,C: Byte Описание переменных в е щ е с т в е н н о г о типа (типа Real): var A,B,C: Real; Описание переменных б у л е в с к о г о типа (типа Boolean): var A,B,C: Boolean; Описание переменных с и м в о л ь н о г о типа (типа Char): var A,B,C: Char; 3.2.5. П е р е м е н н ы е с т р о к о в о г о т и п а (типа STRING) ──────────────────────────────────────────────────────────────── В определении строкового типа должна быть указана максимальная длина строки данного типа. Определение содержит служебное слово String, за кото- рым идет максимальная длина строки в квадратных скобках (целочисленная константа в диапазоне от 0 до 255). В н и м а н и е ! Длины по умолчанию не существует ! П р и м е р ы. var a: String[14] ───────────── Screenline: String [80]; Строковая переменная занимает в памяти место, равное (в байтах) макси- мально определенной длине строки плюс 1. Символы внутри строки индексируют- ся с 1 до длины строки. В компоненте строки с индексом 0 находится целое число, обозначающее т е к у щ у ю д л и н у с т р о к и (эта фраза не совсем точна... см.далее). П р и м е р. ─────────── PROGRAM A; var X: String[5]; BEGIN Write ('Введите слово... ',X); Readln (X); Write ('Длина слова: ',Ord(X[0])) END. Доступ к элементам строки призводится с помощью индексации. В результа- те получается величина типа Char. Например: buffer[6]; line[length(line)-1]; Тип String и стандартный тип Char с о в м е с т и м ы , т.е. строки и символы могут употребляться в одних и тех же выражениях. При сравнении двух строк в результате получается истина только в том случае, когда сравниваемые сроки 1) совпадают п о с и м в о л ь н о и 2) имеют о д и н а к о в у ю длину (принадлежат одному и тому же типу). 3.2.7. П е р е м е н н ы е т и п а "п е р е ч и с л е н и е" ─────────────────────────────────────────────────────── В программу можно ввести и переменные какого-либо типа, не совпадающего ни с одним из стандартных. Такой тип задается перечислением значений, кото- рые может принимать переменная. Общий вид описания нестандартного типа: ┌─────────────────────────────────────────┐ │ type NM = (WORD1,WORD2,...,WORDN); │ └─────────────────────────────────────────┘ здесь: TYPE ("type" - "тип") - служебное слово; NM - идентификатор типа; WORD1,WORD2,...,WORDN - конкретные значения. Причем данные значения считаются у п о р я д о ч е н н ы м и, т.е. описание типа одновременно вводит упорядочивание WORD1 < WORD2 <... < WORDN . П р и м е р. type COLOR = (RED,YELLOW,GREEN,BLUE); ─────────── Здесь определено, что RED < YELLOW < GREEN < BLUE . А теперь опишем, как обычно, переменную типа COLOR: var C: COLOR; Каждая из констант имеет порядковый номер; счет начинается с н у л я . В примере константа RED имеет порядковый номер 0, константа YELLOW имеет порядковый номер 1 и т.д. Над значениями перечислимого типа определены только операции сравнения - при этом, естественно, сравниваться могут только значения одного и того же типа. Забегая вперед, отметим, что для аргумента x перечислимого типа приме- нимы стандартные функции Succ(x), Pred(x), Ord(x). П р и м е р. var teacher: (стажер,ассистент,доцент, профессор); ─────────── Последовательность значений, составляющая скалярный тип, считается упо- рядоченной: стажер < ассистент < доцент < профессор При этом каждое значение получает номер, начиная с нуля, для вычисления которого служит специальная стандартная функция Ord. Например, Ord (ассистент) возвращает 1, Ord (доцент) возвращает 2, Ord (профессор) возвращает 3. Далее Pred (профессор) возвращает доцент, Succ (доцент) возвращает профессор 3.2.8. П е р е м е н н ы е о г р а н и ч е н н о г о т и п а ─────────────────────────────────────────────────────── Если какая-то переменная принимает не все значения своего типа,а только значения, содержащиеся в некотором ограниченном диапазоне, то ее можно рас- сматривать как переменную о г р а н и ч е н н о г о т и п а . При определении ограниченного типа указываются начальное и конечное зна- чения, которые может принимать константа базового типа на этом отрезке, разделенные двумя точками (..). Описание ограниченного типа имеет вид: TYPE И м я т и п а = константа..константа; при этом должны выполнятся следующие правила: 1) обе ограниченные константы должны быть одинакового типа (этот тип на- зывается б а з о в ы м ); 2) в качестве базового типа можно использовать любой скалярный тип, кроме д е й с т в и т е л ь н о г о (Real). Например, возможны отрезки: целого типа - INDEX = 0..63; символьного типа - LETTER = 'A'..'Z' перечислимого типа - ОСЕНЬ = Сент..Ноябрь; 3) начальное значение при определении ограниченного типа не должно быть больше конечного значения; 4) переменные ограниченного типа описываются в разделе переменных с по- мощью имен этих типов. Например var char1,char2: 'A'..'Z'; П р е о б р а з о в а н и е т и п о в ────────────────────────────────────── В данной версии языка Pascal возможно преобразование скалярных ограни- ченных и перечислимых типов (кроме типа Real). Для этого используется сле- дующая конструкция: ┌───────────────────────────────────┐ │ Имя_типа ( п е р е м е н н а я ) │ └───────────────────────────────────┘ где: Имя_типа - имя того типа, к которому происходит преобразование; п е р е м е н н а я - переменная того типа, который преобразуется. П р и м е р ы. ───────────── Если значением вещественной переменной West является 1.2345, то значением выражения Integer (east) является 1. Значением выражения Char(78) будет являться символ 'N'. Метапринцип. Никогда не отвергайте как очевидный никакой фунда- ─────────── ментальный принцип, так как только о с о з н а н- н о е п р и м е н е н и е таких принципов может принести успех. Д.Грис "Приведем одну из простых и наиболее важных стратегий работы с перемен- ными. Перед использованием переменных определите их, а затем убедитесь, что их использование следует их определению. Данное правило выглядит совершенно очевидным, но тем не менее именно ему трудно научиться и следовать на практике. Определения переменных важны точно так же при чтении программы, как и при ее построении. Читателю должны быть предложены вначале определения вместе с текстом, помогающим их понять. А когда они поняты, сама програм- ма часто становится очевидной. Кроме того, просто неэтично предлагать программу без точных определений переменных. Подходящим местом для определений (большинства) переменных является так же, как и для их описаний, начало программы. Это приносит некоторые преимущества: 1. Такое решение заставляет нас группировать переменные в соответствии с логическими связями между ними (вместо того, чтобы группировать их по типам или в произвольном порядке). Опсания каждой группы логически связан- ных переменных должны размещаться единой группой вместе с их определением и, возможно, отделяться пустыми строчками от других групп. 2. Определения, если они написаны достаточно рано и точно, дают в руки программисту добавочное орудие проверки. Всякий раз, когда он напишет текст в программе, который изменит одну из переменных некоторой группы, он сможет обратиться к ее определению и посмотреть, каким образом должны быть изменены другие переменные, чтобы сохранилось их определение. 3. Читателю известно, куда ему следует посмотреть, чтобы понять, как используется переменная: ее описание сопровождается ее определением, а также определением логически связанных с ней переменных. 4. В комментариях внутри программы, например, в командах комментариях, можно ссылаться на определения переменных и таким образом укорачивать про- грамму. И последнее замечание: нет ничего хуже, чем комментарии типа "i являет- ся индексом в массиве B". При определении переменных воздерживайтесь от употребления слов-паразитов типа "указатель","счетчик" или "индекс", так как они служат указателями на Вашу лень и нечеткость Ваших мыслей." Д.Грис З а г о л о в о к п р о г р а м м ы и п р о г р а м м н ы й б л о к ─────────────────────────────────────────────────────────────────────── Любая программа состоит из блока и заголовка. Б л о к содержит раздел описаний, в котором определяются все локальные по отношению к данной программе объекты и раздел операторов. Он задает дей- ствия, которые надо выполнить над этими объектами. З а г о л о в о к п р о г р а м м ы. В TURBO заголовок программы не имеет какого-либо смысла. Если он задан, то присваивает программе имя и содержит список параметров, через которые осуществляется связь программы с оборудованием. Список параметров, разделенных запятыми, заключают в скоб- ки. П р и м е р ы. program circies; program Accountant (Input,Output); program Writer(Input,printer); Р а з д е л о п и с а н и й Раздел описаний делится на 5 секций: 1) раздел меток; 2) раздел констант; 3) раздел типов; 4)раздел переменных; 5) раздел процедур и функций. В отличие от стандартного Паскаля, в котором каждая секция может исполь- зоваться не более одного раза и только в указанном порядке, в TURBO-секции могут использоваться несколько раз и в любом порядке. Р а з д е л м е т о к Любой оператор программы можно выделить, поставив перед ним через двое- точие метку (тем самым появляется возможность ссылаться на эту метку в опе- раторе перехода). Однако такая метка, прежде чем ее использовать, должна быть определена в разделе меток. В начале раздела стоит зарезервировонное слово Label и далее список меток, разделенных между собой запятыми. В конце раздела ставится символ ";". Например: Label 10,error,999,Quit; В отличие от стандартного Паскаля, в котором метка представляет собой число без знака, содержащие максимум 4 цифры, в TURBO метка - любое число или идентификатор. Р а з д е л к о н с т а н т Определение констант вводит имя как синоним некоторой константы. В нача- ле раздела стоит зарезервированное слово Const, в конце раздела ставится символ ";". Значения констант присваиваются идентификаторам при помощи сим- вола "=". Под константом здесь подразумевается либо число, либо строка. П р и м е р. Const Limit=255;Max=1024; PassWord="sesam";CursHome=^["v"; Следующие константы уже определены в TURBO: И м я Т и п З н а ч е н и е Pi Real 3.1415926536E+00 FALSE Boolean логическая ложь True Boolean логическая истина Maxint Integer 32767 Р а з д е л т и п о в Тип данных можно либо описывать непосредственно в описании переменных, либо ссылаться на него с помощью имени (идентификатора). В языке преду- смотрено несколько стандартных типов, и существует механизм определения типа для создания нового. Каждое определение задает множество значений и связывает с этим множеством некоторое имя. Раздел начинается с зарезер- вированного слова Type, каждое присваивание представляет собой типовой идентификатор, за которым следует знак '=' и тип, и заканчивается знаком ';'. П р и м е р: Type Number=Integer; Day=(mon,tues,wed,thur,fri,sat,sun); List=array[1..10] of integer; Примеры определения типов можно найти в последующих разделах. Р а з д е л п е р е м е н н ы х Любая встречающаяся в каком-либо операторе переменная должна быть опи- сана в некотором описании переменной. Это описание текстуально должно предшествовать использованию переменной. Раздел начинается с зарезервиро- ванного слова Var , следом записывается один или несколько идентификаторов, разделенных запя- тыми, далее знак ':', тип и знак ';'. Описание каждой переменной связыва- ет с новой переменной имя и указанный тип. Вводимая связь имя-тип имеет силу во всем блоке, содержащем данное описание, если только имя не будет предопределено во вложенном блоке. С этим именем будет связана локальная по отношению к вложенному блоку переменная любого нужного типа, а перемен- ная, описанная во внешнем блоке (глобальная переменная) станет недоступна. П р и м е р. Var Result,Intermediate,SubTotal:Real; ─────────── I,J,X,Y:Integer; Accepted,Valid:Boolean; Period:Day; Buffer:array[0..127] of Byte; Р а з д е л п р о ц е д у р и ф у н к ц и й Любая процедура или функция перед использованием должна быть определена. Описание процедур и функций подробно разбирается в последующих главах. П р о ц е д у р а представляет собой подпрограмму и активизируется (на- чинает выполнятся) оператором процедуры. Ф у н к ц и я - это тоже подпрограмма, но она возвращает некоторое зна- чение и поэтому может использоваться как компонента выражения. В ы р а ж е н и я ───────────────── В ы р а ж е н и я - это алгоритмические конструкции, задающие правила обработки данных . Они состоят из о п е р а н д о в : переменных, конс- тант и функциональных знаков . В этой главе показывается, как обрабатывать выражения над переменными стандартных скалярных типов: Integer,Real,Char. 4. О п е р а ц и и ─────────────── О п е р а ц и и подразделяются на 5 категорий: 1) унарный минус (минус только с одним операндом ); 2) оператор Not ; 3) мультипликативные операции: *, /, div ,mod, and, shl, shr ; 4) аддитивные операторы : +, -, or, xor ; 5) операторы отношения : =, <>, <, >, <=, >=, in . Выражение задает порядок вычисления значения, основанный на обычном пра- виле вычисления слева направо и старшенстве операций в соответствии с ука- занными категориями: самый высокий приоритет у первой категории, а самый низкий - у оператора in . Выражение, заключенное в скобки, вычисляются независимо от предшествую- щей ему и последующей операции . Если в мультипликативных и аддитивных опе- раторах оба операнда имеют тип Integer, то полученный результат будет типа Integer, если один (или оба) операнда типа Real , то и результат будет типа Real. У н а р н ы й м и н у с . Унарный минус обозначает отрицание (умноже- ние на -1 ) своего операнда, который может быть типа Real или Integer. О п е р а ц и я Not . Операция Not обозначает отрицание (инверсию) логического значения своего операнда типа Boolean: not TRUE = FALSE not FALSE = TRUE TURBO допускает применение оператора Not к операнду типа Integer: при этом получается побитовое отрицание . П р и м е р ы. not 0 = -1 not -15 = 14 ───────────── not $2345 = $DCBA М у л ь т и п л и к а т и в н ы е о п е р а ц и и Символ операции Операция Тип операндов Тип результата ─────────────── ──────── ───────────── ────────────── * умножение Real Real * умножение Integer Integer * умножение Real , Integer Real / деление Real , Integer Real / деление Integer Real / деление Real Real div деление Integer Integer mod взятие по модулю Integer Integer and арифметическое И Integer Integer shl Integer Integer shr Integer Integer П р и м е р ы. 12*34=408 123/4=30.75 ───────────── 123 div 4 =30 12 mod 5=2 True and Fales=Fales 2 shl 7=256 256 shr 7=2 А д д и т и в н ы е о п е р а ц и и Оператор Операции Тип операндов Тип результата ──────── ──────── ───────────── ────────────── + сложение Real Real + сложение Integer Integer + сложение Real,Integer Real - вычитание Real Real - вычитание Integer Integer - вычитание Real,Integer Real or арифметическое ИЛИ Integer Integer or логическое ИЛИ Boolean Boolean xor арифметическое Integer Integer xor логическое Boolean Boolean П р и м е р ы. 123+456=579 456-123,0=333,0 True or False=True ───────────── 12 or 22=30 True or False =True 12 xor 22=26 О п е р а т о р ы о т н о ш е н и я . Эти операторы работают со стан- дартными скалярными типами : Real,Integer,Boolean,Char,Byte . Операторы ти- пов Integer, Real и Byte могут встречаться в одном выражении . Тип резуль- тата всегда Boolean ,т.е. True или False. = равно >= больше или равно <> не равно <= меньше или равно < меньше > больше чем П р и м е р ы. a=b TRUE если a=b ───────────── atrue если a не равно b a<=b TRUE если a меньше или равно b a>b TRUE если a больше b a>=b TRUE если a больше или равно b В ы з о в ф у н к ц и и Для обращения к функции указывается имя функции, за которым следует спи- сок передаваемых параметров, разделенных запятыми и заключенных в скобки. Если функция не является стандартной, она должна быть описана. П р и м е р ы. Round(Plotpos) (Max(X,Y)<25) and (Z>Sqrt(X*Y)) ───────────── Writeln(Pi*(8 оr (R))) Volume(Radius,Height) О п е р а ц и и (без приоритета!) ┌────────┬──────────────────────┬──────────────────┬────────────────────┐ │Операция│ Смысл │ Тип операнда(-ов)│ Т и п результата │ ├────────┼──────────────────────┼──────────────────┼────────────────────┤ │ + │ Унарный плюс │ Integer, Real │ Результат того же │ │ │ │ │ типа │ │ - │ Унарный минус │ Integer,Real │ Результат того же │ │ │ │ │ типа │ │ not │ Отрицание │ Integer,Boolean │ Результат того же │ │ │ │ │ типа │ │ * │ У м н о ж е н и е │ Integer,Real │ Integer,Real │ │ * │ Пересечение множеств │ Любой множествен-│ Результат того же │ │ │ │ ный тип │ типа │ │ / │ Д е л е н и е │ Integer,Real │ Real │ │ div │ Целочисленное деление│ Integer │ Integer │ │ mod │ Нахождение остатка │ Integer │ Integer │ │ and │ Арифметическое "и" │ Integer │ Integer │ │ and │ Логическое "и" │ Boolean │ Boolean │ │ shl │ Сдвиг влево │ Integer │ Integer │ │ shr │ Сдвиг вправо │ Integer │ Integer │ │ + │ С л о ж е н и е │ Integer,Real │ Integer,Real │ │ + │ Конкатенация строк │ String │ String │ │ + │ Объединение множеств │ Любой множествен-│ Результат того же │ │ │ │ ный тип │ типа │ │ - │ В ы ч и т а н и е │ Integer,Real │ Integer,Real │ │ - │ Вычитание множеств │ Любой множествен-│ Результат того же │ │ │ │ ный тип │ типа │ │ or │ Арифметическое "или" │ Integer │ Integer │ │ or │ Логическое "или" │ Boolean │ Boolean │ │ xor │ Арифметическое "ис- │ Integer │ Integer │ │ │ ключающее или" │ │ │ │ xor │ Логическое "исключа- │ Boolean │ Boolean │ │ │ ющее или" │ │ │ │ = │ Равенство │любой скалярный │ Boolean │ │ │ │ тип │ │ │ = │ Равенство │ String │ Boolean │ │ = │ Равенство │ любой множествен-│ Boolean │ │ │ │ ный тип │ │ │ = │ Равенство │ ссылочный тип │ Boolean │ │ <> │ Неравенство │любой скалярный │ Boolean │ │ │ │ тип │ │ │ <> │ Неравенство │ String │ Boolean │ │ <> │ Неравенство │ любой множествен-│ Boolean │ │ │ │ ный тип │ │ │ <> │ Неравенство │любой ссылочный │ Boolean │ │ │ │ │ │ │ >= │ Больше либо равно │любой скалярный │ Boolean │ │ │ │ тип │ │ │ >= │ Больше либо равно │ String │ Boolean │ │ >= │ Проверка на включение│ любой множествен-│ Boolean │ │ │ Множеств │ ный тип │ │ │ <= │ Меньше либо равно │любой скалярный │ Boolean │ │ │ │ тип │ │ │ <= │ Меньше либо равно │ String │ Boolean │ │ <= │ Проверка на включение│ любой множествен-│ Boolean │ │ │ Множеств │ ный тип │ │ │ < │ Меньше │любой скалярный │ Boolean │ │ │ │ тип │ │ │ < │ Меньше │ String │ Boolean │ │ > │ Больше │любой скалярный │ Boolean │ │ │ │ тип │ │ │ > │ Больше │ String │ Boolean │ │ in │ Проверка на вхождение│ см. ниже │ Boolean │ │ │ элемента в множество │ │ │ └────────┴──────────────────────┴──────────────────┴────────────────────┘ 1. Знаки операций +,-,*,/ не требуют дополнительных пояснений (сложе- ние, вычитание, умножение, деление), но две операции, знаки которых div и mod, являющиеся двухместными (для двух целых аргументов), поясним. Если p и q - неотрицательные целые числа и q┼0, то p div q - целое число, частное от деления p на q; p mod q - остаток, возникающий при делении p на q. В математических обозначениях по определению { ┌ p ┐ p { │ ─ │ , ─ >0 { └ q ┘ q p div q = { { ┌ p ┐ p { -││ ─ ││ , ─ <0 { └ q ┘ q где [a] - целая часть a. p mod q = p - ((p div q)*q) 2. Первый операнд в операции in может быть любого скалярного типа, а второй операнд должен быть множеством того же типа. 3. < Выражение1 > shr < Выражение 2 > Значение < Выражение 1 > сдвигается в п р а в о на < Выражение2 > битов. П р и м е р. 2 shl 7 ───Ў 256 ибо ─────────── 00000010 ──Ў 100000000 4. В and, xor, or, not, применимых к целым - побитная обработка. 5. Перейдем к союзу "или". В бытовой речи этот союз употребляется в двух смыслах - исключенном и неисключенном. Например, высказывание "в поездке будут использованы поезда или само- леты" можно трактовать двояко: а) "в поездке будут использованы или поезда, или самолеты, или и то, и другое"; в) "в поездке будет использован только один какой-нибудь вид тран- спорта - поезда или самолеты". Какой смысл вкладывается в высказывание с союзом "или", обычно ясно из к о н т е к с т а . (А что такое контекст?) Чтобы пользоваться контекстом и определенно знать, что мы имеет в виду, будем различать эти два случая употребления союза "или" и говорить, что в первом случае употреблено н е и с к л ю ч е н н о е ИЛИ, а во втором - и с к л ю ч е н н о е ИЛИ. Условимся далее считать, что составное высказывание "X или Y" , где "или" - и с к л ю ч е н н о е, истинно тогда, когда либо X истинно, а Y ложно, либо когда X ложно, а Y истинно; в остальных случаях, т.е. когда и X, и Y истинны, или и X, и Y ложны, это высказывание будем считать ложным. Таким образом имеем следующую таблицу истинности: ┌───────┬───────┬───────────┐ │ X │ Y │ X xor Y │ ├───────┼───────┼───────────┤ │ TRUE │ TRUE │ FALSE │ │ FALSE │ FALSE │ FALSE │ │ TRUE │ FALSE │ TRUE │ │ FALSE │ TRUE │ TRUE │ └───────┴───────┴───────────┘ 4.1 С т а н д а р т н ы е ф у н к ц и и ──────────────────────────────────── Язык программирования Pascal имеет простые средства записи элементар- ных или, как их называют, с т а н д а р т н ы х функций. При этом пользо- вателю-программисту необязательно знать, как вычисляется значение стан- дартной функции, ему достаточно правильно записать ее вид. П р а в и л а записи стандартных функций: 1) имя функции записывается буквами латинского алфавита; 2) аргумент функции записывается в круглых скобках после имени функции; 3) аргумент функции может быть константой, именем переменной или выра- жением. Стандартные арифметические функции приведены в таблице ниже.Следует за- метить, что в тригонометрических функциях синус и косинус аргумент может быть задан только в радианной мере. Если аргумент X дан в градусах, то для перевода его в радианы используется формула X■3.14159/180. А р и ф м е т и ч е с к и е ф у н к ц и и ┌─────────┬───────────────────────────────┬─────────────┬───────────────┐ │ Функция │ Н а з н а ч е н и е │Тип аргумента│ Тип функции │ ├─────────┼───────────────────────────────┼─────────────┼───────────────┤ │ Abs(X) │ Вычисление абсолютного значе- │Real,Integer │ Real, Integer │ │ │ ния X │ │ │ │ Sqr(X) │ Вычисление квадрата X (X2) │Real,Integer │ Real, Integer │ │ Sin(X) │ Вычисление синуса X │Real,Integer │ Real, Real │ │ Cos(X) │ Вычисление косинуса X │Real,Integer │ Real, Real │ │Arctan(X)│ Вычисление арктангенса X │Real,Integer │ Real, Real │ │ Exp(X) │ Вычисление экспоненты X │Real,Integer │ Real, Real │ │ Ln(X) │ Вычисление натурального лога- │Real,Integer │ Real, Real │ │ │ рифма X │ │ │ │ Sqrt(X) │ Вычисление квадратного корня │Real,Integer │ Real, Real │ │ │ из X │ │ │ │ Trunc(X)│ Отбрасывание дробной части X │Real,Integer │Integer,Integer│ │ Round(X)│ Округление X в сторону ближай-│Real,Integer │Integer,Integer│ │ │ шего целого │ │ │ │ Int(X) │ Значение целой части X │Real,Integer │ Real, Real │ │ Frac(X) │ Значение дробной части X │Real,Integer │ Real, Real │ └─────────┴───────────────────────────────┴─────────────┴───────────────┘ Для возведения в степень используются стандартные функции: exp(x) - экспонента и ln(x) - натуральный логарифм. x При необходимости вычислить значение функции y = a на языке Pascal воспользуйтесь арифметическим выражением Exp(x*Ln(a)) Вместе с тем небольшие целые степени лучше вычислять с помощью умно- жения, т.к. результат умножения более точен, чем результат вычислений с помощью стандартных функций exp и ln. Заметим, что людольфово число п (так иногда называют число п в честь голландского математика Людольфа ван Цойтена (1540-1610)) можно получить следующим обращением к встроенной функции Arctan(X): 4 * Arctan(1) = 3.1415926536 (п с 11 знаками) или a неперово число е: Exp(1) = 2.7182818285 . Обратите внимание, что из-за особенностей машинной арифметики в послед- них двух цифрах результата - ошибка: мы должны были бы иметь...вместо...! В ы з о в стандартной функции осуществляется путем указания в нужном месте программы и м е н и функции (Abs,Ln,Exp и т.д.) и ее аргумента, заключенного в круглые скобки. После вычисления значения встроенной функ- ции вызов функции заменяется вычисленным значением и затем продолжается вычисление выражения, содержащего вызов функции. Следующий Ваш вопрос: как вычислить логарифм по любому положительному и отличному от единицы основанию? Для этого воспользуйтесь следующей формулой ln a log a = ──── b ln b В приведенной таблице отсутствуют функции tg x , ctg x, arcsin x и arccos x. Они известным образом выражаются через табличные функции, например x arcsin x = arctg ────── , │x│<1 v(1-x2) { v(1-x2 { arctg ────── , 00 Trunc(X) = { [X+1] , X<0 { Trunc(X+0.5), X>0 Round(X) = { Trunc(X-0.5), X<0 Функция Trunc называется "отсечением дробных десятичных разрядов", а функция Round - "округлением". 4.2 П р е д и к а т ы (логические функции) ─────────────────────────────────────── ┌─────────┬─────────────────────────────────┬─────────────┬──────────────┐ │ Функция │ Н а з н а ч е н и е │Тип аргумента│Тип результата│ ├─────────┼─────────────────────────────────┼─────────────┼──────────────┤ │ Odd(X) │ TRUE, если Х - н е ч е т н о е │ Integer │ Boolean │ │ │ FALSE, если Х - ч е т н о е │ │ │ │ Succ(X) │ Элемент, являющийся следующим │ Boolean │ Boolean │ │ │ для данного в перечне допустимых│ │ │ │ │ элементов │ │ │ │ EOF(F) │ TRUE, если файловая переменная │ Файловый │ Boolean │ │ │ F указывает на символ "конец │ │ │ │ │ файла" │ │ │ │ │ FALSE, если файловая переменная │ │ │ │ │ F не указывает на символ "конец │ │ │ │ │ файла" │ │ │ │ EOLN(F) │ TRUE, если файловая переменная │ Файловый │ Boolean │ │ │ F указывает на "символ" "конец │ │ │ │ │ строки" │ │ │ │ │ FALSE, если файловая переменная │ │ │ │ │ F не указывает на "символ" "ко- │ │ │ │ │ нец строки" │ │ │ └─────────┴─────────────────────────────────┴─────────────┴──────────────┘ 4.3 Ф у н к ц и и п р е о б р а з о в а н и я ────────────────────────────────────────── Функции преобразования позволяют отображать множество литер на подмно- жество натуральных чисел и наоборот. Порядковые номера литер - это значения целого типа,которые определяются реализацией и задаются путем отображения литерных значений в последователь- ные неотрицательные целые значения, начинающиеся с нуля. Отображение должно сохранять порядок следования литер. ┌─────────┬─────────────────────────────────┬───────────────┬────────────┐ │ Функция │ Н а з н а ч е н и е │ Тип аргумента │ Тип функции│ │─────────┼─────────────────────────────────┼───────────────┼────────────┤ │ │ 1. Нахождение порядкового номера│ │ │ │ │ элемента Х в перечне допусти-│ Boolean │ Integer │ │ │ мых типов (счет начинается от│ перечислимый │ Integer │ │ │ нуля) │ │ │ │ Ord(X) ├─────────────────────────────────┼───────────────┼────────────┤ │ │ 2. ORD(X)=X │ Integer │ Integer │ │ ├─────────────────────────────────┼───────────────┼────────────┤ │ │ 3. Определение номера символа │ │ │ │ │ языка Pascal в десятичной │ Char │ Integer │ │ │ системе счисления │ │ │ │─────────┼─────────────────────────────────┼───────────────┼────────────┤ │ Chr(X) │ Определение символа по его коду │ Integer │ Char │ │ │ ASCII │ │ │ │─────────┼─────────────────────────────────┼───────────────┼────────────┤ │ │ Нахождение элемента, являющегося│ │ │ │ Pred(X) │ предыдущим для данного в перечне│ перечислимый │перечислимый│ │ │ допустимых элементов │ │ │ │─────────┼─────────────────────────────────┼───────────────┼────────────┤ │ Succ(X) │ Нахождение элемента, являющегося│ Integer │ Integer │ │ │ следующим для данного в перечне │ Char │ Char │ │ │ допустимых элементов │ │ │ └─────────┴─────────────────────────────────┴───────────────┴────────────┘ В коде ASCII множество латинских букв является с в я з н ы м, т.е. коды всех латинских букв идут п о д р я д! Нетрудно видеть, что между функциями преобразования существует следующая взаимосвязь: Chr(Ord(C)) возвращает C . Обратное соотношение Ord(Chr(I)) возвращает I, вообще говоря, не всегда выполняется. Оно несправедливо в случае, когда I выходит за пределы целых значений, в которые отображается множество литер. Значение функции Chr(I) тогда оказывается неопределенным. Отметим, что упорядоченность литерных значений точно такая же, как и упорядоченость их порядковых номеров. Пусть CH1 и CH2 - переменные литерного типа. В этом случае CH1, <, <=, >, >= . В этом случае от- ношение CH1 R CH2 выполняется тогда и только тогда, когда ORD(CH1) R ORD(CH2) П р и м е р. ─────────── { Имеется перечень зверей. Определить в этом списке порядковый номер тигра и порядковый номер зверя после косули } PROGRAM pr (input,output); type zwerx=(lisa,wolk,zaqc,zubr,tigr,lew,medwedx,kosulq,olenx,bars); var p1,p2: zwerx; n1,n2: integer; BEGIN p1:=tigr; p2:=succ (kosulq); n1:=ord(p1)+1; n2:=ord(p2)+1; writeln('Порядковый номер tigra=',n1:2); writeln('Порядковый номер зверя ','после kosuli=',n2:2) END.