Ohjelmoinnin peruskäsitteet:

Luku C
Muuttujat ja tietotyypit

  1. Muuttuja
  2. Javan tietotyypit
  3. Lausekkeet
  4. Taulukot

1. Muuttuja

Korttiprosessorissa muuttuja kuvattiin paikkana, johon saa asettaa kortin. Muuttuja kuvattiin käännetyllä kortilla:

ABC

Korttiprosessorissa muuttuja sai olla tyhjä (määrittelemätön), kätketty tai paljastettu. Muuttujalla voi myös olla tyyppi, esimerkiksi hertta, ruutu, risti tai pata.

Java-ohjelmointikielen muuttujat ovat paljolti samanlaisia. Ne ovat ainoita arvojen talletuspaikkoja Java-ohjelmassa (tai sovelmassa). Muuttujalle annetaan aina tyyppi, joka määrittelee, millaisia arvoja se voi sisältää. Muuttuja voi olla määrittelemätön, jos siihen ei vielä ole asetettu arvoa. Muuttuja on tavallaan aina kätketty ellei ohjelma käytä sitä lausekkeessa.

Muuttujan määrittely

Muuttuja määritellään lauseella, jossa mainitaan muuttujan tyyppi, nimi ja mahdollinen alkuarvo. Esimerkiksi kokonaislukumuuttuja luku alkuarvolla 0 määritellään lauseella

int luku = 0;

Tyypin nimi int tarkoittaa, että muuttujaan saa tallettaa vain kokonaislukuarvoja.

Muuttujan nimi voi sisältää kirjaimia, numeroita tai alaviivoja (_). Se ei kuitenkaan saa alkaa numerolla. Vaikka Java sallii periaatteessa kaikkien kirjaimien käytön, on parasta pitäytyä kirjaimissa a-z ja A-Z, ellei käytä Unicode-merkistöä koodin kirjoittamisessa.

Samassa lauseessa voi määritellä useita saman tyyppisiä muuttujia pilkulla eroteltuna (huomaa: muuttuja apu on ilman alkuarvoa):

int luku = 0, lkm = 13, apu;

Arvon sijoittaminen muuttujaan

Korttiprosessorissa on mahdollista asettaa kortti muuttujaan pakasta tai toisesta muuttujasta. Sama tehdään Java-ohjelmassa sijoituslauseella. Sijoituslauseen muoto on

muuttuja = lauseke;

Siinä muuttujan arvoksi tulee lausekkeen tulos. Yksinkertaisin lauseke on vakioarvo eli literaali. Sijoitetaan muuttujaan luku kokonaisluku 100:

luku = 100;

Lauseke voi olla myös muuttuja, eli esimerkiksi lauseessa

apu = luku;

muuttuja apu saa myös arvokseen 100. Muuttujan luku arvona säilyy edelleen 100, joten kysymys on kopioinnista eikä siirrosta. Muuttujaa käsitellään eri tavalla sijoituslauseen eri puolilla. Sijoitusoperaattorin vasemmalla puolella sitä käsitellään muuttujana ja oikealla puolella arvona.

Korttiprosessorissa käytetty esimerkki kahden muuttujan sisällön vaihtamisesta voidaan kirjoittaa kokonaislukumuuttujille a ja b seuraavasti:

int a = 10, b = 5;

int apu = a;
a = b;
b = apu;

Muuttujan arvon tulostaminen ja syöttäminen

Muuttujan arvo on varsin helppoa tulostaa terminaaliin. Tavalliset muuttujat (perustietotyyppiä) voi suoraan antaa parametriksi funktioille System.out.print ja System.out.println. Esimerkiksi koodi

int x = 100, y = 200;

System.out.print("Piste on (");
System.out.print(x);
System.out.print(",");
System.out.print(y);
System.out.println(").");

tulostaa terminaaliin

Piste on (100,200).

Tämä on kuitenkin hankala (pirkä) tapa tulosta tietoja, varsinkin monimutkaisia muuttujien ja merkkijonojen yhdistelmiä. Lyhyempi tapa käyttää hyväkseen operaattoria + (plus), jolla voi yhdistellä merkkijonoja muiden tietojen kanssa. Esimerkiksi edellinen voidaan kirjoittaa myös

int x = 100, y = 200;

System.out.println("Piste on (" + x + "," + y + ").");

Ohjelmista tulee hyödyllisiä usein vasta silloin, kun käyttäjä pääsee määräämään muuttujien alkuarvoja. Tätä kutsutaan usein tietojen syöttämiseksi. Yksinkertaisin tapa syöttää tietoja Java-sovellukseen on käyttää komentoriviä.

