Od strojového kódu k programovacím jazykům

Programovací jazyky v historickém vývoji

  • Strojově závislé:
    • Strojový kód
    • Jazyky relativních adres
    • Jazyky symbolických adres - assemblery
    • Autokódy
  • Strojově nezávislé:
    • Zaměřené na určitý typ úloh:
      Fortran, Algol 60 - vědeckotechnické výpočty
      Cobol, RPG - hromadné zpracování dat
      Snobol - manipulace s texty
      Pascal - jednoduché výukové programy
      GPSS, Simula, Simscript - modelování diskrétních systémů
      ML/1 - univerzální makrojazyk
    • Univerzální (PL/I, Algol 68, Ada)

Jiné dělení

  • Procedurální (důraz na popis postupu výpočtu)
  • Neprocedurální (důraz na popis řešeného problému, např. LISP, Prolog a jiné specializované jazyky - například simulační, databázové, pro řízení v reálném čase...)
  • Smíšené (prvky obou přístupů, např. C++)

Strojový kód

Každý počítač dokáže zpracovávat jen určitý soubor instrukcí jemu vlastní. (V novější době sdílí často několik příbuzných typů počítačů tentýž strojový kód; mluvíme pak o rodině počítačů).

Program ve strojovém kódu se skládá z jednoduchých příkazů - instrukcí. Instrukce má většinou dvě základní části - kód operace, který udává, co se má udělat, a adresy (někdy i více adres), který říká, s jakými daty se má operace provést. Instrukce jsou zapsány čísly (navíc zapsanými ve dvojkové či šestnáctkové soustavě), strojový kód je proto pro člověka velmi nesrozumitelný. Z toho důvodu se v něm programuje jen zcela výjimečně a byla postupně vytvořena řada programovacích jazyků, které jsou pro člověka přece jenom srozumitelnější. Program zapsaný v takovém jazyce ovšem počítač přímo vykonávat neumí, a musí být proto speciálním programem - tzv. překladačem - přeložen do strojového kódu, který se teprve může provést.

Příklad kousku programu ve strojovém kódu pro počítač s procesorem Intel:

sw-machine.gif (3726 bytes)

Jazyky nižší úrovně

Tímto termínem nazýváme jazyky, které svou srozumitelností a snadností programování stojí sice nad čistým strojovým kódem, ale zůstávají vázány na konkrétní počítač. Programy napsané v nich nejsou přenositelné na počítač jiný.

Historicky se vyvinuly tři typy takových jazyků:

Jazyky relativních adres

Program je stejně jako ve strojovém kódu rozložen až na jednotlivé strojové instrukce, ale adresy v nich jsou počítány relativně vůči určité základní (bázové) adrese. Program je proto nezávislý na konkrétním umístění v paměti, relativní adresy se před spuštěním musí transformovat na adresy reálné.

Jazyky symbolických adres - assemblery

U těchto jazyků jsou adresy nahrazeny názvy, každému názvu odpovídá určitá konkrétní adresa, kterou obvykle přiřazuje překladač a ne programátor. Téměř vždy se pro zvýšení srozumitelnosti v symbolickém tvaru zapisují i kódy operací, například instrukce uložení do paměti (store) se zapíše zkratkou ST.

Assemblery jsou daleko nejrozšířenější (v současné době prakticky jediné používané) jazyky nižší úrovně.

Příklad - fragment programu v assembleru pro PC

ExcessOfMemory label near
   mov bx, di
   add bx, dx
   mov word ptr _heapbase@ + 2, bx
   mov word ptr _brklvl@ + 2, bx
   mov ax, _psp@
   sub bx, ax ; BX = Number of paragraphs to keep
   mov es, ax ; ES = Program Segment Prefix address
   mov ah, 04Ah
   push di ; preserve DI
   int 021h ; this call clobbers SI,DI,BP !!!!!!
   pop di ; restore DI

Autokódy

