43
1 Programski jezici 1. Povijest programskih jezika 2. Što definira programski jezik: Leksička struktura Sintaksa Semantika 3. Elementi s kojima manipuliramo programskim jezikom: tipovi i klase, konstante i varijable, funkcije i procedure, kontrolne strukture i iznimke 4. Temeljne paradigme za podjelu programskih jezika: Strojni i asemblerski jezik Proceduralni (imperativni) jezici (C, Pascal, Fortran) Objektno orijentirani jezici (C++, Java, C#) Funkcionalni jezici (Lisp, Sheme, ML, Haskell) Logički orijentirani jezici (Prolog) Vizualno programiranje Učit ćemo barem jedan jezik iz svake grupe.

Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

  • Upload
    hathu

  • View
    268

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

1

Programski jezici

1. Povijest programskih jezika

2. Što definira programski jezik:

Leksička struktura

Sintaksa

Semantika

3. Elementi s kojima manipuliramo programskim jezikom:

tipovi i klase,

konstante i varijable,

funkcije i procedure,

kontrolne strukture i iznimke

4. Temeljne paradigme za podjelu programskih jezika:

Strojni i asemblerski jezik

Proceduralni (imperativni) jezici (C, Pascal, Fortran)

Objektno orijentirani jezici (C++, Java, C#)

Funkcionalni jezici (Lisp, Sheme, ML, Haskell)

Logički orijentirani jezici (Prolog)

Vizualno programiranje

Učit ćemo barem jedan jezik iz svake grupe.

Page 2: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

2

Smjerovi razvoja programskih jezika U početku, ... programi su pisani u strojnom kodu, sekvence bitova, obično u heksadecimalnoj notaciji, predstavljali su i

naredbe i podatke u računalu.

Primjer: 34020005

0000000c

3c011001

Koji čudak može pisati programe na ovaj način (bilo ih je nekoliko).

Prvi simbolički jezik - Asembler Umjesto binarnih nizova pišu se simbolička imena naredbi i memorijskih lokacija

Primjer: mov eax,5

push eax

call absvalue

sub esp, 4

Ovo je lakše razumjeti od binarnih sekvenci, ali i dalje se mora programirati na vrlo niskoj razini - direktno se manipulira s

memorijom i vanjskim uređajima.

Page 3: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

3

U asembleru:

o Postoji samo jedan tip podataka - niz bajta.

o Kontrolne strukture su: uvjetni i bezuvjetni skokovi.

o Imena (varijabli i labela) su globalni objekti

o Potprogrami se realiziraju kao prosti skokovi na mjesto izvršenja programa.

o Nije poznat mehanizam prijenosa argumenata funkcije.

Fortran (Formula Translator)

Prvi pravi programski jezik, razvijen 50-tih godina.

Primjer: sum = 0

do 10 i=1,100

10 sum = sum + a(i)

Korak naprijed u programiranju:

Programiranje postaje “problemski orijentirano”, a manje je “strojno orijentirano.”

Uvode se kontrolne strukture: "if" - selekcija i "do"-petlja .

Uvodi se mehanizam prijenosa argumenata potprograma

Razlikuju se funkcije i procedure

Novije varijante su: Fortran 77, Fortran 90 i HPF (High Performance Fortran).

Page 4: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

4

Cobol (Common Business Oriented Language)

Jezik za poslovne aplikacije s bazama podataka. Razvijen početkom 60-tih godina.

Primjer: multiply i by 3 giving j.

move j to k.

write line1 after advancing

1 lines.

Cobol je:

o Prvi standardizirani programski jezik.

o Još i danas se koristi u komercijalnim aplikacijama.

o Jezik s dosta riječi, pogodan za proste programere.

o Prvi puta otvara diskusiju o potrebi pisanja razumljivog kôda

Page 5: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

5

BASIC

BASIC (Beginner’s All-purpose Symbolic Instruction Code) je kreiran na DARTMOUTH College od John Kemeny i

Thomas Kurtz-a 1964. godine kao jezik za ne-profesionalce. To je bio prvi pravi interpreter.

Varijable su zapisivane jednim slovom ili slovom iza kojeg slijede znamenke.

Ne koristi se eksplicitne deklaracije varijabli.

Varijable mogu biti numeričke vrijednosti ili stringovi.

Svakoj naredbi prethodi numerička oznaka, koja se koristi kao oznaka za skokove u programu.

Primjer: 10 REM A SAMPLE BASIC PROGRAM FOR SORTING ARRAY A

20 DIM A(100)

30 FOR I = 1 TO 100

40 INPUT A(I)

50 NEXT I

60 FOR I = 1 TO 100

70 J = I

80 FOR K = J+1 TO 100

90 IF A(K) < A(J) THEN 130

100 T = A(I)

110 A(I) = A(J)

120 A(J) = T

130 NEXT K

140 NEXT I

150 STOP

160 END

Današnje verzije BASIC jezika, primjerice Visual Basic, nemaju značajnije sličnosti s ovim jezikom.

Page 6: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

6

Algol 60 (Algorithmic Language)

Razvijen 1960. kao prvi jezik koji je potpuno pogodan za strukturalno programiranje. Direktni je prethodnik jezika Pascal,

C, C++ i Java.

Primjer:

real procedure cheb(x,n);

value x,n;

real x; integer n;

cheb := if n = 0 then 1

else if n = 1 then x

else 2 * x * cheb(x,n-1) - cheb(x,n-2);

Algol uvodi u programske jezika danas standardne elemente:

o Blokovi s lokalnim deklaracijama

o Ugniježđene deklaracije i kontrolne strukture.

o Prijenos parametara potprograma,

o Potprogrami mogu biti rekurzivni.

Iako dobro koncipiran, nije šire prihvaćen jer:

o Nema standardizirani pristup I/O uređajima.

o IBM je preferirao razvoj Fortrana i PL/I.

Page 7: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

7

Lisp (List Processing Language)

Lisp je razvijen početkom 60-tih godina. U njemu se odstupa od proceduralne (imperativne) osnove programskih jezika, a

uvode se elementi funkcionalnog programiranja

Primjer Lisp interpretera:

>(+ 1 2 5)

8

>((lambda (x) (* x x)) 10)

100

Karakterisike Lispa:

o Program i podaci se predstavljaju kao liste u prefiksnoj notaciji

o (+ 9 8 7) znači: izraz kojem se rezultat dobije zbrajanjem brojeva 8,8 i 7

o Ne postoji deklaracija tipova varijabli

o Tipovi su svojstva vrijednosti podataka, a ne svojstva varijable ili parametara funkcije.

o Program u toku izvršenja može stvarati i izvršavati funkcije i izraze

o Vrši se automatsko alociranje memorije - koristi se "garbage collection" mehanizam

Pri razvoju jezika prvi put je razvijena i definirana formalna semantika - njome se precizno određuje značenja

programa.

Slijednik Lispa je jezik Scheme koji uvodi i elemente iz Algola (lokalni doseg). Pored Scheme jezika od funkcionalnih

jezika dosta su u upotrebi Haskell, ML, OCaml i F#.

Page 8: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

8

Simula 67 (Simulation Algol)

Simula 67 je prvi objektni jezik - uvodi se definiciju klasa

Primjer:

Class Rectangle (Width, Height);

Real Width, Height;

Boolean Procedure IsSquare;

IsSquare := Width=Height;

End of Rectangle;

Simula 67 proširuje Algol s:

definicija klase i proširene klase.

Definicija objekata i garbage collector.

ADA

ADA - jezik je sredinom 70-tih razvijen za U.S. Dept. of Defense

Ističe važnost modularnog programiranja

Page 9: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

9

C i C++ C je razvijen početkom 70-tih godina, a C++ sredinom 80-tih godina. Oba jezika su prihvaćeni kao temeljni jezici za

"performance-critical applications": izradu operativnih sustava i sistemskog softvera.

Omogućuju platform-independent programiranje. (#define leksičke - supstitiucije)

Oba jezika mogu koristiti i početnici i profesionalni programeri, ali to ne znači da su podesni za početno poimanje

programiranja.

To bolje omogućuju Java i C#. Jednostavnost slijedi iz činjenice da ovi jezici ne koriste pokazivače.

Java Jezik Java je razvijen krajem 90-tih, kao jezik za izradu distribuiranih mrežnih programa. Glavne karakteristike su :

Jednostavniji je i čišći jezik od C++, što je ostvareno nauštrb brzine izvršenja programa.

Čisti OO jezik - sve konstrukcije jezika se definiraju unutar klase.

Naglasan na sigurnosti, a ne na brzini.

Potpuna neovisnost o operativnom sustavu.

C# Vrlo je sličan Javi, ali je nešto bliži C++ jeziku nego Java.

Objective C Objective C je razvijen i korišten na Next i Mac OS sustavima. Preuzima elementa C-a i Smalltalka.

Swift Apple-ov odgovor na C#

Page 10: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

10

Zašto se istražuju novi programski jezici?

1. Znatiželja

Koji drugi oblici jezika mogu biti realizirani?

2. Produktivnost

Standardni proceduralni jezici su vrlo zahtjevni kad treba razvijati softver posebne namjene. U tom slučaju je možda bolje

razviti intepreter za tu posebnu namjenu. Primjerice, jezik Matlab omogućuje jednostavno rješavanje matematičkih

problema.

3. Sigurnost i pouzdanost

I dalje je pitanje sigurnosti izvršenja programa vrlo važno pitanje, koje je možda može bolje riješiti u samom programskom

jeziku.

4. Brzina izvršenja

Jezici C i C++ omogućuju najbrže izvršenje programa na standardnim računalima, međutim nisu pogodni za sustave

računala koji rade paralelno ili distributivno.

5. Nove tehnologije traže nove jezike Go – Google razvija novi jezik – proširen je C jezik s elementima potrebnim za sinkronizaciju više istovremenih procesa.

Page 11: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

11

Poželjne karakteristike programskih jezika Gledano teoretski, kada programski jezik tretiramo kao dio stroja računala, tada su skoro svi programski jezici ekvivalentni

i pomoću njih se mogu riješiti svi problemi koje je moguće riješiti računalom (Church –Turing teza). Ipak, jezici imaju i

druge, mnogo značajnije funkcije a to je da omoguće apstrakciju, efikasne programe i ugodno programiranje.

Koje svojstva jezika su poželjna?

Jednostavnost upotrebe jezika.

o Programi trebaju biti jednostavni i razumljivi

o Konstrukcije jezika trebaju biti ortogonalne, tj. da postoji samo jedan način izvršenja.

o Zapis treba biti što bliži duhu aplikacije koja se programira.

Jezik treba podržavati apstrakciju.

o Postojeće strukture i operacije trebaju biti dogradive za nove apstraktne strukture.

Jezik treba omogućiti jednostavno testiranje i debagiranje programa.

Poželjno je imati IDE sa sustavom pomoći, editorom i debagerom.

Poželjno je da jezik omogućuje portabilnost za različite operativne sustave.

Opći su zahtjevi:

o Brzina izvršenja i mali zahtjevi za memorijom.

o Prevođenje brzo i modularno, s pripadnim bibliotekama.

o Komponente jezika trebaju biti "reusable"

Page 12: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

12

Programske i jezičke paradigme

Programske jezike dijelimo prema 4 fundamentalna stila - paradigme: proceduralni, objektno orijentirani, funkcionalni i

logički.

Proceduralni jezici

C, Fortran, Pascal, Ada, itd.

Program se izvršava naredbu po naredbu, te očitava i mijenja sadržaj memorije.

Na isti način radi i procesor koji komunicira s RAM memorijom..

Pitanje: Za segment programa

a = a + 1;

if (a > 10)

b = 10;

else

b = 15;

a = a * b;

Zašto ovaj program pet procesora ne može izvršiti pet puta brže?

Uoči: ovisnost reda izvršenja i vrijednosti varijable.

Page 13: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

13

Kod proceduralnih jezika funkcije često iskazuju bočne efekte (side effects)

int global=1;

int Mul(int x) {

global = global *x; // side effect – bočni efekt na globalnu var. return global;

}

int main()

{ // Loše je što

cout << Mul(3) // svaki poziv

cout << Mul(3) // daje drukčiji

} // rezultat

Izlaz:

3

9

Bočni efekti nisu poželjni u programiranju, jer višestruki poziv neke funkcije s istim argumentima daje različite rezultate.

Page 14: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

14

Objektno-orijentirani jezici

C++, Java, C#, Smalltalk, Pizza i Python su objektno-orijentirani jezici.

Podaci i funkcije združeno određuju svojstva i aktivnost objekata.

Objekti su aktivni entiteti sa stabilnim stanjem, i sučeljem prema drugim objektima, s kojima se komunicira pomoću poruka

ili metoda.

U definiranju objekata koristi se princip nasljeđivanja, princip komponiranja objekata i princip zajedničkog sučelja

(interfejsa).

Interface (sučelje) u JAVI ili virtualne funkcije u C++ jeziku određuju način komuniciranja s različitim objektima, što

omogućuje da se programi izvršavaju polimorfno (višeoblično).

C++ također omogućuje programske tehnike:

o Modularno programiranje kao podrška za „data hidding“

o Generičko programiranje

o Rukovanje iznimkama

U C# i Javi sve mora biti deklarirano unutar klase, čak i Main() funkcija, od koje starta izvršenje programa

Page 15: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

15

//C++ program

int main()

{

cout << " hello, world "

}

//Java program

class Hello

{

public static void main(String[] args) {

System.out.println("hello, world");

}

}

// C# program

class Hello

{

static void Main() {

System.Console.WriteLine("hello, world");

}

}

Page 16: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

16

Funkcionalni jezici

U funkcionalnim jezicima,

procedure (funkcije) su entiteti prve klase

Entiteti prve klase:

Mogu biti pridjeljeni varijablama

Mogu biti argumenti funkcija

Mogu biti vrijednost koju funkcija vraća.

Mogu biti elementi složenih struktura podataka.

Lisp, Scheme i ML su "prirodno" funkcionalni jezici.

> (define sqr (lambda (x) (* x x)) # varijabla sqr je funkcija(lambda?)

> (sqr 10) # apliciraj funkciju sqr na argument 10

> 100 # rezultat je 100

Program sadrži izraze koji se "evaluiraju".

Dizajn jezika minimizira bočne efekte uključujući i izbjegavanje upotrebe naredbe pridjele vrijednosti.

Page 17: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

17

Logički programski jezici

Prolog je logički programski jezik. U njemu korisnik zapisuje:

o činjenice i

o što program treba obaviti,

o a ne zapisuje se postupak kojim se izvršava program

Ne koristi se klasična kontrola tijeka programa.

Primjer:

inOrder( [] ).

inOrder( [ _ ] ).

inOrder([a,b|c]) :- (a < b),

inOrder([b|c]).

Ovo je kompletni program, kojim se određuje da li je lista uređena.

Primjetite da nema deklaracija, varijabli i eksplicitno zadanih petlji.

Page 18: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

18

Koncepti iz programskih jezika

Deklaracija / Doseg / Životnost / Povezivanje - statičko/dinamičko

Identifikatori varijabli i funkcija se deklariraju, eksplicitno ili implicitno iz konteksta prve upotrebe.

Deklaracije povezuju (bind) tip i vrstu s identifikatorom. Primjerice

static int var;

int je tip, static je vrsta varijable var.

Svaki identifikator ima doseg (scope ) u programu— to je dio programa u kojem je vidljiv identifikator

Životnost (lifetime) — je vremenski interval u kojem identifikator referira memorijski objekt. Obično je životnost

povezana s dosegom identifikatora, tj. objekt traje za vrijeme izvršenja programa iz dosega identifikatora.

Svojstva identifikatora (i objekta koji on predstavlja) se određuju:

1. Tijekom kompiliranja (Compile-time )

Ta svojstva se nazivaju statična i ne mijenjaju se tijekom izvršenja programa

Primjeri: tip varijable ili tijelo funkcije.

2. Tijekom izvršenja (Run-time)

Ta svojstva se nazivaju dinamička i mogu se mijenjati tijekom izvršenja programa. Primjeri: vrijednost varijable, dinamički alocirani objekti, argumenti funkcije itd.

Page 19: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

19

Dinamički alocirane varijable

U C++ se koristi pokazivače i operatore new i delete. Primjerice, dinamički niz od 6 cijelih brojeva formira se naredbom:

int *pa = new int[6]; // C++

Kada nam više ne treba ova varijabla brišemo je iz memorije operatorom delete:

delete [] pa; // C++

U Javi i C# se svi objekti i nizovi formiraju dinamički - primjenom new operatora. Dealociranje memorije ne vrši korisnik

već se vrši automatski pomoću mehanizma "skupljača smeća" (garbage collection). Zbog toga, jer u Javi i C# nema

statičkih nizova i objekata, njihova imena, iako predstavljaju pokazivače, tretiraju se kao reference. To pojednostavljuje

zapis programa na način da se članovima struktura i klasa uvijek pristupa pomoću točka operatora.

class Test // Java program

{

public static void main(String[] args) {

int[] arr = new int[6];

for (int i = 0; i < arr.length; i++)

arr[i] = i * i;

for (int i = 0; i < arr.length; i++)

System.out.println("arr[" + i + "] = " + arr[i]);

}

}

Page 20: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

20

U Javi i C# svi objekti se stvaraju dinamički

class A

{

public void F() { System.out.println("A.F"); }

}

class Test

{

public static void main(String[] args) {

A b = new A(); // dinamički alocirani objekt b

b.F(); // članovima se pristupa pomoću točka operatora

} // iako b stvarno predstavlja pokazivač

}

Page 21: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

21

Blok struktuirani jezici

Algol 60, Pascal, C, C++, Java.

Identifikatori mogu imati lokalni i globalni doseg.

Deklaracije mogu biti lokalne - unutar klase ili bloka.

Ugnježdeni blokovi imaju različiti doseg. Identifikatoru se pridjeljuje leksički najbliža deklaracija.

Povezivanje identifikatora i deklaracije je obično statično (ili leksičko), ali su moguća i dinamička povezivanja (npr.

pretvorba tipa).

Statičko (ili leksičko ) povezivanje se vrši prije izvršenja programa— za vrijeme kompiliranja

Primjer (C jezik):

int x,z;

void A() {

float x,y;

print(x,y,z); // global var z

}

void B(int y) {

print (x,y,z) // global var x,z

}

Page 22: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

22

Blok struktura

U većini slučajeva blok struktura znači:

Nije moguć pristup identifikatorima izvan njihova dosega.

Primjenjuje se najbliža prethodna deklaracija.

Lokalne varijable se automatski alociraju i dealociraju

Postoje varijacije od ovih pravila. U Javi se može koristiti objekt tek kada je kreiran pomoću new operatora,

Primjerice, ...

Object Obj;

...

stvara referencu Java objekta ali ne i memoriju za taj objekt.

Tek kada se izvrši stvaranje objekta s

Object Obj = new Object();

...

njemu se može pristupiti.

Page 23: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

23

Dinamički doseg

Pod dinamičkim dosegom podrazumijeva se da se za identifikator uzima deklaracija koja je najbliže prema vremenu

izvršenja programa. Taj se princip koristio u ranim verzijama jezika Lisp.

Problem nastaje ako varijabla nije lokalno deklarirana. Primjerice, problem je ilustriran s kvazi-C jezikom

int x;

void print()

{

write(x);

}

main () {

bool x;

print();

}

Kod statičkog povezivanja x se ispisuje u funkciji print() kao tip int, jer je int x, globalno deklariran.

Kod dinamičkog povezivanja, pošto print nema lokalnu deklaraciju za x, ispituje se pozvana funkcija u kojoj je x tipa

bool.

Dinamičko povezivanje je vrlo teško provesti, stoga se ono izbjegava. Ono čak izgleda i bizarno, ali se ipak koristi, i to kod

virtualnih funkcija u C++, C# i Java jeziku.

Page 24: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

24

Virtualne funkcije

Primjer: C# jezik – dinamičko povezivanje s virtualnim funkcijama

using System;

class C {

public void DoIt() {PrintIt();}

public virtual void PrintIt() {Console.WriteLine("C rules!");}

}

class D : C {

override public void PrintIt() {Console.WriteLine("D rules!");}

public void TestIt() {DoIt();}

}

class Test{

public static void Main() {

D dvar = new D();

dvar.TestIt();

}

}

//D rules! is printed.

Page 25: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

25

U jeziku Java – "sve metode su virtualne"

Primjer:

class C {

void DoIt() {PrintIt();}

void PrintIt() {System.out.println("C rules!");}

}

class D extends C {

void PrintIt() {System.out.println("D rules!");}

void TestIt() {DoIt();}

}

class Test {

public static void main (String args[]) {

D dvar = new D();

dvar.TestIt();

}

}

//D rules! is printed.

Domaći rad: Napišite C++ program koji daje isti izlaz.

Page 26: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

26

Doseg i životnost

Obično se zahtijeva da životnost varijable bude barem jednaka vremenu koji odgovara izvršenu dosega varijable.

Životnost nekih objekata nadmašuje njihov doseg. Primjer za to su static ili own varijable.

void f() {

static int i = 0;

print(i++);

}

Svaki poziv f() ispisuje različitu vrijednost od i (0, 1, ...) . Varijabla i zadržava vrijednost između poziva funkcije.

Neki jezici dozvoljavaju inicijaliziranje varijabli u svakom dosegu.

ML C

Let

id = val

in

statements

end;

{

type id = val;

statements

}

Page 27: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

27

Strukture i blokovi

Podaci se grupiraju u strukture:

struct complex { float re, im; }

a programski kod se grupira u blokove:

{

float re, im;

re = 0.0; im = 1.0;

}

Iako slično izgledaju, blok i struktura su potpuno različiti entiteti:

o Strukture su podaci, o Blokovi sadrže programski kod i deklaracije,

Ako u strukturu dodamo definiciju funkcija i inicijalizacijski kod (konstruktora i destruktora) dobije se definicija klase:

class complex

{

public:

float re, im;

complex (float v1, float v2){ re = v1; im = v2; }

}

Page 28: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

28

Klase

Klasa se koristi za stvaranje jednog ili više objekata

Deklarirane varijable se nazivaju članovi ili polja, a deklarirane funkcije se nazivaju metode ili članske funkcije klase,

Dvije posebne funkcije, kojima se ne zadaje tip, i koje imaju ime klase , predstavljaju konstruktor i destruktor klase

Unutar klase članovi se mogu grupirati s atributom public, private ili protected, što označava razinu dozvole pristupa

članovima klase.

Ekvivalentnost tipa za klase

Klase dijelo možemo tretirati i kao tipove podataka.

U C++ i Javi, objekti neke klase su ekvivalentnog tipa i mogu se pridjeljivati jedan drugom, pr.

class MyClass {

...

}

MyClass v1, v2;

v1 = v2; // Pridjela vrijednosti je OK

Ova naredba pridjele vrijednosti ne mora biti uvijek u C++ izvršena s željenim učinkom.

Pogledajmo slučaj u Javi i C++

Page 29: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

29

JAVA

Razmotrimo klasu Point kojom se može stvarati n-dimenzionalne točke:

class Point { // in Java

int dimensions;

float coordinates[];

Point () {

dimensions = 2;

coordinates = new float[2];

}

Point (int d) {

dimensions = d;

coordinates = new float[d];

}

}

Point plane = new Point();

Point solid = new Point(3);

plane = solid; //OK u Javi

U Javi je dozvoljeno pridjeljivanje objekata iste klase, iako u ovom primjeru, od dvodimenzionalne točke stvaramo

trodimenzionalnu točku.

Page 30: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

30

U C++ postoji problem plitkog i dubokog kopiranja, koji se rješava tako da korisnik sam definira operator pridjele

vrijednosti. Ortodoksni kanonički oblik klase u C++ zahtijeva da se definira a) konstruktor, b) destruktor, c) operator = i d)

