Pascal (programovací jazyk)

programovací jazyk původně určený pro výuku programování
Tento článek je o standardním jazyku Pascal. O jeho rozšířeních usnadňujících praktické programování pojednává článek Turbo Pascal.

Pascal je programovací jazyk, původně určený hlavně k výuce programování. Jeho různé varianty a odvozeniny se však používají i k programování reálných aplikací. Jeho název byl zvolen na počest francouzského filosofa, matematika a fyzika Blaise Pascala.

Pascal
Paradigmaimperativní, strukturovaný
Vznik1970
AutorNiklaus Wirth
Typová kontrolastatická, silná
Hlavní implementaceCDC 6000, ICL 1900, Pascal-P, PDP-11, PDP-10, IBM System/370, HP, GNU
DialektyBorland Pascal, Turbo Pascal, UCSD Pascal
Ovlivněn jazykyALGOL, ALGOL W
Ovlivnil jazykyAda, Component Pascal, Java, Modula, Modula-2, Modula-3, Oberon, Oberon-2, Object Pascal, Oxygene, Seed7

Programovací jazyk Pascal navrhl na začátku 70. let profesor Niklaus Wirth z Vysoké školy technické v Curychu[1] s těmito cíli:

  • vytvořit jazyk vhodný pro výuku programování, který by byl založen na omezeném počtu srozumitelných konstrukcí,
  • navrhnout strukturu jazyka tak, aby jej bylo možné snadno implementovat na většině tehdejších počítačů.

První verze Pascalu byla publikována v roce 1970, mírně opravená definice jazyka vyšla v roce 1974. V roce 1981 byla vydána norma ISO. Většina implementací Pascalu se od normy ISO více či méně odchyluje, zejména zavedením dalších konstrukcí zjednodušujících praktické programování. V oblasti PC dosáhla patrně největšího úspěchu implementace Turbo Pascal firmy Borland. Objektové rozšíření Pascalu se pak stalo i základem systému Delphi téže firmy.

Historie

editovat

První kompilátor Pascalu byl navržen v Curychu pro počítače řady CDC 6000 a do provozu byl uveden v roce 1970.

První kompilátor Pascalu napsaný v Severní Americe vznikl na Illinoiské univerzitě pod vedením Donalda B. Gilliese pro počítač PDP-11 a generoval nativní strojový kód.

Za účelem rychlého rozšíření jazyka vznikl v Curychu tzv. compiler porting kit, zahrnující kompilátor do „virtuálního“ strojového kódu (nebo přesněji mezikódu) a simulátor toho kódu. Z této sady vznikl P-systém. Ačkoli byl tento systém navržen, aby umožnil vznik kompilátorů do pravých strojových kódů, minimálně jeden systém, pozoruhodná implementace USCD, jej využila k vytvoření interpretačního systému USCD p-System.

IP Pascal byl implementací používající Micropolis DOS, rychle se však přesunul na CP/M běžící na Z80.

Začátkem 80. let byl UCSD Pascal portován pro počítače Apple II a Apple III, aby tak poskytl strukturovanou alternativu k interpretům BASICu, dodávaným spolu s počítačem.

V 80. letech také napsal Anders Hejlsberg kompilátor Blue Label Pascal pro počítač Nascom-2. Později začal pracovat pro Borland a svůj kompilátor přepsal na Turbo Pascal pro CP/M a IBM PC. Nový kompilátor prodával za 49,95 USD, což byla mnohem nižší cena než za jakou prodával původní Blue Label Pascal.

Laciný kompilátor společnosti Borland měl velký vliv na komunitu okolo Pascalu, která se koncem 80. let zaměřila především na IBM PC. Mnoho počítačových nadšenců ve svém hledání strukturované alternativy k BASICu tento produkt používalo. Turbo Pascal, dostupný pouze na této architektuře, překládal přímo do strojového kódu Intel 8088, čímž docílil mnohem větší rychlosti než interpretované návrhy.