Byly to jazyky na půl cesty mezi jazyky nižší a vyšší úrovně. Byly sice vázány na určitý typ počítače, ale zbavily se již pravidla: jeden příkaz jazyka = jedna strojová instrukce. V současné době se prakticky nepoužívají, neboť byly nahrazeny jazyky vyšší úrovně.

Malé panoptikum jazyků vyšší úrovně

(Jazyky, které zásadně - kladně či záporně - ovlivnily další vývoj)

Fortran

1. verze 1956 (FORmula TRANslator) - firma IBM. Brzy se z něj stal první jazyk nezávislý na konkrétním počítači.

Základní charakteristiky:

  • Určen pro vědeckotechnické výpočty
  • Tvar zápisu odvozen z formátu děrného štítku (odstraněno teprve koncem 80. let)
  • Procedury a funkce (nerekurzivní)
  • Ve starších verzích absence většiny obvyklých řídicích struktur, velmi omezené možnosti práce s texty
  • Velmi efektivní přeložený kód - pro vědeckotechnické výpočty prakticky bez konkurence
  • Mnoho vestavěných funkcí
  • Zaměřen na separátní překlad jednotlivých modulů - snadná tvorba knihoven
  • Existují mimořádně rozsáhlé knihovny programů

Vývojové etapy:

  • Fortran II
  • Fortran IV, základ pro oficiální normu ANSI Fortran (1966)
  • Fortran 77 (1977) - pozdě, ale přece zavedl strukturu IF - THEN - ELSE - ENDIF, proměnné typu CHARACTER, příkazy pro práci se soubory aj.
  • Fortran 90 (1990) - mnoho dalších rozšíření (práce s polem jako celkem, prvky OOP), celková modernizace jazyka při zachování zpětné kompatibility
  • Fortran 95

Příklad programu (Fortran 77):

      CHARACTER RECORD*9,VERSE*9,PEN6*6,PEN(6)
      EQUIVALENCE (PEN6,PEN)
      VERSE=CHAR(0)//'GR 90.06'
      OPEN(8,FILE=' ',FORM='BINARY')
      READ(8,END=200) RECORD
      IF(RECORD.NE.VERSE) THEN
      PRINT *,'****ERROR: MISSING "PLOTS" OR INVALID FILE'
      GOTO 300
      END IF
      XMIN= 1.0E9
      YMIN= 1.0E9
      XMAX=-1.0E9
      YMAX=-1.0E9
      DO 110 I=1,6
110     PEN(I)=' '
      CALL SIZSUB(XMIN,YMIN,XMAX,YMAX,PEN,'H',NUM)
      PRINT 1000,NUM,XMIN,XMAX,MIN(32.00/(XMAX-XMIN),
     * 28.70/(YMAX-YMIN)),
     * YMIN,YMAX,MIN(22.00/(XMAX-XMIN),17.00/(YMAX-YMIN))
1000  FORMAT(12X,'**** GRAPH LIMITS ****'/
     * ' Number of graphs in the metafile:',i3/
     * ' XMIN =',F9.3,' CM',10X,'XMAX =',F9.3,' CM',10X,
     * 'LP_FACTOR =',F10.5/' YMIN =',F9.3,' CM',10X,
     * 'YMAX =',F9.3,' CM',10X,'COLFACTOR =',F10.5)
      IF(PEN6.NE.' ') PRINT 1001,PEN
1001  FORMAT(/' 1 2 3 4 5 6 7'/
     *' PENS USED : *',6A3)
      GOTO 400
200   PRINT '(''****ERROR: EMPTY GRAPHIC FILE'')'
300   PRINT '(''****SIZE_GR ABORTED'')'
400   END

Cobol