kopirni konstruktor:

#include <iostream>

class Point {

public:

int dimensions;

float *coordinates;

Point (int d = 2) {

dimensions = d;

coordinates = new float[d];

}

~Point() {delete [] coordinates;}

// mora se definirati za dinamički

// alocirane članove

Point &operator =(Point &p) {

if(this == &p) return *this;

if(p.dimensions != dimensions) {

delete [] coordinates;

coordinates = new float[p.dimensions];

}

for(int i=0; i<p.dimensions; i++)

coordinates[i]=p.coordinates[i];

return *this;

}

};

// Zadatak: definiraj kopirni konstruktor

int main()

{

int i;

Point *plane = new Point();

Point *solid = new Point(3);

for (i=0; i<solid->dimensions; i++)

solid->coordinates[i]=i;

plane = solid; //OK in if operator = defined

// but plane is now 3d point

for (i=0; i<plane->dimensions; i++)

std::cout << solid->coordinates[i] << " ";

return 0;

}

Page 31: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

31

Subklase nisu ekvivalentnog tipa

Temeljna se klasa naziva superklasa, a izvedene klase se nazivaju subklase. Također se za temeljnu klasu koristi

naziv roditelj (parent class), a izvedene klase se nazivaju djeca (child classes),

U C++, C# i Javi subklase (ili subtipovi) se stvaraju pomoću nasljeđivanja, ali to ne znači da se te klase istog tipa

