Programski vzorci

Programski vzorci
June 5, 2012
Contents
1 Sintaksa in semantika
1.1 Leksikalna analiza . . . . . . . . . . . . . . . . . . . . .
1.1.1 Groba zgradba prevajalnika . . . . . . . . . . . .
1.1.2 Pregledovalnik . . . . . . . . . . . . . . . . . . .
1.1.3 Neformalni in formalni opis vzorca . . . . . . . .
1.2 Regularni izrazi . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Regularne definicije . . . . . . . . . . . . . . . .
1.2.2 Regularni izrazi, ki se pogosno pojavljajo . . . .
1.2.3 Deterministični končni avtomat . . . . . . . . . .
1.3 Sintaktična analiza . . . . . . . . . . . . . . . . . . . . .
1.3.1 Gramatika . . . . . . . . . . . . . . . . . . . . . .
1.3.2 Jezik . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2.1 Drevo izpeljav . . . . . . . . . . . . . .
1.3.3 Sintaktična analiza ali razpoznavanje . . . . . .
1.3.4 BNF (Backus-Naur Form) . . . . . . . . . . . . .
1.3.4.1 EBNF . . . . . . . . . . . . . . . . . . .
1.3.4.2 Sintaktični analizator ali razpoznavalnik
1.3.5 Razpoznavalniki LL(1) . . . . . . . . . . . . . . .
1.3.5.1 Kaj je gramatika LL(1)? . . . . . . . .
1.3.5.2 Odpravljanje leve rekurzije . . . . . . .
1.3.5.3 Levo faktoriranje . . . . . . . . . . . . .
1.4 Semantična analiza . . . . . . . . . . . . . . . . . . . . .
1.4.1 Atributna gramatika . . . . . . . . . . . . . . . .
2 Programski vzorci, programske paradigme
2.1 Razlogi za preučevanje programskih vzorcev . .
2.2 Domene programiranja . . . . . . . . . . . . . .
2.3 Kriteriji za ocenjevanje jezikov . . . . . . . . .
2.3.1 Drugi ocenitveni kriteriji . . . . . . . . .
2.4 Vpliv na načrtovanje jezikov . . . . . . . . . . .
2.4.1 Vpliv von Neumann arhitekture . . . . .
2.4.2 Izvajanje strojnega koda . . . . . . . . .
2.4.3 Modeli programiranja . . . . . . . . . .
2.4.4 Vplivi na metodologije programiranje .
2.4.5 Vrste programskih jezikov . . . . . . . .
2.4.6 Kompromisi načrtovanja jezikov . . . .
2.5 Metode implementacije . . . . . . . . . . . . . .
2.5.1 Prevajanje . . . . . . . . . . . . . . . . .
2.5.1.1 Dodatni termini pri prevajanju
2.5.2 Interpretiranje . . . . . . . . . . . . . .
2.5.3 Pred-procesiranje . . . . . . . . . . . . .
2.5.4 Programska okolja . . . . . . . . . . . .
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
(ang. parser)
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
3
3
4
4
4
5
5
5
6
6
6
6
7
7
7
7
8
8
9
9
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10
10
10
11
11
11
12
12
12
12
13
13
14
14
14
14
14
15
3 Tipi in spremenljivke
16
3.1
Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2
Spremenljivke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3
3.2.1
Imena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.2
Atributi spremenljivk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Koncept povezljivosti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3.1
Možni časi povezovanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3.2
Statična in dinamična povezljivost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.2.1
3.3.3
Statično povezovanje tipov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.2.2 Dinamično povezovanje tipov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Atributi spremenljivk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.4
Organizacija pomnilnika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.5
Čas povezovanja spremenljivke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.6
Smetar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.7
Implementacija podatkovnih tipov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.7.1
Podatkovni tipi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.8
Osnovni podatkovni tipi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.9
Uporabniško določeni števni tipi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.9.1
Naštevni tipi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.9.1.1
Ovrednotenje naštevnega tipa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.9.1.2
Naštevni tipi v Javi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.10 Polja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.10.1 Vezava indeksov in tipi polj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.10.2 Inicializacija polja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.10.3 Rezine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.10.4 Dostop do večdimenzionalnih polj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.10.5 Deskriptorji v času izvajanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.10.6 Asociativna polja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2
Chapter 1
Sintaksa in semantika
1.1
Leksikalna analiza
• Opravimo jo pred sintaktično analizo.
• Naloga leksikalne analize je poiskati iz niza znakov besede (rezervirane besede, identifikatorje, operatorje,
literale . . . ) oz. osnovne leksikalne simbole (tokens).
Zgledi
1. Maja se uči.
2. Toni sta vek.
3. Mojca je prebral knjigo.
4. if (a==b) z=0; else z=’a’;
Prevajalnik opravi semantično analizo da preveri morebitne nepravilnosti v programu.
1.1.1
Groba zgradba prevajalnika
niz znakov → Leksikalni analizator → osnovni leksikalni simboli → Sintaktični in semantični analizator →
vmesna predstavitev → . . .
1.1.2
Pregledovalnik
• Leksikalno analizo opravi leksikalni analizator ali pregledovalnik (scanner ). Njegove naloge so:
–
–
–
–
sintaktičnemu analizatorju posredovati osnovne leksikalne simbole
izločitev znakov, ki nimajo pomen (prazna mesta, nove vrstice, komentar)
polnitev simbolne tabele z dodatnimi informacijami
sintaktičnemu analizatorju posredovati poleg leksikalnega simbola še leksikalno vrednost oz. lexem
Zgled Primeri neformalnih opisov osnovnih leksikalnih simbolov:
Osnovni leksikalni simbol
Lexem
Neformalni opis vzorca
id
stevec, b12, pi
znak, ki mu sledijo znaki in cifre
num
3.4, 0, 2.6E+12
numerični literal
relop
<, <=, ==, !=, >, >=
relacijski operator
1.1.3
Neformalni in formalni opis vzorca
• “znak, ki mu sledijo znaki in cifre” — neformalni opis.
• Opis za realno število?
• potrebujemo formalni opis:
– regularni izrazi
3
1.2
Regularni izrazi
decreal: -?(\.\d+|\d+\.\d*)([Ee][+-]?\d+)?
hexreal: -?0[Xx](\.[A-Za-z\d]+|[A-Za-z\d]+\.[A-Za-z\d]*)([Pp][+-]?\d+)?
1. je regularni izraz
2. a je regularni izraz
3. Če sta r in s regularna izraza, potem je:
• (r)|(s) je regularni izraz — (unija)
• (r)(s) je regularni izraz — (konkatenacija)
• (r)∗ je regularni izraz — (operacija zaprtja)
• (r) je regularni izraz
Zgled
• Σ = {a, b} (abeceda)
– a|b označuje jezik {a, b}
– (a|b)(a|b) označuje jezik {aa, ab, ba, bb}
– a ∗ označuje jezik {, a, aa, aaa, . . .}
1.2.1
Regularne definicije
Regularna definicija je zaporedje poimenovanih regularnih izrazov oblike:
d1
d2
→
r1
→
r2
...
dn
→
rn
kjer:
• di so različni identifikatorji,
• ri so regularni izrazi nad Σ in predhodno definiranimi d1 · · · dn .
Zgled Opis leksikalnega simbola id:
znak
→ A|B| . . . |Z|a|b| . . . |z
cif ra
→ 1|2| . . . |9
id
1.2.2
→ znak(znak|cif ra)∗
Regularni izrazi, ki se pogosno pojavljajo
1. r+ = rr∗ (r∗ = r+ |r) (pozitivna iteracija)
2. r? = r| (opcija)
3. [abc] = a|b|c (razred znakov)
4. [a − z] = a|b| . . . |z
4
Zgled
cif ra
num
1.2.3
→ [0 − 9]
→ cif ra+ (.cif ra+ )?(E(+|−)?cif ra+ )?
Deterministični končni avtomat
Definicija: Deterministični končni avtomat je peterka M = hQ, Σ, δ, q0 , F i, kjer je:
• Q: končna množica stanj
• Σ: abeceda avtomata
• δ: parcialna funkcija, ki preslika stanje in vhodni simbol abecede Σ v novo stanje, δ : (Q × E) → Q
• qo : začetno stanje avtomata, q0 ∈ Q
• F : neprazna množica končnih stanj avtomata, F ⊂ Q
Funkcijo δ predstavimo s tabelo prehodov.
δ
+ − .
d
S
A A G B
A
G B
B
H B
G
H
H
H
1.3
Sintaktična analiza
• Naloga sint. analize je ugotavljanje strukture stavkov jezika.
• Potrebujemo neka pravila, ki povedo, kako naj povezujemo posamezne besede.
• Tej množici pravil rečemo sintaksa ali gramatika jezika.
1.3.1
Gramatika
Definicija: Gramatika G je četverka: G = hT, N, Z, P i
• T : končna množica terminalnih (končnih) simbolov
• N : končna množica neterminalnih (nekončnih) simbolov
– velja: T ∩ N = ∅
• Z: začetni simbol, Z ∈ N
• P : množica produkcij:
– končna neprazna podmnožica relacije (T ∪ N ) ∗ N (T ∪ N )∗ 7→ (T ∪ N )∗
• terminalne simbole (terminale) pišemo z malimi črkami
• neterminalne simbole (neterminale) pišemo z velikimi črkami
• elemente (T ∪ N )∗ pišemo z malimi grškimi črkami
• “iz α izpeljemo v β v enem ali več korakih”:
– α ⇒ α1 ⇒ α2 ⇒ · · · ⇒ αn ⇒ β, n > 0
• α ⇒+ β (“obstaja izpeljava iz α v β”)
• α ⇒∗ β ⇔ (α ⇒+ β ∨ α = β)
5
1.3.2
Jezik
Definicija: Jezik L, generiran iz gramatike G:
L(G) = {x | Z ⇒∗ x ∧ x ∈ T ∗ }
• Jezik je množica vseh tistih zaporedij terminalnih simbolov (oznaka: T ∗ ), ki jih lahko izpeljemo iz
začetnega simbola gramatike.
• Takšna zaporedja terminalnih simbolov imenujemo stavek jezika.
1.3.2.1
Drevo izpeljav
E
7→ E + E
E
7→ E ∗ E
E
7→ (E)
E
7→ a
Stavek a + a ∗ a ime dve drevesi izpeljav (gramatika je dvoumna).
Primer: Jezik aritmetičnih izrazov G = h{+, ∗, (, ), a} , {E, T, F } , E, P i
E
7→ E + T
E
7→ T
T
7→ T ∗ F
T
7→ F
F
7→ (E)
F
7→ a
Pokažimo, da je zaporedje terminalnih simbolov a + a ∗ a stavek jezika.
E →E+T →T +T ∗F →F +F ∗a→a+a∗a
E
|
E+T
+---------------+
T
T*F
|
+-------+
F
F
a
|
|
a
a
1.3.3
Sintaktična analiza ali razpoznavanje
• ang. parsing
• prveri, ali je neko zaporedje terminalnih simbolov stavek jezika
1.3.4
BNF (Backus-Naur Form)
• Je metajezik za opis sintakse programskih jezikov
• Metajezik uporablja simbole, ki jih imenujemo metasimboli.
• Produkcije imajo obliko:
A ::= α1 | α2 | · · · | αn
kjer velja: A ∈ N ∧ αi ∈ (T ∪ N)∗
6
Primer: Jezik aritmetičnih izrazov v BNF G = h{+, ∗, (, ), a} , {E, T, F } , E, P i
E ::= E + T | T
T ::= T * F | F
F ::= (E) | a
1.3.4.1
EBNF
Razširjena Backus-Naurova oblika vpelje metasimbola {} in []:
• iteracija: A ::= {a}
• opcja: A ::= [a]
1.3.4.2
(A ::= a A|)
(A ::= a|)
Sintaktični analizator ali razpoznavalnik (ang. parser)
• Program, ki opravlja sintaktično analizo
• Ločimo dva pristopa:
1. rezpoznavanje od zgoraj navzdol (izhajamo iz začetnega simbola. . . ) [razpoznavalnik LL(1)]
2. razpoznavanje od spodaj navzgor (izhajamo iz listov drevesa (terminalov). . . )
• Obstaja mnogo pristopov in tehnik za razpoznavanje (glej literaturo)
• Izgradnja razpoznavalnika sodi na področje prevajalnikov!
1.3.5
Razpoznavalniki LL(1)
Glede na trenutni terminalni simbol na vhodu za izpeljavo vedno izberemo pravilno produkcijo (ter tako
preprečimo vračanje (backtracking)).
Uvedemo funkciji FIRST in FOLLOW.
FIRST(α)
FOLLOW(A)
= {x | α ⇒∗ xβ, x ∈ T }
= {x | Z ⇒∗ αAβ, x ∈ FIRST(β)}
1. FIRST(a) = {a}
2. FIRST() = {}
3. FIRST(αβ) = FIRST(FIRST(α) ◦ FIRST(β))
4. FIRST(A) = FIRST(α1 ) ∪ FIRST(α2 ) ∪ . . . ∪ FIRST(αn ), če A ::= α1 | α2 | · · · | αn
5. FOLLOW(X) = FIRST(β ◦ FOLLOW(A)), če A ::= αXβ
1.3.5.1
(β . . . )
Kaj je gramatika LL(1)?
Definicija: Gramatika je LL(1), če:
1. za vsako produkcijo A ::= α1 | α2 | · · · | αn velja: ∀i, j : FIRST(αi ) ∩ FIRST(αj ) = ∅ ∧ i 6= j
2. za vse neterminale A, kjer A ⇒∗ , velja: FIRST(A) ∩ FOLLOW(A) = ∅
7
Primer:
P ::= Ac | Bd
A ::= aA | B ::= bB | FIRST(P) =
=
=
=
FIRST(A) =
=
=
=
FIRST(B) =
1.3.5.2
FIRST(Ac)∪FIRST(Bd) =
FIRST(FIRST(A)◦FIRST(c))∪FIRST(FIRST(B)◦FIRST(d))) =
{a} ∪ {c} =
{a, c}
FIRST(aA)∪FIRST() =
FIRST((FIRST(a)◦FIRST(A))∪ {} =
{a} ∪ {} =
{a, }
... = {b, }
Odpravljanje leve rekurzije
Pravilo: Levo rekurzijo v gramatiki odpravimo takole:
Produkcijo oblike:
A ::= Aα1 | Aα2 | · · · | Aαm | β1 | β2 | · · · | βn
zamenjamo z:
A ::
A0
1.3.5.3
=
β 1 A0 | β 2 A0 | · · · | β n A0
::= α1 A0 | α2 A0 | · · · | αm A0 | Levo faktoriranje
Pravilo: Levo faktoriranje:
Produkcijo oblike:
A ::= αβ1 | αβ2 | · · · | αβn
vse alternativne produkcije se pričejo z α ∈ (N ∪ T )
zamenjamo z:
A ::
A0
=
αA0
::= β1 | β2 | · · · | βn
Primer: Jezik aritmetičnih izrazov v BNF
G = h{+, ∗, (, ), a} , {E, T, F } , E, P i
E ::= T EE
EE ::= + T EE | T ::= F TT
TT ::= * F TT | F ::= (E) | a
Kako zgradimo rekurzivni navzdolnji razpoznavalnik?
Primer v jeziku C++ (del kode za dve produkciji):
8
bool E ( ) {
return T( ) && EE ( ) ;
}
bool EE( ) {
i f ( s c a n n e r −>currentToken ( ) . getLexem ( ) == "+" ) {
s c a n n e r −>nextToken ( ) ;
return T( ) && EE ( ) ;
}
return true ;
}
1.4
Semantična analiza
• Za opis semantike programskih jezikov običajno uporabljamo naravni jezik.
• Pri sintaksi imamo BNF (standard), a pri semantiki. . .
• Obstaja nekaj formalnih metod: ena izmed njih je atributna gramatika.
• Prednosti formalnih metod:
– nedvoumna določitev pomena
– avtomatiziran postopek generiranja prevajalnika oz. interpreterja
1.4.1
Atributna gramatika
Atributna gramatika je nadgradnja standarizirane kontekstno proste gramatike G, tako da vsaki produkciji
priredimo množico semantičnih funkcij.
Vsakemu neterminalu X ∈ N priredimo dve končni množici atributov:
• S(X) – pridobljeni atributi (ang. synthesized attributes)
• I(X) – podedovani atributi (ang. inherited attributes)
Velja še:
• S(X) ∩ I(X) = ∅
• I(X) = ∅ (začetni neterminal gramatike G nima podedovanih atributov)
Atributne gramatike delimo:
• atributne gramatike vrste S
• atributne gramatike vrste L
• neciklične atributne gramatike
• absolutno neciklične atributne gramatike
9
Chapter 2
Programski vzorci, programske paradigme
• Programski vzorec je način konceptualizacije, kako naj strukturiramo program, da z njim rešimo dan
problem.
2.1
Razlogi za preučevanje programskih vzorcev
• Povečana sposobnost izražanja zamisli v različnih oblikah
• Naučiti se pomembnih kriterijev za izbiro ustreznih jezikov
• Povečati zmožnost učenja novih jezikov
– Danes se od inženirjev računalništva in informacijskih tehnologij zahteva znanje več naravnih in tudi
več programskih jezikov
• Boljše razumevanje pomembnosti implementacije
– Ta predmet dopolnjuje predmet Prevajanje programskih jezikov
2.2
Domene programiranja
• Aplikacije v znanosti
– Veliko število operacij z realnimi števili (C/C++, Fortran)
• Industrijske aplikacije
– Izdelava poročil, grafov ter uporaba decimalnih števil in znakov
• Umetna inteligenca
– Manipulacija nad simboli (Lisp, Prolog)
• Sistemsko programiranje
– Učinkovitost in fleksibilnost (C, Bash)
• Internetne aplikacije
– Skupina jezikov: označevalni (HTML in XML), skriptni (PHP, JSP) in splošno namenski (Java, C#,
Python)
10
2.3
Kriteriji za ocenjevanje jezikov
• Berljivost (ang. Readability): kako enostavno je prebrati in razumeti programe
–
–
–
–
–
Enostavnost
Ortogonalnost
Znane krmilne strukture
Ustrezni podatkovni tipi in strukture
Sintaksa s smiselnimi izrazi
• Zapisljivost (ang. Writability): kako enostavno je program zapisati v programskem jeziku
– Enovstavnost in ortogonalnost
∗ Malo število konstruktov, primitivov in mala množica pravil, ki kombinirajo konstrukte in primitive
– Podpora abstrakciji
∗ Definicija in uporaba kompleksnih struktur in operatorjev na način, da se s podrobnostmi ne
ukvarjamo
– Moč izražanja
∗ Množica relativnih načinov za specifikacijo operacij
• Zanesljivost (ang. Reliability): glede na specifikacije (npr.: izvajanje podanih specifikacij)
– Preverjanje tipov (ang. Type checking)
– Upravljanje z izjemami (ang. Exception handling)
– Sklicevanje (ang. Aliasing)
∗ Prisotnost dveh ali več sklicevalnih načinov za eno in isto pomnilniško lokacijo
– Berljivost in zapisljivost
• Cena (ang. Cost): končna celotna cena
– Vzdrževanje, razvijanje, dostopnost prevajalnika, zanesljivost, produktivnost programerjev itd.
2.3.1
Drugi ocenitveni kriteriji
• Prenosljivost (ang. Portability): kako preprosto je prenesti program iz ene na drugo implementacijo
– Java se izvaja na različnih platformah (Linux, Mac OS X, Solaris, Windows)
– .NET je omejen le na nekaj platform (Windows, Linux-Mono) toda podpira več jezikov (C#, J#,
VB itd.)
• Splošnost (ang. Generality)
– Aplicirati ga je možno na obsežno področje aplikacij
• Dobra definiranost (ang. Well-definedness)
– Popolnost in natančnost uradne definicije jezika
2.4
Vpliv na načrtovanje jezikov
• Računalniška arhitektura
– Jeziki so se razvijali v osnovi za prevladujočo računalniško arhitekturo, znano kot von Neumann
arhitektura
• Metodologije programiranja
– Nove metode razvoja programske opreme (npr.: objektno orientiran razvoj programske opreme)
določajo nove programske vzorce. Novi vzorci razširijo obstoječe programske jezike in tako nastajajo
novi programski jeziki.
11
2.4.1
Vpliv von Neumann arhitekture
• Imperativni jeziki, kot je recimo C, so najbolj dominantni zaradi direktne preslikave na von Neumann
arhitekture
– Podatki in program so shranjeni v pomnilniku
– Pomnilnik je ločen od CPE
– Inštrukcije in podatki se posredujejo iz pomnilnika v CPE
int val , i , a r r a y [ 1 0 ] ;
f o r ( i = 0 ; i < 1 0 ; i ++)
v a l += a r r a y [ i ] ;
2.4.2
Izvajanje strojnega koda
• Cikel: dostaviti, dekodirati in izvršiti (na von Neumann arhitekturi)
Inicializacija programskega števca
neskončna zanka
1) dostava instrukcija na katero kaže programski števec // dostop do pomnilnika
2) programski števec se poveča za 1
3) dekodiranje inštrukcije
4) izvajanje inštrukcije // možen dostop do pomnilnika
konec zanke
2.4.3
Modeli programiranja
• Modeli 1. generacije
– Mehanizemsko programiranje: mehanski računalnik - C. Babagge
– Preklopno programiranje: ENIAC - eden prvih elektronskih računalnikov
– Zbirniško programiranje: IBM 701
• Modeli 2. generacije
– Proceduralno orientirano programiranje: procedure
– Objektno orientirano programiranje: podatkovni tipi in hierarhije
– Funkcijsko orientirano programiranje: funkcije
– Logično orientirano programiranje: logika
• Modeli 3. generacije
– Komponentno orientirano programiranje: komponente
– Aspektno orientirano programiranje: aspekti
– Omejeno orientirano programiranje: odnosi med spremenljivkami so navedeni v obliki omejitev
– Vizualno orientirano programiranje: grafično ustvarjanje programov
2.4.4
Vplivi na metodologije programiranje
• 1950 in zgodnja 1960
– Enostavne aplikacije; najbolj pomembna je bila strojna učinkovitost
• Pozna 1960
– Učinkovitost ljudi postaja pomembno; berljivost, boljše krmilne strukture
∗ Strukturirano programiranje
12
∗ Načrtovanje od zgoraj navzdol (ang. top-down) in koračni način razhroščevanja
• Pozna 1970: procesno orientirano do podatkovno orientirano
– Abstrakcija podatkov
• Srednja 1980: objektno orientirano programiranje
– Abstrakcija podatkov + dedovanje + polimorfizem
• Pozna 1990: komponentno orientirano programiranje
– Distribuirane aplikacije
• 2000: aspektno orientirano programiranje (inženirstvo programske opreme)
– Ločevanje zadev (lastnosti)
– Modularnost in enkapsulacija
2.4.5
Vrste programskih jezikov
• Imperativni (ang. Imperative)
– Osnovne značilnosti: spremenljivke, določeni so programski stavki in iteracije
– Primer: C, Pascal
• Funkcijski (ang. Functional )
– Osnova za izvajanje računanja je funkcija nad podanimi argumenti
– Primer: LISP, Scheme
• Logični (ang. Logic)
– Temelječ na določenih pravilih
– Primer: Prolog
• Objektno orientirani (ang. Object-oriented )
– Abstrakcija podatkov, dedovanje, dinamično povezovanje
• Označevalni (ang. Markup)
– Sam po sebi ni programski jezik, toda omogoča oblikovanje Web dokumentov
– Primer: XHTML, HTML
2.4.6
Kompromisi načrtovanja jezikov
• Zanesljivost / cena izvajanja
– Primer: Java pri vsakem dostopu do elementa polja preverja, ali je element dejansko del polja. Tako
se po eni strani poveča zanesljivost, po drugi strani pa se poveča cena izvajanja.
• Berljivost / zapisljivost
– Primer: APL ime močne operatorje, ki omogočajo kompleksne izračune in kompaktno zapisane
programe, po drugi strani pa programe, ki so težko berljivi.
• Zapisljivost (fleksibilnost) / zanesljivost
– Primer: C++ kazalci so zelo močni in fleksibilni toda ravno oni povzročajo nezanesljivost programov.
13
2.5
Metode implementacije
• Prevajanje (ang. Compilation)
– Program se prevede v strojni jezik
• Interpretiranje (ang. Interpretation)
– Program se interpretira s pomočjo programa, ki ga imenujemo interpreter
• Hibridna implementacija
– Kompromis med prevajanjem in interpretiranjem
2.5.1
Prevajanje
• Prevajanje visoko-nivojskih programskih jezikov v strojni jezik
• Počasno prevajanje, hitro izvajanje
• Proces prevajanja vsebuje naslednje faze:
– Leksikalna analiza (ang. Lexical analysis): preslikava znakov programa v leksikalne simbole (ang.
Tokens)
– Sintaktična analiza (ang. Synctatic analysis): razpoznava pravilnost stavkov oz. zaporedja razpoznanih leksikalnih simbolov
– Semantična analiza (ang. Semantic analysis): razumevanje stavkov in ustvarjanje vmesne kode
– Generiranje kode (ang. Code generation): generira se strojna koda (izvedljivi program)
2.5.1.1
Dodatni termini pri prevajanju
• Povezovanje in nalaganje
– Proces zbiranja sistemskih programov (knjižnic) in njihovo povezovanje v uporabniški program
• Nalaganje modula
– Izvedljivi program: združena sistemska in uporabniška koda
2.5.2
Interpretiranje
• Ni prevajanja v strojni jezik
– Izrazi (stavki) se izvajajo neposredno s pomočjo interpreterja
• Enostavnejša implementacija programov (napake v času izvajanja se enostavno in takoj prikažejo)
• Počasnejše izvajanje (od 10 do 100-krat počasnejše izvajanje v primarjavi s programi, ki so prevedeni)
• Ponavadi zahtevajo več prostora
• Pojavljajo se tudi v obliki skriptnih jezikov, ki se izvajajo znotraj spletnih brskalnikov
2.5.3
Pred-procesiranje
• Pred-procesorski makroji definirajo določeno kodo, ki jo lahko uporabljamo v drugih datotekah
• Pred-procesiranje (razširjanje makrojev) se izvaja neposredno pred prevajanjem programa
• Primeri v jeziku C: #include, #define
14
2.5.4
Programska okolja
• Množica razvojnih orodij
• UNIX (Linux)
– Grafična okolja: CDE, KDE, Gnome
• Netbeans
– Integrirano razvojno okolje za Javo
• Microsoft Visual Studio .NET
– Za programiranje v C#, Visual Basic .NET, JScript, C, C++, J#
15
Chapter 3
Tipi in spremenljivke
3.1
Uvod
• Imperativni jeziki so abstrakcije von Neumannove arhitekture
– pomnilnik (kjer se nahajajo programske spremenljivke)
– procesor (ki izvaja programske inštrukcije)
• Spremenljivke so definirane z atributi
– model tipov za jezik mora upoštevati
∗ doseg, življenski cikel, preverjanje tipov, incializacijo
∗ združljivost tipov
3.2
Spremenljivke
• Spremenljivka je abstrakcija pomnilniške celice
• Spremenljivke so lahko definirane kot šesterica atributov:
– ime
– naslov
– vrednost
– tip
– življenski cikel
– doseg
• Abstraktna pomnilniška celica – fizična celica ali nabor celic, povezanih s spremenljivko
– Ime → Tip → Naslov/Vrednost
3.2.1
Imena
• Težave pri načrtovanju imen spremenljivk:
– Največja dolžina?
– Ali so povezovalni znaki (npr. “_”) dovoljeni?
– Ali pri imenih razlikujemo med malimi in velikimi črkami, kot v C++/Javi
– Ali so posebne besede rezervirane besede ali ključne besede?
∗ rezerviranih besed ni mogoče uporabiti za imena programskih spremenljivk
• Nekatere spremenljivke nimajo imena (npr. spremenljivke v kopici); anonimni razredi v Javi
16
• Posebne besede: se uporabljajo za izdelavo bolj berljivih programov, s poimenovanjem dejavnosti, ki jih
je treba opraviti. Uporabljajo se tudi za ločevanje delov skradnje v programih.
– Ključna beseda je beseda, ki je posebna samo v nekaterih kontekstih, npr. v Fortranu:
∗ Real VarName (Real je podatkovni tip, ki mu sledi ime, zato je Real ključna beseda)
∗ Real = 3.4 (Real je spremenljivka)
– Rezervirana beseda je posebna besede, ki je ni možno uporabljati kot uporabniško določeno ime (npr.
if in int v Javi)
3.2.2
Atributi spremenljivk
• Naslov – pripadajoč pomnilniški naslov spremenljivke
– spremenljivke imajo lahko različne naslove: ob različnih časih med izvajanjem; na različnih mestih v
programu
– če se dve imeni spremenljivk lahko uporabita za dostop do iste pomnilniške lokacije, sta to vzdevka
∗ vzdevke ustvarimo prek kazalcev, referenc in C/C++ unij
∗ vzdevki so škodljivi za berljivost (bralci programa si morajo zapomniti vse vzdevke)
• Vrednost – vsebina lokacije, s katero je spremenljivka povezana
• Tip – določa razpon vrednosti spremenljivk ter določi operacije, ki so opredeljene nad vrednostmi teh
tipov
– primitivni (ali osnovni) podatkovni tipi
– uporabniško določeni števni tipi
– polja
– znakovni nizi
– asociativni seznami
– zapisi
– unije
– množice
– kazalčni tipi
3.3
Koncept povezljivosti
• primer: int a = 10;
• l-vrednost spremenljivke je njen naslov
• r-vrednost spremenljivke je njena vrednost
• povezljivost je povezava med atributom in entiteto ali med operacijo in simbolom
• čas povezovanja je čas, ob katerem se povezovanje zgodi
3.3.1
Možni časi povezovanja
• med načrtovanjem jezika – povezava simbolov za operatorje z operacijami, npr. znak + v C
• v implementaciji jezika – npr. povezava tipa za realna števila z njegovo predstavitvijo (npr. s predstavitvijo
od IEEE)
• med prevajanjem – povezava spremenljivke na tip, npr. int count;
• med nalaganjem – npr. povezava FORTRAN 77 spremenljivke s pomnilniško celico (ali statično spremenljivko v C)
• med izvajanjem – povezava nestatične lokalne spremenljivke s pomnilniško celico, npr. count = count +
5;
17
3.3.2
Statična in dinamična povezljivost
• povezava je statična, če se zgodi pred izvajanjem in ostane nespremenjena skozi ves čas izvajanja programa
• povezava je dinamična, če se prvič izvede med izvajanjem ali pa jo je možno spremeniti med izvajanjem
programa
• zgodnje napram poznemu povezovanju – veliko načrtovalskih odločitev glede jezika je odvisnih od časa
povezovanja:
– pozno – bolj prilagodljivo
– zgodnje – bolj učinkovito
– zgodnje povezovanje omogoča prevajanje, pozno omogoča interpretiranje
3.3.2.1
Statično povezovanje tipov
• Eksplicitna deklaracija je programski stavek, ki se uporablja za deklaracijo tipov spremenljivk
• Implicitna deklaracija je privzeti mehanizem za določanje tipov spremenljivk (prva pojavitev spremenljivke
v programu). FORTRAN, PL/I, BASIC, Javascript in Perl omogočajo implicitne deklaracije
– npr. var ime = “Ime” – spremenljivka tipa niz, v Javascriptu
– npr. $x (scalar), @barve (array), %preglednice (hash) – v Perlu
– prednost: lažji zapis
– slabost: zanesljivost (manj težav pri Perlu)
3.3.2.2
Dinamično povezovanje tipov
• Dinamično povezovanje tipov uporabljajo npr. Ruby, Javascript in PHP
• Izvedeno ob prireditvenem stavku, za npr. Javascript
– seznam = [2, 4.33, 6, 8];
– seznam = 17.3;
– prednost: fleksibilnost (splošnejši programski stavki)
– slabosti:
∗ visoki stroški (dinamično preverjanje tipov in interpretiranje)
∗ zaznavanje napak med prevajanjem je oteženo
3.3.3
Atributi spremenljivk
• Izpeljave tipov (ML, Miranda in Haskell). Tipi so določeni iz konteksta reference, npr. v ML:
– fun circumf(r)=3.14*r*r (*vrača realno število*)
• Povezava s pomnilniškim prostorom
– dodelitev – dodelitev pomnilniške celice iz bazena razpoložljivih celic
– sprostitev – sproščanje celic nazaj v bazen
• Življenjski cikel spremenljivke je čas, ko je ta vezana na določeno pomnilniško celico
– statično
– dinamično na skladu
– eksplicitno dinamično na kopici
– implicitno dinamično na kopici
18
3.4
Organizacija pomnilnika
• Statično
– koda in nespremenljivi podatki
• Sklad
– lokalni podatki: zapisi klicev
• Razpoložljiv pomnilnik
• Kopica
– spremenljivi podatki
3.5
Čas povezovanja spremenljivke
• Statična vezljivost
– povezava se sklene “pred” pričetkom izvedbe programa in ostane enaka do zaključka programa
– tip in naslov sta nespremenljiva
– učinkovitost: pomnilniška lokacija se lahko izračuna ob času prevajanja
– je ni možno uporabiti z rekurzijo
– primeri:
∗ vse FORTRAN 77 spremenljivke
∗ C static spremenljivke
• Dinamično na skladu
– tip je nespremenljiv, naslov je dinamičen
– neposredno podpira rekurzijo
– učinkovito podprto s skladom v času izvajanja
– ni nujno, da je učinkovito kot statična vezljivost
– primeri:
∗ lokalne spremenljivke v C podprogramih in Java metodah
• Eksplicitno dinamično na kopici
– prostor je eksplicitno dodeljen/sproščen iz pomnilniškega bazena v času izvajanja
– uporabno je za strukture s spremenljivo velikostjo (npr. povezani seznam, sklad)
– programiranje kompleksnosti za ohranitev celovitnosti (npr. viseče reference, preverjanje mej polja)
– primeri:
∗ dinamično dodeljevanje pomnilnika v C (preko malloc in free)
∗ dinamični objekti v C++ (preko new in delete)
∗ vsi objekti v Javi
• Implicitno dinamično na kopici
– pomnilniški prostor je dodeljen ob prirejanju vrednosti
– zelo fleksibilno
– zmanjšana kompleksnost programiranja
– režija v času izvajanja (preverjanja mej polja, smetar)
– primeri:
∗ vse spremenljivke v APL
∗ vsi nizi in polja v Perlu in Javascriptu
19
3.6
Smetar
• skoraj bistven za sisteme z implicitno dinamičnim dodeljevanjem prostora na kopici
• smeti : vse, kar ne izhaja iz znanih korenin
• korenine: trenutni sklad + trenutne povezave spremenljivk
3.7
3.7.1
Implementacija podatkovnih tipov
Podatkovni tipi
• Podatkovni tip sestavljajo: nabor operacij, nizkonivojska predstavitev in množica podatkovnih vrednosti
• Nabor operacij
– za int i; so to +, -, /, *, %
• Nizkonivojska predstavitev
– za int i; je z 32 biti
• Množica podatkovnih vrednosti
– za int i; je od −231 − 1 do 231 pri implementaciji z dvojiških komplementom
• Osnovni podatkovni tipi: tisti, ki niso definirani z drugimi podatkovnimi tipi
• Uporabniško definirani tipi: sestavljeni tipi, ki uporabljajo osnovne podatkovne tipe
• Abstraktni podatkovnii tipi (ADT): uporaba tipa je ločena od predstavitve in množice operacij nad vrednostmi tega tipa
– implementacija tipa je skrita
– samo vmesnik je objavljen
– primer: ADT seznam je lahko implementiran s poljem ali s povezanim seznamom
3.8
Osnovni podatkovni tipi
• Številčni
– celoštevilski : velikosti predznačnega tipa v Javi so byte, short, int, long
– s plavajočo vejico: IEEE standard 754
– decimalni : v poslovnih aplikacijah: Cobol, C# (razred Decimal), Java (razred BigDecimal). Predstavitev je bila BCD.
• Primerjava številskih tipov
– C:
∗
∗
∗
∗
∗
char, unsigned char
short int, unsigned short int
int, unsigned int
long int, unsigned long int
ni standardne implementacije, vendar daljši tipi morajo zagotavljati vsaj tolikšen razpon kot
krajši tipi
– Java:
∗ byte (1-zložni predznačen)
∗ char (2-zložni nepredznačen)
∗ short (2-zložni predznačen)
20
∗ int (4-zložni predznačen)
∗ long (8-zložni predznačen)
• logični : lahko implementiran bitno, vendar ponavadi z zlogi, pogosto kot bytes
• znakovni : ASCII ali 16-bitno kodiranje Unicode
• nizovni : osnovni v Javi, C#, Scheme, Ruby, vendar ne v nekaterih jezikih, kot C. Osnovne operacije:
– prirejanje in kopiranje
– primerjava (=, >, itd.)
– konkatenacija
– reference na podnize
– ujemanje vzorcev (z regularnimi izrazi)
3.9
Uporabniško določeni števni tipi
• Števni tip je tak tip, pri katerem je razpon možnih vrednosti moč povezati z množico pozitivnih celih
števil
• Primeri osnovnih števnih tipov v Javi:
– int
– char
– boolean
• Uporabniško določeni števni tipi:
– naštevni tipi
– intervali
3.9.1
Naštevni tipi
• Vse možne vrednosti (poimenovane konstante) so navedene v definiciji
– C#: enum dnevi (pon, tor, sre, čet, pet, sob, ned);
– Težave pri načrtovanju
∗ Ali se naštevna konstanta lahko pojavi v več kot eni definiciji tipa in če, kako se preverja tip te
konstante ob njeni pojavitvi?
∗ —
3.9.1.1
Ovrednotenje naštevnega tipa
• Pripomore k berljivosti: npr. ni nam treba kodirati dneva v tednu kot številke
• Pripomore k zanesljivosti, npr. prevajalnik lahko preveri —
3.9.1.2
Naštevni tipi v Javi
public c l a s s PrimerNastevnegaTipa {
enum mesec {Jan , Feb , Mar , Apr , Maj , Jun , Jul , Avg , Sep , Okt , Nov , Dec } ;
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
f o r ( Mesec m : j a v a . u t i l . EnumSet . r a n g e ( Mesec . Jun , Mesec . Avg ) )
System . out . p r i n t l n ( " p o l e t j e ␣ v k l j u c u j e : " + m) ;
}
}
21
3.10
Polja
• V poljih shranjujemo elemente istega tipa. Nekaj težav pri načrtovanju:
– veljavnost tipov indeksov
– izrazi za izračun indeksov in preverjanje mej
– dodeljevanje pomnilniškega prostora
– inicializacija
– ali je razrez v reže dovoljen
• Indeksni dostop je preslikava iz indeksov v elemente:
– ime_polja(seznam_vrednosti_indeksov) → element
• Sintaksa za dostop preko indeksov
– FORTRAN, PL/I in Ada uporabljajo navadne oklepaje
– večina drugih jezikov uporablja oglate oklepaje
• Možni tipi indeksov: cela števila, vrstilni tipi, naštevni tipi
3.10.1
Vezava indeksov in tipi polj
• Statični: intervali indeksov so statično vezani, tudi dodeljevanje pomnilnika je statično (pred pričetkom
izvajanja)
– prednost: učinkovitost (ni dinamičnega dodeljevanja)
–
void p r o c ( ) {
s t a t i c int A [ 1 0 ] [ 1 0 ] ;
}
• Fiksno naslavljanje na dinamičnem skladu: indeksi so statično vezani, vendar je dodeljevanje prostora na
—
–
−−−
• Dinamično na skladu: nabori indeksov so dinamično vezani, dodeljevanje prostora je prav tako dinamično
(ob času izvajanja)
– prednost: prilagodljivost (velikost polja ni potrebno vedeti pred uporabo tega polha)
–
Get ( List_Len )
declare L i s t : array ( 1 . . List_Len ) of I n t e g e r
begin
end ; ; v j e z i k u ADA
• Nespremenljivo na dinamični kopici : podobno zgornji možnosti: dodeljevanje pomnilnika je dinamično
(med časom izvajanja), vendar nespremenljivo pri dodelitvi (npr. povezava je ustvarjena ob zahtevi,
prostor je dodeljen iz kopice, ne iz sklada)
–
int s i z e ; // j a v a , C#
i f ( cond ) s i z e = 1 0 0 ;
else s i z e = 10;
int [ ] A = new int [ s i z e ∗ 2 ] ;
• Dinamično na kopici : povezava naborov indeksov in dodeljevanje prostora je dinamično in se lahko
poljubno-krat spremeni
22
– prednost: prilagodljivost (velikost polja lahko med izvajanjem programa povečamo ali zmanjšamo)
– primer:
∗
3.10.2
// C#, Java
A r r a y L i s t i n t L i s t = new a r r a y L i s t ( ) ;
...
i n t L i s t . add ( o b j e c t ) ;
Inicializacija polja
• Nekateri jeziki dovoljujejo inicializacijo ob času dodelitve prostora
– npr. C, C++, Java, C#
∗ int seznam [] = { 4, 5, 7, 83 };
– nizi znakov v C in C++
∗ char ime [] = “Janez”;
– polja nizov v C in C++
∗ char * ime [] = { “Janez”, “Marko”, “Mitja” };
3.10.3
Rezine
• Rezina je podstruktura polja, nič več kot referenčni mehanizem. Podpora v nekaterih jezikih (Fortraj 95).
– Integer, Dimension(3, 3, 3)::Cube
3.10.4
Dostop do večdimenzionalnih polj
• Dvodimenzionalna polja so lahko shranjena v pomnilniku na dva načina:
– urejena po vrsticah (večina jezikov)
– urejena po stolpcih (Fortran)
3.10.5
Deskriptorji v času izvajanja
Enodimenzionalno polje
Polje
Tip elementa
Tip indeksa
Spodnja meja za indeks
Zgornja meja za indeks
Naslov
3.10.6
Večdimenzionalno polje
Tip elementa
Tip indeksa
Število dimenzij
Nabor indeksov 1
...
Nabor indeksov n
Naslov
Asociativna polja
• Asociativno polje je neurejen zbir podatkovnih elementov, ki so indeksirani (ključ)
– Uporabniško definirane ključe moramo hraniti
• Načrtovalski vidik: Kakšna naj bo oblika referenc na podatkovne elemente?
• Perl:
– vis_temp = (“Pon” => 32, “Tor” => 33, “Sre” => 31, ...);
– za dostop do elementa uporabimo oklepaje in ključe: vis_temp{”Sre”} = 35;
23