Паскаль (язык программирования)
Паскаль | |
---|---|
Класс языка | императивный,структурированный |
Тип исполнения | компилируемый |
Появился в | 1970 |
Автор | Никлаус Вирт |
Расширениефайлов |
.pas для файлов кода,.inc длязаголовочных файлов. |
Выпуск | ISO/IEC 10206:1991 Stage: 90.93 (29 июля2008 года) |
Система типов | статическая,сильная,безопасная[1] |
Основные реализации | CDC 6000,ICT 1900,Pascal-P,PDP-11,PDP-10,IBM System/370,HP,Free Pascal,GNU,PascalABC.NET |
Диалекты | UCSD,Turbo,Delphi |
Испытал влияние | Алгол |
Повлиял на | Модула-2,Оберон,Компонентный Паскаль,Ада,Object Pascal,Java[2][3][4],Oxygene |
Сайт | iso.org/standard/18237.h… |
Медиафайлы на Викискладе |
Паска́ль(англ.Pascal) — один из наиболее известных языков программирования[5],используется для обучения программированию в старших классах и на первых курсах вузов, является основой для ряда других языков.
История
[править|править код]Язык программирования Pascal был создан в 1970 году на основе языкаАлгол-60[6].
Pascal создавалсяНиклаусом Виртомв 1968—1969 годах после его участия в работе комитета разработки стандарта языкаАлгол-68.Язык назван в честь французского математика, физика, литератора и философаБлеза Паскаля,который создал одну из первых в мире механических машин,складывающую два числа.Первая публикация Вирта о языке датирована 1970 годом; представляя язык, автор в качестве цели его создания указывал построение небольшого и эффективного языка, способствующего хорошему стилю программирования, использующемуструктурное программированиеи структурированные данные.[источник не указан 918 дней]
Последующая работа Вирта была направлена на создание на основе Паскаля языка системного программирования с сохранением возможности вести на его базе систематический, целостный курс обучения профессиональному программированию: «The guiding idea was to construct a genuine successor of Pascal meeting the requirements of system engineering, yet also to satisfy my teacher’s urge to present a systematic, consistent, appealing, and teachable framework for professional programming.». Результатом этой работы стал языкМодула-2,после которого Вирт занялся разработкой объектно-ориентированного языка программированияOberonна основе всех предыдущих разработок[6].
Одной из целей создания языка Паскаль Никлаус Вирт считал обучение студентов структурному программированию. До сих пор Паскаль заслуженно считается одним из лучших языков для начального обучения программированию. Его современные модификации, такие как Object Pascal, широко используются в коммерческом программировании (среда Delphi). Также на основе синтаксиса языка Паскаль создан язык программированияStructured Text(ST) или Structured Control Language (SCL) дляпрограммируемых логических контроллеров.[источник не указан 918 дней]
К 1990-м годам Pascal стал одним из наиболее распространённых в мире алгоритмических языков программирования. Ведущие разработчики программного обеспечения регулярно выпускали новые версии своих компиляторов для этого языка. Популярные компиляторы того времени: Turbo Pascal (разработан компаниейBorland), Microsoft Pascal Compiler, Quick Pascal, Pascal-2, Professional Pascal, USCD Pascal[7].
Реализации и диалекты
[править|править код]Язык Pascal имеет много реализаций[8].
UCSD Pascal
[править|править код]В 1978 году вКалифорнийском университете в Сан-Диегобыла разработана система UCSD p-System, включавшаяпорткомпилятора Вирта с языка Паскаль в переносимыйp-код,редактор исходных кодов, файловую систему и прочее[9],а также реализовывавшая значительное число расширений языка Паскаль, такие как модули, строки символов переменной длины, директивы трансляции, обработка ошибок ввода-вывода, обращение к файлам по именам и другое. Впоследствии основные реализации языка Паскаль основывались на этом диалекте.
Object Pascal
[править|править код]В1986 годуфирмаAppleразработалаобъектноерасширение языка Паскаль, получив в результатеObject Pascal.Он был разработан группойЛарри Теслера,который консультировался сНиклаусом Виртом.
Turbo Pascal и Object Pascal
[править|править код]В1983 годупоявилась первая версияинтегрированной среды разработкиTurbo Pascal фирмыBorland,основывавшаяся на одноимённой реализации Паскаля.
В1989 годуобъектное расширение языка было добавлено в Turbo Pascal версии 5.5.
Последняя версия (7.0) была переименована в Borland Pascal.
Объектные средства были позаимствованы из Object Pascal от Apple, языковые различия между объектным Turbo Pascal 5.5 и Object Pascal от Apple крайне незначительны.
Почти в то же самое время, что и Borland,Microsoftвыпустил свою версию объектно-ориентированного языка Паскаль.[10][11]Эта версия Паскаля не получила широкого распространения.
Дальнейшее развитие реализации Паскаля от Borland породило вариантObject Pascalот Borland, впоследствии, в ходе развития среды программированияDelphi,получившийодноимённое название.
MidletPascal
[править|править код]Современные реализации Pascal
[править|править код]Free Pascal и GNU Pascal
[править|править код]Важным шагом в развитии языка является появление свободных реализаций языка ПаскальFree PascalиGNU Pascal,которые не только вобрали в себя черты множества других диалектов языка, но и обеспечили чрезвычайно широкую переносимость написанных на нём программ (например GNU Pascal поддерживает более 20 различных платформ, под более чем 10 различными операционными системами, Free Pascal обеспечивает специальные режимы совместимости с различными распространёнными диалектами языка, такими как Turbo Pascal (полная совместимость), Delphi и другими).
Delphi и Delphi.NET
[править|править код]Delphi- реализация языка Object Pascal, используемая в среде разработкиEmbarcadero Delphi.Delphi.NET - реализация языка Delphi, ориентированная на разработку приложений для платформыMicrosoft.Net.
PascalABC.NET
[править|править код]BЮжном федеральном университетеразработанPascalABC.NET— язык программирования Паскаль, включающий большинство возможностей языкаDelphi,а также ряд собственных расширений. Он основан на платформеMicrosoft.NETи содержит практически все современные языковые средства:классы,перегрузку операций,интерфейсы,обработку исключений,обобщённые классы и подпрограммы,сборку мусора,лямбда-выражения.
Pascal Next
[править|править код]Pascal Next – компилируемый, типизированный, алгоритмический, универсальный язык программирования и среда разработки, ориентированные на решение задачиобучения основам программирования. В основе синтаксиса языка Pascal Next лежит синтаксис "классического" Паскаля Вирта. В то же время, синтаксис инструкций выбора и циклов заимствован из Basic, что позволило отказаться от избыточных begin.
Особенности языка
[править|править код]Особенностями языка являютсястрогая типизацияи наличие средствструктурного (процедурного) программирования.Паскаль был одним из первых таких языков. По мнению Вирта, язык должен способствовать дисциплинированному программированию, поэтому, наряду со строгой типизацией, в Паскале сведены к минимуму возможные синтаксические неоднозначности, а сам синтаксис автор постарался сделать интуитивно понятным даже при первом знакомстве с языком.
Тем не менее, первоначально язык имел ряд ограничений: невозможность передачи функцияммассивовпеременной длины, отсутствие нормальных средств работы сдинамической памятью,ограниченнаябиблиотека ввода-вывода,отсутствие средств для подключения функций, написанных на других языках, отсутствие средств раздельной компиляции и т. п. Подробный разбор недостатков языка Паскаль того времени был выполненБрайаном Керниганомв статье «Почему Паскаль не является моим любимым языком программирования»[12](эта статья вышла в начале 1980-х, когда уже существовал языкМодула-2,потомок Паскаля, избавленный от большинства его пороков, а также более развитые диалекты Паскаля). Некоторые недостатки Паскаля были исправлены в ISO-стандарте 1982 года, в частности, в языке появились открытые массивы, давшие возможность использовать одни и те же процедуры для обработки одномерных массивов различных размеров.
Однако многие недостатки языка не проявляются или даже становятся достоинствами при обучении программированию. Кроме того, по сравнению с основным языком программирования в академической среде1970-х(которым былФортран,обладавший гораздо более существенными недостатками), Паскаль представлял собой значительный шаг вперёд. К 1980-м годам Паскаль стал основой для многочисленных учебных программ, в отдельных случаях на его основе были созданы специализированные обучающие языки программирования, так, в начале 1980-х годов в СССР для обучения школьников основам информатики и вычислительной техникиАндрей Ершовразработал алголо-паскалеподобный «учебный алгоритмический язык».
Наиболее известной реализацией Паскаля, обеспечившей широкое распространение и развитие языка, является Turbo Pascal фирмыBorland,выросшая затем в объектный Паскаль для DOS (начиная с версии 5.5) и Windows и далее в Delphi, в которой были внедрены значительные расширения языка.
Стандарты
[править|править код]После начала использования Паскаля в1970 годуи появления реализаций, расходящихся не только в дополнениях, но и в синтаксисе, был поднят вопрос о стандартизации языка. Стандарт языка был разработан Никлаусом Виртом в1974 годусовместно с Кетлин Йенсен (Kathleen Jensen).[13]В дальнейшем были приняты международный стандарт ISO и американский ANSI. На данный момент выделяют три принципиально разных стандарта: Unextended Pascal (исходный), Extended Pascal (расширенный), Object-Oriented Extensions to Pascal (объектно-ориентированное расширение Паскаля).
Название | Вариант | Кем/где разработан | Год создания |
---|---|---|---|
Pascal Standard | исходный | Н. Вирт, Кетлин Йенсен | 1974 |
Pascal Standard | исходный | ISO 7185:1983 ANSI/IEEE770X3.97:1983 |
1982 |
Unextended Pascal | исходный | ISO 7185:1990 | 1989 |
Extended Pascal | расширенный | ANSI/IEEE 770X3.160:1989 | 1989 |
ISO/IEC10206 | 1991 | ||
Object-Oriented Extensions to Pascal[14] |
объектно-ориентированное расширение | ANSI/X3-TR-13:1994 | 1993 |
Одним из главных дополнительных свойств объектно-ориентированного расширения Extended Pascal стала модульность и средства, облегчающие раздельную компиляцию.
Стандартизация языка была запаздывающей по отношению к реальному появлению в языке тех или иных возможностей. Коммерческие реализации расширяли стандартный Паскаль; так было сделано в UCSD Pascal, модификацииObject Pascalфирмой Apple, Turbo Pascal от Borland (незначительно модифицированная версия Apple) и его ответвлений. Ни одна из распространённых коммерческих реализаций Паскаля не соответствует в точности ни одному из официальных стандартов языка.
Синтаксис и языковые конструкции
[править|править код]Паскаль, в его первоначальном виде, представляет собою чистопроцедурный языки включает в себя множество алголоподобных структур и конструкций с зарезервированными словами наподобиеif
,then
,else
,while
,for
,repeat
и т. д. Тем не менее, Паскаль также содержит большое количество возможностей для структурирования информации и абстракций, которые отсутствуют в изначальномАлголе-60,такие какопределение типов,записи,указатели,перечисления,имножества.Эти конструкции были частично унаследованы или инспирированы от языковСимула-67,Алгол-68[источник не указан 4194 дня],созданногоНиклаусом ВиртомAlgolW[англ.]и предложеныХоаром.
В современных диалектах (Delphi Pascal, Free Pascal) доступны такие операции, как перегрузка операторов и функций.
Hello, world!
[править|править код]Программы на Паскале начинаются сключевого словаProgram
и следующего за ним имени программы сточкой с запятой(в некоторых диалектах является необязательным),
за именем может в скобках следовать список внешних файловых дескрипторов («окружение») в качестве параметров;
за ним следует тело программы, состоящее изсекций описания
констант(Const
),
типов(Type
),
переменных(Var
),
объявленийпроцедур(Procedure
)
ифункций(Function
)
и следующего за нимиблока операторов,являющегосяточкой входав программу.
В языке Паскальблокограничивается ключевыми словамиbegin
иend
.
Операторы разделяютсяточками с запятой,
после тела помещаетсяточка,
служащая признаком конца программы.
Регистр символов в Паскале не имеет значения.
Таким образом, простейшая («пустая») программа на Паскале будет выглядеть следующим образом:
programp;
begin
end.
Приведённая выше программа не выполняет никаких действий и содержитпустой блокоператоров.
Пример программы, выводящей строку «Hello, world!»:
programhello;
begin
writeln('Hello, World!');// оператор вывода строки
end.
Типы данных
[править|править код]Простые типы
[править|править код]В стандартном и расширенном Паскале есть такиепростыетипы:числа с плавающей запятой(real
),целые(integer
),символьный(char
),логический(boolean
) иперечисления(конструктор нового типа, введённый в Pascal).
Turbo Pascalдополнил язык вариациями этих типов: например,shortint
будет корочеinteger
,аlongint
— длиннее.
Современные диалекты Pascal, такие, какFPCилиDelphi,считают, чтоinteger
— это наиболее подходящий для данной машины целый, применяемый, например, дляиндексов массива,аshortint
,longint
и другие — целые определённой длины; это удобно прикроссплатформенномпрограммировании. Аналогично и с дробными числами.
Ещё раз расширили типы при переходе наx64— «просто целое» (integer
) осталось 32-битным, но потребовался особый тип, который равенlongint
на x86 иint64
на x64.
Целочисленные типы:
Тип | Диапазон | Формат | Размер в байтах | Примечания |
---|---|---|---|---|
Byte | 0..255 | Беззнаковый | 1 | |
ShortInt | −128..127 | Знаковый | 1 | |
SmallInt | −32768..32767 | Знаковый | 2 | Может не существовать; вместо него Integer с тем же диапазоном |
Word | 0..65535 | Беззнаковый | 2 | |
LongWord | 0..4294967295 | Беззнаковый | 4 | |
LongInt | −2147483648..2147483647 | Знаковый | 4 | |
Int64 | −9223372036854775808..9223372036854775807 | Знаковый | 8 | |
QWord | 0..18446744073709551615 | Беззнаковый | 8 | |
Integer | -32768..32767. | Знаковый | 2 или 4 | Наиболее быстрый целый; SmallInt или LongInt |
Cardinal | ? | Беззнаковый | ? | Наиболее быстрый целый; обычно LongWord |
NativeInt | ? | Знаковый | ? | Соответствует машинному регистру; LongInt или Int64 |
NativeUInt | ? | Беззнаковый | ? | Соответствует машинному регистру; LongWord или QWord |
Числа с плавающей запятой:
Тип | Диапазон | Кол-во значащих цифр | Размер в байтах | Поддержка |
---|---|---|---|---|
Real | зависит от платформы | ??? | ??? | Все компиляторы; на современных обычно эквивалентен Double |
Real48 | 2.9E−39..1.7E38 | 11−12 | 6 | Borland; в Turbo Pascal назывался Real; не использует сопроцессора и потому результат повторяем до бита |
Single | 1.5E−45..3.4E38 | 7−8 | 4 | Большинство вариантов подIEEE 754-совместимые машины |
Double | 5.0E−324..1.7E308 | 15−16 | 8 | Большинство вариантов подIEEE 754-совместимые машины |
Extended | 3.4E−4951..1.1E4932 | 19−20 | 10 | Большинство вариантов под x86 |
Comp | −9223372036854775808..9223372036854775807 | 8 | Borland; рассчитываемое на сопроцессоре 8-байтовое целое; актуально для 16-битного x86 | |
Currency | −922337203685477.5808..922337203685477.5807 | 8 | Borland и другие компиляторы под Windows; связано сOLE;фиксированная запятаяс единицей, равной 10000 |
var{ секция объявления переменных }
r:Real;{ переменная вещественного типа }
i:Integer;{ переменная целого типа }
c:Char;{ переменная-символ }
b:Boolean;{ логическая переменная }
s:String;{ переменная строки }
t:Text;{ переменная для объявления текстового файла }
e:(apple,pear,banana,orange,lemon);{ переменная типа-перечисления }
В Pascal над целыми типами (byte, shortint, word, integer, longint и их диапазоны) допустимы побитовые операции. Логические операции над битами:
Над битами двух целых операндов можно выполнять ранее рассмотренные логические операции: not, and, or, xor. Отличие между побитовыми и логическими операциями состоит в том, что побитовые (поразрядные) операции выполняются над отдельными битами операндов, а не над их значением в десятичном (обычно) представлении.
Выделяется понятиепорядковыхтипов данных (ordinal), к ним относятся целые типы (знаковые и беззнаковые), логический (boolean
), символьный (char
), перечислимые типы и типы-диапазоны.
Порядковые типы задаются целым числом (кодом), которое можно получить с помощью функции ord. Все операции, выполняемые над порядковыми типами, выполняются с их кодами.
Диапазоны содержат подмножество значений других порядковых типов:
var
x:1..10;
y:'a'..'z';
z:pear..orange;
Для порядковых типов определены операцииinc
,dec
,succ
,pred
,ord
,операции сравнения (=
>
<
=>
<=
<>
), их можно использовать в операторахcase
,for
(как счётчик цикла), как границы массивов, для задания элементов множеств и типов-диапазонов.
В Pascal, в отличие от Си-подобных языков, с типамиboolean
иchar
арифметические целочисленные операции не определены.
Множества
[править|править код]В отличие от многих распространённых языков, Pascal поддерживает специальный тип данныхмножество:
var
set1:setof1..10;
set2:setof'a'..'z';
set3:setofpear..orange;
Множество — фундаментальное понятие в современной математике, которое может быть использовано во многих алгоритмах.
В паскале тип множество может содержать только однотипные элементы порядкового типа. Эта особенность широко используется и обычно быстрее эквивалентной конструкции в языке, не поддерживающем множества. К примеру, для большинства компиляторов Паскаля:
ifiin[5..10]then{ проверка на принадлежность элемента множеству }
...
обработается быстрее, чем
if(i>=5)and(i<=10)then{ проверка логическими условиями }
...
Для задания значения множества используется список элементов множества, отделённых запятыми и заключённый в квадратные скобки (как уже было показано выше):
var{ секция объявления переменных }
d:setofchar;
begin{ начало блока }
d:=['a','b'];
...
В Паскале Йенсен и Вирта строки представлялись как упакованные массивы символов; следовательно, они имели фиксированную длину и обычно дополнялись до этой длины пробелами.
Составные типы
[править|править код]Новые типы могут быть определены из существующих:
type{ секция объявления типов }
x=Integer;
y=x;
...
Более того, из примитивных типов могут быть сконструированы составные:
type{ секция объявления типов }
a=Array[1..10]ofInteger;{ определение массива }
b=record{ определение записи }
x:Integer;
y:Char;
end;
c=Fileofa;{ определение файла }
Файловые типы в Паскале делятся на типизированные, текстовые и файлы без типов.
Как показано в вышеприведённом примере, типизированныефайлыв Паскале — это последовательности однотипных элементов. Для каждого файла существует переменная-указатель на буфер, которая обозначаетсяf^
.Процедурыget
(для чтения) иput
(для записи) перемещают указатель к следующему элементу. Чтение реализовано так, чтоread(f, x)
представляет собою то же, что иget(f); x:=f^
.Соответственно, запись реализована так, чтоwrite(f, x)
представляет собою то же, что иf^:= x; put(f)
.Текстовые файлыtext
определены как расширение типаfile of char
и помимо стандартных операций над типизированными файлами (чтение, запись символа), позволяют осуществлять символьный ввод-вывод в файл всех типов данных аналогично консольному вводу-выводу.
Файлы без типов объявляются как переменные типаfile
.С ними можно проводить операции побайтового нетипизированного ввода-вывода по несколько блоков байт указанной длины через буфер, для этого служат специальные процедурыblockread
иblockwrite
(расширение UCSD).
Строки
[править|править код]В современном Паскале[15]для работы со строками используется встроенный типstring
,поддерживающий операции конкатенации (+
) и сравнения (>
<
=
<>
>=
<=
). Строки сравниваются влексикографическом порядке.Например, строки считаются равными, если они имеют одинаковую длину и коды всех символов с одинаковыми индексами совпадают.
Типstring [n]
или простоstring
в диалектах языка 1970—1990-х годов определялся в виде массива символовarray [0..n] of char
(n по умолчанию принимало значение 80 в UCSD Pascal и 255 в Turbo/Borland Pascal),
нулевой элемент массива при таком представлении служит для задания длины строки, соответственно строка могла иметь максимальный размер 255 символов. По умолчанию в Delphi и FreePascal в качестве String используется тип AnsiString, память под который выделяется и освобождается компилятором динамически, а максимальный размер строки в текущих реализациях составляет 2 гигабайта. Кроме того, в Delphi и Free Pascal в качествеstring
может использоваться тип UnicodeString, где применяется 16-битное представление символов в кодировкеUCS-2,при этом средства преобразования из однобайтовых строк в многобайтовые и обратно в стандартной библиотеке FPC отсутствуют, но имеются в Delphi.
В Delphi 2009 и выше имеется конструкция для объявления AnsiString с определённой кодовой страницей:
type
CyrillicString=AnsiString(1251);
CP866String=AnsiString(20866);
Указатели
[править|править код]Паскаль поддерживает использованиеуказателей(типизированные^тип
и нетипизированныеpointer
):
type
a=^b;
b=record
x:Integer;
y:Char;
z:a;
end;
var
pointer_to_b:a;
Здесь переменнаяpointer_to_b
— указатель на тип данныхb
,являющийся записью. Типизированный указатель может быть определён (опережающее определение) перед объявлением типа, на который он ссылается. Это одно изисключенийкправилу,которое гласит, чтолюбой элемент (константа, тип, переменная, процедура, функция) должен быть объявлен перед тем, как используется.Введение этого исключения позволяет организовыватьрекуррентныеопределения структур данных, в том числе такие, каклинейные списки,стеки,очереди,деревья,включая указатель на запись в описание этой записи (см. также: нулевой указатель —nil
).
Для типизированного указателя определена операцияразыменования(её синтаксис:указатель^
).
Чтобы создать новую запись и присвоить значение10
и символA
полямx
иy
в ней, необходимы следующие операторы:
new(pointer_to_b);{ выделение памяти указателю }
pointer_to_b^.x:=10;{ разыменовывание указателя и обращение к полю записи }
pointer_to_b^.y:='A';
pointer_to_b^.z:=nil;
...
dispose(pointer_to_b);{ освобождение памяти из-под указателя }
Для целей обращения к полям записей и объектов можно также использовать операторwith
,как показано в примере:
new(pointer_to_b);
withpointer_to_b^do
begin
x:=10;
y:='A';
z:=nil
end;
...
dispose(pointer_to_b);
Процедурный тип
[править|править код]В оригинальном языке Паскаль Йенсен и Вирта процедурный тип использовался только при описании формального параметра. Уже в TP существовал полноправныйпроцедурный тип.В объявлении типа ставится заголовок процедуры либо функции (без имени), обобщённо описывающий интерфейс подпрограммы. Значение этого типа содержит указатель на подпрограмму с заголовком, соответствующую описанному в объявлении типа. С помощью идентификатора переменной может происходить вызов соответствующей процедуры или функции.
typemyfunc=function:string;
functionfunc1:string;
begin
func1:='func № 1'
end;
functionfunc2:string;
begin
func2:='func № 2'
end;
varfun:myfunc;
begin
fun:=@func1;
writeln(fun){происходит вызов функции func1}
end.
Операторы управления
[править|править код]Паскаль — языкструктурного программирования,что означает, что программа состоит из выполняющихся последовательно отдельных стандартных операторов, в идеале — без использования командыGOTO
.
whilea<>bdo{ цикл с предусловием }
writeln('Ожидание');
ifa>bthen{ условный оператор }
writeln('Условие выполнилось')
else{ else-секция - может отсутствовать}
writeln('Условие не выполнилось');
fori:=1to10do{ итерационный цикл }
writeln('Итерация №',i:1);
foriin[1..10]do{ итерационный цикл по множеству }
writeln('Итерация №',i:1);{ появился в версии 2.4.0 }
withado{Оператор With - метод ускорения доступа к полям записи}
begin
l:=1;
k:=2;
p:=-3;
end;
repeat{ цикл с постусловием }
a:=a+1
untila=10;
caseiof{ условный оператор множественного выбора }
0:write('ноль');
1:write('один');
2:write('два')
elsewrite('неизвестное число'){ else-секция - может отсутствовать}
end;
В операторахwhile
,for
,if
,case
в качестве выполняемого оператора может использоватьсяблок.Такая конструкция, представляющая собой обычный оператор или блок, называетсясложным оператором.
В Turbo Pascal для управления процессом компиляции существуют директивы, которые помещаются в комментарии и позволяют переключать режимы работы компилятора — например, включать и отключать проверку операций ввода-вывода, переполнения:
assign(inp,'text.txt');
{$I-}{ отключение режима IO checking- генерации кода завершения программы в случае ошибки ввода-вывода }
{ (для случая, если файл не найден)}
reset(inp);
{$I+}{ включение режима IO checking }
ifIOresult=0thenbegin{ проверяем значение переменой ioresult(<>0 в случае ошибки ввода-вывода) }
...
close(inp);
endelsewriteln('file not found')
Существуют директивы, аналогичные директивам препроцессора C/C++ ($ifdef
,$define
,$include
), они обрабатываются компилятором в процессе компиляции.
Процедуры и функции
[править|править код]В Паскале подпрограммы делятся на процедуры и функции. При этом, функции явно возвращают значение (результат) определённого типа, а процедуры явно ничего не возвращают.
Синтаксически описание процедуры или функции состоит иззаголовка,содержащего ключевое словоprocedure
илиfunction
,имени, за которым может следовать описание передаваемых (формальных) параметров в скобках. Для функции через символ «двоеточие»:
указывается тип возвращаемого значения. Заголовок заканчивается символом «точка с запятой»;
.После заголовка следуеттело,(возможно) содержащее секции описания локальных констант, типов, переменных, процедур, функций и (обязательно) содержащее блок операторов, после которого ставится символ «точка с запятой»;
.
programmine(output);
vari:integer;
procedureprint(varj:integer);
functionnext(k:integer):integer;
begin
next:=k+1
end;
begin
writeln('Всего: ',j);
j:=next(j)
end;
begin
i:=1;
whilei<=10do
print(i)
end.
Тело процедуры, как и программы, в свою очередь может содержать описания процедур и функций. Таким образом, процедуры и функции могут быть вложены друг в друга как угодно глубоко, при этом тело программы — самое верхнее в цепочке.
Причём содержимое секций описания переменных, типов, констант, внешнего тела (процедуры, функции, программы), расположенных перед описанием процедуры/функции, доступны внутри неё. Также, в большинстве диалектов из процедуры можно обращаться к параметрам внешней процедуры.
Вслед за заголовком процедур/функций вместо тела может помещаться ключевое словоforward
,это делается в том случае, если описание процедуры/функции располагается в программе после её вызова, и связано с поддерживаемой в Паскале возможностью компиляции программы за один проход.
Стандартные математические функции и процедуры Паскаля
[править|править код]Математические функции
[править|править код]Наименование функции | Тип аргумента | Тип значения | Результат вычисления |
Abs(x) | целый вещественный | целый вещественный | Абсолютное значение "х" |
Sin(x) | вещественный | вещественный | синус "х" рад. |
Cos(x) | вещественный | вещественный | косинус "х" рад. |
Arctan(x) | вещественный | вещественный | арктангенс "х" ( -Pi/2 <y< Pi/2 ) |
Sqrt(x) | вещественный | вещественный | квадратный корень из "х" |
Sqr(x) | целый вещественный | целый вещественный | значение "х" в квадрате (x2) |
Power(a,x) | вещественный | вещественный | значение "a" в степени "x" (ax) |
Exp(x) | вещественный | вещественный | значение "е" в степени "х" (ex,где e= 2.718282... ) |
Ln(x) | вещественный | вещественный | натуральный логарифм "х" ( х > 0 ) |
Frac(x) | вещественный | вещественный | дробная часть "х" |
Int(x) | вещественный | вещественный | целая часть "х" |
Random | - | вещественный | случайное число ( 0 <=y< 1 ) |
Random(x) | Word | Word | случайное число ( 0 <=y< x ) |
Succ(c) | порядковый | порядковый | следующий за "с" символ |
Pred(c) | порядковый | порядковый | предшествующий "с" символ |
Математические процедуры
[править|править код]Наименование функции | Тип аргумента | Тип значения | Результат вычисления |
Inc(x) | целый | целый | Увеличивает "х" на 1 ( x:=x+1; ) |
Dec(x) | целый | целый | Уменьшает "х" на 1 ( x:=x-1; ) |
Inc(x, n) | целый | целый | "х" на n ( x:=x+n; ) |
Dec(x, n) | целый | целый | "х" на n ( x:=x-n; ) |
Процедуры преобразования типов переменных
[править|править код]Наименование функции | Тип аргумента | Тип значения | Результат вычисления |
Str(x, s) | x-целый или вещественный | s-строковый | Последовательность символов "s" из цифр числа "x" |
Val(s, v, cod) | s-строковый | v-целый или вещественный cod-целый | Двоичная форма числа последовательности "s" cod=0 (код ошибки) |
Функции преобразования типов переменных
[править|править код]Наименование функции | Тип аргумента | Тип значения | Результат вычисления |
Trunc(x) | вещественный | LongInt | целая часть "х" |
Round(x) | вещественный | LongInt | округление "х" до целого |
Odd(x) | целый | логический | возвращает True если "х" - нечётное число |
Chr(x) | Byte | Char | Символ ASCII кода "х" |
Ord(x) | Char | Byte | ASCII код символа "x" |
Модули
[править|править код]До появления связных модулей в их современном виде некоторые реализации Паскаля поддерживали модульность за счёт механизма включения заголовочных файлов, похожего на механизм#include
в языке Си: с помощью специальной директивы, оформляемой в виде псевдокомментария, например,{$INCLUDE "файл" }
,содержимое указанного файла прямо включалось в текст программы в исходном, текстовом виде. Таким образом можно было разделить программный код на множество фрагментов, для удобства редактирования, но перед компиляцией они автоматически объединялись в один файл программы, который в итоге и обрабатывался компилятором. Такая реализация модульности примитивна и имеет множество очевидных недостатков, поэтому она была быстро заменена.
Современные реализации языка Паскаль (начиная с UCSD Pascal) поддерживают модули. Программные модули могут быть двух видов: модуль главной программы, который, как обычно, начинается с ключевого слова program и тело которого содержит код, запускаемый после загрузки программы в память, и вспомогательных модулей, содержащих типы, константы, переменные, процедуры и функции, предназначенные для использования в других модулях, в том числе в главном модуле.
Структура
[править|править код]Общая структура подключаемого модуля на Паскале выглядит следующим образом:
unitUnitName1;
interface
...
implementation
...
begin{может отсутствовать - используется, если необходимо поместить операторы инициализации}
...
end.
Возможен также ещё один вариант:
unitUnitName2;
interface
...
implementation
...
initialization
...
finalization
....
end.
В отличие от главной программы, файл модуля начинается с ключевого словаUNIT
,за которым следует имя модуля и точка с запятой. Современные реализации, как правило, требуют, чтобы имя модуля совпадало с именем файла исходного кода, в котором этот модуль содержится. Модуль содержит три секции: интерфейсную секцию, секцию реализации и тело модуля.
Интерфейсная секция идёт первой, начинается с ключевого словаINTERFACE
и заканчивается в том месте модуля, где начинается секция реализации или тело. В интерфейсной секции объявляются те объекты (типы, константы, переменные, процедуры и функции — для них помещаются заголовки), которые должны быть доступны извне модуля. При этом допускается частичное объявление типов: они могут объявляться без указания структуры, одним только именем. При использовании такого типа во внешней программе допускается объявление переменных и параметров этого типа, присваивание значений, но невозможно получить доступ к деталям его реализации. Процедуры и функции в интерфейсной секции объявляются в виде форвардов — заголовков с параметрами, но без тела. Состав интерфейсной секции модуля таков, что его достаточно для генерации кода, использующего данный модуль. Переменные, объявленные в интерфейсной секции, являются глобальными, то есть существуют в единственном экземпляре и доступны во всех частях программы, использующих данный модуль.
Секция реализации следует за интерфейсной и начинается с ключевого словаIMPLEMENTATION
.В нём располагаются описания процедур и функций, объявленных в интерфейсной секции, а также описания типов, констант, переменных, процедур и функций, которые необходимы для реализации интерфейсных процедур и функций. Описание процедуры или функции, объявленной в интерфейсной секции, должно иметь в точности такой же заголовок, как в объявлении. В теле могут использоваться другие процедуры и функции данного модуля, объявленные как в интерфейсной части, так и в секции реализации. Переменные, объявленные в секции реализации, являются, по сути, глобальными (то есть существует только один экземпляр каждой такой переменной на всю программу), но доступны они только из процедур и функций, описанных в секции реализации данного модуля, а также из его тела. Если в интерфейсной секции есть сокращённые объявления типов, то эти типы должны быть полностью описаны в секции реализации.
Тело модуля начинается находящимся на верхнем уровне вложенности ключевым словомBEGIN
.Тело содержит программный код, который выполняется один раз при загрузке модуля. Тело может применяться для инициализации, присваивания начальных значений переменным модуля, выделения ресурсов для его работы и так далее. Тело модуля может отсутствовать. В ряде реализаций Паскаля, например, в Delphi, вместо тела модуля могут применяться две секции (также необязательные) —INITIALIZATION
иFINALIZATION
.Они располагаются в конце модуля, после соответствующего ключевого слова. Первая — секция инициализации, — содержит код, который должен быть выполнен при загрузке модуля, вторая — секция финализации, — код, который будет выполнен при выгрузке модуля. Секция финализации может выполнять действия, обратные инициализации — удалять объекты из памяти, закрывать файлы, освобождать выделенные ресурсы.
Модуль заканчивается ключевым словомEND
с точкой.
Использование
[править|править код]Чтобы использовать модуль, главная программа или другой модуль должны импортировать данный модуль, то есть содержать объявление о его использовании. Это объявление делается с помощью инструкции подключения модулей, представляющей собой ключевое словоUSES
,за которым через запятую следуют имена модулей, которые требуется подключить. Инструкция подключения должна следовать непосредственно за заголовком программы, либо после ключевого словаINTERFACE
,если подключение производится в модуле.
Модули, подключённые в интерфейсной секции, могут использоваться во всём модуле — и в секции реализации, и в теле. Но секция реализации может иметь собственную инструкцию подключения (она следует за ключевым словомIMPLEMENTATION
), содержащую имена подключаемых модулей, которые отсутствуют в интерфейсной секции, но нужны для секции реализации. Одним из поводов использования отдельного списка подключения для раздела реализации является ситуация, когда два или более модуля используют друг друга. Чтобы не возникали циклические ссылки в объявлениях использования таких модулей, по крайней мере один из них должен подключать другой в секции реализации.
Любые объявленные в интерфейсных секциях модулей объекты можно использовать в программе там, где эти модули подключены. Имена импортированных из подключённых модулей объектов остаются теми же самыми, и их можно использовать непосредственно. Если два или более подключённых модуля имеют объекты, называемые одинаково, и компилятор не может их различить, то при попытке использования такого объекта будет выдана ошибка компиляции — неоднозначное задание имени. В этом случае программист должен применять квалификацию имени — указать имя в формате «<имя_модуля>.<имя_объекта>».
Проблемы могут возникнуть, если появляется необходимость использования в программе двух разных одноимённых модулей. Если модули доступны только в откомпилированном виде (то есть поменять их имена невозможно), оказывается невозможным их одновременный импорт. Стандартного решения такой коллизии на уровне языка не существует, но конкретные компиляторы могут предлагать те или иные способы её обхода, в частности, средства назначения псевдонимов импортируемым модулям и прямого указания, какой модуль из какого файла брать.
Компиляция и компоновка
[править|править код]Модули спроектированы в расчёте на обеспечение раздельной компиляции — компилятор не должен компилировать импортированные модули для того, чтобы откомпилировать модуль, который их использует. Однако, чтобы правильно компилировать модуль, компилятор должен иметь доступ к секции интерфейса всех используемых им модулей. Существует два разных, иногда совмещаемых подхода к организации такого доступа.
- Модули компилируются в бинарные файлы специального формата (у каждого компилятора своего), в которых сохранена подробная информация об объектах, объявленных в интерфейсной секции, также может содержаться созданный при компиляции модуля объектом языке, но использует при этом только интерфейсную секцию модуля. Если библиотечный модуль поставляется в откомпилированном виде (без полных исходных текстов), то вместе с бинарным файлом идёт урезанный файл исходного кода модуля, содержащий только интерфейсную секцию. Компилятору этого достаточно, чтобы правильно обрабатывать обращения из использующих модулей, а на этапе сборки программы компоновщик просто включает в программу бинарный файл.
Загрузка и выгрузка модулей
[править|править код]Для нормальной работы модуля может потребоваться выполнить некоторые действия до начала его использования: инициализировать переменные, открыть нужные файлы, выделить память или другие ресурсы. Всё это может быть сделано в теле модуля, либо в секции инициализации. Действия, обратные инициализации, делаются в секции финализации.
Порядок инициализации и финализации модулей косвенно определяется порядком объявления в секции uses, но для статически откомпилированных программ (где модуль либо компилируется в один исполняемый файл с главной программой, либо находится в отдельной динамической библиотеке, но загружается на этапе первоначальной загрузки), компилятор всегда гарантирует, что инициализация будет выполнена до момента первого использования модуля. Финализация выполняется при завершении работы программы, после завершения главного модуля, так, что используемые модули финализируются позже, чем использующие их.
В случае динамической загрузки модулей, управляемой самим программистом, инициализаторы выполняются при загрузке, то есть в момент, когда команда загрузки модуля вернула управление, инициализатор его уже выполнен. Финализатор выполняется после выгрузки, обычно — при выполнении команды выгрузки модуля. Если эта команда не вызывается, динамически загруженные модули финализируются так же, как все остальные — при завершении программы.
Объектно-ориентированное программирование
[править|править код]ВObject Pascalимеется возможность разрабатывать программы с применением парадигмыобъектно-ориентированного программирования.Классы задаются с помощью типаobject
,аналогичногоrecord
,который кроме полей данных может содержать заголовки процедур иметодов.Имена описываемых методов следуют за именем класса через точку.
Конструкторидеструкторзадаются как обычные процедуры, но вместо идентификатораprocedure
задаются ключевые словаconstructor
иdestructor
.Соответственно, в отличие отC++-подобных языков они имеют имя, отличное от имени класса, деструкторов может быть несколько, и они могут иметь параметры (на практике эта возможность используется редко, обычно класс имеет единственный деструкторDestroy
,переопределяющий виртуальный деструктор класса-родителя).
Поддерживаются единичное наследование,полиморфизм классов,механизмвиртуальныхметодов (словоvirtual
после заголовка метода класса). Существуют и динамические методы (в TP описываются путём добавления целого числа после словаvirtual
и используются преимущественно для обработки сообщений; в Delphi и FreePascal для этих целей используется словоmessage
,а для создания обычных динамических методов — словоdynamic
), отличающиеся меньшим использованием памяти и меньшей скоростью вызова за счёт отсутствия дублирования динамических методов предков в VMT потомка (однако FreePascal не делает различий между виртуальными и динамическими методами).
В Delphi, FPC реализованаперегрузка операций,абстрактные методы, директивыprivate
,protected
,public
,published
(по умолчанию члены класса являютсяpublic
):
type
TbasicO=object
procedurewriteByte(b:byte);virtual;abstract;
end;
TtextO=object(TbasicO){наследует TbasicO, реализует остальные операции вывода на основе writeByte}
procedurewriteS(s:string);
{..}
end;
TfileO=object(TbasicO){класс файлового вывода - реализует операцию вывода как вывод байта в файл}
constructorinit(n:string);
procedurewriteByte(b:byte);virtual;
destructorclosefile;
private
f:fileofbyte;
end;
basicO=^TbasicO;
textO=^TtextO;
fileO=^TfileO;
constructorTfileO.init(n:string);
begin
assign(f,n);
rewrite(f)
end;
destructorTfileO.closefile;
begin
close(f)
end;
procedureTfileO.writeByte(b:byte);
begin
write(f,b)
end;
procedureTtextO.writeS(s:string);
vari:integer;
begin
fori:=1tolength(s)do
writeByte(ord(s[i]))
end;
{..}
varf:fileO;
begin
new(f,init('tstobj.txt'));{выделяет память под объект и вызывает конструктор}
textO(f)^.writeS('text string');
dispose(f,closefile){вызывает деструктор и освобождает память объекта}
end.
В диалекте Delphi классы могут также конструироваться с помощью словаclass
(причём взаимное наследование сobject
-классами не допускается) и введеныинтерфейсы(interface
) — все методы абстрактные и не могут содержать полей данных.
Все классы (созданные с помощьюclass
) являются наследникамиTObject
,все интерфейсы происходят отIUnknown
.Классы, созданные с помощьюclass
,могут реализовывать несколько интерфейсов.
В Delphi интерфейсы были введены для поддержки технологииCOMфирмы Microsoft.
Классы (Class
) в отличие от обычных классов (Object
) не нуждаются в явном выделении/освобождении памяти, память под них динамически выделяется конструктором с именемCreate
,вызываемым с именем класса, и освобождается при вызове деструктора с именемDestroy
(могут иметь другие имена). Переменная такого класса в отличие от классаobject
хранит адрес экземпляра класса в памяти, значениеnil
используется для указания пустой ссылки, поэтому для освобождения объекта вTObject
определён специальный методfree
,проверяющий ссылку наnil
и вызывающий виртуальный деструкторDestroy
.Код с использованием таких классов будет выглядеть следующим образом:
q1:=t1.create(9);{ конструируем объект(t1 - имя класса) }
writeln(q1.InstanceSize);{ вывод размера экземпляра класса }
q1.Free;{ уничтожение объекта }
q1:=nil;{ чтобы не происходило повторного вызова деструктора при вызове free }
В модификации ObjectPascal/Delphi/FreePascal в описании классов появляются свойства (property), которые совмещают удобство работы с переменными (роль которых в ООП играют поля) и вызовы методов, которые всегда уведомляют объект об изменении его состояния:
type
TMyObj=class(TObject)
FProp:integer;
procedureSetProp(AValue:integer);
propertyMyProp:integerreadFPropwriteSetProp;
end;
procedureTMyObj.SetProp(AValue:integer);
begin
FProp:=AValue;
Writeln('Somebody has changed MyProp!');
end;
varMyObj:TMyObj;
begin
MyObj:=TMyObj.Create;
MyObj.FProp:=5;
MyObj.MyProp:=MyObj.MyProp+6;
end.
В первом случае (использование MyObj.FProp) поле объекта было изменено непосредственно, в итоге, методы объекта не будут подозревать, что это поле было ранее изменено; в более сложном случае они могут полагаться на то, что поле неизменно, либо же полю может быть присвоено значение, недопустимое для данного объекта. Во втором случае значение присваивается непосредственно свойству объекта, которое ссылается на вызов метода, корректно обрабатывающего изменение данного поля.
Этот подход удобен, если объект связан с визуальным элементом: непосредственное изменение поля, отвечающего, например, за ширину элемента, никак не отразится на самом визуальном элементе, а объект будет «дезинформирован» относительно реальных размеров элемента. Корректным подходом без использования свойств является разработка методов на получение и установку любого значения поля, но работа с такими методами будет менее удобна, например, вместо последней строки надо было бы написать
MyObj.SetProp(MyObj.GetProp+6);
причём метод MyObj.GetProp следовало бы написать для унификации доступа.
Большой интерес представляют индексные свойства, которые ведут себя практически так же, как и массивы, заменяя обращение к элементу массива вызовом соответствующего метода.
Тем не менее, свойства не являются «панацеей»: при компиляции обращения к свойствам непосредственно транслируются в вызов методов или прямую работу с полями, поэтому настоящими переменными свойства не являются, в частности, их невозможно передавать в виде var-параметров.
Примечания
[править|править код]- ↑Kim B. Bruce.Foundations of Object-oriented Languages: Types and Semantics.— MIT Press, 2002-01-01. — С. 9. — 416 с. —ISBN 9780262025232.Архивировано18 июня 2016 года.
- ↑White Paper. About Microsoft’s «Delegates»Архивная копияот 27 июня 2012 наWayback Machine,java.sun
- ↑History of Java, Java Application Servers ReportАрхивировано29 декабря 2010 года.TechMetrix Research, 1999
- ↑A Conversation with James Gosling .Дата обращения: 16 октября 2009.Архивировано16 июля 2015 года.
- ↑Индекс популярности языков программирования TIOBEАрхивная копияот 25 декабря 2018 наWayback Machine(англ.)
- ↑12Wirth, N.Modula-2 and Oberon //HOPL III:Proceedings of the third ACM SIGPLAN conference on History of programming languages:[англ.]:[арх.22 декабря 2012]. — ACM, 2007. — June. — P. 3-1–3-10. —doi:10.1145/1238844.1238847.
- ↑Бородич, Ю. С.Предисловие // Паскаль для персональных компьютеров: справ. пособ. / Ю. С. Бородич, А. Н. Вальвачев, А. И. Кузьмич. —Мн.:Вышэйшая школа, 1991. — С. 3. — 365 с.: ил. —ББК32.973-01я2.—УДК681.3.06(035.5)(G).—ISBN 5-339-00662-X.
- ↑Liste compilateur Pascal - Pascal compiler list .Дата обращения: 19 января 2021.Архивировано11 апреля 2021 года.
- ↑Wirth N. Recollections about the development of Pascal (HOPL II), 3.3 .Дата обращения: 16 апреля 2011.Архивировано22 декабря 2012 года.
- ↑Jon Udell, Crash of the Object-Oriented Pascals, BYTE, July, 1989.
- ↑M. I. Trofimov, The End of Pascal?, BYTE, March, 1990, p. 36.
- ↑Why Pascal is Not My Favorite Programming Language .Дата обращения: 27 августа 2004.Архивировано28 апреля 2009 года.
- ↑PASCAL: User Manual and ReportISO Pascal Standard Kathleen Jensen and Niklaus Wirth, 4th edition, Springer Verlag New York, Inc. 1974, 1985, 1991
- ↑Object-Oriented Extensions to PascalАрхивная копияот 5 июня 2021 наWayback Machine,Technical Committee X3J9, Programming Language Pascal
- ↑ISO 7185 Pascal .Дата обращения: 12 апреля 2009.Архивировано25 ноября 2006 года.
Литература
[править|править код]- Вирт Н.Алгоритмы + структуры данных = программы. —М.:Мир,1985. — 406 с.
- Вирт Н., Йенсен К.Паскаль. Руководство для пользователя и описание языка. —М.:Финансы и статистика,1982. — 151 с.
- Грогоно П.Программирование на языке Паскаль. —М.:Мир,1982. — 384 с.
- Культин Н. Б.Программирование в Turbo Pascal 7.0 и Delphi: 3-е изд., перераб. и доп.. —СПб.:БХВ-Петербург,2007. — 400 с. —ISBN 978-5-9775-0109-5.
- Культин Н. Б.Delphi 6. Программирование на Object Pascal. —СПб.:БХВ-Петербург,2001. — 528 с. —ISBN 5-94157-112-7.
- Моргун А. Н.Программирование на языке Паскаль (Pascal). Основы обработки структур данных. —М.:Диалектика,2005. — 576 с. —ISBN 5-8459-0935-X.
- Перминов О. Н.Язык программирования Паскаль: Справочник. —М.:Радио и связь,1989. — 128 с. —ISBN 5-256-00311-9.
- Рубенкинг Н. Дж.Турбо Паскаль для Windows: в 2-х томах. Пер. с англ. —М.:Мир, 1993.
- Языки программирования Ада, Си, Паскаль = Comparing and Assessong Programming Languages Ada, C, and Pascal / А. Фьюэр, Н. Джехани. —М.:Радио и Связь, 1989. — 368 с. —50 000 экз.—ISBN 5-256-00309-7.
Стандарты
- ISO 7185:1983 Programming languages — PASCAL (заменён стандартом ISO 7185:1990)
- ANSI/IEEE770X3.97-1983
- ГОСТ 28140-89 Системы обработки информации. Язык программирования ПАСКАЛЬ
- ISO 7185:1990 Information technology — Programming languages — PascalАрхивная копияот 25 октября 2012 наWayback Machine
- ISO/IEC 10206:1991 Information technology — Progamming languages — Extended PascalАрхивная копияот 25 октября 2012 наWayback Machine
Ссылки
[править|править код]- Программирование на pascal— online tutorial (rus)
- Паскальв каталоге ссылокCurlie(dmoz)
- Pascal CentralАрхивная копияот 10 марта 2010 наWayback Machine(англ.)
- Паскальные исходники со всего мираАрхивная копияот 3 октября 2010 наWayback Machine,Сайт о программе
- Статья о ПаскалеАрхивная копияот 27 мая 2007 наWayback Machineв энциклопедии progopedia.ru
Для улучшения этой статьижелательно:
|