Primjer u Javi:

class Point2 extends Point

{

Point2() {super(2); } // super je konstruktor roditelja

}

class Point3 extends Point

{

Point3() {super(3); }

}

Point2 plane = new Point2();

Point3 solid = new Point3();

plane = solid; //Illegal in Java

Page 32: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

32

C++: class Point2 :public Point {

public:

Point2() : Point(2) {}

};

class Point3 :public Point {

public:

Point3() : Point(3) {}

};

int main()

{

Point2 *plane = new Point2();

Point3 *solid = new Point3();

for (i=0; i<solid->dimensions; i++)

solid->coordinates[i]=i;

plane =reinterpret_cast<Point2 *> (solid); //OK if type cast

for (int i=0; i<plane->dimensions; i++)

std::cout << plane->coordinates[i] << " ";

// Ilegalno u Javi, Ok u C++ ako se koristi pretvorba tipa,

// ali, tko može razumjeti ovaj program u C++

return 0;

}

Izlaz je: 0 1 2

Page 33: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

33

Ako se deklarira u C++:

class Point2 :public Point {

public:

Point2() { Point(2); } // umjesto Point2() : Point(2) {}

};

class Point3 :public Point {

public:

Point3() { Point(3); } // umjesto Point3() : Point(3) {}

};

Za main() isti kao prije

izlaz je: 0 1

Objasni: Zašto je nestala treća dimenzija?

Problem je u korištenju konstruktora :

Point3() { Point(3); } umjesto Point3() : Point(3) {}

Zaključak: Dobro je da nas Java čuva od ovakovih grešaka.

Page 34: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

34

Generičke klase i parametrički polimorfizam Postavlja se pitanje, kako se može stvarati napredne strukture podataka koje se mogu primijeniti na različite tipove.

Primjerice, može li se napraviti klasu za vezanu listu koja će moći sadržavati različite tipove podataka.

Najjednostavniji način je primijenjen u jeziku Java, na način da sve klase nasljeđuju jedinstvenu temeljnu klasu Object.

U Javi se onda vezana lista definira sljedećom klasom:

class LinkedList

{

Object value;

LinkedList next;

Object head() {return value;}

LinkedList tail(){return next;}

LinkedList(Object O)

{value = O; next = null;}

LinkedList(Object O,LinkedList L)

{value = O; next = L;}

}

Vidimo da ova klasa sadrži objekte tipa Object. Pošto je referenca objekta u Javi zapravo pokazivač objekta tada se ovom

objektu može pridijeliti objekt bilo kojeg tipa, ali:

o Mora se vršiti pretvorba tipa Object u stvarni tip ako želimo dobiti objekt iz liste

o Za pretvorbu tipa mora postojati definirana klasa. Primjerice ako želimo da lista sadrži cijele brojeve za

pretvorbu tipa nam je potrebna klasa Integer a ne primitivni tip int (jer primitivni tip nije klasa).

Page 35: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

35

Primjer, manipuliranje s vezanom listom koja sadrži cijele brojeve :

LinkedList l =new LinkedList(new Integer(123));

int i = ((Integer) l.head()).intValue();

Očito je ovaj pristup u Javi, a slično je bilo i u prvim bibliotekama C++, dosta nepraktičan. Zbog toga je u C++ uveden

mehanizam predložaka (template) a sada se uvodi u C# i u Javu (probna verzija je dana u jeziku Pizza). Mahanizam

predložaka stvara generičke klase i to se naziva parametrički polimorfizam.

Evo kako izgleda generički definirana vezana lista u jeziku Pizza:

class LinkedList<T> {

T value;

LinkedList<T> next;

T head() {return value;}

LinkedList<T> tail() {return next;}

LinkedList(T O) {value = O; next = null;}

LinkedList(T O,LinkedList<T> L){value=O; next=L;}

}

LinkedList<int> l = new LinkedList(123);

int i = l.head();

Isto kao u C++ parametrički tip se zapisuje u zagradama <>, a stvarni tip se definira pri deklaraciji objekta.

