Знаймо

Додати знання

приховати рекламу



Цей текст може містити помилки.

Паскаль (мова програмування)



План:


Введення

Паскаль ( англ. Pascal ) - мова програмування загального призначення. Один з найбільш відомих мов програмування, широко застосовувався в промисловому програмуванні [4], навчання програмуванню у вищій школі, є базою для ряду інших мов.


1. Історія

Мова названий на честь видатного французького математика, фізика, літератора і філософа Блеза Паскаля, який створив першу в світі механічну машину, складаються два числа.

Паскаль був створений Никлаусом Віртом в 1968-69 роках після його участі в роботі комітету розробки стандарту мови Алгол-68. Він був опублікований в 1970 році Віртом як невеликий і ефективний мову, щоб сприяти хорошому стилю програмування, використовувати структурне програмування і структуровані дані.

Подальша робота Вірта була спрямована на створення на основі Паскаля мови системного програмування, зі збереженням можливості вести на його базі систематичний, цілісний курс навчання професійному програмування [5]. Результат цієї роботи - мова Модула-2.


2. Реалізації

2.1. UCSD Pascal

У 1978 році в Університеті Сан-Дієго (Каліфорнія, США) була розроблена система UCSD p-System, що включала порт віртовского компілятора з мови Паскаль в переносимий p-код, редактор вихідних кодів, файлову систему і пр. [6], а також реалізовувати значну кількість розширень мови Паскаль, такі як модулі, рядки символів змінної довжини, директиви трансляції, обробка помилок вводу-виводу, звернення до файлів по іменах і пр. Згодом основні реалізації мови Паскаль грунтувалися на цьому діалекті.


2.2. Object Pascal від Apple

В 1986 фірма Apple Computer розробила об'єктне розширення мови Паскаль, отримавши в результаті Object Pascal. Він був розроблений групою Ларрі Теслер, який консультувався з Никлаусом Віртом.

2.3. Turbo Pascal і Object Pascal від Borland, Microsoft Pascal

В 1989 об'єктне розширення мови було додано фірмою Borland в Turbo Pascal версії 5.5 (починаючи з наступної версії середовище було перейменовано в Borland Pascal). Об'єктні кошти були запозичені з Object Pascal від Apple, мовні відмінності між об'єктним Turbo Pascal 5.5 і Object Pascal від Apple вкрай незначні.

Майже в той же самий час, що і Borland, Microsoft випустив свою версію об'єктно-орієнтованої мови Паскаль. [7] [8] Ця версія Паскаля не отримала широкого розповсюдження.

Подальший розвиток реалізації Паскаля від Borland породило Object Pascal від Borland, згодом, у ході розвитку середовища програмування Delphi, що отримав однойменну назву.


2.4. Сучасні версії Object Pascal

