Паскаль (язык программирования): различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
м Исправление псевдозаголовков (см. Википедия:Доступность#Заголовки)
 
(не показаны 983 промежуточные версии, сделанные более чем 100 участниками)
Строка 1: Строка 1:
{{другие значения|Паскаль (значения)}}
{{Карточка языка программирования |
{{Карточка языка программирования
name = Pascal |
| name = Паскаль
semantics = [[Процедурное программирование|процедурный]] |
| logo =
class = [[компилятор]] |
| paradigm = [[Императивное программирование|императивный]], [[Структурное программирование|структурированный]]
year = [[1970]] |
| class = [[Компилятор|компилируемый]]
designer = [[Вирт, Никлаус|Никлаус Вирт]] |
| typing = [[статическая типизация|статическая]], [[сильная типизация|сильная]], [[Типобезопасность|безопасная]] <ref>{{Книга|автор = Kim B. Bruce|год = 2002-01-01|isbn = 9780262025232|страниц = 416|издательство = MIT Press|заглавие = Foundations of Object-oriented Languages: Types and Semantics|ссылка = https://books.google.com/books?id=9NGWq3K1RwUC|страницы = 9|archive-date = 2016-06-18|archive-url = https://web.archive.org/web/20160618062032/https://books.google.com/books?id=9NGWq3K1RwUC}}</ref>
<!--
| implementations = [[CDC 6000]], [[ICT 1900]], [[Pascal-P]], [[PDP-11]], [[PDP-10]], [[IBM System/370]], [[Hewlett-Packard|HP]], [[Free Pascal]], [[GNU Pascal|GNU]], [[PascalABC.NET]]
| dialects = [[UCSD Pascal|UCSD]], [[Turbo Pascal|Turbo]], [[Delphi (язык программирования)|Delphi]]
| year = [[1970]]
| designer = [[Вирт, Никлаус|Никлаус Вирт]]
| influenced_by = [[Алгол]]
| influenced = [[Модула-2]], [[Оберон (язык программирования)|Оберон]], [[Компонентный Паскаль]], [[Ада (язык программирования)|Ада]], [[Object Pascal]], [[Java]]<ref>[http://java.sun.com/docs/white/delegates.html White Paper. About Microsoft’s «Delegates»] {{Wayback|url=http://java.sun.com/docs/white/delegates.html |date=20120627043929 }}, java.sun.com</ref><ref>[http://www.fscript.org/prof/javapassport.pdf History of Java, Java Application Servers Report] {{webarchive|url=https://web.archive.org/web/20101229090912/http://www.fscript.org/prof/javapassport.pdf |date=2010-12-29 }} TechMetrix Research, 1999</ref><ref>{{Cite web |url=http://queue.acm.org/detail.cfm?id=1017013 |title=A Conversation with James Gosling |access-date=2009-10-16 |archive-date=2015-07-16 |archive-url=https://web.archive.org/web/20150716194245/http://queue.acm.org/detail.cfm?id=1017013 |deadlink=no }}</ref>, [[Oxygene (язык программирования)|Oxygene]]
| operating_system = [[Linux]], [[Microsoft Windows]], [[Mac OS X]], [[FreeBSD]] и другие
| license =
| website = https://www.iso.org/standard/18237.html
| extension = <code>.pas</code> для файлов кода, <code>.inc</code> для [[Заголовочный файл|заголовочных файлов]].
| последняя версия = ISO/IEC 10206:1991 Stage: 90.93
| дата выпуска последней версии = [[29 июля]] [[2008 год]]а
}}
'''Паска́ль''' ({{lang-en|Pascal}}) — один из наиболее известных языков программирования<ref>[http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html Индекс популярности языков программирования TIOBE] {{Wayback|url=http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html |date=20181225175216 }}{{ref-en}}</ref>, используется для обучения программированию в старших классах и на первых курсах вузов, является основой для ряда других языков.


[[Файл:LagrangePAS.jpg|400px|thumb|Пример программы на языке Паскаль]]
typing = |
== История ==
dialects = |
Язык программирования Pascal был создан в 1970 году на основе языка [[Алгол-60]]<ref name="Wirth, 2007">{{публикация|книга |язык=en |автор линк=Вирт, Никлаус |автор=Wirth |автор имя=N. |часть=Modula-2 and Oberon |заглавие=HOPL III |подзаголовок=Proceedings of the third ACM SIGPLAN conference on History of programming languages |год=2007 |месяц=06 |издательство=ACM |pages=3-1–3-10 |doi=10.1145/1238844.1238847 |ссылка=http://oberoncore.ru/_media/library/n._wirth_-_modula-2_and_oberon_hopl_iii_.pdf |архив дата=20121222075805 |архив=https://web.archive.org/web/20121222075805/http://oberoncore.ru/_media/library/n._wirth_-_modula-2_and_oberon_hopl_iii_.pdf }}</ref>.
implementations = |
influenced_by = |
influenced =


Pascal создавался [[Вирт, Никлаус|Никлаусом Виртом]] в 1968—1969 годах после его участия в работе комитета разработки стандарта языка [[Алгол-68]]. Язык назван в честь французского математика, физика, литератора и философа [[Паскаль, Блез|Блеза Паскаля]], который создал одну из первых в мире механических машин, [[Суммирующая машина Паскаля|складывающую два числа]]. Первая публикация Вирта о языке датирована 1970 годом; представляя язык, автор в качестве цели его создания указывал построение небольшого и эффективного языка, способствующего хорошему стилю программирования, использующему [[структурное программирование]] и структурированные данные.{{нет АИ|15|05|2022}}
-->
}}
'''Паскаль''' ({{lang-en|Pascal}}) — [[высокоуровневый язык программирования]] общего назначения. Один из наиболее известных языков программирования, широко применяется в промышленном программировании, обучении программированию в высшей школе, является базой для большого числа других языков. Был создан [[Вирт, Никлаус|Никлаусом Виртом]] в 1968/9 годах (опубликован в [[1970]]-м) после его участия в работе комитета разработки стандарта языка [[Алгол-68]].


Последующая работа Вирта была направлена на создание на основе Паскаля языка системного программирования с сохранением возможности вести на его базе систематический, целостный курс обучения профессиональному программированию: «''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]] на основе всех предыдущих разработок<ref name="Wirth, 2007" />.
== Предыстория ==
Паскаль был создан как язык для обучения [[Процедурное программирование|процедурному программированию]] (хотя, по словам Вирта, язык нельзя считать только учебным, поскольку язык, непригодный для написания реальных программ, для обучения использоваться не должен). Название языку дано в честь выдающегося французского математика, физика, литератора и философа [[Паскаль, Блез|Блеза Паскаля]].


Одной из целей создания языка Паскаль Никлаус Вирт считал обучение студентов структурному программированию. До сих пор Паскаль заслуженно считается одним из лучших языков для начального обучения программированию. Его современные модификации, такие как Object Pascal, широко используются в коммерческом программировании (среда Delphi). Также на основе синтаксиса языка Паскаль создан язык программирования [[Structured Text]] (ST) или Structured Control Language (SCL) для [[Программируемый логический контроллер|программируемых логических контроллеров]].{{нет АИ|15|05|2022}}
Паскаль был создан [[Вирт, Никлаус|Никлаусом Виртом]] в 1968/9 годах после его участия в работе комитета разработки стандарта языка [[Алгол-68]]. Он был опубликован в 1970 году Виртом как небольшой и эффективный язык, чтобы способствовать хорошему стилю программированию, использовать [[структурное программирование]] и структурированные данные.


К 1990-м годам Pascal стал одним из наиболее распространённых в мире алгоритмических языков программирования. Ведущие разработчики программного обеспечения регулярно выпускали новые версии своих компиляторов для этого языка. Популярные компиляторы того времени: Turbo Pascal (разработан компанией [[Borland]]), Microsoft Pascal Compiler, Quick Pascal, Pascal-2, Professional Pascal, USCD Pascal<ref name="Бородич и др., 1991">{{публикация|книга |автор=Бородич |автор имя=Ю. С. |автор2=Вальвачев |автор2 имя=А. Н. |автор3=Кузьмич |автор3 имя=А. И. |заглавие=Паскаль для персональных компьютеров |часть=Предисловие |страницы=3 |вид=справ. пособ. |место=Мн. |издательство=Вышэйшая школа |год=1991 |страниц=365 |иллюстрации=ил |isbn=5-339-00662-X |удк=681.3.06(035.5) |ббк=32.973-01я2 }}</ref>.
Компилятор Паскаля был написан на самом Паскале, используя «метод раскрутки», когда создается ядро языка, с постепенным наращивагием новых возможности.

== Реализации и диалекты ==
Язык Pascal имеет много реализаций<ref>{{Cite web|lang=|url=http://pascaland.org/pascall.htm|title=Liste compilateur Pascal - Pascal compiler list|author=|website=|date=|publisher=|access-date=2021-01-19|archive-date=2021-04-11|archive-url=https://web.archive.org/web/20210411042236/http://www.pascaland.org/pascall.htm|deadlink=no}}</ref>.


==Версии языка==
=== UCSD Pascal ===
=== UCSD Pascal ===
{{main|UCSD Pascal}}
В 1978 году в Университете Сан-Диего (Калифорния, США) была разработана система UCSD p-System, включавшая компилятор с языка Паскаль в переносимый p-код и реализовывавшая значительное число расширений языка Паскаль, такие как модули, строки символов переменной длины, директивы трансляции, обработка ошибок ввода-вывода, обращение к файлам по именам и пр. Впоследствии основные реализации языка Паскаль основывались на этом диалекте.
В 1978 году в [[Калифорнийский университет в Сан-Диего|Калифорнийском университете в Сан-Диего]] была разработана система UCSD p-System, включавшая [[Портирование программного обеспечения|порт]] компилятора Вирта с языка Паскаль в переносимый [[p-код]], редактор исходных кодов, файловую систему и прочее<ref>{{Cite web |url=http://oberoncore.ru/_media/library/n._wirth_-_recollections_about_the_development_of_pascal_hopl_ii_.pdf |title=Wirth N. Recollections about the development of Pascal (HOPL II), 3.3 |access-date=2011-04-16 |archive-date=2012-12-22 |archive-url=https://web.archive.org/web/20121222075737/http://oberoncore.ru/_media/library/n._wirth_-_recollections_about_the_development_of_pascal_hopl_ii_.pdf |deadlink=no }}</ref>, а также реализовывавшая значительное число расширений языка Паскаль, такие как модули, строки символов переменной длины, директивы трансляции, обработка ошибок ввода-вывода, обращение к файлам по именам и другое. Впоследствии основные реализации языка Паскаль основывались на этом диалекте.


=== Object Pascal ===
{{основная статья|UCSD Pascal}}
{{main|Object Pascal}}
В [[1986 год]]у фирма [[Apple]] разработала [[Объектно-ориентированное программирование|объектное]] расширение языка Паскаль, получив в результате [[Object Pascal]]. Он был разработан группой [[Ларри Теслер]]а, который консультировался с [[Вирт, Никлаус|Никлаусом Виртом]].


=== Object Pascal от Apple ===
=== Turbo Pascal и Object Pascal ===
{{main|Turbo Pascal}}
В [[1986 год]]у фирма [[Apple Computer]] разработала [[Объектно-ориентированное программирование|объектное]] расширение языка Паскаль, получив в результате [[Object Pascal]]. Он был разработан группой [[Ларри Теслер|Ларри Теслера]], который консультировался с [[Никлаус Вирт|Никлаусом Виртом]].
В [[1983 год]]у появилась первая версия [[Интегрированная среда разработки|интегрированной среды разработки]] Turbo Pascal фирмы [[Borland]], основывавшаяся на одноимённой реализации Паскаля.


В [[1989 год]]у объектное расширение языка было добавлено в Turbo Pascal версии 5.5.
=== Turbo Pascal и Object Pascal от Borland, Microsoft Pascal ===


Последняя версия (7.0) была переименована в Borland Pascal.
В [[1989 год]]у объектное расширение языка было добавлено фирмой Borland в [[Turbo Pascal]] версии 5.5 (начиная со следующей версии среда была переименована в Borland Pascal). Объектные средства были позаимствованы из Object Pascal от Apple, языковые различия между объектным Turbo Pascal 5.5 и Object Pascal от Apple крайне незначительны.


Объектные средства были позаимствованы из Object Pascal от Apple, языковые различия между объектным Turbo Pascal 5.5 и Object Pascal от Apple крайне незначительны.
В то же самое время, что и Borland, [[Microsoft]] выпустил свою версию объектно-ориентированного языка Паскаль.<ref>Jon Udell, Crash of the Object-Oriented Pascals, BYTE, July, 1989.</ref><ref>M.I.Trofimov, The End of Pascal?, BYTE, March, 1990, p.36.</ref> Эта версия Паскаля не получила широкого распространения.


Почти в то же самое время, что и Borland, [[Microsoft]] выпустил свою версию объектно-ориентированного языка Паскаль.<ref>Jon Udell, Crash of the Object-Oriented Pascals, BYTE, July, 1989.</ref><ref>M. I. Trofimov, The End of Pascal?, BYTE, March, 1990, p. 36.</ref> Эта версия Паскаля не получила широкого распространения.
Дальнейшее развитие реализации Паскаля от Borland породило [[Object Pascal]] от Borland, впоследствии, в ходе развития среды программирования [[Delphi (язык программирования)|Delphi]] получивший [[Delphi (язык программирования)|одноименное название]].


Дальнейшее развитие реализации Паскаля от Borland породило вариант [[Object Pascal]] от Borland, впоследствии, в ходе развития среды программирования [[Delphi (среда разработки)|Delphi]], получивший [[Delphi (язык программирования)|одноимённое название]].
{{основная статья|Turbo Pascal}}


=== MidletPascal ===
=== Современные версии Object Pascal ===
{{main|MIDletPascal}}
Важным шагом в развитии языка является появление свободных реализаций языка Паскаль [[Free Pascal]] и [[GNU Pascal]], которые не только вобрали в себя черты множества других диалектов языка, но и обеспечили чрезвычайно широкую переносимость написанных на нём программ (например GNU Pascal поддерживает более 20 различных платформ, под более чем 10 различными операционными системами, [[Free Pascal]] обеспечивает специальные режимы совместимости с различными распространёнными диалектами языка (Turbo Pascal (полная совместимость), Delphi и другими).


=== Современные реализации Pascal ===
В настоящее время, начиная с Delphi 2003, создана реализация языка для платформы .Net, хотя разработчики продолжают использовать Delphi более ранних версий.
==== 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, ориентированная на разработку приложений для платформы [[.NET Framework|Microsoft.Net]].
==== PascalABC.NET ====
B [[Южный федеральный университет|Южном федеральном университете]] разработан [[PascalABC.NET]] — язык программирования Паскаль, включающий большинство возможностей языка [[Delphi (язык программирования)|Delphi]], а также ряд собственных расширений. Он основан на платформе [[.NET Framework|Microsoft.NET]] и содержит практически все современные языковые средства: [[Класс (программирование)|классы]], [[перегрузка операторов|перегрузку операций]], [[Интерфейс (объектно-ориентированное программирование)|интерфейсы]], [[Обработка исключений|обработку исключений]], [[обобщённое программирование|обобщённые классы и подпрограммы]], [[сборка мусора (программирование)|сборку мусора]], [[Лямбда-выражение|лямбда-выражения]].
==== Pascal Next ====


Pascal Next – компилируемый, типизированный, алгоритмический, универсальный язык программирования и среда разработки, ориентированные на решение задачи '''обучения основам программирования'''.
О коммерческих разработках на [[Free Pascal]], [[GNU Pascal]] и [[TMT Pascal]] на данный момент известно мало.
В основе синтаксиса языка Pascal Next лежит синтаксис "классического" Паскаля Вирта. В то же время, синтаксис инструкций выбора и циклов заимствован из Basic, что позволило отказаться от избыточных begin.

Кроме того, в Южном Федеральном Университете разрабатывается язык и система программирования [[PascalABC.NET]], ориентированная на обучение современному программированию . Язык системы — это это [[Object Pascal]] для платформы [[Microsoft .NET|Microsoft&nbsp;.NET]], который содержит все основные элементы современных языков программирования: модули, классы, [[перегрузка операций|перегрузку операций]], [[Интерфейс (объектно-ориентированное программирование)|интерфейс]]ы, исключения, [[обобщенные классы (язык программирования)|обобщенные классы]], [[сборка мусора|сборку мусора]], а также некоторые средства [[Параллельное программирование|параллельного программирования]].


== Особенности языка ==
== Особенности языка ==
Особенностями языка являются [[строгая типизация]] и наличие средств [[Процедурное программирование|структурного (процедурного) программирования]]. Паскаль был одним из первых таких языков. По мнению Н.&nbsp;Вирта, язык должен способствовать дисциплинированию программирования, поэтому, наряду со строгой типизацией, в Паскале сведены к минимуму возможные синтаксические неоднозначности, а сам синтаксис автор постарался сделать интуитивно понятным даже при первом знакомстве с языком.
Особенностями языка являются [[строгая типизация]] и наличие средств [[Процедурное программирование|структурного (процедурного) программирования]]. Паскаль был одним из первых таких языков. По мнению Вирта, язык должен способствовать дисциплинированному программированию, поэтому, наряду со строгой типизацией, в Паскале сведены к минимуму возможные синтаксические неоднозначности, а сам синтаксис автор постарался сделать интуитивно понятным даже при первом знакомстве с языком.


Тем не менее, первоначально язык имел ряд ограничений: невозможность передачи функциям [[массив]]ов переменной длины, отсутствие нормальных средств работы с [[динамически распределяемая память|динамической памятью]], ограниченная [[библиотека ввода-вывода]], отсутствие средств для подключения функций написанных на других языках, отсутствие средств раздельной компиляции и т.&nbsp;п. <!--Наиболее бросающийся в глаза недостаток синтаксиса — некритически заимствованная из Алгола структура управляющих конструкций (операторов if и циклов), требующая, как правило, постоянного использования составных операторов «begin — end», хотя например в первоначальном варианте языка c они вообще отсутствовали.--> Подробный разбор недостатков языка Паскаль того времени был выполнен [[Керниган, Брайан Уильям|Брайаном Керниганом]] в статье «[http://www.lysator.liu.se/c/bwk-on-pascal.html Почему Паскаль не является моим любимым языком программирования]» (интересно, что эта статья вышла в начале 1980-х, когда уже существовал язык [[Модула-2]], потомок Паскаля, избавленный от большинства его пороков, а также более развитые диалекты Паскаля). Некоторые недостатки Паскаля были исправлены в ISO-стандарте 1982 года, в частности, в языке появились открытые массивы, давшие возможность использовать одни и те же процедуры для обработки одномерных массивов различных размеров.
Тем не менее, первоначально язык имел ряд ограничений: невозможность передачи функциям [[Массив (программирование)|массивов]] переменной длины, отсутствие нормальных средств работы с [[динамически распределяемая память|динамической памятью]], ограниченная [[библиотека ввода-вывода]], отсутствие средств для подключения функций, написанных на других языках, отсутствие средств раздельной компиляции и т. п.<!-- Наиболее бросающийся в глаза недостаток синтаксиса — некритически заимствованная из Алгола структура управляющих конструкций (операторов if и циклов), требующая, как правило, постоянного использования составных операторов «begin — end», хотя например в первоначальном варианте языка c они вообще отсутствовали.--> Подробный разбор недостатков языка Паскаль того времени был выполнен [[Керниган, Брайан Уильям|Брайаном Керниганом]] в статье «Почему Паскаль не является моим любимым языком программирования»<ref>{{Cite web |url=http://www.lysator.liu.se/c/bwk-on-pascal.html |title=Why Pascal is Not My Favorite Programming Language |access-date=2004-08-27 |archive-date=2009-04-28 |archive-url=https://web.archive.org/web/20090428163341/https://www.princeton.edu/~mike/unixhistory |deadlink=no }}</ref> (эта статья вышла в начале 1980-х, когда уже существовал язык [[Модула-2]], потомок Паскаля, избавленный от большинства его пороков, а также более развитые диалекты Паскаля). Некоторые недостатки Паскаля были исправлены в ISO-стандарте 1982 года, в частности, в языке появились открытые массивы, давшие возможность использовать одни и те же процедуры для обработки одномерных массивов различных размеров.


Необходимо заметить, что многие недостатки языка не проявляются или даже становятся достоинствами при обучении программированию. Кроме того, по сравнению с основным языком программирования в академической среде [[1970-е|70-х]] (которым был [[Фортран]], обладавший гораздо более существенными недостатками), Паскаль представлял собой значительный шаг вперёд. В начале 1980-х годов в СССР для обучения школьников основам информатики и вычислительной техники академик [[Ершов, Андрей Петрович|А.&nbsp;П.&nbsp;Ершов]] разработал алголо-паскалеподобный [[Алгоритмический язык|«алгоритмический язык»]].
Однако многие недостатки языка не проявляются или даже становятся достоинствами при обучении программированию. Кроме того, по сравнению с основным языком программирования в академической среде [[1970-е|1970-х]] (которым был [[Фортран]], обладавший гораздо более существенными недостатками), Паскаль представлял собой значительный шаг вперёд. К 1980-м годам Паскаль стал основой для многочисленных учебных программ, в отдельных случаях на его основе были созданы специализированные обучающие языки программирования, так, в начале 1980-х годов в СССР для обучения школьников основам информатики и вычислительной техники [[Ершов, Андрей Петрович|Андрей Ершов]] разработал алголо-паскалеподобный «[[учебный алгоритмический язык]]».


Наиболее известной реализацией Паскаля, обеспечившей широкое распространение и развитие языка, является Turbo Pascal фирмы [[Borland]], выросшая затем в объектный Паскаль для DOS (начиная с версии 5.5) и Windows и далее в Delphi, в которой были внедрены значительные расширения языка.
<!-- орисс
Никлаус Вирт понимал недостатки созданного им языка, но, следуя традициям академической среды и собственным принципам, согласно которым «неподходящий инструмент надо не исправлять, а заменять», не стал его развивать дальше, а разработал новые языки семейства: [[Модула-2]] и [[Оберон (язык программирования)|Оберон]]. В противоположность этому промышленные традиции и достоинства языка побудили многие коммерческие и некоммерческие организации продолжать разрабатывать и развивать системы программирования именно на основе языка Паскаль, подвергая язык произвольному расширению, добавляя в него, часто совершенно механически, новые средства и синтаксические конструкции.-->


== Стандарты ==
Наиболее известной реализацией Паскаля, обеспечившая широкое распространение и развитие языка является [[Turbo Pascal]] фирмы [[Borland]], выросшая затем в объектный Паскаль для DOS (начиная с версии 5.5) и Windows и далее в Delphi, в которой использовались значительные расширения языка.
После начала использования Паскаля в [[1970&nbsp;год]]у и появления реализаций, расходящихся не только в дополнениях, но и в синтаксисе, был поднят вопрос о стандартизации языка. Стандарт языка был разработан Никлаусом Виртом в [[1974&nbsp;год]]у совместно с Кетлин Йенсен (Kathleen Jensen).<ref>[https://www.amazon.com/Pascal-User-Manual-Report-Standard/dp/0387976493/ref=sr_1_1/104-1876135-1071931?ie=UTF8&s=books&qid=1194117642&sr=1-1#reader PASCAL: User Manual and Report] ISO Pascal Standard Kathleen Jensen and Niklaus Wirth, 4th edition, Springer Verlag New York, Inc. 1974, 1985, 1991</ref> В дальнейшем были приняты международный стандарт ISO и американский ANSI. На данный момент выделяют три принципиально разных стандарта: Unextended Pascal (исходный), Extended Pascal (расширенный), Object-Oriented Extensions to Pascal (объектно-ориентированное расширение Паскаля).


{| class="standard"
Диалекты Паскаля, применяемые в Turbo Pascal для DOS и Delphi для Windows, из-за отстутствия других успешных коммерческих реализаций стали популярны.
|+ Стандарты языка Pascal: исходный, международные [[ISO]] и американские [[ANSI]]
! Название || Вариант || Кем/где разработан || Год создания
|-
!Pascal Standard
| исходный || Н. Вирт, Кетлин Йенсен || [[1974]]
|-
! Pascal Standard
| исходный || ISO 7185:1983<br>ANSI/[[IEEE]] 770X3.97:1983 || [[1982]]
|-
! Unextended Pascal
| исходный || ISO 7185:1990 || [[1989]]
|-
!rowspan="2"| Extended Pascal
|rowspan="2"| расширенный
| ANSI/IEEE 770X3.160:1989 || 1989
|-
| ISO/[[IEC]] 10206 || [[1991]]
|-
! Object-Oriented<br>Extensions to Pascal<ref>[http://pascal-central.com/OOE-stds.html Object-Oriented Extensions to Pascal] {{Wayback|url=http://pascal-central.com/OOE-stds.html |date=20210605064414 }}, Technical Committee X3J9, Programming Language Pascal</ref>
| объектно-ориентированное расширение || ANSI/X3-TR-13:1994 || [[1993]]
|}
Одним из главных дополнительных свойств объектно-ориентированного расширения Extended Pascal стала модульность и средства, облегчающие раздельную компиляцию.


Стандартизация языка была запаздывающей по отношению к реальному появлению в языке тех или иных возможностей. Коммерческие реализации расширяли стандартный Паскаль; так было сделано в UCSD Pascal, модификации [[Object Pascal]] фирмой Apple, Turbo Pascal от Borland (незначительно модифицированная версия Apple) и его ответвлений. Ни одна из распространённых коммерческих реализаций Паскаля не соответствует в точности ни одному из официальных стандартов языка.
Объектный Паскаль от Borland и в отсутствие отраслевой стандартизации стал сильно отличаться от классического Паскаля. <!-- не надо путать среду и язык - здесь речь идёт как раз о стандартизации де-факто и распространении диалекта языка, принятого Borland -->


== Синтаксис и языковые конструкции ==
== Стандарты языка Паскаль ==
Паскаль, в его первоначальном виде, представляет собою чисто [[Процедурное программирование|процедурный язык]] и включает в себя множество алголоподобных структур и конструкций с зарезервированными словами наподобие <code>if</code>, <code>then</code>, <code>else</code>, <code>while</code>, <code>for</code>, <code>repeat</code> и т. д. Тем не менее, Паскаль также содержит большое количество возможностей для структурирования информации и абстракций, которые отсутствуют в изначальном [[Алгол-60|Алголе-60]], такие как [[Тип данных|определение типов]], [[Структура (программирование)|записи]], [[Указатель (тип данных)|указатели]], [[Перечислимый тип|перечисления]], и [[Множество|множества]]. Эти конструкции были частично унаследованы или инспирированы от языков [[Симула]]-67, [[Алгол-68]]{{Нет АИ|26|5|2013}}<!-- сравнивая А68 с А60 и паскалем, вижу, что Паскаль — почти А60, А68 наблюдаю скорее в C++ -->, созданного [[Вирт, Никлаус|Никлаусом Виртом]] {{нп3|AlgolW}} и предложены [[Хоар, Чарльз Энтони Ричард|Хоаром]].
После нескольких лет эксплуатации Паскаля и появления реализаций, расходящихся не только в части расширений, но и в основной части языка, был поднят вопрос о стандартизации языка. Впервые это было сделано в 1977 году на конференции по Паскалю в Саутгемптоне. Реальная работа по стандартизации языка и появившихся уже к тому времени его расширений началась в 1978 году, после конференции в Сан-Диего (США).


В современных диалектах (Delphi Pascal, Free Pascal) доступны такие операции, как перегрузка операторов и функций.
Принято выделять три принципиально разных стандарта: Unextended Pascal (исходный), Extended Pascal (расширенный) и Object-Oriented Extensions to Pascal (объектно-ориентированный).


=== Hello, world! ===
* В 1982 году выпущен стандарт ISO 7185:1983 — международный стандарт исходного Паскаля. Одновременно появился соответствующий ему американский стандарт ANSI/IEEE 770X3.97:1983. В 1989 г. стандарт ISO 7185:1983 был подкорректирован, после чего надобность в самостоятельном ANSI-стандарте отпала и он был заменен ссылкой на ISO 7185:1990.
Программы на Паскале начинаются с [[зарезервированное слово|ключевого слова]] <code>Program</code> и следующего за ним имени программы с '''точкой с запятой''' (в некоторых диалектах является необязательным),
* Extended Pascal был закреплен международным стандартом ISO/IEC 10206 (1991) и американским ANSI/IEEE 770X3.160:1989. Одним из главных дополнительных свойств Extended Pascal стала модульность и средства, облегчающие раздельную компиляцию.
за именем может в скобках следовать список внешних файловых дескрипторов («окружение») в качестве параметров;
* Объектно-ориентированное расширение Extended Pascal было описано в техническом отчете ANSI/X3-TR-13:1994.
за ним следует тело программы, состоящее из ''секций описания''
'''констант''' (<code>Const</code>),
'''типов''' (<code>Type</code>),
'''переменных''' (<code>Var</code>),
''объявлений'' '''процедур''' (<code>Procedure</code>)
и '''функций''' (<code>Function</code>)
и следующего за ними [[Блок (программирование)|блока операторов]], являющегося '''точкой входа''' в программу.
В языке Паскаль '''блок''' ограничивается ключевыми словами <code>begin</code> и <code>end</code>.
Операторы разделяются [[Точка с запятой|точками с запятой]],
после тела помещается [[Точка (знак препинания)|точка]],
служащая признаком конца программы.


[[Чувствительность к регистру символов|Регистр символов]]
Стандартизация языка была запаздывающий по отношению к реальному появлению в языке тех или иных возможностей. Коммерческие реализации расширяли стандартный Паскаль; так было сделано в UCSD&nbsp; Pascal, модификации [[Object Pascal]] фирмой Apple, Turbo Pascal от Borland (незначительно модифицированная версия Apple) и его ответвлений. Ни одна из распространённых коммерческих реализаций Паскаля не соответствует в точности ни одному из официальных стандартов языка.
в Паскале не имеет значения.

== Синтаксис и языковые конструкции ==
Паскаль, в его первоначальном виде, представляет собою чисто [[Процедурное программирование|процедурный язык]] и включает в себя множество [[Алгол]]оподобных структур и конструкций с зарезервированными словами наподобие '''if''', '''then''', '''else''', '''while''', '''for''', и т. д. Тем не менее, Паскаль также содержит большое количество возможностей для структурирования информации и абстракций, которые отсутствуют в изначальном [[Алгол|Алголе-60]], такие как [[Тип данных|определение типов]], [[Запись (тип данных)|записи]], [[Указатель|указатели]], [[Перечислимый тип|перечисления]], и [[Множество|множества]]. Эти конструкции были частично унаследованы или инспирированы от языков [[Симула|Симула-67]], [[Алгол-68]], созданного [[Никлаус Вирт|Никлаусом Виртом]] [[AlgolW]] и предложены [[Хоар, Чарльз Энтони Ричард|Хоаром]].
В современных диалектах (Free Pascal) доступны такие операции как перегрузка операторов и функций.

=== Hello world ===
Программы на Паскале начинаются с [[зарезервированное слово|ключевого слова]] '''program''' и следующего за ним имени программы с точкой с запятой (в большинстве диалектов является необязательным), за именем может в скобках следовать список внешних файловых дескрипторов в качестве параметров; за ним следует тело программы, состоящее из секций описания переменных, типов и констант, объявлений процедур и функций и следующего за ними [[Блок (программирование)|блока операторов]] являющегося точкой входа в программу, в языке Паскаль блок ограничивается ключевыми словами '''begin''' и '''end'''. Операторы разделяются [[Точка с запятой|точками с запятой]], после тела помещается [[Точка (знак препинания)|точка]], служащая признаком конца программы. [[Регистр символов]] в Паскале не имеет значения.

Таким образом, простейшая программа на Паскале будет выглядеть следующим образом:


Таким образом, простейшая («пустая») программа на Паскале будет выглядеть следующим образом:
<source lang="pascal">
<source lang="pascal">
program p;
begin
begin
end.
end.
</source>
</source>
Программа не выполняет никаких действий и содержит пустой блок операторов.
Приведённая выше программа не выполняет никаких действий и содержит '''пустой блок''' операторов.

Пример программы, выводящей строку 'Hello, World!':


Пример программы, выводящей строку «[[Hello, world!]]»:
<source lang="pascal">
<source lang="pascal" line="1">
Program HelloWorld(output);
program hello;
begin
begin
writeLn('Hello, World!'); { оператор вывода строки }
writeln('Hello, World!'); // оператор вывода строки
end.
end.
</source>
</source>


=== Типы данных ===
=== Типы данных ===

''Примитивные'' типы данных Паскаля: типы с плавающей запятой ([[Числа с плавающей запятой|real]]), целые ([[Целый тип|integer]]), [[Символьный тип|char]], [[Логический тип|boolean]] и [[Перечислимый тип|перечисления]] (конструктор нового типа, введённый в Паскале):
==== Простые типы ====
В стандартном и расширенном Паскале есть такие '''простые''' типы: [[числа с плавающей запятой]] (<code>real</code>), [[Целый тип|целые]] (<code>integer</code>), [[Символьный тип|символьный]] (<code>char</code>), [[Логический тип|логический]] (<code>boolean</code>) и [[Перечислимый тип|перечисления]] (конструктор нового типа, введённый в Pascal).

[[Turbo Pascal]] дополнил язык вариациями этих типов: например, <code>shortint</code> будет короче <code>integer</code>, а <code>longint</code> — длиннее.

Современные диалекты Pascal, такие, как [[FPC]] или [[Delphi (язык программирования)|Delphi]], считают, что <code>integer</code> — это наиболее подходящий для данной машины целый, применяемый, например, для [[массив (программирование)|индексов массива]], а <code>shortint</code>, <code>longint</code> и другие — целые определённой длины; это удобно при [[кроссплатформенное ПО|кроссплатформенном]] программировании. Аналогично и с дробными числами.

Ещё раз расширили типы при переходе на [[x64]] — «просто целое» (<code>integer</code>) осталось 32-битным, но потребовался особый тип, который равен <code>longint</code> на x86 и <code>int64</code> на x64.

Целочисленные типы:
{| class="wikitable"
! Тип !! Диапазон !! Формат !! Размер в байтах !! Примечания
|-
| 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
|}
Числа с плавающей запятой:
{|class="wikitable"
|-
!Тип !! Диапазон !! Кол-во значащих цифр!! Размер в байтах !! Поддержка
|-
| 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 || colspan=2| −9223372036854775808..9223372036854775807 || 8 || Borland; рассчитываемое на сопроцессоре 8-байтовое целое; актуально для 16-битного x86
|-
| Currency || colspan=2 | −922337203685477.5808..922337203685477.5807 || 8 || Borland и другие компиляторы под Windows; связано с [[OLE]]; [[фиксированная запятая]] с единицей, равной 10000
|}


<source lang="pascal">
<source lang="pascal">
Строка 112: Строка 215:
c: Char; { переменная-символ }
c: Char; { переменная-символ }
b: Boolean; { логическая переменная }
b: Boolean; { логическая переменная }
s: String; { переменная строки }
t: Text; { переменная для объявления текстового файла }
e: (apple, pear, banana, orange, lemon); { переменная типа-перечисления }
e: (apple, pear, banana, orange, lemon); { переменная типа-перечисления }
</source>
</source>


В Pascal над целыми типами (byte, shortint, word, integer, longint и их диапазоны) допустимы побитовые операции. Логические операции над битами:
Выделяется понятие ''порядковых'' типов данных (''ordinal''), к ним относятся целые типы(знаковые и беззнаковые), логический ([[Логический тип|boolean]]), символьный ([[Символьный тип|char]]), [[Перечислимый тип|перечислимые типы]] и типы-диапазоны.


Над битами двух целых операндов можно выполнять ранее рассмотренные логические операции: not, and, or, xor. Отличие между побитовыми и логическими операциями состоит в том, что побитовые (поразрядные) операции выполняются над отдельными битами операндов, а не над их значением в десятичном (обычно) представлении.
Порядковые типы задаются целым числом(кодом), которое можно получить с помощью функции ord. Все операции, выполняемые над порядковыми типами, выполняются с их кодами.

Выделяется понятие ''порядковых'' типов данных (ordinal), к ним относятся целые типы (знаковые и беззнаковые), логический (<code>boolean</code>), символьный (<code>char</code>), перечислимые типы и типы-диапазоны.

Порядковые типы задаются целым числом (кодом), которое можно получить с помощью функции ord. Все операции, выполняемые над порядковыми типами, выполняются с их кодами.


Диапазоны содержат подмножество значений других порядковых типов:
Диапазоны содержат подмножество значений других порядковых типов:
Строка 126: Строка 235:
z: pear..orange;
z: pear..orange;
</source>
</source>
Для порядковых типов определены операции <code>inc</code>, <code>dec</code>, <code>succ</code>, <code>pred</code>, <code>ord</code>, операции сравнения (<code>=</code> <code>&gt;</code> <code>&lt;</code> <code>=&gt;</code> <code>&lt;=</code> <code>&lt;&gt;</code>), их можно использовать в операторах <code>case</code>, <code>for</code> (как счётчик цикла), как границы массивов, для задания элементов множеств и типов-диапазонов.


В Pascal, в отличие от Си-подобных языков, с типами <code>boolean</code> и <code>char</code> арифметические целочисленные операции не определены.
Для порядковых типов определены операции ''inc, dec, succ, pred, ord'', операции сравнения(=,>,<,=>,<=,<>), их можно использовать в операторах '''case''', '''for''' (как счётчик цикла), как границы массивов, для задания элементов множеств и типов-диапазонов.

В паскале в отличие от си-подобных языков с типами boolean, char арифметические целочисленные операции не определены.

В отличие от многих распространённых языков, Паскаль поддерживает специальный тип данных ''множество'':


==== Множества ====
В отличие от многих распространённых языков, Pascal поддерживает специальный тип данных ''множество'':
<source lang="pascal">
<source lang="pascal">
var
var
Строка 139: Строка 247:
set3: set of pear..orange;
set3: set of pear..orange;
</source>
</source>

Множество — фундаментальное понятие в современной математике, которое может быть использовано во многих алгоритмах.
Множество — фундаментальное понятие в современной математике, которое может быть использовано во многих алгоритмах.
В паскале тип множество может содержать только однотипные элементы порядкового типа.
Эта особенность широко используется и обычно быстрее эквивалентной конструкции в языке, не поддерживающем множества. К примеру, для большинства компиляторов Паскаля:


В паскале тип множество может содержать только однотипные элементы порядкового типа. Эта особенность широко используется и обычно быстрее эквивалентной конструкции в языке, не поддерживающем множества. К примеру, для большинства компиляторов Паскаля:
<source lang="pascal">
<source lang="pascal">
if i in [5..10] then { проверка на принадлежность элемента множеству }
if i in [5..10] then { проверка на принадлежность элемента множеству }
...
...
</source>
</source>

обработается быстрее, чем
обработается быстрее, чем

<source lang="pascal">
<source lang="pascal">
if (i>4) and (i<11) then { проверка логическими условиями }
if (i>=5) and (i<=10) then { проверка логическими условиями }
...
...
</source>
</source>
Для задания значения множества используется список элементов множества, отделённых запятыми и заключённый в квадратные скобки (как уже было показано выше):

Для задания значения множества используется <!-- ''конструктор множества''(<ref>[http://thor.kubsu.ru/index.php/corporate/informatika/klassifikator_predmetnyh_znanij/yazyk_programmirovaniya_turbo_pascal/strukturirovannye_tipy_dannyh/mnozhestva Тип данных множество в Паскале]</ref>)-

Попытайтесь найти термин «конструктор множества» применительно к языку Паскаль в авторитетном источнике, например в стандарте ISO или у Вирта, а не в какой-то левой методичке. Слово «конструктор» в программировании имеет вполне определённый смысл, это блок кода. Данная конструкция (список установленных битов в машинном слове) им не является.
--> список элементов множества, отделенных запятыми и заключённый в квадратные скобки (как уже было показано выше):
<source lang="pascal">
<source lang="pascal">
var { секция объявления переменных }
var { секция объявления переменных }
d:set of char;
d:set of char;
begin { начало блока }
begin { начало блока }
d:=['a','b'];
d:=['a','b'];
...
...
</source>
</source>
В Паскале Йенсен и Вирта строки представлялись как упакованные массивы символов; следовательно, они имели фиксированную длину и обычно дополнялись до этой длины пробелами.


==== Составные типы ====
<small>В Паскале Йенсен и Вирта строки представлялись как упакованные массивы символов; следовательно, они имели фиксированную длину и обычно дополнялись до этой длины пробелами.
</small><br />
В современном <ref>[http://www.cs.bilkent.edu.tr/~guvenir/courses/CS315/iso7185pascal.pdf ISO 7185 Pascal]</ref> Паскале для работы со строками используется встроенный тип '''string''', поддерживающий операции конкатенации('''+''') и сравнения (>,<,=,<>,>=,<=). Строки сравниваются в [[Лексикографический порядок|лексикографическом порядке]]. Например, строки считаются равными если они имеют одинаковую длину и коды всех символов с одинаковыми индексами совпадают.
Тип '''string [n]''' или просто '''string''' в диалектах языка 1970-х — 1990-х гг. определялся в виде массива символов ''array [0..n] of char'' (n по умолчанию принимало значение 80 в UCSD Pascal и 255 в Turbo/Borland Pascal), код нулевого символа при таком представлении служит для задания длины строки, соответственно строка могла иметь максимальный размер 255 символов. По умолчанию в качестве String используется тип AnsiString в старых версиях [[Delphi]] (теперь [[юникод]]) и [[Free Pascal]], память под который выделяется и освобождается компилятором динамически, а максимальный размер строки в текущих реализациях составляет 2 гигабайта. Кроме того, в [[Delphi]] и [[Free Pascal]] в качестве '''string''' может использоваться тип WideString, где применяется 16-битное представление символов в кодировке [[UCS-2|UCS2]]. <!--В то же время, многие операции над строками AnsiString в текущих версиях систем программирования реализованы через ориентированный на язык Си API, в результате чего символ с нулевым кодом может восприниматься при обработке как признак конца строки, в отличие от '''string'''.<ref>[http://www.cyberguru.ru/programming/delphi/strings-details-page6.html Тонкости работы со строками в Delphi. Нулевой символ в середине строки]</ref> //тип pChar используется сам по себе как указатель на c-подобную строку, то есть с типом AnsiString как таковым это не связано-->

Новые типы могут быть определены из существующих:
Новые типы могут быть определены из существующих:

<source lang="pascal">
<source lang="pascal">
type { секция объявления типов }
type { секция объявления типов }
Строка 184: Строка 279:


Более того, из примитивных типов могут быть сконструированы составные:
Более того, из примитивных типов могут быть сконструированы составные:

<source lang="pascal">
<source lang="pascal">
type { секция объявления типов }
type { секция объявления типов }
Строка 194: Строка 288:
c = File of a; { определение файла }
c = File of a; { определение файла }
</source>
</source>

Файловые типы в Паскале делятся на типизированные, текстовые и файлы без типов.
Файловые типы в Паскале делятся на типизированные, текстовые и файлы без типов.
Как показано в вышеприведённом примере, типизированные [[файл]]ы в Паскале — это последовательности однотипных элементов. Для каждого файла существует переменная-указатель на буфер, которая обозначается ''f^''. Процедуры ''get'' (для чтения) и ''put'' (для записи) перемещают указатель к следующему элементу. Чтение реализовано так, что ''read(f, x)'' представляет собою то же, что и ''get(f); x:=f^;''. Соответственно, запись реализована так, что ''write(f, x)'' представляет собою то же, что и ''f^ := x; put(f);'' Текстовые файлы '''text''' определены как расширение типа '''file of char''' и помимо стандартных операций над типизированными файлами(чтение, запись символа), позволяют осуществлять символьный ввод-вывод в файл всех типов данных аналогично консольному вводу-выводу.


Как показано в вышеприведённом примере, типизированные [[файл]]ы в Паскале — это последовательности однотипных элементов. Для каждого файла существует переменная-указатель на буфер, которая обозначается <code>f^</code>. Процедуры <code>get</code> (для чтения) и <code>put</code> (для записи) перемещают указатель к следующему элементу. Чтение реализовано так, что <code>read(f, x)</code> представляет собою то же, что и <code>get(f); x:=f^</code>. Соответственно, запись реализована так, что <code>write(f, x)</code> представляет собою то же, что и <code>f^ := x; put(f)</code>. Текстовые файлы <code>text</code> определены как расширение типа <code>file of char</code> и помимо стандартных операций над типизированными файлами (чтение, запись символа), позволяют осуществлять символьный ввод-вывод в файл всех типов данных аналогично консольному вводу-выводу.
Файлы без типов объявляются как переменные типа '''file'''. С ними можно проводить операции побайтового нетипизированного ввода-вывода по несколько блоков байт указанной длины через буфер, для этого служат специальные процедуры ''blockread'' и ''blockwrite''.


Файлы без типов объявляются как переменные типа <code>file</code>. С ними можно проводить операции побайтового нетипизированного ввода-вывода по несколько блоков байт указанной длины через буфер, для этого служат специальные процедуры <code>blockread</code> и <code>blockwrite</code> (расширение UCSD).
==== Указатели ====
Паскаль поддерживает использование [[Указатель (тип данных)|указателей]] (типизированные ''^тип'' и нетипизированные ''pointer''):


==== Строки ====
В современном Паскале<ref>{{Cite web |url=http://www.cs.bilkent.edu.tr/~guvenir/courses/CS315/iso7185pascal.pdf |title=ISO 7185 Pascal |access-date=2009-04-12 |archive-date=2006-11-25 |archive-url=https://web.archive.org/web/20061125202811/http://cs.bilkent.edu.tr/%7Eguvenir/courses/CS315/iso7185pascal.pdf |deadlink=no }}</ref> для работы со строками используется встроенный тип <code>string</code>, поддерживающий операции конкатенации (<code>+</code>) и сравнения (<code>&gt;</code> <code>&lt;</code> <code>=</code> <code>&lt;&gt;</code> <code>&gt;=</code> <code>&lt;=</code>). Строки сравниваются в [[Лексикографический порядок|лексикографическом порядке]]. Например, строки считаются равными, если они имеют одинаковую длину и коды всех символов с одинаковыми индексами совпадают.

Тип <code>string [n]</code> или просто <code>string</code> в диалектах языка 1970—1990-х годов определялся в виде массива символов <code>array [0..n] of char</code> (n по умолчанию принимало значение 80 в UCSD Pascal и 255 в Turbo/Borland Pascal),
нулевой элемент массива при таком представлении служит для задания длины строки, соответственно строка могла иметь максимальный размер 255 символов. <!--По умолчанию в качестве String используется тип AnsiString в старых версиях Delphi (теперь [[юникод]]) и [[Free Pascal]]-- не совсем грамотно сформулировано- юникод это не тип данных. надо убрать либо перефразировать-->По умолчанию в Delphi и FreePascal в качестве String используется тип AnsiString, память под который выделяется и освобождается компилятором динамически, а максимальный размер строки в текущих реализациях составляет 2 гигабайта. Кроме того, в Delphi и Free Pascal в качестве <code>string</code> может использоваться тип UnicodeString, где применяется 16-битное представление символов в кодировке [[UCS-2]], при этом средства преобразования из однобайтовых строк в многобайтовые и обратно в стандартной библиотеке FPC отсутствуют, но имеются в Delphi.<!--В то же время, многие операции над строками <code>AnsiString</code> в текущих версиях систем программирования реализованы через ориентированный на язык Си API, в результате чего символ с нулевым кодом может восприниматься при обработке как признак конца строки, в отличие от <code>string</code>.<ref>[http://www.cyberguru.ru/programming/delphi/strings-details-page6.html Тонкости работы со строками в Delphi. Нулевой символ в середине строки]</ref> //тип pChar используется сам по себе как указатель на c-подобную строку, то есть с типом AnsiString как таковым это не связано-->

В Delphi 2009 и выше имеется конструкция для объявления AnsiString с определённой кодовой страницей:
<source lang="pascal">
<source lang="pascal">
type
type
CyrillicString = AnsiString(1251);
CP866String = AnsiString(20866);
</source>

==== Указатели ====
Паскаль поддерживает использование [[Указатель (тип данных)|указателей]] (типизированные <code>^тип</code> и нетипизированные <code>pointer</code>):
<source lang="pascal">
type
a = ^b;
a = ^b;
b = record
b = record
Строка 214: Строка 320:
pointer_to_b:a;
pointer_to_b:a;
</source>
</source>
Здесь переменная <code>pointer_to_b</code> — указатель на тип данных <code>b</code>, являющийся записью. Типизированный указатель может быть определён (''опережающее определение'') перед объявлением типа, на который он ссылается. Это одно из ''исключений'' к '''правилу''', которое гласит, что ''любой элемент (константа, тип, переменная, процедура, функция) должен быть объявлен перед тем, как используется''. Введение этого исключения позволяет организовывать ''рекуррентные'' определения структур данных, в том числе такие, как [[Линейный список|линейные списки]], [[стек]]и, [[Очередь (программирование)|очереди]], [[Дерево (структура данных)|деревья]], включая указатель на запись в описание этой записи (см. также: нулевой указатель — <code>nil</code>).


Для типизированного указателя определена операция '''разыменования''' (её синтаксис: <code>указатель^</code>).
Здесь переменная ''pointer_to_b'' — указатель на тип данных ''b'',являющийся записью. Тип типизированного указателя может быть задан перед объявлением типа на который он ссылается. Это исключение к правилу, которое гласит, что любая вещь должная быть объявлена перед тем, как используется. Введение этого исключения позволило организовывать рекуррентные определения структур данных, в том числе такие, как [[Линейный список|линейные списки]], [[стек]]и и [[Очередь (программирование)|очереди]], включая указатель на запись в описании этой записи (см. также нулевой указатель ([[Указатель (тип данных)|nil]])).

Для типизированного указателя определена операция [[Указатель (тип данных)|разыменования]] (её синтаксис: ''указатель^'')

Чтобы создать новую запись и присвоить значение ''10'' и символ ''A'' полям ''a'' и ''b'' в ней, необходимы следующие операторы:


Чтобы создать новую запись и присвоить значение <code>10</code> и символ <code>A</code> полям <code>x</code> и <code>y</code> в ней, необходимы следующие операторы:
<source lang="pascal">
<source lang="pascal">
new(pointer_to_b); { выделение памяти указателю }
new(pointer_to_b); { выделение памяти указателю }


pointer_to_b^.x := 10; { разыменовывание указателя и обращение к полю записи }
pointer_to_b^.x := 10; { разыменовывание указателя и обращение к полю записи }
pointer_to_b^.y := 'A';
pointer_to_b^.y := 'A';
pointer_to_b^.z := nil;
pointer_to_b^.z := nil;
...
...
dispose(pointer_to_b); { освобождение памяти из-под указателя }
dispose(pointer_to_b); { освобождение памяти из-под указателя }
</source>
</source>
Для целей обращения к полям записей и объектов можно также использовать оператор <code>with</code>, как показано в примере:

Для целей обращения к полям записей и объектов можно также использовать оператор '''with''', как показано в примере:

<source lang="pascal">
<source lang="pascal">
new(pointer_to_b);
new(pointer_to_b);
Строка 246: Строка 348:
</source>
</source>


==== Процедурный тип ====
=== Операторы управления выполнением программы ===
В оригинальном языке Паскаль Йенсен и Вирта процедурный тип использовался только при описании формального параметра. Уже в TP существовал полноправный [[Делегат (программирование)|процедурный тип]]. В объявлении типа ставится заголовок процедуры либо функции (без имени), обобщённо описывающий интерфейс подпрограммы. Значение этого типа содержит указатель на подпрограмму с заголовком, соответствующую описанному в объявлении типа. С помощью идентификатора переменной может происходить вызов соответствующей процедуры или функции.
Паскаль — язык [[Структурное программирование|структурного программирования]], что означает, что программа состоит из выполняющихся последовательно отдельных стандартных операторов, в идеале — без использования команды '''[[GOTO]]'''.
{{Hider hiding
|title=Пример подпрограмм для Pascal
|content=
<source lang="pascal">
type myfunc=function:string;

function func1:string;
begin
func1:='func № 1'
end;

function func2:string;
begin
func2:='func № 2'
end;

var fun:myfunc;
begin
fun:=@func1;
writeln(fun) {происходит вызов функции func1}
end.
</source>
}}


=== Операторы управления ===
Паскаль — язык [[Структурное программирование|структурного программирования]], что означает, что программа состоит из выполняющихся последовательно отдельных стандартных операторов, в идеале — без использования команды <code>[[GOTO]]</code>.
{{Hider hiding
|title=Пример для Pascal
|content=
<source lang="pascal">
<source lang="pascal">
while a <> b do { цикл с предусловием }
while a <> b do { цикл с предусловием }
writeln('Ожидание');
writeln('Ожидание');

if a > b then { условный оператор }
if a > b then { условный оператор }
writeln('Условие выполнилось')
writeln('Условие выполнилось')
else { else-секция - может отсутствовать}
else { else-секция - может отсутствовать}
writeln('Условие не выполнилось');
writeln('Условие не выполнилось');

for i := 1 to 10 do { итерационный цикл }
for i := 1 to 10 do { итерационный цикл }
writeln('Итерация №', i:1);
writeln('Итерация №', i:1);

for i in [1..10] do { итерационный цикл по множеству }
repeat { цикл с постусловием }
writeln('Итерация №', i:1); { появился в версии 2.4.0 }

with a do {Оператор With - метод ускорения доступа к полям записи}
begin
l:=1;
k:=2;
p:=-3;
end;

repeat { цикл с постусловием }
a := a + 1
a := a + 1
until a = 10;
until a = 10;


case i of { условный оператор множественного выбора }
case i of { условный оператор множественного выбора }
0: write('ноль');
0: write('ноль');
1: write('один');
1: write('один');
Строка 272: Строка 412:
end;
end;
</source>
</source>
}}
В операторах <code>while</code>, <code>for</code>, <code>if</code>, <code>case</code> в качестве выполняемого оператора может использоваться ''блок''. Такая конструкция, представляющая собой обычный оператор или блок, называется ''сложным оператором''.


В Turbo Pascal для управления процессом компиляции существуют директивы, которые помещаются в комментарии и позволяют переключать режимы работы компилятора — например, включать и отключать проверку операций ввода-вывода, переполнения:
В операторах ''while, for, if, case'' в качестве выполняемого оператора может использоваться ''блок''. Такая конструкция, представляющая собой обычный оператор или блок, называется ''сложным оператором''.
{{Hider hiding

|title=Пример для Pascal
Для управления процессом компиляции в паскале существуют директивы компилятора, они помещаются в комментарии и позволяют переключать режимы работы компилятора, например включать и отключать проверку операций ввода-вывода, проверки переполнения:
|content=
<source lang="pascal">
<source lang="pascal">
assign(inp,'text.txt');
assign(inp,'text.txt');
Строка 287: Строка 430:
end else writeln('file not found')
end else writeln('file not found')
</source>
</source>
}}

Существуют директивы, аналогичные директивам препроцессора C/C++ ($ifdef, $define, $include), они обрабатываются компилятором в процессе компиляции.
Существуют директивы, аналогичные директивам препроцессора C/C++ (<code>$ifdef</code>, <code>$define</code>, <code>$include</code>), они обрабатываются компилятором в процессе компиляции.


=== Процедуры и функции ===
=== Процедуры и функции ===
В Паскале подпрограммы делятся на процедуры и функции:
В Паскале подпрограммы делятся на процедуры и функции. При этом, функции явно возвращают значение (результат) определённого типа, а процедуры явно ничего не возвращают.

Синтаксически процедуры и функции состоят из ''заголовка''(содержащего ключевое слово ''procedure'' или ''function'', имени, за которым может следовать описание передаваемых параметров в скобках, тип возвращаемого значения через символ двоеточия для функций и точки с запятой), после заголовка следует ''тело'', после которого ставится символ '';''.


Синтаксически описание процедуры или функции состоит из ''заголовка'', содержащего ключевое слово <code>procedure</code> или <code>function</code>, имени, за которым может следовать описание передаваемых (формальных) параметров в скобках. Для функции через символ «двоеточие» <code>:</code> указывается тип возвращаемого значения. Заголовок заканчивается символом «точка с запятой» <code>;</code>. После заголовка следует ''тело'', (возможно) содержащее секции описания локальных констант, типов, переменных, процедур, функций и (обязательно) содержащее блок операторов, после которого ставится символ «точка с запятой» <code>;</code>.
{{Hider hiding
|title=Пример программы для Pascal
|content=
<source lang="pascal">
<source lang="pascal">
program mine(output);
program mine(output);


var i : integer;
var i : integer;

procedure print(var j: integer);
procedure print(var j: integer);

function next(k: integer): integer;
function next(k: integer): integer;
begin
begin
next := k + 1
next := k + 1
end;
end;

begin
begin
writeln('Всего: ', j);
writeln('Всего: ', j);
j := next(j)
j := next(j)
end;
end;

begin
begin
i := 1;
i := 1;
Строка 318: Строка 463:
end.
end.
</source>
</source>
}}
Тело процедуры, как и программы, в свою очередь может содержать описания процедур и функций. Таким образом, процедуры и функции могут быть вложены друг в друга как угодно глубоко, при этом тело программы — самое верхнее в цепочке.

Причём содержимое секций описания переменных, типов, констант, внешнего тела (процедуры, функции, программы), расположенных перед описанием процедуры/функции, доступны внутри неё. Также, в большинстве диалектов из процедуры можно обращаться к параметрам внешней процедуры.
<!--
Каждая процедура/функция может содержать собственные объявления меток, констант, типов, переменных, а также других процедур и функций, причём именно в вышеуказанном порядке. Такой порядок объявлений установлен с целью добиться эффективного компилирования за один проход. Тем не менее, в некоторых диалектах этот строгий порядок секций не является обязательным.//-во всяком случае в Turbo Pascal,Delphi,FPC это не так
-->

Вслед за заголовком процедур/функций вместо тела может помещаться ключевое слово <code>forward</code>, это делается в том случае, если описание процедуры/функции располагается в программе после её вызова, и связано с поддерживаемой в Паскале возможностью компиляции программы за один проход.

==== Стандартные математические функции и процедуры Паскаля ====

===== Математические функции =====
{| border="1"
|-
|Наименование функции ||Тип аргумента ||Тип значения||Результат вычисления
|-
|Abs(x)||целый вещественный||целый вещественный||Абсолютное значение "х"
|-
|Sin(x)||вещественный||вещественный||синус "х" рад.
|-
|Cos(x)||вещественный||вещественный||косинус "х" рад.
|-
|Arctan(x)||вещественный||вещественный||арктангенс "х" ( -Pi/2 <y< Pi/2 )
|-
|Sqrt(x)||вещественный||вещественный||квадратный корень из "х"
|-
|Sqr(x)||целый вещественный||целый вещественный||значение "х" в квадрате ( ''x''<sup>2</sup> )
|-
|Power(a,x)||вещественный||вещественный||значение "a" в степени "x" ( ''a''<sup>x</sup> )
|-
|Exp(x)||вещественный||вещественный||значение "е" в степени "х" ( ''e''<sup>x</sup>, где 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)||порядковый||порядковый||предшествующий "с" символ
|}


===== Математические процедуры =====
Тело процедуры, так же как и программы в свою очередь может содержать описания процедур и функций, таким образом, процедуры и функции могут быть вложены друг в друга как угодно глубоко, при этом тело программы — самое верхнее в цепочке.
{| border="1"
Причем содержимое секций описания переменных, типов, констант, внешнего тела(процедуры, функции, программы) расположенных перед описанием процедуры/функции доступны внутри неё. Также в большинстве диалектов из процедуры можно обращаться к параметрам внешней процедуры.
|-
<!--Каждая процедура/функция может содержать собственные объявления меток, констант, типов, переменных, а также других процедур и функций, причём именно в вышеуказанном порядке. Такой порядок объявлений установлен с целью добиться эффективного компилирования за один проход. Тем не менее, в некоторых диалектах этот строгий порядок секций не является обязательным.//-во всяком случае в Turbo Pascal,Delphi,FPC это не так-->
|Наименование функции ||Тип аргумента ||Тип значения||Результат вычисления
|-
|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; )
|}


===== Процедуры преобразования типов переменных =====
Вслед за заголовком процедур/функций вместо тела может помещаться ключевое слово '''forward''', это делается в том случае, если описание процедуры/функции располагается в программе после её вызова, и связано с поддерживаемой в Паскале возможностью компиляции программы за один проход.
{| border="1"
|-
|Наименование функции ||Тип аргумента ||Тип значения||Результат вычисления
|-
|Str(x , s)||x-целый или вещественный||s-строковый||Последовательность символов "s" из цифр числа "x"
|-
|Val(s , v, cod)||s-строковый||v-целый или вещественный cod-целый||Двоичная форма числа последовательности "s" cod=0 (код ошибки)
|}


===== Функции преобразования типов переменных =====
Процедуры отличаются от функций тем, что функции возвращают какое-либо значение, а процедуры — нет.
{| border="1"
|-
|Наименование функции ||Тип аргумента ||Тип значения||Результат вычисления
|-
|Trunc(x)||вещественный||LongInt||целая часть "х"
|-
|Round(x)||вещественный||LongInt||округление "х" до целого
|-
|Odd(x)||целый||логический||возвращает True если "х" - нечётное число
|-
|Chr(x)||Byte||Char||Символ ASCII кода "х"
|-
|Ord(x)||Char||Byte||ASCII код символа "x"
|}


=== Модули ===
=== Модули ===
До появления модулей в их современном виде некоторые реализации Паскаля поддерживали модульность за счёт механизма включения заголовочных файлов, похожего на механизм #include в языке Си: с помощью специальной директивы, оформляемой в виде псевдокомментария, например, <code>{$INCLUDE "файл"}</code>, содержимое указанного файла прямо включалось в текст программы в исходном, текстовом виде. Таким образом можно было разделить программный код на множество фрагментов, для удобства редактирования, но перед компиляцией они автоматически объединялись в один файл программы, который в итоге и обрабатывался компилятором. Такая реализация модульности примитивна и имеет множество очевидных недостатков, поэтому она была быстро заменена.
До появления связных модулей в их современном виде некоторые реализации Паскаля поддерживали модульность за счёт механизма включения заголовочных файлов, похожего на механизм <code>#include</code> в языке Си: с помощью специальной директивы, оформляемой в виде псевдокомментария, например, <code>{$INCLUDE "файл"}</code>, содержимое указанного файла прямо включалось в текст программы в исходном, текстовом виде. Таким образом можно было разделить программный код на множество фрагментов, для удобства редактирования, но перед компиляцией они автоматически объединялись в один файл программы, который в итоге и обрабатывался компилятором. Такая реализация модульности примитивна и имеет множество очевидных недостатков, поэтому она была быстро заменена.
Современные реализации языка Паскаль (начиная с UCSD Pascal) поддерживают модули, концепция которых заимствована, с изменениями, из языка Modula. Программные модули могут быть двух видов: модуль главной программы, который, как обычно, начинается с ключевого слова program и тело которого содержит код, запускаемый после загрузки программы в память, и вспомогательных модулей, содержащих типы, константы, переменные, процедуры и функции, предназначенные для использования в других модулях, в том числе в главном модуле.


Современные реализации языка Паскаль (начиная с UCSD Pascal) поддерживают модули. Программные модули могут быть двух видов: модуль главной программы, который, как обычно, начинается с ключевого слова program и тело которого содержит код, запускаемый после загрузки программы в память, и вспомогательных модулей, содержащих типы, константы, переменные, процедуры и функции, предназначенные для использования в других модулях, в том числе в главном модуле.


==== Структура ====
==== Структура ====

Общая структура подключаемого модуля на Паскале выглядит следующим образом:
Общая структура подключаемого модуля на Паскале выглядит следующим образом:
<source lang="pascal">
<source lang="pascal">
Строка 344: Строка 566:
...
...


begin {может отсутствовать-используется, если необходимо поместить операторы инициализации}
begin {может отсутствовать - используется, если необходимо поместить операторы инициализации}
...
...
end.
end.
Строка 361: Строка 583:


finalization
finalization
...
....


end.
end.
</source>
</source>
В отличие от главной программы, файл модуля начинается с ключевого слова <code>UNIT</code>, за которым следует имя модуля и точка с запятой. Современные реализации, как правило, требуют, чтобы имя модуля совпадало с именем файла исходного кода, в котором этот модуль содержится. Модуль содержит три секции: интерфейсную секцию, секцию реализации и тело модуля.


Интерфейсная секция идёт первой, начинается с ключевого слова <code>INTERFACE</code> и заканчивается в том месте модуля, где начинается секция реализации или тело. В интерфейсной секции объявляются те объекты (типы, константы, переменные, процедуры и функции — для них помещаются заголовки), которые должны быть доступны извне модуля. При этом допускается частичное объявление типов: они могут объявляться без указания структуры, одним только именем. При использовании такого типа во внешней программе допускается объявление переменных и параметров этого типа, присваивание значений, но невозможно получить доступ к деталям его реализации. Процедуры и функции в интерфейсной секции объявляются в виде форвардов — заголовков с параметрами, но без тела. Состав интерфейсной секции модуля таков, что его достаточно для генерации кода, использующего данный модуль. Переменные, объявленные в интерфейсной секции, являются глобальными, то есть существуют в единственном экземпляре и доступны во всех частях программы, использующих данный модуль.
В отличие от главной программы, файл модуля начинается с ключевого слова '''<code>UNIT</code>''', за которым следует имя модуля и точка с запятой. Современные реализации, как правило, требуют, чтобы имя модуля совпадало с именем файла исходного кода, в котором этот модуль содержится. Модуль содержит три секции: интерфейсную секцию, секцию реализации и тело модуля.

Интерфейсная секция идёт первой, начинается с ключевого слова '''<code>INTERFACE</code>''' и заканчивается в том месте модуля, где начинается секция реализации или тело. В интерфейсной секции объявляются те объекты (типы, константы, переменные, процедуры и функции(для них помещаются заголовки)), которые должны быть доступны извне модуля. При этом допускается частичное объявление типов: они могут объявляться без указания структуры, одним только именем. При использовании такого типа во внешней программе допускается объявление переменных и параметров этого типа, присваивание значений, но невозможно получить доступ к деталям его реализации. Процедуры и функции в интерфейсной секции объявляются в виде форвардов — заголовков с параметрами, но без тела. Состав интерфейсной секции модуля таков, что его достаточно для генерации кода, использующего данный модуль. Переменные, объявленные в интерфейсной секции, являются глобальными, то есть существуют в единственном экземпляре и доступны во всех частях программы, использующих данный модуль.


Секция реализации следует за интерфейсной и начинается с ключевого слова '''<code>IMPLEMENTATION</code>'''. В нём располагаются описания процедур и функций, объявленных в интерфейсной секции, а также описания типов, констант, переменных, процедур и функций, которые необходимы для реализации интерфейсных процедур и функций. Описание процедуры или функции, объявленной в интерфейсной секции, должно иметь в точности такой же заголовок, как в объявлении. В теле могут использоваться другие процедуры и функции данного модуля, объявленные как в интерфейсной части, так и в секции реализации. Переменные, объявленные в секции реализации, являются, по сути, глобальными (то есть существует только один экземпляр каждой такой переменной на всю программу), но доступны они только из процедур и функций, описанных в секции реализации данного модуля, а также из его тела. Если в интерфейсной секции есть сокращённые объявления типов, то эти типы должны быть полностью описаны в секции реализации.
Секция реализации следует за интерфейсной и начинается с ключевого слова <code>IMPLEMENTATION</code>. В нём располагаются описания процедур и функций, объявленных в интерфейсной секции, а также описания типов, констант, переменных, процедур и функций, которые необходимы для реализации интерфейсных процедур и функций. Описание процедуры или функции, объявленной в интерфейсной секции, должно иметь в точности такой же заголовок, как в объявлении. В теле могут использоваться другие процедуры и функции данного модуля, объявленные как в интерфейсной части, так и в секции реализации. Переменные, объявленные в секции реализации, являются, по сути, глобальными (то есть существует только один экземпляр каждой такой переменной на всю программу), но доступны они только из процедур и функций, описанных в секции реализации данного модуля, а также из его тела. Если в интерфейсной секции есть сокращённые объявления типов, то эти типы должны быть полностью описаны в секции реализации.


Тело модуля начинается находящимся на верхнем уровне вложенности ключевым словом '''<code>BEGIN</code>'''. Тело содержит программный код, который выполняется один раз при загрузке модуля. Тело может применяться для инициализации, присваивания начальных значений переменным модуля, выделения ресурсов для его работы и так далее. Тело модуля может отсутствовать. В ряде реализаций Паскаля, например, в Delphi, вместо тела модуля могут применяться две секции (также необязательные) — '''<code>INITIALIZATION</code>''' и '''<code>FINALIZATION</code>'''. Они располагаются в конце модуля, после соответствующего ключевого слова. Первая — секция инициализации, — содержит код, который должен быть выполнен при загрузке модуля, вторая — секция финализации, — код, который будет выполнен при выгрузке модуля. Секция финализации может выполнять действия, обратные инициализации — удалять объекты из памяти, закрывать файлы, освобождать выделенные ресурсы.
Тело модуля начинается находящимся на верхнем уровне вложенности ключевым словом <code>BEGIN</code>. Тело содержит программный код, который выполняется один раз при загрузке модуля. Тело может применяться для инициализации, присваивания начальных значений переменным модуля, выделения ресурсов для его работы и так далее. Тело модуля может отсутствовать. В ряде реализаций Паскаля, например, в Delphi, вместо тела модуля могут применяться две секции (также необязательные) — <code>INITIALIZATION</code> и <code>FINALIZATION</code>. Они располагаются в конце модуля, после соответствующего ключевого слова. Первая — секция инициализации, — содержит код, который должен быть выполнен при загрузке модуля, вторая — секция финализации, — код, который будет выполнен при выгрузке модуля. Секция финализации может выполнять действия, обратные инициализации — удалять объекты из памяти, закрывать файлы, освобождать выделенные ресурсы.


Модуль заканчивается ключевым словом '''<code>END</code>''' с точкой.
Модуль заканчивается ключевым словом <code>END</code> с точкой.


==== Использование ====
==== Использование ====
Чтобы использовать модуль, главная программа или другой модуль должны импортировать данный модуль, то есть содержать объявление о его использовании. Это объявление делается с помощью инструкции подключения модулей, представляющей собой ключевое слово <code>USES</code>, за которым через запятую следуют имена модулей, которые требуется подключить. Инструкция подключения должна следовать непосредственно за заголовком программы, либо после ключевого слова <code>INTERFACE</code>, если подключение производится в модуле.


Модули, подключённые в интерфейсной секции, могут использоваться во всём модуле — и в секции реализации, и в теле. Но секция реализации может иметь собственную инструкцию подключения (она следует за ключевым словом <code>IMPLEMENTATION</code>), содержащую имена подключаемых модулей, которые отсутствуют в интерфейсной секции, но нужны для секции реализации. Одним из поводов использования отдельного списка подключения для раздела реализации является ситуация, когда два или более модуля используют друг друга. Чтобы не возникали циклические ссылки в объявлениях использования таких модулей, по крайней мере один из них должен подключать другой в секции реализации.
Чтобы использовать модуль, главная программа или другой модуль должны импортировать данный модуль, то есть содержать объявление о его использовании. Это объявление делается с помощью инструкции подключения модулей, представляющей собой ключевое слово '''<code>USES</code>''', за которым через запятую следуют имена модулей, которые требуется подключить. Инструкция подключения должна следовать непосредственно за заголовком программы, либо после ключевого слова INTERFACE, если подключение производится в модуле.


Любые объявленные в интерфейсных секциях модулей объекты можно использовать в программе там, где эти модули подключены. Имена импортированных из подключённых модулей объектов остаются теми же самыми, и их можно использовать непосредственно. Если два или более подключённых модуля имеют объекты, называемые одинаково, и компилятор не может их различить, то при попытке использования такого объекта будет выдана ошибка компиляции — неоднозначное задание имени. В этом случае программист должен применять квалификацию имени — указать имя в формате «&lt;имя_модуля&gt;.&lt;имя_объекта&gt;».
Модули, подключённые в интерфейсной секции, могут использоваться во всём модуле — и в секции реализации, и в теле. Но секция реализации может иметь собственную инструкцию подключения (она следует за ключевым словом IMPLEMENTATION), содержащую имена подключаемых модулей, которые отсутствуют в интерфейсной секции, но нужны для секции реализации. Одним из поводов использования отдельного списка подключения для раздела реализации является ситуация, когда два или более модуля используют друг друга. Чтобы не возникали циклические ссылки в объявлениях использования таких модулей, по крайней мере один из них должен подключать другой в секции реализации.

Любые объявленные в интерфейсных секциях модулей объекты можно использовать в программе там, где эти модули подключены. Имена импортированных из подключённых модулей объектов остаются теми же самыми, и их можно использовать непосредственно. Если два или более подключённых модуля имеют объекты, называемые одинаково, и компилятор не может их различить, то при попытке использования такого объекта будет выдана ошибка компиляции — неоднозначное задание имени. В этом случае программист должен применять квалификацию имени — указать имя в формате «<имя_модуля>.<имя_объекта>».


Проблемы могут возникнуть, если появляется необходимость использования в программе двух разных одноимённых модулей. Если модули доступны только в откомпилированном виде (то есть поменять их имена невозможно), оказывается невозможным их одновременный импорт. Стандартного решения такой коллизии на уровне языка не существует, но конкретные компиляторы могут предлагать те или иные способы её обхода, в частности, средства назначения псевдонимов импортируемым модулям и прямого указания, какой модуль из какого файла брать.
Проблемы могут возникнуть, если появляется необходимость использования в программе двух разных одноимённых модулей. Если модули доступны только в откомпилированном виде (то есть поменять их имена невозможно), оказывается невозможным их одновременный импорт. Стандартного решения такой коллизии на уровне языка не существует, но конкретные компиляторы могут предлагать те или иные способы её обхода, в частности, средства назначения псевдонимов импортируемым модулям и прямого указания, какой модуль из какого файла брать.


==== Компиляция и компоновка ====
==== Компиляция и компоновка ====
Модули спроектированы в расчёте на обеспечение раздельной компиляции — компилятор не должен компилировать импортированные модули для того, чтобы откомпилировать модуль, который их использует. Однако, чтобы правильно компилировать модуль, компилятор должен иметь доступ к секции интерфейса всех используемых им модулей. Существует два разных, иногда совмещаемых подхода к организации такого доступа.

* Модули компилируются в бинарные файлы специального формата (у каждого компилятора своего), в которых сохранена подробная информация об объектах, объявленных в интерфейсной секции, также может содержаться созданный при компиляции модуля объектом языке, но использует при этом только интерфейсную секцию модуля. Если библиотечный модуль поставляется в откомпилированном виде (без полных исходных текстов), то вместе с бинарным файлом идёт урезанный файл исходного кода модуля, содержащий только интерфейсную секцию. Компилятору этого достаточно, чтобы правильно обрабатывать обращения из использующих модулей, а на этапе сборки программы компоновщик просто включает в программу бинарный файл.
Модули спроектированы в расчёте на обеспечение раздельной компиляции — компилятор не должен компилировать импортированные модули для того, чтобы откомпилировать модуль, которых их использует. Однако, чтобы правильно компилировать модуль, компилятор должен иметь доступ к секции интерфейса всех используемых им модулей. Существует два разных, иногда совмещаемых подхода к организации такого доступа.
* Модули компилируются в бинарные файлы специального формата(у каждого компилятора своего), в которых сохранена подробная информация об объектах, объявленных в интерфейсной секции, также может содержаться созданный при компиляции модуля объектный код. При компиляции любого модуля компилятор требует, чтобы все импортируемые модули были уже откомпилированы и доступны. В таком случае, при наличии правильно откомпилированных модулей, их исходные тексты на этапе компиляции не нужны.
* Модули компилируются в обычные бинарные файлы и подключаются компоновщиком только на этапе сборки конечного исполняемого файла программы. Для обработки обращений к подключаемым модулям компилятор обрабатывает непосредственно текст этих модулей на исходном языке, но использует при этом только интерфейсную секцию модуля. Если библиотечный модуль поставляется в откомпилированном виде (без полных исходных текстов), то вместе с бинарным файлом идёт урезанный файл исходного кода модуля, содержащий только интерфейсную секцию. Компилятору этого достаточно, чтобы правильно обрабатывать обращения из использующих модулей, а на этапе сборки программы компоновщик просто включает в программу бинарный файл.


==== Загрузка и выгрузка модулей ====
==== Загрузка и выгрузка модулей ====

Для нормальной работы модуля может потребоваться выполнить некоторые действия до начала его использования: инициализировать переменные, открыть нужные файлы, выделить память или другие ресурсы. Всё это может быть сделано в теле модуля, либо в секции инициализации. Действия, обратные инициализации, делаются в секции финализации.
Для нормальной работы модуля может потребоваться выполнить некоторые действия до начала его использования: инициализировать переменные, открыть нужные файлы, выделить память или другие ресурсы. Всё это может быть сделано в теле модуля, либо в секции инициализации. Действия, обратные инициализации, делаются в секции финализации.


Порядок инициализации и финализации модулей не определён никакими стандартами, но для статически откомпилированных программ (где модуль либо компилируется в один исполняемый файл с главной программой, либо находится в отдельной динамической библиотеке, но загружается на этапе первоначальной загрузки), компилятор всегда гарантирует, что инициализация будет выполнена до момента первого использования модуля. Финализация выполняется при завершении работы программы, после завершения главного модуля, так, что используемые модули финализируются позже, чем использующие их.
Порядок инициализации и финализации модулей косвенно определяется порядком объявления в секции uses, но для статически откомпилированных программ (где модуль либо компилируется в один исполняемый файл с главной программой, либо находится в отдельной динамической библиотеке, но загружается на этапе первоначальной загрузки), компилятор всегда гарантирует, что инициализация будет выполнена до момента первого использования модуля. Финализация выполняется при завершении работы программы, после завершения главного модуля, так, что используемые модули финализируются позже, чем использующие их.


В случае динамической загрузки модулей, управляемой самим программистом, инициализаторы выполняются при загрузке, то есть в момент, когда команда загрузки модуля вернула управление, инициализатор его уже выполнен. Финализатор выполняется после выгрузки, обычно — при выполнении команды выгрузки модуля. Если эта команда не вызывается, динамически загруженные модули финализируются так же, как все остальные — при завершении программы.
В случае динамической загрузки модулей, управляемой самим программистом, инициализаторы выполняются при загрузке, то есть в момент, когда команда загрузки модуля вернула управление, инициализатор его уже выполнен. Финализатор выполняется после выгрузки, обычно — при выполнении команды выгрузки модуля. Если эта команда не вызывается, динамически загруженные модули финализируются так же, как все остальные — при завершении программы.


=== Объектно-ориентированное программирование ===
=== Объектно-ориентированное программирование ===
В [[Object Pascal]] имеется возможность разрабатывать программы с применением парадигмы [[объектно-ориентированное программирование|объектно-ориентированного программирования]]. Классы задаются с помощью типа <code>object</code>, аналогичного <code>record</code>, который кроме полей данных может содержать заголовки процедур и [[метод (языки программирования)|методов]]. Имена описываемых методов следуют за именем класса через точку.
{{заготовка раздела}}
В [[Object Pascal]] классы задаются с помощью типа '''object''', аналогичного '''record''', который кроме полей данных может содержать заголовки процедур и функций(называются [[Метод (языки программирования)|методами]]). Имена описываемых методов следуют за именем класса через точку.
[[Конструктор (программирование)|''Конструктор'']] и [[Деструктор (программирование)|''деструктор'']] задаются как обычные процедуры, но вместо идентификатора ''procedure'' задаются ключевые слова ''constructor'' и ''destructor''. Соответственно, в отличие от [[С++]]-подобных языков они имеют имя, отличное от имени класса, деструкторов может быть несколько и они могут иметь параметры (на практике эта возможность используется редко, обычно класс имеет единственный деструктор Destroy, переопределяющий виртуальный деструктор класса-родителя). Все объекты в Object Pascal(fpc, tp) создаются и уничтожаются динамически, конструктор и деструктор всегда должны вызываться явно.


''[[Конструктор (объектно-ориентированное программирование)|Конструктор]]'' и ''[[Деструктор (программирование)|деструктор]]'' задаются как обычные процедуры, но вместо идентификатора <code>procedure</code> задаются ключевые слова <code>constructor</code> и <code>destructor</code>. Соответственно, в отличие от [[C++]]-подобных языков они имеют имя, отличное от имени класса, деструкторов может быть несколько, и они могут иметь параметры (на практике эта возможность используется редко, обычно класс имеет единственный деструктор <code>Destroy</code>, переопределяющий виртуальный деструктор класса-родителя).
Поддерживаются единичное наследование, [[Полиморфизм (программирование)|полиморфизм классов]], механизм [[Virtual function table|виртуальных]] методов(слово '''virtual''' после заголовка метода класса).
<!--
«Все объекты в Object Pascal (FPC, TP) создаются и уничтожаются динамически, конструктор и деструктор всегда должны вызываться явно.» -
1. неправда (объекты Object Pascal создаются при объявлении переменной такого типа всегда статически(а динамическое создание — только с помощью оператора new)), а вот Delphi-объекты(при объявлении такой переменной) -как раз динамически(вроде всегда — это надо уточнить)-это разные несовместимые виды объектов
2. для статических объектов конструктор и деструктор вызываться не должны — это делается на усмотрение программиста- по крайней мере в object-объектах — поэтому там и сделан ручной вызов конструктора и деструктора и множество имён) В Object Pascal реально это необходимо только при использовании virtual-методов(так как именно в конструкторе заполняется таблица виртуальных методов)
С Delphi объектами вроде так и есть -обязателен явный вызов
-->

Поддерживаются единичное наследование, [[Полиморфизм (программирование)|полиморфизм классов]], механизм [[Таблица виртуальных методов|виртуальных]] методов (слово <code>virtual</code> после заголовка метода класса). Существуют и динамические методы (в TP описываются путём добавления целого числа после слова <code>virtual</code> и используются преимущественно для обработки сообщений; в Delphi и FreePascal для этих целей используется слово <code>message</code>, а для создания обычных динамических методов — слово <code>dynamic</code>), отличающиеся меньшим использованием памяти и меньшей скоростью вызова за счёт отсутствия дублирования динамических методов предков в VMT потомка (однако FreePascal не делает различий между виртуальными и динамическими методами).


В Delphi, FPC реализована [[перегрузка операций]], абстрактные методы, директивы ''private'', ''protected'', ''public'', ''published'' (по умолчанию члены класса являются ''public''):
В Delphi, FPC реализована [[перегрузка операций]], абстрактные методы, директивы <code>private</code>, <code>protected</code>, <code>public</code>, <code>published</code> (по умолчанию члены класса являются <code>public</code>):<!-- директивы public private были реализованы ещё в TP -->
{{Hider hiding
|title=Пример программы для Pascal
|content=
<source lang="Pascal">
<source lang="Pascal">
type
type
TbasicO=object
TbasicO = object
procedure writeByte(b:byte); virtual; abstract;
procedure writeByte (b:byte); virtual; abstract;
end;
end;


TtextO=object(TbasicO) {наследует TbasicO, реализует остальные операции вывода на основе writeByte}
TtextO =object (TbasicO) {наследует TbasicO, реализует остальные операции вывода на основе writeByte}
procedure writeS(s:string);
procedure writeS (s: string);
{..}
{..}
end;
end;


TfileO=object(TbasicO) {класс файлового вывода - реализует операцию вывода как вывод байта в файл}
TfileO = object (TbasicO) {класс файлового вывода - реализует операцию вывода как вывод байта в файл}
constructor init(n:string);
constructor init (n: string);
procedure writeByte(b:byte); virtual;
procedure writeByte (b: byte); virtual;
destructor closefile;
destructor closefile;
private
private
f:file of byte;
f: file of byte;
end;
end;


basicO=^TbasicO; textO=^TtextO; fileO=^TfileO;
basicO = ^TbasicO;
textO = ^TtextO;
fileO = ^TfileO;


constructor TfileO.init(n:string);
constructor TfileO.init (n: string);
begin
begin
assign(f,n);rewrite(f)
assign (f, n);
rewrite (f)
end;
end;

destructor TfileO.closefile;
destructor TfileO.closefile;
begin
begin
close(f)
close (f)
end;
end;

procedure TfileO.writeByte(b:byte);
procedure TfileO.writeByte (b: byte);
begin
begin
write(f,b)
write (f, b)
end;
end;


procedure TtextO.writeS(s:string);
procedure TtextO.writeS (s: string);
var i:integer;
var i: integer;
begin
begin
for i:=1 to length(s) do writeByte(ord(s[i]))
for i:=1 to length(s) do
writeByte (ord(s[i]))
end;
end;
{..}
{..}

var f:fileO;
var f: fileO;
begin
begin
new(f,init('tstobj.txt'));{выделяет пямять под объект и вызывает конструктор}
new (f, init('tstobj.txt')); {выделяет память под объект и вызывает конструктор}
textO(f)^.writeS('text string');
textO(f)^.writeS ('text string');
dispose(f,closefile) {вызывает деструктор и освобождает память объекта}
dispose (f, closefile) {вызывает деструктор и освобождает память объекта}
end.
end.
</source>
</source>
}}
В диалекте Delphi классы могут также конструироваться с помощью слова ''class''(причем взаимное наследование с ''object''-классами не допускается), и введены [[Интерфейс (ООП)|интерфейсы]](''interface'')-все методы абстрактные и не могут содержать полей данных.
В диалекте Delphi классы могут также конструироваться с помощью слова <code>class</code> (причём взаимное наследование с <code>object</code>-классами не допускается) и введены [[Интерфейс (объектно-ориентированное программирование)|интерфейсы]] (<code>interface</code>) — все методы абстрактные и не могут содержать полей данных.
Все классы(созданные с помощью ''class'') являются наследниками ''TObject'', все интерфейсы происходят от ''IUnknown''. Классы(созданные с помощью ''class'') могут реализовывать несколько интерфейсов.

В Delphi интерфейсы были введены для поддержки [[COM+|COM технологии]] фирмы Microsoft.<br />
Все классы (созданные с помощью <code>class</code>) являются наследниками <code>TObject</code>, все интерфейсы происходят от <code>IUnknown</code>. Классы, созданные с помощью <code>class</code>, могут реализовывать несколько интерфейсов.
Классы (''Class'') в отличие от обычных классов (''Object'') не нуждаются в явном выделении/освобождении памяти, память под них динамически выделяется конструктором с именем ''Create'', вызываемым с именем класса, и освобождается при вызове деструктора с именем ''Destroy''(могут иметь другие имена). Переменная такого класса в отличие от класса ''object'' хранит адрес экземпляра класса в памяти, значение ''nil'' используется для указания пустой ссылки, поэтому для освобождения объекта в TObject определен специальный метод ''free'', проверяющий ссылку на ''nil'' и вызывающий виртуальный деструктор ''Destroy''. Код с использованием таких классов будет выглядеть следующим образом:

В Delphi интерфейсы были введены для поддержки технологии [[COM+|COM]] фирмы Microsoft.

Классы (<code>Class</code>) в отличие от обычных классов (<code>Object</code>) не нуждаются в явном выделении/освобождении памяти, память под них динамически выделяется конструктором с именем <code>Create</code>, вызываемым с именем класса, и освобождается при вызове деструктора с именем <code>Destroy</code> (могут иметь другие имена). Переменная такого класса в отличие от класса <code>object</code> хранит адрес экземпляра класса в памяти, значение <code>nil</code> используется для указания пустой ссылки, поэтому для освобождения объекта в <code>TObject</code> определён специальный метод <code>free</code>, проверяющий ссылку на <code>nil</code> и вызывающий виртуальный деструктор <code>Destroy</code>. Код с использованием таких классов будет выглядеть следующим образом:
{{Hider hiding
|title=Пример для Pascal
|content=
<source lang="Pascal">
<source lang="Pascal">
q1:=t1.create(9); { конструируем объект(t1 - имя класса) }
q1 := t1.create(9); { конструируем объект(t1 - имя класса) }
writeln(q1.InstanceSize); { вывод размера экземпляра класса }
writeln (q1.InstanceSize); { вывод размера экземпляра класса }
q1.Free; { уничтожение объекта }
q1.Free; { уничтожение объекта }
q1:=nil; { чтобы не происходило повторного вызова деструктора при вызове free }
q1 := nil; { чтобы не происходило повторного вызова деструктора при вызове free }
</source>
</source>
}}


В модификации ObjectPascal/Delphi/FreePascal в описании классов появляются свойства (property), которые совмещают удобство работы с переменными (роль которых в ООП играют поля) и вызовы методов, которые всегда уведомляют объект об изменении его состояния:
== См. также ==
{{Hider hiding
* [[Free Pascal]]
|title=Пример программы для Pascal
* [[TMT Pascal]]
|content=
* [[Delphi (язык программирования)]]
* [[Turbo Pascal]]
<source lang="Pascal">
type
* [[UCSD Pascal]]
TMyObj=class(TObject)
* [[MIDletPascal]]
FProp:integer;
* [[PascalABC.NET]]
procedure SetProp(AValue:integer);
* [[Алгол]]
property MyProp:integer read FProp write SetProp;
end;
procedure TMyObj.SetProp(AValue:integer);
begin
FProp:=AValue;
Writeln('Somebody has changed MyProp!');
end;
var MyObj:TMyObj;
begin
MyObj:=TMyObj.Create;
MyObj.FProp:=5;
MyObj.MyProp:=MyObj.MyProp+6;
end.
</source>
}}
В первом случае (использование MyObj.FProp) поле объекта было изменено непосредственно, в итоге, методы объекта не будут подозревать, что это поле было ранее изменено; в более сложном случае они могут полагаться на то, что поле неизменно, либо же полю может быть присвоено значение, недопустимое для данного объекта. Во втором случае значение присваивается непосредственно свойству объекта, которое ссылается на вызов метода, корректно обрабатывающего изменение данного поля.


Этот подход удобен, если объект связан с визуальным элементом: непосредственное изменение поля, отвечающего, например, за ширину элемента, никак не отразится на самом визуальном элементе, а объект будет «дезинформирован» относительно реальных размеров элемента. Корректным подходом без использования свойств является разработка методов на получение и установку любого значения поля, но работа с такими методами будет менее удобна, например, вместо последней строки надо было бы написать
== Ссылки ==
<source lang="Pascal">
<!-- Пожалуйста, не засоряйте раздел ссылок.
MyObj.SetProp(MyObj.GetProp+6);
Википедия — не каталог ссылок. Каждый сайт в этом списке должен нести важную для читателя Википедии информацию и своевременно обновляться. -->
</source>
* [http://pascal.sources.ru/articles/058.htm Летопись языков Паскаль], Мир ПК, № 04/2001
причём метод MyObj.GetProp следовало бы написать для унификации доступа.
* [http://www.cyberguru.ru/programming/pascal/ Статьи о Паскале, Энциклопедия Turbo Pascal]

* [http://www.cyberforum.ru/pascal/ Форум Pascal]
Большой интерес представляют индексные свойства, которые ведут себя практически так же, как и массивы, заменяя обращение к элементу массива вызовом соответствующего метода.
* [http://pascal-entering.ru/ Вступление в Pascal]

* [http://www.cyberguru.ru/delphi-sources/ Исходники Pascal]
Тем не менее, свойства не являются «панацеей»: при компиляции обращения к свойствам непосредственно транслируются в вызов методов или прямую работу с полями, поэтому настоящими переменными свойства не являются, в частности, их невозможно передавать в виде var-параметров.
* [http://progopedia.ru/language/pascal/ Статья о Паскале в энциклопедии progopedia.ru]
* [http://pascal.helpov.net Теория программирования для учеников и студентов]
* [http://www.uchites.ru/informatika/pascal Примеры программ]
* [http://bdrc.ru/index/0-14 Статьи, примеры программ]
* [http://pascal.proweb.kz Паскаль программирование]
* [http://www.pascalguru.com Решение задач Паскаль]
* [http://forum.pascal.net.ru Форум Все о Паскале - обсуждение и решение задач, головоломок и других вопросов]


== Примечания ==
== Примечания ==
Строка 496: Строка 747:


== Литература ==
== Литература ==

* {{книга
|автор = Йенсен К., Вирт Н.
|часть =
|заглавие = Паскаль. Руководство для пользователя и описание языка
|оригинал =
|ссылка =
|место = М.
|издательство = [[Финансы и статистика(издательство)|«Финансы и статистика»]]
|год = 1982
|страницы = 151
|isbn =
}}

* {{книга
* {{книга
|автор = Вирт Н.
|автор = Вирт Н.
|заглавие = Алгоритмы + структуры данных = программы
|часть =
|место = М. |издательство = [[Мир (издательство)|Мир]]
|заглавие = Алгоритмы+структуры данных= программы
|оригинал =
|ссылка =
|место = М.
|издательство = [[Мир(издательство)|«Мир»]]
|год = 1985
|год = 1985
|страницы = 406
|страниц = 406
}}
|isbn =
* {{книга
|автор = Вирт Н., Йенсен К.
|заглавие = Паскаль. Руководство для пользователя и описание языка
|место = М. |издательство = [[Финансы и статистика]]
|год = 1982
|страниц = 151
}}
}}

* {{книга
* {{книга
|автор = Грогоно П.
|автор = Грогоно П.
|часть =
|заглавие = Программирование на языке Паскаль
|заглавие = Программирование на языке Паскаль
|место = М. |издательство = [[Мир (издательство)|Мир]]
|оригинал =
|ссылка =
|место = М.
|издательство = [[Мир(издательство)|«Мир»]]
|год = 1982
|год = 1982
|страницы = 384
|страниц = 384
|isbn =
}}
}}

* {{книга
* {{книга
|автор = Перминов О. Н.
|автор = Культин Н. Б.
|заглавие = Программирование в Turbo Pascal 7.0 и Delphi: 3-е изд., перераб. и доп.
|часть =
|место = СПб. |издательство = [[БХВ-Петербург]]
|заглавие = Язык программирования Паскаль : Справочник
|год = 2007
|оригинал =
|страниц = 400
|ссылка =
|isbn = 978-5-9775-0109-5
|место = М.
|издательство = [[Радио и связь(издательство)|«Радио и связь»]]
|год = 1989
|страницы = 128
|isbn = 5-256-00311-9
}}
}}

* {{книга
* {{книга
|автор = Культин Н.Б.
|автор = Культин Н. Б.
|часть =
|заглавие = Delphi 6. Программирование на Object Pascal
|заглавие = Delphi 6. Программирование на Object Pascal
|место = СПб. |издательство = [[БХВ-Петербург]]
|оригинал =
|ссылка =
|место = СПб.
|издательство = [[БХВ-Петербург(издательство)|«БХВ-Петербург»]]
|год = 2001
|год = 2001
|страницы = 528
|страниц = 528
|isbn = 5-94157-112-7
|isbn = 5-94157-112-7
}}
}}

* {{книга
* {{книга
|автор = Моргун А. Н.
|автор = Моргун А. Н.
|часть =
|заглавие = Программирование на языке Паскаль (Pascal). Основы обработки структур данных
|заглавие = Программирование на языке Паскаль (Pascal). Основы обработки структур данных
|место = М. |издательство = [[Диалектика (издательство)|Диалектика]]
|оригинал =
|ссылка =
|издание =
|место = М.
|издательство = [[Диалектика (издательство)|«Диалектика»]]
|год = 2005
|год = 2005
|страницы = 576
|страниц = 576
|isbn = 5‐8459‐0935‐X
|isbn = 5-8459-0935-X
}}
}}
* {{книга
|автор = Перминов О. Н.
|заглавие = Язык программирования Паскаль : Справочник
|место = М. |издательство = [[Радио и связь]]
|год = 1989
|страниц = 128
|isbn = 5-256-00311-9
}}
* {{книга
|автор = Рубенкинг Н. Дж.
|заглавие = Турбо Паскаль для Windows: в 2-х томах. Пер. с англ
|место = М.|издательство = Мир
|год = 1993
}}
* {{Книга|автор = |заглавие = Языки программирования Ада, Си, Паскаль|ответственный = А. Фьюэр, Н. Джехани|издание = |место = М.|издательство = Радио и Связь|год = 1989|страницы = |страниц = 368|isbn = 5-256-00309-7|оригинал = Comparing and Assessong Programming Languages Ada, C, and Pascal|тираж = 50000|ref = Фьюэр, Джехани}}


'''Стандарты'''
* ISO 7185:1983 Programming languages — PASCAL (заменён стандартом ISO 7185:1990)
* ANSI/IEEE770X3.97-1983
* ГОСТ 28140-89 Системы обработки информации. Язык программирования ПАСКАЛЬ
* [http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=13802 ISO 7185:1990 Information technology — Programming languages — Pascal] {{Wayback|url=http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=13802 |date=20121025015116 }}
* [http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=18237 ISO/IEC 10206:1991 Information technology — Progamming languages — Extended Pascal] {{Wayback|url=http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=18237 |date=20121025024827 }}

== Ссылки ==

* [https://web.archive.org/web/20141209022915/http://pascal-dev.ru/ Программирование на pascal] — online tutorial (rus)
{{dmoz|World/Russian/Компьютеры/Программирование/Языки/Pascal/|Паскаль}}
* [http://pascal-central.com/ Pascal Central] {{Wayback|url=http://pascal-central.com/ |date=20100310135522 }}{{ref-en}}
* [http://pascal.sources.ru/index.htm Паскальные исходники со всего мира] {{Wayback|url=http://pascal.sources.ru/index.htm |date=20101003194032 }}, Сайт о программе
* [http://progopedia.ru/language/pascal/ Статья о Паскале] {{Wayback|url=http://progopedia.ru/language/pascal/ |date=20070527070347 }} в энциклопедии progopedia.ru
{{Внешние ссылки}}

{{Pascal}}
{{Языки программирования}}
{{Языки программирования}}
{{Стандарты ISO}}
{{IDE}}
{{rq|sources|check}}


[[Категория:Паскаль|*]]
[[Категория:Паскаль|*]]
[[Категория:Семейство языков программирования Pascal]]
[[Категория:Языки программирования семейства Паскаля]]
[[Категория:Языки программирования для образования]]

[[Категория:Статьи с примерами кода на Паскале]]
[[af:Pascal]]
[[Категория:Языки программирования со статическим распределением памяти]]
[[an:Luengache de programazión Pascal]]
[[ar:باسكال (لغة برمجة)]]
[[az:Paskal (proqramlaşdırma dili)]]
[[bar:Pascal (Programmiersprach)]]
[[bat-smg:Pascal]]
[[be:Pascal]]
[[be-x-old:Pascal]]
[[bg:Паскал (език за програмиране)]]
[[bs:Pascal programski jezik]]
[[ca:Pascal (llenguatge de programació)]]
[[cs:Pascal (programovací jazyk)]]
[[cv:Паскаль (компьютер чĕлхи)]]
[[da:Pascal (programmeringssprog)]]
[[de:Pascal (Programmiersprache)]]
[[el:Pascal (γλώσσα προγραμματισμού)]]
[[en:Pascal (programming language)]]
[[eo:Paskalo (programlingvo)]]
[[es:Lenguaje de programación Pascal]]
[[et:Pascal]]
[[eu:Pascal (programazio lengoaia)]]
[[fa:زبان برنامه‌نویسی پاسکال]]
[[fi:Pascal (ohjelmointikieli)]]
[[fr:Pascal (langage)]]
[[gl:Linguaxe Pascal]]
[[he:פסקל (שפת תכנות)]]
[[hr:Pascal (programski jezik)]]
[[hu:Pascal (programozási nyelv)]]
[[id:Pascal (bahasa pemrograman)]]
[[is:Pascal (forritunarmál)]]
[[it:Pascal (linguaggio)]]
[[ja:Pascal]]
[[kab:Pascal]]
[[ko:파스칼 (프로그래밍 언어)]]
[[la:Pascal]]
[[lt:Pascal]]
[[mk:Паскал (програмски јазик)]]
[[ms:Pascal (bahasa pengaturcaraan)]]
[[nl:Pascal (programmeertaal)]]
[[nn:Programmeringsspråket Pascal]]
[[no:Pascal (programmeringsspråk)]]
[[pl:Pascal (język programowania)]]
[[pt:Pascal (linguagem de programação)]]
[[ro:Pascal (limbaj de programare)]]
[[sh:Pascal (programski jezik)]]
[[simple:Pascal]]
[[sk:Pascal (programovací jazyk)]]
[[sl:Programski jezik paskal]]
[[sr:Паскал (програмски језик)]]
[[sv:Pascal (programspråk)]]
[[ta:பாசுக்கல் நிரலாக்க மொழி]]
[[th:ภาษาปาสกาล]]
[[tl:Pascal (programming language)]]
[[tr:Pascal programlama dili]]
[[uk:Pascal]]
[[vi:Pascal (ngôn ngữ lập trình)]]
[[zh:Pascal]]

Текущая версия от 23:10, 10 октября 2024

Паскаль
Класс языка императивный, структурированный
Тип исполнения компилируемый
Появился в 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 годом; представляя язык, автор в качестве цели его создания указывал построение небольшого и эффективного языка, способствующего хорошему стилю программирования, использующему структурное программирование и структурированные данные.[источник не указан 931 день]

Последующая работа Вирта была направлена на создание на основе Паскаля языка системного программирования с сохранением возможности вести на его базе систематический, целостный курс обучения профессиональному программированию: «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) для программируемых логических контроллеров.[источник не указан 931 день]

К 1990-м годам Pascal стал одним из наиболее распространённых в мире алгоритмических языков программирования. Ведущие разработчики программного обеспечения регулярно выпускали новые версии своих компиляторов для этого языка. Популярные компиляторы того времени: Turbo Pascal (разработан компанией Borland), Microsoft Pascal Compiler, Quick Pascal, Pascal-2, Professional Pascal, USCD Pascal[7].

Реализации и диалекты

[править | править код]

Язык Pascal имеет много реализаций[8].

В 1978 году в Калифорнийском университете в Сан-Диего была разработана система UCSD p-System, включавшая порт компилятора Вирта с языка Паскаль в переносимый p-код, редактор исходных кодов, файловую систему и прочее[9], а также реализовывавшая значительное число расширений языка Паскаль, такие как модули, строки символов переменной длины, директивы трансляции, обработка ошибок ввода-вывода, обращение к файлам по именам и другое. Впоследствии основные реализации языка Паскаль основывались на этом диалекте.

В 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, получивший одноимённое название.

Современные реализации 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.

B Южном федеральном университете разработан PascalABC.NET — язык программирования Паскаль, включающий большинство возможностей языка Delphi, а также ряд собственных расширений. Он основан на платформе Microsoft.NET и содержит практически все современные языковые средства: классы, перегрузку операций, интерфейсы, обработку исключений, обобщённые классы и подпрограммы, сборку мусора, лямбда-выражения.

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: исходный, международные ISO и американские ANSI
Название Вариант Кем/где разработан Год создания
Pascal Standard исходный Н. Вирт, Кетлин Йенсен 1974
Pascal Standard исходный ISO 7185:1983
ANSI/IEEE 770X3.97:1983
1982
Unextended Pascal исходный ISO 7185:1990 1989
Extended Pascal расширенный ANSI/IEEE 770X3.160:1989 1989
ISO/IEC 10206 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[источник не указан 4207 дней], созданного Никлаусом Виртом AlgolW[англ.] и предложены Хоаром.

В современных диалектах (Delphi Pascal, Free Pascal) доступны такие операции, как перегрузка операторов и функций.

Программы на Паскале начинаются с ключевого слова Program и следующего за ним имени программы с точкой с запятой (в некоторых диалектах является необязательным), за именем может в скобках следовать список внешних файловых дескрипторов («окружение») в качестве параметров; за ним следует тело программы, состоящее из секций описания констант (Const), типов (Type), переменных (Var), объявлений процедур (Procedure) и функций (Function) и следующего за ними блока операторов, являющегося точкой входа в программу. В языке Паскаль блок ограничивается ключевыми словами begin и end. Операторы разделяются точками с запятой, после тела помещается точка, служащая признаком конца программы.

Регистр символов в Паскале не имеет значения.

Таким образом, простейшая («пустая») программа на Паскале будет выглядеть следующим образом:

program p;
begin
end.

Приведённая выше программа не выполняет никаких действий и содержит пустой блок операторов.

Пример программы, выводящей строку «Hello, world!»:

program hello;
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: set of 1..10;
  set2: set of 'a'..'z';
  set3: set of pear..orange;

Множество — фундаментальное понятие в современной математике, которое может быть использовано во многих алгоритмах.

В паскале тип множество может содержать только однотипные элементы порядкового типа. Эта особенность широко используется и обычно быстрее эквивалентной конструкции в языке, не поддерживающем множества. К примеру, для большинства компиляторов Паскаля:

if i in [5..10] then { проверка на принадлежность элемента множеству }
...

обработается быстрее, чем

if (i>=5) and (i<=10) then { проверка логическими условиями }
...

Для задания значения множества используется список элементов множества, отделённых запятыми и заключённый в квадратные скобки (как уже было показано выше):

var { секция объявления переменных }
 d:set of char;
begin { начало блока }
 d:=['a','b']; 
...

В Паскале Йенсен и Вирта строки представлялись как упакованные массивы символов; следовательно, они имели фиксированную длину и обычно дополнялись до этой длины пробелами.

Составные типы

[править | править код]

Новые типы могут быть определены из существующих:

type { секция объявления типов }
  x = Integer;
  y = x;
...

Более того, из примитивных типов могут быть сконструированы составные:

type { секция объявления типов }
  a = Array [1..10] of Integer;  { определение массива }
  b = record  { определение записи }
        x: Integer;
        y: Char;
      end;
  c = File of a;  { определение файла }

Файловые типы в Паскале делятся на типизированные, текстовые и файлы без типов.

Как показано в вышеприведённом примере, типизированные файлы в Паскале — это последовательности однотипных элементов. Для каждого файла существует переменная-указатель на буфер, которая обозначается 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);

with pointer_to_b^ do
begin
  x := 10;
  y := 'A';
  z := nil
end;
...
dispose(pointer_to_b);

Процедурный тип

[править | править код]

В оригинальном языке Паскаль Йенсен и Вирта процедурный тип использовался только при описании формального параметра. Уже в TP существовал полноправный процедурный тип. В объявлении типа ставится заголовок процедуры либо функции (без имени), обобщённо описывающий интерфейс подпрограммы. Значение этого типа содержит указатель на подпрограмму с заголовком, соответствующую описанному в объявлении типа. С помощью идентификатора переменной может происходить вызов соответствующей процедуры или функции.

Операторы управления

[править | править код]

Паскаль — язык структурного программирования, что означает, что программа состоит из выполняющихся последовательно отдельных стандартных операторов, в идеале — без использования команды GOTO.

В операторах while, for, if, case в качестве выполняемого оператора может использоваться блок. Такая конструкция, представляющая собой обычный оператор или блок, называется сложным оператором.

В Turbo Pascal для управления процессом компиляции существуют директивы, которые помещаются в комментарии и позволяют переключать режимы работы компилятора — например, включать и отключать проверку операций ввода-вывода, переполнения:

Существуют директивы, аналогичные директивам препроцессора C/C++ ($ifdef, $define, $include), они обрабатываются компилятором в процессе компиляции.

Процедуры и функции

[править | править код]

В Паскале подпрограммы делятся на процедуры и функции. При этом, функции явно возвращают значение (результат) определённого типа, а процедуры явно ничего не возвращают.

Синтаксически описание процедуры или функции состоит из заголовка, содержащего ключевое слово procedure или function, имени, за которым может следовать описание передаваемых (формальных) параметров в скобках. Для функции через символ «двоеточие» : указывается тип возвращаемого значения. Заголовок заканчивается символом «точка с запятой» ;. После заголовка следует тело, (возможно) содержащее секции описания локальных констант, типов, переменных, процедур, функций и (обязательно) содержащее блок операторов, после которого ставится символ «точка с запятой» ;.

Тело процедуры, как и программы, в свою очередь может содержать описания процедур и функций. Таким образом, процедуры и функции могут быть вложены друг в друга как угодно глубоко, при этом тело программы — самое верхнее в цепочке.

Причём содержимое секций описания переменных, типов, констант, внешнего тела (процедуры, функции, программы), расположенных перед описанием процедуры/функции, доступны внутри неё. Также, в большинстве диалектов из процедуры можно обращаться к параметрам внешней процедуры.

Вслед за заголовком процедур/функций вместо тела может помещаться ключевое слово 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 и тело которого содержит код, запускаемый после загрузки программы в память, и вспомогательных модулей, содержащих типы, константы, переменные, процедуры и функции, предназначенные для использования в других модулях, в том числе в главном модуле.

Общая структура подключаемого модуля на Паскале выглядит следующим образом:

unit UnitName1;
interface
  ...

implementation
  ...

begin {может отсутствовать - используется, если необходимо поместить операторы инициализации}
  ...
end.

Возможен также ещё один вариант:

unit UnitName2;
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):

В диалекте Delphi классы могут также конструироваться с помощью слова class (причём взаимное наследование с object-классами не допускается) и введены интерфейсы (interface) — все методы абстрактные и не могут содержать полей данных.

Все классы (созданные с помощью class) являются наследниками TObject, все интерфейсы происходят от IUnknown. Классы, созданные с помощью class, могут реализовывать несколько интерфейсов.

В Delphi интерфейсы были введены для поддержки технологии COM фирмы Microsoft.

Классы (Class) в отличие от обычных классов (Object) не нуждаются в явном выделении/освобождении памяти, память под них динамически выделяется конструктором с именем Create, вызываемым с именем класса, и освобождается при вызове деструктора с именем Destroy (могут иметь другие имена). Переменная такого класса в отличие от класса object хранит адрес экземпляра класса в памяти, значение nil используется для указания пустой ссылки, поэтому для освобождения объекта в TObject определён специальный метод free, проверяющий ссылку на nil и вызывающий виртуальный деструктор Destroy. Код с использованием таких классов будет выглядеть следующим образом:

В модификации ObjectPascal/Delphi/FreePascal в описании классов появляются свойства (property), которые совмещают удобство работы с переменными (роль которых в ООП играют поля) и вызовы методов, которые всегда уведомляют объект об изменении его состояния:

В первом случае (использование MyObj.FProp) поле объекта было изменено непосредственно, в итоге, методы объекта не будут подозревать, что это поле было ранее изменено; в более сложном случае они могут полагаться на то, что поле неизменно, либо же полю может быть присвоено значение, недопустимое для данного объекта. Во втором случае значение присваивается непосредственно свойству объекта, которое ссылается на вызов метода, корректно обрабатывающего изменение данного поля.

Этот подход удобен, если объект связан с визуальным элементом: непосредственное изменение поля, отвечающего, например, за ширину элемента, никак не отразится на самом визуальном элементе, а объект будет «дезинформирован» относительно реальных размеров элемента. Корректным подходом без использования свойств является разработка методов на получение и установку любого значения поля, но работа с такими методами будет менее удобна, например, вместо последней строки надо было бы написать

   MyObj.SetProp(MyObj.GetProp+6);

причём метод MyObj.GetProp следовало бы написать для унификации доступа.

Большой интерес представляют индексные свойства, которые ведут себя практически так же, как и массивы, заменяя обращение к элементу массива вызовом соответствующего метода.

Тем не менее, свойства не являются «панацеей»: при компиляции обращения к свойствам непосредственно транслируются в вызов методов или прямую работу с полями, поэтому настоящими переменными свойства не являются, в частности, их невозможно передавать в виде var-параметров.

Примечания

[править | править код]
  1. Kim B. Bruce. Foundations of Object-oriented Languages: Types and Semantics. — MIT Press, 2002-01-01. — С. 9. — 416 с. — ISBN 9780262025232. Архивировано 18 июня 2016 года.
  2. White Paper. About Microsoft’s «Delegates» Архивная копия от 27 июня 2012 на Wayback Machine, java.sun.com
  3. History of Java, Java Application Servers Report Архивировано 29 декабря 2010 года. TechMetrix Research, 1999
  4. A Conversation with James Gosling. Дата обращения: 16 октября 2009. Архивировано 16 июля 2015 года.
  5. Индекс популярности языков программирования TIOBE Архивная копия от 25 декабря 2018 на Wayback Machine (англ.)
  6. 1 2 Wirth, 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.
  7. Бородич, Ю. С. Предисловие // Паскаль для персональных компьютеров : справ. пособ. / Ю. С. Бородич, А. Н. Вальвачев, А. И. Кузьмич. — Мн. : Вышэйшая школа, 1991. — С. 3. — 365 с. : ил. — ББК 32.973-01я2. — УДК 681.3.06(035.5)(G). — ISBN 5-339-00662-X.
  8. Liste compilateur Pascal - Pascal compiler list. Дата обращения: 19 января 2021. Архивировано 11 апреля 2021 года.
  9. Wirth N. Recollections about the development of Pascal (HOPL II), 3.3. Дата обращения: 16 апреля 2011. Архивировано 22 декабря 2012 года.
  10. Jon Udell, Crash of the Object-Oriented Pascals, BYTE, July, 1989.
  11. M. I. Trofimov, The End of Pascal?, BYTE, March, 1990, p. 36.
  12. Why Pascal is Not My Favorite Programming Language. Дата обращения: 27 августа 2004. Архивировано 28 апреля 2009 года.
  13. PASCAL: User Manual and Report ISO Pascal Standard Kathleen Jensen and Niklaus Wirth, 4th edition, Springer Verlag New York, Inc. 1974, 1985, 1991
  14. Object-Oriented Extensions to Pascal Архивная копия от 5 июня 2021 на Wayback Machine, Technical Committee X3J9, Programming Language Pascal
  15. 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.

Стандарты