[Obsah] [Přednáška 2]

Přednáška 1


Témata


Vyšší programovací jazyky

Programovací jazyky se dělí na nižší (např. assembler neboli jazyk symbolických instrukcí) a vyšší. Vyšší programovací jazyk je formální jazyk, ve kterém se algoritmus zapisuje strukturovaně. Zápis je srozumitelný, připomíná běžný jazyk (anglický) a matematický zápis; jazyky nejsou závislé na strojových principech počítače (procesoru, architektuře).

Vyšší programovací jazyky jsou dvojího typu: imperativní (příkazové)a neimperativní.

Program zapsaný v imperativním jazyku (např. Cobol, Pascal, Ada, C/C++, Basic, Java, Javascript, php, Python) je založen na zápisu algoritmu posloupností příkazů (zahrnující také cykly a větvení), pro práci s daty se využívají proměnné. V neimperativním jazyku je program zpravidla tvořen množinou nějakých odvozovacích pravidel, např. logických formulí. Neimperativní jazyky se dělí na funkcionální a logické.

Mezi funkcionální jazyky patří např. LISP (jehož varianta AutoLISP je součástí AutoCADu). Program ve funkcionálním jazyku je vlastně množina (ne posloupnost!) funkcí, většinou neexistují proměnné, místo nich se pracuje se seznamy dat.

V logickém jazyku je program zpravidla tvořen množinou nějakých odvozovacích pravidel, např. logických formulí. Logické jazyky se využívají zejména v umělé inteligenci, v expertních systémech. Typickým představitelem logického jazyka je Prolog (logický jazyk vestavěný do databází a odvozený od Prologu je Datalog).
Ukážeme si zápis programu v Prologu jako množinu pravidel, který umí řešit problémy vztahů mezi členy rodiny.

Definujeme klauzule:
rodic(Jana,Petr) % Jana je rodič Petra
rodic(Petr,Eva)  % Petr je rodič Evy 
muz(Petr)        % definuji, že Petr je muž
zena(Jana)       % definuji, že Jana je žena
Definujeme odvozovací pravidla:
syn(Y,X) :- rodic(X,Y), muz(Y). % čárka znamená logickou spojku „a“
dcera(Y,X) :- rodic(X,Y), zena(Y). 
prarodic(X,Z) :- rodic(X,Y), rodic(Y,Z).
potomek(Y,X) :- syn(Y,X);dcera(Y,X). % čárka znamená logickou spojku „nebo“
Pak můžeme klást dotazy:
?-rodic(A,Petr)
?-prarodic(Jana,Eva)
Systém odpoví na první dotaz A=Jana a na druhý yes.

Prolog není omezen jenom na odvozovací formule, v Prologu lze psát i výpočty, např. výpočet faktoriálu rekurzí.

Uvedený příklad ke stažení ve formě souboru: priklad.pl

Poznámka: Určitou skupinou jazyků imperativních jsou také objektově orientované jazyky (např. C++, Java), objektové rysy byly přidány i do jiných jazyků (php od verze 5, Python).

Náplní tohoto předmětu je výuka „klasického“ jazyka C se zaměřením na speciality a detaily jazyka.

Syntaxe a sémantika

S programovacími jazyky souvisejí dva pojmy, které je nutné znát, a to syntaxe a sémantika. Syntaxe definuje (řečeno zjednodušeně) pravidla zápisu programu (sentaxe je obecně v jazycích větná skladba), říká např., kde je v zápisu programu závorka, že každý příkaz je ukončen středníkem apod. Syntaxe jazyka je definována gramatikou, často se čtenář může setkat se syntaktickými diagramy. Sémantika pak určuje význam jednotlivých vět (neboli význam zápisu, který pomocí syntaktických pravidel vytvořen).
Příklad: Syntaxe jazyka C říká, že cyklus s podmínkou na začátku se zapisuje:
while (podmínka) příkaz;
Sémantika (význam) takto zapsaného cyklu je: příkaz se provádí opakovaně, zatímco je podmínka splněna.
Zkusíme si zapsat algoritmus pro výpočet kořenu lineární rovnice a ukážeme si některé „záludnosti“ vztahu mezi syntaxí a sémantikou (Algoritmus řešení lineární rovnice).

Kompilační a interpretované jazyky

Textový zápis programu ve vyšším programovacím jazyce se nazývá zdrojový kód. V případě kompilačního programovacího jazyka je zdrojový kód vstupem speciálního programu, který se nazývá překladač (kompilátor, compiler). Překladač provede nejprve syntaktickou kontrolu celého textu (kontrolu, zda je program zapsán podle pravidel jazyka); pokud se vyskytne chyba v zápise programu, překlad je přerušen a seznam chyb je zobrazen uživateli. Program bez syntaktických chyb je přeložen do strojového kódu (a optimalizován) do formy samostatně spustitelného souboru (soubory .exe nebo .com v operačních systémech firmy Microsoft, ELF formát v systému Linux). Ten je pak možné spustit samostatně. Zástupci kompilačních jazyků jsou např. Pascal, C/C++.

