- •Программирование и алгоритмические языки
- •Основные понятия процедурного программирования. Области и процедуры
- •Способы обозначения и определения процедур
- •Языки блок-схем
- •Трассировка программы
- •Структурное программирование
- •Программы, как файловые процедуры
- •Итерационные и рекуррентные последовательности
- •Восходящее и нисходящее программирование
- •Язык программирования Pascal
- •Процедурный Паскаль Синтаксис Паскаль-программы
- •Основные операторы
- •Классификация типов Простые (скалярные) типы
- •Стандартные типы
- •Пользовательские скалярные типы данных
- •Алгоритмическое определение булевских операций
- •Стратегия вычисления условий
- •Вычисление кванторов
- •Символьный тип
- •Производные(структурные) типы Массивы
- •Операции над массивами
- •Расширенный синтаксис. Массивы размерности n.
- •Строки. Динамические массивы.
- •Комбинированные типы и записи
- •Оператор присоединения
- •Типизированные файлы.
- •Упорядоченные файлы
- •Поиск в упорядоченном файле
- •Арифметика упорядоченных файлов
- •Дихотомический поиск в упорядоченном массиве
- •Простые алгоритмы сортировки
- •Множества
- •Операции над множествами
- •Решето Эратосфена
- •Подпрограммы. Пользовательские процедуры и функции
- •Синтаксис обращения к процедурам
- •Синтаксис использования или обращения к процедурам.
- •Семантика
- •Правила построения модифицированного тела:
- •Пользовательские процедуры (продолжение)
- •Подпрограммы и функции
- •Описание функции
- •Обращение к функции
Язык программирования Pascal
Язык создал швейцарский теоретик программирования Н.Вирт. Назван он был в честь известного французского математика и физика Б.Паскаля, создавшего первый арифмометр. Язык четко ориентирован на структурное программирование, технологию нисходящего программирования и концепцию типа данных – в целом, на разработку логичных, следовательно надежных, пусть и не сверх эффективных в вычислительном смысле программ. Создавался как учебный язык, но быстро стал популярен, как язык профессионального программирования. Существуют многочисленные версии языка, особенно широко известны продукты фирмы Borland Enterprise – Turbo Pascal, Delphi …
Наша цель – изучение основных концепций программирования, а не конкретных версий языка. Мы ограничимся стандартом языка, а также теми дополнениями языка Turbo и Object Pascal, которые:
исправляют немногочисленные недочеты стандарта;
отмечают наиболее существенные концептуальные изменения, произошедшие в программировании со времен создания стандарта.
Процедурный Паскаль Синтаксис Паскаль-программы
Программа – это функция, <потоковая / файловая процедура>.
Заголовок программы
[Program пользовательское имя (список файлов);]
В Turbo и Object заголовок может опускаться
[Uses список имен модулей-описаний дополнительных объектов, используемых в данной программе]
{$ директивы компилятора}
Дополнительное указание, делающее семантику языка полной и/или не двусмысленной.
(Не именованный) Блок состоящий из:
областей описаний пользовательских имен;
собственно запись алгоритма в виде составного оператора – последовательности операторов языка, соединенных символом «;» и заключенных в операторные скобки BEGIN…END и «.»
Pascal-программа содержит имена двух видов:
Пользовательские имена – термины, значения которых выбираются (определяются) программистом в соответствующей области описания.
Ключевые слова языка, смысл которых фиксирован и не может быть изменен.
В любом случае в качестве имен используются идентификаторы – последовательности латинских букв и цифр, начинающиеся с буквы. Допустимая длина идентификатора определяется конкретной версией языка (в Object Pascal до 255 символов).
Все пользовательские имена должны быть явно определены в программе. Стандартный порядок описания пользовательских имен:
Label – список имен меток оператора GoTo
Const
имя константы = значение константы (или выражение);
MaxIndex = 100;
Pi = 3,14159;
Type – область описания типов
имя типа = определение типа;
Var – область описания переменных
список переменных: тип;
x: real;
n1: integer;
Область определения процедур и функций.
Для пользовательских имен справедливо классическое правило прямых определений – имя можно использовать только после того, как оно описано.
Есть интересное исключение, выводящее Паскаль из чисто процедурных языков – смотри «ссылочные типы и рекурсия».
Основные операторы
Оператор присваивания
V:=Exp
где V – переменная, а Exp – выражение.
Типы V и Exp должны быть согласованы. Как правило, это означает, что это одни и те же типы. С точки зрения семантики достаточно, чтобы тип выражения Exp был подтипом тип переменной V.
целый := вещественный – невозможно
вещественный := целый – возможно
К сожалению, реальное определение согласованности типов достаточно сложно и ориентировано не на значения и даже не на определения типов, а на их имена.
Type
Real1 = Real;
Real2 = Real;
Совет
Применяй явное преобразование типов в каждом сомнительном случае.
Операторы ввода/вывода. Текстовые файлы.
В Паскале под файлом понимается последовательный набор данных с возможностью многократного использования.
Рассмотрим частный случай текстовых файлов
text (textfile)
Имена файлов, как и имена любых других переменных, обязаны быть описаны в области Var.
Var f: text;
По стандарту все внешние входные и выходные файлы должны быть перечислены также в заголовке программы.
Семантика (упрощенная)
Множество значений типа text – последовательность значений стандартных типов integer, real, char, string.
Функции и операторы
assign (AssignFile) – в стандарте отсутствует
В реальном программировании естественно разделять понятия логического файла (файл как математический объект, тип данных) и физического файла (файл как набор данных на материальном носителе). Функция assign задает соответствие между логическими и физическими именами.
Assign(логическое имя файла (идентификатор, имя переменной), физическое имя файла (имя файла в синтаксисе ОС))
Пример:
Assign(f,’c:\dir\file.txt’);
Eof(f); Предикат конца файла. Семантика такая же, как и потоков.
Read(f, v1, …, vn); Write(f, e1, …, em); Семантика как для потоков.
Reset(f);
Подготовка (открытие) файла для чтения. Любой оператор reset предшествует любому read, то есть попытке чтения из файла f. Потоки Input и Output – не файлы, так как нельзя многократно записывать.
Rewrite(f);
Подготовка к режиму записи, обязан предшествовать оператору write, то есть любой попытке записи в файл f.
Операторы reset и rewrite опускаются для так называемых входных и выходных файлов input и output. Имена этих файлов также опускаются в операторах чтения и записи.
close(f) (CloseFile(f))
Обратный по функции оператору assign, разрывает связь между логическим и физическим файлами. Хотя по умолчанию все файлы должны автоматически закрываться после выполнения программы, лучше делать это явно.
Замечание:
Как подсказывает название, множеством значений типа text в реальности является последовательность символов произвольной конечной длины, в том числе специальных символов, так называемых маркеров конца строки и конца файла. При чтении и записи текстовых файлов происходит неявное преобразование последовательности символов в значения нужного типа. Очевидно, для этого необходимо, чтобы последовательность символов могла служить обозначением константы нужного типа.
Натуральные числа: c1…cn
ci = ‘0’,’1’,…
Вещественные числа: c1…cn.d1…dm – запись с «плавающей» точкой.
DEP – экспоненциальная запись, где D – запись с «плавающей» точкой, P – целое число. DEP = D•10P
С понятием строки связаны операторы: readln(f) – найти начало следующей строки, writeln(f) – записать символ конца строки.
readln(f, x1, …, xn) read(f, x1, …, xn); readln(f);
writeln(f, e1, …, en) write(f, e1, …, en); writeln(f);
Композиция операторов и составной оператор
S1; S2; …; Sn
Суперпозиция соответствующих функций → функциональная семантика.
begin S1; …, Sn end
также композиция функций, но синтаксически представляет собой один оператор.
последовательность операторов S1; S2; …; Sn
один оператор begin S1; S2; …; Sn end
Условный оператор
If B then S1 [else S2]
Наличие укороченной формы вносит неоднозначность в чтение операторов. Какую семантику имеет оператор If B1 then B2 then S1 else S2
В ерна вторая семантика, то есть else всегда принадлежит ближайшему оператору if.
Оператор цикла с предусловием
while B do S
B – предикат (условие выполнения)
S – оператор
Оператор цикла с постусловием
repeat S1; …; Sn until B
B – предикат (условие окончания)
Введение такого оператора часто удобно, но избыточно. Запись на паскале структурных блок-схем почти тривиальная задача. Единственная техническая проблема – записать последовательность операторов там где синтаксис допускает лишь один оператор. Проблема решается просто – навешиванием операторных скобок.
Задача: выяснить, есть ли в последовательности целых чисел а заданное х.
Решение верно, но не эффективно.
Второй вариант – так называемый побочный выход из цикла.
Третий вариант.
Program N1(input, output);
Var p,b:Boolean;
x,a:integer;
begin
b:=false;
read(x);
while eof=false do
begin
read(a);
if x=a then b:=true;
end;
write(b);
end.
Замечание. Более эффективное решение – см. далее «Булевский тип»