S verzí Turbo Pascal 5.5 přidal Borland podporu pro objektově orientované programování. Později se Borland rozhodl, že je potřeba komplikovanějších vlastností a začal pracovat na Delphi, přičemž vycházel z návrhu jazyka Object Pascal společnosti Apple. V raných verzích nazýval tento jazyk rovněž Object Pascal, později jméno změnil na programovací jazyk Delphi.

Jazykové konstrukce

editovat

Pascal je ve své původní formě čistým procedurálním jazykem, obsahující skupinu řídicích konstrukcí jako je for, while, if, then, else, převzaté z ALGOLu. Obsahuje však také mnoho konstrukcí pro strukturování dat, jako jsou definice datových typů, záznamy (také struktury, record), ukazatele (pointer), výčtové typy a množiny (set).

Programy v Pascalu začínají klíčovým slovem program, v původních variantách se seznamem standardních vstupů a výstupů ve formě parametrů. Následují deklarace návěští, konstant, typů a proměnných a pak hlavní blok příkazů, uvozený klíčovými slovy begin a end. Jednotlivé příkazy jsou odděleny středníkem, tečka ukončuje program. Jazyk nerozlišuje velká a malá písmena.

Hello world

editovat

Standardní program Hello world vypadá v jazyce Pascal takto:

program HelloWorld(output);
begin
  WriteLn('Hello, World!');
end.

Datové typy

editovat

Datový typ definuje strukturu proměnné a způsob nakládání s ní. Jazyk obsahuje několik předdefinovaných typů, přičemž programátor může odvozením tvořit typy další. Mezi předdefinované typy patří:

Datový typ Typ hodnot, které lze do typu uložit
integer Celé číslo
real Číslo s plovoucí řádovou čárkou
boolean Hodnota true nebo false
char Jeden znak znakové sady

Rozsah povolených hodnot, které je možno uložit do proměnných těchto typů, je dán implementací. Mezi některými typy existují konverzní funkce, například Round (zaokrouhlení real na integer).

Deklarace typu

editovat

Programátor může vytvořit vlastní datový typ odvozením ze základních typů pomocí konstrukce type:

type
  MyInteger = integer;
  MyIntegerPlus = 0..maxint;

Výčet

editovat

Datový typ výčet umožňuje vytvořit proměnnou, která může nabývat určitý počet pojmenovaných číselných hodnot (hodnot označených identifikátory).

type
  FruitEnum = (jablko, hruska, svestka, banan, citron, pomeranc, grapefruit, mandarinka);
var
  Ovoce: FruitEnum;

Hodnoty výčtových typů nelze v Pascalu přímo vypisovat ani načítat. Pro výpis by bylo možné použít pole obsahující jména ovoce v textovém tvaru:

var
  Nazvy_Ovoce: array[FruitEnum] of packed array[1..10] of char;

begin
  Nazvy_Ovoce[jablko] := 'jablko    ';
  Nazvy_Ovoce[hruska] := 'hruska    ';
  ...
  Nazvy_Ovoce[mandarinka] := 'mandarinka';

  for Ovoce := jablko to mandarinka do
    Writeln('Název ovoce je: ', Nazvy_Ovoce[Ovoce]);
end.

I typ boolean je v podstatě výčtem:

type boolean = (false, true);

Intervalové typy

editovat

Z libovolného ordinálního typu (všechny dříve jmenované kromě real) můžeme pomocí intervalu vybrat část, která se pak použije jako nový typ:

type
  Cislice = 0..9;
  Jadroviny = jablko..hruska;

Množinové typy

editovat

Zatímco většina programovacích jazyků používá pro reprezentaci složených bitových typů bitové řetězce, Pascal používá množinovou abstrakci. Množina je vždy určena na ordinálním typu:

type
  Citrusy = set of FruitEnum;
  Mnozina_Cislic = set of Cislice;

Ke konstruování množin se používají hranaté závorky:

  Citrusova_mnozina := [ citron, pomeranc, mandarinka, grapefruit ];
  Ciselna_mnozina := [ ]; { prázdná mnozina }

K zjištění příslušnosti prvku k množině slouží operátor in:

  if ovoce in Citrusova_mnozina then
   begin
    Writeln('Je to citrus');
   end;