Komentorivien käyttöä esiteltiin jo aiemmin. Siinä käsiteltiin kuitenkin vain merkkijonoja. Ohjelma saa komentorivit merkkijonoina args[0], args[1], args[2],... Jos tieto halutaan käyttää esimerkiksi kokonaislukuna int, se pitää muuntaa. Esimerkkinä ohjelma "Summa" (tiedostossa "Summa.java"), joka laskee yhteen komentorivillä annetut luvut.

   1:class Summa
   2:{
   3:   public static void main(String[] args)
   4:   {
   5:      int a = Integer.parseInt(args[0]);
   6:      int b = Integer.parseInt(args[1]);
   7:      int summa = a + b;
   8:      System.out.println("  " + a + " + " + b + " = " + summa);
   9:   }
  10:}

Ohjelmassa komentoriviltä saadut tiedot muunnetaan kokonaisluvuiksi funktiolla Integer.parseInt. Tämä palauttaa kokonaisluvun, jos annettu tieto on mahdollista muuttaa kokonaisluvuksi. Ohjelma käännetään ja sitä käytetään seuraavalla tavalla:

C:\java> javac Summa.java

C:\java> java Summa 12 67
  12 + 67 = 79

C:\java>

Ohjelmassa ei ole virheenkäsittelyä, joten väärä käyttö aiheuttaa poikkeuksen:

C:\java> java Summa 5
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
        at Summa.main(Summa.java:6)

C:\java> java Summa a b
Exception in thread "main" java.lang.NumberFormatException: a
        at java.lang.Integer.parseInt(Integer.java:426)
        at java.lang.Integer.parseInt(Integer.java:476)
        at Summa.main(Summa.java:5)

C:\java>

Tehtävä C1: Tee ohjelma "Tulo", joka laskee komentoriviltä saamiensa kahden luvun tulon edellisen esimerkin mukaan.

2. Javan tietotyypit

Javan tärkeimmät tietotyypit on kuvattu seuraavassa taulukossa. Sarake muunnos kertoo, kuinka merkkijono m muutetaan kyseisen tyyppiseksi (jos se on mahdollista).

Tyyppi Kuvaus Arvot Muunnos
int Kokonaisluku -231, ..., 0, ..., 231-1 Integer.parseInt(m)
float ja double Liukuluku Float.parseFloat(m), Double.parseDouble(m)
boolean Totuusarvo, tosi/epätosi true tai false Boolean.valueOf(m).booleanValue();
char Merkki Unicode-merkistön merkit m.charAt(n)
String Merkkijono Merkeistä char koostuvat jonot

Yksinkertaiset tyypit

Kokonaislukutyyppi on int. Sillä voi esittää lukuja välillä -231 ... 231-1.

Kokonaislukuja voi esittää kolmella tavalla:

Näistä ensimmäinen on luonnollisesti tavallisin.

Liukulukutyyppejä on kaksi: float ja double. Näistä jälkimmäinen on tarkempi ja pystyy esittämään suurempia (ja pienempiä) lukuja. Tyyppi double on suositeltavampi, koska esimerkiksi valmiit funktiot (Math.sqrt(), Math.sin(), ...) käyttävät sitä.

Liukuluvun (double-tyyppisen) voi esittää seuraavilla tavoilla:

18.0 18. 1.8e1 .18E2

Jos halutaan esittää float-tyyppinen luku, pitää sen perään asettaa kirjain 'f' tai 'F', eli

18.0f 18.F 1.8e1f .18E2F

Esimerkkinä ohjelma, joka laskee ympyrän pinta-alan, kun sille annetaan ympyrän säde. Tiedostossa "YmpyranAla.java":

1:class YmpyranAla {
2:  
3:  public static void main(String[] args) {
4:    double sade = Double.parseDouble(args[0]);
5:    double ala = Math.PI * sade * sade;
6:    System.out.println("Ympyrän ala on " + ala);
7:  }
8:}

Käännetään ja ajetaan ohjelma:

C:\java> javac YmpyranAla.java

C:\java> java YmpyranAla 1
Ympyrän ala on 3.141592653589793

C:\java> java YmpyranAla 2
Ympyrän ala on 12.566370614359172

C:\java>

Tehtävä C2: Ympyrän kehän pituus lasketaan tutusti 2*PI*r. Tee ohjelma, jolle annetaan ympyrän säde ja joka tulostaa ympyrän kehän pituuden. Katso mallia edellisestä esimerkistä.

Yksittäisiä merkkejä varten on olemassa tyyppi char. Se perustuu Unicode-merkistöön, jolla voi esittää suoraan 65535 merkkiä ja erityisellä koodaustavalla vielä enemmän.

Merkkivakio esitetään heittomerkkien sisällä, esimerkiksi 'a'. Kenoviivan \ avulla on mahdollista esittää tiettyjä erikoismerkkejä:

'\udddd' Unicode-merkki, jonka koodi heksadesimaalimuodossa on dddd (jokainen d on välillä 0-9A-F)
'\n'Rivin vaihto (\u000A)
'\t'Tabulaattori (\u0009)
'\\'Kenoviiva (\u005C)
'\''Heittomerkki (\u0027)
'\"'Lainausmerkki (\u0022)

Merkkijonot

Merkkijonotyyppi on String. Merkkijonovakio esitetään lainausmerkkien sisällä. Aiemmin kuvatut merkkien erikoiskoodit toimivat myös merkkijonoissa. Esimerkiksi koodi

String rivit = "-\trivi\t1\n-\trivi\t2\n-\trivi\t3\n";
System.out.println(rivit);

tulostaa terminaaliin (tabulaattorin leveys 8 merkkiä)

-       rivi    1
-       rivi    2
-       rivi    3

Merkkijonomuuttujiin voi soveltaa useita hyödyllisiä metodeja. Alla on lueteltu niistä hyödyllisimmät (merkkijonomuuttujan nimenä s):

MetodiKuvaus
s.length() Merkkijonon merkkien lukumäärä
s.toLowerCase() Merkkijono muutettuna pieniksi kirjaimiksi
s.toUpperCase() Merkkijono muutettuna isoiksi kirjaimiksi
s.trim() Välilyönnit poistettu merkkijonon alusta ja lopusta
s.charAt(n) Merkkijono n:s merkki
s.substring(a, b) Merkkijono merkit väliltä a - b

Lisää hyödyllisiä funktioita löydät Javan käyttöohjeesta. Esimerkkiohjelma soveltaa joitakin funktioita annettuun merkkijonoon:

 1:class MjonoVatkain {
 2:
 3:  public static void main(String[] args) {
 4:    String s = args[0];
 5:    
 6:    // sovelletaan funktioita
 7:    int pituus = s.length();
 8:    String pienet = s.toLowerCase();
 9:    String isot = s.toUpperCase();
10:    char eka = s.charAt(0);
11:    String ekat = s.substring(0, 5);
12:    
13:    // näytetään tulokset
14:    System.out.println("Pituus      = " + pituus);
15:    System.out.println("Pieninä     = " + pienet);
16:    System.out.println("Isoina      = " + isot);
17:    System.out.println("1. merkki   = " + eka);
18:    System.out.println("1-5. merkki = " + ekat);
19:  }
20:}

Ohjelman käännös ja käyttö:

C:\java> javac MjonoVatkain.java

C:\java> java MjonoVatkain kalaBaliikki12
Pituus      = 14
Pieninä     = kalabaliikki12
Isoina      = KALABALIIKKI12
1. merkki   = k
1-5. merkki = kalaB

C:\java>
Tehtävä C3: Tee ohjelma "Erottele", jolle annetaan merkkijono ja kaksi kokonaislukua a ja b. Ohjelma erottelee merkkijonosta merkit a-b ja tulostaa ne. Esimerkiksi:
C:\java> java Erottele merkkijono 2 5
rkk

C:\java> java Erottele MERKKIJONO 5 9
IJONO

C:\java>

3. Lausekkeet

Lauseke on vakioarvo (esimerkiksi luku tai merkkijono), muuttuja, funktion kutsu (esimerkiksi s.substring(0, 5)) yllä) tai operaattorien (+, -, *, ...) avulla edellisitä koottu operaatio, jolla on tulos.

Lausekkeita on käytetty aiemmissa esimerkeissä jo paljon, mutta tässä kerrotaan niistä joitakin yksityiskohtia.

Aritmeettiset operaattorit

Aritmeettisten operaattorien avulla tehdään tavallisimpi laskutoimituksia. Aritmeettisia operaattoreita Javassa ovat:

+  summa
-erotus
*tulo
/osamäärä
%jakojäännös

Näistä jakojäännöstä voi soveltaa ainoastaan kokonaislukuihin. Kaikki muut soveltuvat myös liukuluvuille.

Jakolasku käyttäytyy eri tavalla liukuluvuille ja kokonaisluvuille. Kokonaislukujen jakolasku katkaiseen tuloksesta desimaalit. Esimerkiksi lausekkeen 7 / 2 tulos on 3. Alla oleva koodi tulostaa muuttujien jaon arvon murtolukuna jakolaskun ja jakojäännöksen avulla:

int a, b;
// arvot muuttujille tässä
int j = a / b;
int jj = a % b;
System.out.println(j + " " + jj + "/" + b);

Jos muuttujan a arvona on 7 ja muuttujan b arvona on 2, edellinen koodi tulostaa 3 1/2.

Tehtävä C4: Tee ohjelma "Jako", joka saa kaksi kokonaislukua, laskee niiden osamäärän ja tulostaa sen murtolukuna.

Aritmeettisten operaattorien suoritusjärjestys on tavanomainen, ensin kertolaskut, jakolaskut ja jakojäännökset vasemmalta oikealle ja sitten yhteenlaskut ja vähennyslaskut vasemmalta oikealle.