Важливим кроком у розвитку мови є поява вільних реалізацій мови Паскаль Free Pascal та GNU Pascal, які не тільки увібрали в себе риси безлічі інших діалектів мови, але й забезпечили надзвичайно широку переносимість написаних на ньому програм (наприклад GNU Pascal підтримує більше 20 різних платформ, під більш ніж 10 різними операційними системами, Free Pascal забезпечує спеціальні режими сумісності з різними поширеними діалектами мови, такими як Turbo Pascal (повна сумісність), Delphi і іншими.

В даний час, починаючи з Delphi 2003, створена реалізація мови для платформи Net, хоча розробники продовжують використовувати Delphi більш ранніх версій.

Про комерційні розробках на Free Pascal, GNU Pascal і TMT Pascal на даний момент відомо мало.

Крім того, в Південному федеральному університеті розробляється мова та система програмування PascalABC.NET, орієнтована на навчання сучасному програмування. Мова системи - це Object Pascal для платформи Microsoft. NET, який містить всі основні елементи сучасних мов програмування: модулі, класи, перевантаження операцій, інтерфейси, виключення, узагальнені класи, збірку сміття, а також деякі засоби паралельного програмування.


3. Особливості мови

Особливостями мови є сувора типізація та наявність засобів структурного (процедурного) програмування. Паскаль був одним з перших таких мов. На думку Н. Вірта, мова повинна сприяти дисциплінованість програмування, тому, поряд із строгою типізацією, у Паскалі зведені до мінімуму можливі синтаксичні неоднозначності, а сам синтаксис автор постарався зробити інтуїтивно зрозумілим навіть при першому знайомстві з мовою.

Проте, спочатку мова мала ряд обмежень: неможливість передачі функцій масивів змінної довжини, відсутність нормальних засобів роботи з динамічною пам'яттю, обмежена бібліотека вводу-виводу, відсутність засобів для підключення функцій написаних на інших мовах, відсутність коштів роздільної компіляції і т. п. Докладний розбір недоліків мови Паскаль того часу був виконаний Брайаном Керніганом у статті "Чому Паскаль не є моїм улюбленим мовою програмування" [9] (ця стаття вийшла на початку 1980-х, коли вже існував мову Модула-2, нащадок Паскаля, позбавлений від більшості його пороків, а також більш розвинені діалекти Паскаля). Деякі недоліки Паскаля були виправлені в ISO-стандарті 1982 року, зокрема, в мові з'явилися відкриті масиви, що дали можливість використовувати одні і ті ж процедури для обробки одновимірних масивів різних розмірів.

Необхідно зауважити, що багато недоліків мови не виявляються або навіть стають достоїнствами при навчанні програмуванню. Крім того, порівняно з основною мовою програмування в академічному середовищі 1970-х (яким був Фортран, що володів набагато більш істотними недоліками), Паскаль представляв собою значний крок вперед. На початку 1980-х років в СРСР для навчання школярів основам інформатики та обчислювальної техніки академік А. П. Єршов розробив Алгол-паскалеподобний " навчальний алгоритмічну мову ".

Найбільш відомою реалізацією Паскаля, що забезпечила широке поширення і розвиток мови, є Turbo Pascal фірми Borland, що виросла потім у об'єктний Паскаль для DOS (починаючи з версії 5.5) і Windows і далі в Delphi, в якій були впроваджені значні розширення мови.

Діалекти Паскаля, застосовувані в Turbo Pascal для DOS і Delphi для Windows, стали популярні з-за відсутності інших успішних комерційних реалізацій.


4. Стандарти

Після початку використання Паскаля в 1970 і появи реалізацій, що розходяться не тільки в доповненнях, але і в синтаксисі, було піднято питання про стандартизацію мови. Стандарт мови був розроблений Никлаусом Віртом в 1974 спільно з Кетлін Йенсен (Kathleen Jensen). [10] У подальшому, були прийняті міжнародний стандарт 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
об'єктно-орієнтоване розширення ANSI/X3-TR-13: 1994 1993

Одним з головних додаткових властивостей об'єктно-орієнтованого розширення Extended Pascal стала модульність і засоби, що полегшують роздільну компіляцію.

Стандартизація мови була запізнілої по відношенню до реального появи в мові тих чи інших можливостей. Комерційні реалізації розширювали стандартний Паскаль; так було зроблено в UCSD Pascal, модифікації Object Pascal фірмою Apple, Turbo Pascal від Borland (незначно модифікована версія Apple) і його відгалужень. Жодна з поширених комерційних реалізацій Паскаля не відповідає в точності жодному з офіційних стандартів мови.


5. Синтаксис і мовні конструкції

Паскаль, в його первісному вигляді, представляє собою чисто процедурний мову і включає в себе безліч алголоподобних структур і конструкцій з зарезервованими словами на зразок if, then, else, while, for, і т. д. Проте, Паскаль також містить велику кількість можливостей для структурування інформації та абстракцій, які відсутні в початковому Алгол-60, такі як визначення типів, записи, покажчики, перерахування, і безлічі. Ці конструкції були частково успадковані або інспіровані від мов Симула -67, Алгол-68, створеного Никлаусом Віртом AlgolW та запропоновано Хоаром.

У сучасних діалектах (Free Pascal) доступні такі операції як перевантаження операторів і функцій.


5.1. Hello world

Програми на Паскалі починаються з ключового слова program і наступного за ним ім'я програм з крапкою з комою (в деяких діалектах є необов'язковим), за ім'ям може в дужках слідувати список зовнішніх файлових дескрипторів в якості параметрів, за ним слід тіло програми, що складається із секцій опису змінних, типів і констант , оголошень процедур і функцій і наступного за ними блоку операторів, що є точкою входу в програму. У мові Паскаль блок обмежується ключовими словами begin і end. Оператори поділяються крапкою з комою, після тіла поміщається точка, що служить ознакою кінця програми. Літери в Паскалі не має значення.