Základní charakteristiky:

  • Určen pro hromadné zpracování dat
  • Tvar zápisu odvozen z formátu děrného štítku
  • Procedurální část programu vypadá převážně jako psaná v běžné angličtině
  • Velmi "ukecaný"
  • První jazyk, který zavedl datové struktury
  • Program sestává ze 4 částí: IDENTIFICATION DIVISION (údaje o programu a operačním systému), ENVIRONMENT DIVISION (používané soubory; údaje o počítači a operačním systému), DATA DIVISION (popis dat), PROCEDURE DIVISION (algoritmus zpracování)

Vývojové etapy:

Mnoho postupně rozvíjených verzí (Cobol 60, 61, 65 a další). V novějších verzích zabudováno třídění, zjednodušená tvorba sestav, přístup k databázím aj.

 

Příklad programu:

Tvorba čtvrtletního výkazu:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TABLES.
       AUTHOR. JOE DOE.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SOURCE-COMPUTER. ABC-480.
       OBJECT-COMPUTER. ABC-480.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INPUT-FILE ASSIGN TO CARD-READER.
           SELECT OUTPUT-FILE ASSIGN TO PRINTER.
       DATA DIVISION.
       FILE SECTION.
       FD  INPUT-FILE LABEL RECORDS OMITTED
                      DATA RECORD IS INPUT-RECORD.
       01  INPUT-RECORD.
           02 QUARTER  PIC 9.
           02 REGION   PIC 9.
           02 AMOUNT   PIC 999.
           02 FILLER   PIC X(75).
       FD  OUTPUT-FILE LABEL RECORDS OMITTED
                      DATA RECORD IS OUTPUT-RECORD.
       01  OUTPUT-RECORD PIC X(132).
       WORKING-STORAGE-SECTION.
       77  END-OF-DATA PIC XXX.
       01  SALES-TABLE.
           02 QUARTER-DATA OCCURS 4 TIMES.
              03 SALES OCCURS 4 TIMES PICTURE 9(5).
...

       PROCEDURE DIVISION.
       MAIN-ROUTINE.
           OPEN INPUT INPUT-FILE OUTPUT OUTPUT-FILE.
           MOVE 'NO' TO END-OF-DATA.
           INITIALIZE SALES-TABLE.
           PERFORM READ-DATA.
           PERFORM READ-ACCUMULATE UNTIL END-OF-DATA = 'YES'.
           PERFORM HEADERS.
           PERFORM PRINT-TABLE VARYING QUARTER FROM 1 BY 1
                   UNTIL QUARTER IS GRATER THAN 4.
           CLOSE INPUT-FILE, OUTPUT-FILE.
           STOP RUN.
       READ-DATA.
           READ INPUT FILE AT END MOVE 'YES' TO END-OF-DATA.
           READ-ACCUMULATE.
           ADD AMOUNT TO SALES (QUARTER, REGION)
           PERFORM READ-DATA.
...

Algol

Základní charakteristiky:

  • Jazyk algoritmický (nikoli programovací)
  • Zavedl některé netradiční znaky (operátor násobení ×, celočíselného dělení ÷, umocňování wpe23.jpg (732 bytes), negace ¬, dekadický exponent 10
  • Klíčová slova se podtrhují nebo tisknou polotučně
  • Mnoho revolučních prvků (v dnešních jazycích už považovaných za samozřejmé): podmíněné výrazy a příkazy, příkaz for, přepínač, rekurzivní procedury, volání parametrů jménem nebo hodnotou ...)
  • Starší verze neřešily vstup a výstup
  • Minimální možnosti práce s texty ve starších verzích
  • Přesný formální popis syntaxe (Backusova normální forma)

Vývojové etapy:

Algol 58

Význam pouze jako předstupeň Algolu 60

Algol 60

Snad nejvýznamnější jazyk všech dob, ovlivnil na desítiletí ostatní jazyky

Algol 68

Podstatně zdokonalený oproti Algolu 60, už je spíše jazykem programovacím. Zavedl "krátké" a "dlouhé" datové typy (int, short int, real, long real, long long real ...), ukazatele, tj. odkazy či reference na proměnné(ref int ...), l-hodnoty, paralelní větve programu, struktury a uniony, uživatelem deklarované operátory aj.

