Pascal | |
---|---|
Clasa de limba | imperativ , structurat |
Tipul de execuție | compilate |
Aparut in | 1970 |
Autor | Niklaus Wirth |
Extensie de fișier | .paspentru fișierele de cod, .incpentru fișierele de antet . |
Eliberare | Etapa ISO/IEC 10206:1991: 90,93 ( 29 iulie 2008 ) |
Tip sistem | static , puternic , sigur [1] |
Implementări majore | CDC 6000 , ICT 1900 , Pascal-P , PDP-11 , PDP-10 , IBM System/370 , HP , Free Pascal , GNU , PascalABC.NET |
Dialectele | UCSD , Turbo , Delphi |
A fost influențat | ALGOL |
influențat | Modula-2 , Oberon , Componenta Pascal , Ada , Object Pascal , Java [2] [3] [4] , Oxigen |
Site-ul web | iso.org/standard/18237.h… |
Fișiere media la Wikimedia Commons |
Pascal esteunul dintre cele mai cunoscute limbaje de programare [ 5 ] , folosit pentru predarea programarii in liceu si in primii ani de universitate, sta la baza pentru o serie de alte limbaje.
Limbajul de programare Pascal a fost creat în 1970 pe baza limbajului Algol-60 [6] .
Pascal a fost creat de Niklaus Wirth în 1968-1969, după participarea sa la lucrările comitetului de dezvoltare a standardelor lingvistice Algol-68 . Limba este numită după matematicianul, fizicianul, scriitorul și filozoful francez Blaise Pascal , care a creat una dintre primele mașini mecanice din lume pentru a adăuga două numere . Prima publicație a lui Wirth despre limbă este datată 1970; prezentând limbajul, autorul a indicat ca scop al creării acestuia construcția unui limbaj mic și eficient care să promoveze un bun stil de programare folosind programarea structurată și datele structurate.
Lucrarea ulterioară a lui Wirth a fost aceea de a crea un limbaj de programare a sistemelor bazat pe Pascal, menținând în același timp capacitatea de a conduce un curs sistematic și holistic de formare profesională în programare pe baza acestuia: „ Ideea călăuzitoare a fost de a construi un succesor autentic al lui Pascal, care să îndeplinească cerințele ingineriei de sistem. , dar și pentru a satisface dorința profesorului meu de a prezenta un cadru sistematic, consistent, atrăgător și care poate fi predat pentru programarea profesională. ". Rezultatul acestei lucrări a fost limbajul Modula-2 , după care Wirth a început să dezvolte limbajul de programare orientat pe obiecte Oberon pe baza tuturor dezvoltărilor anterioare [6] .
Niklaus Wirth a considerat unul dintre obiectivele creării limbajului Pascal pentru a-i preda pe elevi programarea structurală. Până acum, Pascal este considerat pe bună dreptate unul dintre cele mai bune limbaje pentru învățarea inițială a programării. Modificările sale moderne, cum ar fi Object Pascal, sunt utilizate pe scară largă în programarea industrială (mediul Delphi). De asemenea, pe baza sintaxei limbajului Pascal, a fost creat limbajul de programare Structured Text (ST) sau Structured Control Language (SCL) pentru controlere logice programabile .
Până în anii 1990, Pascal a devenit unul dintre cele mai utilizate limbaje de programare algoritmică din lume. Dezvoltatorii de software de top au lansat în mod regulat noi versiuni ale compilatoarelor lor pentru acest limbaj. Compilatoare populare ale vremii: Turbo Pascal (dezvoltat de Borland ), Microsoft Pascal Compiler, Quick Pascal, Pascal-2, Professional Pascal, USCD Pascal [7] .
Limbajul Pascal are multe implementări [8] .
În 1978, UCSD p-System a fost dezvoltat la Universitatea din California din San Diego , care includea un port al compilatorului Wirth din limbajul Pascal la p-code portabil , un editor de cod sursă, un sistem de fișiere etc. [9] ] și, de asemenea, a implementat un număr semnificativ de extensii de limbă Pascal, cum ar fi module, șiruri de caractere cu lungime variabilă, directive de traducere, gestionarea erorilor I/O, referire la fișiere după nume și multe altele. Ulterior, principalele implementări ale limbajului Pascal s-au bazat pe acest dialect.
În 1986, Apple a dezvoltat o extensie de obiect a limbajului Pascal, rezultând Object Pascal . A fost dezvoltat de grupul lui Larry Tesler , care sa consultat cu Niklaus Wirth .
În 1983, a apărut prima versiune a mediului de dezvoltare integrat Turbo Pascal de la Borland , bazată pe implementarea Pascal cu același nume.
În 1989, la Turbo Pascal versiunea 5.5 a fost adăugată o extensie de limbaj obiect.
Cea mai recentă versiune (7.0) a fost redenumită Borland Pascal.
Facilitățile obiectului au fost împrumutate de la Object Pascal de la Apple și există foarte puține diferențe de limbaj între Object Turbo Pascal 5.5 și Object Pascal de la Apple.
Aproape în același timp cu Borland, Microsoft a lansat versiunea sa a limbajului orientat pe obiecte Pascal. [10] [11] Această versiune a lui Pascal nu a fost folosită pe scară largă.
Dezvoltarea ulterioară a implementării Pascal de la Borland a dat naștere variantei Object Pascal a lui Borland , mai târziu, în timpul dezvoltării mediului de programare Delphi , care a primit același nume .
Un pas important în dezvoltarea limbajului este apariția unor implementări gratuite ale limbajului Pascal Free Pascal și GNU Pascal , care nu numai că au absorbit caracteristicile multor alte dialecte ale limbii, dar au asigurat și portabilitatea extrem de largă a programelor scrise în acesta. (de exemplu, GNU Pascal suportă mai mult de 20 de platforme diferite, sub peste 10 sisteme de operare diferite, Free Pascal oferă moduri speciale de compatibilitate cu diverse dialecte comune ale limbii, cum ar fi Turbo Pascal (compatibilitate deplină), Delphi și altele).
Din Delphi 2003, a fost creată o implementare de limbaj pentru platforma .Net , deși dezvoltatorii continuă să folosească Delphi din versiunile anterioare.
În prezent, se știu puține despre dezvoltarea comercială în Free Pascal, GNU Pascal și TMT Pascal .
În plus, Southern Federal University a dezvoltat PascalABC.NET , un limbaj de programare Pascal care include majoritatea caracteristicilor limbajului Delphi , precum și o serie de extensii proprii. Se bazează pe platforma Microsoft.NET și conține aproape toate caracteristicile limbajului modern: clase , supraîncărcare operator , interfețe , gestionarea excepțiilor , clase și subrutine generice , garbage collection , expresii lambda .
Caracteristicile limbajului sunt tastarea strictă și disponibilitatea instrumentelor de programare structurale (procedurale) . Pascal a fost una dintre primele astfel de limbi. Potrivit lui Wirth, limbajul ar trebui să contribuie la programarea disciplinată, prin urmare, alături de tastarea puternică, posibilele ambiguități sintactice sunt minimizate în Pascal, iar autorul a încercat să facă sintaxa în sine intuitivă chiar și la prima cunoaștere a limbajului.
Cu toate acestea, inițial limbajul a avut o serie de limitări: imposibilitatea de a trece matrice de lungime variabilă la funcții, lipsa mijloacelor normale de lucru cu memoria dinamică , o bibliotecă limitată de I/O , lipsa mijloacelor de conectare a funcțiilor scrise în alte O analiză detaliată a deficiențelor limbajului Pascal din acea vreme a fost realizată de Brian Kernighan în articolul „De ce Pascal nu este limbajul meu de programare preferat” [12] (acest articol a apărut la începutul anilor 1980, când Modula-2 , un descendent al lui Pascal, a scăpat de majoritatea viciilor sale, precum și de dialectele mai dezvoltate ale lui Pascal). Unele deficiențe ale lui Pascal au fost corectate în standardul ISO din 1982, în special, au apărut matrice deschise în limbaj, ceea ce a făcut posibilă utilizarea acelorași proceduri pentru procesarea matricelor unidimensionale de diferite dimensiuni.
Cu toate acestea, multe dintre deficiențele limbii nu apar sau chiar devin avantaje atunci când învățați să programați. În plus, în comparație cu principalul limbaj de programare din mediul academic al anilor 1970 (care a fost Fortran , care avea dezavantaje mult mai semnificative), Pascal a reprezentat un pas semnificativ înainte. Până în anii 1980, Pascal a devenit baza pentru numeroase programe educaționale, în unele cazuri, pe baza sa au fost create limbaje de programare de predare specializate, de exemplu, la începutul anilor 1980 în URSS, Andrei Ershov a dezvoltat un limbaj asemănător Algol-Pascal. pentru a preda elevilor noțiunile de bază ale informaticii și tehnologiei informatice. „ învățarea limbajului algoritmic ”.
Cea mai faimoasă implementare a lui Pascal, care a asigurat o largă distribuție și dezvoltare a limbajului, este Turbo Pascal de la Borland , care a devenit apoi obiectul Pascal pentru DOS (începând cu versiunea 5.5) și Windows și mai departe în Delphi, în care limbaj semnificativ. au fost introduse extensii.
După ce utilizarea lui Pascal a început în 1970 și apariția unor implementări care diferă nu numai în adăugiri, ci și în sintaxă, s-a pus problema standardizării limbajului. Standardul de limbaj a fost dezvoltat de Niklaus Wirth în 1974 împreună cu Kathleen Jensen. [13] Ulterior, au fost adoptate un standard internațional de la ISO și un standard american de la ANSI. În prezent, există trei standarde fundamental diferite: Pascal neextins (original), Pascal extins (extins), Extensii orientate pe obiect la Pascal (extensie Pascal orientată pe obiect).
Nume | Opțiune | Cine/unde s-a dezvoltat | Anul creației |
---|---|---|---|
Pascal Standard | iniţială | N. Wirth, Kathleen Jensen | 1974 |
Pascal Standard | iniţială | ISO 7185:1983 ANSI/ IEEE 770X3.97:1983 |
1982 |
Pascal neprelungit | iniţială | ISO 7185:1990 | 1989 |
Pascal extins | extins | ANSI/IEEE 770X3.160:1989 | 1989 |
ISO/ IEC 10206 | 1991 | ||
Extensii orientate pe obiecte la Pascal [14] |
extensie orientată pe obiecte | ANSI/X3-TR-13:1994 | 1993 |
Una dintre principalele caracteristici suplimentare ale extensiei Extended Pascal orientate pe obiecte a fost modularitatea și facilitățile care facilitează compilarea separată.
Standardizarea limbii era în urmă cu aspectul real al anumitor caracteristici ale limbii. Implementările comerciale au standardul Pascal extins; acest lucru a fost făcut în UCSD Pascal, modificarea de către Apple a Object Pascal , Turbo Pascal de la Borland (o versiune ușor modificată a Apple) și ramurile sale. Niciuna dintre implementările comerciale comune ale lui Pascal nu se conformează exact cu niciunul dintre standardele de limbă oficială.
Pascal, în forma sa originală, este un limbaj pur procedural și include multe structuri asemănătoare algolului și constructe de cuvinte rezervate precum if, then, else, while, etc. Cu toate acestea for, repeatPascal conține și un număr mare de posibilități de structurare a informațiilor și abstracțiilor , care lipsesc din Algol-60 original , cum ar fi definiții de tip , înregistrări , pointeri , enumerări și seturi . Aceste construcții au fost parțial moștenite sau inspirate din Simula -67 , Algol-68 creat de Niklaus Wirth AlgolWsi propus de Hoare .
În dialectele moderne (Delphi Pascal, Free Pascal), sunt disponibile operațiuni precum supraîncărcarea operatorului și a funcțiilor.
Programele Pascal încep cu un cuvânt cheie Program urmat de numele programului urmat de un punct și virgulă (opțional în unele dialecte), numele poate fi urmat în paranteze de o listă de descriptori de fișier extern ("mediu") ca parametri; este urmat de corpul programului, format din secțiuni care descriu constante ( Const), tipuri ( Type), variabile ( Var), declarații de proceduri ( Procedure) și funcții ( Function) și blocul de instrucțiuni care le urmează , care este punctul de intrare în program. În Pascal , blocul este limitat la cuvintele cheie beginși end. Instrucțiunile sunt separate prin punct și virgulă , după ce corpului este plasat un punct , care servește ca semn al sfârșitului programului.
Cazul personajelor din Pascal nu contează.
Astfel, cel mai simplu program Pascal („blank”) ar arăta astfel:
programul p ; incepe sfarsitul .Programul de mai sus nu face nimic și conține un bloc gol de instrucțiuni.
Un exemplu de program care tipărește șirul „ Bună, lume!” »:
program salut ; ÎNCEPE writeln ( "Bună ziua, lume!" ) ; // operator de ieșire șir sfârşitul .Există tipuri simple în Pascal standard și extins: virgulă mobilă ( real), numere întregi ( integer), caracter ( char), boolean ( boolean) și enumerații (constructor de tip nou introdus în Pascal).
Turbo Pascal a adăugat limbii variante de aceste tipuri: de exemplu, shortintva fi mai scurt integerși va fi longint mai lung.
Dialectele moderne ale lui Pascal, cum ar fi FPC sau Delphi , consideră că integer - acesta este numărul întreg cel mai potrivit pentru o anumită mașină, folosit, de exemplu, pentru indici de matrice , și shortint, longintși altele - numere întregi de o anumită lungime; acest lucru este util pentru programarea multiplatformă . La fel și cu numerele fracționale.
Tipurile au fost extinse din nou la trecerea la x64 - „doar un număr întreg” ( integer) a rămas pe 32 de biți, dar era necesar un tip special, care este egal longintcu x86 și int64x64.
Tipuri întregi:
Tip de | Gamă | Format | Dimensiunea în octeți | Note |
---|---|---|---|---|
octeți | 0..255 | nesemnat | unu | |
ShortInt | −128..127 | Simbolic | unu | |
SmallInt | −32768..32767 | Simbolic | 2 | Poate să nu existe; în schimb un număr întreg cu același interval |
Cuvânt | 0..65535 | nesemnat | 2 | |
cuvânt lung | 0..4294967295 | nesemnat | patru | |
LongInt | −2147483648..2147483647 | Simbolic | patru | |
int64 | −9223372036854775808..9223372036854775807 | Simbolic | opt | |
QWord | 0..18446744073709551615 | nesemnat | opt | |
Întreg | -32768..32767. | Simbolic | 2 sau 4 | Cel mai rapid număr întreg; SmallInt sau LongInt |
cardinal | ? | nesemnat | ? | Cel mai rapid număr întreg; de obicei LongWord |
NativeInt | ? | Simbolic | ? | Se potrivește cu registrul mașinii; LongInt sau Int64 |
NativeUInt | ? | nesemnat | ? | Se potrivește cu registrul mașinii; LongWord sau QWord |
Numere în virgulă mobilă:
Tip de | Gamă | Numărul de cifre semnificative | Dimensiunea în octeți | A sustine |
---|---|---|---|---|
Real | dependent de platformă | ??? | ??? | Toate compilatoarele; pe cele moderne este de obicei echivalent cu Double |
Real48 | 2.9E−39..1.7E38 | 11-12 | 6 | Borland; în Turbo Pascal se numea Real; nu folosește un coprocesor și, prin urmare, rezultatul se repetă la bit |
Singur | 1.5E−45..3.4E38 | 7−8 | patru | Cele mai multe opțiuni pentru mașini compatibile cu IEEE 754 |
Dubla | 5.0E-324..1.7E308 | 15−16 | opt | Cele mai multe opțiuni pentru mașini compatibile cu IEEE 754 |
Extins | 3.4E-4951..1.1E4932 | 19−20 | zece | Cele mai multe opțiuni pentru x86 |
Comp | −9223372036854775808..9223372036854775807 | opt | Borland; Număr întreg de 8 octeți calculat pe coprocesor; relevante pentru x86 pe 16 biți | |
Valută | −922337203685477.5808..922337203685477.5807 | opt | Borland și alte compilatoare pentru Windows; asociat cu OLE ; punct fix cu unitatea egală cu 10000 |
În Pascal, operațiunile pe biți sunt permise pe tipuri de întregi (octet, scurtă, cuvânt, întreg, lung și intervalele acestora). Operații logice pe biți:
Pe biții a doi operanzi întregi, puteți efectua operațiunile logice considerate anterior: not, și, sau, xor. Diferența dintre operațiile bit-bit și cele logice este că operațiile bit-bit (bit-bit) sunt efectuate pe biți individuali ai operanzilor, și nu pe valoarea lor în reprezentare zecimală (de obicei).
Se distinge conceptul de tipuri de date ordinale (ordinal), ele includ tipuri întregi (semnate și nesemnate), logice ( boolean), caractere ( char), tipuri enumerate și tipuri de intervale.
Tipurile ordinale sunt specificate printr-un număr întreg (cod), care poate fi obținut folosind funcția ord. Toate operațiile efectuate pe tipurile ordinale sunt efectuate pe codurile acestora.
Intervalele conțin un subset de valori ale altor tipuri ordinale:
var x : 1 .. 10 ; y : 'a' .. 'z' ; z : pară..portocaliu ; _ _Pentru tipurile ordinale, sunt definite operații inc, dec, succ, pred, ord, operații de comparare ( ), ele pot fi folosite în operatori , (ca numărător de bucle), ca limite de matrice, pentru a specifica elemente de seturi și tipuri de intervale. = > < => <= <>casefor
În Pascal, spre deosebire de limbajele asemănătoare C, operațiile aritmetice cu numere întregi nu sunt definite cu booleantipuri char.
SeturiSpre deosebire de multe limbaje comune, Pascal acceptă un tip de date set special :
var set1 : set de 1 .. 10 ; set2 : set de 'a' .. 'z' ; set3 : set de pere ..portocaliu ; _Un set este un concept fundamental în matematica modernă care poate fi folosit în mulți algoritmi.
În Pascal, un tip de set poate conține doar elemente de același tip de tip ordinal. Această caracteristică este utilizată pe scară largă și este de obicei mai rapidă decât construcția echivalentă într-un limbaj care nu acceptă seturi. De exemplu, pentru majoritatea compilatoarelor Pascal:
if i in [ 5 .. 10 ] then { verificarea daca elementul apartine multimii } ...procesate mai repede decât
dacă ( i >= 5 ) și ( i <= 10 ) atunci { test boolean } ...Pentru a seta valoarea setului, se folosește o listă de elemente ale setului, separate prin virgule și cuprinse între paranteze drepte (după cum se arată deja mai sus):
var { secțiunea declarație variabilă } d : set de caractere ; începe { începutul blocului } d := [ 'a' , 'b' ] ; ...În Pascalul lui Jensen și Wirth, șirurile de caractere erau reprezentate ca șiruri de caractere împachetate; prin urmare, aveau o lungime fixă și erau de obicei căptușite la acea lungime cu spații.
Tipuri compoziteNoi tipuri pot fi definite din cele existente:
type { type declaration section } x = Integer ; y = x ; ...Mai mult, tipurile compozite pot fi construite din tipuri primitive:
type { type declaration section } a = Array [ 1 .. 10 ] of Integer ; { definiția matricei } b = înregistrare { definiția înregistrării } x : Integer ; y : Char ; sfârşitul ; c = Fișierul a ; _ { definiția fișierului }Tipurile de fișiere în Pascal sunt împărțite în fișiere tip, text și fără tipuri.
După cum se arată în exemplul de mai sus, fișierele tastate în Pascal sunt secvențe de elemente de același tip. Pentru fiecare fișier, există o variabilă de tip buffer pointer, notat cu f^. Procedurile get(pentru citire) și put(pentru scriere) mută indicatorul la următorul element. Citirea este implementată în așa fel încât read(f, x)să fie la fel ca get(f); x:=f^. În consecință, înregistrarea este implementată în așa fel încât write(f, x)să fie la fel ca f^ := x; put(f). Fișierele text sunt textdefinite ca o extensie de tip file of charși, în plus față de operațiunile standard asupra fișierelor tastate (citirea, scrierea unui caracter), permit introducerea/ieșirea caracterelor într-un fișier de toate tipurile de date, similar intrării/ieșirii din consolă.
Fișierele fără tipuri sunt declarate ca variabile de tip file. Cu ele, puteți efectua operațiuni I/O netipizate octet cu octet pentru mai multe blocuri de octeți de o lungime specificată printr-un buffer, pentru aceasta se folosesc proceduri speciale blockreadși blockwrite(extensie UCSD).
ȘiruriPascal modern [15] folosește tipul încorporat string, care acceptă concatenarea ( +) și compararea ( > < = <> >= <=), pentru a lucra cu șiruri. Șirurile sunt comparate în ordine lexicografică . De exemplu, șirurile sunt considerate egale dacă au aceeași lungime și codurile tuturor caracterelor cu același index se potrivesc.
Tipul string [n]sau pur și simplu stringîn dialectele limbajului anilor 1970-1990 a fost definit ca o matrice de caractere array [0..n] of char(n implicit a luat valoarea 80 în UCSD Pascal și 255 în Turbo / Borland Pascal), elementul zero al matricei din acest reprezentarea servește la setarea lungimii șirului, respectiv, șirul ar putea avea o dimensiune maximă de 255 de caractere. În mod implicit, în Delphi și FreePascal, tipul AnsiString este folosit ca șir de caractere, a cărui memorie este alocată și eliberată dinamic de către compilator, iar dimensiunea maximă a șirului în implementările curente este de 2 gigaocteți. În plus, în Delphi și Free Pascal , tipul UnicodeString poate fi folosit ca tip, unde este utilizată o reprezentare pe 16 biți a caracterelor în stringcodificarea UCS-2 , în timp ce nu există mijloace de conversie din șiruri de un singur octet în șiruri de mai mulți octeți. și înapoi în biblioteca standard FPC, dar sunt disponibile în Delphi.
Delphi 2009 și versiunile superioare au o construcție pentru declararea unui AnsiString cu o anumită pagină de cod:
tip CyrillicString = AnsiString ( 1251 ) ; CP866String = AnsiString ( 20866 ) ; IndicatoriPascal acceptă utilizarea pointerilor (tactile ^типși netipizate pointer):
tip a = ^ b ; b = înregistrarea x : Număr întreg ; y : Char ; z : a ; sfârşitul ; var pointer_to_b : a ;Aici variabila pointer_to_b este un pointer către tipul de date b, care este o înregistrare. Un pointer tipizat poate fi definit ( lookahead ) înainte de declararea tipului la care se referă. Aceasta este una dintre excepțiile de la regulă , care prevede că orice element (constant, tip, variabilă, procedură, funcție) trebuie declarat înainte de a fi utilizat . Introducerea acestei excepții vă permite să organizați definiții recurente ale structurilor de date, inclusiv cum ar fi liste liniare , stive , cozi , arbori, inclusiv un pointer către o intrare în descrierea acestei intrări (vezi și: null pointer - nil).
Pentru un pointer tipizat, este definită o operație de dereferire (sintaxa sa este: указатель^).
Pentru a crea o înregistrare nouă și a atribui o valoare 10și un simbol Acâmpurilor xși yîn aceasta, sunt necesare următoarele instrucțiuni:
nou ( pointer_to_b ) ; { alocarea memoriei către pointer } pointer_to_b ^. x := 10 ; { dereferențiarea indicatorului și accesarea câmpului de înregistrare } pointer_to_b ^. y := 'A' ; pointer_to_b ^. z : = zero ... dispune ( pointer_to_b ) ; { eliberarea memoriei de sub indicator }De asemenea, puteți utiliza operatorul pentru a face referire la câmpuri din înregistrări și obiecte with, așa cum se arată în exemplu:
nou ( pointer_to_b ) ; cu pointer_to_b ^ do begin x := 10 ; y := 'A' ; z := sfârşit nul ; ... dispune ( pointer_to_b ) ; Tip proceduralÎn limbajul original al lui Pascal Jensen și Wirth, tipul procedural a fost folosit numai atunci când descrie un parametru formal. Exista deja un tip procedural complet în TP . Declarația de tip conține antetul unei proceduri sau funcție (fără nume), care descrie în general interfața subrutinei. O valoare de acest tip conține un pointer către o subrutină cu un titlu corespunzător celui declarat în declarația de tip. Un identificator de variabilă poate fi utilizat pentru a apela procedura sau funcția corespunzătoare.
Exemplu de subrutină pentru Pascal tip myfunc = function : string ; func1 : șir ; _ begin func1 := 'functia #1' end ; func2 : șir _ _ begin func2 := 'functia #2' end ; var fun : my func ; începe distracția :=@ func1 ; writeln ( distracție ) {funcția func1 este numită} end .Pascal este un limbaj de programare structurat , ceea ce înseamnă că un program constă din instrucțiuni standard separate care sunt executate secvenţial, în mod ideal fără a utiliza o comandă GOTO.
Exemplu pentru Pascal while a <> b do { buclă cu precondiție } writeln ( 'Așteptare' ) ; if a > b then { conditional statement } writeln ( 'Condiția îndeplinită' ) else { else-section - poate fi omis} writeln ( 'Condiția a eșuat' ) ; for i := 1 to 10 do { iteration loop } writeln ( 'Iteratie #' , i : 1 ) ; pentru i în [ 1 .. 10 ] do { iterați prin mulțime } writeln ( ' Iterația # ' , i : 1 ) ; { a apărut în versiunea 2.4.0 } cu un do {Operator Cu - o metodă de a accelera accesul la câmpurile de înregistrare} începe l := 1 ; k := 2 ; p :=- 3 ; sfârşitul ; repeta { postcondition bucla } a := a + 1 pana la a = 10 ; cazul i de { operator cu alegere multiplă condiționată } 0 : scrieți ( 'zero' ) ; 1 : scrie ( 'unul' ) ; 2 : scrie ( 'două' ) else scrie ( 'număr necunoscut' ) { else-section - poate fi omis} end ;În instrucțiuni while, for, if, un bloccase poate fi folosit ca instrucțiune executabilă . O astfel de construcție, care este o declarație obișnuită sau bloc, se numește o declarație complexă .
În Turbo Pascal, pentru a controla procesul de compilare, există directive care sunt plasate în comentarii și vă permit să comutați modurile de funcționare ale compilatorului - de exemplu, activați și dezactivați verificările pentru operațiuni I/O, depășiri:
Exemplu pentru Pascal atribui ( inp , 'text.txt' ) ; {$I-} { dezactivează modul de verificare IO - generarea codului de ieșire al programului în caz de eroare I/O } { (pentru cazul în care fișierul nu este găsit)} reset ( inp ) ; {$I+} { enable IO checking mode } if IOresult = 0 then begin { verificați valoarea variabilei ioresult(<>0 în cazul unei erori I/O) } ... close ( inp ) ; end else writeln ( 'fișierul nu a fost găsit' )Există directive similare cu directivele de preprocesor C/C++ ( $ifdef, $define, $include), acestea sunt procesate de compilator în timpul compilării.
În Pascal, subrutinele sunt împărțite în proceduri și funcții. În același timp, funcțiile returnează în mod explicit o valoare (rezultat) de un anumit tip, iar procedurile în mod explicit nu returnează nimic.
Sintactic, descrierea unei proceduri sau a unei funcții constă dintr- un antet care conține cuvântul cheie proceduresau function, numele, care poate fi urmată de o descriere a parametrilor (formali) trecuți între paranteze. :Pentru o funcție , tipul valorii returnate este indicat prin caracterul două puncte . Titlul se termină cu punct și virgulă ;. Antetul este urmat de corpul , care conține (eventual) secțiuni de descriere a constantelor locale, tipuri, variabile, proceduri, funcții și (obligatoriu) care conține un bloc de instrucțiuni, urmat de un caracter punct și virgulă ;.
Exemplu de program pentru Pascal program ( ieșire ) ; _ var i : întreg ; procedura print ( var j : integer ) ; function next ( k : intreg ) : intreg ; start next := k + 1 end ; începe scrierea ( 'Total: ' , j ) ; j := următorul ( j ) sfârşitul ; începe i := 1 ; în timp ce i < = 10 imprimă ( i ) sfârşitul .Corpul unei proceduri, ca un program, poate conține, la rândul său, descrieri ale procedurilor și funcțiilor. Astfel, procedurile și funcțiile pot fi imbricate unele în altele atât de adânc cât se dorește, în timp ce corpul programului este cel mai de sus din lanț.
Mai mult, în interiorul acestuia sunt disponibile conținutul secțiunilor de descriere de variabile, tipuri, constante, corp extern (proceduri, funcții, programe) aflate înainte de descrierea procedurii/funcției. De asemenea, în majoritatea dialectelor, puteți accesa parametrii unei proceduri externe dintr-o procedură.
După antetul procedurilor/funcțiilor, în locul corpului, se poate plasa cuvântul cheie forward, acest lucru se face dacă descrierea procedurii/funcției se află în program după apelarea acestuia și este asociată cu posibilitatea de compilare a programului în o trecere susținută în Pascal.
Funcțiile și procedurile matematice standard ale lui Pascal Funcții matematiceNumele funcției | Tipul argumentului | Tipul valorii | Rezultatul calculului |
Abs(x) | întreg real | întreg real | Valoarea absolută a lui "x" |
sin(x) | real | real | sine "x" rad. |
Cos(x) | real | real | cosinus "x" rad. |
Arctan(x) | real | real | arc-tangente a lui "x" ( -Pi/2 <y< Pi/2 ) |
Sqrt(x) | real | real | rădăcină pătrată a lui "x" |
Sqr(x) | întreg real | întreg real | valoarea lui "x" la pătrat ( x 2 ) |
putere(a,x) | real | real | valoarea lui "a" la puterea lui "x" ( a x ) |
exp(x) | real | real | valoarea lui "e" la puterea lui "x" ( e x , unde e= 2,718282... ) |
Ln(x) | real | real | logaritmul natural al lui "x" ( x > 0 ) |
frac(x) | real | real | parte fracțională „x” |
Int(x) | real | real | parte întreagă „x” |
Aleatoriu | - | real | număr aleatoriu ( 0 <=y< 1 ) |
Aleatoriu (x) | Cuvânt | Cuvânt | număr aleatoriu ( 0 <=y< x ) |
Succ(c) | ordinal | ordinal | caracter după „s” |
pred(c) | ordinal | ordinal | precedând caracterul „cu”. |
Numele funcției | Tipul argumentului | Tipul valorii | Rezultatul calculului |
Inc(x) | întreg | întreg | Mărește „x” cu 1 ( x:=x+1; ) |
Dec(x) | întreg | întreg | Reduce „x” cu 1 ( x:=x-1; ) |
Inc(x, n) | întreg | întreg | „x” prin n ( x:=x+n; ) |
Dec(x, n) | întreg | întreg | „x” prin n ( x:=xn; ) |
Numele funcției | Tipul argumentului | Tipul valorii | Rezultatul calculului |
Str(x, s) | x-întreg sau real | s-string | Secvența de caractere „s” din cifrele numărului „x” |
Val(s, v, cod) | s-string | v-întreg sau cod-întreg real | Forma binară a numărului de secvență „s” cod=0 (cod de eroare) |
Numele funcției | Tipul argumentului | Tipul valorii | Rezultatul calculului |
Trunc(x) | real | LongInt | parte întreagă „x” |
Rotunzi (x) | real | LongInt | rotunjind „x” la un număr întreg |
Impar(x) | întreg | logic | returnează True dacă „x” este un număr impar |
Chr(x) | octeți | Char | caracterul cod ASCII „x” |
Ord(x) | Char | octeți | Cod de caractere ASCII „x” |
Înainte de apariția modulelor conectate în forma lor modernă, unele implementări ale lui Pascal suportau modularitatea datorită mecanismului de includere a fișierelor de antet, similar mecanismului #includedin limbajul C: folosind o directivă specială formatată ca pseudo-comentare, de exemplu, {$INCLUDE "файл"}, conținutul fișierului specificat a fost inclus direct în codul sursă al programului, sub formă de text. Astfel, a fost posibil să se împartă codul programului în mai multe fragmente, pentru o editare ușoară, dar înainte de compilare, acestea au fost combinate automat într-un singur fișier de program, care a fost în cele din urmă procesat de compilator. Această implementare a modularității este primitivă și are multe defecte evidente, așa că a fost rapid înlocuită.
Implementările moderne Pascal (începând cu UCSD Pascal) suportă module. Modulele de program pot fi de două tipuri: modulul principal de program, care, ca de obicei, începe cu cuvântul cheie program și al cărui corp conține cod care se rulează după ce programul este încărcat în memorie și module auxiliare care conțin tipuri, constante, variabile, proceduri și funcții destinate utilizării în alte module, inclusiv în modulul principal.
StructuraStructura generală a unui plug-in în Pascal este următoarea:
unitate UnitName1 ; interfata ... implementare ... begin {poate fi omis - folosit dacă instrucțiunile de inițializare trebuie plasate} ... end .Este posibilă și o altă opțiune:
unitate UnitName2 ; interfata ... implementare ... initializare ... finalizare .... sfârşitul .Spre deosebire de programul principal, un fișier modul începe cu cuvântul cheie UNITurmat de numele modulului și punct și virgulă. Implementările moderne necesită de obicei ca numele unui modul să fie același cu numele fișierului de cod sursă care conține modulul. Un modul conține trei secțiuni: o secțiune de interfață, o secțiune de implementare și un corp de modul.
Secțiunea de interfață vine pe primul loc, începe cu un cuvânt cheie INTERFACEși se termină în punctul din modul în care începe secțiunea sau corpul de implementare. Secțiunea de interfață declară acele obiecte (tipuri, constante, variabile, proceduri și funcții - pentru ele sunt plasate anteturi) care trebuie să fie disponibile din afara modulului. În acest caz, este permisă o declarație parțială de tipuri: acestea pot fi declarate fără a specifica o structură, cu un singur nume. Când se utilizează acest tip într-un program extern, este permisă declararea variabilelor și parametrilor de acest tip, atribuirea de valori, dar este imposibil să accesați detaliile implementării acestuia. Procedurile și funcțiile din secțiunea de interfață sunt declarate ca forward - anteturi cu parametri, dar fără corp. Compoziția secțiunii de interfață a modulului este de așa natură încât este suficientă generarea codului care utilizează acest modul. Variabilele declarate în secțiunea de interfață sunt globale, adică există într-o singură instanță și sunt disponibile în toate părțile programului care utilizează acest modul.
Secțiunea de implementare urmează secțiunea de interfață și începe cu cuvântul cheie IMPLEMENTATION. Conține descrieri ale procedurilor și funcțiilor declarate în secțiunea de interfață, precum și descrieri ale tipurilor, constantelor, variabilelor, procedurilor și funcțiilor care sunt necesare pentru implementarea procedurilor și funcțiilor de interfață. Descrierea unei proceduri sau funcție declarată într-o secțiune de interfață trebuie să aibă exact același titlu ca și în declarație. Organismul poate utiliza alte proceduri și funcții ale acestui modul, declarate atât în partea interfață, cât și în secțiunea implementare. Variabilele declarate în secțiunea de implementare sunt, de fapt, globale (adică există o singură instanță a fiecărei variabile în întregul program), dar sunt accesibile doar din procedurile și funcțiile descrise în secțiunea de implementare a acestui modul, cât şi din corpul său. Dacă există declarații de tip prescurtate în secțiunea de interfață, atunci acele tipuri trebuie să fie declarate integral în secțiunea de implementare.
Corpul unui modul începe cu cuvântul cheie la nivelul superior de imbricare BEGIN. Corpul conține cod de program care este executat o dată când modulul este încărcat. Corpul poate fi folosit pentru inițializare, alocarea de valori inițiale variabilelor modulului, alocarea de resurse pentru funcționarea acestuia și așa mai departe. Corpul modulului poate lipsi. Într-un număr de implementări Pascal, de exemplu, în Delphi, două secțiuni (de asemenea, opționale) pot fi utilizate în locul corpului modulului - INITIALIZATIONși FINALIZATION. Sunt plasate la sfârșitul modulului, după cuvântul cheie corespunzător. Prima, secțiunea de inițializare, conține codul care trebuie executat la încărcarea modulului; a doua, secțiunea de finalizare, conține codul care va fi executat la descărcarea modulului. Secțiunea de finalizare poate efectua acțiuni, inițializări inverse - elimina obiecte din memorie, închide fișiere, eliberează resursele alocate.
ENDModulul se termină cu un cuvânt cheie punct.
UtilizarePentru a utiliza un modul, programul principal sau alt modul trebuie să importe modulul, adică să conțină o declarație de utilizare a acestuia. Această declarație se face cu o instrucțiune de includere a modulelor, care este cuvântul cheie USESurmat de un nume separat prin virgulă al modulelor care urmează să fie incluse. Instrucțiunea de conectare trebuie să urmeze imediat antetul programului sau după cuvântul cheie INTERFACEdacă conexiunea se face într-un modul.
Modulele conectate în secțiunea de interfață pot fi utilizate în întregul modul - atât în secțiunea de implementare, cât și în corp. Dar secțiunea de implementare poate avea propria instrucțiune include (urmează cuvântul cheie IMPLEMENTATION) care conține numele pluginurilor care nu sunt în secțiunea de interfață, dar sunt necesare secțiunii de implementare. Un motiv pentru a utiliza o listă de conexiuni separată pentru secțiunea de implementare este atunci când două sau mai multe module se folosesc reciproc. Pentru a evita trimiterile circulare în declarațiile de utilizare a unor astfel de module, cel puțin unul dintre ele trebuie să îl includă pe celălalt în secțiunea implementare.
Orice obiecte declarate în secțiunile de interfață ale modulelor pot fi utilizate în programul la care sunt conectate aceste module. Numele obiectelor importate din pluginuri rămân aceleași și pot fi folosite direct. Dacă două sau mai multe module conectate au obiecte care au același nume și compilatorul nu poate face distincția între ele, atunci când se încearcă utilizarea unui astfel de obiect, va fi generată o eroare de compilare - specificarea numelui ambiguu. În acest caz, programatorul trebuie să aplice calificarea numelui - specificați numele în formatul „<nume_modul>.<nume_obiect>”.
Pot apărea probleme dacă este nevoie de a utiliza două module diferite cu același nume în program. Dacă modulele sunt disponibile numai în formă compilată (adică este imposibil să le schimbi numele), este imposibil să le importați în același timp. Nu există o soluție standard pentru o astfel de coliziune la nivel de limbaj, dar compilatorii specifici pot oferi o modalitate sau alta de a o ocoli, în special, mijloacele de a atribui alias-uri modulelor importate și de a specifica direct ce modul să ia din ce fișier.
Compilarea și legareaModulele sunt concepute pentru a fi compilate separat - compilatorul nu trebuie să compileze module importate pentru a compila modulul care le utilizează. Totuși, pentru a compila corect un modul, compilatorul trebuie să aibă acces la secțiunea de interfață a tuturor modulelor pe care le folosește. Există două abordări diferite, uneori combinate, pentru organizarea unui astfel de acces.
Pentru funcționarea normală a modulului, poate fi necesară efectuarea unor acțiuni înainte de a-l utiliza: inițializarea variabilelor, deschiderea fișierelor necesare, alocarea memoriei sau a altor resurse. Toate acestea se pot face în corpul modulului sau în secțiunea de inițializare. Reversul initializării se face în secțiunea de finalizare.
Ordinea de inițializare și finalizare a modulelor este indirect determinată de ordinea de declarare în secțiunea utilizări, dar pentru programele compilate static (unde modulul este fie compilat într-un fișier executabil cu programul principal, fie localizat într-o bibliotecă dinamică separată, dar încărcat în stadiul inițial de încărcare), compilatorul garantează întotdeauna că inițializarea se va face înainte de prima utilizare a modulului. Finalizarea se face atunci când programul se termină, după terminarea modulului principal, astfel încât modulele care sunt utilizate sunt finalizate mai târziu decât cele care le folosesc.
In cazul incarcarii dinamice a modulelor controlate de insusi programatorul, initializatoarele sunt executate la incarcare, adica in momentul in care comanda de incarcare a modulului a returnat controlul, initializatorul acestuia a fost deja executat. Finalizatorul este executat după descărcare, de obicei când este executată comanda de descărcare a modulului. Dacă această comandă nu este apelată, modulele încărcate dinamic sunt finalizate în același mod ca toate celelalte module - când programul se termină.
Object Pascal are capacitatea de a dezvolta programe folosind paradigma de programare orientată pe obiecte . Clasele sunt definite folosind un tip objectsimilar record, care, pe lângă câmpurile de date, poate conține anteturi de procedură și metodă . Numele metodelor descrise urmează numele clasei separate printr-un punct.
Constructorul și destructorul sunt specificate ca proceduri obișnuite, dar în loc de un identificator,proceduresuntconstructorspecificatedestructor. În consecință, spre deosebire de limbajele de tip C++ , ele au un nume diferit de numele clasei, pot exista mai mulți destructori și pot avea parametri (în practică, această caracteristică este rar folosită, de obicei o clasă are un singur destructorDestroycare suprascrie virtualuldestructor al clasei părinte).
Sunt acceptate moștenirea unică, polimorfismul clasei , mecanismul metodei virtuale (cuvânt virtualdupă antetul metodei clasei). Există și metode dinamice (în TP sunt descrise prin adăugarea unui număr întreg după cuvânt virtualși sunt folosite în principal pentru procesarea mesajelor; în Delphi și FreePascal, cuvântul este folosit în aceste scopuri message, iar cuvântul este folosit pentru a crea metode dinamice obișnuite dynamic) , care se disting printr-o utilizare mai mică a memoriei și o viteză mai mică a apelurilor din cauza lipsei de duplicare a metodelor dinamice ale strămoșilor în VMT-ul copilului (cu toate acestea, FreePascal nu face distincție între metodele virtuale și cele dinamice).
În Delphi, FPC a implementat supraîncărcarea operatorului , metode abstracte, directive private, protected, public, published(în mod implicit membrii clasei sunt public):
Exemplu de program pentru Pascal tip TbasicO = procedura obiect writeByte ( b : octet ) ; virtual ; abstract ; sfârşitul ; TtextO = obiect ( TbasicO ) { moștenește TbasicO, implementează alte operațiuni de ieșire bazate pe procedura writeByte } writeS ( s : șir ) ; {..} sfârşit ; TfileO = obiect ( TbasicO ) {clasa de ieșire fișier - implementează operația de ieșire ca ieșire a unui octet într-un fișier} constructor init ( n : șir ) ; procedura writeByte ( b : octet ) ; virtual ; destructor closefile ; private f : fișier de octet ; sfârşitul ; basicO = ^ TbasicO ; textO = ^ TtextO ; fisierO = ^ TfileO ; constructor TfileO . init ( n : șir ) ; începe atribui ( f , n ) ; rescrie ( f ) sfârşit ; destructor TfileO . closefile ; începe aproape ( f ) sfârşit ; procedura TfileO . scrie octet ( b : octet ) ; începe scrie ( f , b ) sfârşit ; procedura TtextO . scrieS ( s : șir ) ; var i : întreg ; începe pentru i := 1 până la lungimea ( s ) do writeByte ( ord ( s [ i ])) final ; {..} var f : fileO ; începe nou ( f , init ( 'tstobj.txt' )) ; {aloca memorie pentru obiect și apelează constructorul} textO ( f ) ^. scrieS ( 'șir de text' ) ; dispose ( f , closefile ) {apelează destructorul și eliberează memoria obiectului} end .În dialectul Delphi, clasele pot fi construite și folosind un cuvânt class(mai mult, moștenirea reciprocă cu object-clasele nu este permisă) și sunt introduse interfețe ( interface) - toate metodele sunt abstracte și nu pot conține câmpuri de date.
Toate clasele (create cu class) moștenesc TObjectde la , toate interfețele derivă din IUnknown. Clasele create cu classpot implementa mai multe interfețe.
Interfețele au fost introduse în Delphi pentru a sprijini tehnologia COM a Microsoft .
Clasele ( Class) spre deosebire de clasele obișnuite ( Object) nu au nevoie de alocare/dealocare explicită a memoriei, memoria pentru ele este alocată dinamic de către un constructor cu numele Create, numită cu numele clasei și este eliberată când destructorul cu numele este apelat Destroy(ele poate avea alte nume). O variabilă a unei astfel de clase, spre deosebire de o clasă, objectstochează adresa unei instanțe a clasei în memorie, valoarea nileste folosită pentru a indica o referință goală, prin urmare, pentru a elibera un obiect, este definită TObjecto metodă specială freecare verifică referința la nilși cheamă destructorul virtual Destroy. Codul care utilizează astfel de clase ar arăta astfel:
Exemplu pentru Pascal q1 := t1 . crea ( 9 ) ; { obiect de construcție (t1 - numele clasei) } writeln ( q1 . InstanceSize ) ; { afișarea dimensiunii unei instanțe de clasă } q1 . Gratuit ; { distrugere obiect } q1 := nil ; { astfel încât destructorul să nu fie apelat din nou când este numit gratuit }În modificarea ObjectPascal/Delphi/FreePascal, în descrierea claselor apar proprietăți (proprietate), care combină comoditatea lucrului cu variabile (al căror rol în OOP îl joacă câmpurile) și apeluri de metodă care notifică întotdeauna obiectul de o schimbare a stării sale:
Exemplu de program pentru Pascal tip TMyObj = clasa ( TObject ) FProp : întreg ; procedura SetProp ( AValue : integer ) ; proprietate MyProp : întreg citit FProp scrie SetProp ; sfârşitul ; procedura TMyObj . SetProp ( AValue : întreg ) ; începe FProp := AValue ; Writeln ( „Cineva a schimbat MyProp!’ ) ; sfârşitul ; var MyObj : TMyObj ; începe MyObj := TMyObj . a crea ; MyObj . FProp := 5 ; MyObj . MyProp := MyObj . MyProp + 6 ; sfârşitul .În primul caz (folosind MyObj.FProp) câmpul obiectului a fost modificat direct, ca urmare, metodele obiectului nu vor bănui că acest câmp a fost modificat anterior; într-un caz mai complex, aceștia se pot baza pe câmpul să fie neschimbat sau câmpului i se poate atribui o valoare invalidă pentru obiectul dat. În al doilea caz, valoarea este atribuită direct proprietății obiectului, care se referă la un apel de metodă care gestionează corect modificarea câmpului dat.
Această abordare este convenabilă dacă obiectul este asociat cu un element vizual: modificarea directă a câmpului responsabil, de exemplu, pentru lățimea elementului, nu va afecta elementul vizual în sine, iar obiectul va fi „informat greșit” despre dimensiunea reală. a elementului. Abordarea corectă fără a utiliza proprietăți este de a dezvolta metode pentru obținerea și setarea oricărei valori de câmp, dar lucrul cu astfel de metode va fi mai puțin convenabil, de exemplu, în loc de ultima linie, ar trebui să scrieți
MyObj . SetProp ( MyObj . GetProp + 6 ) ;mai mult, metoda MyObj.GetProp ar fi trebuit scrisă pentru a unifica accesul.
De mare interes sunt proprietățile indexului, care se comportă aproape în același mod ca și tablourile, înlocuind accesul la un element de matrice cu un apel la metoda corespunzătoare.
Cu toate acestea, proprietățile nu sunt un „panacee”: atunci când sunt compilate, apelurile de proprietate sunt traduse direct în apeluri de metodă sau lucru direct cu câmpuri, astfel încât proprietățile nu sunt variabile reale, în special, nu pot fi transmise ca parametri var.
Dicționare și enciclopedii | |
---|---|
În cataloagele bibliografice |
|
Pascal | |||||||
---|---|---|---|---|---|---|---|
Dialectele |
| ||||||
Compilatoare |
| ||||||
IDE | |||||||
Persoane |
Limbaje de programare | |
---|---|
|
ISO | Standardele|
---|---|
| |
de la 1 la 9999 |
|
10000 până la 19999 |
|
20000+ | |
Vezi și: Lista articolelor ale căror titluri încep cu „ISO” |