Suoritusjärjestystä voi muuttaa suluilla esim. a * (b + 2).

Operaattori + toimii merkkijonoille eri tavalla kuin luvuille. Sillä yhdistellään merkkijonoista ja muista tietotyypeistä pidempiä merkkijonoja. Esimerkkejä on edellisissä esimerkeissä lukuisia.

Muita operaattoreita

Vertailuoperaattoreista puhutaan myöhemmässä materiaalissa.

Operaattoreita ++ ja -- käytetään muuttamaan kokonaislukumuuttujan arvoa yhden verran suuremmaksi tai pienemmäksi. Operaattorit ovat unaarisia eli niitä sovelletaan yhteen ainoaan muuttujaan. Esimerkiksi operaattori + on binaarinen, koska sitä sovelletaan kahteen lukuun.

Myös sijoitus = on operaattori. Sen käytöstä on aiemmin esitetty monta esimerkkiä. Sijoitusoperaattorin voi yhdistää useimpiin binaarisiin operaattoreihin, esimerkiksi

a += 2;
b *= 3;

jotka tarkoittavat samaa kuin

a = a + 2;
b = b * 3;

Myös . (piste) on operaattori, jota käytetään viittaamaan olion sisälle. Esimerkiksi aiemmin esitetyissä merkkijono-operaatioissa oli esimerkkinä

String ekat = s.substring(0, 5);
               ^

jossa operaattoria käytetään viittaamaan merkkijonon s funktioon substring.

Tyypin muunnos

Joskus muuttujan tai lausekkeen ei ole yhteensopiva lausekkeen muiden osien kanssa. Silloin lausekkeen tyypin voi muuntaa toiseksi tyypinmuunnosoperaattorin avulla.

Tyypinmuunnosoperaattori koostuu tyypin nimestä sulkuihin kirjoitettuna, esimerkiksi (int) ja (double).

Esimerkiksi kahden kokonaislukumuuttujan osamäärän liukulukuna voi laskea seuraavalla tavalla:

int a, b;
// arvon muuttujille
double t = (double) a / (double) b;

Jos lauseke kirjoitetaan ilman tyypinmuunnoksia, jakolasku tehdään kokonaisluvuille eikä siinä ole desimaaleja.

4. Taulukot

Taulukko kuvattiin muuttujarivinä, jossa jokaisella muuttujalla on indeksi (järjestysnumero).

T[1]T[2]T[3]T[4]T[5]

Javan taulukko voidaan todellakin käsittää joukkona muuttujia, joilla on sama nimi, mutta eri järjestysnumero. Tällaisenaan taulukko on yksinkertaisin ja monikäyttöisin tietorakenne.

Taulukon luonti

Taulukon määrittelyssä tarvitaan ensin taulukkomuuttuja. Taulukkomuuttujalla on kantatyyppi (taulukon alkioiden tyyppi) ja hakasulut [] merkitsemässä se taulukoksi. Esimerkiksi

int[] luvut;
String[] merkkijonot;

Taulukkomuuttuja ei kuitenkaan vielä ole taulukko. Taulukko pitää luoda erikseen operaattorilla new.

int[] luvut = new int[100];
String[] merkkijonot = new String[10];

Nyt meillä on kokonaislukutaulukko, jossa on indeksit 0 - 99, ja merkkijonotaulukko, jossa on indeksi 0 - 9. Huomaa, että taulukon indeksit alkavat nollasta toisin kuin korttiprosessorissa.

Taulukon käsittely

Taulukon käsittelyyn tarvitaan yleensä toistolauseita, joita käsitellään myöhemmin. Nyt katsotaan, kuin taulukon alkioihin viitataan.

Taulukon pituuden (alkioiden lukumäärän) saa selville taulukon ominaisuuden length avulla:

int pituus = luvut.length;

Muuttujan pituus arvoksi tulee nyt 100 edellä luodun taulukon mukaan.

Taulukon alkioon viitataan hakasulkujen ja indeksin avulla. Esimerkkejä:

// ensimmäiseen alkioon 2
luvut[0] = 2;
// toiseen alkioon sama kuin ensimmäisessä
luvut[1] = luvut[0];
// tulostetaan kaksi ensimmäistä
System.out.println(luvut[0] + " ja " + luvut[1]);

Jos taulukkoon yritetään viitata väärällä indeksillä, ohjelman suoritus keskeytyy virheeseen "ArrayIndexOutOfBoundsException".

Tehtävä C5: Java-sovellus saa komentoriville annetut parametrit taulukossa args. Tee ohjelma "Parametrit", joka tulostaa komentoriviparametrien lukumäärän ja viimeisen parametrin:
C:\java> java Parametrit yksi kaksi kolme
  Lkm: 3
  Viimeinen: kolme

C:\java>