Přesná formální definice syntaxe a částečně i sémantiky.

 

Příklad programu (Algol 60):

Násobení úsporně uložené symetrické matice vektorem

procedure mulsym(A,b,n);
     value n; integer n; real array A,b;
comment mulsym násobí matici invertovanou procedurou symin
        na symetrickou matici A řádu n vektorem b.
        Výsledek přepíše prvních n prvků pole A;
begin integer i,k,l,p;
     l:=n;
     for i:=1 step 1 until n do
        begin A[i]:=0; p:=l+i;
           for k:=i step -1 until 1 do
              begin
                 A[i]:=A[i]+A[p]×b[k];
                 p:=p-n-1+k;
              end;
           if i<n then
              for k:=i+1 step 1 until n do
                 A[i]:=A[i]+A[l+k]×b[k];
              l:=l+n-i;
        end
end multsym;
 

Basic

Základní charakteristiky:

  • Původně vyvinula firma IBM jako jazyk pro souběžný přístup mnoha uživatelů z terminálů k sálovému počítači
  • Později nejvýznamnější jazyk na nejmenších počítačích (na stolních kalkulátorech a domácích počítačích často jediný dostupný jazyk, integrovaný přímo do hardwaru)

Vývojové etapy:

Původní verze velmi primitivní - např. názvy proměnných pouze jedno písmeno nebo jedno písmeno a jedna číslice, pouze 2 datové typy: číslo (reálné) a řetězec. Každý příkaz začíná pořadovým číslem, které lze použít jako návěští. První slovo příkazu charakterizuje, co příkaz dělá.

Později podstatně rozšířené dialekty (např. Visual Basic).

 

Příklad programu (základní verze Basicu):

