Prvi koraki v Javi
Programiranje je za ene znanost, za
druge umetnost, za večino
programerjev pa je obrt, s katero se preživljajo. V teh lekcijah
bo poudarek predvsem na obrti programiranja, torej na praktičnih
osnovah. Velik del snovi je podan v obliki primerov, s katerimi
se sreča vsak programer.
Nobene obrti se ne da naučiti brez prakse in tako je tudi s
programiranjem. Zato lekcije vsebujejo veliko vaj, ki jih
rešujte sproti. Vse vaje so opremljene z namigi in rešitvami.
Pomembna načela in pravila programiranja so izpostavljena kot
slogani, takole:
Vaja dela mojstra. |
Skratka, programirati se boste naučili le v potu svojega obraza.
Računski postopki
Preden začnemo programirati računalnik, se naučimo zapisati
računske postopke z diagrami poteka. Snov bo
razložil predavatelj na predavanjih, nato pa bomo naredili nekaj
vaj.
Naloga 1
Sestavi diagrame poteka za naslednje računske postopke:
- Postopek, ki ima vedno isti rezultat 5.
- Postopek, katerega izhod je enak vhodu.
- Postopek za zamenjavo vrednosti dveh spremenljivk.
- Posopek, katerega izhod so stotice vhodnega števila.
- Postopek ki ugotovi ali je dano število deljivo s 6 in ni deljivo s 5.
- Postopek za reševanje linearne enačbe a x + b = 0.
- Postopek za izračun absolutne vrednosti realnega števila.
- Postopek za izbiro večjega od dveh števil.
- Postopek za izbiro največjega od treh števil.
- Postopek za zamenjavo števk dvomestnega števila (npr. vhod=27, izhod=72).
- Postopek za reševanje kvadratne enačbe a x2 + b x + c = 0 (Najprej samo za realni rešitvi, nato pa dovolimo še kompleksne.)
- Postopek za ugotavljanje prestopnega leta.
- Vhodni podatek je količina denarja v tolarjih, ki bi ga radi izplačali s kovanci po 10, 5, 2 in 1 tolar. Na primer, če je znesek enak 38 tolarjev, potem bi izplačali tri kovance po 10, enega po 5, enega po 2 in enega za 1 tolar. Opiši postopek, ki izračuna, koliko kovancev vsake vrste moramo izplačati.
Kako deluje računalnik in kako se izvajajo programi
Povejmo na kratko nekaj o tem, kako deluje računalnik, da si
bomo lahko predstavljali, kaj se zgodi, ko poženemo program
napisan v Javi.
Računalnik, kakršnega boste uporabljali, je sestavljen iz nekaj
komponent. Tukaj je zelo poenostavljena slika:
Srce računalnika je procesor. Ta je povezan s
pomnilinikom, diskom, monitorjem in tipkovnico, ter z vsemi
ostalimi deli računalnika. Puščice ponazarjajo smer
komuniciranja: procesor lahko bere in piše na disk in pomnilnik,
iz tipkovnice samo bere tipke, ki so pritisnjene, na ekran pa
samo zapisuje.
Procesor izvaja zelo preproste ukaze, kot so na primer:
- INC (135): povečaj za ena število, ki je zapisano v pomnilniku na lokaciji 135.
- MOV BC, (12): preberi število, ki je zapisano na pomnilniški lokaciji 12 in ga shrani v register BC.
- JZ A, 17: če je v registru A število 0, potem izvedi ukaz, ki je zapisan v pomnilniški lokaciji 17.
- OUT (32), 65: na komunikacijski kanal 32 pošlji kodo 65 (to bi lahko na primer pomenilo, da naj se na zaslonu izpiše črka s kodo 65).
Taki ukazi se imenujejo zbirna koda (angl. assembly code). V
zbirni kodi je zelo težko pisati večje programe, saj mora program sam
paziti, da pravilno uporabi pomnilniške lokacije, zapomniti si mora
kaj je shranjeno na posameznih lokacijah, ipd. Kar je pomembno pri
vsem tem je tole:
Vse računanje, ki se dogaja v računalniku, opravi procesor tako,
da bere in piše po pomnilniku ter izvaja preproste aritmetične
operacije.
|
Kar želim poudariti je, da so tipkovnica, ekran in disk samo dodatki,
ki naredijo računalnik uporaben. Brez teh dodatkov bi lahko še vedno
izvajali programe, le da ne bi nikoli videli, kaj se je zračunalno,
saj bi bili vsi rezultati shranjeni v pomnilniku, do katerega pa
nimamo dostopa! Zato je računalnik opremljen z ekranom, na katerega
lahko procesor izpiše sporočila in riše slike. S tipkovnico in miško
je uporabniku omogočeno, da vpliva na potek programa (seveda, samo v
primeru, da bere podatke s tipkovnice in miške ter ustrezno reagira).
Ker programov ne želimo pisati v zbirni kodi, bomo uporabili
programski jezik. Programski jezik sestoji iz ukazov in raznih
konstruktov, ki naredijo programiranje bolj prijetno. Osnovni postopek
programiranja te takšen:
- V programskem jeziku napišemo program.
- Prevajalnik prevede program v zbirno kodo. Če je program napisan nepravilno, prevajalnik javi napako, ki jo moramo odstraniti, da se bo program uspešno prevedel.
- Prevedeni program lahko nato poženemo diretkno na procesorju.
Ukazi, ki jih pišemo v programskem jeziku so bolj "abstraktni". Na
primer (zdaj se ti še ni treba zapomniti vseh ukazov, ki so našteti
tukaj):
- int starost = 12;
to je deklaracija spremenljivke starost z začetno vrednostjo 12. V zbirni kodi lahko naslavljamo samo pomnilniške lokacije, ki so oštevilčene. Če torej naš program potrebuje lokacijo, v katero bo shranil celo število, moramo sami paziti, da izberemo primerno lokacijo, ki je ne uporablja noben drug del programa, kar je nadležno. Programski jezik nam omogoča, da namesto pomnilniških lokacij uporabljamo spremenljivke s smiselnimi imeni, kot je na primer starost ali koordinata_x. Ko prevajalnik prevede program v zbirno kodo, predela spremenljivke v posamezne pomnilniške lokacije. - System.out.println("Lep pozdrav");
to je ukaz za izpis sporočila Lep pozdrav na zaslon. Če bi hoteli doseči isto v zbirni kodi, bi morali napisati ukaz za izpis vsake posamezne črke, ali še huje, za izpis posameznih pik, iz katerih so črke sestavljane! - if (starost < 12) { x = 6; } else { x = 7; }
to je pogojni ukaz, ki pomeni "če je vrednost spremenljivke starost manjša od 12, potem nastavi spremenljivko x na 6, sicer nastavi spremenljivko x na 7." V zbirnem jeziku bi morali napisati nekaj takega kot:1 2 3 4 5 6
MOV A, 12 ; nalozi 12 v register A SUB (1284), A ; odstej register A in lokacijo 1284 JRN 3 ; skoci za 3 ukaze naprej, ce rezultat ni negativen MOV (4955), 6 ; nalozi 6 v lokacijo 4955 JR 2 ; skoci za 2 ukaza naprej MOV (4955), 7 ; nalozi 7 v lokacijo 4955
Predpostavili smo, da je prevajalnik za spremenljivko starost rezerviral lokacijo 1284, za spremenljivko x pa lokacijo 4955.
Na vajah boste napisali nekaj zelo preprostih programov in se
pomenili, kako bi jih prevajalnik prevedel v zborno kodo.
Java
Uporabljali bomo programski jezik Java, ki so ga razvili pri Sun Microsystems. To je moderen
programski jezik, ki se je v zadnjem desetletju zelo razširil v svetu
računalništva. Java je opremljena z bogato standardno knjižnico
programskih struktur in funkcij (za delo z datotekami, za dostop do
podatkovnih baz, za mrežne povezave, hkratno izvajanje več programov,
grafične aplikacije, aplikacije vgrajene v brskalnike, itn.) V
začetnem tečaju programiranja ni časa, da bi predelali vse, kar Java
ponuja. A pravzaprav sploh ne bi bilo smiselno učiti se na pamet, kaj
vse ponuja Javina standardna knjižnica, saj tega dobri programerji ne
počnejo. Standardna knjižnica je dobro dokumentirana.
Kadar potrebujemo orodje, za katerega se zdi, da bi lahko že bilo v
knjižnici, se splača brskati po dokumentaciji.
Programer uporablja dokumentacijo in vsa orodja, ki so mu na voljo.
|
Zato se domenimo takole: če v standardni knjižnici najdete rešitev
kake vaje, to ni le veljavna rešitev, ampak celo najboljša. To pravilo
velja tudi za domače naloge, kolokvije in izpite. Če vajo rešite "na
roko", se boste seveda tudi kaj naučili, a za začetek je bolj
pomembno, da se naučite reševati probleme tako, kot jih rešujejo
programerji v praksi.
Pa gremo kar na delo. Najprej moramo poskrbeti, da imate na
računalniku inštalirano Javo in urejevalnik teksta. Ne bomo se
spuščali v podrobna navodila, kako se inštalira Java. Javo in navodila
za inštalacijo dobite tukaj. Če se vam zatakne,
prosite za pomoč koga, ki že zna uporabljati Javo. Predpostavili bomo
tudi, da znate uporavljati urejevalnik teksta kot je TextPad ali Emacs in da znate poganjati programe
z ukazne vrstice.
Med programerji velja tradicija, da je prvi program, ki ga napišejo,
ko se učijo nov programski jezik, programček, ki izpiše "Hello,
world!". V urejevalniku besedila napišite datoteko
HelloWorld.java z naslednjo vsebino:
HelloWorld.java | |
---|---|
1 2 3 4 5 | public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, world!"); } } |
Pomembno je, da upoštevate velike in male črke. Številk na levi ne
vpisujte, te le označujejo posamezne vrstice. Programov in ostalih
datotek, ki so prikazane tu, vam ni treba prepisovati na roko. Dobite
jih tako, da kliknete na naslov
datoteke.
Vsak program napisan v Javi je treba prevesti z Javinim prevajalnikom
javac (angl. "javacompiler"), ki preveri, ali
je program napisan po pravilih programskega jezika Java, in ga prevede
v t.i. "byte kodo" (angl. "bytecode"). V ukazni vrstici izvedemo:
C:\> javac HelloWorld.java C:\> |
Če gre vse po sreči, prevajalnik uspešno prevede program in ga v
prevedeni obliki shrani v datoteko HelloWorld.class. Program
lahko sedaj poženemo z Javinim interpretejem java:
C:\> java HelloWorld Hello world! C:\> |
Bravo! Vaš prvi program. (Če vam ne uspe pognati prvega programa, je
verjetno prišlo do kake napake pri inštalaciji Jave. V tem primeru
poiščite pomoč koga, ki zna uporabljati Javo.) Zapomnimo si osnovni
postopek prevajanja programov v Javi:
- Java program shranimo v datoteko s končnico .java.
- Program prevedemo s prevajalnikom javac.
- Prevedeni program se shrani v datoteko s končnico .class.
- Program poženemo z interpreterjem java
Program torej napišemo, prevedemo in poženemo. In to je vse? Vsak
programer vam bo povedal, da gre v resnici drugače: program napišemo,
poženemo prevajalnik, ta javi napako, ki jo odpravimo, še enkrat
poženemo prevajalnik, ki javi naslednjo napako, itn. Ko navsezadnje
uspešno prevedemo program in ga poženemo, ta ne deluje tako, kot smo
to načrtovali. Sedaj se prične iskanje logičnih napak. To so
take napake, ki jih prevajalnik ne more odkriti (na primer, v programu
za izračunavanje plač po pomoti delimo s koeficienti namesto, da bi
množili). Z več ali manj potrpljenja odpravimo vse napake (oziroma
tiste, ki smo jih našli!) in končno imamo delujoč program.
Kako odpravljamo napake? S potrpežljivostjo, izkušnjami in tako, da
skrbno preberemo sporočila, ki jih izpiše prevajalnik.
Odpravljanje napak je sestavni del programiranja,
zato programer skrbno prebere sporočila o napakah.
|
Oglejmo si to na primeru. Denimo, da ste pretipkali program
HelloWorld.java in da dobite takole sporočilo, ko ga
prevedete:
C:\> javac HelloWorld.java HelloWorld.java:1: Public class HelloWolrd must be defined in a file called "HelloWolrd.java". public class HelloWolrd { ^ 1 error C:\> |
Prevajalnik je javil napako v prvi vrstici datoteke
HelloWorld.java, ko je izpisal "HelloWorld.java:1:".
To ne pomeni, da je napaka res v prvi vrstici, ampak da jo se
je prevajalnik prvič zavedel, da je nekaj narobe, ko je prevajal prvo
vrstico! Ponavadi je napaka res v vrstici, ki jo javlja prevajalnik,
ali pa v kaki bližnji vrstici.
Kaj pa pravi sporočilo o napaki? Prevedeno v slovenščino se glasi:
Javni razred HelloWolrd mora biti definiran v datoteki
"HelloWolrd.java".
Označeno je tudi mesto, na katerem se je prevajalnik ustavil, to je na
besedici "HelloWolrd". Nekaj je torej narobe s to besedico.
Prevajalnik trdi, da je ime datoteke napačno. Kaj se dogaja? Če
pozorno pogledamo, vidimo, da piše "HelloWolrd" namesto "HelloWorld".
Zatipkali smo se--to je vse. Prevajalnik pa je javil, da je napačno
ime datoteke, ker pač ne ve, ali smo se zatipkali pri imenu datoteke
ali v programu.
Naloga 2
Denimo, da smo dobili tole sporočilo o napaki pri prevajanju
HelloWorld.java:
C:\> javac HelloWorld.java HelloWorld.java:3: String not terminated at end of line. System.out.println("Hello, world!\n); ^ HelloWorld.java:4: ')' expected. } ^ 2 errors C:\> |
Kaj je narobe?
Prvo lekcijo zaključimo z razlago programa HelloWorld.java.
Vsak Java program sestoji iz enega ali več razredov (angl
"class"). Razred je zaključena celota, ki vsebuje podatke in metode,
ki sestavljajo zaključeno celoto. Na primer, če bi pisali program za
risanje likov, bi ga verjetno razdelili na razrede kot so
Trikotnik, Krog in Kvadrat. Vsak razred bi
vseboval podatke, ki določajo dani lik. Za krog bi to bile koordinate
središča in polmer, za kvadrat pa središce, dolžina stranice in nagib.
Java pozna objekte, ki so posamezni primerki razredov. Vsak
objekt pripada nekemu razredu. Na primer, Krog(0.2, 1.7, 2.3)
bi bil primer objekta, ki pripada razredu Krog (središce je v
točki (0.2, 1.7), polmer je 2.3). Pravimo, da je Java objektni
programski jezik (angl. "object oriented"). Zaenkrat je to vse,
kar bomo povedali o objektih.
V našem primeru imamo samo en razred, ki se imenuje
HelloWorld. Razred mora biti shranjen v datoteki z istim
imenom in s končnico .java, torej HelloWorld.java.
Razred definiramo takole:
public class HelloWorld { ... } |
Med zavitim oklepaji definiramo podatke in metode, ki spadajo v ta
razred. Za zdaj bomo preskočili pomen besedice public.
Razred HelloWorld vsebuje definicijo metode main, ki
je definirana takole:
public static void main(String[] args) { System.out.println("Hello, world!"); } |
Ko zaženemo program, Java interpreter vedno pokliče metodo z imenom
main. Za zdaj se ne ozirajmo na pomen besedic public
in static, povejmo le, da so v tem primeru obvezne. Besedica
void (angl. "prazen") pomeni, da metoda main ne
vrača nobenega rezultata (izpis sporočila "Hello, world!" na ekran ni
rezultat, ampak učinek), main je ime metode, "String[]
args" pa določa, da metoda main sprejme en argument, ki
se imenuje args in je tabela nizov. Njegov pomen bomo
razložili bolj podrobno kasneje.
Metoda main vsebuje en sam ukaz, System.out.println("Hello,
world");. To preberemo takole: izvedi metodo println na
objektu out iz razreda System z argumentom
"Hello, world". Razred System je del standardne
knjižnice. V njem je definiran objekt out, ki se uporablja za
izpis sporočil na ekran. Ta objekt ima metodo println, ki
izpiše dano sporočilo in postavi izpis v novo vrstico.
Kako izvemo vse to? Tako, da pogledamo v dokumentacijo o razredu
System in objektu out.
Naloga 3
Poišči dokumentacijo o razredu System,
objektu System.out in metodi println.
Katera metoda v objektu System.out se uporablja za izpis na
ekran brez pomika v novo vrstico?
Ponovimo:
- Java program sestoji iz enega ali več razredov.
- Razred je zaključen del programa, ki vsebuje podatke in metode.
- Razred mora biti v datoteki z istim imenom in s končnico .java.
- Ko poženemo program, se izvede metoda main.
Naloga 5
Spremeni naslednja navodila v ukaze v Javi in napiši program
Brezveze.java
, ki te ukaze izvede:
- Deklariraj celoštevilčno spremenljivko
x
z začetno vrednostjo12
. - Deklariraj celoštevilčno spremenljivko
y
z začetno vrednostjo-715
. - Deklariraj celoštevilčno spremenljivko
z
z začetno vrednostjo0
. - Nastavi
z
na vsoto spremenljivkx
iny
. - Odštej 7 od
x
. - Nastavi
y
na produktx
inz
.
Naloga 6
V Javi poznamo pogojni stavek:
Pomen tega ukaza je: "če velja pogoj
if (p) { A; } else { B } |
p
potem izvedi
ukaz A
, sicer izvedi ukaz B
". Ukaza
A
in B
lahko sestojita iz večih ukazov
(zato sta zapisana vsak znotraj svojih zavitih oklepajev).
Denimo, da imamo celoštevilčne spremenljivke
x
,
y
in z
. Vrednost z
bi radi
nastavili na vrednost manjše od spremenljivk x
in
y
. Na primer, če je x
enako 17 in
y
enako 8, potem naj se z
nastavi na 8,
ker je 8 < 17.
Zapiši pogojni stavek, ki to naredi. Napiši program
Manjsi.java
, v katerem so najprej deklarirane
spremenljivke x
, y
in z
nato pa
se izvede tvoj pogojni stavek. Preizkusi program za različne
začetne vrednosti spremenljivk x
in y
.
(Ker program ničesar ne izpiše na zaslon, seveda ne boš
vedel, kaj se je dejansko izračunalo--vseeno pa se bo
izračunalo.)
Povej, kako se tvoj program izvede, če imata
x
in
y
enako vrednost.
Naloga 7: Menjava dveh spremenljivk
Pogost opravek v programiranju je menjava vrednosti dveh spremenljivk.
Denimo, da imamo deklarirani dve celoštevilski spremenljivki
Kaj se zares zgodi, ko se izvedeta ta ukaza?
x
in y
. Programerji začetniki pogosto
mislijo, da se njuni vrednosti zamenja takole:
x = y; y = x; |
Kako se zamenja vrednost dveh spremenljivk? Namig: uporabi
tretjo, pomožno spremenljivko.