1. История языка Паскаль

advertisement
ИСТОРИЯ ЯЗЫКА ПАСКАЛЬ. СПОСОБЫ ОПИСАНИЯ ЯЗЫКА ПРОГРАММИРОВАНИЯ.
ВВЕДЕНИЕ В ЯЗЫК ПРОГРАММИРОВАНИЯ ПАСКАЛЬ ................................................................................ 1
ИСТОРИЯ ЯЗЫКА ПАСКАЛЬ ............................................................................................................. 1
1.
2. ПОНЯТИЯ СИНТАКСИСА, СЕМАНТИКИ И ПРАГМАТИКИ ЯЗЫКА
ПРОГРАММИРОВАНИЯ ............................................................................................................................................. 3
АЛФАВИТ ЯЗЫКА ПАСКАЛЬ И ОСНОВНЫЕ ЛЕКСЕМЫ ........................................................ 5
3.
АЛФАВИТ ЯЗЫКА ПАСКАЛЬ ............................................................................................................................ 5
ПРАВИЛА ПОСТРОЕНИЯ ОСНОВНЫХ ВИДОВ ЛЕКСЕМ...................................................................................... 6
Имена ........................................................................................................................................................ 6
Константы .............................................................................................................................................. 7
Комментарии ........................................................................................................................................... 8
СТРУКТУРА ПРОГРАММЫ И ЕЕ СИНТАКСИС ......................................................................... 10
4.
СИНТАКСИЧЕСКИЕ ДИАГРАММЫ ВИРТА И СТРУКТУРА ПРОГРАММЫ........................................................... 10
РАЗДЕЛ ОПИСАНИЙ ....................................................................................................................................... 12
Раздел описания меток ......................................................................................................................... 13
Раздел описания констант ................................................................................................................... 14
Раздел описания переменных ................................................................................................................ 15
5.
ЛИТЕРАТУРА .......................................................................................................................................... 16
История языка Паскаль. Способы описания языка
программирования. Введение в язык программирования
Паскаль
1. История языка Паскаль
Паскаль – язык программирования, созданный в 70-х годах швейцарским
профессором
Николаусом
Виртом
специально
для
обучения
программированию. Им же был написан ряд книг [1], [2], [3], в которых
подробно рассматриваются возможности этого языка и его применение для
решения многих «классических» в области программирования задач. Название
языку было дано в честь выдающегося французского математика Блеза
Паскаля.
Язык Паскаль характеризуется чёткой структурой программы, простотой
и ясностью конструкций. С момента создания Паскаль был универсален и
пригоден для решения широкого круга задач. Строгая типизация языка
значительно сокращает количество ошибок в программах.
Существует три стандарта языка:
1. Нерасширенный Паскаль (Unextended Pascal) был разработан в 1983
году и практически полностью совпадает с описанием языка по Вирту.
1
2. Расширенный Паскаль (Extended Pascal) содержит расширения,
затрагивающие модульное программирование (отдельная компиляция модулей,
импорт-экспорт подпрограмм, интерфейсная часть и реализация) и дополнен
рядом процедур и функций (прямой доступ к файлам, работа со строками и
др.).
3. Объектный Паскаль (Object Pascal) принят в 1993 г. Он поддерживает
классы,
обладающие
свойствами
и
методами,
наследование
классов,
переопределение методов у потомков (полиморфизм) и другие атрибуты
объектно-ориентированного программирования. Начиная со среды разработки
Delphi 7.0, в официальных документах Borland стала использовать название
Delphi для обозначения языка Object Pascal.
Реализации языка:
1. Для операционной системы MS-DOS самое большое распространение
приобрела реализация языка Паскаль фирмы Borland под названием Turbo
Pascal (первая версия языка появилась в 1983 году).
2. Borland Pascal включает в себя более дешёвый и менее мощный Turbo
Pascal и, кроме того позволяет создавать программы как под реальный, так и
под защищённый 16-битный режим DOS, а так же программы для Windows. В
нем открыты исходные тексты системных библиотек и функций времени
выполнения.
3. Delphi – интегрированная среда разработки ПО для Microsoft Windows
на языке Delphi, созданная первоначально фирмой Borland и на данный момент
принадлежащая и разрабатываемая Embarcadero Technologies.
4. Free Pascal – свободно распространяемый компилятор языка
программирования Pascal с ориентацией на Object Pascal.
5. Lazarus – свободно распространяемая интегрированная Delphiподобная среда разработки программного обеспечения для компилятора Free
Pascal,
предоставляющая
возможности
приложений.
2
кроссплатформенной
разработки
6. PascalABC – система, представляющая собой интерпретатор языка
программирования Паскаль с интегрированной оболочкой. Создавалась как
учебная среда программирования. Pascal ABC и PascalABC.NET всех версий
является свободно распространяемым программным обеспечением.
Учитывая,
что
задания
практических
работ
могут
выполняться
студентами с помощью любой из приведенных систем программирования, мы
будем стараться описывать только те возможности языка, которые есть во всех
этих системах. Описываемые возможности иногда будут шире стандарта языка
Паскаль. Связано это с тем, что существует ряд полезных доработок языка дефакто используемых большинством программистов.
2. Понятия
синтаксиса,
семантики
и
прагматики
языка
программирования
Разработка программы состоит из следующих этапов:
 Создание или редактирование текста программы.
 Компиляция – перевод программы с языка высокого уровня в машинноориентированные коды.
 Исполнение откомпилированного файла.
 Тестирование и отладка.
Компиляцию программы выполняет особая программа, называемая
компилятором.
Этапы компиляции:
 Лексический анализ.
 Синтаксический анализ.
 Семантический анализ.
 Генерация промежуточного кода.
 Оптимизация кода.
 Генерация результирующего машинного кода.
В ходе лексического анализа текст программы разбивается на отдельные
составляющие – лексемы. При выделении лексем важную роль играет алфавит
3
языка, а также правила построения ее отдельных элементов: имен,
комментариев, констант.
В ходе синтаксического анализа проверяется правильность записи
операторов в соответствии с правилами языка. Ошибки, выявленные
компилятором во время лексического и синтаксического анализа, называются
синтаксическими ошибками.
Семантика языка программирования – это система правил определения
поведения отдельных языковых конструкций. Семантика определяет смысловое
значение предложений языка. Не все семантические ошибки могут быть
выявлены компилятором. Например, запись выражения
a
в виде a/b*c не
bc
вызовет ошибки, хотя и является неправильной, исходя из приоритета
выполнения операций. В ходе семантического анализа компилятор проверяет
соответствие типов и допустимость операндов в операторах. Так попытка
изменить значение константы, которая по определению является неизменяемым
значением, приведет к семантической ошибке. Использование типа данных,
недопустимого в данной конструкции, или несоответствие типов формальных и
фактических
параметров
процедуры
или
функции,
так
же
является
семантической ошибкой.
При описании языков программирования большое внимание уделяется
описанию синтаксиса и семантики, но знание только синтаксиса и семантики не
сделает из человека программиста, он кроме этого должен знать прагматику
языка. Прагматика языка программирования – это, по сути дела, методология
программирования, т.е. описание методов и приемов, позволяющих, исходя из
постановки задачи, составить программу ее решения. Описание прагматики
языка программирования осложняется тем, что некоторые задачи, хотя и
формулируются крайне просто, не имеют никакого алгоритма для их решения.
Такова, например, задача: проверить, является ли любая данная программа
семантически правильной. Задачи этого рода называются алгоритмически
неразрешимыми.
4
Из-за существования алгоритмически неразрешимых задач предмет
прагматики становится несколько расплывчатым и неопределенным – нельзя в
общем случае дать никаких рекомендаций, которые от постановки задачи
гарантированно приводили бы к ее решению. Кроме того, из-за разнообразия
задач, решаемых с помощью компьютера, те рекомендации, которые могут
быть даны, либо носят чересчур общий характер, либо, наоборот, слишком
конкретны, относятся к узкому классу задач. Теория программирования, хотя и
может гордиться рядом значительных достижений, ориентирована больше на
разработчиков алгоритмических языков и программного обеспечения ЭВМ, чем
на пользователей. Многие ее рекомендации представляют собой лишь
постановки задач, решение которых потребует еще многих лет труда
системных программистов, если вообще когда-либо будет достигнуто. Поэтому
большую роль в овладении навыками составления программ играет разбор
примеров разной степени сложности из разных классов задач.
3. Алфавит языка Паскаль и основные лексемы
Алфавит языка Паскаль
 Латинские буквы прописные и строчные: A…Z, a…z.
 Символы национальных алфавитов, например, русского.
 Цифры: (0...9).
 Зарезервированные символы:
; : , . + - * / < > = ^ ‘ ( ) [ ] { } $ # @
 Зарезервированные сочетания символов:
:= >= <= <> .. (*
 Ключевые (зарезервированные) слова:
*)
and
end
implementation
program
type
array
file
label
record
unit
begin
for
mod
repeat
until
case
forward
nil
set
uses
const
function
not
shl
var
div
goto
of
shr
while
5
do
if
or
string
with
downto
in
packed
then
xor
else
interface
procedure
to
Использовать эти слова каким-либо другим способом, например, в
качестве имен, нельзя. В большинстве систем программирования ключевые
слова выделяются автоматически цветом или шрифтом. Мы же в дальнейшем,
ключевые слова в программах будем выделять подчеркиванием.
Правила построения основных видов лексем
Прописные и строчные буквы во всем тексте программы на языке
Паскаль не различаются. К основным лексемам относятся: имена, константы,
комментарии.
Имена
Имя любого программного объекта в программе на Паскале должно быть
идентификатором.
К
программным
объектам
относят
переменные,
константы, типы, саму программу, процедуры и функции. В современных
версиях
языка
Паскаль
идентификатор
–
это
последовательность
латинских букв, цифр и знака подчеркивания ( _ ), начинающаяся с буквы
или со знака подчеркивания. Кроме этого, при записи идентификаторов в
программе на Паскале нужно учитывать следующее:
1)
Поскольку большие и маленькие буквы во всем тексте программы
не различаются, т.е. идентификаторы Otvet, otvet, OTVET и oTVET будут с
точки зрения компилятора эквивалентны.
2)
Идентификатор не может совпадать с ключевым словом. Именно
поэтому ключевые слова еще называют зарезервированными словами, т.е. они
заняты под нужды языка, и программист их использовать не может.
Пример 3.1
A1, _fg, r_304 – будут являться идентификаторами
123, 1de, авп, packed – не будут.
6
Константы
Константы, встречающиеся в тексте программы, могут быть различных
типов: числовые, строковые, символьные, логические.
Числовые константы могут быть целые и вещественные. Для записи
целого числа могут использоваться цифры 0...9 и знаки +, –. Если знак перед
числом не указан, то число считается положительным. Допустимы ведущие
незначащие нули, при выводе числа они отбрасываются. Целое число,
представленное в шестнадцатеричной системе счисления, записывается с
использованием префикса $. При выводе такое число будет переведено в
десятичную систему счисления.
Пример 3.2. Константы целого типа:
34
–825
$40 –$F $0b
+19
000056
– в десятичной форме;
00
– в шестнадцатеричной форме (при выводе: 64, –15,
11).
Вещественное число может задаваться в форме с фиксированной точкой
и с плавающей точкой. При записи вещественного числа в форме с
фиксированной точкой в качестве разделителя целой и дробной части
используется символ точка (.). Нужно отметить, что десятичная точка требует,
по крайней мере, одну цифру слева от себя, т.е. запись
.9,
например,
недопустима. При записи вещественного числа в форме с плавающей точкой
сначала записывается мантисса числа (m), затем символ E (или e, поскольку
большие и маленькие буквы Паскалем не различаются) и указывается порядок
числа (p). Мантисса может быть целым числом или вещественным в форме с
фиксированной точкой. Порядок задается целым десятичным числом. Формула,
для преобразования числа из формы с плавающей точкой в форму с
фиксированной точкой, следующая:
m E p = m ·10p.
Пример 3.3. Константы вещественного типа:
7
3.1415 0.00000127 –125.0 0.0
– в форме с фиксированной точкой;
0.31415E+001 789e–4 –1e+01 –
в
форме
(соответствуют числам: 3,1415 0,0789
c
плавающей
точкой
–10).
Вещественные числа, записанные с ошибкой:
Строковая
константа
–
3,14 .001 –5.12E 2e0.2
произвольная последовательность
это
символов, заключенная c обеих сторон в апострофы (‘). Если внутри строковой
константы должен присутствовать символ апострофа, то он указывается
дважды. Пустая строковая константа записывается в виде двух подряд идущих
апострофов (‘‘).
Пример 3.4. Константы строкового типа:
‘Добро пожаловать!‘
‘Магнитофон ‘‘Вега‘‘ продан.‘
(будет выведено: Магнитофон ‘Вега‘ продан.)
Символьная константа – это ровно один символ, ограниченный
апострофами. Обращение к любому символу возможен через его номер в
таблице кодировки, путем указания этого номера с предшествующим символом
решетки (#). Так, записи ‘D‘ и #68 дают ссылку на один и тот же символ, так
как номер символа D в таблице кодировки равен 68.
Логическая константа может принимать только два значения True или
False (при записи слов true и false регистр не имеет значения, как и при записи
всего текста программы, при выводе логическая константа будет записана
прописными буквами).
Пример 3.5. Константы логического, строкового и символьного типа:
TRUE – логическая константа;
‘TRUE‘ – строковая константа;
‘T‘, #12 – символьные константы.
Комментарии
Комментарий
с
точки
зрения
Паскаль-компилятора
–
это
последовательность символов, которая должна быть исключена из дальнейшей
8
обработки текста программы. С помощью комментариев программист может
пояснять текст программы. Комментарии, безусловно, полезны при передаче
текста программы другим лицам, а так же и для самого программиста, если он
захочет дорабатывать программу в будущем. Комментарии выделяются
символами фигурных скобок, при этом символ { означает начало комментария,
а символ } – конец комментария. Альтернативный способ выделения
комментариев: с помощью зарезервированных сочетаний символов (* и *),
первое из которых означает начало комментария, а второе – конец. Оба выше
перечисленных способа создания комментариев позволяют делать как
однострочные, так и многострочные комментарии. В современных версиях
языка Паскаль, в частности в Pascal ABC, Free Pascal и Delphi, имеется
возможность задавать однострочные комментарии с помощью сочетания
символов //, которое означает начало комментария, и комментарий при этом
распространяется только до конца текущей строки.
Пример 3.6. Использование комментариев в программе.
Var a:integer; (*Переменная а имеет целый тип*)
Begin
Readln(a); // Ввод значения переменной а с клавиатуры
a:=a+1; { Это на потом . . .
a:=a*2;
a:=a-a;
}
writeln(a)
End.
В данном примере три комментария, первый – «Переменная а имеет
целый тип», второй – «Ввод значения переменной а с клавиатуры» и третий –
«Это на потом … а:=a*2; a:=a-a;». Третий комментарий многострочный, и
использован для временного исключения части текста из программы.
9
4. Структура программы и ее синтаксис
Синтаксические диаграммы Вирта и структура программы
Для
описания
синтаксиса
языка
Паскаль
будем
использовать
синтаксические диаграммы, введенные Н. Виртом. Элементы алфавита языка
будем заключать в круг, например,
, или, если они имеют большую длину, в
прямоугольник со скругленными углами, например,
. Понятия,
требующие дальнейшей расшифровки, будем заключать в прямоугольник,
например
или
.
Понятие,
расшифровываемое
диаграммой, будем писать в начале диаграммы.
Рассмотрим синтаксическую диаграмму понятия «программа на языке
Паскаль».
Рис. 1. Синтаксическая диаграмма понятия «программа на языке Паскаль»
На данной диаграмме отражены следующие факты:
 обязательным элементом программы является только тело программы
(в современных версиях Паскаля это именно так);
 телу программы может (могут) предшествовать заголовок программы
и(или) раздел описаний.
Рис. 2. Синтаксическая диаграмма понятия «заголовок программы»
Заголовок программы состоит из ключевого слова program, после которого
в обязательном порядке должно быть указано имя, а после имени — точка с
запятой, например:
program Primer;
10
Тело
программы
представляет
собой
составной
оператор,
заканчивающийся точкой.
Рис.3. Синтаксическая диаграмма понятия «тело программы»
Рассмотрим, что представляет собой составной оператор.
Рис. 4. Синтаксическая диаграмма понятия «составной оператор»
Последовательность возникновения тех или иных элементов диаграммы в
программе определяется изгибами стрелочек. Так запись на рис. 5 означает, что
оператор между begin и end может быть или не быть, но если присутствует, то
ровно в одном экземпляре.
Рис. 5. Пример диаграммы, в которой некоторый элемент встречается 0 или 1 раз
Запись на рис. 6 показывает, что операторов может быть много, но если
операторов больше одного, то между ними нужно обязательно ставить «точку с
запятой» (;).
Рис. 6. Пример диаграммы, в которой некоторый элемент встречается 1 или более раз
Таким образом, тело программы с точки зрения языка Паскаль это ноль
или больше операторов, ограниченных спереди ключевым словом begin, а в
конце ключевым словом end c точкой (end.). В соответствии с этим
определением простейшая программа на языке Паскаль имеет вид:
begin
end.
11
Данная программа не содержит никаких действий. Она содержит только
операторные скобки begin (открывающая скобка) и end (закрывающая скобка),
роль которых — объединить группу операторов в единый блок. Причем,
поскольку после end стоит точка (.), данный блок имеет особую роль, он
определяет всю программу. В тексте программы так же могут встречаться
блоки операторов, оформленные с помощью операторных скобок begin...end,
но они уже будут рассматриваться как части программы, а не как вся
программа. Синтаксис Паскаля требует, чтобы операторы внутри составного
оператора разделялись знаком «точка с запятой» (;). Нужно заметить, что не
является ошибкой, если программист ставит точку запятой после каждого
оператора, в том числе и после последнего оператора, т.е. перед end. В этом
случае лишний знак «точка с запятой» будет трактоваться компилятором как
пустой оператор, поскольку имеет место следующее определение:
Рис. 7. Синтаксическая диаграмма понятия «пустой оператор»
Приведенная выше программа, состоящая только из операторных скобок,
довольно бесполезна, поскольку ничего не делает. Чтобы наполнить программу
смыслом, рассмотрим основные виды операторов.
Раздел описаний
Раздел описаний является одной из частей программы и располагается
перед телом программы. Раздел описаний в свою очередь может состоять из
следующих частей:
1) раздел подключаемых модулей
uses . . .
2) раздел описания меток
label . . .
3) раздел описания констант
const . . .
4) раздел описания типов
12
type . . .
5) раздел описания переменных;
var . . .
6) раздел описания процедур и функций.
procedure . . .
или
function . . .
Раздел подключаемых модулей должен располагаться первым и может
встречаться только один раз. Все остальные разделы описаний могут
располагаться в любом порядке и встречаться по несколько раз.
Раздел описания меток
Раздел описания меток начинается с ключевого слова label, его
синтаксис представлен на рис. 8.
Рис. 8. Синтаксическая диаграмма для раздела описания меток
Меткой может быть идентификатор или целое число без знака. С
помощью метки можно пометить любую строку в программе, указав в начале
строки саму метку и двоеточие. Перейти на строку, помеченную меткой, можно
с помощью оператора перехода, синтаксис которого описан на рис. 9.
Рис. 9. Синтаксическая диаграмма для оператора перехода
Использование меток и операторов перехода в программе ухудшает ее
понятность и затрудняет поиск ошибок. Э.Дейкстра и Н.Вирт сформулировали
принципы
структурного
программирования,
согласно
которым
любая
программа может быть написана с использованием трех базовых конструкций:
последовательное исполнение, ветвление, цикл. Поскольку использование
методологии структурного программирования повышает эффективность труда
программистов, подавляющее большинство из них используют эти принципы в
13
своей работе, и поэтому раздел label и метки в настоящее время практически
не используются. В Паскале АВС раздел label не реализован.
Раздел описания констант
В
разделе
описания
констант
можно
обозначить
некоторую
постоянную величину именем, и в дальнейшем обращаться по этому имени к
константе.
Использование
идентификаторов
для
констант
повышает
читабельность программы и удобство работы с ней, ведь в случае
необходимости изменить значение константы придется менять только в одном
месте, и не просматривать всю программу в поисках тех мест, где эта константа
встречалась.
Современные реализации языка Паскаль позволяют использовать два
типа констант:
1)
«обычные» константы, могут хранить только одну величину
(число, символ, строку, логическую величину, величину перечислимого типа) и
не могут изменять свое значение по ходу программы;
2)
типизированные
константы,
могут
принимать
значения
структурированных типов, а так же изменять свое значение в программе.
Подробно типизированные константы будут рассмотрены позже.
Синтаксис раздела описания констант приведен на рис. 10.
Рис. 10. Синтаксические диаграммы для описания «обычных» констант
«Обычные» константы удобно использовать, если в программе часто
используется одно и то же значение, которое не может измениться (например,
ставка подоходного налога). Кроме того, их можно использовать, если значение
14
очень длинное и при его наборе можно ошибиться. Тип для «обычной»
константы не указывается. Он определяется автоматически при анализе
значения константы. Можно определять константы как значения выражений,
используя в качестве операндов даже имена ранее определенных констант.
Такие выражения называются константными, основное требование
для их
вычисления не требуется исполнять всю программу. В выражениях могут
использоваться все математические операции (+, -, /, *, div, mod), логические
операции (not, or, and, xor), операции отношения и некоторые функции.
Пример 4.1. Определение «обычных» констант.
const
Min = 0;
{константа - целое число}
Max = 100; {константа - целое число}
e = 2.7;
{константа - вещественное число}
SpecChar = '\'; {константа - символ}
HelpStr = 'Нажмите клавишу F1'; {константа - строка}
OK = True; {логическая константа "истина"}
Interval = Max - Min + 1;
e2 = e*e;
BigHelpStr = HelpStr + ' для подсказки';
В Турбо-Паскале есть несколько зарезервированных констант, которые не
нужно описывать в программе. Вот некоторые из них:
PI = 3.141592653E+00,
MaxInt = 32767 или 2147483647 (подробнее о константе MaxInt в
следующей главе).
Раздел описания переменных
Синтаксис раздела описания переменных приведен на рис. 11.
Рис. 11. Синтаксическая диаграмма для раздела описания переменных
При описании переменной происходит выделение памяти для ее
хранения. Начальное значение переменной при описании не присваивается, т.е.
15
в
начале
работы
программы
значения
всех
переменных
являются
неопределенными.
5. Литература
1) Йенсен К., Вирт Н. Паскаль. Руководство пользователя. М.: Финансы и
статистика, 1989.
2) Вирт Н. Систематическое программирования. Введение. М.: Мир, 1977.
3) Вирт Н. Алгоритмы + структуры данных = программы. – М.: Мир, 1985.
ОСНОВНЫЕ ТИПЫ ДАННЫХ. РАБОТА С ВЫРАЖЕНИЯМИ. ПРОГРАММИРОВАНИЕ
ЛИНЕЙНЫХ И ВЕТВЯЩИХСЯ АЛГОРИТМОВ ................................................................................................. 16
1.
ОСНОВНЫЕ ТИПЫ ДАННЫХ .......................................................................................................... 16
Иерархия типов данных ........................................................................................................................ 16
Целые типы данных .............................................................................................................................. 18
Вещественные типы данных................................................................................................................ 20
Символьный тип .................................................................................................................................... 21
Логический тип...................................................................................................................................... 22
2.
РАБОТА С ВЫРАЖЕНИЯМИ ............................................................................................................ 23
Арифметические выражения ............................................................................................................... 23
Оператор присваивания........................................................................................................................ 24
Алгоритмы обмена значений двух переменных .................................................................................. 25
Побитовые операции над значениями целого типа ........................................................................... 25
Операции сравнения .............................................................................................................................. 27
Логические выражения ......................................................................................................................... 28
Правила вычисления выражений ......................................................................................................... 28
3. СРЕДСТВА ЯЗЫКА ПАСКАЛЬ ДЛЯ СОЗДАНИЯ ЛИНЕЙНЫХ И ВЕТВЯЩИХСЯ
АЛГОРИТМОВ ............................................................................................................................................................. 31
Операторы вывода ................................................................................................................................ 31
Операторы ввода .................................................................................................................................. 34
Оператор ветвления ............................................................................................................................. 37
Оператор выбора (варианта) Case ..................................................................................................... 39
Основные типы данных. Работа с выражениями.
Программирование линейных и ветвящихся алгоритмов
6. Основные типы данных
Иерархия типов данных
Компьютер работает с информацией, хранящейся в его памяти.
Отдельный информационный объект (число, символ, строка, таблица и пр.)
называется величиной. Величины в программировании, так же, как и
математические величины, делятся на переменные и константы (постоянные).
Для каждой величины должен быть определен тип.
16
Тип определяет:
1) множество допустимых значений того или иного объекта;
2) множество операций, которые к нему применимы;
3) формат внутреннего представления данных в памяти ЭВМ.
В отношении типов объектов Паскаль является статическим языком. Это
означает, что тип объекта, например, переменной, определяется при ее
описании и не может быть изменен в дальнейшем.
Все типы данных разделяются на три группы: скалярные (простые –
определяют тип только одного отдельного значения), структурированные
(составные, состоящие из нескольких элементов скалярного типа) и ссылочные
(указатели на некоторую область оперативной памяти). Скалярные типы в
свою очередь делятся на порядковые и вещественные. Иерархия типов данных
в Паскале представлена на рис. 1.
Типы данных в Паскале
Структурированные
Скалярные
Порядковые
Ссылочные
Массивы
Вещественные
Целые
Строки
Логический
Множества
Символьный
Записи
Перечислимый
Файлы
Интервальный
Рис. 1. Иерархия типов данных в Паскале
Порядковый тип – это тип, состоящий из счётного количества значений,
которые можно пронумеровать. На этом множестве значений существуют
понятия «следующий» и «предыдущий».
17
Целые типы данных
В большинстве реализаций языка Паскаль существуют следующие типы
данных для представления целых чисел (см. Таблица 1. Целые типы данных).
Таблица 1. Целые типы данных
Тип
Диапазон значений
Объем памяти
Integer
–2147483648...2147483647
4 байта, со знаком
Byte
0...255
1 байт, без знака
Word
0...65535
2 байта, без знака
Основным целым типом является Integer. Другие целые типы (а их
может быть в конкретной реализации больше, чем представлено в таблице 1)
применяются в целях эффективного использования оперативной памяти. В
ранних реализациях языка Паскаль, в частности в Turbo Pascal и Borland Pascal,
значения типа Integer занимают по 2 байта и позволяют хранить значения из
диапазона –32768..32767, но при этом имеется тип LongInt, позволяющий
хранить
четырехбайтовые
целые
со
знаком.
Максимальное
значение,
соответствующее типу Integer, занесено в предопределенную константу с
именем MaxInt, которая может быть равна 32767 или 2147483647 в
зависимости от реализации языка.
При выполнении арифметических операций возможна ситуация, когда
результат выходит за границу разрядной сетки, она называется переполнением.
Попытка выйти за границу типа может не фиксироваться системой и не
приводить к сообщению об ошибке. Возникновение ошибки, или ее отсутствие,
зависит от настроек компилятора, которые можно менять в диалоговом режиме
посредством
меню
и
в
программном
режиме,
используя
директивы
компилятора. Директивы компилятора – это комментарии со специальным
синтаксисом. Они могут располагаться везде, где допустимы комментарии.
Если требуется, чтобы директива компилятора распространяла свое действие на
всю программу, ее располагают в начале программы. Для того чтобы
18
отслеживать выход за границу типа и исключить неверные вычисления в
программе рекомендуется использовать директивы:
{$R+} – включить контроль границ диапазона;
{$Q+} – включить контроль переполнения.
Эти же директивы со знаком «минус», отключают указанные опции.
Паскаль АВС не допускает использование директив компилятора, т.к.
использует в своей работе не компилятор, а интерпретатор. Этот недостаток
Паскаль АВС компенсируется тем, что в нем выход за границу типа
отслеживается автоматически.
Пример 1.1. В ячейке памяти размером 1 байт хранится целое число
255 (переменная имеет тип byte). К данному числу прибавляют число 10. Какое
значение будет находиться в этой ячейке?
Правильный ответ: 9, т.е. получили: 255+10=9! Для объяснения
результата вспомним представление целых чисел в памяти ЭВМ.
Чтобы получить внутреннее представление целого положительного
числа N, хранящегося в k-разрядной ячейке, необходимо:
1. перевести число N в двоичную систему счисления;
2. полученный результат дополнить слева незначащими нулями до k
разрядов.
В нашем примере в 8-разрядную ячейку памяти пытаемся записать
получившееся в результате сложения число 265. Двоичное представление
этого числа 100001001 имеет 9 разрядов, т.е. значение выходит за границу
разрядной сетки. В этом случае единица в старшем (крайнем левом) разряде
теряется. В ячейке памяти останется двоичное число 00001001, которое
соответствует числу 9 в десятичной системе счисления.
Задание. Зарплата сотрудника хранится в переменной, которая имеет тип
Integer (программа начисления зарплаты написана в системе Turbo Pascal).
Обычная месячная зарплата составляет 30 тысяч рублей. Какую сумму получит
сотрудник, если однажды ему к зарплате выдали премию в размере 10 тысяч
рублей? Объясните результат.
19
Вещественные типы данных
Для вещественных чисел в большинстве реализаций языка Паскаль
определено пять диапазонов значений и соответственно пять идентификаторов
для описания (см. Таблица 2. Вещественные типы данных):
Таблица 2. Вещественные типы данных
Точность
Тип
Наименование
Допустимые
(число
значения
значащих
цифр)
Single
С одинарной точностью 1.5Е-45…3.4Е38
Real
Вещественный
Extended
Comp
С повышенной
точностью
Сложный (длинное
целое)
Объем
памяти
(Байт)
7-8
4
5Е-324…1.7Е308
15-16
8
3.4Е-4932…1.1Е4932
19-20
10
–9.2Е18…9.2Е18
19-20
8
Основным вещественным типом данных является Real, и в Pascal АВС
существует только этот тип. В ранних реализациях языка Паскаль (Turbo Pascal,
Borland Pascal) значения типа Real занимают по 6 байт и позволяют хранить
11-12 значащих цифр, но при этом имеется тип Double, занимающий 8 байт и
позволяющий хранить 15–16 значащих цифр. Особое положение в Паскале
занимает числовой тип данных comp, который трактуется как вещественное
число без экспоненциальной и дробной частей. Фактически, comp – это
«большое» целое число со знаком, сохраняющее 19–20 значащих десятичных
цифр. В то же время числовой тип данных comp в выражениях полностью
совместим с другими вещественными типами: над ним определены все
вещественные
операции,
он
может
использоваться
как
аргумент
математических функций и т.д. Часто тип comp используется для проведения
финансовых расчетов.
20
В Turbo Pascal и Borland Pascal доступ к числовым типам данных single,
double, comp и extended возможен только при особых режимах компиляции.
Подключить возможность использования этих типов в Turbo Pascal можно,
включив в начале программы директивы компилятора:
{$N+} – использовать математический сопроцессор;
{$E+} – использовать эмуляцию математического сопроцессора.
Наиболее эффективно включать обе директивы сразу {$N+,E+}, в этом
случае скомпилированный exe-файл сможет быть выполнен на любой машине,
независимо от наличия математического сопроцессора.
При сравнении вещественных чисел следует помнить, что вследствие
неточности их представления в памяти компьютера (в виду неизбежности
округления) стоит избегать попыток определения строгого равенства двух
вещественных значений. Есть шанс, что равенство окажется ложным, даже если
на самом деле это не так. Более точной проверкой условия, что «х равен y
(x=y)», является проверка, того что «x отличается от у на малую величину
(|x-y|<ε)». Здесь ε – это малая константа, определяющая желаемую точность
сравнения, например ε=0.0001 используется для сравнения с точностью до 5-го
разряда.
Также не рекомендуется использовать операции, дающие вещественный
результат без необходимости. Например, если нужно проверить условие
z
x 2  y 2 , лучше проверять эквивалентное ему условие
аналогично, проверяя условие
x2  y2  z 2 ,
x y
 t , мы получим меньше ошибок
