Helsingin yliopisto / Tietojenkäsittelytieteen laitos
Copyright © 2005 Arto Wikla. Tämän oppimateriaalin käyttö on sallittu vain yksityishenkilöille opiskelutarkoituksissa. Materiaalin käyttö muihin tarkoituksiin, kuten kaupallisilla tai muilla kursseilla, on kielletty.

2.2 Tyyppejä, aritmeettisia lausekkeita ja sijoituksia

(Muutettu viimeksi 8.9, edellinen muutos 9.5.2005)

Tässä luvussa kirjoitellaan lausekkeita - arvon ilmauksia - ja sijoitellaan niitä muuttujien arvoiksi. Käytössä on eräitä Javan välineitä. Luvussa 3 opitaan lisää.

Kommentteja

Ohjelmiin on syytä (miksi?) kirjoittaa selityksiä eli kommentteja. Edellisen luvun esimerkki voidaan kirjoittaa vaikkapa seuraavasti:
 
  /* Sovellus maailman tervehtimiseen
     tekijä: Arto Wikla   */

   public class Hoi {

     public static void main(String[] args) { // pääohjelma
       System.out.println("Hoi maailma!");
     }
   } 

Ilmaus "/*" aloittaa kommentin, jonka "*/" lopettaa. Ilmaus "//" sanoo, että loppurivi on kommenttia.

Näillä kommenteilla on merkitystä vain ihmiselle, joka lukee ohjelmatekstiä. Kääntäjä ei niistä välitä. Javassa on myös automaattista dokumentointia helpottavia kommentteja. Niistä myöhemmin.

Kokonais- ja desimaalilukuja, totuusarvoja, merkkijonoja

Javassa muuttujat on aina määriteltävä. Se tehdään kirjoittamalla tyypin nimi ja yksi tai useampia muuttujan nimiä:
  int lkm, kpl;
  double pituus, leveys, korkeus;
  boolean oikein;
  String nimi;
Tämä tarkoittaa, että muuttujat lkm ja kpl ovat kokonaislukutyyppisiä, so. niiden arvoksi voi asettaa vain kokonaislukuja. Muuttujat pituus, leveys, korkeus ovat desimaalilukuja (ns. "kaksoistarkkuuden liukulukuja") ja muuttuja oikein on totuusarvoinen (true, false). Muuttuja nimi on merkkijonoarvoinen.

Java kääntäjä (ja osin tulkki) tarkistaa, ettei muttuja koskaan voi saada arvokseen väärän tyyppistä arvoa.

Sijoituslauseita

Muuttujalle voi sijoittaa arvon sijoituslauseella. Sen ilmaukseksi on Java-kielessä (onnettomasti!) valittu merkki "=":
   lkm = 567;
   kpl = -9876;
   pituus = 123.456;
   korkeus = -0.001;
   oikein = false;
   nimi = "Matti Mainio";
Sijoitusoperaatio on syytä lukea "saa arvon", EI "on".

Jos muuttujalle yrittää antaa väärän tyyppisen arvon, esimerkiksi

  lkm = 3.14;
kääntäjä antaa virheilmoituksen:
Ohjelma.java:5: possible loss of precision
found   : double
required: int
       lkm = 3.14;
             ^
1 error
Kääntäjä ei virheen havaittuaan tuota lainkaan Bytecode-ohjelmaa!

Muuttujille voidaan antaa alkuarvo jo määrittelyn yhteydessä:

  int lkm=1, kpl=100;
  double pituus=1.1, leveys=2.2, korkeus=3.3;
  boolean oikein=true;
  String nimi="Jussi Juonio"; 

Algoritmeissa muuttujan uusi arvo usein lasketaan sen vanhasta arvosta, esimerkiksi:
  lkm = lkm + 10;
  pituus = pituus - 3;
  korkeus = korkeus * 2;
  leveys = leveys / 2;
Näissä tapauksissa voi käyttää (mutta ei tarvitse!) erityisiä sijoitusoperaatioita "+=", "-=", "*=" ja "/=" :
  lkm += 10;
  pituus -= 3;
  korkeus *= 2;
  leveys /= 2;

Hyvin yleistä on, että muuttujan arvoa kasvatetaan tai vähennetään yhdellä:
  kpl = kpl + 1;
  leveys = leveys - 1;