10  REM PROLOZENI BODU PRIMKOU Y=A+BX
20  REM METODOU NEJMENSICH CTVERCU
30  PRINT "KOLIK BODU BUDE ZADANO (3-100)?"
40  INPUT N
45  IF N<3 THEN 30
46  IF N>100 THEN 30
50  REM POCATECNI STAV PROMENNYCH
52  LET P1=0
54  LET P2=0
56  LET P3=0
58  LET P4=0
60  REM CTENI SOURADNIC A SUMACE
70  FOR I=1 TO N
80    PRINT I;". DVOJICE X,Y: ";
90    INPUT X,Y
100   LET P1=P1+X
110   LET P2=P2+Y
120   LET P3=P3+X*Y
130   LET P4=P4+X^2
140 NEXT I
150 REM VYPOCET REGRESNICH KOEFICIENTU A, B
160 LET B=(P3-P1*P2/N)/(P4-P1^2/N)
170 LET A=(P2-P1*B)/N
180 IF(B<0 THEN 186
182   LET Z$="-"
184   GOTO 190
186 LET Z$="+"
190 PRINT
200 PRINT "ROVNICE PRIMKY JE   Y="A;Z$;ABS(B);"X"
210 PRINT
 

PL/I

Základní charakteristiky:

  • Univerzální programovací jazyk
  • Vznikl ze snahy o vylepšení Fortranu
  • Deklarované cíle (nepodařilo se je zcela splnit):
    1. Co je intuitivně jasné a jednoznačné, není zakázáno
    2. Pokud je to možné, neuchylovat se ke strojovému kódu
    3. Strojově nezávislý (přesto je na něm patrno, že vznikl pro IBM/360)
    4. Modularita
    5. Péče o začátečníky
    6. Programovací, a ne algoritmický jazyk
  • Velmi mnoho vymožeností, což vedlo k nepřehledné syntaxi i sémantice:
    E. Dijkstra: Používat PL/I musí být jako pilotovat letadlo pomocí 7000 tlačítek, přepínačů a pák v kokpitu. Absolutně nechápu, jak bychom mohli intelektuálně zvládnout naše rozrůstající se programy, když už sám programovací jazyk - náš hlavní nástroj! - se pro svou baroknost vymkl z naší intelektuální kontroly.

Vývojové etapy:

  • Původně vyvíjen organizací SHARE (sdružení uživatelů IBM) jako vylepšení Fortranu "SHARE Fortran"
  • Vzdálil se od Fortranu tak, že byl nazván NPL (New Programming Language). Pro konflikt zkratky s National Physical Laboratory přejmenován na PL/I
  • Postupně 3 verze návrhu
  • Normalizován ANSI (kontroversní forma normy)

Příklad podprogramu:

DECLARE ABS GENERIC
   (ABS1 ENTRY (FIXED),
    ABS2 ENTRY (FLOAT REAL),
    ABS3 ENTRY (COMPLEX));
ABS1: ABS2: PROCEDURE (X); DECLARE Y;
   Y=X;
   IF Y LT 0 THEN Y=-Y; RETURN(Y);
ABS3: ENTRY (X);
   RETURN (SQRT(REAL(X)**2 + IMAG(X)**2));
END ABS;

    

APL

Základní charakteristiky:

  • Univerzální programovací jazyk
  • Velmi "hutný" zápis (až 10krát stručnější než v běžných jazycích)
  • Speciální sortiment znaků (nutnost používat zvláštní terminál či font nebo nahrazovat speciální znaky náhradními kombinacemi znaků ASCII)
  • Program na první pohled (nezasvěcenému) zcela nesrozumitelný
  • Velmi mnoho operátorů, většina jako unární i binární (obvykle s různými významy: ÷x znamená 1/x, x÷y znamená x/y; *x znamená ex, x*y znamená xy)
  • Operátory mají stejnou prioritu a provádějí se odzadu, pořadí však lze změnit závorkami
  • Bohatá podpora práce s vektory a maticemi (např. Awpe2F.jpg (795 bytes)B znamená vynásob matici A inverzí matice B)

Vývojové etapy:

  • První verze Iverson 1962
  • Implementace v 60. letech na IBM 360/370, CDC, UNIVAC, ruském BESM aj.
  • Používá se dodnes, překladače a speciální fonty jsou na Webu

Příklad programu:

Deklarace funkce SUM, která spočítá aritmetický průměr kladných prvků zadaného pole:

apl.gif

 

LISP

Základní charakteristiky:

  • Jazyk pro zpracování seznamů. Jeden z hlavních jazyků v oblasti umělé inteligence.
  • Seznam má tvar (hlava ocas); hlava i ocas jsou buď atomy nebo opět seznamy
  • Je-li ocas seznam, lze použít zkrácený zápis: místo (A (B (C D))) píšeme (A B C D)
  • Program a data jsou spojeny do jediného souboru
  • Jazyk má řadu vestavěných funkcí. Nejdůležitější: (CAR SEZNAM) extrahuje hlavu seznamu, (CDR SEZNAM) jeho ocas. Lze kombinovat: např. (CADR SEZNAM) představuje (CAR(CDR   SEZNAM)). CONS(A B) vytvoří seznam, jehož hlavou je A a ocasem B.
  • LISP je mimořádně nepřehledný, je proto extrémně důležité strukturu programu zvýrazňovat vhodnou grafickou úpravou.

Příklad programu:

Program, který vypíše seznam v přehledném tvaru:

(PRETTYPRINT (LAMBDA (SYVY)
  (PROG (SLOUPEC)
    (RETURN (PEKNYTISK SYVY 0 T))
  )
))
(PEKNYTISK (LAMBDA (SYVY ZACSL RADKU)
  (PROG ARGZAC)
    (COND (RADKU (PROGN(TERPRI)
                 (SETQ SLOUPEC 0))))
DALE (COND ((LESSP  SLOUPEC ZACSL)
              (PROGN
                (PRIN1 SP)
                (SETQ SLOUPEC (ADD1 SLOUPEC))
                (DO DALE))))
  (COND ((ATOM SYVY)
            (PROGN
              (PRIN1 SP)
              (SETQ SLOUPEC (PLUS SLOUPEC 5))))
        (T (PROGN 
             (PRIN1 LPAR)
             (SETQ SLOUPEC (ADD1 SLOUPEC))
             (PEKNYTISK (CAR SYVY) SLOUPEC NIL)
             (COND ((CDR SYVY)
               (PROGN
               (PRIN1 SP)
               (SETQ SLOUPEC (ADD1 SLOUPEC))
               (SETQ ARGZAC SLOUPCE)
               (PEKNYTISK (CADR SYVY)
               ARGZAC
               NIL)
               (MAPCAR (CDDR SYVY)
                 (FUNCTION (LAMBDA (PRVEK
                   (PEKNYTISK PRVEK
                     ARGZAC
                     T))))
               )))
             (PRIN1 RPAR)
             (SETQ SLOUPEC (ADD1 SLOUPEC))
        )))
        (RETURN SYVY)
  )
))
 

Ada

Základní charakteristiky:

  • Univerzální jazyk pro všechny typy aplikací včetně řízení v reálném čase
  • Zavedl nebo převzal některé neobvyklé moderní prvky (zpracování výjimek, generické funkce)
  • V resortu ministerstva obrany USA prosazen jako jediný jazyk pro vývoj nových systémů
  • Velmi dokonalý, ale málo rozšířený

Příklad programu:

restricted(MATH_LIB, TEXT_IO)
procedure QUADRATIC_EQUATION is
   use TEXT_IO;
   A, B, C, D: FLOAT;
begin
   GET(A); GET(B); GET(C);
   D:=B**2-4.0*A*C;
   if D<0.0 then
      PUT("COMPLEX ROOTS");
   else
      declare
         use MATH_LIB; -- tam je funkce SQRT
         begin
            PUT("REAL ROOTS: ");
            PUT(B-SQRT(D))/(2.0*A));
            PUT(B+SQRT(D))/(2.0*A));
            PUT(NEWLINE);
         end;
   end if;