2
округления, если будем проверять эквивалентное ему: x  y  2t .
Символьный тип
Символьный тип данных описывается идентификатором Char и позволяет
хранить символы в расширенном варианте кодировки ASCII. Каждое значение
типа Char занимает 1 байт памяти. Структура кодов расширенного варианта
ASCII:
21
1) Коды символов находятся в диапазоне от 0 до 255.
2) Вся таблица кодировки делится на две равные части: I половина
(стандарт ASCII) – коды символов от 0 до 127, II половина – коды символов от
128 до 255.
3) I половина таблицы кодировки включает следующие категории
символов (в скобках указаны их коды):
– управляющие символы (0..31);
– цифры (48..57);
– заглавные буквы латинского алфавита (65..90);
– строчные буквы латинского алфавита (97..122);
– знаки препинания.
4) II половина таблицы кодировки хранит:
– символы национальных алфавитов, например, русского;
– знаки препинания;
– символы псевдографики.
Цифры
и
символы
алфавитов
хранятся
в
таблице
кодировки
непрерывными блоками: цифровые символы в порядке возрастания, буквы в
алфавитном порядке. Так, если у цифры ’0’ код 48, то у цифры ’1’ код 49, у
цифры ’2’ код 50 и так далее до цифры ’9’ с кодом 57. Аналогично с буквами,
если заглавная латинская буква ’А’ имеет код 65, то код 66 будет принадлежать
’В’, 67 – ’С’ и т.д.
Символьный тип является порядковым типом, и порядок значение в типе
определяется порядком символов в кодировочной таблице. Таким образом,
символ ‘Z’ больше, чем символ ‘4’, т.к.
символ ‘Z’ хранится в таблице
кодировки позже, его код больше, чем код символа ‘4’.
Логический тип
Логический тип данных описывается идентификатором Boolean и
позволяет хранить только два значения: True (истина) и False (ложь).
Логический тип является порядковым типом, порядок значений в типе
22
следующий: False, True. Таким образом, значение True больше, чем
значение False.
7. Работа с выражениями
Арифметические выражения
Арифметические выражения могут содержать переменные, константы,
арифметические операции, функции и круглые скобки.
В языке Паскаль имеются следующие арифметические операции:
Унарная операция (применимая к одному операнду):
– (операция смены знака, например, –b).
Бинарные операции (применимые к двум операндам):
+ (сложение);
– (вычитание);
* (умножение);
/ (вещественное деление);
div (деление нацело);
mod (остаток от деления нацело).
Арифметические
операции
применяются
к
данным
целых
и
вещественных типов. При их использовании нужно учитывать, что:
 Результат вещественного деления всегда вещественное число, даже
