5. Jezici za programiranje
Kompjutor može uraditi samo ono za što mu je netko dao instrukcije (program) - niz logičkih i aritmetickih operacija napisanih jezikom kompjutora. Kompjutor takve instrukcije izvršava brzo i gotovo nepogrešivo, upravo onako kako su zadane.
Kompjutor može izvršiti samo mali broj veoma jednostavnih operacija. Na primjer, oduzimanje, množenje i dijeljenje svodi na operacije zbrajanja i pomi-canja znamenki. Kompjutor "razumije" i može izvršiti samo instrukcije strojnog jezika.
5.1. Generacije jezika za programiranje
S razvojem kompjutora usavršavao se i jezik za komuniciranje (programiranje), pa razlikujemo četiri generacije:
1. strojni jezici,
2. simbolički (asemblerski) jezici,
3. jezici za programiranje visoke razine,
4. jezici četvrte generacije (jezici krajnjih korisnika).
Generacije jezika za programiranje ne treba poistovjećivati s generacijama kompjutora. Na primjer, danas su u upotrebi kompjutori četvrte generacije, na kojima nalazimo sve četiri generacije jezika za programiranje.
Osim dane podjele jezika za programiranje, postoje i druge. Prema jednoj od njih, na primjer, svi jezici za programiranje dijele se na:
1. proceduralne,
2. neproceduralne.
No, prije nego što detaljnije opišemo generacije jezika, neka nam sljedeći problem i dani postupak - rješenje u "pseudojeziku" - posluži kao primjer koji će dovoljno zorno odražavati temeljne karakteristike pojedinih generacija jezika.
Problem
Izračunati zbroj neparnih brojeva komponenti cjelobrojnog polja duljine N.
Rješenje
Dajemo rješenje (algoritam) u notaciji nekad popularnog "dijagrama toka".
Srce algoritma jest petlja koja se izvršava N puta. Pri svakom prolasku kroz petlju ispituje se vrijednost komponente polja s indeksom i; ako je broj neparan, pribraja se ukupnom zbroju. Pogledajmo kako bi se algoritam izvršavao kad bi duljina polja bila jednaka 4. Simbol ":=" ima značenje pridruživanja vrijednosti izraza s desne strane varijabli s lijeve strane. Broj u uglatoj zagradi jest indeks polja B (identificira komponentu polja B).
5.1.1. Strojni jezik
Pisanje programa za prve kompjutore obavljalo se isključivo strojnim jezikom. To je bilo dosta mukotrpno jer je strojni jezik niz nula i jedinica određene konačne duljine. Trebalo je pamtiti što koji od tih nizova znači. Na primjer, rješenje postavljenog problema u strojnom jeziku, napisanom za mikroprocesor Motorola 68000 jest:
00100100 | 01011111 | ||||
00100010 | 01011111 | ||||
00110010 | 01000000 | ||||
01001110 | 11111010 | 00000000 | 00000110 | ||
00001000 | 00101001 | 00000000 | 00000000 | 00000000 | 00000001 |
01100111 | 00000010 | ||||
11010100 | 01010001 | ||||
01010100 | 01001001 | ||||
01010001 | 11001001 | 11111111 | 11110010 | ||
00111110 | 10000010 | ||||
01001110 | 11010010 |
Pisanje programa strojnim jezikom ne samo da je bilo otežano nerazumljivim kodovima pojedinih instrukcija (je li dani program napisan bez greške?!), već nije postojao ni jedinstveni strojni jezik, pa onaj tko je poznavao jezik jednog stroja nije mogao tim jezikom programirati na drugome.
5. 1.2. Simbolički (asemblerski) jezik
Prvi korak ka tzv. jezicima više razine bilo je uvođenje simboličkog (asemblerskog ili mnemoničkog) jezika. U torn jeziku programer se koristi mnemoničkim imenima i za operacije i za operande. Tako se simboličkim jezikom mikroprocesora Motorola 68000 može napisati:
SUMODDS MOVE.L (A7)+,A2
umjesto 00100100 01011111 u strojnom jeziku.
Program napisan simboličkim jezikom lakši je za pisanje i razumijevanje od programa pisanog strojnim jezikom. Prije svega, numerički kodovi za operacije i adrese zamijenjeni su prihvatljivim simboličkim kodovima koji već svojim nazivom podsjećaju korisnika na svoju namjenu. Pogledajmo ustrojenje danog algoritma na asemblerskom jeziku, takoder za mikroprocesor Motorola 68000:
SUMMODDS | MOVE.L | (A7)+,A2 |
MOVE.L | (A7)+,A1 | |
MOVE.W | (A7)+,D2 | |
CLR.W | D2 | |
JMP | COUNT | |
LOOP | BTST | 0,1(A1) |
BEQ.S | NEXT | |
ADD.W | (A1),D2 | |
NEXT | ADDQ.W | #2,A1 |
COUNT | DBF | D1,LOOP |
MOVE.W | D2,-(A7) | |
JMP | (A2) |
5.1.3. Jezici visoke razine
Uvodenjem asemblerskih jezika znatno je olakšano pisanje i razumijevanje programa. Ali je još ostalo odredenih teškoća. Naime, programer je morao detaljno poznavati način na koji određeni kompjutor izvršava operacije. Također je morao, računanjem napamet prevoditi kompleksne operacije i strukture podataka u niz operacija niske razine, koje rabe samo primitivne tipove podataka strojnog jezika. Ili, morao je paziti kako su i gdje podaci postavljeni u radnoj memoriji kompjutora.
Radi izbjegavanja takvih i sličnih problema, razvijeni su jezici visoke razine. U osnovi, jezici visoke razine omogućuju programeru da piše algoritme u prirod-nijoj notaciji u kojoj se ne treba baviti mnogim detaljima vezanim za neki specifični kompjutor. Na primjer, neusporedivo je ugodnije pisati A=B+C nego niz asemblerskih instrukcija.
Danas je u široj upotrebi dvadesetak jezika visoke razine. To su Ada, ALGOL 60 i 68, APL, BASIC, C, COBOL, FORTRAN, ICON, LISP, Modula-2, Pascal, PL/1, PROLOG, RPG, SNOBOL itd. Razlikuju se po svom stupnju bliskosti matematičkome ili prirodnim jezicima, s jedne strane, i strojnom jeziku, s druge strane. Također se razlikuju po vrsti problema čijem su rješavanju najbolje prilagođeni. Suv-remeni jezici za programiranje visoke razine sličnih su osnovnih mogućnosti; ipak razlikujemo nekoliko skupina jezika, ovisno o vrsti problema za čije su rješavanje prilagođeni. To su:
. jezici za učenje programiranja (LOGO, BASIC, Pascal)
. jezici za rješavanje znanstvenih problema
. algoritamski algebarski jezici (ALGOL, APL, BASIC, FORTRAN, Pascal)
. jezici za obradu podataka (COBOL, PL/l)
. jezici za sistemske programe (Ada, C, Modula-2)
. jezici za sisteme umjetne inteligencije (LISP, PROLOG)
. jezici za obradu teksta (ICON, SNOBOL, TEX), itd.
Jezici za programiranje visoke razine podvrgnuti su standardima s propisanom sintaksom (pravilima pisanja) i semantikom (značenjem), čime je uvelike pos-tignuta neovisnost o karakteristikama kompjutora i operativnog sustava na kojemu su instalirani.
Od velikog broja jezika visoke razine izabrali smo BASIC, Pascal, COBOL, APL i LISP da bi smo na primjeru programa za postavljanje našeg algoritma predočili koliko su bliski i istodobno toliko različiti.
5.1.4. Jezici četvrte generacije
Bez obzira na to što je svaka nova generacija jezika bila bliža korisniku, još je uvijek programiranje s tim jezicima posebna disciplina. Tek je s pojavom jezika četvrte generacije stvorena alternativa profesionalnom programiranju. Karak-teristika tih jezika je potpuna prilagođenost krajnjim korisnicima - najčešće neprogramerima, a primjenjuju ih veoma uspješno i informatičari (programeri i analitičari sustava) radi ubrzanja procesa programiranja.
Ne postoje opći standardi o sintaksi i semantici jezika četvrte generacije, osim u jednom dijelu - za upitne jezike za baze podataka. Ovisno o njihovoj namjeni, možemo ih razvrstati u nekoliko kategorija:
. upitni jezici za bazu podataka (Query-By-Example, Intellect,
Quick Query, Easytrieve, Asi, SQL, GIS, Mark IV, Datatrieve i dr)
. generatori izvještaja (NOMAD, ADRS II, GIS, RPG III; MARK
IV/Rep.)
. jezici za podršku odlučivanju (VisiCalc, Multiplan, System W Ex-
press)
. generatori programa (Mapper, RAMISII, Fokus, Line, ADF, ADS,
DMS)
. jezici za programiranje vrlo visoke razine (AME, NOMAD, FOKUS,
MANTIS)
. jezici za crtanje
Neki od tih jezika su višenamjenski (ali ne i općenamjenski), pa se mogu svrstati u nekoliko kategorija. Obično rade s bazom podataka, pa krajnjim korisnicima omogućuju definiranje i kreiranje vlastite baze podataka i pristup tim podacima.
Često se neki noviji jezici za programiranje visoke razine pogrešno svrstavaju u jezike četvrte generacije, na primjer, APL i Prolog. Točno je da dijelovi nekih novijih jezika pripadaju klasi jezika četvrte generacije, ali sam jezik pripada trećoj generaciji.
5.1.5. Proceduralni i neproceduralni jezici
Proceduralni jezik specificira kako ce nesto biti izvršeno, a neproceduralni što ce biti izvršeno, ne ulazeći u detalje kako.
Strojni jezik je 100% proceduralan. Za druge se jezike moze govoriti o udjelu proceduralnosti ili neproceduralnosti. Jezici četvrte generacije su neprocedu-ralni, ili su to u većem postotku. Najčešće je proceduralnost jezika obrnuto proporcionalna njegovoj razumljivosti za korisnika, kao što je pokazano na sljedećem crtežu.
Suvremeni jezici treće i četvrte generacije kombinacija su proceduralnih i neproceduralnih komponenti. To je i poželjno jer se neproceduralnim kom-ponentama ubrzava programiranje i pojednostavnjuje upotreba jezika, a pro-ceduralnim se komponentama proširuje obujam primjene jezika u rješavanju problema. I jezici budućnosti takoder će sadržavati proceduralne i neproce-duralne komponente, s naglaskom na vizualnoj interakciji.
Pitanja i zadaci
1. Nabroj generacije jezika za programiranje.
2. Kojoj generaciji jezika za programiranje pripada BASIC?
3. Navedi temeljne karakteristike jezika četvrte generacije.
4. Što su proceduralni, a što neproceduralni jezici za programiranje?
Evolucija jezika za programiranje, od asemblerskih do jezika visoke razine, uvela je potrebu za posebnim programima - prevodiocima. Kako kompjutor neposredno izvršava instrukcije u svom strojnom jeziku, nužno je programe prevesti u taj jezik.
5.2.1. Vrste prevodilaca
Prevodilac je, dakle, program koji instrukcije korisnika prevodi iz izvornog jezika u program izražen ciljnim (objektnim) jezikom. Ako izvorni jezik pripada klasi jezika visoke razine, kao sto je to naprimjer Pascal, a ciljni je asemblerski ili strojni jezik, prevodilac se naziva kompilatorom.
Izvršavanje programa pisanog jezikom visoke razine u osnovi je dvostepeni proces. Izvorni se program najprije kompilira, tj. prevede u objektni program, potonji se zatim smjesti u memoriju i izvršava. Budući da postoji nekoliko vrsta izvornih i ciljnih jezika, postoji i nekoliko vrsta prevodilaca.
Asembler je prevodilac koji prevodi program pisan asemblerskim jezikom na strojni jezik.
Neki prevodioci transformiraju program pisan izvornim jezikom u pojedno-stavljeni jezik, nazvan međukodom, koji se može direktno izvršiti pomoću programa zvanog interpretator.
Termin predprocesor katkad se upotrebljava za prevodioce koji prihvaćaju programe pisane jednim od jezika visoke razine i prevode ga u ekvivalentni program na drugom jeziku visoke razine.
5.2.2. Faze prevođenja
Prevodilac na ulazu prihvaća izvorni program i stvara semantički ekvivalentan niz naredbi ili instrukcija u ciljnom jeziku. Takav proces previše je kompleksan, i s logičkog i s implementacijskog aspekta, da bi se mogao razmatrati u jednom koraku. Stoga je mnogo prikladnije podijeliti ga na niz procesa nazvanih faze, i promatrati ih odvojeno. Faze prevodenja jesu:
. leksička analiza
. sintaktička analiza
. generiranje međukoda
. optimiziranje koda
. generiranje koda
Leksička analiza je prva faza prevođenja. Njezin zadatak je čitanje izvornog programa, znak po znak, i grupiranje nizova znakova u šire leksičke strukture -riječi (simbole). Na primjer, ako je na ulazu niz znakova
IF(K.GT.MAX)MAX=K
u leksičkoj analizi Fortrana taj se niz znakova grupira u niz simbola:
IF ( K .GT. MAX ) MAX = K
Sintaktička analiza je druga faza prevođenja. To je proces kojim se utvrđuje može li dani niz simbola (izlaz iz leksičke analize) tvoriti dio programa napisanog izvornim jezikom. Ako je moguće, simboli će na izlazu iz sintaktičke analize biti grupirani u šire sintaktičke strukture. Često će to biti predočeno u obliku stabla.
Generator međukoda koristi se strukturom dobivenom na izlazu sintaktičke analize da bi kreirao niz primitivnih instrukcija, na nekom međujeziku -apstraktnom jeziku sličnom asemblerskom.
Optimiziranje koda je faza u kojoj se međukod "popravlja". Time se dobiva konačni objektni kod koji radi brže i zauzima manje memorijskog prostora.
U zavrsnoj fazi, generiranju koda, proizvodi se objektni kod, uz određivanje memorijskih lokacija za podatke, odvajanje koda za pristup svakom podatku i biranje registara u kojima će biti obavljena pojedina izračunavanja.
Tablica simbola dio je prevodioca u kojemu se vode imena upotrijebljena u programu, sa svim potrebnim dodatnim informacijama, a dostupna je svim fazama prevođenja.
U bilo kojoj fazi prevođenja može se otkriti greška. Sve greške pamte se na jednome mjestu i dojavljuju nakon završenog prevođenja. Otkrivanjem prve greške prekida se daljnje generiranje međukoda. Sa stajališta programera po-trebno je razlikovati leksičke i sintaktičke greške.
Leksičke greške nastaju kršenjem leksičkih pravila, na primjer, pisanjem znaka koji ne pripada alfabetu jezika. Sintaktičke greške nastaju kršenjem sintaktičkih pravila jezika.
Pitanja i zadaci
1. Što je prevodilac?
2. Koje vrste prevodilaca poznaješ?
3. Što su faze prevođenja?
4. Dana je linija programa u GW-Basic-u:
222 IF X > =0 AND X < 10 THEN Y=SQR(X)
Napiši niz simbola dobiven na izlazu iz leksičke analize.
Već smo nekoliko puta upotrijebili termin jezik za programiranje a da nismo definirali što on znači.
Jezik za programiranje može se definirati kao notacijska tehnika (pismo) kojom se na kompaktan, nedvosmislen i konačan način specificira niz operacija koje će se obaviti nad nekim objektima - podacima. Određeni niz tih operacija napisan nekim jezikom naziva se program.
5.3.1. Hijerarhijska struktura jezika
I operacije i podaci u većini jezika za programiranje općenito se mogu grupirati hijerarhijski, što je prikazano na crtežu.
Korištenjem takve hijerarhijske strukture znatno se olakšava i učenje jezika. Naime, iako su jezici za programiranje mnogo jednostavniji od prirodnih, bilo bi ih teško učiti bez određene sistematizacije.
Sagledavajući dijelove jezika postupno, putem hijerarhijske strukture i grupe naredbi, jezik se može naučiti mnogo brže i potpunije.
U daljnjem detaljnijem opisu elemenata programa poći ćemo redom, od onih koji su na najnižoj razini prema vrhu.
5.3.2. Tipovi i strukture podataka
Podaci se na razini strojnog jezika predočuju kao nizovi znakova binarnog alfabeta. U jezicima za programiranje visoke razine podaci ne pripadaju samo jednom skupu vrijednosti niti su s različitim skupovima vrijednosti dopuštene sve operacije. Zato se u tim jezicima uvodi pojam tipa podataka.
Tip podataka je skup vrijednosti koje imaju neke zajedničke karakteristike. Najznačajnija od njih jest skup operacija definiranih nad vrijednostima tog tipa.
U programiranju općenito, a posebno u jezicima za programiranje visoke razine, pojam tipa osobito je važan. Tipom se određuje iz kojeg se skupa vrijednosti varijablama u programu mogu dodjeljivati vrijednosti i koje su operacije dopuštene. U većini jezika za programiranje, kao sto je slučaj u Fortranu i Pascalu, zahtijeva se eksplicitno deklariranje varijabli po tipu prije njihove prve upotrebe u programu.
Jedan od osnovnih razloga za uvođenje tipova bio je omogućavanje kontrole korektnosti upotrebe vrijednosti različitog tipa i operacija s njima u izrazima programa. Jednako važan razlog u implementaciji jezika jest to što različiti tipovi vrijednosti zahtijevaju različit broj ćelija za memoriranje i različit prikaz u memoriji.
U većini jezika za programiranje susreću se sljedeći standardni tipovi podataka:
. numerički (cjelobrojni i realni)
. logički
. znakovni
Ta četiri tipa podataka nazivaju se još primitivnim tipovima zato što u jezicima za programiranje visoke razine čine nedjeljive cjeline i imaju izravan prikaz u memoriji kompjutora.
Cjelobrojni tip (integer) podskup je skupa cijelih brojeva, odnosno skup cjelobrojnih vrijednosti iz intervala
(-2 n - 1 ,2 n - 1 -1)
gdje je n duljina memorijske ćelije (u bitovima) za pamćenje cjelobrojnih vrijednosti, uključivši predznak.
Koji je to točno podskup, ovisi o realizaciji jezika za programiranje i verziji kompjutora. Nad tim su tipom u većini jezika za programiranje definirane standardne operacije cjelobrojne aritmetike: zbrajanje, oduzimanje, množenje, cjelobrojno dijeljenje i potenciranje. Pri izvršavanju tih operacija vrijede svi zakoni aritmetike, uz uvjet da nisu prekoračene najveće vrijednosti cijelog broja
(što je određeno duljinom pridružene memorijske ćelije).
Realni tip (real) podskup je realnih brojeva, odnosno skup brojeva oblika
O.mx2 e
gdje je m mantisa, a e eksponent. Mantisa i eksponent su oblika
Pritom je n duljina binarne mantise, a k duljina binarnog eksponenta, ovisno o realizaciji jezika i vrste kompjutora.
Nad realnim tipom definirane su standardne operacije realne aritmetike (zbrajanje, oduzimanje, množenje, dijeljenje i potenciranje).
Zbog ograničene i konačne duljine memorijskih ćelija za pamćenje realnih vrijednosti u memoriji kompjutora, praktično je nemoguće prikazati i u me-moriji upamtiti proizvoljnu realnu vrijednost, već samo vrijednost iz podskupa realnih vrijednosti. Drugim riječima, realni tip na kompjutoru konačan je skup realnih vrijednosti. Zbog toga se računske operacije ne obavljaju s točnim već s približnim vrijednostima. Posljedica toga je činjenica da su rezultati operacija aproksimacija točnih rezultata.
Skup vrijednosti logičkog tipa (logical ili Boolean) sastoji se od dvije logičke konstante: true (istina) i false (neistina, laž).
U većini jezika za programiranje, u kojima je uveden logički tip podataka, definirane su Boolove operacije - negacija, konjunkcija i disjunkcija, a u nekim jezicima i implikacija te još neke operacije.
Skup vrijednosti znakovnog tipa (character) odreden je alfabetom jezika za programiranje (skupom svih znakova dopuštenih u jeziku za programiranje). Nad znakovnim tipom najčešće je definirana samo operacija nastavljanja, ali rezultat te operacije nije znak već niz znakova.
5.3.3. Imena
Na apstraktnoj se razini svaki jezik za programiranje koristi objektima: cjelobrojnim, realnim, logičkim itd. Kao što je opisano u prethodnom poglavlju, kompjutorska se memorija sastoji od ćelija koje mogu pamtiti podatak bilo kojeg tipa. Ćelije su različite duljine, od jednog bajta do nekoliko memorijskih riječi, ovisno o tipu podataka. Svaka ćelija ima ime, koje je obično varijabla jezika za programiranje. Ime je riječ koja se tvori prema pravilima leksičke strukture jezika. U većini jezika ime je najmanje jedno slovo ili slovo popraćeno nizom znamenaka i slova.
5.3.4. Varijable i konstante
Općenito, podaci bilo kojeg tipa mogu biti:
. varijable
. konstante
Varijabla u matematici ne označava nijednu posebnu vrijednost. Tako je i u tvrdnji da za svaki prirodni broj n vrijedi:
n 2 > 0
U jezicima za programiranje pojam varijable upotrebljava se za nešto sto postoji s vremenom i što u svakom trenutku ima izvjesnu vrijednost.
Varijabla je odredena svojim imenom i tipom. Tip varijable određuje iz kojeg će se skupa varijabli dodjeljivati (pridruživati) vrijednosti. U nekim jezicima tip varijable može biti definiran početnim slovom, u drugima određenim sufiksom, a u nekima tek eksplicitnom deklaracijom tipa.
Konstante imaju određene vrijednosti koje se ne mijenjaju tokom izvršavanja programa. Zadaju se eksplicitno, uz pisane konkretne vrijednosti iz skupa svih vrijednosti nekog tipa ili im se pridružuje simboličko ime. Na primjer, -123 je cjelobrojna konstanta, a 0,505 realna. Važno je primijetiti da u jezicima za programiranje konstante nisu vrijednosti. Bolje ih je zamislitikao posebnu vrstu varijabli koje svoje vrijednosti steknu prije nego što program počne i nikad ih ne mijenjaju.
5.5.5. Strukture podataka
Vrijednosti bez komponenti, koje predstavljaju same sebe i dalje se ne dijele, nazivaju se primitivni tipovi. Nosioci primitivnih tipova su konstante ili varijable koje se mogu nazvati primitivnim varijablama.
Polazeći od prostih tipova, moguće je definirati strukturirane tipove - skupove vrijednosti čija struktura ima određeni smisao. Nosioci strukturiranih podataka bit će strukturirane varijable. One se mogu primjenjivati tako da se odnose na strukturiranu vrijednost u cjelini ili na pojedine komponente.
Da bi se definirao strukturirani tip, nužno je definirati metodu struk-turiranja i tipove komponenti. U većini jezika za programiranje susreću se sljedeći strukturirani tipovi po-dataka:
. polje
. niz
. slog
. datoteka
Polje (array) jest kolekcija elemenata istog tipa (npr. realnog ili znakovnog) objedinjenih u k-dimenzionalnoj strukturi. Elementi polja imaju isto ime, ali k različitih indeksa:
A (ii, i2, ..., ik)
Pritom je A ime polja, a il, ..., ik su indeksi elemenata polja. Broj k (kl) je dimenzija polja. Na primjer, jednodimenzionalno polje B(n) od n elemenata može se predočiti kao uređena n-torka:
a dvodimenzionalno polje C(m,n), od m x n elemenata kao uređena tablica:
c(1,1) |
c(1,2) |
c(1,3) |
. . . |
c(1,n) |
c(2,1) |
c(2,2) |
c(2,3) |
. . . |
c(2,n) |
c(3,1) |
c(3,2) |
c(3,3) |
. . . |
c(3,n) |
. . . |
. . . |
. . . |
. . . |
. . . |
c(m,1) |
c(m,3) |
c(m,3) |
. . . |
c(m,n) |
Jednodimenzionalno polje naziva se vektor, dvodimenzionalno matrica. Polje B iz prethodnog primjera je vektor, a C matrica.
Svi poznati jezici za programiranje imaju strukturu polja, ali malo je onih u kojima su definirane i operacije s poljima. Sintakse polja, a djelomično i seman-tike, u pojedinim se jezicima razlikuju.
Niz (string) kolekcija je znakova koja se na razini jezika za programiranje tretira kao nedjeljiva cjelina. Stoga se niz znakova često promatra kao primitivni tip podataka, nad kojim je najčešće definirana samo operacija nastavljanja.
U nekim jezicima, na primjer u Fortranu i Pascalu, niz znakova je specijalan slučaj jednodimenzionalnog polja ciji su elementi znakovi. Tako realiziran, niz znakova čini strukturu podataka znakovnog tipa, koja omogućuje definiranje operacija nad cjelinom, ali i nad njezinim dijelovima.
Slog (record) jest struktura podataka koju čini uredena kolekcija općenito različitih primitivnih ili strukturiranih tipova podataka. Svaka komponenta zapisa ima jedinstveno ime kojim se na nju poziva. To je dosta važna struktura podataka koju susrećemo u nekoliko jezika visoke razine (Pascal, Quick BASIC, na primjer).
Datoteka (file) je organizirana kolekcija zapisa, obično pohranjena na sekun-darnoj memoriji kompjutora. U većini jezika za programiranje razlikuju se dvije vrste datoteka: one u kojima je pristup zapisima sekvencijalan (u nizu) i datoteke s direktnim pristupom zapisima.
Na datotekama se čuvaju ne samo podaci, već i softver potreban za rad na kompjutoru, kao i korisnički programi.
Izrazi
Izrazi nisu naredbe već sintaktičke strukture koje, općenito, sadrže operande (varijable, konstante i funkcije) i operacije. Prema tipu vrijednosti izraza, u većini jezika za programiranje razlikujemo:
. aritmetičke
. znakovne (nizovne)
. logičke izraze
Aritmetički izrazi sadrže cjelobrojne, realne, a u Fortranu i kompleksne operande, te poznate i o tipu ovisne aritmetičke operacije. Znakovni izrazi sadrže nizove znakova kao operande i samo jednu operaciju - nastavljanje. Logički izrazi sadrže relacijske podizraze, logičke konstante i varijable te logičke operacije.
Naredbe
Elementarni postupci izračunavanja, dodjeljivanja i kontrole redoslijeda izračunavanja specificiraju se naredbama jezika za programiranje. Naredbe mogu imati različite oblike i značenje. Uobičajena je podjela na:
. primitivne (jednostavne)
. strukturirane (složene) naredbe.
Ta je podjela odraz sintakse naredbi. Osim nje, ponekad se naredbe, na temelju svog značenja, dijele na:
. naredbe za izračunavanje
. naredbe za kontrolu toka izvršavanja
. deklarativne naredbe
. ulazno-izlazne naredbe itd.
Primitivne naredbe su one koje ne sadrže druge naredbe. To su, na primjer, naredba za dodjeljivanje, naredba za ispisivanje, naredba za čitanje podataka itd. U nekim jezicima program se može promatrati kao niz primitivnih naredbi (na primjer u jezicima SNOBOL i APL). Strukturirane naredbe (složene ili komponirane) sadrže jednu ili više naredbi. Strukturirane su naredbe, na prim-jer, naredba IF-THEN-ELSE, WHILE i REPEAT petlja u Pascalu.
Podprogrami
Podprogrami su takoder Strukturirane naredbe koje sadrze grupu primitivnih i strukturiranih naredbi, odnosno cjeline po svojoj funkciji i operacijama koje obavljaju.
Programi
Konačno, stigli smo do najviše hijerarhijske strukture elemenata programa. Program sada možemo definirati kao niz naredbi, primitivnih i složenih, kojima se opisuje postupak ulaza, izračunavanja i izlaza podataka i rezultata izračun-avanja.
5.3.6. Semantika jezika za programiranje
Znajući da je naredba sintaktički korektna, postavlja se pitanje: što je njezino značenje? Pravila koja daju odgovor na to pitanje nazivaju se semantika jezika za programiranje. Semantiku jezika za programiranje mnogo je teže odrediti nego njegovu sintaksu.
Jasna razlika izmedu sintakse i semantike jezika za programiranje prvi se put očitovala u izvjestaju jezika ALGOL 60,1963. godine. Otada postoji nekoliko pristupa njezinoj specifikaciji. Mi ćemo pod pojmom semantika razumijevati ono sto je u literaturi poznato kao interpretativna semantika. Interpretativna semantika neke naredbe jezika za programiranje jest učinak njezinog izvršenja na odredenom kompjutoru. Na primjer, semantika naredbe
N = 55
a čitat ćemo "N stječe vrijednost 55", ili: "broj 55 dodijeljen je varijabli s imenom N". Ili, semantika naredbe
PRINT N
napisane također BASIC-om, jest ispis vrijednosti varijable N.
Svi programi koje smo dali kao primjer ustrojenja algoritma za izračunavanje zbroja neparnih brojeva komponenti polja u strojnom i asemblerskom jeziku, te u jezicima visoke razine -BASIC-u, Pascal-u, COBOL-u, APL-u i LISIP-u, imaju jednako značenje, jednaku interpretativnu semantiku.
Još ne postoji pogodna notacija za opis semantike naredbi jezika za programiranje. Najčešće se to čini riječima.
Pitanja i zadaci
1. Definiraj opću hijerarhijsku strukturu jezika za programiranje.
2. Što je tip podataka i koje standardne tipove podataka ima većina jezika za programiranje?
3. Što su strukturirani tipovi podataka?
4. Što je vektor, a što matrica?