end QUADRATIC_EQUATION;
 

Simula

Základní charakteristiky:

  • Odvozen z Algolu 60
  • Doplněn o prostředky simulace diskrétních systémů
  • Zavedl do programování pojem třídy (class) - již v 60. letech (!) - Simula67

Pascal

Základní charakteristiky:

  • Snadný k naučení
  • Silná typová kontrola, většina chyb se zachytí už při kompilaci
  • Zvlášť vhodný pro výuku, méně pro praktické programování
  • Program se musí kompilovat vcelku - žádná modularita
  • Spíše jazyk algoritmický než programovací (např. absence "krátkých" a "dlouhých" typů)
  • Vyjadřovací možnosti tak malé, že většina implementací jazyk rozšiřuje (neportabilně, např. unit v překladačích fy Borland)

Vývojové etapy:

Některé nedostatky byly odstraněny v revidované verzi jazyka (např. zavedení konformantních polí). Novější překladače jazyk podstatně rozšířily - za cenu vážného omezení přenositelnosti programů.

C

Základní charakteristiky:

  • Spojuje prvky jazyků vysoké a nízké úrovně
  • Velmi bohatá nabídka operátorů
  • Univerzální, zvlášť vhodný pro systémové programování
  • Těsná návaznost na operační. systém, zpočátku silně svázán s Unixem
  • Snadno se v něm udělá chyba, která neporušuje syntax a není proto zachycena překladačem
  • Velmi efektivní generovaný kód

Vývojové etapy:

  • Kernighan-Ritchie (K-R) C
  • ANSI C (postupně několik verzí)
  • ISO/IEC C (C99)

Následovníci:

  • C++ (prakticky nový jazyk, avšak vychází z C, objektově orientovaný)
  • Java
  • C#

Předchozí Předchozí přednáška Další Další přednáška Hlavní stránka Hlavní stránka