Page 36: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

36

Preopterećenje (Overloading) funkcija ili ad-hoc polimorfizam

U klasama se često definira više funkcija (ili konstruktora) s istim imenom ali s različitim parametrima. To zovemo

preopterećenjem funkcije. Primjer:

class MyClass {

int f(int i) { ... }

int f(float g) { ... }

int f(int i, int j) { ... }

}

C++ i Java ne dozvoljavaju de se preopterećene funkcije razlikuju po povratnoj vrijednosti, već moraju biti različiti

parametri funkcije (broj parametara ili tip) To znači da

class MyClass {

int f() { ... }

float f() { ... }

}

nije dozvoljeno.

Page 37: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

37

Preopterećenje operatora

C++ i C#, dozvoljavaju preopterećenje (promjenu značenja) postojećih operatora. Primjer:

class MyClass {

int i;

public:

int operator+(int j) { return i+j; }

}

MyClass c;

int i = c+10;

int j = c.operator+(10);

int k = 10+c; // Nije dozvoljeno!

Izraz 10+c nije ispravan jer nije definirano djelovanje operatora + za objekte tipa int i MyClass&. To se može

ostvariti u C++ pomoću friend mehanizma, koji omogućuje pristup private članovima:

class MyClass {

int i;

public:

int operator+(int j) {return i+j; }

friend int operator+ (int j, MyClass& v) {return j+v.i; }

}