Таким чином, найпростіша програма на Паскалі буде виглядати наступним чином:

 program  p;  begin  end  . 

Програма не виконує ніяких дій і містить порожній блок операторів.

Приклад програми, що виводить рядок "Hello, World!":

 program  HelloWorld  (  output  )  ;  begin  writeln  (  'Hello, World!'  )  {Оператор виведення рядка}  end  . 

5.2. Типи даних

Прості типи даних Паскаля: числа з плаваючою комою ( real), цілі ( integer), символьний ( char), логічний ( boolean) та перерахування (конструктор нового типу, введений в Паскалі).

У діалекті Delphi існують такі прості типи:

-Цілочисельні:

Тип Діапазон Формат Розмір в байтах
Byte 0 .. 255 Беззнакові 1
ShortInt -128 .. 127 Знаковий 1
SmallInt -32768 .. 32767 Знаковий 2
Word 0 .. 65535 Беззнакові 2
Integer -32768 .. 32767 Знаковий 4
Cardinal = LongWord Беззнакові 4
LongWord 0 .. 4294967295 Беззнакові 4
LongInt -2147483648 .. 2147483647 Знаковий 4
Int64 -9223372036854775808 .. 9223372036854775807 Знаковий 8
QWord 0 .. 18446744073709551615 Беззнакові 8

-Типи з плаваючою крапкою:

Тип Діапазон кількість значущих цифр Розмір в байтах
Real / Double залежить від платформи ??? 8
Real48 ??? 11-12 6
Single 1.5E-45 .. 3.4E38 7-8 4
Extended 1.9E-4932 .. 1.1E4932 19-20 10
Comp -2E64 +1 .. 2E63-1 19-20 8
Currency -922337203685477.5808 .. 922337203685477.5807 19-20 8

-Логічні типи: Boolean, ByteBool, WordBool і LongBool.

-Символьні типи: Char, AnsiChar, WideChar.

-Перечіслімий тип.

 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 (як лічильник циклу), як кордони масивів, для завдання елементів множин і типів-діапазонів.

У Паскалі, на відміну від Сі-подібних мов, з типами boolean і char арифметичні цілочисельні операції не визначені.

На відміну від багатьох поширених мов, Паскаль підтримує спеціальний тип даних безліч:

 var  set1  :  set  of  1  ..  10  ; Set2  :  set  of  'A'  ..  'Z'  ; Set3  :  set  of  pear ..  orange  ; 

Безліч - фундаментальне поняття в сучасній математиці, яке може бути використане в багатьох алгоритмах.

В паскалі тип множина може містити тільки однотипні елементи порядкового типу. Ця особливість широко використовується і звичайно швидше еквівалентної конструкції у мові, що не підтримує множини. Наприклад, для більшості компіляторів Паскаля:

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

обробиться швидше, ніж

 if  (  i>  4  )  and  (  i <  11  )  then  {Перевірка логічними умовами}  ... 

Для завдання значення безлічі використовується список елементів множини, відокремлених комами і ув'язнений в квадратні дужки (як уже було показано вище):

 var  {Секція оголошення змінних}  d  :  set  of  char  ;  begin  {Початок блоку}  d  : =  [  'A'  ,  'B'  ]  ; ... 

У Паскалі Йенсен і Вірта рядка представлялися як упаковані масиви символів, отже, вони мали фіксовану довжину і зазвичай доповнювалися до цієї довжини пробілами.

У сучасному Паскалі [11] для роботи з рядками використовується вбудований тип 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 може використовуватися тип WideString, де застосовується 16-бітове представлення символів в кодуванні UCS-2, при цьому кошти перетворення з однобайтових рядків у багатобайтові і назад в стандартній бібліотеці мови відсутні.

Нові типи можуть бути визначені з існуючих:

 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).


5.2.1. Покажчики

Паскаль підтримує використання покажчиків (типізовані ^тип і нетипізовані 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 полям a і b в ній, необхідні наступні оператори:

 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  )  ; 

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

