Рефераты - Афоризмы - Словари
Русские, белорусские и английские сочинения
Русские и белорусские изложения
 

Основы программирования на языке Паскаль

Работа из раздела: «Программирование и комп-ры»

|                                                                           |
|Краткий курс лекций                                                        |
|'Основы программирования на языке Паскаль'                                 |
|                                                                           |
|                                                                           |
|Введение.                                                                  |
|     Прежде всего, следует напомнить, что изучение языка программирования  |
|представляет собой знакомство с формальными правилами записи алгоритмов для|
|их последующего выполнения компьютером. Формальность сия проистекает из    |
|самих принципов, заложенных в архитектуру вычислительных устройств, и      |
|жесткости математической логики. Поэтому, постарайтесь воспринять все      |
|довольно строгие правила как неизбежность, настроить себя на серьезную,    |
|скрупулезную, порой сложную работу. Однако не стоит бояться, расстраиваться|
|и сетовать на судьбу: немного аккуратности, внимания, знания предыдущего   |
|материала - и вы уже программист.                                          |
|                                                                           |
|Основные понятия.                                                          |
|     Как и любой алгоритм, являющийся, как вы помните, последовательностью |
|инструкций, программа на языке Паскаль состоит из команд (операторов),     |
|записанных в определенном порядке и формате.                               |
|     Команды позволяют получать, сохранять и обрабатывать данные различных |
|типов (например, целые числа, символы, строки символов, т.д.). Однако кроме|
|команд в записи программы участвуют еще так называемые 'служебные слова'.  |
|Это и есть элементы формальности, организующие структуру программы. Их не  |
|так много, но их значение трудно переоценить. Служебные слова можно        |
|использовать только по своему прямому назначению. Переопределять их не     |
|разрешается.                                                               |
|     Вам уже известно, что основное назначение компьютера - облегчить      |
|человеку работу с большими объемами информации, поэтому подавляющее        |
|большинство программ построено по одному, довольно простому принципу:      |
|получение данных из внешнего мира (ввод), обработка их по соответствующему |
|алгоритму, хранение необходимой информации и вывод во внешний (по отношению|
|к компьютеру) мир полученных результатов. Все эти действия реализуются     |
|через имеющиеся в языках программирования команды, алгоритмические         |
|структуры и структуры данных.                                              |
|                                                                           |
|Основная структура программы.                                              |
|     Правила языка Паскаль предусматривают единую для всех программ форму  |
|основной структуры:                                                        |
|Program <Имя программы>;                                                   |
|<Раздел описаний>                                                          |
|Begin                                                                      |
|<Тело программы>                                                           |
|End.                                                                       |
|     Здесь слова Program, Begin и End являются служебными. Правильное и    |
|уместное употребление этих слов является обязательным.                     |
|     Угловые скобки в формате указывают на то, что вместо них при реальном |
|программировании должно быть подставлено конкретное значение. Сама запись  |
|программы в принципе может производиться вообще в одну стоку. При этом ее  |
|части должны отделяться друг от друга хотя бы одним пробелом. Однако, такая|
|запись неудобна для чтения, недостаточно наглядна, поэтому я рекомендую    |
|придерживаться приведенной структуры, а в теле программы по возможности    |
|записывать по одному оператору в строке.                                   |
|     Имя программы выбирается программистом самостоятельно в соответствии с|
|правилами построения идентификаторов.                                      |
|     Все объекты, не являющиеся зарезервированными в Паскале, наличие      |
|которых обусловлено инициативой программиста, перед первым использованием в|
|программе должны быть описаны. Это производится для того, чтобы компьютер  |
|перед выполнением программы зарезервировал память под соответствующие      |
|объекты и поставил в соответствие этим участкам памяти идентификаторы.     |
|Раздел описаний может состоять из пяти подразделов:                        |
|     1. Описание меток (Label).                                            |
|     2. Описание типов (Type).                                             |
|     3. Описание констант (Const).                                         |
|     4. Описание переменных (Var).                                         |
|     5. Описание процедур и функций (Procedure, Function).                 |
|     При отсутствии необходимости в каком-либо виде объектов,              |
|соответствующий подраздел может быть опущен.                               |
|                                                                           |
|Алфавит языка.                                                             |
|     Основу любого языка составляет алфавит, то есть конечный,             |
|фиксированный набор символов, используемых для составления текстов на      |
|данном языке (в нашем случае - программ). Конечно, стройность картины      |
|немного портит наличие диалектов, создающихся стихийно и очень часто       |
|включающих в себя апокрифические (неканонические) буквы и знаки. В         |
|программировании эта проблема решается введением понятия 'стандарт языка'. |
|Оно практически неприменимо к языкам человеческим, вечно развивающимся и   |
|изменяющимся. Мы с вами в основном будем говорить о той самодостаточной    |
|части языка Паскаль, которая входит в различные его компьютерные реализации|
|в неизменном виде. В плане изучения, я не вижу большого смысла излагать вам|
|строгие правила стандарта, хотя такие существуют. Ограничимся некоторыми   |
|замечаниями, раскрывающими все же формальности употребления символов в     |
|языке Паскаль.                                                             |
|     Итак, алфавит языка Паскаль составляют:                               |
|     1) буквы латинского алфавита;                                         |
|     2) арабские цифры;                                                    |
|     3) специальные знаки.                                                 |
|     Использование символов первой группы чаще всего вопросов не вызывает, |
|но свои тонкости здесь имеются. Во-первых, это употребление заглавных и    |
|строчных букв. Большинство существующих трансляторов не различают буквы    |
|разных регистров. Таким образом, записи 'progRaM' и 'PROGram' будем считать|
|идентичными. Во-вторых, некоторые символы латиницы и кириллицы совпадают по|
|начертанию. Нельзя ли вместо буквы 'К' латинской написать 'K' русскую?     |
|Ответ: в тетради (если вы их сможете различить) - пожалуйста, в программе  |
|на ЭВМ - ни в коем случае. На вид они может быть и похожи, но уж коды-то у |
|них совершенно разные, а компьютер, как вам известно, оперирует внутри себя|
|не буквами, а их числовыми кодами.                                         |
|     По поводу привычных арабских цифр сказать можно только то, что с их   |
|помощью записываются не только числа. Цифры в качестве обыкновенных        |
|символов могут использоваться в различных других конструкциях языка.       |
|     Сложнее всего обстоит дело со специальными знаками, поэтому их        |
|придется разобрать подробно, иногда забегая вперед, но вы пока можете      |
|пропускать мимо ушей непонятные термины, не забывая, однако, записывать все|
|в тетрадь. Потом, при изучении соответствующих структур, вы будете иметь   |
|возможность заглянуть в этот раздел для того, чтобы уточнить какой знак в  |
|данном месте необходимо использовать.                                      |
|     Наиболее часто употребляемым специальным символом является пробел (в  |
|значимых местах мы будем обозначать его в записях знаком 'V'). Его         |
|использование связано с форматами основной структуры программы, разделов   |
|описаний, операторов. Не следует путать наличие пробела с отсутствием      |
|символа.                                                                   |
|     .    конец программы, разделение целой и дробной частей вещественного |
|числа (десятичная точка), разделение полей в переменной типа Record;       |
|     ,    разделение элементов списков;                                    |
|     ..    указание диапазона;                                             |
|     :    используется в составе оператора присваивания, а также для       |
|указания формата вывода в операторе Writeln;                               |
|     ;    отделяет один раздел программы от другого, разделяет операторы;  |
|     '    используется для ограничения строковых констант;                 |
|     - + * / ( )    арифметические знаки (используются по своему           |
|назначению);                                                               |
|     < >    знаки отношений;                                               |
|     =    используется в составе оператора присваивания, в разделах        |
|описаний констант и типов, используется как знак отношения (равно);        |
|     @    имя специального оператора определения адреса переменной,        |
|подпрограммы;                                                              |
|     ^    используется для именования динамических переменных;             |
|     {}    ограничение комментариев в программе;                           |
|     [ ]    заключают в себе индексы элементов массивов;                   |
|     _    символ подчеркивания используется также как любая буква,         |
|например, в идентификаторах - вместо пробела;                              |
|     #    обозначение символа по его коду;                                 |
|     $    обозначение директивы компилятора, обозначение шестнадцатеричного|
|числа.                                                                     |
|     Возникает вопрос, а как же быть с русскими буквами и другими знаками, |
|имеющимися на клавиатуре? Некоторые версии Паскаля допускают их            |
|использование в программе, но стандарт языка этого не подразумевает.       |
|Поэтому включать эти символы в программу можно только в качестве строковых |
|констант или внутри комментария, то есть там, где транслятор при компиляции|
|их игнорирует. При использовании этих знаков в качестве данных, они        |
|равноправны со всеми символами, которые может хранить в памяти и           |
|обрабатывать компьютер.                                                    |
|                                                                           |
|Идентификаторы.                                                            |
|     Имена операторов, переменных, констант, типов величин, имя самой      |
|программы назначаются программистом и называются в Паскале                 |
|идентификаторами. Существуют правила, которым должны отвечать все          |
|идентификаторы:                                                            |
|идентификатор должен быть уникальным, то есть одним и тем же именем разные |
|объекты не могут быть названы;                                             |
|идентификатор имеет ограничение по длине (зависит от конкретной реализации |
|языка на компьютере);                                                      |
|идентификатор может состоять только из символов латинского алфавита, цифр и|
|знака подчеркивания ('_');                                                 |
|идентификатор не может начинаться с цифры.                                 |
|                                                                           |
|Константы.                                                                 |
|     Из всех подразделов описаний сейчас мы рассмотрим только описание     |
|констант и переменных, остальные - позже.                                  |
|     Вообще говоря, в Паскале константами являются любые явно заданные в   |
|программе данные (например, 7493, 'привет', 54.899). Следует обратить ваше |
|внимание на то, что при записи числовых констант с дробной частью эта часть|
|отделяется от целой не запятой, как, возможно, вы привыкли, а точкой. Для  |
|записи очень больших по модулю или очень малых (близких к нулю) чисел      |
|существует возможность записи их в так называемой экспоненциальной форме. С|
|такой записью вы встречались в математике и физике, но называли ее         |
|стандартным видом числа.                                                   |
|     Пример: 2 . 4 5 6 7 Е - 0 6                                           |
|                ^мантисса   ^порядок                                       |
|     Здесь буква 'Е' отделяет мантиссу (совокупность значащих цифр числа с |
|десятичной точкой после первой) от порядка (показателя степени десятки в   |
|стандартном виде числа). Вам предстоит научиться как читать числа в таком  |
|виде, так и записывать.                                                    |
|     Константы, представляющие собой строковые величины, заключаются в     |
|апострофы.                                                                 |
|     Если одна и та же величина используется в программе несколько раз, то |
|удобнее было бы обозначить ее каким-нибудь именем и использовать это имя   |
|везде, где требуется записать соответствующую константу. Кроме сокращения  |
|размера исходного текста программы, это позволит избежать случайных ошибок,|
|а также упростит отладку программы. Описание именованных констант          |
|начинается служебным словом Const. Далее следуют записи вида:              |
|<Идентификатор>=<значение>;                                                |
|Пример:                                                                    |
|Const                                                                      |
|Pi=3.14;                                                                   |
|Name1='Татьяна';                                                           |
|Name2='Виктор';                                                            |
|R21=6.33187E+03;                                                           |
|W_W_W=934122;                                                              |
|Понятие переменной. Типы.                                                  |
|     Данные, как вы знаете, хранятся в памяти компьютера, но для указания  |
|на конкретную информацию очень неудобно все время записывать физические    |
|адреса ячеек. Эта проблема в языках программирования высокого уровня, в    |
|частности в Паскале, решена введением понятия переменной. Переменная в     |
|Паскале - именованный участок памяти для хранения данных определенного     |
|типа. Значение переменной (информация в соответствующих ячейках памяти) в  |
|ходе выполнения программы может быть изменено. Константами же, как вы уже  |
|знаете, называются величины, значение которых в ходе выполнения программы  |
|изменено быть не может. Конкретные переменные и константы представляют     |
|собой объекты уникальные и отличаются друг от друга именем.                |
|     В качестве данных в программах на языке Паскаль могут выступать числа,|
|символы, целые строки символов. Заметьте, что с этими различными видами    |
|информации выполняются совершенно разные действия. Например, с числовыми   |
|величинами производятся арифметические операции, чего невозможно сделать с |
|символьными. Кроме того, разные виды данных требуют различного объема      |
|памяти для хранения. В соответствии с этими соображениями в языке Паскаль  |
|введено понятие 'Тип' (TYPE). Тип переменной указывает на то, какие данные |
|могут быть сохранены в этом участке памяти, и в каких действиях эта        |
|переменная может участвовать. Существуют зарезервированные (базовые) типы в|
|языке Паскаль, но, как далее вы убедитесь, есть также возможность создавать|
|свои собственные, определяемые программистом типы переменных.              |
|     К базовым типам относятся:                                            |
|тип целых чисел - Integer                                                  |
|тип 'длинных' целых чисел - Longint                                        |
|тип действительных (вещественных) чисел (то есть - с дробной частью) - Real|
|                                                                           |
|тип неотрицательных целых чисел от 0 до 255 - Byte                         |
|тип неотрицательных целых чисел от 0 до 65535 - Word                       |
|символьный тип - Char                                                      |
|строковый тип - String                                                     |
|логический тип - Boolean                                                   |
|     Физически типы данных отличаются друг от друга количеством ячеек      |
|памяти (байтов), отводимых для хранения соответствующей переменной.        |
|Логическое же отличие проявляется в интерпретации хранящейся информации.   |
|Например, переменные типа Char и типа Byte занимают в памяти по одному     |
|байту. Однако в первом случае содержимое ячейки памяти интерпретируется как|
|целое беззнаковое число, а во втором - как код (ASC) символа.              |
|     В отличие от констант, неименованных переменных не существует. Все    |
|используемые в программе переменные должны быть описаны в соответствующем  |
|разделе описания.                                                          |
|     Раздел описания переменных начинается служебным словом Var, после     |
|которого следуют записи следующего вида: <Список имен переменных>:<Название|
|типа>;                                                                     |
|     Список может состоять из нескольких имен (при этом они разделяются    |
|запятыми), а также и из одного имени. Тип, указываемый после двоеточия,    |
|определяет, какие данные теперь могут храниться в описанных таким образом  |
|переменных. Для каждого используемого в программе типа переменных в разделе|
|их описания должна быть, как минимум, одна собственная строка.             |
|     Пример:                                                               |
|Var                                                                        |
|A,B,H_22,Angle : Real;                                                     |
|Name3 : String;                                                            |
|Flag : Boolean;                                                            |
|I,J,K,Count : Word;                                                        |
|Оператор присваивания. Арифметические выражения.                           |
|     Самым простым действием над переменной является занесение в нее       |
|величины соответствующего типа. Иногда говорят об этом, как о присвоении   |
|переменной конкретного значения. Такая команда (оператор) в общем виде     |
|выглядит на языке Паскаль следующим образом:                               |
|     <Имя переменной>:=<Выражение>;                                        |
|     Выражение, указанное справа от знака ':=', должно приводить к значению|
|того же типа, какого и сама переменная, или типа, совместимого с переменной|
|относительно команды присваивания. Например, переменной типа Real можно    |
|присвоить значение типа Integer или Word (впрочем, наоборот делать нельзя).|
|Выражение будет сначала вычислено, затем, его результат будет положен в    |
|ячейки памяти, отведенные для переменной.                                  |
|     Что же представляет собой выражение на языке Паскаль? Многое зависит  |
|от типа выражения. Рассмотрим сначала выражения арифметические, то есть те,|
|результатом которых является число.                                        |
|     В состав арифметического выражения на языке Паскаль могут входить:    |
|числовые константы;                                                        |
|имена переменных;                                                          |
|знаки математических операций;                                             |
|математические функции и функции, возвращающие число;                      |
|открывающиеся и закрывающиеся круглые скобки.                              |
|     Правила построения выражений напоминают математические с некоторыми   |
|уточнениями. Выражение записывается в одну строку (никакой многоэтажности),|
|между операндами обязательно должен стоять знак операции (Запись '2x' - не |
|допускается), знаки некоторых операций и названия некоторых функций отличны|
|от привычных вам.                                                          |
|     Операции:                                                             |
|+     сложение;                                                            |
|-     вычитание;                                                           |
|/     деление;                                                             |
|*     умножение;                                                           |
|MOD     остаток от деления (записывается так: A MOD B; читается: остаток от|
|деления A на B); эта операция применима только к целым числам;             |
|DIV     целочисленное деление (записывается так A DIV B; читается:         |
|результат деления A на B без дробной части); эта операция тоже применяется |
|только для целых операндов.                                                |
|     Аргументы функций всегда записываются в круглых скобках:              |
|SIN(X)     sin x;                                                          |
|COS(X)    cos x;                                                           |
|ARCTAN(X)     arctg x;                                                     |
|ABS(X)     абсолютное значение x (в математике - |x|);                     |
|SQR(X)     возведение x в квадрат;                                         |
|SQRT(X)     извлечение квадратного корня;                                  |
|TRUNC(X)     отбрасывание дробной части х;                                 |
|ROUND(X)     округление х до ближайшего целого числа;                      |
|     После выполнения второго оператора присваивания в участке памяти,     |
|отведенном под переменную R, окажется результат указанного выражения,      |
|однако, к сожалению, узнать его мы не сможем, поскольку пока не имеем      |
|возможности 'заглянуть' в память машины, вывести значение переменной хотя  |
|бы на экран.                                                               |
|                                                                           |
|Составной оператор                                                         |
|     Этот оператор, строго говоря, оператором не является. Дело в том, что |
|также как арифметические действия иногда бывает необходимо заключать в     |
|скобки, последовательности команд (операторов) тоже иногда требуют         |
|объединения. Это позволяют сделать так называемые операторные скобки.      |
|Формат (общий вид) составного оператора таков:                             |
|Begin                                                                      |
|<Оператор 1>;                                                              |
|<Оператор 2>;                                                              |
|......                                                                     |
|<Оператор N>                                                               |
|End;                                                                       |
|     Возможно, такая структура напоминает вам основную структуру программы.|
|Действительно, отличие только в том, что после End в конце составного      |
|оператора ставится точка с запятой, а в конце программы - точка. По своей  |
|сути вся программа представляет собой большой составной оператор.          |
|     Обратите внимание на то, что точка с запятой перед End может не       |
|ставиться.                                                                 |
|     Составной оператор предоставляет возможность выполнить произвольное   |
|количество команд там, где подразумевается использование только одного     |
|оператора. Как вы узнаете потом, такая необходимость встречается довольно  |
|часто.                                                                     |
|                                                                           |
|Операторы ввода и вывода информации                                        |
|     Если вы помните, при рассмотрении примера работы оператора            |
|присваивания мы столкнулись с необходимостью узнать результат выполнения   |
|программы. Мы разобрались с тем, как информацию сохранять (в переменных),  |
|как обрабатывать (с использованием выражений), но два фундаментальнейших   |
|информационных процесса остались вне нашего внимания: получение информации |
|и передача ее во внешний по отношению к компьютеру мир. Пока наши программы|
|могут использовать лишь информацию, которая находится непосредственно в    |
|тексте программы. Узнать, какие значения в данный момент имеют переменные, |
|также не представлялось возможным. Программирование в таких условиях теряет|
|смысл.                                                                     |
|     Взаимодействие устройств обработки и хранения информации с внешней    |
|средой (хотя бы с пользователем) является совершенно необходимым. За такой |
|интерфейс в языке Паскаль отвечают операторы ввода-вывода информации. Эти  |
|инструкции позволяют ввести аргументы, параметры расчетов во время         |
|выполнения программы (а не на этапе ее написания), осуществить вывод       |
|рассчитанных данных в понятном человеку виде.                              |
|     Сначала операторы ввода (форматы операторов):                         |
|Read(<Список ввода>);                                                      |
|Readln(<Список ввода>);                                                    |
|     В таком формате эти команды позволяют вводить данные в переменные во  |
|время выполнения программы с клавиатуры. Элементами списка ввода могут быть|
|имена переменных, которые должны быть заполнены значениями, введенными с   |
|клавиатуры.                                                                |
|     Выполнение операторов ввода происходит так: ход программы             |
|приостанавливается, на экран выводится курсор, компьютер ожидает от        |
|пользователя набора данных для переменных, имена которых указаны в списке  |
|ввода. Пользователь с клавиатуры вводит необходимые значения в том порядке,|
|в котором они требуются списком ввода, нажимает Enter. После этого         |
|набранные данные попадают в соответствующие им переменные и выполнение     |
|программы продолжается.                                                    |
|     Примечание: данные при вводе разделяются пробелами.                   |
|     Разница между работой процедур Read и Readln (от Read line) состоит в |
|следующем: после выполнения Read значение следующего данного считывается с |
|этой же строчки, а после выполнения Readln - с новой строки.               |
|     Для вывода информации в Паскале также есть две команды:               |
|Write(<Список вывода>);                                                    |
|Writeln(<Список вывода>);                                                  |
|     Такой формат использования Write и Writeln позволяет выводить на экран|
|монитора данные из списка вывода. Элементами списка вывода могут являться  |
|имена переменных, выражения, константы. Прежде чем вывести на экран        |
|компьютер значения выражений сначала вычислит. Элементы списка, также как и|
|в операторах ввода, разделяются запятыми.                                  |
|     Различие между двумя операторами вывода таково: после выполнения      |
|оператора Writeln (от Write line) происходит переход на новую строчку, а   |
|после выполнения инструкции Write, переход на новую строчку не происходит и|
|печать по последующим командам вывода Write или Writeln будет происходить  |
|на той же строчке. При вызове оператора Writeln без параметров просто      |
|происходит переход на новую строчку.                                       |
|     Приведем пример использования операторов ввода и вывода:              |
|Program Inteface;                                                          |
|Var                                                                        |
|   R,S : Real;                                                             |
|Begin                                                                      |
|   Write('Введите радиус круга ');      {Печать на экране просьбы о вводе} |
|   Readln(R);                                        {Ввод значения в      |
|переменную R с клавиатуры}                                                 |
|   S:=4*ARCTAN(1)*SQR(R);           {Вычисление площади круга (pR2)}       |
|   Writeln('Площадь круга радиусом ',R,' равна ',S)                        |
|End.                                                                       |
|     Эта программа запрашивает у пользователя значение радиуса круга,      |
|обеспечивает возможность ввести его значение, рассчитывает и выводит на    |
|экран величину площади круга с таким радиусом. Таким образом, появляется   |
|возможность, не внося изменений в текст программы, вводить различные       |
|значения радиуса и получать, соответствующие им значения площади круга. Для|
|этого достаточно несколько раз запустить программу. Также эта программа    |
|демонстрирует следующее правило: выдача результатов должна быть            |
|прокомментирована так, чтобы был ясен смысл напечатанных чисел.            |
|Действительно, ведь можно было бы ограничиться Writeln(S), но значение     |
|выведенного программой числа в этом случае было бы ясно только тому, кто   |
|эту программу написал.                                                     |
|                                                                           |
|Метки. Оператор безусловного перехода.                                     |
|     Каждый дом на улице имеет свой номер, все люди имеют собственные      |
|имена, даже ячейки памяти компьютера имеют каждая свой адрес. Все это      |
|принято для того, чтобы иметь возможность однозначно указать на            |
|определяемый объект. Точно также, для указания на операторы в программах   |
|применяются метки.                                                         |
|     Метка в стандарте языка Паскаль представляет собой целое              |
|неотрицательное число. Все используемые в программе метки должны быть      |
|перечислены в разделе описания меток, начинающемся служебным словом Label, |
|например:                                                                  |
|      Label 1, 2, 8;                                                       |
|     Одной меткой можно пометить только один оператор. Метка от помеченного|
|оператора отделяется двоеточием.                                           |
|Пример:                                                                    |
|     6: Writeln(14/2);                                                     |
|     Во всех приведенных ранее программах операторы выполнялись один за    |
|другим в том порядке, в котором они были записаны в тексте. Такая          |
|алгоритмическая структура называется прямым следованием. Однако, в языке   |
|Паскаль изначально существует оператор, нарушающий прямолинейное выполнение|
|программы, передающий управление в произвольную ее точку. Такая инструкция |
|называется безусловным переходом и имеет такой формат:                     |
|     Goto <метка>;                                                         |
|     Оператор, к которому происходит переход должен быть помечен данной    |
|меткой.                                                                    |
|     Использовать оператор безусловного перехода следует крайне осторожно  |
|во избежание получения ошибочных результатов или полного 'зацикливания'    |
|программы. Вообще, употребление данной команды среди программистов         |
|считается дурным тоном. Как вы убедитесь, всегда существует возможность    |
|обойтись без него.                                                         |
|                                                                           |
|Условный оператор                                                          |
|Одной из основных алгоритмических структур является ветвление              |
|(альтернатива).                                                            |
|     Если условие выполняется, то будет выполнена инструкция '1', если нет,|
|то - инструкция '2'. Несмотря на то, что в схеме присутствуют два действия,|
|выполнено будет только одно, так как условие либо ложно, либо истинно.     |
|Третьего не дано. Такая схема позволяет решать задачи, в которых в         |
|зависимости от сложившихся обстоятельств требуется совершить то или иное   |
|действие. Нет никакого сомнения, что число задач такого рода огромно. Более|
|того, очень сложно придумать реально значимое задание, алгоритм выполнения |
|которого содержал бы в себе простое прямое следование команд. Даже         |
|примитивный пример, взятый из курса математики, как вы увидите, не может   |
|быть решен без использования ветвления. Итак, необходимо вычислить значение|
|выражения y=1/x. Вам известно, что данная функция не всегда имеет значение,|
|то есть не для всех значений аргумента существует значение результата. Наша|
|задача так составить алгоритм, чтобы исполнитель ни в коем случае не встал |
|в тупик, даже при получении нуля в качестве аргумента. Сформулировать это  |
|на естественном языке не трудно:                                           |
|1. Получить значение x.                                                    |
|2. Если x=0, то сообщить, что выражение значения не имеет, иначе -         |
|вычислить y как 1/x.                                                       |
|     Таким образом используется приведенная выше алгоритмическая структура.|
|Она может быть выражена простыми словами:                                  |
|     Если <усл.>                {Если выполняется условие}                 |
|     то <действие 1>         {то выполнить действие № 1 }                  |
|     иначе <действие 2>   {иначе - выполнить действие № 2 }                |
|все                                                                        |
|     Как это записать на Паскале? Да точно так же, только по-английски.    |
|     Формат условного оператора на языке Паскаль:                          |
|     If <условие>                                                          |
|     Then <оператор 1>                                                     |
|     Else <оператор 2>;                                                    |
|     Обратите внимание на то, что в Then- и Else- части стоит только один  |
|оператор. Но что делать, чтобы решить задачу, в которой по выполнению или  |
|невыполнению условия нужно совершить не одно, а несколько действий? Здесь  |
|приходит на помощь уже известный вам составной оператор. В операторные     |
|скобки можно заключить любое количество операторов.                        |
|     Вариант условного оператора в этом случае:                            |
|If <условие>                                                               |
|Then Begin <группа операторов 1> end                                       |
|Else Begin < группа операторов 2> end;                                     |
|     Знак 'точка с запятой' не ставится перед служебным словом Else, но    |
|операторы в группах, естественно, отделяются друг от друга этим знаком.    |
|     Теперь поговорим об условиях. В программах на языке Паскаль условия   |
|представляют собой выражения, значением которых является величина          |
|логического (Boolean) типа. Это может быть как просто переменная указанного|
|типа, так и сложная последовательность высказываний, связанных логическими |
|операциями.                                                                |
|     В простых условиях могут применяться знаки операций сравнения:        |
|>(больше), <(меньше), =(равно), <>(не равно), >=(больше или равно),        |
|<=(меньше или равно).                                                      |
|     Примеры простых условий:      A=5 {Значение переменной А равно 5}     |
|     (C+D3)>=(D1*(45-2)) {Значение выражения в левой части больше либо     |
|равно значению выражения из правой части}                                  |
|     S<>'ABC' {Значение переменной S не равно строковой константе 'ABC'}   |
|     Приведем пример решения еще одной задачи: 'Из двух чисел выбрать      |
|наибольшее'.                                                               |
|     На первый взгляд решение очевидно, но оно не столь тривиально, как    |
|кажется.                                                                   |
|Program Example;                                                           |
|Var A,B,C : Real; {A,B - для хранения аргументов, C - результат}           |
|Begin                                                                      |
|Writeln('Введите два числа');                                              |
|Readln(A,B);                            {Вводим аргументы с клавиатуры}    |
|If A>B Then C:=A Else C:=B; {Если A>B, то результат - A, иначе результат - |
|B}                                                                         |
|Writeln(C);                               {Выводим результат на экран}     |
|End.                                                                       |
|     Еще один классический пример: 'По заданным коэффициентам решить       |
|квадратное уравнение'. Эта задача сложнее, поэтому перед тем как писать    |
|программу составим алгоритм, записав его в виде блок-схемы.                |
|Сначала вводим коэффициенты, затем вычисляем дискриминант. Теперь возникает|
|две возможности: либо отсутствие действительных корней в случае            |
|отрицательного дискриминанта, либо эти корни можно все-таки вычислить и    |
|вывести на экран в случае неотрицательного дискриминанта (случай равенства |
|дискриминанта нулю входит сюда же, корней - два, только они одинаковые J). |
|     При записи алгоритма на языке программирования следует учесть, что в  |
|ветви 'нет' не одно действие, а три, поэтому следует применить составной   |
|оператор. Арифметические выражения не забывайте записывать в соответствии с|
|правилами языка Паскаль. В остальном, эта программа не сложнее предыдущей. |
|                                                                           |
|                                                                           |
|                                                                           |
|Program Sq1;                                                               |
|Var A, B, C, D, X1, X2 : Real;                                             |
|Begin                                                                      |
|Writeln ('Введите коэффициенты квадратного уравнения');                    |
|Readln (A,B,C);                                                            |
|D:=B*B-4*A*C;                                                              |
|If D<0 Then Writeln ('Корней нет! ')                                       |
|Else                                                                       |
|Begin                                                                      |
|X1:=(-B+SQRT(D))/2/A;                                                      |
|X2:=(-B-SQRT(D))/2/A;                                                      |
|Writeln ('X1=', X1:8:3, ' X2=',X2:8:3)                                     |
|End                                                                        |
|End.                                                                       |
|     Интересно, что в качестве оператора, который выполняется по выполнению|
|или невыполнению условия, может выступать условный же оператор. В этом     |
|случае говорят о вложенности условных операторов. Я настоятельно рекомендую|
|при решении такого рода задач составлять блок-схему алгоритма в тетради.   |
|Только потом, при составлении программы, вам остается лишь аккуратно       |
|прописывать сначала всю Then- часть, а затем переходить к Else- части.     |
|Обычно при записи условных операторов на языке Паскаль (особенно при       |
|множественных ветвлениях) команды записывают уступом вправо и вниз. Это    |
|повышает наглядность, и, поверьте, снижает потери времени на отладку.      |
|     Для иллюстрации решим еще одну задачу: 'решить уравнение вида A*x^2 + |
|B*x + C = 0'. Прошу не путать с квадратным уравнением, для которого нам    |
|было известно, что коэффициент А не равен нулю. Здесь же коэффициенты могут|
|быть любыми числами. Исходя из элементарных математических рассуждений,    |
|получаем следующий алгоритм:                                               |
|[pic]                                                                      |
|Program Sq2;                                                               |
|Var A, B, C, D, X, X1, X2 : Real;                                          |
|Begin                                                                      |
|Writeln ('Введите коэффициенты уравнения (A, B, C) ');                     |
|If A=0 Then                                                                |
|    If B=0 Then                                                            |
|If C=0 Then Writeln('X - любое число')                                     |
|Else Writeln('Корней нет! ')                                               |
|    Else Begin X:=-C/B; Writeln('X=',X:8:3) End                            |
|Else                                                                       |
|Begin                                                                      |
|D:=B*B-4*A*C;                                                              |
|If D<0 Then Writeln ('Корней нет! ')                                       |
|Else                                                                       |
|Begin                                                                      |
|X1:=(-B+SQRT(D))/2/A;                                                      |
|X2:=(-B-SQRT(D))/2/A;                                                      |
|Writeln ('X1=', X1:8:3, ' X2=',X2:8:3)                                     |
|End                                                                        |
|End                                                                        |
|End.                                                                       |
|                                                                           |
|Цикл. Виды Циклов.                                                         |
|     Циклом называется многократное повторение однотипных действий. Телом  |
|же цикла будем называть те самые действия, которые нужно многократно       |
|повторять.                                                                 |
|     Как вы понимаете, повторять одни и те же действия можно и при помощи  |
|оператора безусловного перехода. Если записать эти действия в программе    |
|одно за другим, а в конце поставить оператор перехода к началу этого блока.|
|Однако таким образом можно получить только программу, которая работает     |
|вечно (зацикливается). Этого можно избежать, используя совместно с         |
|оператором перехода условный оператор, поставив выполнение перехода в      |
|зависимость от выполнения некого условия. Таким образом, мы получим        |
|структуру условного перехода и возможность организации конечного цикла.    |
|Вообще говоря, так мы можем решить практически любую задачу, требующую     |
|реализации циклического алгоритма. Конечно же, при помощи одного только    |
|топора можно построить дом. Поставим перед собой вопросы: 'А будет ли этот |
|дом красив? Сколько времени и сил можно сэкономить, используя всевозможные |
|специальные инструменты?'. Создатель языка Паскаль Никлаус Вирт также      |
|задался этими вопросами и решил их в пользу расширения языка тремя         |
|специальными возможностями организации циклов. Для чего? - Для удобства,   |
|краткости, простоты чтения программы и, не побоюсь этого слова, красоты.   |
|Итак, существует три вида цикла, имеющих собственные операторы на языке    |
|Паскаль для их записи. Эти виды имеют собственные условные названия:       |
|'Пока', 'До', 'С параметром'. Друг от друга они несколько отличаются и     |
|используются каждый для своего класса задач.                               |
|                                                                           |
|Цикл 'ПОКА'                                                                |
|Группа операторов, называемая 'телом цикла', судя по этой схеме, будет     |
|выполняться пока истинно условие цикла. Выход из цикла произойдет, когда   |
|условие перестанет выполняться.                                            |
|     Если условие ложно изначально, то тело цикла не будет выполнено ни    |
|разу. Если условие изначально истинно и в теле цикла нет действий, влияющих|
|на истинность этого условия, то тело цикла будет выполняться бесконечное   |
|количество раз. Такая ситуация называется 'зацикливанием'. Прервать        |
|зациклившуюся программу может либо оператор (нажав Ctrl+C), либо аварийный |
|останов самой программы, в случае переполнения переменной, деления на ноль |
|и т.п., поэтому использовать структуру цикла следует с осторожностью,      |
|хорошо понимая, что многократное выполнение должно когда-нибудь            |
|заканчиваться.                                                             |
|     На языке Pascal структура цикла 'Пока' записывается следующим образом:|
|                                                                           |
|     While <условие> Do <оператор>;                                        |
|     Правда, лаконично? По-русски можно прочитать так: 'Пока истинно       |
|условие, выполнять оператор'. Здесь, так же как в формате условного        |
|оператора, подразумевается выполнение только одного оператора. Если        |
|необходимо выполнить несколько действий, то может быть использован         |
|составной оператор. Тогда формат оператора принимает такой вид:            |
|While <условие> Do                                                         |
|Begin                                                                      |
|<оператор #1>;                                                             |
|<оператор #2>;                                                             |
|<оператор #3>;                                                             |
|. . .                                                                      |
|End;                                                                       |
|                                                                           |
|Цикл 'ДО'                                                                  |
|     Этот вид цикла отличается от предыдущего в основном тем, что проверка |
|условия повторения тела цикла находится не перед ним, а после. Поэтому цикл|
|'До' называют циклом 'с постусловием', а 'Пока' - 'с предусловием'.        |
|     Обратите также внимание на то, что новая итерация (повторное          |
|выполнение тела цикла) происходит не тогда, когда условие справедливо, а   |
|как раз тогда, когда оно ложно. Поэтому цикл и получил свое название       |
|(выполнять тело цикла до выполнения соответствующего условия).             |
|     Интересно, что в случае, когда условие цикла изначально истинно, тело |
|цикла все равно будет выполнено хотя бы один раз. Именно это отличие 'до'  |
|от 'пока' привело к тому, что в программировании они не подменяют друг     |
|друга, а используются для решения задач, к которым они более подходят.     |
|     Формат цикла на языке Pascal:                                         |
|Repeat                                                                     |
|<оператор #1>;                                                             |
|<оператор #2>;                                                             |
|<оператор #3>;                                                             |
|. . .                                                                      |
|Until <условие>;                                                           |
|     Читается так: 'Выполнять оператор #1, оператор #2. : до выполнения    |
|условия'.                                                                  |
|     Здесь не требуется использование составного оператора, потому, что    |
|сами слова Repeat и Until являются операторными скобками.                  |
|                                                                           |
|Цикл 'С параметром'.                                                       |
|     В данном случае параметром будет являться целочисленная переменная,   |
|которая будет изменяться на единицу при каждой итерации цикла. Таким       |
|образом, задав начальное и конечное значения для такой переменной, можно   |
|точно установить количество выполнений тела цикла. Нарисовать блок-схему   |
|такой структуры вы сможете сами после некоторых пояснений.                 |
|     Форматов у этого вида цикла предусмотрено два:                        |
|    For <И.П.>:=<Н.З.> To <К.З.> Do <оператор>;                            |
|    For <И.П.>:=<Н.З.> Downto <К.З.> Do <оператор>;                        |
|     Здесь И.П. - имя переменной-параметра, Н.З. - его начальное значение, |
|К.З. - соответственно конечное значение параметра. В качестве начального и |
|конечного значений                                                         |
|     Читается данная структура так: 'Для переменной (далее следует ее имя) |
|от начального значения до конечного выполнять оператор (являющийся телом   |
|цикла)'. Иногда цикл с параметром даже называют 'Для' или 'For'. В первом  |
|случае параметр с каждой итерацией увеличивается на единицу, во втором -   |
|уменьшается.                                                               |
|     Выполняется этот цикл по следующему алгоритму:                        |
|    1. переменной-параметру присваивается начальное значение;              |
|    2. выполняется тело цикла;                                             |
|    3. переменная-параметр автоматически увеличивается на 1 (в первом      |
|случае формата);                                                           |
|    4. если параметр превышает конечное значение, то происходит выход из   |
|цикла, иначе - переход к пункту 2.                                         |
|     Примечание: при использовании Downto параметр автоматически           |
|уменьшается на 1, а выход из цикла происходит тогда, когда параметр        |
|становится меньше конечного значения.                                      |
|     Таким образом, в отличие от первых двух видов цикла, этот цикл        |
|используется тогда, когда известно необходимое количество выполнений тела  |
|цикла.                                                                     |
|     Вообще говоря, цикл 'Пока' является универсальным, то есть любая      |
|задача, требующая использования цикла, может быть решена с применением этой|
|структуры. Циклы 'До' и 'С параметром' созданы для удобства                |
|программирования.                                                          |
|     Пример.                                                               |
|     Найти сумму квадратов всех натуральных чисел от 1 до 100.             |
|     Решим эту задачу с использованием всех трех видов циклов.             |
|I. С использованием цикла 'Пока'.                                          |
|Program Ex1;                                                               |
|Var                                                                        |
|   A : Integer;                                                            |
|   S : Longint;                                                            |
|Begin                                                                      |
|A:=1; S:=0;                                                                |
|While A<=100 Do                                                            |
|Begin                                                                      |
|S:=S+A*A;                                                                  |
|A:=A+1                                                                     |
|End;                                                                       |
|Writeln(S)                                                                 |
|End.                                                                       |
|II. С использованием цикла 'До'.                                           |
|Program Ex2;                                                               |
|Var                                                                        |
|    A : Integer;                                                           |
|    S : Longint;                                                           |
|Begin                                                                      |
|A:=1; S:=0;                                                                |
|Repeat                                                                     |
|S:=S+A*A;                                                                  |
|A:=A+1                                                                     |
|Until A>100;                                                               |
|Writeln(S)                                                                 |
|End.                                                                       |
|III. С использованием цикла 'С параметром'.                                |
|Program Ex3;                                                               |
|Var                                                                        |
|    A : Integer;                                                           |
|    S : Longint;                                                           |
|Begin                                                                      |
|S:=0;                                                                      |
|For A:=1 To 100 Do S:=S+A*A;                                               |
|Writeln(S)                                                                 |
|End.                                                                       |
|     Теперь вам известны все основные алгоритмические структуры языка      |
|Паскаль. Комбинируя их, возможно запрограммировать решение любой задачи,   |
|конечно, если таковое существует. Тем не менее, изучение языка на этом не  |
|закачивается, так как для написания хороших программ по утверждению        |
|уважаемого Никлауса Вирта (за время моей работы у меня не появилось        |
|оснований в этом сомневаться) нужны кроме алгоритмических, еще удобные     |
|структуры данных. В рассматриваемом языке таких структур множество, для    |
|каждого вида определены свои команды и операции. К их рассмотрению мы и    |
|переходим.                                                                 |
|                                                                           |
|Строковые операции                                                         |
|     До сих пор мы с вами рассматривали программы, реализующие алгоритмы   |
|обработки числовых данных. Однако хоть ЭВМ изначально и были созданы только|
|для этой цели, по мере развития аппаратной части появилась возможность     |
|оцифровывать данные других типов, хранить их в памяти машины,              |
|перерабатывать, выводить во внешний по отношению к компьютеру мир. Проще   |
|всего можно было так поступить с текстовой информацией. Если не ставить    |
|перед машиной задачу 'понимания' смысла текста, то задача оцифровки        |
|сводится к установлению правил замены символов (литер) при вводе в         |
|компьютер на их коды и обратной замены при выводе информации на экран или  |
|принтер. Такие правила, конечно же, были составлены. Как водится, сначала  |
|их было множество (вспомните разнообразие таблиц кодировки), затем весь мир|
|остановился на ASCII.                                                      |
|     Все языки программирования высокого уровня имеют средства работы с    |
|литерными величинами. Паскаль - не исключение. Как вам уже известно, в     |
|стандарте языка описаны два типа переменных для литерных величин. Это -    |
|String и Char. Напомню - переменная типа Char может содержать в себе только|
|один единственный символ, тип String предназначен для хранения строковых   |
|величин до 255 символов длиною. Кстати, вы знаете не все о типе String. При|
|описании переменной этого типа вы можете сами указать максимальное число   |
|символов, которое можно занести в нее. Конечно же, это число не должно     |
|превышать 255. Делается это так:                                           |
|Var                                                                        |
|S : String[30];                                                            |
|     Для чего это нужно?                                                   |
|     Дело в том, что при компиляции для каждой переменной отводится свой   |
|участок памяти. Если мы будем выделять для всех переменных типа String по  |
|256 байт, то это приведет к тому, что при использовании достаточно большого|
|их количества, памяти может и не хватить? Но если в переменной мы          |
|собираемся хранить, например, фамилию пользователя, то тридцати символов   |
|(тридцати байт) для этого вполне достаточно. Таким образом, экономится     |
|память и увеличивается быстродействие программ.                            |
|     Переменным строкового типа можно присваивать строковые величины       |
|(внутри программы они заключаются в апострофы), значения выражений, которые|
|приводят к строковым величинам. Значения можно также вводить с клавиатуры. |
|При этом апострофы не используются. Как вам известно, в числовую переменную|
|нельзя ввести строковую величину. Сделать наоборот - возможно, однако      |
|число, находящееся в строковой переменной представляет собой просто        |
|последовательность символов (цифр), поэтому в арифметических выражениях    |
|участвовать не может.                                                      |
|     Также, новым для вас явится то, что при использовании строковой       |
|переменной, к каждому ее символу можно обратиться отдельно. Необходимо     |
|только знать номер нужного символа от начала строки. Его достаточно        |
|поставить после имени переменной типа String в квадратных скобках.         |
|     Пример: S[5] - пятый символ строки S.                                 |
|     С отдельным символом строки можно производить все действия, которые   |
|можно производить с любой символьной переменной (ввод, присвоение, вывод на|
|экран, участие в выражениях и т.д.).                                       |
|     Обратите внимание на то, что нумерация символов в строке начинается с |
|единицы. Внутри квадратных скобок вместо числа может находиться выражение, |
|результатом которого является целое число. Главное чтобы символ с таким    |
|номером в строке существовал. Но как же узнать, сколько символов в данный  |
|момент находится в строковой переменной? Для этого существует специальная  |
|функция, которая возвращает длину строковой переменной в символах. Это     |
|функция Length. Ее формат: Length(S)                                       |
|     Здесь S - либо строковая величина, либо строковая переменная.         |
|     Приведенная далее программа выводит на экран длину введенной          |
|пользователем строковой величины.                                          |
|Program Str1;                                                              |
|Var                                                                        |
|S : String;                                                                |
|Begin                                                                      |
|Writeln('Введите последовательность символов');                            |
|Readln(S);                                                                 |
|Writeln('Вы ввели строку из ',Length(S), ' символов')                      |
|End.                                                                       |
|     Другой пример:                                                        |
|Решим задачу: 'Введенную строку вывести на экран по одному символу в строке|
|экрана'.                                                                   |
|Program Str2;                                                              |
|Var                                                                        |
|S : String;                                                                |
|I : Byte;                                                                  |
|Begin                                                                      |
|Writeln('Введите строку');                                                 |
|Readln(S);                                                                 |
|For I:=1 to Length(S) do {организуем цикл, начиная с первого символа}      |
|Writeln(S[I])                   {строки, до последнего (номер последнего}  |
|{совпадает с количеством символов строки S) }                              |
|End.                                                                       |
|     Какие же еще действия можно выполнять с переменными строкового типа?  |
|     Две строковые величины можно состыковывать. Эта операция называется   |
|конкатенацией и обозначается знаком '+'.                                   |
|     Например, результатом выполнения следующих команд:                    |
|   R:= 'kadabra';                                                          |
|   H:= 'abra';                                                             |
|   S:=H+R;                                                                 |
|в переменной S будет значение 'abrakadabra'.                               |
|     Для конкатенации результат зависит от порядка операндов (в отличие от |
|операции сложения). Следует помнить о том, какой максимальной длины может  |
|быть результирующая переменная, так как в случае превышения значением      |
|выражения числа, указанного после String в описании переменной, 'лишние'   |
|символы в переменную не попадут.                                           |
|     Строковые величины можно сравнивать между собой. Это относится также и|
|к строковым переменным. Но как же компьютер определяет, какая строка       |
|больше:                                                                    |
|та, которая длиннее?                                                       |
|та, которая содержит больше заглавных букв?                                |
|     На самом деле такая проверка проходит довольно сложно: компьютер      |
|сравнивает сначала первые символы строк. Большим из двух считается тот, код|
|которого больше (вспомните, что такое код символа). Если равны первые      |
|символы, то так же анализируется следующая пара до тех пор, пока не будет  |
|найдено различие. Если начало строк совпадает, а одна из них кончается     |
|раньше, то вторая автоматически называется большей.                        |
|     Код символа в Паскале можно определить при помощи функции Ord.        |
|     Ее формат: Ord(C), где С - либо непосредственно указанный символ, либо|
|переменная символьного типа, либо один символ строковой переменной. Вообще,|
|функция Ord имеет более глубокий смысл, но об этом - позже. Есть и обратная|
|функция, которая возвращает символ по известному коду. Это функция Chr(N), |
|где N - выражение, приводящее к целому числу в интервале от 0 до 255       |
|(возможные значения кода символа). Очевидно, что Chr(Ord(C))=C,            |
|Ord(Chr(N))=N.                                                             |
|     Следующая маленькая программа выводит на экран кодовую таблицу:       |
|Program Str3;                                                              |
|Var                                                                        |
|    I : Byte;                                                              |
|Begin                                                                      |
|For I:=32 to 255 do                                                        |
|Write('VV',I:4, '-',Chr(I))                                                |
|End.                                                                       |
|     Цикл в программе начинается с 32 потому, что символы с кодами от 0 до |
|31 являются управляющими и не имеют соответствующего графического          |
|представления.                                                             |
|     Задача: 'Определить, является ли введенная строка 'перевертышем'.     |
|Перевертышем называется такая строка, которая одинаково читается с начала и|
|с конца. Например, 'казак' и 'потоп' - перевертыши, 'канат' - не           |
|перевертыш'.                                                               |
|     Поступим следующим образом: из введенной строки сформируем другую     |
|строку из символов первой, записанных в обратном порядке, затем сравним    |
|первую строку со второй; если они окажутся равны, то ответ положительный,  |
|иначе - отрицательный. Естественно, предложенный способ решения не является|
|единственно возможным.                                                     |
|Program Str4;                                                              |
|Var                                                                        |
|     S,B : String;                                                         |
|     I : Byte;                                                             |
|Begin                                                                      |
|Writeln('Введите строку');                                                 |
|Readln(S);                                                                 |
|B:='';              {Переменной B присваиваем значение 'пустая строка'}    |
|For I:=1 to Length(S) do                                                   |
|B:=S[I]+B;     {Конкатенация. Символы строки S пристыковываются к}         |
|{переменной B слева. Самым левым окажется последний.}                      |
|If B=S Then Writeln('Перевертыш') Else Writeln('Не перевертыш')            |
|End.                                                                       |
|     Число, записанное в строковую переменную, естественно числом не       |
|является, но очень часто требуется его все же использовать в качестве      |
|числа. Для этого нужно произвести преобразование типа. Перевод строкового  |
|представления числа в числовое выполняет в Паскале оператор Val.           |
|Его формат:                                                                |
|Val(S,X,C);                                                                |
|     Здесь S - строка, содержащая число, X - числовая переменная, в которую|
|будет помещен результат, С - переменная целочисленного типа, в которую     |
|помещается первого встреченного в S отличного от цифры символа. Если после |
|выполнения оператора Val переменная С имеет значение 0, то это означает,   |
|что преобразование типа прошло совершенно успешно и в строке нецифровых    |
|символов не встретилось.                                                   |
|     Противоположное действие осуществляет оператор Str. Формат оператора: |
|   Str(X,S);                                                               |
|X - число (либо арифметическое выражение), S - строковая переменная.       |
|     В переменную S попадает строковое представление числа X. Это нужно,   |
|например, при необходимости выводить на экран числа в графическом режиме   |
|(будет изучено позже), так как стандартные процедуры вывода на экран там   |
|работают только со строковыми величинами.                                  |
|     Для иллюстрации рассмотрим такую задачу: 'Найти сумму цифр введенного |
|натурального числа'. Используя только числовые переменные, решить ее можно,|
|но предлагаемое здесь решение, по-моему, проще.                            |
|Program Str5;                                                              |
|Var                                                                        |
|S : String;                                                                |
|I,X,A,C : Integer;                                                         |
|Begin                                                                      |
|Writeln('Введите натуральное число');                                      |
|Readln(S); {Число вводится в строковую переменную}                         |
|A:=0;                                                                      |
|For I:=1 To Length(S) Do                                                   |
|Begin                                                                      |
|Val(S[I],X,C); {Цифровой символ превращается в число}                      |
|A:=A+X {Цифры суммируются}                                                 |
|End;                                                                       |
|Writeln('Сумма цифр равна ',A)                                             |
|End.                                                                       |
|     Теперь рассмотрим еще несколько действий над строками:                |
|оператор DELETE(S,I,C) из строковой переменной S удаляет C символов,       |
|начиная с I-того;                                                          |
|оператор INSERT(SN,S,I) вставляет подстроку SN в строковую переменную S    |
|перед символом с номером I;                                                |
|функция COPY(S,I,C) возвращает подстроку строки S из C символов, начиная с |
|символа с номером I;                                                       |
|функция Pos(SN,S) возвращает номер символа, с которого в строке S          |
|начинается подстрока SN (позицию первого вхождения подстроки в строку).    |
|Если такой подстроки нет, то возвращается ноль.                            |
|     Пример их использования:                                              |
|'Во введенной строке заменить все вхождения подстроки 'ABC' на подстроки   |
|'KLMNO''.                                                                  |
|Program Str6;                                                              |
|Var                                                                        |
|S : String;                                                                |
|A : Byte;                                                                  |
|Begin                                                                      |
|Writeln('Введите строку');                                                 |
|Readln(S);                                                                 |
|While Pos('ABC',S)<>0 Do                                                   |
|Begin                                                                      |
|A:= Pos('ABC',S);                                                          |
|Delete(S,A,3);                                                             |
|Insert('KLMNO',S,A)                                                        |
|End;                                                                       |
|Writeln(S)                                                                 |
|End.                                                                       |
|                                                                           |
|Определение типов                                                          |
|     Как было упомянуто ранее, в изучаемом языке возможно определять новые |
|типы переменных. После определения этот тип становится доступным для       |
|описания переменных, также как и стандартные типы.                         |
|     Новый тип перед первым его использованием должен быть описан в        |
|соответствующем разделе описаний. Его заголовок - служебное слово Type.    |
|Type                                                                       |
|    <Имя типа> = <Описание типа>;                                          |
|     Есть несколько способов описания. Иногда говорят даже о видах типов   |
|(как бы это странно ни звучало).                                           |
|     Итак, первым рассмотрим так называемый перечисляемый тип.             |
|     Перечисляемый тип используется для повышения наглядности программ,    |
|позволяя записывать в переменные этого типа названия разнообразных         |
|объектов, исследуемых программой. Этот тип представляет собой набор        |
|идентификаторов, с которыми могут совпадать значения параметров.           |
|     Формат описания следующий: <Имя типа> = (<Ид.1>, <Ид.2>,? <Ид.n>);    |
|     Далее можно определить любое число переменных уже описанного типа.    |
|Обратите внимание на то, что каждый идентификатор может участвовать в      |
|описании только одного перечисляемого типа.                                |
|     Этим переменным можно присваивать только значения из списка,          |
|определенного при описании типа. Эти значения не являются ни числами, ни   |
|строковыми величинами, ни даже величинами логического типа, поэтому они не |
|могут участвовать в арифметических, строковых, логических выражениях, а    |
|также не могут быть выведены на экран или принтер. Величины перечисляемого |
|типа можно сравнивать между собой, над их множеством в языке Паскаль       |
|определены несколько функций:                                              |
|    Ord(X) - порядковый номер значения переменной X в списке               |
|идентификаторов.                                                           |
|    Succ(X) - следующее значение для величины Х.                           |
|    Pred(X) - предыдущее значение данного типа.                            |
|     Обратите внимание на то, что для функции Ord нумерация среди значений |
|идет, начиная от нуля. Для последнего значения нельзя применять функцию    |
|Succ, для первого - Pred.                                                  |
|     Переменные различных перечисляемых типов несовместимы друг с другом.  |
|     Множество стандартных порядковых типов в языке Паскаль на самом деле  |
|определены как перечисляемые. Это типы Char, Integer, другие. Достоинства  |
|стандартных порядковых типов лишь в том, что над каждым из них уже         |
|определены специфические действия. Например, тип Boolean описан так:       |
|Type                                                                       |
|Boolean = (False, True);                                                   |
|     Единственное его отличие от перечисляемых типов, определяемых         |
|программистом, состоит в том, что значения типа Boolean можно выводить на  |
|экран. Можете проверить, Ord(False)=0.                                     |
|     Интересно, что переменная перечисляемого типа может быть счетчиком в  |
|цикле 'с параметром'.                                                      |
|Пример:                                                                    |
|Program T1;                                                                |
|Type                                                                       |
|    Colors = (Black, Blue, Green, Cyan, Red, Magenta, Brown, Yellow,       |
|White);                                                                    |
|Var                                                                        |
|    C1,C2 : Colors;                                                        |
|Begin                                                                      |
|C1:=Green;                                                                 |
|C2:=Red;                                                                   |
|Writeln(Ord(C1), Ord(Succ(C2)))                                            |
|End.                                                                       |
|     Во время выполнения на экране появятся числа '2' и '5', что           |
|соответствует номерам значений Green и Magenta.                            |
|     Следующий тип, который можно определить в программе - тип-диапазон.   |
|     Здесь не нужно перечислять все значения этого типа, потому, что       |
|возможными для него являются значения поддиапазона уже определенного до    |
|него любого порядкового типа (стандартного или описанного ранее            |
|перечисляемого типа). Достаточно лишь указать начальную и конечную величину|
|отрезка порядкового типа. Единственное условие: начальное значение не      |
|должно превышать конечное.                                                 |
|     Формат описания отрезочного типа:                                     |
|Type                                                                       |
|    <Имя типа>=<Нач.>..<Кон.>;                                             |
|Примеры:                                                                   |
|Type                                                                       |
|Age=0..150; {Целое число в интервале от 0 до 150}                          |
|Lat='A'.. 'Z'; {Заглавные буквы латинского алфавита}                       |
|Month=(January, February, March, April, May, June, July, August, September,|
|October, November, December);                                              |
|Spring=March..May; {Весенние месяцы}                                       |
|     Есть еще одна возможность определить новый тип, о существовании       |
|которой можно было бы и догадаться.                                        |
|Type                                                                       |
|    <Имя типа>=<Имя ранее определенного или стандартного типа>;            |
|Пример:                                                                    |
|Type                                                                       |
|    Number=Byte;                                                           |
|                                                                           |
|Массивы                                                                    |
|     До сих пор мы рассматривали переменные, которые имели только одно     |
|значение, могли содержать в себе только одну величину определенного типа.  |
|Исключением являлись лишь строковые переменные, которые представляют собой |
|совокупность данных символьного типа, но и при этом мы говорили о строке,  |
|как об отдельной величине.                                                 |
|     Вы знаете, что компьютер предназначен в основном для облегчения работы|
|человека с большими информационными объемами. Как же, используя только     |
|переменные известных вам типов, сохранить в памяти и обработать данные,    |
|содержащие десяток, сотню, тысячу чисел или, к примеру, строк? А ведь такие|
|задачи встречаются в любой области знания. Конечно, можно завести столько  |
|переменных, сколько данных, можно даже занести в них значения, но только   |
|представьте, какой величины будет текст такой программы, сколько времени   |
|потребуется для его составления, как много места для возможных ошибок?     |
|Естественно, об этом задумывались и авторы языков программирования. Поэтому|
|во всех существующих языках имеются типы переменных, отвечающие за хранение|
|больших массивов данных. В языке Паскаль они так и называются: 'массивы'.  |
|     Массивом будем называть упорядоченную последовательность данных одного|
|типа, объединенных под одним именем. Кстати, под это определение подходит  |
|множество объектов из реального мира: словарь (последовательность слов),   |
|мультфильм (последовательность картинок) и т. д. Проще всего представить   |
|себе массив в виде таблицы, где каждая величина находится в собственной    |
|ячейке. Положение ячейки в таблице должно однозначно определяться набором  |
|координат (индексов). Самой простой является линейная таблица, в которой   |
|для точного указания на элемент данных достаточно знания только одного     |
|числа (индекса). Мы с вами пока будем заниматься только линейными          |
|массивами, так как более сложные структуры строятся на их основе.          |
|     Описание типа линейного массива выглядит так:                         |
|    Type     <Имя типа>=Array [<Диапазон индексов>] Of <Тип элементов>;    |
|     В качестве индексов могут выступать переменные любых порядковых типов.|
|При указании диапазона начальный индекс не должен превышать конечный. Тип  |
|элементов массива может быть любым (стандартным или описанным ранее).      |
|     Описать переменную-массив можно и сразу (без предварительного описания|
|типа) в разделе описания переменных:                                       |
|    Var     <Переменная-массив> : Array [<Диапазон индексов>] Of <Тип      |
|элементов>;                                                                |
|     Примеры описания массивов:                                            |
|Var                                                                        |
|S, BB : Array [1..40] Of Real;                                             |
|N : Array ['A'..'Z'] Of Integer;                                           |
|R : Array [-20..20] Of Word;                                               |
|T : Array [1..40] Of Real;                                                 |
|     Теперь переменные S, BB и T представляют собой массивы из сорока      |
|вещественных чисел; массив N имеет индексы символьного типа и целочисленные|
|элементы; массив R может хранить в себе 41 число типа Word.                |
|     Единственным действием, которое возможно произвести с массивом целиком|
|- присваивание. Для данного примера описания впоследствии допустима        |
|следующая запись:                                                          |
|    S:=BB;                                                                 |
|     Однако, присваивать можно только массивы одинаковых типов. Даже       |
|массиву T присвоить массив S нельзя, хотя, казалось бы, их описания        |
|совпадают, произведены они в различных записях раздела описания.           |
|     Никаких других операций с массивами целиком произвести невозможно, но |
|с элементами массивов можно работать точно также, как с простыми           |
|переменными соответствующего типа. Обращение к отдельному элементу массива |
|производится при помощи указания имени всего массива и в квадратных скобках|
|- индекса конкретного элемента. Например:                                  |
|R[10] - элемент массива R с индексом 10.                                   |
|     Фундаментальное отличие компонента массива от простой переменной      |
|состоит в том, что для элемента массива в квадратных скобках может стоять  |
|не только непосредственное значение индекса, но и выражение, приводящее к  |
|значению индексного типа. Таким образом реализуется косвенная адресация:   |
|BB[15] - прямая адресация;                                                 |
|BB[K] - косвенная адресация через переменную K, значение которой будет     |
|использовано в качестве индекса элемента массива BB.                       |
|     Такая организация работы с такой структурой данных, как массив,       |
|позволяет использовать цикл для заполнения, обработки и распечатки его     |
|содержимого.                                                               |
|     Если вы помните, с такой формой организации данных мы встречались,    |
|когда изучали строковые переменные. Действительно, переменные типа String  |
|очень близки по своим свойствам массивам типа Char. Отличия в следующем:   |
|строковые переменные можно было вводить с клавиатуры и распечатывать на    |
|экране (с обычным массивом это не проходит); длина строковой переменной    |
|была ограничена 255 символами (255 B), а для размера массива критическим   |
|объемом информации является 64 KB.                                         |
|     Теперь рассмотрим несколько способов заполнения массивов и вывода их  |
|содержимого на экран. В основном мы будем пользоваться числовыми типами    |
|компонент, но приведенные примеры будут справедливы и для других типов     |
|(если они допускают указанные действия).                                   |
|Program M1;                                                                |
|Var                                                                        |
|     A : Array [1..20] Of Integer;                                         |
|Begin                                                                      |
|A[1]:=7; {Заполняем массив значениями (отдельно каждый компонент)}         |
|A[2]:=32;                                                                  |
|A[3]:=-70;                                                                 |
|.............. {Трудоемкая задача?}                                        |
|A[20]:=56;                                                                 |
|Writeln(A[1],A[2],A[3], ?,A[20])                                           |
|End.                                                                       |
|     Как бы ни был примитивен приведенный пример, он все же иллюстрирует   |
|возможность непосредственного обращения к каждому элементу массива         |
|отдельно. Правда, никакого преимущества массива перед несколькими простыми |
|переменными здесь не видно. Поэтому - другой способ:                       |
|Program M2;                                                                |
|Var                                                                        |
|A : Array [1..20] Of Integer;                                              |
|I : Integer;                                                               |
|Begin                                                                      |
|For I:=1 To 20 Do {Организуем цикл с параметром I по всем возможным}       |
|Readln(A[I]); {значениям индексов и вводим A[I] с клавиатуры }             |
|For I:=20 Downto 1 Do {Распечатываем массив в обратном порядке}            |
|Write(A[I],'VVV')                                                          |
|End.                                                                       |
|     Эта программа вводит с клавиатуры 20 целых чисел, а затем             |
|распечатывает их в обратном порядке. Теперь попробуйте написать такую же   |
|программу, но без использования структуры массива. Во сколько раз она      |
|станет длиннее? Кстати, введение язык Паскаль цикла с параметром было      |
|обусловлено во многом необходимостью обработки информационных              |
|последовательностей, т. е. массивов.                                       |
|     Следующая программа заполняет массив значениям квадратов индексов     |
|элементов:                                                                 |
|Program M3;                                                                |
|Const                                                                      |
|N=50; {Константа N будет содержать количество элементов массива}           |
|Var                                                                        |
|A : Array [1..N] Of Integer;                                               |
|I : Integer;                                                               |
|Begin                                                                      |
|For I:=1 To N Do                                                           |
|A[I]:=I*I                                                                  |
|For I:=1 To N Do                                                           |
|Write(A[I],'VVV')                                                          |
|End.                                                                       |
|     В дальнейшем для учебных целей мы будем использовать массивы, заданные|
|с помощью генератора случайных чисел. В языке Паскаль случайные числа      |
|формирует функция Random. Числа получаются дробными, равномерно            |
|расположенными в интервале от 0 до 1. Выражение, дающее целое случайное    |
|число в интервале [-50,50] будет выглядеть так:                            |
|Trunc(Random*101)-50                                                       |
|Зададим и распечатаем случайный массив из сорока целых чисел:              |
|Program M4;                                                                |
|Const                                                                      |
|N=40; {Константа N будет содержать количество элементов массива}           |
|Var                                                                        |
|A : Array [1..N] Of Integer;                                               |
|I : Integer;                                                               |
|Begin                                                                      |
|For I:=1 To N Do                                                           |
|Begin                                                                      |
|A[I]:= Trunc(Random*101)-50                                                |
|Write(A[I],'VVV')                                                          |
|End                                                                        |
|End.                                                                       |
|     С обработкой линейных массивов связано множество задач. Их мы         |
|рассмотрим на практических занятиях.                                       |
|                                                                           |
|Двумерные и многомерные массивы                                            |
|Представьте себе таблицу, состоящую из нескольких строк. Каждая строка     |
|состоит из нескольких ячеек. Тогда для точного определения положения ячейки|
|нам потребуется знать не одно число (как в случае таблицы линейной), а два:|
|номер строки и номер столбца. Структура данных в языке Паскаль для хранения|
|такой таблицы называется двумерным массивом. Описать такой массив можно    |
|двумя способами:                                                           |
|I.                                                                         |
|Var                                                                        |
|    A : Array [1..20] Of Array [1..30] Of Integer;                         |
|II.                                                                        |
|Var                                                                        |
|    A : Array [1..20,1..30] Of Integer;                                    |
|В обоих случаях описан двумерный массив, соответствующий таблице, состоящей|
|из 20 строк и 30 столбцов. Приведенные описания совершенно равноправны.    |
|Отдельный элемент двумерного массива адресуется, естественно, двумя        |
|индексами. Например, ячейка, находящаяся в 5-й строке и 6-м столбце будет  |
|называться A[5][6] или A[5,6].                                             |
|Для иллюстрации способов работы с двумерными массивами решим задачу:       |
|'Задать и распечатать массив 10X10, состоящий из целых случайных чисел в   |
|интервале [1,100]. Найти сумму элементов, лежащих выше главной диагонали.' |
|При отсчете, начиная с левого верхнего угла таблицы, главной будем считать |
|диагональ из левого верхнего угла таблицы в правый нижний. При этом        |
|получается, что элементы, лежащие на главной диагонали будут иметь         |
|одинаковые индексы, а для элементов выше главной диагонали номер столбца   |
|будет всегда превышать номер строки. Договоримся также сначала указывать   |
|номер строки, а затем - номер столбца.                                     |
|Program M5;                                                                |
|Var                                                                        |
|A : Array[1..10,1..10] Of Integer;                                         |
|I, K : Byte;                                                               |
|S : Integer;                                                               |
|Begin                                                                      |
|S:=0;                                                                      |
|For I:=1 To 10 Do                                                          |
|Begin                                                                      |
|For K:=1 To 10 Do                                                          |
|Begin                                                                      |
|A[I,K]:=Trunc(Random*100)+1;                                               |
|Write(A[I,K]:6);                                                           |
|If K>I Then S:=S+A[I,K]                                                    |
|End;                                                                       |
|Writeln                                                                    |
|End;                                                                       |
|Writeln('Сумма элементов выше гл. диагонали равнаV',S)                     |
|End.                                                                       |
|Если модель данных в какой-либо задаче не может свестись к линейной или    |
|плоской таблице, то могут использоваться массивы произвольной размерности. |
|N-мерный массив характеризуется N индексами. Формат описания такого типа   |
|данных:                                                                    |
|Type                                                                       |
|<Имя типа>=Array[<диапазон индекса1>,<диапазон индекса2>,...               |
|<диапазон индекса N>] Of <тип компонент>;                                  |
|Отдельный элемент именуется так:                                           |
|          <Имя массива>[<Индекс 1>,<Индекс 2>,...,<Индекс N>]              |
|                                                                           |
|Процедуры и функции                                                        |
|При решении сложных объемных задач часто целесообразно разбивать их на     |
|более простые. Метод последовательной детализации позволяет составить      |
|алгоритм из действий, которые, не являясь простыми, сами представляют собой|
|достаточно самостоятельные алгоритмы. В этом случае говорят о              |
|вспомогательных алгоритмах или подпрограммах. Использование подпрограмм    |
|позволяет сделать основную программу более наглядной, понятной, а в случае,|
|когда одна и та же последовательность команд встречается в программе       |
|несколько раз, даже более короткой и эффективной.                          |
|В языке Паскаль существует два вида подпрограмм: процедуры и функции,      |
|определяемые программистом. Процедурой в Паскале называется именованная    |
|последовательность инструкций, реализующая некоторое действие. Функция     |
|отличается от процедуры тем, что она должна обязательно выработать значение|
|определенного типа.                                                        |
|Процедуры и функции, используемые в программе, должны быть соответствующим |
|образом описаны до первого их упоминания. Вызов процедуры или функции      |
|производится по их имени.                                                  |
|Подпрограммы в языке Паскаль могут иметь параметры (значения, передаваемые |
|в процедуру или функцию в качестве аргументов). При описании указываются   |
|так называемые формальные параметры (имена, под которыми будут фигурировать|
|передаваемые данные внутри подпрограммы) и их типы. При вызове подпрограммы|
|вместе с ее именем должны быть заданы все необходимые параметры в том      |
|порядке, в котором они находятся в описании. Значения, указываемые при     |
|вызове подпрограммы, называются фактическими параметрами.                  |
|Формат описания процедуры:                                                 |
|Procedure <Имя процедуры> (<Имя форм. параметра 1>:<Тип>;                  |
|< Имя форм. параметра 2>:<Тип>?);                                          |
|<Раздел описаний>                                                          |
|Begin                                                                      |
|<Тело процедуры>                                                           |
|End;                                                                       |
|Раздел описаний может иметь такие же подразделы, как и раздел описаний     |
|основной программы (описание процедур и функций - в том числе). Однако все |
|описанные здесь объекты 'видимы' лишь в этой процедуре. Они здесь локальны |
|также, как и имена формальных параметров. Объекты, описанные ранее в       |
|разделе описаний основной программы и не переопределенные в процедуре,     |
|называются глобальными для этой подпрограммы и доступны для использования. |
|Легко заметить схожесть структуры программы целиком и любой из ее процедур.|
|Действительно, ведь и процедура и основная программа реализуют некий       |
|алгоритм, просто процедура не дает решения всей задачи. Отличие в заголовке|
|и в знаке после End.                                                       |
|Формат описания функции:                                                   |
|Function <Имя функции> (<Имя форм. параметра 1>:<Тип>;                     |
|< Имя форм. параметра 2>:<Тип>?) : <Тип результата>;                       |
|<Раздел описаний>                                                          |
|Begin                                                                      |
|<Тело функции>                                                             |
|End;                                                                       |
|В теле функции обязательно должна быть хотя бы команда присвоения такого   |
|вида: <Имя функции>:=<Выражение>;                                          |
|Указанное выражение должно приводить к значению того же типа, что и тип    |
|результата функции, описанный выше.                                        |
|Вызов процедуры представляет в программе самостоятельную инструкцию:       |
|<Имя процедуры>(<Фактический параметр 1>, < Фактический параметр 2>?);     |
|Типы фактических параметров должны быть такими же, что и у соответсвующих  |
|им формальных.                                                             |
|Вызов функции должен входить в выражение. При вычислении значения такого   |
|выражения функция будет вызвана, действия, находящиеся в ее теле, будут    |
|выполнены, в выражение будет подставлено значение результата функции.      |
|Приведем простейший пример использования подпрограммы.                     |
|Задача: 'Найти максимальное из трех введенных чисел'. Для решения          |
|воспользуемся описанием функции, принимающей значение максимального из двух|
|чисел, которые передаются в нее в виде параметров.                         |
|Program Fn;                                                                |
|Var                                                                        |
|A,B,C :Real;                                                               |
|Function Max(A,B:Real):Real; {Описываем функцию Max с формальными}         |
|Begin {параметрами A и B, которая принимает }                              |
|If A>B Then Max:=A {значение максимального из них }                        |
|Else Max:=B {Здесь A и B - локальные переменные }                          |
|End;                                                                       |
|Begin                                                                      |
|Writeln('Введите три числа');                                              |
|Readln(A,B,C);                                                             |
|Writeln('Максимальным из всех является ', Max(Max(A,B),C))                 |
|End.                                                                       |
|Обратите внимание на краткость тела основной программы и на прозрачность   |
|действий внутри функции. Формальные параметры A и B, используемые в        |
|подпрограмме, не имеют никакого отношения переменным A и B, описанным в    |
|основной программе.                                                        |
|Существует два способа передачи фактических параметров в подпрограмму: по  |
|значению и по ссылке. В первом случае значение переменной-фактического     |
|параметра при вызове подпрограммы присваивается локальной переменной,      |
|являющейся формальным параметром подпрограммы. Что бы потом ни происходило |
|с локальной переменной, это никак не отразится на соответствующей          |
|глобальной. Для одних задач это благо, но иногда требуется произвести в    |
|подпрограмме действия над самими переменными, указанными в качестве        |
|фактических параметров. На помощь приходит второй способ. Происходит       |
|следующее: при обращении к подпрограмме не происходит формирования         |
|локальной переменной-формального параметра. Просто на время выполнения     |
|подпрограммы имя этой локальной переменной будет указывать на ту же область|
|памяти, что и имя соответствующей глобальной переменной. Если в этом случае|
|изменить локальную переменную, изменятся данные и в глобальной.            |
|Передача параметров по ссылке отличается тем, что при описании подпрограммы|
|перед именем переменной-формального параметра ставится служебное слово Var.|
|Теперь использование в качестве фактических параметров выражений или       |
|непосредственных значений уже не допускается - они должны быть именами     |
|переменных.                                                                |
|Еще один классический пример. Задача: 'Расположить в порядке неубывания три|
|целых числа'.                                                              |
|Program Pr;                                                                |
|Var                                                                        |
|     S1,S2,S3 :Integer;                                                    |
|Procedure Swap(Var A,B: Integer);{Процедура Swap с параметрами-переменными}|
|                                                                           |
|Var C : Integer; {C - независимая локальная переменная}                    |
|Begin                                                                      |
|      C:=A; A:=B; B:=C {Меняем местами содержимое A и B}                   |
|End;                                                                       |
|Begin                                                                      |
|Writeln('Введите три числа');                                              |
|Readln(S1,S2,S3);                                                          |
|If S1>S2 Then Swap(S1,S2);                                                 |
|If S2>S3 Then Swap(S2,S3);                                                 |
|If S1>S2 Then Swap(S1,S2);                                                 |
|Writeln('Числа в порядке неубывания:V',S1,S2,S3)                           |
|End.                                                                       |
|                                                                           |
|Работа с файлами                                                           |
|Тип-файл представляет собой последовательность компонент одного типа,      |
|расположенных на внешнем устройстве (например, на диске). Элементы могут   |
|быть любого типа, за исключением самого типа-файла. Число элементов в файле|
|при описании не объявляется. Работа с физическими файлами происходит через |
|так называемые файловые переменные.                                        |
|Для задания типа-файла следует использовать зарезервированные слова File и |
|Of, после чего указать тип компонент файла.                                |
|Пример:                                                                    |
|Type                                                                       |
|N = File Of Integer; {Тип-файл целых чисел}                                |
|C = File Of Char; {Тип-файл символов}                                      |
|Есть заранее определенный в Паскале тип файла с именем Text. Файлы этого   |
|типа называют текстовыми.                                                  |
|Введя файловый тип, можно определить и переменные файлового типа:          |
|Var                                                                        |
|F1 : N;                                                                    |
|F2 : C;                                                                    |
|F3 : Text;                                                                 |
|Тип-файл можно описать и непосредственно при введении файловых переменных: |
|Var                                                                        |
|     Z : File Of Word;                                                     |
|Файловые переменные имеют специфическое применение. Над ними нельзя        |
|выполнять никаких операций (присваивать значение, сравнивать и т.д.). Их   |
|можно использовать лишь для выполнения операций с файлами (чтение, запись и|
|т.д.).                                                                     |
|Элементы файла считаются расположенными последовательно, то есть так же,   |
|как элементы линейного массива. Отличие же состоит в том, что, во-первых,  |
|размеры файла могут меняться, во-вторых, способ обращения к элементам      |
|совсем другой: невозможно обратиться к произвольному элементу файла;       |
|элементы его просматриваются только подряд от начала к концу, при этом в   |
|каждый момент времени доступен только один элемент. Можно представить себе,|
|что для каждого файла существует указатель, показывающий в данный момент на|
|определенный компонент файла. После проведения операции чтения или записи  |
|указатель автоматически передвигается на следующий компонент.              |
|Перед тем, как осуществлять ввод-вывод, файловая переменная должна быть    |
|связана с конкретным внешним файлом при помощи процедуры Assign.           |
|Формат:                                                                    |
|     Assign(<Имя файловой переменной>,<Имя файла>);                        |
|Имя файла задается либо строковой константой, либо через переменную типа   |
|Sting. Имя файла должно соответствовать правилам работающей в данный момент|
|операционной системы. Если строка имени пустая, то связь файловой          |
|переменной осуществляется со стандартным устройством ввода-вывода (как     |
|правило - с консолью).                                                     |
|После этого файл должен быть открыт одной из процедур:                     |
|Reset(<Имя файловой переменной>);                                          |
|Открывается существующий файл для чтения, указатель текущей компоненты     |
|файла настраивается на начало файла. Если физического файла,               |
|соответствующего файловой переменной не существует, то возникает ситуация  |
|ошибки ввода-вывода.                                                       |
|Rewrite(<Имя файловой переменной>);                                        |
|Открывается новый пустой файл для записи, ему присваивается имя, заданное  |
|процедурой Assign. Если файл с таким именем уже существует, то он          |
|уничтожается.                                                              |
|После работы с файлом он, как правило, должен быть закрыт процедурой Close.|
|                                                                           |
|Close(<Имя файловой переменной>);                                          |
|Это требование обязательно должно соблюдаться для файла, в который         |
|производилась запись.                                                      |
|Теперь рассмотрим непосредственную организацию чтения и записи.            |
|Для ввода информации из файла, открытого для чтения, используется уже      |
|знакомый вам оператор Read. Правда, в его формате и использовании вы       |
|заметите некоторые изменения:                                              |
|Read(<Имя файловой переменной>, <Список ввода>);                           |
|Происходит считывание данных из файла в переменные, имена которых указаны в|
|списке ввода. Переменные должны быть того же типа, что и компоненты файла. |
|                                                                           |
|Вывод информации производит, как можно догадаться оператор Write(<Имя      |
|файловой переменной>, <Список вывода>);                                    |
|Данные из списка вывода заносятся в файл, открытый для записи.             |
|Для текстовых файлов используются также операторы Readln и Writeln с       |
|соответствующими дополнениями, относящимися к файловому вводу-выводу.      |
|Любопытно, что вывод данных на монитор и ввод с клавиатуры в языке Паскаль |
|тоже являются действиями с файлами. Они даже имеют свои предопределенные   |
|файловые переменные текстового типа: Output и Input соответственно.        |
|Переменная Output всегда открыта для записи, Input - для чтения. Если не   |
|указывать файловые переменные в операторах ввода-вывода (придем к формату, |
|рассмотренному в теме 'Операторы ввода-вывода'), то в случае записи по     |
|умолчанию выбирается файл Output, в случае чтения - Input.                 |
|Как вы знаете, любой файл конечен и продолжать чтение из него информации   |
|можно лишь до определенного предела. Как этот предел установить? Проверить,|
|окончен ли файл, можно вызовом стандартной логической функции Eof(<Имя     |
|файловой переменной>)                                                      |
|Она вырабатывает значение True, если файл окончен, и False - в противном   |
|случае.                                                                    |
|Решим следующую задачу: 'Написать программу, которая вводит с клавиатуры   |
|список фамилий учащихся, а затем распечатывает его, кроме тех учащихся, у  |
|которых фамилия начинается с буквы 'Ш''.                                   |
|Так как заранее количество данных не известно, то для их хранения          |
|используем файл. Тип элементов - строковый.                                |
|Program L;                                                                 |
|Var                                                                        |
|I,N : Integer;                                                             |
|F : File Of String;                                                        |
|S : String;                                                                |
|Begin                                                                      |
|Assign(F,'Spis.lst'); {Связываем переменную F с файлом Spis.lst}           |
|Writeln('Введите количество учащихся');                                    |
|Readln(N); {Вводим количество учащихся}                                    |
|Rewrite(F); {Создаем файл для записи в него данных}                        |
|For I:=1 To N Do {Для всех учащихся}                                       |
|Begin                                                                      |
|Writeln('Введите фамилию');                                                |
|Readln(S);                                                                 |
|Write(F,S)                                                                 |
|End;                                                                       |
|Close(F);                                                                  |
|Reset(F);                                                                  |
|Writeln; Writeln('Список учащихся:');                                      |
|While Not(Eof(F)) Do                                                       |
|Begin                                                                      |
|Read(F,S);                                                                 |
|If S[1]<>'Ш' Then                                                          |
|Writeln(S)                                                                 |
|End;                                                                       |
|Close(F)                                                                   |
|End.                                                                       |


ref.by 2006—2022
contextus@mail.ru