MyClass c;

int k = 10+c; // OK!

C++ dozvoljava preopterećenje postojećih operatora. Neki jezici, poput Algola 68 dozvoljavaju definiranje novih operatora.

Page 38: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

38

Prijenos argumenata (stvarnih parametara) funkcije

Stvarni parametar ili argument funkcije je objekt koji se deklarira kao formalni parametar funkcije. On ima ime, i

vrijednost i adresu (ukoliko nije konstanta). U funkciju se mogu prenositi sve tri značajke argumenta. Koriste se sljedeći

nazivi za prijenos argumenata u funkciju:

Prenosi se

Vrijednost: Formalni parametar se tretira kao lokalna varijabla koja se inicijalizira na vrijednost argumenta. To je

standardni oblik prijenosa vrijednosti konstanti i skalarnih varijabli u C i Javi.

Referenca: Formalni parametre je pokazivač na stvarni parametar. Koristi se u C++ i C za prijenos nizova i varijabli.

Rezultat: Formalni parametar se tretira kao lokalna varijabla. Njena konačna vrijednost se nakon završetka funkcije

kopira u stvarni argument funkcije.

Vrijednost/Rezultat: Kombinacija dva moda. Formalni parametar se tretira kao lokalna varijabla koja se inicijalizira

na vrijednost argumenta. Nakon završetka funkcije rezultat se upisuje u stvarni argument.

Ime: Formalni parametar predstavlja blok koda (zovemo ga thunk) koji se evaluira da bi se dobila vrijednost ili

adresa argumenta. Koristi se jedino u jeziku Algol.

Read-only (Const): Dozvoljen je argument koristiti samo kao konstantu.

Koji se načini prijenosa argumenata stvarno koristi?

• C jezik koristi se prijenos vrijednosti, jedino se nizovima prenosi referenca (adresa nultog elementa)

• C++ dozvoljava prijenos reference varijable

void swap(int &a, int &b) {int t = a; a = b; b = t:}

• C#: koristi prijenos vrijednosti, reference i rezultata;

Page 39: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

39

int g(int a, out int b)

• Java: Skalarni tipovi (int, float, char, etc.) se prenose po vrijednosti, a objekti po referenci.

• Fortran: prenosi se referenca (čak i za konstante).

• Ada prenosi vrijednost / rezultat, reference i readonly konstante.

Zašto se koriste različiti modovi prijenosa argumenata funkcije?

o Prijenos vrijednosti štiti aktualni parametar - on se ne mijenja već se mijenja formalni parametar, koji je lokalna

varijabla.

o Prijenos readonly je ekvivalentan prijenosu vrijednosti, ali se naglašava “konstantni” karakter argumenta.

o Prijenos reference omogućuje mijenjanje argumenta. To može stvoriti bočne efekte, pa se koristi samo u iznimnim

slučajevima.

o Prijenos vrijednosti/rezultata ima efekt kao prijenos reference, ali se to izvršava na drugi način. Umjesto neposredne

promjene argumenta, on se mijenja tek po završetku funkcije..