U interpretovaných jazyků není výsledkem procesu zpracování zdrojového kódu samostatně spustitelný soubor. Abychom program spustili, musíme mít program, který se nazývá interpret. Vstupem interpretu je také zdrojový kód. Rozdíl je, že interpret přečte jeden řádek zdrojového kódu, provede syntaktickou kontrolu a ihned zajistí jeho provedení (vykonání). Na chyby v zápise programu se tedy přijde až při běhu programu (běh programu se v tomto případě přeruší). Příkladem interpretovaných jazyků je Basic, Python, JavaScript, Visual Basic Script.

Každý z obou přístupů má své výhody a nevýhody. Výhoda kompilačního jazyka je, že se provede syntaktická kontrola celého textu, výsledný program je možné spustit samostatně bez nutnosti mít speciální programové prostředí. Běžící samostatný program je rychlejší než v případě interpretovaného jazyka. Nevýhodou je, že při jakékoliv změně programu (zdrojového kódu) je nutné provést znovu překlad (a distribuovat spustitelný soubor). Pokud je potřebné mít program pro různé operační systémy, event. pro různé počítače, je nutné mít překladač pro každý systém.
Hlavní nevýhodou programů zapsaných pomocí interpretovaného jazyka je jejich pomalý běh. Pokud se změní zdrojový kód, není potřeba jej překládat, nový program se spustí pomocí interpretu. Pokud existují interprety pro různé operační systémy, pak je snadná distribuce nových verzí programů uživatelům.

Několik moderních programovacích jazyků spojuje oba principy. Zdrojový kód syntakticky kontroluje překladač a provádí překlad jako u kompilačních jazyků. Výsledkem není samostatně spustitelný soubor, ale speciální soubor obsahující jakýsi „mezijazyk“ (vnitřní formu, virtuální strojový kód). Tato vnitřní forma je pak interpretována interpretem (kterému se také říká virtuální počítač či virtuální stroj). Výhoda tohoto přístupu je zřejmá - interpretace vnitřní formy je rychlejší než v případě klasického intepretačního jazyka, protože je při překladu provedena kompletní syntaktická kontrola a vnitřní forma může být optimalizována. Intepretace je samozřejmě ale pomalejší než při běhu samostatného kódu. Výhodou přístupu je, že mezijazyk může být intepretován stejně na různých platformách, pokud je k dispozici příslušný interpret.
Typickým zástupcem této technologie je jazyk Java. Zdrojový kód (soubory s příponou .java) jsou přeloženy do souboru s příponou .class (což je zmíněná vnitřní forma, v Javě nazývaná bytecode). Bytecode je pak interpretován programem, který se nazývá JVM (Java Virtual Machine). JVM je součástí internetových prohlížečů a interpretuje tzv. applety vložené do webových stránek.
Firma Microsoft později představila vývojový systém .NET (Dot Net), který implementuje tento princip. Zdrojové kódy mohou být v zapsány v jazyce Visual Basic NET, Visual C NET, C# (C Sharp) NET. Vnitřní formu nazývá firma Microsoft zkratkou MSIL (Microsoft Intermediate Language), interpret této vnitřní formy se nazývá CLR (Common Language RunTime).

Prezentaci věnovanou vyšším a nižším programovacím jazykům s ukázkami, která byla promítána v rámci předmětu Úvod do programování na cvičení 2, si můžete prohlédnout: Programovací jazyky.

Ukázku programu v interpretovaném jazyce Javascript, který je prováděn prohlížečem webových stránek, si můžete také stáhnout (je nutné uložit webovou stránku i soubor s kódem obsah.js a otevírat soubor vypocet_obsahu.html): vypocet_obsahu.html, obsah.js

Poznámka k překladu:
Každý programový balík překladače obsahuje soubory s programovými moduly nazývané knihovny (libraries). Jedná se nejčastěji o soubory s příponami .lib nebo .obj, resp. .o. Názorným příkladem knihovny je matematická knihovna. Procesory běžně nemají instrukci pro výpočet např. hodnoty funkce sin, logaritmu, odmocniny aj. Hodnoty se musí spočítat programově (např. součtem řady, přibližnými vzorci). Aby běžný programátor nemusel tyto výpočty zbytečně programovat sám, dodává výrobce překladače tyto funkce ve formě hotového strojového kódu právě v modulech zvaných knihovny.
A nyní konečně detailně k překladu. Překlad zpravidla probíhá dvoufázově. V první fázi, která se skutečně nazývá překlad a provádí ji překladač, se provede syntaktická kontrola. Výsledkem překladu není ještě samostatně spustitelný program, ale zatím jeho „polotovar“. Polotovar se nazývá object code a bývá uložen v souboru s příponou .obj, v operačních systémech Unixového typu typicky mají soubory příponu .o. Soubor s kódem obj obsahuje již části kódu s běžnými instrukcemi (např. sčítání). Pokud obsahuje zdrojový kód volání knihovních funkcí (např. sin), je v kódu pouze odkaz na volání funkce sin. Další fáze překladu je sestavení (neboli linkování) a provádí jej sestavovací program (linker). Vstupem sestavovacího program je object kód a potřebné knihovny. Sestavovací program vybere z knihoven kódy funkcí použitých v programu, připojí je k object kódu a teprve výsledkem sestavení je hotový spustitelný program.


  [Obsah] [Přednáška 2]