если с точки зрения математики получается целый результат.
 Операции div и mod применимы только к значениям целого типа, их
результат так же целое число.
 Для остальных операций: если среди операндов выражения есть
вещественные значения, то результат вещественный, в противном случае –
целый.
Правила записи арифметических выражений:
 все символы пишутся в строчку на одном уровне,
 проставляются все знаки арифметических операций,
23
 не допускается два следующих подряд знака операций (в этом случае
используются скобки),
Пример 2.1. Записать следующую формулу в виде арифметического
выражения на Паскале:

1
3 y 5x  
y

2 + 3xy
2
+ 4x
x2
Ответ: 3*y*(5*x-1/y)/(2/(x*x)+4*x)*(2+3*x*y)
Оператор присваивания
Оператор присваивания представляет собой зарезервированную пару
символов «:=», употребляемую в контексте, представленном на рис. 2:
Рис. 2. Синтаксическая диаграмма для оператора присваивания
Работает оператор присваивания следующим образом: сначала вычисляется
значение выражения, а затем полученное значение заносится в указанную
переменную. Тип переменной и тип выражения должны быть совместимы.
Пример 2.2. Определить, какие операторы присваивания записаны без
ошибок:
Var a:integer;
b:real;
. . .
a:=b*5;
{ошибка, т.к. переменной целого типа нельзя
присвоить значение вещественного типа}
b:=(a+7)/3;
a:=1/(1+a);
{ошибка, т.к. операция / всегда возвращает
вещественное значение, которое не может быть
присвоено переменной целого типа}
b:=-b/3;
Пример 2.3. Определите значения переменных а и b.
24
a:=123 div 9;
{a=13}
b:=123 mod 9;
{b=6}
Операции div и mod очень часто используются для выделения цифр в
числах. Например, если n – целое четырёхзначное число, и если пронумеровать
цифры в числе справа налево, то
e:=n mod 10;
{4 цифра}
d:=n div 10 mod 10;
{3 цифра}
s:=n div 100 mod 10;
{2 цифра}
t:=n div 1000;
{1 цифра}
Задание. Попробуйте построить другие выражения с использованием div
и mod для получения второй и третьей цифры четырехзначного числа.
Алгоритмы обмена значений двух переменных
Пример 2.4. Обмен значений двух переменных с использованием
дополнительной переменной.
c:=x;
x:=y;
y:=c;
Пример 2.5. Обмен значениями двух переменных без использования
дополнительной переменной.
x:=x+y;
y:=x-y;
x:=x-y;
Задание. Пусть все переменные в примерах 2.4–2.5 имеют тип Byte, и в
начале работы программы присвоены следующие значения: x:=200; y:=300.
Какие значения будут иметь переменные x и y в результате работы алгоритмов,
описанных в примерах 2.4–2.5?
Побитовые операции над значениями целого типа
При
машинное
выполнении
побитовых
представление
целого
операций
числа,
рассматриваются как логические величины:
1 – «истина»,
25
при
используется
этом
внутреннее
значения
битов
0 – «ложь».
Результат побитовой операции имеет одинаковый тип данных с ее
аргументом. Перечислим побитовые операции, допустимые над целым типом:

побитовое отрицание not;

двуместные побитовые операции and, or, xor – аналогичные
соответствующим логическим операциям;

операции побитового сдвига: Shr – сдвиг вправо, Shl – сдвиг влево,
сдвиг производится на столько бит, каково значение второго аргумента, при
сдвиге вновь образовавшиеся биты заполняются нулями. Операции сдвига Shr
и Shl на k разрядов равносильны соответственно делению и умножению на 2k.
Пример 2.6. Выполнение побитовых операций.
Var x,y,z,t,v,w:Byte;
Begin
x:=5;
{внутреннее представление x - 00000101}
y:=12;
{внутреннее представление y - 00001100}
z:=x and y; {внутреннее представление z – 00000100, z=4}
t:=x or y;
{внутреннее представление t – 00001101, t=13}
v:=x xor y; {внутреннее представление v – 00001001, v=9}
w:= not x;
{внутреннее представление w – 11111010, w=250}
x:=x Shr 2; {внутреннее представление x – 00000001, x=1}
y:=y Shl 3; {внутреннее представление y – 01100000, y=96}
End.
Пример 2.7. Применение побитовых операций.
В некоторой операционной системе права пользователя задаются с
помощью «битовых масок», т.е. вся информация о правах хранится в одном
целом числе и каждый бит во внутреннем представлении числа имеет свое
смысловое значение. Например, отдельными битами могут кодироваться:
право чтения (просмотра) содержимого файлов, право записи (внесение
изменений) в файлы, право запуска файлов на выполнение и т.д. Значение бита
равное 1 означает наличие определенного права, а 0 – его отсутствие. При
создании нового пользователя ему автоматически назначаются права,
26
соответствующие той группе, к которой он принадлежит. В дальнейшем при
работе в рамках одной группы его права могут расшириться. Пусть
переменная right_group определяет права некоторой группы пользователей,
переменная right_new хранит вновь определенные (добавленные) права для
конкретного пользователя. Требуется определить значение переменной
right_user, хранящей права пользователя после их расширения.
Операции сравнения
В Паскале имеются следующие операции сравнения:
> (больше),
< (меньше),
>= (больше, либо равно),
<= (меньше, либо равно),
<> (не равно).
Результатом сравнения является логическое выражение. Операции
сравнения применимы к любому порядковому типу.
Пример 2.8. Даны следующие описания:
Var flag:Boolean; symbol:Char; digit:Byte; number:Integer;
Требуется определить значения переменой flag после выполнения
каждого оператора присваивания.
digit:=5;
{значение переменной flag не определено}
numder:=999;
flag:=digit>=3; {flag=true}
symbol:=’0’;
flag:=symbol >’9’; {flag=false}
flag:=Flag< >true; {flag=true}
flag:= digit=numder; {flag=false}
27
Логические выражения
Операции not, or, and, xor, применяемые к логическому типу называются
логическими (побитовые операции для целого типа называются так же). Они
соответствуют операциям, вводимым в математической логике:
not – логическое отрицание;
and – конъюнкция, логическое умножение;
or – дизъюнкция, логическое сложение;
xor – «исключающее» ИЛИ, сложение по модулю 2.
Таблицы истинности для данных логических операций приведены ниже.
Таблица 3. Таблица истинности для not
Таблица 4. Таблица истинности для and, or, xor
A
not A
A
B
A and B
A or B
A xor B
T
F
T
T
T
T
F
F
T
T
F
F
T
T
F
F
F
F
F
F
T
F
T
T
Логические выражения строятся на основе логических операций.
Аргументы для логических выражений – логические переменные и константы
или выражения, возвращающие логические значения.
Правила вычисления выражений
1) выражения, стоящие в скобках, вычисляются в первую очередь;
2) функции имеют более высокий приоритет, чем операции;
3) операции вычисляются согласно их приоритету (см. таблицу 5).
Таблица 5. Приоритеты выполнения операций языка Паскаль
Операции
@ not -(унарный)
Приоритет
Категория
1 (наивысший) унарные операции
* / div mod and shl shr 2
операции типа умножения
+ - or xor
3
операции типа сложения
4 (низший)
операции сравнения
= <> < > <= >= in
28
Операция @ позволяет получить адрес переменной, операция In
служит для определения принадлежности элемента множеству, эти
операции будут рассмотрены позже;
4) операции с равным приоритетом производятся слева направо.
Пример 2.9.
Требуется
составить
логическое
выражение,
возвращающее значение True, если точка с координатами (x,y) принадлежит
заштрихованной
части
плоскости,
изображенной на рис. 3, и возвращающее False
в противном случае.
(y>=0) and (x*x+y*y<=4) and (x*x+y*y>=1)
В любом логическом выражении, а точнее там,
где операции not, and, or, xor используются
как логические, а не как побитовые, нужно не
Рис. 3.
забывать, что операции сравнения имеют самый низкий приоритет, и значит
их для всех типов величин, за исключением логических, необходимо заключать в
скобки. В случае сравнения логических величин отсутствие скобок не вызовет
синтаксической ошибки, однако это не отменяет того, что сравниваться
величины будут в последнюю очередь.
Пример 2.10. Вычислить значение выражения, если используется
система программирования Turbo Pascal.
Var numb:integer;
. . .
numb:=6;
not True xor (4 > numb shl 2 or 12 mod 5) and (numb < not 9 shr 2)
Пронумеруем операции в том порядке, в каком они будут выполняться.
8
10
4
1
3
2
9
7
5
6
not True xor (4 > numb shl 2 or 12 mod 5) and (numb < not 9 shr 2)
Везде внутреннее машинное представление чисел будем писать в круглых
скобках.
Сначала вычисляем выражение в «первых» скобках
29
1) побитовый сдвиг числа numb влево на 2 разряда
numb shl 2 = (0000 0000 0000 0110) shl 2 = (0000 0000 0001 1000) = 24
2) вычисляем целочисленный остаток от деления числа 12 на 5
12 mod 5 = 2
3) побитовая операция or над двумя целыми числами, которые являются
результатом предыдущих операций
24 or 2 =(0000 0000 0001 1000) or (0000 0000 0000 0010) =
(0000 0000 0001 1010) = 26
4) сравниваем 4 с результатом предыдущей операции
4 > 26 =False
Вычисляем выражение во «вторых» скобках
5) операция побитового отрицания над числом 9
not 9 = not (0000 0000 0000 1001) = (1111 1111 1111 0110) = –10
6) побитовый сдвиг вправо на 2 разряда результата предыдущей операции
(1111 1111 1111 0110) shr 2 = (0011 1111 1111 1101) = 16381
7) сравниваем numb с результатом предыдущей операции
numb < 16381 = 6 < 16381 =True
Вычисляем операции вне скобок, согласно их приоритету.
8) логическое отрицание
Not True =False
9) логическое умножение
False and True =False
10) логическая операция «исключающее ИЛИ»
False xor False = False
Пример 2.11. Вычислить, если возможно, значение выражения.
Var x,y,z:Byte;
. . .
x:=1; y:=2; z:=3;
not x<>12 and y=8 or z>x
30
Пронумеруем операции в том порядке, в каком они будут выполняться.
1
4
2
5
3
6
not x<>12 and y=8 or z>x
1) Сначала выполнится логическое отрицание:
not x=not 1 =not(00000001)= (11111110)=254
2) Логическое умножение:
12 and y = 12 and 2= (00001100) and (00000010)=(00000000)=0
3) Логическое сложение:
8 or z= 8 or 3=(000001000) or (00000011)=(00001011)=11
4) Сравниваем результаты выполнения пунктов 1) и 2):
254 <>0 = True
5) Сравниваем на равенство результаты выполнения пунктов 3) и 4):
True=11! Такое сравнение недопустимо: операнды имеют неприводимые типы.
Дальнейшее вычисление выражения невозможно.
8. Средства языка Паскаль для создания линейных и
ветвящихся алгоритмов
Операторы вывода
Существует два оператора вывода:
 Write(<список параметров вывода>)
 WriteLn(<список параметров вывода>)