o Prijenos imena odlaže promjenu aktualnog parametra dok on stvarno ne bude korišten u nekom izrazu ( možda i

nikada. Da bi shvatili tu vrstu prijenosa razmotrimo poziv f(i,j/0). Kod normalnog poziva prvo se evaluira

j/0, što daje divide fault i program završava. Ako se j/0 prenosi po imenu tada se dijeljenje odlaže dok ne

bude potreban drugi argument, a to može biti nikada.

Prijenos po imenu je sličan onome što se kod funkcionalnih jezika naziva "lazy evaluation" (odloženo evaluiranje argumanta). Kod "lazy evaluation", ne vrši se proračun vrijednosti argumenta već se definira posebna funkcija

suspension— koja daje vrijednost kada ona bude potrebna. Suprotno od "lazy evaluation" je "eagger evaluation" gdje se

argumenti evaluiraju čim su definirani.

Page 40: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

40

Ekvivalentnost tipova

Provjera tipova se obično radi za vrijeme kompiliranja – to zovemo static typing.

Provjera tipova se može raditi i za vrijeme izvršenja programa - to zovemo dynamic typing.

Program je tipski-siguran (type-safe) ako nije moguće primijeniti operacije na nekompatibilne tipove podataka.

Čvrsto tipizirani (Strongly-typed) programski jezik zabranjuje formiranje (ili izvršenje) tipski-nesigurnih programa.

Slabo tipizirani (Weakly-typed) programski jezik omogućije formiranje (ili izvršenje) tipski-nesigurnih programa.

Java je čvrsto tipizirani jezik, a C i C++ su slabo tipizirani jezici koji dozvoljavaju da se zaobiđu tipska pravila, primjerice:

int i;

int* p;

p = (int *)i * i;

Sada se p može koristiti kao pokazivač na int premda množenje može rezultirati nedozvoljenim pokazivačem.

Kod kontrole tipova prvo se utvrđuje da li su dva objekta, iz nekog izraza, koji imaju tipove T1 i T2, tipski ekvivalentan.

Koristi se dvije definicije tipske ekvivalentnosti:

o ekvivalencija po imenu

o strukturalna ekvivalencija.

Page 41: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

41

Ekvivalencija po imenu

Dva tipa su ekvivalentna ako označavaju istu vrst deklaracije.

Primjer: typedef int i;

int j;

Očito su tipovi od x i y ekvivalentni.

Primjer, type PackerSalaries = int[100];

type AssemblySizes = int[100];

PackerSalaries salary;

AssemblySizes size;

Sada salary = size; nema ekvivalenciju po imenu

Formalno, definira se N (ekvivalencija po imenu) s:

(a) T N T

(b) Za deklaraciju oblika Type T1 = T2;

T1 N T2

U analizi se anonimni tipovi tretiraju kao da imaju jedinstveno ime, tako

int A[10]; se razmatra kao typedef int[10] T; T A;

Page 42: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

42

Strukturalna ekvivalencija

Dva tipa su strukturalno ekvivalentna ako imaju istu definiciju članova strukture . Strukturalna ekvivalencija se označava s

S, a definira se na sljedeći način:

(a) T S T

(b) Za deklaraciju oblika Type T = Q;

T S Q

ako T i Q su definirani pomoću istih konstruktora tipa i na isti način.

To znači da u prijašnjem primjeru

type PackerSalaries = int[100];

type AssemblySizes = int[100];

PackerSalaries salary;

AssemblySizes size;

salary S size

pošto su oba niza s 100=100 i int S int.

C i C++ u kontroli tipova koriste strukturalnu ekvivalenciju osim za strukture i klase, kod kojih se koristi ekvivalencija po

imenu. Kod nizova ignorira se veličina niza. Java koristi strukturalnu ekvivalenciju za skalarne tipove. Kod nizova

zahtijeva ekvivalenciju po imenu, bez obzira na veličinu niza. Za klase koristi ekvivalenciju po imenu osim što se može

koristiti podklasa na mjestu gdje je definirana klasa.

Page 43: Programski jezici - marjan.fesb.hrmarjan.fesb.hr/~mateljan/jip/1Uvod/01-koncepti proceduralnih jezika... · Jezik Java je razvijen krajem 90-tih, ... kada programski jezik tretiramo

43

To znači da za definiranu funkciju:

void fun(Object O) { ... };

poziv

fun(new Integer(100));

je ispravan jer je Integer subklasa od Object.

Automatska pretvorba tipova

C, C++ i Java dozvoljavaju pretvorbu tipova, od toga neke pretvorbe se vrše automatski

In C, C++ i Java, float se automatski stvara od tipa int, u izrazu:

float f = 10; // No type error

Cjelobrojni tipovi (char, short, int, long) sa automatski "proširuju":

int i = 'x'; // OK - char u int

U C i C++ (ali ne u Javi), cijeli broj se može i "suziti" s mogućim gubitkom bitova:

char c = 1000000; //dozvoljeno u C++ ali ne u Javi