Záznamy

editovat

Záznam je složený datový typ, sestávající z pojmenovaných položek obecně různých typů; odpovídá typu struktura v jiných programovacích jazycích :

type
  MyStruct = record
    a: integer;
    c: char;
    r: real;
  end;

Pole je lineární sekvence prvků, definovaná klíčovým slovem array. Ve standardním Pascalu mají pole pevnou délku, určenou při deklaraci. Indexování pole je určeno taktéž při deklaraci. Příklad definice typu pole:

type
  IntArray = array[-5..5] of integer;
  CharArray = array[1..20] of char;
  StructArray = array[0..5] of MyStruct;

Ukazatele

editovat

Ukazatel je zvláštní typ proměnné, ukazující na skutečnou hodnotu v paměti. Ukazatele lze tvořit z téměř každého typu pomocí konstrukce ^Typ. Ve standardním Pascalu nelze nijak získat adresu proměnné, inicializovat ukazatel je možné (kromě zkopírování hodnoty jiného ukazatele) pouze vyvoláním funkce New pro alokaci paměti. Dereference ukazatele se provádí operátorem ^ za názvem ukazatele:

var
  p, q: ^integer;
  i, j: integer;
begin
...
  i := 50;

  New(p);
  New(q);
  if (p=nil) or (q=nil) then
   begin
    Writeln('Nepodarilo se alokovat pamet');
   end
  else
   begin
    p^ := 1;
    q^ := i;
    i := p^;
    j := q^;
    Dispose(p);
    Dispose(q); 
   end;
...

Ukazatele se často používají ve spojitosti se strukturami, například při vytváření spojových seznamů. Pro vytvoření nové proměnné na haldě slouží procedura New, pro její uvolnění procedura Dispose. Nulová hodnota ukazatele je určena konstantou nil.

type
  PRec = ^TRec;
  TRec = record
    Data: integer;
    Next: PRec;
  end;

var
  p: TRec;

...
  New(p);
...
  Dispose(p);
...
  p := nil;
...

Typ soubor

editovat

Soubor je ve standardním Pascalu chápán jako sekvence identických komponent (file of typ komponenty). Pro každý soubor existuje přístupová proměnná, která má stejné jméno jako identifikátor souboru a je typu „ukazatel na typ komponenty“. Vstupní soubor se otevírá funkcí Reset, po jejímž vyvolání ukazuje přístupová proměnná na první komponentu souboru (pokud není soubor prázdný). Pomocí funkce Get lze zpřístupnit další komponentu. Pokud funkce eof vrací hodnotu true, nesmí se s hodnotou referencovanou přístupovou proměnnou pracovat. Pro výstup do souboru slouží funkce Rewrite pro otevření souboru a Put pro zapsání komponenty referencované přístupovou proměnnou do souboru:

program copy_non_neg(input, output);
var
  input: file of integer;
  output: file of integer;
  i: integer;

begin
  Reset(input);
  Rewrite(output);
  while not Eof(input) do
   begin
     i := input^;
     Get(input);
     if i>= 0 then
      begin
       output^ := i;
       Put(output)
      end
   end
end.

Kromě tohoto poněkud krkolomného přístupu lze používat i funkce Read a Write, které umožňují se obejít bez přístupové proměnné: Read(soubor, promenna) funguje jako promenna := soubor^; Get(soubor) a Write(soubor, promenna) funguje jako soubor^ := promenna; Put(soubor). Výše uvedený program pak lze zapsat takto:

program copy_non_neg(input, output);
var
  input: file of integer;
  output: file of integer;
  i: integer;

begin
  Reset(input);
  Rewrite(output);
  while not Eof(input) do
   begin
     Read(input, i);
     if i>= 0 then Write(output, i);
   end;
end.

Mnoho implementací ani funkce Get a Put a přístupovou proměnnou k souboru vůbec nepoužívá. Standardní Pascal nemá možnost aktualizace souboru, posunu ukazovátka po souboru, ani funkci pro zavření souboru).

