Spremenljivke in aritmetične operacije
Aritmetične operacije in elementarne funkcije
Računalnike imamo zato, da z njimi kaj računamo. Na primer:
Produkt.java |
---|
1
2
3
4
5
| public class Produkt {
public static void main(String[] args) {
int x = 1234 * 4321;
}
} |
Ta program izračuna produkt števil 1234 in 4321. Ko ga prevedemo
in poženemo, seveda ne vidimo, kolikšen je produkt, ker program
rezultata ne izpiše ne zaslon, ampak ga shrani v spremenljivko
x:
> javac Produkt.java
> java Produkt
> |
Če bi želeli videti rezultat, bi dodali ukaz za izpis na ekran:
Produkt2.java |
---|
1
2
3
4
5
6
| public class Produkt2 {
public static void main(String[] args) {
int x = 1234 * 4321;
System.out.println(x);
}
} |
> javac Produkt2.java
> java Produkt2
5332114
> |
Program bi lahko napisali tudi takole:
Produkt3.java |
---|
1
2
3
4
5
| public class Produkt3 {
public static void main(String[] args) {
System.out.println(1234 * 4321);
}
} |
> javac Produkt3.java
> java Produkt3
5332114
> |
Kot vidimo,
Produkt3 izpiše isto kot
Produkt2,
vendar med njima obstaja bistvena razlika. Program
Produkt2shrani rezultat v spremenljivkox, medtem ko ga
Produkt3 samo izpiše na ekran.
To je pomembno, kadar rezultat potrebujemo v nadalnjem
računanju.
Računske rezultate, ki jih še potrebujemo v nadalnjem računanju,
moramo spraviti v spremenljivko.
|
V Javi (pa tudi v večini programskih jezikov) je množenje označeno
z zvezdico
*. Kakšne osnovne aritmetične operacije še
pozna Java? Naštete so v spodnji tabeli:
Aritmetične operacije |
---|
x + y | vsota |
s + t | stakni niza String s in String t |
x - y |
razlika
|
x * y |
zmnožek
|
x / y |
kvocient
|
x % y |
ostanek pri delenju
|
-x |
obratna vrednost
|
x >> k |
bitni pomik v desno za k mest (deli x z
2^k)
|
x << k |
bitni pomik v levo za k mest (množi x z
2^k)
|
x & y |
bitni 'in'
|
x | y |
bitni 'ali'
|
x ^ y |
bitni 'ekskluzivni ali'
|
~x |
bitni komplement
|
p ? x : y |
če velja p, potem je vrednost x, sicer
y |
Primerjave in logične operacije |
---|
x == y
| x je enak y (x in y sta osnovnega tipa)
|
x.equals(y)
| x je enak y (x in y sta objekta)
|
x != y
| x ni enak y (x in y sta osnovnega tipa)
|
x < y
| x je manjši od y |
x > y
| x je večji od y |
x <= y
| x je manjši ali enak y |
x >= y
| x je večji ali enak y |
p && q
|
logični 'in'
|
p || q
|
logični 'ali'
|
! p
|
logični 'ne'
|
Okrajšave |
---|
krajše | daljše |
i++
|
i = i + 1
|
i--
|
i = i - 1
|
x += y
|
x = x + y
|
x -= y
|
x = x - y
|
x *= y
|
x = x * y
|
x /= y
|
x = x / y
|
Danes bomo preizkusili le seštevanje, odštevanje, množenje,
delenje in ostanke. Preizkusimo jih s preprostim programom:
Operacije.java |
---|
1
2
3
4
5
6
7
8
9
| public class Operacije {
public static void main(String[] args) {
System.out.println(12 * 5);
System.out.println(12 + 5);
System.out.println(12 - 5);
System.out.println(12 / 5);
System.out.println(12 % 5);
}
} |
> javac Operacije.java
> java Operacije
60
17
7
2
2
> |
Torej, 12 krat 5 je 60, 12 plus 5 je 17, 12 minus 5 je 7. Kaj pa
12 deljeno s 5? Ali je res 2? Ne, ampak 2.4. Računalnik se je
zmotil! Pravzaprav se ni zmotil, ampak je uporabil
celoštevilsko delenje, ker smo delili cela števila
12 in 5. Torej: 12 deljeno s 5 je 2 (in ostane 2). Zadnja
operacija, označena z znakom "
%" je ostanek pri
delenju.
Kako pa dopovemo Javi, da želimo operacije z realnimi števili in
ne s celimi? Tako, da zapišemo števila z decimalno piko:
RealnoDelenje.java |
---|
1
2
3
4
5
| public class RealnoDelenje {
public static void main(String[] args) {
System.out.println(12.0 / 5.0);
}
} |
> javac RealnoDelenje.java
> java RealnoDelenje
2.4
> |
Pa smo dobili pričakovani rezultat. Torej,
12 je za
Javo celo število,
12.0 pa realno. Pravzaprav Java ne
pozna pravih realnih števil, ampak števila z
omejeno
natančnostjo, ki se v Javi imenujejo "
double"
(od "double floating point number"). Za večino izračunov
natančnost, ki jo ponujajo števila
double zadošča. Mi
jim bomo rekli kar "realna števila", čeprav to zares niso.
Tudi cela števila so omejena. Največje in najmanjše celo
število, s katerimi Java še zna računati sta
Integer.MAX_VALUE in
Integer.MIN_VALUE.
NajvecjaStevila.java |
---|
1
2
3
4
5
6
| public class NajvecjaStevila {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
} |
> javac NajvecjaStevila.java
> java NajvecjaStevila
2147483647
-2147483648
> |
Če prekoračimo te meje, dobimo zelo čudne rezultate, na primer:
KvadratStevila.java |
---|
1
2
3
4
5
6
| public class KvadratStevila {
public static void main(String[] args) {
int x = 1000000 * 1000000;
System.out.println(x);
}
} |
> javac KvadratStevila.java
> java KvadratStevila
-727379968
> |
To je seveda nesmiselen rezultat, saj je kvadrat celega števila
pozitiven, mi pa smo dobili negativno število.
V zvezi z računanjem s števili si torej zapomnimo:
Java pozna cela števila, tip int, in
realna števila, tip double. Oboja so
po velikosti omejena, realna števila pa imajo tudi omejeno
natančnost. V večini primerov nam glede tega ni treba
skrbeti.
Realna števila pišemo z decimalno piko, na primer 12.0,
cela števila pa brez decimalne pike, na primer 12.
|
Naloga 1
Največje in najmanjše celo število sta podatka
Integer.MAX_VALUE in Integer.MIN_VALUE v
razredu Integer, ki je del standardne knjižnice.
Katero pa je največje veljavno realno število v Javi?
[
rešitev]
Kako pa izračunamo elementarne funkcije, kot so logaritem,
eksponentna fukncija, sinus, kosinus, ipd.? Vse te funkcije so
priskrbljene v standardni knjižnici, v razredu Math.
Naloga 2
Poišči dokumentacijo o razredu Math in preglej spisek
funkcij, ki so vgrajene v Javo.
Namig
Mogoče se vam zdi, da ta vaja ni mišljena resno. Pa je, vsaj
70% mišljena zelo resno. Kot programerji se morate namreč
navaditi brskati po dokumentaciji.
[
rešitev]
Na primer, kako izračunamo kosinus 60 stopinj? (Vsi vemo da je
odgovor 0.5, zanima nas, kako se to naredi v Javi.) Preden
napišemo program, se spomnimo, da je treba pisati realna števila
z decimalno piko--torej bomo zapisali šestdeset kot
60.0 in ne kot
60.
Kosinus.java |
---|
1
2
3
4
5
6
| public class Kosinus {
public static void main(String[] args) {
double x = Math.cos(60.0);
System.out.println(x);
}
} |
> javac Kosinus.java
> java Kosinus
-0.9524129804151563
> |
Hm, rezultat bi moral biti 0.5. Kaj je narobe? Zelo težko boste
odkrili, če ne boste prebrali
dokumentacije
za Math.cos. Tam lepo piše, da mora biti kot podan
v
radianih in ne v stopinjah! V dokumentaciji tudi
piše, da obstaja metoda
Math.toRadians,
ki pretvarja iz stopinj v radiane. Oboroženi z novim znanjem
poskusimo še enkrat:
Kosinus2.java |
---|
1
2
3
4
5
6
| public class Kosinus2 {
public static void main(String[] args) {
double x = Math.cos(Math.toRadians(60.0));
System.out.println(x);
}
} |
> javac Kosinus2.java
> java Kosinus2
0.5000000000000001
> |
To je pa že bolje, čeprav ni čisto prav. Do napakice je prišlo,
ker imajo števila tipa
double omejeno natančnost.
Naloga 3
Napiši program, ki izračuna odgovor na tole vprašanje: če
sonce sveti pod kotom 42 stopinj glede na horizont, kako
dolga je senca 183 cm visokega predavatelja?
Namig
Tangens kota, pod katerim sveti sonce, je enak razmerju med višino in
senco predavatelja.
[
rešitev]
Spremenljivke
V drugem delu te lekcije bomo povedali še nekaj podrobnosti o
spremenljivkah ali variablah (angl.
"variable"). Kot že vemo, v programskem jeziku uporabljamo
spremenljivke namesto pomnilniških lokacij, prevajalnik pa
uporabo spremenljivk predela v uporabo pomnilniških lokacij. S
tem je programiranje bolj pregledno in lažje.
Prevajalnik mora vedeti, koliko pomnilnika naj rezervira za
vsako spremenljivko. Zato je treba
prvič, ko
spremenljivko omenimo, povedati kakšnega tipa je. Pravimo, da
smo spremenljivko
deklarirali:
V programskem jeziku uporabljamo spremenljivke namesto
pomnilniških lokacij.
Prvič, ko spremenljivko omenimo, jo moramo
deklarirati, kar pomeni, da povemo njen tip in začetno
vrednost:
int st = 7;
double temperatura = 14.0; |
Zaenkrat poznamo le dva tipa,
int za cela števila in
double za realna števila.
Ime spremenljivke se mora začeti s črko in je lahko sestavljeno
iz črk, številk in podčrtaja.
Ukazi v Javi so razdeljeni na
bloke. Blok se začne
z zavitim oklepajem
{ in konča s pripadajočim zavitim
zaklepajem
}. Na primer:
1
2
3
4
5
6
7
8
9
10
11
12
| {
int x = 7;
int y = 8;
if (x > y) {
int t = x;
x = y;
y = t;
}
int t = (3 * x) % y;
} |
Ta program je sestavljen iz enega velikega bloka (vrstice 1--12), v
njem pa je
vgnezden še en blok (vrstice 6--8).
Spremenljivke v Javi so
lokalne. To pomeni, da
spremenljivka obstaja le od deklaracije do zaključka bloka, v
katerem je deklaracija vsebovana. V zgornjem programu je
veljavnost spremenljivk naslednja:
spremenljivka x je veljavna v vrsticah 2 do 12
spremenljivka y je veljavna v vrsticah 3 do 12
spremenljivka t je veljavna v vrsticah 6 do 8
spremenljivka t je veljavna v vrsticah 11 do 12
Zunaj območja veljavnosti spremenljivke preprosto ni! Ko
prevajalnik prevede program, rezervira lokacijo v pomnilniku za
vsako spremenljivko, vendar samo začasno. Preden spremenljivka
postane veljavna in ko ni več veljavna, lahko prevajalnik porabi
isto lokacijo za kako drugo spremenljivko.
Iz zgornjega programa se naučimo še nekaj: v vrsticah 6--8 je
veljavna spremenljivka t, v vrsticah 11--12 pa
druga spremenljivka, ki se tudi imenuje t.
To je seveda mogoče, ker se območji veljavnosti za ti dve
spremenljivki ne prekrivata. Zapomnimo si, da sta to povsem
različni spremenljivki.
Zapomnimo si:
Spremenljivke v Javi so lokalne.
Spremenljivka je veljavna od deklaracije do konca bloka,
v katerem je deklarirana.
Različne spremenljivke imajo lahko isto ime, če se
njihova območja veljavnosti ne prekrivajo.
Naloga 4
Janezek je napisal program, ki v spremenljivko
z
shrani manjšo od spremenljivk
x in
y. Na
koncu je dodal še ukaz, ki izpiše njeno vrednost na zaslon,
da bi videl, ali program pravilno deluje.
Janezek.java |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| public class Janezek {
public static void main(String[] args) {
int x = 7;
int y = 8;
if (x < y) {
int z = x;
}
else {
int z = y;
}
System.out.println(z);
}
} |
Ko je program prevedel, je dobil tole sporočilo o napaki:
> javac Janezek.java
Janezek.java:13: cannot resolve symbol
symbol : variable z
location: class Janezek
System.out.println(z);
^
1 error |
Pojasni, kaj je narobe z Janezkovim programom.
Metka je sklepala, da je Janezek naredil napako, ker je
dvakrat deklariral spremenljivko
z, zato je njegov
program popravila takole (sprememba je v 10. vrstici):
Metka.java |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| public class Metka {
public static void main(String[] args) {
int x = 7;
int y = 8;
if (x < y) {
int z = x;
}
else {
z = y;
}
System.out.println(z);
}
} |
Ali zna Metka programirati bolje od Janezka?
Popravi Janezkov program.
Namig
Spremenljivko z je treba deklarirati pred
stavkom if. Če jo deklariramo znotraj vgnezdenega
bloka, bo veljavna samo v tistem bloku.
[
rešitev]
Naloga 5
V spremenljivki
int k je dano nenegativno število.
Napiši program, ki na zaslon izpiše
Miha ima k
limon., pri čemer pa mora biti stavek slovnično
pravilen, se pravi:
Miha ima 0 limon.
Miha ima 1 limono.
Miha ima 2 limoni.
Miha ima 3 limone.
Miha ima 4 limone.
Miha ima 5 limon.
Miha ima 6 limon.
(in tako naprej)
Kaj naredi tvoj program, če je
k = 101?
Namig
Uporabi kombinacijo
if-
else takole:
1
2
3
4
5
| if (k == 0) { nic limon }
else if (k == 1) { ena limona }
else if (k == 2) { dve limoni }
else if (k == 3 || k == 4) { tri ali stiri limone }
else { pet ali vec limon } |
Naloga 6
V spremenljivki int x je dana količina denarja v
tolarjih, ki bi ga radi izplačali s kovanci po 10, 5, 2 in 1
tolar. Na primer, če je x = 38, potem bi izplačali
tri kovance po 10, enega po 5, enega po 2 in enega za 1 tolar.
Napiši program, ki izračuna, koliko kovancev vsake vrste
moramo izplačati. Število kovancev vsake vrste naj shrani v
spremenljivke int k10, int k5, int
k2, in int k1.
Program naj na koncu še izpiše na zaslon, koliko kovancev
vsake vrste je treba izplačati.
Namig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| public class Denar {
public static void main(String[] args) {
int k = tu vstavi zacetno vrednost;
int k10, k5, k2, k1;
tu napisi svoj program
System.out.print(k + " tolarjev = ");
System.out.print(k10 + " kovancev za 10 + ");
System.out.print(k5 + " kovancev za 5 + ");
System.out.print(k2 + " kovancev za 2 + ");
System.out.println(k1 + " kovancev za 1 tolar.");
}
} |