В приведенном определении для выделения некоторого понятия,
требующего дальнейшей расшифровки, используются угловые скобки (<…>).
Операторы эти действуют одинаково за исключением того, что writeln после
вывода указанных параметров переводит курсор на новую строку, а write –
оставляет курсор в текущей строке. На рис. 4 приведем расшифровку понятия
«список параметров вывода» в виде синтаксической диаграммы.
31
Рис. 4. Синтаксические диаграммы понятий «список параметров вывода» и «параметр вывода»
Таким образом, параметры вывода в списке перечисляются через
запятую, после каждого параметра может быть указан формат вывода, а в
качестве параметров для вывода могут быть имена переменных или констант,
выражения, а так же явно заданные константы.
Пример 3.1. Использование операторов вывода:
const g=9.81;
{описание константы g}
var a,b:integer;
{описание переменных а и b}
begin
a:=7; b:=13;
{присваивание значений переменным}
write(a);
{вывод значения переменной a}
Writeln(g);
{вывод значения константы g}
Write(‘Привет, мир!‘); {вывод строковой константы}
Writeln($14); {вывод целочисленной константы 20}
Writeln(False);
{вывод логической константы}
Write(2*30-12,‘ ‘); {вывод значения выражения и символьной
константы}
Writeln(a,‘+‘,b,‘=‘,a+b); {вывод 5-ти параметров,
первый и третий из которых переменные,
второй и четвертый – символьные константы,
а пятый – значение выражения}
end.
В результате выполнения данной программы на экран будет выведено:
7981
Привет, мир!
20
32
FALSE
48 7+13=20
Для каждого параметра вывода может указываться формат вывода,
задаваемый следующим образом:
Рис. 5. Синтаксическая диаграмма понятия "формат вывода"
Для всех типов констант и переменных целое число, указанное после
первого двоеточия означает количество позиций, отводимых под данное
значение. Выравнивание при форматном выводе производится по правому
краю. Если количество позиций указано меньше, чем требуется, выводимое
значение все равно будет отображено полностью. Вторая (необязательная)
часть формата вывода используется при выводе вещественных значений, она
задает количество цифр в дробной части. Во всех вышеупомянутых версиях
языка Паскаль (кроме Pascal ABC) если для вещественных чисел не указывать
формат вывода или указывать только первую часть формата, то они выводятся
в форме с плавающей точкой, например, операторы writeln(5689.08) и
writeln(5689.08:5) выведут что-то вроде 5.6890800000Е+03. Если задано
число цифр в дробной части меньше, чем имеется, то производится округление
по правилам математики. Так, оператор writeln(5689.08:6:1) выведет
5689.1.
Пример 3.2. Использование форматного вывода:
оператор
будет выведено
writeln(‘Проба пера‘:15);
writeln(‘Проба пера‘:5);
write(‘Проба‘:7);
writeln(‘ пера‘:7);
Writeln(3.1415926:12:4);
Writeln(3.1415926:2:2);
33
Writeln(0.5e-003:13);
Writeln(0.5e-003:10:5);
Операторы ввода
Как и в случае с операторами вывода, существует два вида операторов
ввода Read и ReadLn:

Read(<список параметров ввода>)

ReadLn(<список параметров ввода>)
Вводимые значения (кроме значений символов и строк) разделяют
пробелами или записывают на разных строках. Отдельные символы и строки
символов при вводе записывают подряд, так как пробел в этом случае также
считается символом.
Физически операции ввода выполняются с использованием буфера, т.е.
вводимая с клавиатуры последовательность сначала помещается в память, а
затем, уже из памяти читается программой. Последовательность передается в
буфер ввода по нажатию клавиши Enter. При этом в буфер, вместе с кодами
введенных символов помещается и код Enter, состоящий из двух символов:
#13 – «возврат каретки», #10 – «новая строка».
Если ввод осуществляется процедурой ReadLn, то буфер ввода после
выполнения
операции
очищается,
причем
символы,
оставшиеся
не
обработанными, игнорируются. Если ввод осуществляется процедурой Read, то
очистка не выполняется и, следовательно, следующий оператор ввода начнет
читать символы из той же строки. Использование процедуры Read может
привести к ошибке, если вводятся значения типа char или string.
Пример 3.3. Использование процедуры Read при вводе чисел:
Var a, b, c: Real; n :integer;
Begin
Read (a, b); {числа могут быть введены в одной строке или в
разных}
ReadLn (c, n); {числа могут быть введены в той же строке, что
и предыдущие числа; ввод осуществляется процедурой ReadLn, поэтому
34
буфер ввода после выполнения операции очищается, причем символы,
оставшиеся необработанными, игнорируются}
end.
Пример 3.4. Использование процедуры Read для ввода символов,
приводящее к игнорированию ввода в средах Turbo Pascal, Borland Pascal. После
ввода значения символа a нажимается клавиша Enter.
Var a, b, c:char;
Begin
Read (a); {очистка буфера ввода не выполняется}
Read (b); {компьютер не переходит в ожидание ввода символа b,
а вводит следующий символ из буфера ввода, т. е. символ #13}
Read (c); {компьютер не переходит в ожидание ввода символа c,
а вводит следующий символ из буфера ввода, т. е. символ #10}
end.
Чтобы избежать «игнорирования ввода», нужно вместо процедуры Read
использовать ReadLn.
Оператор ReadLn, как правило, используется в средах Turbo Pascal,
Borland Pascal для того, чтобы организовать задержку в работе программы до
тех пор, пока пользователь не нажмет клавишу Enter.
Как видно из приведенных на рис. 6 синтаксических диаграмм, в качестве
параметров ввода могут использоваться только идентификаторы.
Семантика данного оператора накладывает дополнительное ограничение:
параметрами ввода могут являться
только идентификаторы, являющиеся
именами переменных, т.к. только переменные могут менять свои значения в
программе.
Рис. 6. Синтаксические диаграммы понятий «список параметров ввода», «параметр ввода»
Пример 3.5. Определить, какие операторы ввода записаны без ошибок:
const g=981;
{описание константы g}
35
var a,b:integer;
{описание переменных а и b}
. . .
{№1}
Readln(‘ а= ‘, a);
{№2}
Read(a);
{№3}
readlN(g);
{№4}
ReadLn(a,b);
{№5}
ReadLn;
В операторе ввода №1 имеет место синтаксическая ошибка, т.к. в
качестве первого параметра записана строковая константа. Оператор ввода
№3 так же записан с ошибкой, т.к. имеет место попытка ввести значение
константы. Константа же по своему определению не может менять свое
значение
в
ходе
программы.
Данная
ошибка
относится
к
разряду
семантических.
Пример 3.6. Определить, что будет выведено следующей программой,
если пользователь вводил числа 2, 3, 4, 5 и после каждого числа нажимал
клавишу Enter. Произойдет ли задержка до нажатия клавиши Enter в конце
работы программы?
Var a,b:integer;
Begin
read(a);
readln(b);
writeln(‘Первый результат - ‘,a,‘ ‘,b);
readln(a);
readln(a);
writeln(‘Второй результат - ‘,a,‘ ‘,b);
readln;
end.
Будет выведено:
Первый результат – 2 3
Второй результат - 5 3
Если рассматривать всю программу за исключением последнего
оператора, мы видим, что в буфер клавиатуры 4 раза попадали пары символов
#13 #10 (пользователь 4 раза нажимал Enter), при этом считаны были только
36
3 пары символов #13 #10 (т.к. три раза встречался оператор readln). Таким
образом, на момент выполнения последнего оператора readln в буфере будет
находиться одна не считанная пара #13 #10. Соответственно, последний
оператор readln, который по замыслу разработчика должен был вызвать
задержку до нажатия клавиши Enter, такой задержки не вызовет. Он просто
считает накопившиеся в буфере клавиатуры спецсимволы и программа после
этого прекратит свою работу.
Пример 3.7. Создание дружественного интерфейса пользователя:
Writeln(‘Введите целое число от 1 до 100‘);
ReadLn(a);
Writeln(‘Введите целое число от 1 до 100‘);
ReadLn(b);
Writeln(a,‘*‘,b,‘=‘,a*b);
Пример диалога, реализуемого программой:
Введите целое число от 1 до 100
12
Введите целое число от 1 до 100
3
12*3=36
Оператор ветвления
Оператор ветвления позволяет организовать выполнение различных
операторов в зависимости от некоторого условия. Условие задается логическим
выражением и поэтому может быть достаточно сложным. Синтаксис данного
оператора представлен на рис. 7.
Рис. 7. Синтаксическая диаграмма для оператора ветвления
Если условие имеет значение «истина», то выполняется оператор,
указанный в ветви Then. Если условие ложно, то выполняется оператор,
указанный в ветви Else, или ничего не выполняется, если эта ветвь
37
отсутствует. В каждой ветви допустим только
один оператор, поэтому при необходимости
выполнить несколько операторов, их нужно
превратить
в
один
оператор,
используя
операторные скобки Begin…End. Как мы уже
говорили
ранее,
ограниченных
группа
операторов,
операторными
скобками
Рис. 8.
Begin…End, является одним оператором и называется составным оператором
(см. материал предыдущей лекции).
При использовании операторов ветвления нужно учитывать, что:
1)
внутри оператора ветвления точек с запятой не ставится, так как это
– единый оператор;
2)
операторы ветвления могут быть вложены друг в друга. В этом
случае, если неясно, к какому оператору If относится ветвь Else, то действует
следующее правило: Else относится к ближайшему оператору If, у которого
отсутствует данная ветвь.
Пример 3.8. Написать программу, определяющую, принадлежит ли
точка с координатами (x,y) заштрихованной области, изображенной на рис. 8.
Var x,y:real;
Begin
writeln(’Введите координаты точки (x,y) через пробел’);
readln(x,y);
if (x >= –2) and
(x <= 2) and (y <= 3) and (y >= 0) or
(x >= –4) and (x <= 4) and (y <= 0) and (y <= -2)
then WriteLn(’ Принадлежит’)
else WriteLn(’Не принадлежит’);
readLn;
End.
Задание. Попробуйте написать универсальную программу для решения
задач, подобных задаче, разобранной в предыдущем примере. Постановка
задачи: имеются два прямоугольника, стороны которых параллельны осям
38
координат, задаваемые координатами вершин. Прямоугольники пересекаются
или хотя бы соприкасаются сторонами. Рассматривается область, находящаяся
внутри
данных
прямоугольников.
Определить,
попадает
ли
точка
с
координатами (x, y) внутрь такой области или нет. Подумайте, каким образом
эффективнее описывать прямоугольники, определяющие область. Сколько для
этого необходимо задать точек?
Пример 3.9. Программа поиска максимума из двух чисел.
Program new;
Var x,y,max: integer;
Begin
WriteLn(‘Введите два целых числа‘);
ReadLn(x,y);
If
x>y Then Max:=x
Else Max:=y;
WriteLn(‘Максимум из чисел ‘,x:3,‘ и ‘,y:3,‘ – ‘, Max:5)
End.
Задание.
Определите
допустимый
тип
чисел,
которые
могут
обрабатываться алгоритмом, рассмотренным в предыдущем примере.
Оператор выбора (варианта) Case
Условный оператор If позволяет выбирать одно из двух возможных
действий. Если требуется выбор из большего числа альтернатив, то
используются вложенные ветвления. Кроме этого, существует оператор
варианта, который позволяет выбрать одну из нескольких альтернатив – это
оператор case, его синтаксическая диаграмма представлена на рис. 9.
39
Рис. 9. Синтаксическая диаграмма для оператора выбора
Работает оператор варианта следующим образом. Сначала вычисляется
значение селектора. Селектор может быть выражением или переменной
порядкового типа, причем порядковые значения верхней и нижней границ этого
типа должны находиться в диапазоне от –32768 до 32767. Порядковым типом
является тип, элементы которого образуют конечное множество. К порядковым
относятся все целые типы, символьный, логический и некоторые другие типы
данных. Значение селектора сравнивается с константами, записанными перед
операторами. При совпадении значения переменной с одной из констант, будет
выполняться оператор, стоящий после этой константы. В одной ветви
оператора case можно использовать следующие возможности:

указать единственную константу;

перечислить несколько констант через запятую;

задать диапазон в формате: <начальное значение>..<конечное
значение>
Тип константы должен совпадать с типом селектора. Если значение
переменной не совпадает ни с одной из констант, то выполняется оператор,
идущий после Else. Если он отсутствует, то никаких действий не выполняется.
Если после константы требуется выполнить несколько операторов, то
используется составной оператор.
Пример 3.10. Составить программу, запрашивающую 2 целых числа и
знак арифметического действия, а затем выполняющую это действие над
заданными числами.
40
Program plus;
Var x,y:integer;
R:real;
znak: char;
Begin
WriteLn(‘Введите два целых числа’);
ReadLn(x,y);
WriteLn(‘Введите знак’);
Readln(znak);
Case znak Of
’+’: WriteLn(x+y);
’*’: WriteLn(x*y);
’-’: WriteLn(x-y);
’:’,’/’: WriteLn(x/y);
Else WriteLn(‘неверный ввод’)
End.
Задание. Модифицируйте программу предыдущего примера, сделав
максимально удобным интерфейс пользователя. Предлагайте не ввести знак
операции, а выбрать из списка, проверяете корректность вводимых данных,
исключите
возможность
возникновения
ошибки
«Деление
на
ноль».
Попробуйте сделать проверку, не ввел ли пользователь вещественное число или
строковое значение. Если недостаточно знаний языка, прочитайте следующие
главы пособия. Посоревнуйтесь между собой, кто сможет организовать более
дружелюбный интерфейс.
Пример 3.11. Использование нескольких констант в одной ветви сase.
var i:integer;
begin
ReadLn(i);
Case i Of
0,2,4,6,8:Writeln(‘четное число меньше 10’);
1,3,5,7,9:Writeln(‘нечетное число меньше 10’);
10..20: Writeln(‘число от 10 до 20’);
Else Writeln(‘число больше 20’)
End
End.
41
42
Download