Pro práci s textovými soubory existuje zvláštní typ text, který se chová podobně jako typ file of char, ale navíc umožňuje pracovat s členěním souboru na řádky pomocí funkcí Readln, Writeln a Eoln.

Řídicí struktury

editovat

Pascal je strukturovaný jazyk, to znamená, že běh programu je strukturován ve standardních konstrukcích, a to ideálně bez použití příkazu goto:

Základní řídicí strukturou je struktura if..then..else, která řídí průběh programu v závislosti na určené podmínce:

if a > b then
  writeln('a je větší než b')
else
  if a = b then
    writeln('a se rovná b')
  else
    writeln('a je menší než b');

Před else nesmí být nikdy středník. Pokud je v then části další podmíněný příkaz, else patří k poslednímu if, pokud patří k jinému if, je nutné vnořený podmíněný příkaz uzavřít mezi begin a end.

Cykly slouží pro opakované provádění příkazu nebo bloku příkazů:

while a < 10 do begin
                a:= a+1;
                end; 

for i := 1 to 10 do
  writeln('Průchod: ', i:1);

repeat
  a := a + 1
until a = 10;

case i of
  0: write('nula');
  1: write('jedna');
  2: write('dvě')
end;

Procedury a funkce

editovat

Pascal umožňuje členit programy na procedury a funkce, které lze navíc libovolně vnořovat. Konstrukce program je vždy nejvnějšnější blok. Funkce se od procedury liší tím, že umožňuje vrátit volajícímu příkazu návratovou hodnotu příslušného typu. Nastavení návratové hodnoty se provádí přiřazením do názvu funkce. Pokud se název funkce vyskytne na pravé straně přiřazovacího příkazu, považuje se za volání funkce (rekurze).

program muj(output);
 
procedure vypis(var i: integer);

  function dalsi(i: integer): integer;
  begin
    dalsi := i + 1;
  end;
 
begin
  WriteLn('Celkem: ', i);
  i := dalsi(i);
end;
 
begin
  i := 1;
  while i <= 10 do 
    vypis(i);
end.

Operátory

editovat

Pascal podporuje tyto operátory:

Operátor Význam
= rovnost
<> nerovnost
> větší než
< menší než
>= větší nebo rovno
<= menší nebo rovno
+ součet, spojení řetězců, sjednocení množin
- rozdíl, rozdíl množin
* násobení, průnik množin
/ dělení, výsledkem je reálné číslo
div celočíselné dělení
mod zbytek po celočíselném dělení, modulo
and logické AND
or logické OR
not logická negace
in přítomnost prvku v množině (set)
^ dereference ukazatele

Nedostatky standardního Pascalu

editovat

Určení jazyka Pascal jako nástroje na výuku programování a vlastnosti tehdejších operačních systémů vedly k tomu, že některé vlastnosti ve standardním Pascalu zcela chybí, a že definice jazyka zbytečně lpí na dodržování některých pravidel, což používání jazyka v mnoha ohledech komplikuje:

  • Nemá řetězce proměnné délky
  • Nemá pole proměnné délky
  • Minimální návaznost na operační systém (zpracování parametrů příkazového řádku, práce se soubory, návratový kód)
  • Úplné vyhodnocování logických výrazů
  • Nemá možnost předčasného výskoku z cyklu a zahájení nového průchodu cyklem (obdoba break a continue z jazyka C)
  • Nemá else v case
  • Neposkytuje žádné prostředky pro zpracování chybových situací
  • Chybí podpora modulárního programování

Většina implementací jazyka obsahuje rozšíření a drobné úpravy oproti standardu, které použitelnost jazyka podstatně zvyšují; nejvýznamnějším rozšířením je Turbo Pascal, který se stal vzorem pro pozdější implementace, jak mají tato rozšíření vypadat.

Související články

editovat

Reference

editovat
  1. EMRY, Katharina. Pascal: a programming language that conquered the world [online]. Curych: Spolková vysoká technická škola v Curychu, 2021-04-20 [cit. 2023-01-26]. Dostupné online. (anglicky) 

Externí odkazy

editovat

překladače: