Министерство общего и профессионального образования Российской Федерации Воронежская государственная лесотехническая ака...
242 downloads
331 Views
367KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Министерство общего и профессионального образования Российской Федерации Воронежская государственная лесотехническая академия
ИНФОРМАТИКА Основы программирования на языке Паскаль Тексты лекций Часть 1
Воронеж − 1999
УДК 519.682.1 Стариков А.В. ИНФОРМАТИКА. Основы программирования на языке Паскаль: Тексты лекций в 3-х частях. Часть 1. Воронеж, 1999. − 51 с.
Первая часть текстов лекций содержит вводную информацию о решении задач на ЭВМ, включающую понятие, свойства и способы описания алгоритмов, алфавит, простые типы данных и операторы языка программирования Турбо-Паскаль версии 6.0. Тексты лекций по основам программирования на языке Паскаль предназначены для студентов специальности 060800 − “Экономика и управление на предприятиях лесного комплекса”. Библиогр.: 33 наим. Ил. 2. Табл. 5.
Печатается по решению редакционно-издательского совета ВГЛТА.
Рецензенты: кафедра прикладной математики и экономико-математических методов ВГТА, д-р техн. наук, проф. ВГТУ Кравец О.Я.
УДК 519.682.1 Стариков А.В., 1999 Оформление. Воронежская государственная лесотехническая академия, 1999
3 Введение Предлагаемые тексты лекций предназначены для студентов специальности 060800 − “Экономика и управление на предприятиях лесного комплекса”, изучающих основы программирования на языке Паскаль в интегрированной среде Турбо-Паскаль версии 6.0 в общем курсе “Информатика”. Тексты лекций разделены на три части, каждая из которых содержит материал нескольких лекций. Все представленные лекции имеют сквозную нумерацию. Тексты лекций содержат завершенные примеры программ, которые можно использовать на лабораторных занятиях. В конце текста каждой лекции содержатся вопросы и упражнения для самопроверки, которые помогут студентам определить насколько прочно они овладели материалом данной лекции. Первая часть, включающая материал 5 лекций, содержит вводную информацию о программировании на языке Паскаль, включающую: понятие, свойства и способы записи алгоритма, алфавит, простые типы данных и операторы языка Паскаль. Вторая часть, включающая материал 6 лекций, содержит информацию о структурных типах данных, файловом вводе-выводе, подпрограммах и механизмах передачи параметров в подпрограммы. Третья часть, включающая материал 3 лекций, содержит информацию о графических возможностях, реализованных в языке Турбо-Паскаль версии 6.0. Лекция 1. Этапы решения задач на ЭВМ. Понятие алгоритма. Свойства и способы описания алгоритмов. Общее знакомство с алгоритмическим языком программирования Паскаль. Структура типичной программы на языке Паскаль. Список литературы. Вопросы и упражнения для самопроверки. Этапы решения задач на ЭВМ Процедура подготовки и решения задачи на ЭВМ – достаточно сложный и трудоемкий процесс, состоящий из следующих этапов: 1. Постановка задачи (задача, которую предстоит решать на ЭВМ, формулируется пользователем или получается в виде задания). Постановка задачи определяет цель решения задачи, раскрывает ее содержание. Задача формулируется на уровне понятий проблемной области, к которой она относится, и должна быть понятна исполнителю (пользователю). 2. Математическая формулировка задачи (математическая постановка задачи, формализация задачи). Формализация задачи фактически представляет разработку математической модели решаемой задачи и включает в себя: 1) описание задачи с помощью формул; 2) определение перечней исходных данных и получаемых результатов; 3) задание начальных условий и точности вычислений.
4 3. Выбор (поиск) метода решения задачи. В ряде случаев одна и та же задача может быть решена с помощью различных методов. Например, существуют несколько численных методов для приближенного решения уравнения и системы уравнений, приближенного вычисления определенного интеграла и т.д. Выбор метода определяется, как правило, многими факторами, основными из которых являются точность получаемых результатов, время решения задачи на ЭВМ, требуемый объем оперативной памяти и дисковой памяти. В каждом конкретном случае в качестве критерия для выбора метода решения задачи принимают какой-либо из указанных критериев или некоторый интегральный критерий. 4. Разработка алгоритма решения задачи. На данном этапе устанавливается необходимая логическая последовательность вычислений с учетом выбранного метода решения задачи и других действий, с помощью которых будут получены результаты. 5. Написание программы на одном из имеющихся языков программирования (в нашем случае – на языке Паскаль). 6. Подготовка исходных данных, если в программе предполагается обработка больших массивов информации. 7. Ввод исходной программы с помощью редактора текстов в память ЭВМ с последующей записью на магнитный диск. 8. Трансляция исходной программы в машинные коды. 9. Отладка программы (путем запуска программы, остановки ее в контрольных точках и проверки содержимого ячеек памяти). 10.Тестирование программы (запуск программы с тестовыми наборами данных и сопоставление результатов с результатами, полученными другими способами). 11.Решение задачи на ЭВМ и обработка (применение) полученных результатов. Процедура решения любой задачи на ЭВМ характеризуется большей или меньшей степенью итеративности, зависящей от ряда как объективных, так и субъективных факторов: сложности решаемой задачи, наличия или отсутствия удобных инструментальных средств, квалификации программиста и других. Так, например, при обнаружении синтаксических ошибок в исходной программе при ее трансляции (этап 7) приходится вновь обратиться к редактору текстов (этап 6) для исправления ошибок, обнаруженных транслятором (компилятором — в случае использования языков высокого уровня). Если же при отладке программы (этап 8) или ее тестировании (этап 9) обнаружилась логическая ошибка (ошибка в алгоритме решения задачи), то приходится вновь заняться разработкой или корректировкой алгоритма (этап 3) или даже вернуться к пересмотру постановки задачи (этап 1) и ее математической формулировки (этап 2). На практических (лабораторных) занятиях большинство задач дается в математической формулировке, поэтому необходимость в выполнении этапов 1
5 и 2 отпадает и можно сразу приступать к разработке алгоритма решения задачи на ЭВМ. Понятие алгоритма и свойства алгоритма Одним из фундаментальных понятий информатики является понятие алгоритма. Сам термин "алгоритм" произошел от имени средневекового математика Мухаммеда аль-Хорезми (IX век), который был родом из Хорезма (в настоящее время находится на территории республики Узбекистан) и жил во "дворце мудрости" багдадского калифа. Аль-Хорезми также принадлежит честь ввода в научный обиход термина "алгебра". Дадим общее определение алгоритма. Итак, алгоритм – это конечный набор правил, позволяющих некоторому исполнителю чисто "механически" (т.е. совершенно не вникая в смысл совершаемых им действий) решать любую конкретную задачу из некоторого класса однотипных задач. Поскольку в нашем случае таким "бездумным" исполнителем является ЭВМ, то программа, которую она выполняет, как раз и является алгоритмом решения задачи (класса задач). Любой алгоритм обладает следующими тремя свойствами: • детерминированностью, означающей, что применение алгоритма к одним и тем же исходным данным должно приводить к одному и тому же результату; • массовостью, позволяющей получать результат при различных исходных данных; • результативностью, обеспечивающей получение результата через конечное число шагов. Существует несколько форм представления (описания) алгоритмов. Выделим среди них три наиболее важные. Это – запись алгоритма на естественном языке, на языке схем алгоритмов (блок-схемы) и на алгоритмическом языке (например, на языке программирования Паскаль). Более подробно эти способы описания алгоритмов рассмотрены ниже. Программа, записанная на языке Паскаль, представляет собой запись алгоритма решения некоторой задачи. Эта программа, записанная на человекоориентированном языке (таким безусловно является язык Паскаль), транслируется (переводится) специальной программой, называемой компилятором языка Паскаль, в объектный код, т.е. программу, записанную на машинноориентированном языке. Таким образом, фактически выполняется трансформация алгоритма из одной формы, понятной человеку, в другую форму, понятную компьютеру. Эту последнюю форму представления алгоритма, называемую выполнимой программой, и использует компьютер для получения необходимых результатов.
6 Различают алгоритмы линейной, разветвляющейся и циклической структуры, а также алгоритмы со структурой вложенных циклов. Алгоритмы решения сложных задач могут включать все перечисленные структуры, которые используются для реализации отдельных участков общего алгоритма. Способы описания алгоритмов Как уже отмечалось, наибольшее распространение для описания алгоритмов получили следующие три способа: • описание на естественном языке; • описание на языке схем алгоритмов (блок-схемы); • описание на алгоритмическом языке (например, на языке программирования Паскаль). Рассмотрим задачу вычисления действительных корней квадратного уравнения. Напоминаем, что квадратным уравнением называется уравнение, имеющее следующий вид: ax 2 + bx + c = 0, где b, c – любые действительные числа; а – также действительное число, отличное от 0. Составим алгоритм решения квадратного уравнения, используя все три способа описания алгоритмов. Запись алгоритма на естественном языке 1-й шаг: Ввести конкретные значения a, b, c. 2-й шаг: D присвоить значения выражения b2 − 4 ac (эта величина называется дискриминантом уравнения). 3-й шаг: Если D < 0, то действительных корней данное уравнение не имеет. Вывести сообщение "Действительных корней нет" и закончить работу. 4-й шаг: Если D ≥ 0, то найти корни уравнения x 1 и x 2 по следующим формулам: −b + D −b − D x1 = , x2 = . 2a 2a 5-й шаг: Напечатать полученные корни уравнения x1 и x2. Запись алгоритма с помощью блок-схем (языка схем алгоритмов) Блок-схема представляет алгоритм с помощью графических символов и соединяющих их линий (линий потока). Графические символы (элементы) блок-схем, их размеры, а также правила построения блок-схем определены го-
7 сударственными стандартами (ГОСТ 19.002-80 ЕСПД. Схема алгоритмов и программ. Правила выполнения; ГОСТ 19.003-80 ЕСПД. Схема алгоритмов и программ. Обозначения графические условные). Полный список графических символов, описанных в указанных стандартах, включает 42 элемента. Ниже в табл. 1 приведены некоторые символы языка схем алгоритмов, необходимые для записи алгоритма нахождения действительных корней квадратного уравнения. Символы (блоки) языка схем алгоритмов Таблица 1. Естественный язык
Язык алгоритмов
Начать выполнение алгоритма решения задачи.
Этот блок является отправной или стартовой точкой алгоритма.
Начало
Ввести значения для переменных a, b и c .
Вводятся исходные данные, необходимые для работы алгоритма.
a, b, c Переменной D присвоить значение выражения b 2 − 4ac . Если значение D меньше 0, то идти по стрелке “Да”; в противном случае – по стрелке “Нет”.
Напечатать значения переменных x1 и x2 . Перейти к следующему блоку алгоритма.
D = b2 - 4ac
Н ет
Да
D<0
x 1, x 2
Комментарий
Вычисляется значение выражения, стоящего справа от знака “=”, и присваивается переменной D. Проверяется условие, записанное в ромбе. Если оно удовлетворено, выполнение продолжается по стрелке “Да”; в противном случае – по стрелке “Нет”. Выполняется вывод на принтер значений указанных переменных или выражений. Выполняется переход к следующему блоку по указанной линии потока.
8 Закончить выполнение алгоритма решения задачи.
Происходит завершение всех вычислений по заданному алгоритму.
Останов
Блок-схема алгоритма решения квадратного уравнения Блок-схема алгоритма нахождения действительных корней квадратного уравнения показана на рис. 1. Н ачало
a, b, c
D = b2 - 4ac
Н ет
Да
D<0 x1 =
−b + D 2a
x2 =
−b − D 2a
Действительных корней нет
x 1, x 2
Останов
Рис. 1. Блок-схема алгоритма решения квадратного уравнения
9 Запись алгоритма на языке программирования Паскаль Запись алгоритма решения квадратного уравнения на языке программирования Паскаль (т.е. программа, вычисляющая корни квадратного уравнения) приведена ниже. { Программа для вычисления действительных корней квадратного уравнения, если они, конечно, имеются... } program Roots(input,output); var a,b,c : real; {переменные для хранения коэффициентов} x1,x2 : real; {переменные для хранения корней уравнения} D: real; {переменная для хранения дискриминанта} begin writeln ('Введите коэффициенты квадратного уравнения'); writeln; write ('a = '); readln(a); write ('b = '); readln(b); write ('c = '); readln(c); d := b*b-4*a*c; {вычислим значение дискриминанта} if
D < 0 then writeln('Действительных корней нет') else begin x1 := (–b+sqrt(D))/(2*a); {вычислим 1-й корень} x2 := (–b–sqrt(D))/(2*a); {вычислим 2-й корень} writeln('x1 = ', x1); {напечатаем 1-й корень} writeln('x2 = ', x2); {напечатаем 2-й корень} end; end. {В конце программы ставим точку!} Общие сведения о языке Паскаль Язык программирования Паскаль был разработан швейцарским ученым Никлаусом Виртом в 1968–71 гг. Вирт назвал свой язык Паскалем в честь французского религиозного философа, математика и физика XVII века Блеза Паскаля. Давая название своему новому языку программирования, Вирт имел в виду прежде всего то обстоятельство, что Паскаль в юности изобрел механиче-
10 ское счетно-решающее устройство, которое назвал "Паскалиной". Первоначально язык Паскаль был задуман как средство для обучения программированию, но в дальнейшем – после расширения языка и разработки высокоэффективных компиляторов (один из них – Турбо-Паскаль) – он стал использоваться как язык для профессионального программирования. В настоящее время Паскаль является одним из наиболее распространенных языков программирования высокого уровня. Одним из наиболее известных диалектов языка Паскаль, использующихся на IBM PC-совместимых компьютерах, является Турбо-Паскаль, разработанный французом Филиппом Каном в 1982 году. В настоящее время используется уже седьмая версия Турбо-Паскаля, работающая как в среде операционной системы DOS, так и в среде Windows, и представленная эффективными программными средствами: интегрированной средой разработки (IDE), объединяющей в своем составе экранный редактор текстов, компилятор, редактор связей, символьный отладчик, подсистему управления файлами и справочную подсистему; компилятором командной строки; инструментальными пакетами Turbo Vision, Turbo Professional, Object Professional и другими. Некоторые высказывания о языке вообще и языке программирования в частности 1) Б.Л. Ворф – "Язык формирует наш способ мышления и определяет, о чем мы можем мыслить." 2) Брайан Керниган – "Единственный способ изучить новый язык программирования – писать на нем программы." Структура программы на языке Паскаль Программа для ЭВМ состоит из двух важных частей: описания действий, которые необходимо выполнить для достижения желаемого результата, и описания данных, с которыми оперируют упомянутые действия. Действия в программе на языке Паскаль описываются с помощью операторов, а данные – с помощью описаний, или объявлений (declaration), и определений (definition). Программа на языке Паскаль состоит из заголовка и "тела" программы, которое называется блоком. В заголовке программе дается имя и могут перечисляться ее параметры – входные и выходные файлы (по крайней мере, так обстоит дело для стандарта языка Паскаль). Блок программы состоит из шести разделов, причем любой из них, за исключением последнего, может быть пустым, т.е. может отсутствовать. Стандартный язык Паскаль требует, чтобы в определении блока разделы следовали в следующем порядке: • раздел описания меток; • раздел определения констант;
11 • раздел определения типов; • раздел описания переменных; • раздел описания процедур и функций; • раздел операторов. В первом разделе перечисляются все метки, определяемые в данном блоке. Во втором – определяются синонимы для констант, т.е. вводятся "имена констант", которые можно позже использовать вместо самих констант. Третий раздел содержит определения типов, которые вводятся программистом, а четвертый – описания используемых переменных. В пятом разделе приводятся описания "автономных" частей программы – процедур и функций. В шестом разделе задаются действия, которые необходимо выполнить в программе. Язык Турбо-Паскаль менее "привередлив" в отношении порядка следования разделов описаний. Он лишь требует, чтобы вначале следовал заголовок программы, если он присутствует в программе, а раздел операторов был последним. Между ними могут размещаться разделы описаний и порядок их следования не регламентируется. Однако в Турбо-Паскале, также как и в стандартном Паскале, необходимо описывать все объекты перед их использованием (в противном случае во время компиляции будет выведено сообщение об обнаружении неизвестного идентификатора). Ниже приведен текст самой короткой программы на Турбо-Паскале, которая содержит лишь раздел операторов, да и тот пустой. Выполнение этой программы не приведет ни к какому полезному эффекту. begin end. Список литературы 1. Вирт Н. Язык программирования ПАСКАЛЬ// Алгоритмы и организация решения экономических задач. – М.: Статистика, 1974. – Вып. 3. – с. 38-66. 2. Вирт Н. Систематическое программирование. Введение / Пер. с англ. – М.: Мир, 1977. – 168 с., ил. 3. Йенсен К., Вирт Н. Паскаль. Руководство для пользователя и описание языка / Пер. с англ. – М.: Финансы и статистика, 1982. – 151 с., ил. 4. Йенсен К., Вирт Н. Паскаль: руководство для пользователя / Пер. с англ.– М.: Финансы и статистика, 1989. – 255 с.: ил. 5. Вирт Н. Алгоритмы + структуры данных = программы: Пер. с англ. – М.: Мир, 1985. – 406 с., ил. 6. Грогоно П. Программирование на языке Паскаль: Пер. с англ. – М.: Мир, 1982. – 384 с., ил. 7. Уилсон И.Р., Эддиман А.М. Практическое введение в ПАСКАЛЬ / Пер. с англ. – М.: Радио и связь, 1983. – 144 с. 8. Перминов О.Н. Программирование на языке Паскаль. – М.: Радио и связь, 1983. – 220 с.
12 9. Перминов О.Н. Язык программирования Паскаль. – М.: Радио и связь, 1983. – 119 с. 10. Керниган Б., Плоджер Ф. Инструментальные средства программирования на языке Паскаль/ Пер. с англ. – М.: Радио и связь, 1985. – 313 с. 11. Бутомо И.Д., Самочадин А.В., Усанова Д.В. Программирование на языке Паскаль для микроЭВМ. – Л.: ЛГУ, 1985. – 214 с. 12. Грэхем Р. Практический курс языка Паскаль для микроЭВМ / Пер. с англ. – М.: Радио и связь, 1986. – 268 с. 13. Прайс Д. Программирование на языке Паскаль / Пер. с англ. – М.: Мир, 1987. – 232 с. 14. Форсайт Р. Паскаль для всех/ Пер. с англ. – М.: Машиностроение, 1987. – 288 с. 15. Абрамов С.А., Зима В.С. Начала программирования на языке ПАСКАЛЬ. – М.: Наука, 1987. – 112 с. 16. Абрамов С.А., Зима Е.В. Начала информатики. – М.: Наука, 1989. – 256 с. 17. Боон К. ПАСКАЛЬ для всех / Пер. с голл. – М.: Энергоатомиздат, 1988. – 190 с. 18. Абрамов В.Г., Трифонов Н.П., Трифонова Г.Н. Введение в язык Паскаль: Учеб. пособие. – М.: Наука, 1988. – 320 с. 19. Пильщиков В.Н. Сборник упражнений по языку Паскаль: Учеб. пособие для вузов. – М.: Наука, 1989. – 160 с. 20. Языки программирования Ада, Си, Паскаль. Сравнение и оценка/ Под ред. А.Р. Фьюера, Н. Джехани: Пер. с англ. – М.: Радио и связь, 1989. –368 с.: ил. 21. Сойер Б., Фостер Д.Л. Программирование экспертных систем на Паскале: Пер. с англ. –М.: Финансы и статистика, 1990. – 191 с.: ил. 22. Алкок Д. Язык Паскаль в иллюстрациях: Пер. с англ. – М.: Мир, 1991. – 192 с., ил. 23. Белецкий Я. Турбо Паскаль с графикой для персональных компьютеров / Пер. с польск. – М.: Машиностроение, 1991. – 320 с.: ил. 24. Зуев Е.А. Система программирования Turbo Pascal. – М.: Радио и связь, 1991. – 288 с. 25. Файсман А. Профессиональное программирование на Турбо-Паскале. –Ташкент, 1992. – 270 с.: ил. 26. Дагене В.А., Григас Г.К., Аугутис К.Ф. 100 задач по программированию: Кн. для учащихся/ Пер. с лит. – М.: Просвещение, 1993. – 255 с.: ил. 27. Ульман Дж. Базы данных на Паскале / Пер. с англ. – М.: Машиностроение, 1990. – 368 с.: ил. 28. Дмитриева М.В., Кубенский А.А. Элементы современного программирования: Учеб. Пособие / Под ред. С.С. Лаврова. – СПб.: Изд-во С.Петербургского университета, 1991. – 272 с.
13 29. Алагич С., Арбиб М. Проектирование корректных структурированных программ / Пер. с англ. – М.: Радио и связь, 1984. – 264 с., ил. 30. Простое и сложное в программировании. – М.: Наука, 1988. – 176с., ил. – (Серия “Кибернетика – неограниченные возможности и возможные ограничения”). 31. Джонс Ж., Харроу К. Решение задач в системе Турбо Паскаль / Пер. с англ. – М.: Финансы и статистика, 1991. – 720 с.: ил. 32. Епанешников А.М., Епанешников В.А. Программирование в среде Turbo Pascal 7.0. – 3-е изд., стер. – М.: "ДИАЛОГ-МИФИ", 1996. – 288 с. 33. Пильщиков В.Н. Сборник упражнений по языку Паскаль: Учеб. Пособие для вузов. – М.: Наука. Гл. ред. физ.-мат. лит., 1989. – 160 с. Вопросы и упражнения для самопроверки 1. Перечислите основные этапы процесса решения задачи на ЭВМ. Какие особенности имеет этот процесс? 2. Дайте определение такому основному понятию информатики, как алгоритм. Какими свойствами должны обладать алгоритмы? Поясните каждое из свойств алгоритма на примере. 3. Какие существуют основные способы описания алгоритмов? Назовите главные особенности каждого из способов. 4. Запишите в виде последовательности пронумерованных шагов алгоритм заваривания чая. Сколько шагов получилось? Выполняется ли в алгоритме проверка таких условий, как наличие чая для заварки, чайника или другой подходящей для данного случая посуды, воды в водопроводе и т.д.? 5. Какие элементы языка схем алгоритмов использовались при разработке блок-схемы алгоритма нахождения действительных корней квадратного уравнения? 6. Является ли программа, записанная на некотором языке программирования, алгоритмом? На кого рассчитан такой алгоритм? 7. Как следует изменить программу Roots, приведенную выше, чтобы она позволила вычислять комплексные корни в случае отрицательного значения дискриминанта. Напоминаем, что комплексным числом называется выражение вида a+b⋅i, где a, b − действительные числа, а i − так называемая мнимая единица, представляющая −1 . 8. Какова структура типичной программы, записанной на стандартном языке Паскаль? В какой последовательности должны располагаться разделы программы на языке Паскаль? 9. Каковы требования к порядку разделов, представленных в программе, в языке Турбо-Паскаль? Какой из разделов должен присутствовать в любой из программ, записанных на Турбо-Паскале?
14 10. Прокомментируйте с точки зрения определения структуры программы “формулу”, “выведенную” Виртом и вынесенную им в название одной из своих книг: Алгоритмы + структуры данных = программы. Лекция 2. Алфавит языка Турбо-Паскаль. Лексемы и разделители. Использование метаязыков для описания синтаксиса языков программирования: расширенные формы Бэкуса-Наура и синтаксические диаграммы Вирта. Система типов данных языка Турбо-Паскаль. Вопросы и упражнения для самопроверки. Алфавит языка Турбо-Паскаль В языках программирования, так же как и в естественных языках (русском, английском, греческом и других), для записи различных языковых конструкций используется конечное множество символов, называемое алфавитом. Алфавит языка Турбо-Паскаль образован следующими символами: • прописные и строчные буквы латинского алфавита и символ подчеркивания, который в Турбо-Паскале также отнесен к буквам: A B C ... Z a b c ... z _ • арабские цифры: 0123456789 • специальные символы: +-*/=><.,;:@'()[]{}#$^ Кроме того, в комментариях и в символьных константах допускается использование прописных и строчных букв русского алфавита. Лексические элементы языка Турбо-Паскаль В естественном языке для высказывания какого-либо утверждения или констатации некоторого факта, используется предложение. В письменной речи предложение строится из слов и знаков пунктуации. Аналогично, любая программа на языке Паскаль (или на любом другом алгоритмическом языке) состоит из предложений, каждое из которых образуется из лексических элементов (лексем) и разделителей. Лексема − это минимальная единица языка, имеющая самостоятельный смысл. Две соседние лексемы часто отделяются друг от друга разделителями. В качестве разделителей лексем в языке Паскаль используются пробел, табуляция, комментарий и конец строки (символы ВК − возврат каретки и ПС − перевод строки). В Турбо-Паскале имеются следующие четыре класса лексем: 1. Служебные (зарезервированные) слова. Служебные слова нельзя использовать в качестве имен, определяемых программистом (т.е. в качестве имен
15 констант, типов, переменных и т.д.). Ниже представлены 52 служебных слова языка Турбо-Паскаль версии 6.0. absolute (абсолютный) and (логическое И) array (массив) begin (начало) case (вариант) const (константа) constructor (конструктор) destructor (деструктор) div (целочисленное деление) do (выполнять) downto (уменьшая до) else (иначе) end (конец) external (внешняя) file (файл) for (для) forward (опережающее объявление) function (функция) goto (переход на) if (если) implementation (реализация) in (в) inline (встроенный) interface (интерфейс) interrupt (прерывание) label (метка)
mod (остаток от деления) nil (пустой указатель) not (логическое ОТРИЦАНИЕ) object (объект) of (из) or (логическое ИЛИ) packed (упакованный) procedure (процедура) program (программа) record (запись) repeat (повторять) set (множество) shl (сдвиг влево) shr (сдвиг вправо) string (строковый) then (то) to (увеличивая до) type (тип) unit (модуль) until (до) uses (использовать) var (переменная) virtual (виртуальный) while (пока) with (с) xor (логическое ИСКЛЮЧАЮЩЕЕ ИЛИ)
2. Имена (идентификаторы). Имена вводятся для обозначения в программе переменных, символических констант, типов, меток, процедур и функций. Имена формируются из букв и цифр, причем первым символом должна быть буква (см. выше алфавит языка Турбо-Паскаль). Длина имени может быть достаточно большой (например, равняться 126 символам − максимально допустимая строка ввода для встроенного редактора интегрированной среды ТурбоПаскаль 6.0), но значащими являются только его первые 63 символа. В ТурбоПаскале прописные и строчные буквы, использованные в идентификаторах, не различаются. Примеры допустимых идентификаторов: I_love_You, Summa123, Pascal, _Zig_Zag и т.д.
16 Помимо зарезервированных имен (см. выше пункт 1) в Турбо-Паскале имеются так называемые стандартные (или предопределенные) имена: integer, real, write, read, eoln, eof и другие. Эти имена программист может использовать в собственных целях (например, в качестве имен переменных), но делать этого не рекомендуется в силу того, что после использования такого имени в объявлении или определении оно утрачивает свой первоначальный смысл в пределах блока, содержащего это объявление или определение. Таким образом, если предположим, программист использовал в своей программе идентификатор write для обозначения переменной, он не сможет использовать это имя для обращения к процедуре вывода, т.е. первоначальный смысл имени write для данного блока будет утрачен. Примечание. Считается, что стандартные имена (см. абзац выше) определены (описаны) во внешнем − по отношению к программе − блоке. По этой причине их иногда называют предопределенными, т.е. предварительно определенными (или описанными) именами. 3. Литералы. Эта группа лексем включает числа, символьные строки и некоторые другие значения. Примеры литералов: 3.1415926, 6.023Е23, 'Привет!', 'I''m Boss' и т.д. Примечание. Если внутри символьной константы требуется указать апостроф, то он задается парой апострофов; таким образом, программист дает знать компилятору, что он желает иметь в этом месте символьной константы апостроф, а не заканчивает константу. 4. Знаки операций. Лексемы этого вида формируются из одного или нескольких специальных символов и предназначены для задания действий по преобразованию данных и вычислению значений. Одновременно знаки операций могут выполнять функцию разделителя двух соседних лексем в предложении. Примеры использования знаков операций: 2*Pi*Radius, (A1+A2+A3)/(A1*A2*A3), A:=B+C и т.д. Рассмотрим простую программу вычисления частичной суммы ряда S=1+1/2+1/3+...+1/n и на ее примере выполним анализ видов лексем, составляющих предложения этой программы. program Summa; var i, n : integer; S : real; begin write(‘Количество членов ряда? ‘); read(n); S:=0; for i := 1 to n do S:=S+1/i; writeln(‘Частичная сумма ряда для ‘, n, ‘ членов = ‘, S)
17 end. Эта программа состоит из заголовка программы и так называемого “тела” программы. Заголовок программы − это первая строка текста программы, которая состоит из двух лексем (одна лексема − зарезервированное слово program, другая − имя программы Summa), разделителя “пробел” (интервал между лексемами), символа-ограничителя (символ “точка с запятой”) и разделителя “конец строки” (этот разделитель появится в тексте программы после того, как будет нажата клавиша “Enter”). Тело программы состоит из раздела описаний (или объявлений) и раздела операторов. Раздел описаний представлен следующими лексемами: зарезервированное слово var (сокращение от variable − переменная), имена трех введенных нами переменных i, n и S, два стандартных (предопределенных) идентификатора − integer и real, разделители (пробел, “конец строки”). Раздел операторов образован рядом операторов (каждый из которых выполняет то или иное действие), заключенных в так называемые операторные скобки begin и end. Операторы могут либо включать в себя зарезервированные слова (например, while, do и другие), либо не иметь их (например, read(n), S:=S+1/i и другие). В качестве разделителей операторов выступает символ “точка с запятой”. Последним символом программы является точка (.). Использование метаязыков для описания синтаксиса Паскаля В основе любого языка (естественного или искусственного, например, языка программирования для ЭВМ) лежат: • синтаксис, определяющий правила построения предложений языка; • семантика, определяющая смысловую нагрузку синтаксически корректных предложений языка; • прагматика, представляющая весь богатейший опыт использования предложений языка. В случае языка программирования семантика, как правило, описывается неформально с использованием естественного языка. Прагматика представлена множеством тестов программ на рассматриваемом языке программирования. Синтаксис языка, как наиболее понятная его часть, часто описывается с привлечением формализованных методов. Для описания синтаксиса языков программирования часто используют так называемые метаязыки (т.е. языки описания языков − точнее синтаксиса языков). Одним из наиболее известных метаязыков является формализм БэкусаНаура (БНФ). Согласно БНФ, описание синтаксиса языка программирования состоит из набора правил (“продукций”), определяющих процесс формирования предложений в этом языке. Множество таких правил называют “грамматикой”. В настоящее время используется модификация БНФ, называемая расширенным формализмом Бэкуса-Наура (РБНФ).
18 Метасимволами РБНФ являются: Метасимвол Значение = есть по определению | или (альтернатива) . конец правила [X] 0 или 1 вхождение X {X} 0 или более вхождений X (X|Y) группирование или X, или Y "XYZ" терминальный символ XYZ Метаимя нетерминальный символ с именем Метаимя Ниже приведен фрагмент синтаксиса языка Турбо-Паскаль, записанный с помощью РБНФ: Программа = [Заголовок программы ";"] Блок ".". Заголовок программы = "program" Имя [Список параметров программы]. Список параметров программы = "("Список имен")". Список имен = Имя {"," Имя}. Блок = [Раздел объявлений] Раздел операторов. Раздел объявлений = [Раздел объявления меток] [Раздел определения констант] [Раздел определения типов] [Раздел объявления переменных] [Раздел объявления процедур и функций]. Раздел объявления меток = "label" Список меток ";". Список меток = Метка {"," Метка}. Метка = Имя | Целое число в диапазоне от 1 до 9999. Имя = Буква | {Буква | Цифра}. Буква = "A"|"B"|"C"|"D"|"E"|"F"|"G"|"H"|"I"|"J"|"K"|"L"|"M"|"N"|"O"|"P"|"Q"|"R"| "S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z"|"a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"| "l"|"m"|"n"|"o"|"p"|"q"|"r"|"s"|"t"|"u"|"v"|"w"|"x"|"y"|"z"|"_". Цифра = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9". ... Никлаус Вирт для описания синтаксиса языка Паскаль использовал разработанные им синтаксические диаграммы. В синтаксических диаграммах нетерминальные символы (т.е. синтаксические конструкции, которые можно подвергнуть дальнейшей “расшифровке”) заключаются в прямоугольники, а терминальные символы (т.е. конечные с точки зрения синтаксиса конструкции) − в овалы и кружки. Линии со стрелками показывают путь прохождения по диаграммам для получения синтаксически правильной программы. Ниже приведен фрагмент описания синтаксиса программы на Турбо-Паскале с помощью синтаксических диаграмм.
19 Программа
Заголовок программы
Заголовок программы
program
;
Блок
Имя
.
;
Список параметров программы Список параметров программы
(
Имя
)
, Блок
Раздел объявлений
Раздел операторов
Раздел объявлений Раздел объявления меток
Раздел определения констант
Раздел определения типов
Раздел объявления переменных
Раздел объявления процедур и функций
Типы данных в языке Турбо-Паскаль Любая информация, обрабатываемая на ЭВМ, состоит из отдельных простейших объектов данных, которые называются значениями. В Паскале все элементарные значения можно разделить на следующие четыре типа: целые, вещественные, булевские (или логические) и символьные.
20 Кроме того, все объекты данных, использующиеся в программе, можно разделить на константы и переменные. Константы не изменяют своего значения во время выполнения программы. Переменные же, как правило, изменяют свое значение во время выполнения программы. Каждая константа однозначно определяется такими характеристиками, как тип данных (целая, вещественная, булевская, символьная) и значение (1995, 3.1415926, TRUE, 'A' и т.д.). Многие языки программирования, включая и Паскаль, позволяют использовать символические константы, т.е. задавать для констант имена, которые выступают в качестве синонимов этих констант, и применять эти имена везде, где требуются значения констант. Раздел определения констант начинается с зарезервированного слова const (сокращение от constant − постоянный) и содержит определения символических имен констант в следующем виде: имя_константы = значение_константы; Компилятор определяет тип данных константы, основываясь на ее значении. Так, например, встретив в программе число 3.1415926 компилятор отнесет его к константам вещественного типа, поскольку в записи этого числа имеется десятичная точка. Встретившаяся в программе строка символов 'Блез Паскаль' будет расценена компилятором как символьная константа, так как она заключена в апострофы. Каждая переменная, помимо типа данных и текущего значения, характеризуется также именем (фактически, это адрес области памяти, распределенной для этой переменной и хранящей ее текущее значение). Кроме того, если это структурная переменная, то она характеризуется также своей внутренней структурой (количеством, порядком следования и типом данных составляющих ее компонентов). Поскольку каждая переменная представляется в программе с помощью имени, на основании которого компилятор не может сделать каких-либо выводов относительно типа данных переменной, то все переменные программы должны быть явно описаны. Описание (или объявление) переменных выполняется в разделе объявлений переменных, который начинается с зарезервированного слова var (сокращение от variable − переменная). Описание одной переменной имеет следующий вид: имя_переменной : имя_типа; Если в программе предполагается использовать несколько переменных одного и того же типа, то их можно описать либо порознь (как показано выше), либо одновременно: имя_переменной_1, имя_переменной_2, ... : имя_типа; Язык Паскаль является языком программирования со строгой типизацией данных, требующим описания в программе всех данных до начала их использования. Кроме того, стандартный Паскаль является языком со статическим использованием типов, т.е. для переменной, объявленной с некоторым типом дан-
21 ных, нельзя изменить тип в ходе выполнения программы. Эта особенность языка, которая некоторыми программистами расценивается как его недостаток, способствует написанию более надежных программ, поскольку позволяет компилятору тщательно контролировать правомерность использования тех или иных операций с переменными того или иного типа данных. Примечание. Турбо-Паскаль, в отличие от стандартного Паскаля, содержит специальную конструкцию явного преобразования типа. Эта конструкция носит название приведения типа переменной. Приведение не осуществляет никаких операций с переменной, а просто позволяет трактовать переменную одного типа как переменную некоторого другого типа. Язык Паскаль имеет развитую и изощренную систему типов данных. На основе небольшого числа стандартных (встроенных в язык) типов данных программист может конструировать данные произвольной структуры и сложности, адекватно отражающие информационную природу задачи. Язык Турбо-Паскаль, поддерживая все типы данных стандартного Паскаля, расширяет их путем добавления новых, практически полезных типов (например, типа данных string и объектов). Система типов данных языка Турбо-Паскаль может быть представлена иерархической схемой, показанной на рис. 2. Типы данных Турбо-П аскаля П ростые типы
Скалярные
Ограниченные Составные типы
Стандартные скалярные П еречислимые
Регулярные (массивы) Комбинированные (записи) Файловые М ножественные Строковые
Ссылочные типы
Объекты
П роцедурные типы Рис. 2. Иерархия типов данных в языке Турбо-Паскаль
22 Базовыми в системе типов данных языка Турбо-Паскаль являются простые типы. Составные типы данных по определенным правилам строятся из простых типов. Ссылочные типы данных образуются из любых других типов. Ограниченные типы данных формируются из простых (дискретных) типов путем сужения их области допустимых значений. Процедурные типы в некотором отношении расширяют традиционное понятие подпрограмм, позволяя обращаться с подпрограммами как переменными. Первичными в иерархии типов являются стандартные скалярные типы, представляющие традиционные в языках программирования множества значений (целые, вещественные, символьные и булевские) и их модификации, учитывающие архитектурные особенности компьютера (длина машинного слова, возможность побайтовой адресации к памяти и т.д.). Вопросы и упражнения для самопроверки 1. Что называется алфавитом языка программирования? Какие группы символов составляют алфавит языка Турбо-Паскаль? Дать краткую характеристику каждой группе символов. 2. Дать определение такому понятию, как лексема языка. Какие классы лексем представлены в Турбо-Паскале? Кратко охарактеризовать каждый из этих классов. 3. Какие символы в Турбо-Паскале используются в качестве разделителей соседних лексем программы? Какие из лексем сами могут выступать в роли разделителей лексем? Привести примеры. 4. В приведенном ниже тексте программы перечислить все лексемы и разделители. Обосновать свою точку зрения. program Hello; var Name : string [20]; begin write(‘Ваше имя? ‘); read(Name); writeln(‘Здравствуйте, ‘, Name) end. 5. Что такое метаязыки и для чего они используются? Какие из метаязыков наиболее часто используются при описании синтаксиса языка программирования? 6. Какими характеристиками описываются константы и переменные, используемые в программах? 7. Как выполнить объявление символических констант в программе на Паскале?
23 8. Как выполнить объявление переменных в программе на Паскале? Могут ли две или более переменных иметь одно и то же имя? Один и тот же тип данных? Обосновать свой ответ. 9. Дать краткую характеристику иерархической системе типов языка ТурбоПаскаль. Лекция 3. Простые типы данных: целый, вещественный, символьный, булевский, ограниченный и перечислимый типы. Примеры программ, использующих простые типы данных. Простые типы данных Стандартные простые типы − это типы данных, которые поддерживаются машинными архитектурами, т.е. являются встроенными для большинства компьютеров. К ним относятся, как правило, целые и вещественные числа, логические (булевские) значения и множество печатных символов. В Паскале существуют простые типы двух видов: порядковые типы и вещественный тип. Порядковый тип либо определяется программистом (и тогда его называют перечислимым типом или ограниченным типом), либо является именем одного из следующих типов: целого, символьного или булевского (см. ниже). Все простые типы, отличные от вещественных, являются порядковыми. Порядковым типам присущи следующие четыре характеристики: 1. Все возможные значения данного порядкового типа представляют собой конечное и упорядоченное множество значений. Каждое из этих значений связано с порядковым номером. Для любого порядкового типа, за исключением целого типа, первое значение имеет номер 0, второе − номер 1, третье − номер 2 и т.д. Порядковым номером значения целого типа является само это значение. Поскольку целочисленные значения могут быть и отрицательными, то и их порядковые номера так же могут быть отрицательными, что само по себе несколько необычно. Каждый порядковый тип имеет минимальное и максимальное значение. Для всех значений кроме минимального существует предшествующее значение, а для всех значений кроме максимального − последующее. 2. К любому значению порядкового типа можно применить стандартную функцию Ord, которая возвращает порядковый номер этого значения. Например, функция Ord(10) возвращает значение 10, поскольку порядковым номером целого числа является само это число; функция Ord(‘N’) возвращает значение 78, т.е. код латинской буквы N в таблице кодов ASCII; функция Ord(FALSE) возвращает значение 0, а Ord(TRUE) − значение 1 (считается, что булевское значение FALSE предшествует булевскому значению TRUE.
24 3. К любому значению порядкового типа, кроме первого, можно применить стандартную функцию Pred, которая возвращает значение, предшествующее данному значению. Например, функция Pred(0) возвращает значение -1 ; функция Pred(‘B’) возвращает значение ‘A’ ; функция Pred(TRUE) возвращает значение FALSE и т.д. 4. К любому значению порядкового типа, кроме последнего, можно применить стандартную функцию Succ, которая возвращает значение, следующее за данным значением. Например, функция Succ(0) возвращает значение 1 ; функция Succ(‘A’) возвращает значение ‘B’ ; функция Pred(FALSE) возвращает значение TRUE и т.д. К любым двум значениям одного и того же порядкового типа применимы операции отношения (или сравнения): = (равно), <> (не равно), < (меньше), <= (меньше или равно, не больше), >= (больше или равно, не меньше) и > (больше). Результатом любой операции отношения является одно из булевских значений (“истина” или “ложь”), которое формируется путем сравнения значений порядковых номеров операндов, участвующих в операции. Например, результатом операции 10 > 0 является значение TRUE (истина), а результатом операции ‘A’ = ‘B’ − значение FALSE (ложь). Ниже рассматриваются простые типы данных, реализованные в языке Турбо-Паскаль. Целые типы В Турбо-Паскале имеются пять целых типов, различающихся диапазоном допустимых значений и размером занимаемой оперативной памяти. Имена этих типов данных и их характеристики приведены в табл. 3. Таблица 3. Целый тип Диапазон значений Размер памяти (в байтах) Shortint (короткое целое) -128..127 1 Integer (целое) -32768..32767 2 Longint (длинное целое) -2147483648..2147483647 4 Byte (байт) 0..255 1 Word (слово) 0..65535 2 В Турбо-Паскале определены две символические константы MaxInt и MaxLongint, которые представляют верхние пределы диапазонов для типов Integer и Longint, т.е. равняются 32767 и 2147483647 соответственно. В программах на Турбо-Паскале целые значения могут записываться двумя способами: 1) в десятичном виде; 2) в шестнадцатеричном виде. При записи целого числа в шестнадцатеричном виде следует использовать шестнадцатеричные цифры (т.е. цифры от 0 до 9 и буквы A, B, C, D, E и F) и в начале числа ставить символ $ (знак доллара). Например,
25 $ABC (то же, что и 2748) $123 (291) $B800 (47104) $F1 (241) Над целыми значениями допустимы следующие арифметические операции: + сложение вычитание * умножение / деление, а также две дополнительные операции, обозначаемые предопределенными именами: div − целочисленное деление (с отбрасыванием дробной части результата) и mod − взятие остатка от целочисленного деления. При применении перечисленных выше операций к целым значения все они, за исключением деления (/), дают целочисленный результат. Операция деления всегда дает вещественный результат. Например, результатом операции 10/2 является 5.0, а не 5 (с точки зрения языка программирования и компьютера это различные значения!). Пример описания пяти целочисленных переменных: var Number : Integer; Size : Byte; Temp : Shortint; Num1, Num2 : Longint; Ключевое слово var (сокращение от variable − переменная) открывает раздел описания переменных в программе на Паскале. Вещественные типы В Турбо-Паскале имеются четыре вещественных типа, различающихся диапазоном допустимых значений, точностью, т.е. количеством цифр мантиссы (дробной части), и размером занимаемой оперативной памяти. Имена этих типов данных и их характеристики приведены в табл. 2. Таблица 2. Вещественный тип Диапазон значений Кол-во цифр Размер памяти (см. Примечание) мантиссы (в байтах) -39 38 Real (веществен11-12 6 2.9×10 ..1.7×10 ное) Single (обычная 7-8 4 1.5×10-45..3.4×1038 точность) Double (двойная 15-16 8 5.0×10-324..1.7×10-308 точность)
26 Extended (расширенная точность)
3.4×10-4932..1.1×104932
19-20
10
Примечание к табл. В графе “Диапазон значений” приведена только “положительная” половина возможного диапазона значений для каждого из перечисленных вещественных типов. Очевидно, что каждый вещественный тип имеет также соответствующую “отрицательную” половину диапазона, содержащую вещественные числа со знаком “минус”. Кроме того, к вещественным типам в Tурбо-Паскале относится тип Comp; этот тип содержит только целые числа из диапазона -2×1063..+2×1063-1, которые представляются в вычислениях как вещественные (с нулевой мантиссой). Вещественные числа могут записываться в программе на языке ТурбоПаскаль двумя способами: в форме с фиксированной точкой и в форме с плавающей точкой. В первом случае целая и дробная части числа отделяются друг от друга символом '.' (точка). Обе эти части должны обязательно присутствовать, например: 3.1415926 0.5 Вещественное число в форме с плавающей точкой записываются как пара чисел следующего вида: мантисса Е порядок Такое обозначение вещественного числа понимается как “мантисса, умноженная на 10 в степени, равной порядку”. Например, запись 6.023E23 означает 6.023×1023; 0.5Е-15 означает 0.5×10-15. Мантисса в записи вещественного числа с плавающей точкой представляется в виде целого числа или как вещественное с фиксированной точкой; порядок обозначается положительным или отрицательным целым числом. Пример описания четырех вещественных переменных: var Number : Real; Length : Single; Num1, Num2 : Double; Над вещественными значениями допустимы следующие арифметические операции: + сложение вычитание * умножение / деление, дающие вещественный результат, если хотя бы один из операндов является вещественным.
27 Когда целое значение присваивается вещественной переменной, оно автоматически преобразуется в вещественный тип; такое преобразование типов называется неявным. Попытка присвоить вещественное значение целой переменной приведет к ошибке. Если все же требуется выполнить присвоение подобного рода, то прибегают к помощи двух стандартных функций Паскаля: Trunc или Round. Функция Trunc преобразует вещественное значение в целый тип путем отбрасывания (усечения) дробной части. Функция Round преобразует вещественное значение в целый тип путем округления до ближайшего целого; другими словами, если R − вещественное значение, то для R>0 Round(R)= Trunc(R+0.5), а для R<0 − Round(R)=Trunc(R-0.5). Например, в результате выполнения следующего фрагмента программы на Паскале: var Number : real; begin Number := 3.7; writeln(trunc(Number),round(Number)); ... end. на экран будут выведены два числа: 3 и 4. Символьный тип Значениями символьного типа (Char) являются элементы конечного и упорядоченного множества символов. В каждом компьютере такое множество есть − оно используется для связи компьютера с “внешним миром”. Символы этого множества есть как на устройствах ввода (например, на клавиатуре), так и на устройствах вывода (например, на принтере). В IBM PC-совместимых компьютерах таким множеством символов является расширенный набор символов ASCII (см. ниже текст программы для вывода таблицы ASCII на экран монитора) Значение символьного типа − это одиночный символ. В программе на языке Паскаль значение символьного типа (символьная константа) представляет собой символ, заключенный в апострофы; если символьным значением является сам символ “апостроф”, то он записывается в виде пары апострофов. Например: 'А', '*', '5', '''', 'а'. Переменные символьного типа описываются так, как показано в примере, приведенном ниже. Для переменной с типом Char компилятор Турбо-Паскаля распределяет в памяти один байт. var Letter : Char;
28 Symbol : Char; Для отображения множества символов в множество порядковых номеров и обратно используются две стандартные функции Ord и Chr, называемые функциями отображения. Функция Ord возвращает порядковый номер символа, переданного ей в качестве параметра. Функция Chr возвращает символ, код которого был передан ей в качестве параметра. Очевидно, что функции Ord и Char являются обратными по отношению друг к другу, т.е. Chr(Ord(C))=C и Ord(Chr(I))=I. Более того, упорядоченность множества символов определяется так, что C1, <, <=, >=, >. Для параметров типа Char стандартные функции Pred и Succ могут быть определены следующим образом: Pred(C) = Chr(Ord(C)-1) и Succ(C) = Chr(Ord(C)+1). Пример программы, использующей данные символьного типа: { Эта программа выводит коды символов и графические представления соответствующих им символов. } program ASCII_Table; uses Crt; var i : byte; c : char; begin for i := 0 to 255 do case i of 7: writeln(i:3,' Bell'); 8: writeln(i:3,' Backspace'); 10: writeln(i:3,' Line Feed'); 13: writeln(i:3,' Carriage Return'); else writeln(i:3,' ',Chr(i)) end end. Приведенная выше программа использует модуль Crt, обеспечивающий интерпретацию только четырех символов (звонок, забой, перевод строки и возврат каретки) в качестве управляющих символов. Остальные символы имеют соответствующие графические представления − иногда достаточно экзотические (например, улыбающиеся рожицы, карточные масти и т.п.). Булевский тип Значениями булевского типа (Boolean) являются два истинностных значения, обозначаемых с помощью стандартных (предопределенных) имен True (истина) и False (ложь). Тип данных назван Н. Виртом "булевским" в честь анг-
29 лийского математика-самоучки Джорджа Буля (1815-1864 гг.), который первым разработал алгебру логики (булеву алгебру). Имеются четыре стандартные логические операции, применимые к булевским операндам и обозначаемые с помощью следующих служебных (зарезервированных) слов: and логическое И (логическое умножение) or логическое ИЛИ (логическое сложение) xor логическое ИСКЛЮЧАЮЩЕЕ ИЛИ (сложение по модулю 2) not логическое ОТРИЦАНИЕ (унарная операция) В приведенной ниже таблице показаны значения булевских операций. Операнд A Операнд B not А A and B A or B A xor B true true false true true false true false false false true true false true true false true true false false true false false false Над значениями булевского типа допустимы операции отношения (сравнения), причем считается, что False < True. Поскольку булевский тип является порядковым типом, то для него имеют место следующие отношения: Ord(False) = 0 Ord(True) = 1 Succ(false) = True Pred(true) = False Любая из операций отношения (=, <>, <=, <, >=, >) и операция принадлежности множеству (in) вырабатывают результат булевского типа. Например, 2<5 имеет результат True (истина), а 3<2 имеет результат False (ложь). Помимо стандартных логических операций в языке Паскаль имеется ряд предопределенных логических функций, вырабатывающих булевский результат: Odd(i) true, если целое i – нечетное; false, если i – четное; EoLn(f) true, если достигнут конец строки; false – в противном случае; EoF(f) true, если достигнут конец файла; false – в противном случае. Ниже приведен пример описания двух булевских переменных. Компилятор Турбо-Паскаля, встретив в программе объявление булевской переменной, распределяет для нее один байт памяти. var Switch : Boolean; Empty : Boolean; Ограниченные типы
30 Рассмотренные выше типы данных являются стандартными или предопределенными (т.е. заранее определенными, встроенными в язык Паскаль); их смысл в языке Паскаль фиксирован. На основе стандартных скалярных типов данных программист может определить новые, собственные скалярные типы, руководствуясь несколькими достаточно простыми правилами. Самый простой способ образования новых типов из уже существующих является ограничение (сужение) допустимого диапазона значений некоторого стандартного скалярного типа. Это ограничение определяется заданием минимального и максимального значений диапазона; например: type FromOneToTen = 1..10; { Числа от 1 до 10 } SmallLetter = 'a'..'z'; { Строчные латинские буквы } var Number : FromOneToTen; Letter : SmallLetter; begin Number := 5; Letter := 'c'; ... end. В данном примере показано определение двух новых типов значений. Первый тип с именем FromOneToTen (буквальный перевод “ОтОдногоДоДесяти”) образован путем ограничения диапазона некоторого целого типа (например, типа Byte). Второй тип с именем SmallLetter (буквальный перевод “МалаяБуква”) является производным от символьного типа и образован путем ограничения множества символьных значений. Допускается создание ограниченных типов из дискретных типов, т.е. из всех скалярных типов, кроме вещественных. Ограниченный тип наследует все свойства базового типа (в частности, набор допустимых операций). Перечислимые типы Другим способом для ввода нового типа данных является явное перечисление всех возможных его значений, причем каждое такое значение будет определяться только идентификатором, т.е. именем . Типы данных, образованные таким образом, называются перечислимыми. Поясним такой способ определения нового типа данных на следующем примере. Пусть требуется разработать программу для управления светофором. Ясно, что такая программа должна оперировать с текущим состоянием светофора, т.е. со светом, включенным в данный момент. Таким образом, переменная, моделирующая светофор, может принимать одно из трех значений, соответствующих красному, желтому и зеленому цветам. Можно было бы ввести для этой
31 цели переменную целого типа и установить, что, например, значения 1, 2 и 3 соответствуют указанным цветам. Однако, очевидно, что числа, кодирующие цвета светофора, не имеют прямого отношения к решаемой задаче и, следовательно, усложняют программу и затемняют ее смысл (мы должны всякий раз, когда оперируем с цветом, помнить, что 1 – это красный, 2 – желтый, а 3 – зеленый свет). Более естественным решением в данном случае будет введение перечислимого типа из трех значений, обозначаемых именами Red, Yellow, Green, и переменной этого типа. Например: type Color3 = (Red, Yellow, Green); {Определение перечислимого типа} var Signal : Color3; {Объявление переменной перечислимого типа} Перечислимые типы считаются дискретными типами. Над значениями перечислимых типов определены операции отношения (считается, что значения перечислимого типа указаны в списке в порядке возрастания). Таким образом, можно сказать, что условие Red < Green выполняется, т.е. имеет результат true. Кроме того, допускается образование ограниченных типов из перечислимых. Пусть, например, мы имеем следующее определение перечислимого типа: type DaysOfWeek = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); Тогда мы всегда можем определить такие ограниченные типы, как type WorkingDays = Monday..Friday; { Рабочие дни } FreeDays = Saturday..Sunday; { Выходные дни } Имена из списка перечислимого типа считаются константами соответствующего типа. Эти имена должны быть уникальными в пределах блока, т.е. не допускаются определения двух и более перечислимых типов с совпадающими значениями (константами). Например, наличие в программе двух следующих определений типов: type Color3 = (Red, Yellow, Green); FlagOfRussia = (White, Blue, Red); приведет к выводу сообщения об ошибке во время компиляции программы, так как имя Red присутствует и в первом и во втором определении типа. Вопросы и упражнения для самопроверки 1. Сформулировать определение для такого понятия, как “тип данных”, имея в виду, что тип данных: 1) определяет допустимый диапазон значений; 2) определяет множество простых операций, применимых к значениям данного типа.
32 2. Какие простые типы данных Паскаля относятся к порядковым типам? Дать характеристику порядковым типам данных. 3. Сколько и какие целые типы данных имеются в Турбо-Паскале? Указать допустимый диапазон значений для каждого из целых типов, а также размер ячейки памяти, выделяемый для значения каждого из этих типов. 4. В каких системах счисления могут быть представлены целые числа в программах на Турбо-Паскале? В чем состоит особенность записи целого числа в каждой из этих систем? 5. Какие простые операции допускаются над целыми типами данных? 6. Сколько и какие вещественные типы данных имеются в Турбо-Паскале? Указать допустимый диапазон значений и точность для каждого из вещественных типов, а также размер ячейки памяти, выделяемый для значения каждого из этих типов. 7. Какие формы записи вещественных чисел могут быть использованы в программах на Турбо-Паскале? 8. Что представляет символьный тип данных? Каков диапазон допустимых значений для символьного типа в Турбо-Паскале? 9. Что представляет собой булевский тип данных? Какие операции определены над булевскими данными? 10. Какой способ лежит в основе определения ограниченного типа данных? Какие типы могут выступать в качестве базовых типов при определении ограниченных типов? 11.Какой способ лежит в основе определения перечислимого типа данных? Какие требования предъявляются к именам, представляющим значения перечислимого типа? Лекция 4. Операторы и выражения в языке программирования Паскаль. Оператор присваивания. Операторы стандартных процедур ввода-вывода. Оператор перехода (goto). Условный оператор (if-then-else). Пример программы, использующей условный оператор. Оператор выбора (case-of). Пример программы, использующей оператор выбора. Пример совместного использования операторов if-then-else и case-of. Вопросы и упражнения для самопроверки. Операторы и выражения Для описания действий, выполняемых программой, используются конструкции языка программирования, называемые операторами. Операторы можно разделить на простые, представляющие элементарный шаг алгоритма и не содержащие внутри себя других операторов, и сложные, представляющие комбинацию других операторов и задающие последовательность их выполнения. Операторы второго типа называются также управляющими; управляющие опе-
33 раторы записываются таким образом, что содержат внутри себя другие простые и/или управляющие операторы. В данной лекции мы рассмотрим оператор присваивания, являющийся простым оператором, а также условный оператор (ifthen-else) и оператор выбора (case-of), являющиеся сложными операторами. Выражение состоит из операндов и знаков операций. Операндом может быть константа или имя константы, имя переменной, обращение к функции (т.е. имя функции и, возможно, список фактических параметров функции, заключенный в круглые скобки) или подвыражение (выражение, заключенное в круглые скобки). Выражение задает очередность выполнения операций, основываясь на обычном порядке вычисления слева направо и старшинстве (приоритете) операций. Порядок вычисления выражения может быть изменен путем заключения операций (операндов и знаков операций) в круглые скобки (точно также, как это делается в математике). Ниже приведены примеры выражений и даны необходимые пояснения. 2∗3–4∗5 Это выражение вычисляется как (2∗3) – (4∗5), т.е. сначала выполняется первая (слева) операция умножения, затем – вторая операция умножения и последней выполняется операция вычитания. Значением этого выражения является целое число 14. 15 div 4 ∗ 4 Это выражение вычисляется как (15 div 4) ∗ 4, так как операция целочисленного деления и операция умножения имеют одинаковое старшинство. Таким образом, результатом этого выражения является целое число 12. 80 / 5 ∗ 3 Это выражение вычисляется как (80/5) ∗ 3, т.е. в порядке следования операций деления и умножения. Значение выражения равняется вещественному числу 48.0 (поскольку имеет место операция вещественного деления). sqrt(sqr(2)+7∗3) Это выражение вычисляется следующим образом: сначала целое число 2 возводится в квадрат (функция sqr), затем 7 умножается на 3, после этого выполняется операция сложения и, в заключение, извлекается квадратный корень (функция sqrt). Результатом этого выражения является вещественное число 5.0 (поскольку функция sqrt возвращает вещественный результат). В Турбо-Паскале все операции разбиты на следующие 7 групп: • арифметические операции (+, −, ∗, /, div, mod), выполняющиеся над целыми и вещественными операндами; • побитовые операции (shl, shr, and, or, xor, not), выполняющиеся на уровне битов над целочисленными операндами;
34 • операции отношения (<, <=, =, >=, >, <>, in), выполняющиеся операндами целого, вещественного, символьного, строкового, перечислимого и ограниченного типов; • булевские операции (and, or, xor, not), выполняющиеся булевскими операндами; • строковая операция (+), называемая конкатенацией и предназначенная для соединения двух символьных строк; • операции над множествами (+, −, ∗, in), выполняющаяся над операндами множественного типа (set); • адресные операции (@, ^), использующиеся при работе с адресами данных. В табл. 3 перечислены все эти операции и указано их старшинство. Таблица 3. Операции языка Турбо-Паскаль Операция Приоритет Классификация @, ^, not Первый Унарные операции (получение адреса перемен(высший) ной, косвенная ссылка через указатель, логическое НЕ) Мультипликативные операции (умножение, деле*, /, div, mod, Второй and, shl, shr ние, целочисленное деление, взятие остатка от деления, логическое И, сдвиг битов влево, сдвиг битов вправо) +, - , or, xor Третий Аддитивные операции (сложение, вычитание, логическое ИЛИ, логическое ИСКЛЮЧАЮЩЕЕ ИЛИ) =, <>, <, >, Четвертый Операции отношения (равно, не равно, меньше, <=,>=, in (низший) больше, меньше или равно, больше или равно, содержится в)
Оператор присваивания Одним из основных операторов алгоритмических языков программирования является оператор присваивания. С его помощью переменной можно присвоить некоторое значение. В простейшем виде оператор присваивания записывается в языке Паскаль как имя-переменной := значение где имя-переменной – указывает переменную, которой необходимо присвоить значение, а значение – значение, которым будет обладать переменная после выполнения оператора присваивания. Например, после выполнения следующих операторов присваивания:
35 var Letter : char; Number : integer; begin Number := 10; Letter := 'A'; ... end. в переменной целого типа Number будет содержаться значение 10, а в символьной переменной Letter – символ 'A'. В более общем виде оператор присваивания записывается как имя-переменной := выражение где выражение – выражение, тип которого соответствует типу переменной, обозначаемой как имя-переменной. Примеры операторов присваивания: Number := Number + Ord(Letter); Z := Sin(X) + Cos(Y); Logic := X < Y; Операторы стандартных процедур ввода-вывода В Паскале нет специальных операторов ввода-вывода. Для выполнения операций ввода-вывода в программах на Паскале чаще всего используют операторы стандартных процедур ввода-вывода: Read (читать) – для ввода, Write (писать) – для вывода информации. Оператор процедуры Read имеет следующий вид: read (имя_переменной_1, имя_переменной_2, ...) где имя_переменной_1, имя_переменной_2 и т.д. – имена переменных; в этих переменных будут храниться введенные значения. По умолчанию в качестве стандартного устройства ввода (input) используется клавиатура. Например, оператор процедуры ввода read (Number, Letter) позволяет осуществить ввод двух значений с клавиатуры; их можно ввести в одной строке, отделив друг от друга пробелом, либо в разных строках, заканчивая ввод каждого значения нажатием клавиши Enter. Для вывода используется оператор процедуры Write, который имеет следующий вид: write (выражение_1, выражение_2, ...) где выражение_1, выражение_2 и т.д. – выражения, значения которых необходимо вывести. По умолчанию в качестве стандартного устройства вывода (output) используется экран монитора. Например, оператор процедуры вывода
36 write ( 'Здравствуй, мир! ', Number+1) позволяет осуществить вывод на экран двух значений: строковую константу 'Здравствуй, мир! ' и числовую константу, представляющую сумму текущего содержимого переменной Number и 1. Существует модификация оператора процедуры write, которая записывается в виде writeln (выражение_1, выражение_2, ...) где суффикс "ln" (line new – новая строка) означает, что после вывода значений указанных выражений происходит переход к новой строке вывода. Существует также возможность задавать ширину поля вывода значений, а для вещественных значений и форму вывода: в виде десятичной дроби или в экспоненциальном виде. Ширина поля вывода задается в виде выражения со значением целого типа, которое указывается непосредственно после выводимого значения, т.е. как write (выражение_1: ширина, выражение_2: ширина: дробь, ...) где выражение_1, выражение_2 и т.д. − выражения, значения которых необходимо вывести, ширина и дробь − выражения целого типа, задающие ширину (количество знакомест) для вывода целой и дробной части числа соответственно. Например, в операторе вывода write (X:10, 'N=', N:2∗A, 1Е-5:8:5) под значение переменной X в строке вывода будет отведено 10 позиций; под значение переменной N – число позиций, равное удвоенному значению переменной целого типа A; вещественная константа, записанная в экспоненциальной форме 1E-5, будет выведена в виде десятичной дроби 0.00001. Если выводимое значение не помещается в отведенное для него поле, то ширина поля увеличивается автоматически так, чтобы значение можно было вывести целиком. При этом перед вещественным значением обязательно выводится по крайней мере один пробел (см. пример выше). Оператор перехода (goto) Оператор перехода предназначен для изменения порядка выполнения операторов, записанных в программе на языке Паскаль; он указывает, что дальнейшая работа программы должна продолжаться с оператора, помеченного соответствующей меткой. Оператор перехода имеет следующий вид: goto метка где метка – целое число в диапазоне от 1 до 9999 или имя метки, предварительно указанное в разделе объявления меток (label). Примеры использования операторов goto: program GotoTest; label 100, Loop;
37 begin Loop: goto 100; writeln('Этот оператор не выполнится никогда'); 100: goto Loop end. Условный оператор (if-then-else) Один из способов организации ветвления в программах на языке Паскаль состоит в использовании условных операторов. Условный оператор имеет следующий вид: if условие then оператор_1 else оператор_2 где условие – произвольное выражение, выдающее результат булевского типа (True или False), a оператор_1 и оператор_2 – произвольные операторы языка Паскаль (в том числе это могут быть другие условные операторы). Если выражение, составляющее условие, имеет результат True (истина), выполняется оператор_1, в противном случае – оператор_2. В программах на языке Паскаль можно использовать краткую форму условного оператора: if условие then оператор В этом случае, если условие дает результат True, то выполняется оператор, стоящий после then; иначе – выполняется оператор, следующий за оператором if-then. В качестве оператора, использующегося после фраз then или else в условном операторе, может использоваться составной оператор. Составной оператор предусматривает выполнение входящих в него операторов в порядке их написания. Операторы, образующие составной оператор, заключаются в операторные скобки begin и end, т.е. составной оператор имеет следующий вид: begin оператор_1; оператор_2; ...; оператор_N end или begin оператор_1; оператор_2; ... оператор_N end Ниже приведен пример программы, использующей условные операторы и составные операторы. Пример программы, использующей условный оператор
38 Приведенная ниже программа запрашивает ввод с клавиатуры начальной буквы одной из геометрических фигур – круга (К), прямоугольника (П) или треугольника (Т). В зависимости от сделанного выбора запрашиваются такие данные, как диаметр или длины сторон. По введенным данным вычисляются такие характеристики геометрических фигур, как длина окружности или периметра и площадь. program Geometry_1; label 100, 200; var D : real; { Для хранения диаметра } A, B, C : real; { Для хранения длин сторон } L, S : real; { Для хранения периметра и площади } Choice : char; { Для хранения начальной буквы названия фигуры } begin 100: writeln('Круг (К), Прямоугольник (П), Треугольник (Т)'); writeln('Выход из программы (В)'); write('Фигура? '); read(Choice); if (Choice = 'K') or (Choice = 'к') then begin write('Диаметр? '); read(D); L := Pi * D; { Вычислить длину окружности } S := Pi * Sqr(D)/4; { Вычислить площадь круга } writeln('Длина окружности = ', L); writeln('Площадь круга = ', S) end else if (Choice = 'П') or (Choice = 'п') then begin write('Длина 1-й стороны? '); read(A); write('Длина 2-й стороны? '); read(B); L := 2 * (A+B); { Вычислить длину периметра } S := A * B; { Вычислить площадь прямоугольника } writeln('Длина периметра = ', L); writeln('Площадь прямоугольника = ', S) end else if (Choice = 'Т') or (Choice = 'т') then begin write('Длина 1-й стороны? '); read(A);
39 write('Длина 2-й стороны? '); read(B); write('Длина 3-й стороны? '); read(C); L := A+B+C; { Вычислить длину периметра } writeln('Периметр треугольника = ', L); L := L/2; { Вычислить полупериметр } S := Sqrt(L*(L-A)*(L-B)*(L-C));{ По формуле Герона } writeln('Площадь треугольника = ', S:7:2) end else if (Choice = 'В') or (Choice = 'в') then goto 200 { Выход из программы } else begin writeln('Ошибка: введена неверная буква!'); goto 100 { Повтор } end; 200: end. Оператор выбора (case-of) Другим способом для организации ветвления в программах на Паскале является использование оператора выбора (case-of). Условный оператор удобно использовать, когда производится выбор из двух возможных вариантов работы программы в зависимости от значения булевского выражения, задающего условие. Оператор выбора удобно использовать, когда производится выбор из нескольких вариантов работы программы в зависимости от значения некоторого выражения, называемого селектором. Оператор выбора имеет следующий вид: case селектор of метка_1 : оператор_1; метка_2 : оператор_2; ... ... метка_N : оператор_N else оператор end где селектор – произвольное выражение, вырабатывающее значение целого, символьного или булевского типа, по которому производится выбор одного из вариантов вычислений; метка_1, метка_2, ..., метка_N – метки, представленные константами того же типа, что и селектор (эти метки не нужно перечислять в разделе label); оператор_1, оператор_2, ..., операторN – произвольные операторы языка Паскаль.
40 Оператор выбора выполняется следующим образом. Сначала вычисляется значение селектора, которое должно совпадать со значением одной из констант, использующихся в качестве меток. Затем выполняется оператор, помеченный меткой, значение которой совпало со значением селектора. Если значение селектора не совпадает ни с одной из представленных меток, то выполняется вариант else (иначе) − оператор; этот вариант не является обязательным и может быть опущен в записи оператора case-of. Оператор case-of заканчивается ключевым словом end (без соответствующего begin), сигнализирующим компилятору об окончании списка возможных вариантов. Ниже приведен пример программы, использующей оператор выбора. Эта программа решает ту же задачу, что и приведенная выше программа Geometry_1, использующая операторы if-then-else. Пример программы, использующей оператор выбора (case-of) program Geometry_2; label 100; var D : real; { Для хранения диаметра } A, B, C : real; { Для хранения длин сторон } L, S : real; { Для хранения длины периметра и площади } Choice : char; { Для хранения начальной буквы названия фигуры } begin 100: writeln('Круг (К), Прямоугольник (П), Треугольник (Т)'); writeln('Выход из программы (В)'); write('Фигура? '); read(Choice); case Choice of 'K', 'к': begin write('Диаметр? '); read(D); L := Pi * D; { Длина окружности } S := Pi * Sqr(D)/4; { Площадь круга } writeln('Длина окружности = ', L); writeln('Площадь круга = ', S) end 'П','п': begin write('Длина 1-й стороны? '); read(A); write('Длина 2-й стороны? ');
41 read(B); L := 2*(A+B); { Длина периметра прямоугольника } S := A * B; { Площадь прямоугольника } writeln('Длина периметра = ', L); writeln('Площадь прямоугольника = ', S) end 'Т','т': begin write('Длина 1-й стороны? '); read(A); write('Длина 2-й стороны? '); read(B); write('Длина 3-й стороны? '); read(C); L := A+B+C; { Длина периметра } writeln('Длина периметра = ', L); L := L / 2; { Полупериметр } S := Sqrt(L*(L-A)*(L-B)*(L-C));{ По ф-ле Герона} writeln('Площадь треугольника = ', S:7:2) end 'В','в': exit; { Функция Турбо-Паскаля для выхода из программы } else writeln('Ошибка: введена неверная буква!') end; {case} goto 100 { Повтор } end. Пример совместного использования операторов if-then-else и case-of Ниже приведена программа, которая запрашивает ввод натурального числа, не превышающего 99, и выводит на экран запись этого числа в римской системе счисления. program Roman; var N : integer; begin write('Натуральное число (1 <= N <=99)? '); read(N); if (N < 1) or (N > 99) then write('Ошибка: неверно задано исходное число N=', N); else begin writeln(N, '- арабскими цифрами'); case N div 10 of { выбор по числу десятков }
42 0 : ; {пустой оператор} 5 : write ('L'); 1 : write ('X'); 6 : write ('LX'); 2 : write ('XX'); 7 : write ('LXX'); 3 : write ('XXX'); 8 : write ('LXXX'); 4 : write ('XL'); 9 : write ('XC') end; {End of case} { Выведены буквы для обозначения числа десятков } case N mod 10 of { выбор по числу единиц } 0 : ; {пустой оператор} 5 : write ('V'); 1 : write ('I'); 6 : write ('VI'); 2 : write ('II'); 7 : write ('VII'); 3 : write ('III'); 8 : write ('VIII'); 4 : write ('IV'); 9 : write ('IX') end; {End of case} { Выведены буквы для обозначения числа единиц } writeln(' - римскими цифрами') end end. Вопросы и упражнения для самопроверки 1. В чем различие между объявлениями (описаниями) и операторами программы? 2. На какие две группы можно разделить все операторы языка Паскаль? Привести примеры операторов первой и второй группы? 3. Что понимается под типом выражения? Выражения каких типов могут быть использованы в программе на языке Паскаль? 4. Чем определяется порядок выполнения операций в выражении? Каким образом можно изменить обычный порядок выполнения операций? 5. Перечислить все операции языка Турбо-Паскаль в порядке понижения их старшинства. 6. Что произойдет в результате выполнения следующего оператора присваивания: A := A+1? 7. Написать короткую программу для ввода с клавиатуры трех значений: целого, вещественного и символьного. Какие средства языка Паскаль при этом необходимо задействовать? 8. Написать короткую программу для вывода на экран следующий значений: результата сложения 25 и 75, результата деления 25 на 75, символьной строки “Программирование - основной раздел информатики”. 9. Для каких целей можно использовать условный оператор (if-then-else)? Что представляет собой вложенный условный оператор? Привести примеры условных и вложенных условных операторов.
43 10. В чем заключается различие между условным оператором (if-then-else) и оператором выбора (case-of)? В каких случаях предпочтительнее использовать оператор выбора, а не условный оператор? Лекция 5. Повторяющиеся вычисления в программах на языке Паскаль: оператор цикла с предусловием (while), оператор цикла с постусловием (repeat-until), оператор цикла с параметром (for). Примеры программ, использующих операторы while, repeat-until и for. Эмуляция операторов цикла с помощью операторов if-then и goto. Вопросы и упражнения для самопроверки. Повторяющиеся вычисления Один из характерных приемов программирования заключается в организации многократного (повторяющегося) выполнения некоторой последовательности операторов (команд), записанных в программе только один раз. В языках программирования высокого уровня для этой цели определены специальные конструкции, называемые операторами цикла. В языке программирования Паскаль имеются три разновидности операторов цикла: оператор цикла с предусловием (while), оператор цикла с постусловием (repeat-until) и оператор цикла с параметром (оператор for). Оператор цикла с предусловием (while) Повторяющееся выполнение операторов можно организовать, использовав оператор цикла с предусловием, который имеет следующий вид: while условие do оператор где условие – выражение булевского типа, управляющее повторным выполнением оператора. Это выражение вычисляется при каждой итерации, поэтому его рекомендуется делать простым насколько это возможно. Оператор, образующий так называемое тело цикла, может быть любым оператором языка Паскаль (простым, составным или управляющим). Выполнение оператора цикла с предусловием состоит из следующих шагов: 1. Вычисляется значение выражения, образующего условие цикла. 2. Если значением выражения, образующего условие цикла, является "ложь" (False), то выполнение цикла завершается; в противном случае – осуществляется переход к шагу 3. 3. Выполняется оператор и осуществляется переход на шаг 1. При выполнении тела цикла должны создаваться условия для изменения значения выражения, составляющего условие цикла. Иначе возникает ситуация "зацикливания" программы или "бесконечного" цикла.
44 Выполнение цикла с предусловием можно проиллюстрировать с помощью следующей блок-схемы:
Условие
False
True Оператор
Пример программы, использующей оператор while Задача. Написать программу для вычисления значения функции F=2N, где N – натуральное число, вводимое с клавиатуры. Так как в Паскале отсутствует функция возведения числа в произвольную целую степень, получим значение F постепенно, накапливая в переменной F значения степеней двойки: 20, 21, 22 и т.д. вплоть до 2N. Текст программы, вычисляющей функцию F, приведен ниже. program Degree_2; var i, F, N : integer; begin read(N); F := 1; i := 0; while i <> N do begin i := i + 1; F := F * 2 end; writeln(F) end. До цикла значение переменной i равно 0. В условии цикла проверяется, что текущее значение переменной не равно N. При каждом выполнении тела цикла значение переменной i увеличивается на 1, т.е. рано или поздно, но возникнет ситуация, когда i=N и цикл прекратит свою работу.
45 Пример программы, эмулирующей цикл while Цикл с предусловием достаточно просто эмулируется (имитируется) с помощью условного оператора (if-then) и оператора перехода (goto). Ниже приведена программа, текстуально отличная от разобранной выше, но функционально ей эквивалентная. program Degree_2; label Loop; var i, N, F : integer; begin read(N); F := 1; i := 0; Loop: if i <> N then begin i := i + 1; F := F * 2; goto Loop end; writeln(F) end. Оператор цикла с постусловием (repeat-until) Для записи повторяющихся действий в программе можно использовать оператор цикла с постусловием, имеющий следующий вид: repeat оператор until условие где оператор – один или несколько операторов языка Паскаль. Если используются несколько операторов, они отделяются друг от друга с помощью символа “точка с запятой” (;). Эти операторы, называемые телом цикла, могут не заключаться в операторные скобки begin и end; роль последних выполняют зарезервированные слова repeat и until. Условие – выражение, результатом которого является булевское значение; оно управляет повторным выполнением "тела цикла". Выполнение оператора цикла с постусловием состоит из следующих шагов: 1. Выполняется последовательность операторов, заключенная между repeat и until. 2. Вычисляется значение выражения, задающего условие окончания для цикла.
46 3. Если значением выражения условие является “истина” (True), то выполнение цикла заканчивается. Если же значением выражения условие является “ложь” (False), то повторяется последовательность шагов, начиная с шага 1. Выполнение оператора цикла с постусловием можно проиллюстрировать следующей блок-схемой:
Оператор
Условие
False
True Следует отметить, что “тело цикла” в случае оператора цикла с постусловием выполняется, по крайней мере, один раз. При этом в “теле цикла” должны создаваться “предпосылки” для того, чтобы рано или поздно условие было удовлетворено, в противном случае будет иметь место "бесконечный" цикл. Пример программы, использующей оператор repeat-until Задача. Написать программу для вычисления частичной суммы ряда Sn=1+1/2+1/3+...+1/n, где n – натуральное число, вводимое с клавиатуры. Эта задача уже однажды нами решалась с использованием оператора for (см. лекцию 2); сейчас же в программе мы будем использовать оператор repeatuntil. program Summa; var n : integer; S : real; begin write(‘Количество членов ряда? ’); read(n); S := 0; repeat S := S + 1/n;
47 n := n - 1 until n = 0; writeln(S) end. Пример программы, эмулирующей цикл repeat-until Цикл с постусловием (repeat-until) достаточно просто эмулируется с помощью условного оператора (if-then-else) и оператора перехода (goto). Ниже приведена программа, текстуально отличная от разобранной выше, но функционально ей идентичная. program Summa; label Loop; var n : integer; S : real; begin read(n); S := 0; Loop: begin S := S + 1/n; n := n - 1 end; if n = 0 then writeln(S) else goto Loop end. Оператор цикла с параметром (for) Если требуется выполнить некоторый оператор заданное число раз, причем число повторений не зависит от результата работы оператора, лучше всего воспользоваться оператором цикла с параметром, имеющим следующий вид: for параметр-цикла := начальное-значение to конечное-значение do оператор или for параметр-цикла := начальное-значение downto конечное-значение do оператор
48 где параметр-цикла – имя управляющей переменной цикла, называемой также параметром цикла; начальное-значение и конечное-значение – выражения, задающие диапазон изменения для параметра цикла; оператор – оператор, называемый телом цикла; to – определяет в качестве шага изменения параметра цикла значение 1; downto – определяет в качестве шага изменения параметра цикла значение -1. Параметр цикла, начальное и конечное значение должны быть одного и того же порядкового типа. Начальное и конечное значения вычисляются лишь один раз. Выполнение цикла с параметром происходит следующим образом: 1. Вычисляются выражения начальное-значение и конечное-значение и начальное значение присваивается параметру цикла. 2. Если для цикла for с to (downto) текущее значение параметра цикла больше (меньше) конечного значения, то тело цикла не выполняется. В противном случае − выполняется тело цикла. 3. Значение параметра цикла увеличивается (уменьшается) на 1 и выполняется переход на шаг 2. При выходе из цикла значение параметра цикла остается неопределенным. Пример программы, использующей оператор цикла for Задача. Написать программу для вычисления частичной суммы ряда Sn=1+1/2+1/3+...+1/n, где n – натуральное число, вводимое с клавиатуры. program Summa; var i, n : integer; S : real; begin write(‘Количество членов ряда? ‘); read(n); S := 0; for i := n downto 1 do S := S + 1/i; writeln(S) end. Пример программы, эмулирующей цикл for Оператор цикла с параметром вида for v := e1 to e2 do S эквивалентен следующей последовательности операторов: if e1 <= e2 then
49 begin v := e1; S; v := succ(v); S; . . .; v := e2; S end { В этой точке значение v не определено } Оператор цикла с параметром вида for v := e1 downto e2 do S эквивалентен следующей последовательности операторов: if e1 >= e2 then begin v := e1; S; v := pred(v); S; . . .; v := e2; S end { В этой точке значение v не определено } Задача. Написать программу для вычисления частичной суммы ряда Sn=1+1/2+1/3+...+1/n, где n – натуральное число, вводимое с клавиатуры. Цикл, вычисляющий частичную сумму ряда, эмулировать с помощью операторов ifthen-else и goto. program Summa; label Loop, OutLoop; var i, n : integer; S : real; begin write(‘Количество членов ряда? ‘); read(n); i := n; Loop: if i >= 1 then begin
50 S := S + 1/i; i := i - 1 end else begin writeln(S); goto OutLoop end; goto Loop; OutLoop: end. Вопросы и упражнения для самопроверки 1. Какие операторы в языке программирования Паскаль используются для организации многократного выполнения одной и той же последовательности действий? 2. Какие операторы цикла имеются в Паскале? Каков синтаксис этих операторов? В чем принципиальные различия этих операторов цикла? 3. Можно ли при написании программ на Паскале обойтись без операторов цикла? С помощью каких операторов языка Паскаль можно смоделировать циклическое выполнение операторов? Привести примеры. 4. Написать программу для вычисления отдельно суммы положительных и суммы отрицательных чисел для любых 20 введенных с клавиатуры вещественных чисел, используя а) оператор цикла while; б) оператор цикла repeat; в) оператор цикла for. 5. Написать программу для подсчета четных и нечетных чисел среди любых 20 введенных с клавиатуры целых чисел, используя булевскую функцию Odd, возвращающую True в случае нечетного параметра, и а) оператор цикла while; б) оператор цикла repeat; в) оператор цикла for. 6. Написать программу для вычисления функции F(N) = N!, где N − натуральное число, вводимое с клавиатуры, с использованием а) оператора цикла while; б) оператора цикла repeat; в) оператора цикла for. 7. Определить значение переменной S после выполнения следующих операторов: a) S := 0; i := 0; while i < 5 do i := i + 1; S := S + 1/i; б) S := 0; i := 1; while i > 1 do begin S := S + 1/i; i := i - 1 end; в) S := 0; i := 1; repeat S := S + 1/i; i := i - 1 until i <= 1; г) S := 0; n := 1; for i := 2 downto n do S := S + 1/i;
51 8. Написать программу для вывода на экран монитора всех “ счастливых” номеров из диапазона от 100000 до 999999 и подсчета их количества. “Счастливым” считать номер, у которого сумма первых трех цифр равна сумме последних трех цифр. Для выделения из очередного числа диапазона нужных групп цифр использовать операции div и mod. Содержание Введение.
3
Лекция 1. Этапы решения задач на ЭВМ. Понятие алгоритма. Свойства и способы описания алгоритмов. Общее знакомство с языком программирования Паскаль. Структура типичной программы на языке Паскаль. Список литературы. Вопросы и упражнения для самопроверки.
3
Лекция 2. Алфавит языка Турбо-Паскаль версии 6.0. Лексемы и разделители. Использование метаязыков для описания синтаксиса языков программирования: расширенные формы Бэкуса-Наура и синтаксические диаграммы Вирта. Система типов данных языка Турбо-Паскаль. Вопросы и упражнения для самопроверки.
14
Лекция 3. Простые типы данных: целый, вещественный, символьный, булевский, ограниченный и перечислимый типы. Примеры программ, использующих простые типы данных. Вопросы и упражнения для самопроверки.
22
Лекция 4. Операторы и выражения в языке Паскаль. Оператор присваивания. Операторы стандартных процедур ввода-вывода. Оператор перехода (goto). Условный оператор (if-then-else). Пример программы, использующей условный оператор. Оператор выбора (case-of). Пример программы, использующей оператор выбора. Пример совместного использования операторов if-then-else и case-of. Вопросы и упражнения для самопроверки.
32
Лекция 5. Повторяющиеся вычисления в программах на языке Паскаль: оператор цикла с предусловием (while), оператор цикла с постусловием (repeat-until), оператор цикла с параметром (for). Примеры программ, использующих операторы while, repeat-until и for. Эмуляция операторов цикла с помощью операторов if-then и goto. Вопросы и упражнения для самопроверки.
42
Стариков Александр Вениаминович
ИНФОРМАТИКА. Основы программирования на языке Паскаль. Тексты лекций в 3-х частях. Часть 1
Редактор А.В. Гладких
Подписано в печать Форм. бум. 297×420, 1/16. Бум. ZOOM. Усл. п. л. Уч.-изд. л. Тираж Заказ № РИО ВГЛТА. УОП ВГЛТА. 394613, г. Воронеж, ул. Тимирязева, 8.