В оригінальному мовою Паскаль Йенсен і Вірта процедурний тип використовувався тільки при описі формального параметра. Вже в TP існував повноправний процедурний тип. В оголошенні типу ставиться заголовок процедури або функції (без імені), узагальнено описує інтерфейс підпрограми. Значення цього типу містить покажчик на підпрограму з заголовком, відповідну описаному в оголошенні типу. За допомогою ідентифікатора змінної може відбуватися виклик відповідної процедури або функції.

 type  myfunc  =  function  :  string  ;  function  func1  :  string  ;  begin  func1  : =  'Func N 1'  end  ;  function  func2  :  string  ;  begin  func2  : =  'Func N 2'  end  ;  var  fun  :  myfunc;  begin  fun  : =  @ Func1;  writeln  (  fun  )  {Відбувається виклик функції func1}  end  . 

5.3. Оператори управління виконанням програми

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

 while  a <> b  do  {Цикл з передумовою}  writeln  (  'Очікування'  )  ;  if  a> b  then  {Умовний оператор}  writeln  (  'Умова виповнилося'  )  else  {Else-секція - може бути відсутнім}  writeln  (  'Умова не виповнилося'  )  ;  for  i  : =  1  to  10  do  {Ітераційний цикл}  writeln  (  'Ітерація №'  ,  i  :  1  )  ; With a  do  {Оператор With - метод прискорення доступу до полів запису}  begin  l  : =  1  ; K  : =  2  ; P  : =-  3  ;  end  ;  repeat  {Цикл з постусловіем}  a  : =  a  +  1  until  a  =  10  ;  case  i  of  {Умовний оператор множинного вибору}  0  :  write  (  'Нуль'  )  ;  1  :  write  (  'Один'  )  ;  2  :  write  (  'Два'  )  else  write  (  'Невідоме число'  )  {Else-секція - може бути відсутнім}  end  ; 

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

Для управління процесом компіляції в паскалі існують директиви компілятора. Вони поміщаються в коментарі і дозволяють перемикати режими роботи компілятора, наприклад, включати і відключати перевірку операцій введення-виведення, перевірки переповнення:

 assign  (  inp  ,  'Text.txt'  )  ;  {$ I-}  {Відключення режиму IO checking-генерації коду завершення програми у разі помилки введення-виведення}  {(Для випадку, якщо файл не знайдено)}  reset  (  inp  )  ;  {$ I +}  {Включення режиму IO checking}  if  IOresult  =  0  then  begin  {Перевіряємо значення зміною ioresult (<> 0 в разі помилки вводу-виводу)}  ...  close  (  inp  )  ;  end  else  writeln  (  'File not found'  ) 

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


5.4. Процедури і функції

У Паскалі підпрограми діляться на процедури і функції:

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

 program  mine  (  output  )  ;  var  i  :  integer  ;  procedure  print  (  var  j  :  integer  )  ;  function  next  (  k  :  integer  )  :  integer  ;  begin  next  : =  k  +  1  end  ;  begin  writeln  (  'Всього:'  ,  j  )  ; J  : =  next  (  j  )  end  ;  begin  i  : =  1  ;  while  i <  =  10  do  print  (  i  )  end  . 

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

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

Слідом за заголовком процедур / функцій замість тіла може міститися ключове слово forward, це робиться в тому випадку, якщо опис процедури / функції розташовується в програмі після її виклику, і пов'язано з підтримуваної в Паскалі можливістю компіляції програми за один прохід.

Процедури відрізняються від функцій тим, що функції повертають яке-небудь значення, а процедури - ні.


5.5. Модулі

До появи модулів в їх сучасному вигляді деякі реалізації Паскаля підтримували модульність за рахунок механізму включення заголовків файлів, схожого на механізм #include в мові Сі: за допомогою спеціальної директиви, що оформляється у вигляді псевдокомментарія, наприклад, {$INCLUDE "файл"}, вміст зазначеного файлу прямо включалося в текст програми у вихідному, текстовому вигляді. Таким чином можна було розділити програмний код на безліч фрагментів, для зручності редагування, але перед компіляцією вони автоматично об'єднувалися в один файл програми, який у результаті і оброблявся компілятором. Така реалізація модульності примітивна і має безліч очевидних недоліків, тому вона була швидко замінена.

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


5.5.1. Структура

Загальна структура модуля на Паскалі виглядає наступним чином:

 unit  UnitName1;  interface  ...  implementation  ...  begin  {Може бути відсутнім-використовується, якщо необхідно помістити оператори ініціалізації}  ...  end  . 

Можливий також ще один варіант:

 unit  UnitName2;  interface  ...  implementation  ...  initialization  ...  finalization  ....  end  . 

На відміну від головної програми, файл модуля починається з ключового слова UNIT, за яким слідує ім'я модуля і крапка з комою. Сучасні реалізації, як правило, вимагають, щоб ім'я модуля збігалося з ім'ям файлу вихідного коду, в якому цей модуль міститься. Модуль містить три секції: інтерфейсну секцію, секцію реалізації і тіло модуля.

Інтерфейсна секція йде першою, починається з ключового слова INTERFACE і закінчується в тому місці модуля, де починається секція реалізації або тіло. У інтерфейсній секції оголошуються ті об'єкти (типи, константи, змінні, процедури і функції - для них містяться заголовки), які повинні бути доступні ззовні модуля. При цьому допускається часткове оголошення типів: вони можуть оголошуватися без вказівки структури, одним тільки ім'ям. При використанні такого типу в зовнішній програмі допускається оголошення змінних і параметрів цього типу, присвоювання значень, але неможливо отримати доступ до деталей його реалізації. Процедури і функції в інтерфейсній секції оголошуються у вигляді форвардів - заголовків з параметрами, але без тіла. Склад інтерфейсній секції модуля такий, що його достатньо для генерації коду, що використовує даний модуль. Змінні, оголошені в інтерфейсній секції, є глобальними, тобто існують в єдиному екземплярі і доступні у всіх частинах програми, що використовують даний модуль.

Секція реалізації слід за інтерфейсної і починається з ключового слова IMPLEMENTATION. У ньому розташовуються опису процедур і функцій, оголошених в інтерфейсній секції, а також описи типів, констант, змінних, процедур і функцій, які необхідні для реалізації інтерфейсних процедур і функцій. Опис процедури або функції, оголошеної в інтерфейсній секції, повинна мати в точності такий же заголовок, як в оголошенні. У тілі можуть використовуватися інші процедури і функції даного модуля, оголошені як в інтерфейсної частини, так і в секції реалізації. Змінні, оголошені в секції реалізації, є, по суті, глобальними (тобто існує тільки один екземпляр кожної такої змінної на всю програму), але доступні вони тільки з процедур і функцій, описаних в секції реалізації даного модуля, а також з його тіла. Якщо в інтерфейсній секції є скорочені оголошення типів, то ці типи повинні бути повністю описані в секції реалізації.

Тіло модуля починається знаходяться на верхньому рівні вкладеності ключовим словом BEGIN. Тіло містить програмний код, який виконується один раз при завантаженні модуля. Тіло може застосовуватися для ініціалізації, присвоювання початкових значень змінним модуля, виділення ресурсів для його роботи і так далі. Тіло модуля може бути відсутнім. У ряді реалізацій Паскаля, наприклад, в Delphi, замість тіла модуля можуть застосовуватися дві секції (також необов'язкові) - INITIALIZATION і FINALIZATION. Вони розташовуються в кінці модуля, після відповідного ключового слова. Перша - секція ініціалізації, - містить код, який повинен бути виконаний при завантаженні модуля, друга - секція фіналізації, - код, який буде виконаний при розвантаженні модуля. Секція фіналізації може виконувати дії, зворотні ініціалізації - видаляти об'єкти з пам'яті, закривати файли, звільняти виділені ресурси.

Модуль закінчується ключовим словом END з крапкою.


5.5.2. Використання

Щоб використовувати модуль, головна програма або інший модуль повинні імпортувати даний модуль, тобто містити оголошення про його використання. Це оголошення робиться за допомогою інструкції підключення модулів, що представляє собою ключове слово USES, за яким через кому йдуть імена модулів, які потрібно підключити. Інструкція підключення повинна слідувати безпосередньо за заголовком програми, або після ключового слова INTERFACE, якщо підключення проводиться в модулі.

Модулі, підключені в інтерфейсній секції, можуть використовуватися у всьому модулі - і в секції реалізації, і в тілі. Але секція реалізації може мати власну інструкцію підключення (вона слідує за ключовим словом IMPLEMENTATION), що містить імена модулів, які відсутні в інтерфейсній секції, але потрібні для секції реалізації. Одним із приводів використання окремого списку підключення для розділу реалізації є ситуація, коли два або більше модуля використовують один одного. Щоб не виникали циклічні посилання в оголошеннях використання таких модулів, принаймні один з них повинен підключати інший в секції реалізації.

Будь-які оголошені в інтерфейсних секціях модулів об'єкти можна використовувати в програмі там, де ці модулі підключені. Імена імпортованих з підключених модулів об'єктів залишаються тими ж самими, і їх можна використовувати безпосередньо. Якщо два або більше підключених модуля мають об'єкти, звані однаково, і компілятор не може їх розрізнити, то при спробі використання такого об'єкта буде видана помилка компіляції - неоднозначне завдання імені. У цьому випадку програміст повинен застосовувати кваліфікацію імені - вказати ім'я в форматі "<імя_модуля>. <Імя_об'екта>".

Проблеми можуть виникнути, якщо з'являється необхідність використання в програмі двох різних однойменних модулів. Якщо модулі доступні тільки в відкомпілювався вигляді (тобто поміняти їх імена неможливо), виявляється неможливим їх одночасний імпорт. Стандартного вирішення такої колізії на рівні мови не існує, але конкретні компілятори можуть пропонувати ті чи інші способи її обходу, зокрема, кошти призначення псевдонімів імпортуються модулів і прямої вказівки, який модуль з якого файлу брати.


5.5.3. Компіляція і компоновка

Модулі спроектовані в розрахунку на забезпечення роздільної компіляції - компілятор не повинен компілювати імпортовані модулі для того, щоб відкомпілювати модуль, який їх використовує. Однак, щоб правильно компілювати модуль, компілятор повинен мати доступ до секції інтерфейсу всіх використовуваних ним модулів. Існує два різних, іноді суміщаються підходу до організації такого доступу.

  • Модулі компілюються в бінарні файли спеціального формату (у кожного компілятора свого), в яких збережена детальна інформація про об'єкти, оголошених в інтерфейсній секції, також може міститися створений при компіляції модуля об'єктний код. При компіляції будь-якого модуля компілятор вимагає, щоб всі імпортовані модулі були вже відкомпілювалися і доступні. У такому випадку, за наявності правильно компільованих модулів, їх вихідні тексти на етапі компіляції не потрібні.
  • Модулі компілюються в звичайні бінарні файли і підключаються компоновщиком тільки на етапі складання кінцевого виконуваного файлу програми. Для обробки звернень до підключається модулям компілятор обробляє безпосередньо текст цих модулів мовою оригіналу, але використовує при цьому лише інтерфейсну секцію модуля. Якщо бібліотечний модуль поставляється в відкомпілювався вигляді (без повних вихідних текстів), то разом з бінарним файлом йде урізаний файл вихідного коду модуля, який містить лише інтерфейсну секцію. Компілятору цього достатньо, щоб правильно обробляти звернення з використовують модулів, а на етапі складання програми компонувальник просто включає в програму бінарний файл.

5.5.4. Завантаження та вивантаження модулів

Для нормальної роботи модуля може знадобитися виконати деякі дії до початку його використання: ініціалізувати змінні, відкрити потрібні файли, виділити пам'ять або інші ресурси. Все це може бути зроблено в тілі модуля, або в секції ініціалізації. Дії, зворотні ініціалізації, робляться в секції фіналізації.

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

У разі динамічного завантаження модулів, керованої самим програмістом, ініціалізатор виконуються при завантаженні, тобто в момент, коли команда завантаження модуля повернула управління, ініціалізатор його вже виконаний. Фіналізатор виконується після вивантаження, зазвичай - при виконанні команди вивантаження модуля. Якщо ця команда не викликається, динамічно завантажені модулі фіналізуються так само, як всі інші - при завершенні програми.


5.6. Об'єктно-орієнтоване програмування

Об'єктно-орієнтоване програмування (ООП) - це технологія створення складного програмного забезпечення, яке засноване на представленні програми у вигляді сукупності об'єктів, кожний з яких є екземпляром певного класу, а класи утворюють ієрархію зі спадкуванням властивостей.

Основна перевага ООП - це скорочення кількості міжмодульних викликів і зменшення обсягів інформації передається між модулями. Це досягається за рахунок більш повної локалізації даних та інтегрування їх з підпрограмами обробки.

Основні недоліки в ООП - це деяке зниження швидкодії через більш складної організації програмної системи, а також, як правило, помітне збільшення обсягу бінарного коду (особливо при використанні стандартних бібліотек класів у невеликих програмах) через те, що більшість сучасних компіляторів компонувальником не здатні виявити і видалити весь код, який припадає на невикористовувані класи, віртуальні методи і інші елементи ООП.

В Object Pascal класи задаються за допомогою типу object, аналогічного record, який окрім полів даних може містити заголовки процедур і функцій (вони називаються методами). Імена описуваних методів слідують за ім'ям класу через крапку.

Конструктор і деструктор задаються як звичайні процедури, але замість ідентифікатора procedure задаються ключові слова constructor і destructor. Відповідно, на відміну від С + + -подібних мов вони мають ім'я, відмінне від імені класу, деструкторів може бути декілька, і вони можуть мати параметри (на практиці ця можливість використовується рідко, зазвичай клас має єдиний деструктор Destroy, перевизначаються віртуальний деструктор класу-батька).

Підтримуються одиничне успадкування, поліморфізм класів, механізм віртуальних методів (слово virtual після заголовка методу класу). Існують і динамічні методи (в TP описуються шляхом додавання цілого числа після слова virtual і використовуються переважно для обробки повідомлень; в Delphi і FreePascal для цих цілей використовується слово message, а для створення звичайних динамічних методів - слово dynamic), що відрізняються меншим використанням пам'яті і меншою швидкістю виклику за рахунок відсутності дублювання динамічних методів предків у VMT нащадка (проте FreePascal не робить відмінностей між віртуальними і динамічними методами).

У Delphi, FPC реалізована перевантаження операцій, абстрактні методи, директиви private, protected, public, published (за замовчуванням члени класу є public):

 type  TbasicO  =  object  procedure  writeByte  (  b  :  byte  )  ; Virtual; abstract;  end  ; TtextO  =  object  (  TbasicO  )  {Успадковує TbasicO, реалізує інші операції виведення на основі writeByte}  procedure  writeS  (  s  :  string  )  ;  {..}  end  ; TfileO  =  object  (  TbasicO  )  {Клас файлового виводу - реалізує операцію виводу як висновок байта в файл}  constructor  init  (  n  :  string  )  ;  procedure  writeByte  (  b  :  byte  )  ; Virtual;  destructor  closefile;  private  f  :  file  of  byte  ;  end  ; BasicO  =  ^ TbasicO; textO  =  ^ TtextO; fileO  =  ^ TfileO;  constructor  TfileO.  init  (  n  :  string  )  ;  begin  assign  (  f  ,  n  )  ; Rewrite  (  f  )  end  ;  destructor  TfileO.  closefile  ;  begin  close  (  f  )  end  ;  procedure  TfileO.  writeByte  (  b  :  byte  )  ;  begin  write  (  f  ,  b  )  end  ;  procedure  TtextO.  writeS  (  s  :  string  )  ;  var  i  :  integer  ;  begin  for  i  : =  1  to  length  (  s  )  do  writeByte  (  ord  (  s  [  i  ]  )  )  end  ;  {..}  var  f  :  fileO;  begin  new  (  f  ,  init  (  'Tstobj.txt'  )  )  ;  {Виділяє пямять під об'єкт і викликає конструктор}  textO  (  f  )  ^.  writeS  (  'Text string'  )  ;  dispose  (  f  ,  closefile  )  {Викликає деструктор і звільняє пам'ять об'єкта}  end  . 

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

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

У Delphi інтерфейси були введені для підтримки технології COM фірми Microsoft.

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

 q1  : =  t1.  create  (  9  )  ;  {Конструюємо об'єкт (t1 - ім'я класу)}  writeln  (  q1.  InstanceSize  )  ;  {Висновок розміру екземпляра класу}  q1.  Free  ;  {Знищення об'єкта}  q1  : =  nil  ;  {Щоб не відбувалося повторного виклику деструктора при виклику free} 

У модифікації ObjectPascal / Delphi / FreePascal в описі класів з'являються властивості (property), які поєднують зручність роботи з змінними (роль яких в ООП грають поля) і виклики методів, які завжди повідомляють об'єкт про зміну його стану:

 type  TMyObj  =  class  (  TObject  )  FProp  :  integer  ;  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  . 

У першому випадку (використання MyObj.FProp) поле об'єкту було змінено безпосередньо, у результаті, методи об'єкта не будуть підозрювати, що це поле було раніше змінено; в більш складному випадку вони можуть покладатися на те, що поле незмінно, або ж полю може бути присвоєно значення, неприпустиме для даного об'єкта. У другому випадку значення присвоюється безпосередньо властивості об'єкта, яке посилається на виклик методу, коректно обробного зміна даного поля. Цей підхід зручний, якщо об'єкт пов'язаний з візуальним елементом: безпосереднє зміна поля, яка відповідає, наприклад, за ширину елемента, ніяк не відіб'ється на самому візуальному елементі, а об'єкт буде "дезінформований" щодо реальних розмірів елементу. Коректним підходом без використання властивостей є розробка методів на отримання і установку будь-якого значення поля, але робота з такими методами буде менш зручна, наприклад, замість останнього рядка треба було б написати

 MyObj.  SetProp  (  MyObj.  GetProp  +  6  )  ; 

,

причому метод MyObj.GetProp слід було б написати для уніфікації доступу. Великий інтерес представляють індексні властивості, які ведуть себе практично так само, як і масиви, замінюючи звернення до елемента масиву викликом відповідного методу. Тим не менш, властивості не є "панацеєю": при компіляції звернення до властивостей безпосередньо транслюються в виклик методів або пряму роботу з полями, тому справжніми змінними властивості не є, зокрема, їх неможливо передавати у вигляді var-параметрів.


Примітки

  1. White Paper. About Microsoft's "Delegates" - java.sun.com / docs / white / delegates.html, java.sun.com
  2. History of Java, Java Application Servers Report - www.fscript.org / prof / javapassport.pdf TechMetrix Research, 1999
  3. A Conversation with James Gosling - queue.acm.org / detail.cfm? id = 1017013
  4. Індекс популярності мов програмування TIOBE - www.tiobe.com / index.php / content / paperinfo / tpci / index.html (Англ.)
  5. "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." - Wirth N. Modula-2 and Oberon (HOPL III) - oberoncore.ru/_media/library/n._wirth_-_modula-2_and_oberon_hopl_iii_.pdf
  6. Wirth N. Recollections about the development of Pascal (HOPL II), 3.3 - oberoncore.ru / _media / library / n._wirth_-_recollections_about_the_development_of_pascal_hopl_ii_.pdf
  7. Jon Udell, Crash of the Object-Oriented Pascals, BYTE, July, 1989.
  8. MI Trofimov, The End of Pascal?, BYTE, March, 1990, p. 36.
  9. Why Pascal is Not My Favorite Programming Language - www.lysator.liu.se / c / bwk-on-pascal.html
  10. PASCAL: User Manual and Report - ISO Pascal Standard Kathleen Jensen and Niklaus Wirth, 4th edition, Springer Verlag New York, Inc. 1974, 1985, 1991
  11. ISO 7185 Pascal - www.cs.bilkent.edu.tr/ ~ guvenir/courses/CS315/iso7185pascal.pdf

Література

  • Йенсен К., Вірт Н. Паскаль. Керівництво для користувача й опис мови - М .: Фінанси і статистика, 1982. - С. 151.
  • Вірт Н. Алгоритми + структури даних = програми - М .: Світ, 1985. - С. 406.
  • Грогоно П. Програмування на мові Паскаль - М .: Світ, 1982. - С. 384.
  • Пермінов О. Н. Мова програмування Паскаль: Довідник - М .: Радіо і зв'язок, 1989. - С. 128. - ISBN 5-256-00311-9.
  • Культін Н. Б. Delphi 6. Програмування на Object Pascal - СПб. : БХВ-Петербург, 2001. - С. 528. - ISBN 5-94157-112-7.
  • Моргун А. Н. Програмування на мові Паскаль (Pascal). Основи обробки структур даних - М .: Діалектика, 2005. - С. 576. - ISBN 5-8459-0935-X.
  • Рубенкінг Н.Дж. Турбо Паскаль для Windows: в 2-х томах. Пер. з англ. - М .: Світ, 1993.

Цей текст може містити помилки.

Схожі роботи | скачати

Схожі роботи:
R (мова програмування)
Oz (мова програмування)
J (мова програмування)
S (мова програмування)
Мова програмування
Сі (мова програмування)
D (мова програмування)
Форт (мова програмування)
Скретч (мова програмування)
© Усі права захищені
написати до нас
Рейтинг@Mail.ru