Nämä voidaan kirjoittaa hyvin lyhyesti:
  ++kpl;
  --leveys;
tai
  kpl++;
  leveys--;


Aritmeettisia laskutoimituksia

Kokonaisluvuille ja liukuluvuille (eli desimaaliluvuille) on käytettävissä laskutoimitukset:
   +  -  *  /  %
Jos molemmat operandit (so. laskettavat) ovat kokonaislukutyyppisiä, myös laskutoimituksen tulos on on kokonaisluku. Muuten tulos on liukuluku.

Operaatio "/" tarkoittaa kokonaisjakoa, jos sekä osoittaja, että nimittäjä ovat kokonaislukutyyppiä. Aina muulloin kyseessä on liukulukujakolasku.

Operaatio "%" on kokonaislukujen jäännösjako eli kokonaislukujakolaskun jakojäännös. Tuloksen etumerkki on sama kuin osoittajan etumerkki, nimittäjän etumerkillä ei ole vaikutusta tuloksen etumerkkiin.

Esimerkkejä:

  
public class Esim {
  public static void main(String[] args) {
    int lkm=1, kpl=100;
    double pituus=1.1, leveys=2.2, korkeus=3.3;

    lkm = kpl- 10 * (kpl-8);
    pituus = leveys * korkeus + pituus * lkm;

    lkm = 5;
    korkeus = 5;
    kpl = lkm/2;        // arvo on 2
    leveys = korkeus/2; // arvo on 2.5
    
    lkm = 17%3;  // arvo on 2
  }
}

Huom: Jos kahden kokonaislukuarvon jakamisen tuloksena halutaan liukuluku, on se erikseen ilmaistava. Yksi tapa on kertoa jompi kumpi kokonaisluku liukuluvulla 1.0 ennen jakolaskua (muita tapoja opitaan myöhemmin) Esimerkiksi ohjelma:

public class Koe {
   public static void main(String[] args) {
      int a=5, b=2;

      System.out.println( a/b );         // tulostus: 2
      System.out.println( a/b * 1.0 );   // tulostus: 2.0
      System.out.println( 1.0 * a/b );   // tulostus: 2.5
      System.out.println( a/(b * 1.0) ); // tulostus: 2.5
   }
}

String-sijoitus ja -yhteenliittäminen

Ohjelmoinnissa muitakin kuin aritmeettisia laskutoimituksia kutsutaan lausekkeiksi (expression) ja vaikkapa merkkijononon liittäminen toiseen, ns. katenointi, on "laskemista".

Operaatio "+" sovellettuna merkkijonoihin tarkoittaa katenointia:

public class Mesim {
  public static void main(String[] args) {
     String alku  = "kissa",
            loppu = "vie";
     String koko;

     koko = alku + loppu;             // "kissavie"
     koko = alku + " " + loppu;       // "kissa vie"
     koko = alku + " " + loppu +"!";  // "kissa vie!"
  }
}

Jos toinen "yhteenlaskettavista" on numeerinen arvo ja ja toinen on merkkijono, yhteenlasku tarkoittaa tällöinkin katenointia (Huom: "yhteenlaskut" lasketaan vasemmalta oikealle):

public class KateKoe {
  public static void main(String[] args){
     String jono  = "kissa",  tulos;

     tulos = jono + 100;
     System.out.println(tulos);   // tulostus: kissa100

     tulos = jono + 100 + 1000;   // tulostus: kissa1001000
     System.out.println(tulos);
     tulos = jono + (100 + 1000); // tulostus: kissa1100
     System.out.println(tulos);

     tulos = 100 + jono;
     System.out.println(tulos);   // tulostus: 100kissa

     tulos = 100 + 1000 + jono;   // tulostus: 1100kissa
     System.out.println(tulos);
     tulos = 100 + (1000 + jono); // tulostus: 1001000kissa
     System.out.println(tulos);
  }
}

Huom: Kun sijoitetaan:

   String a = "qwerty";
   String b = a;
merkkijonoa "qwerty" ei kopioida b:n arvoksi. Muuttujat a ja b vain osoittavat samaan merkkijonoon. Selitys on, että String-arvot ovat olioita, kun vaikkapa kokonaisluvut ovat ns. alkeistyyppiä. Sellaiset arvot sijoitusoperaatiossa kopioidaan. Tähän palataan!


Takaisin luvun 2 sisällysluetteloon.