javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen

2 Basal programmering

Indhold:

Kapitlet forudsættes i resten af bogen.

2.1 Det første javaprogram

Lad os se på et simpelt javaprogram, der skriver "Hej verden" og et citat af Storm P. ud til skærmen. Neden under den vandrette linje er vist, hvad der sker, hvis programmet køres:

// Et simpelt program, der skriver "Hej verden" 
// og et citat af Storm P. ud til skærmen
// Denne fil skal have navnet: HejVerden.java
public class HejVerden
{
  public static void main (String[] arg)
  {
    System.out.println("Hej Verden!");
    System.out.println("Hvornår smager en Tuborg bedst?");
    System.out.println("Hvergang!");
  }
}

Hej Verden!
Hvornår smager en Tuborg bedst?
Hvergang!

Alle javaprogrammer har den samme grundlæggende struktur, som også kan ses af dette eksempel.

2.1.1 Kommentarer

Kommentarer er dokumentation beregnet på, at gøre programmets kildetekst lettere at forstå for læseren. De påvirker ikke programudførelsen.

De første 3 linjer, der starter med //, er kommentarer:

// Et simpelt program, der skriver "Hej verden" 
// og et citat af Storm P. ud til skærmen
// Denne fil skal have navnet: HejVerden.java

I dette tilfælde er der beskrevet, hvad programmet gør og hvilket filnavn kildeteksten bør gemmes i.

Kommentarer bliver sprunget over og har ingen indflydelse på programmet
Kommentarer bør skrives, så de giver forståelse for, hvordan programmet virker - uden at være tvetydige eller forklare indlysende ting

Skråstregerne // markerer, at resten af linjen er en kommentar. Den kan også bruges efter en kommando til at forklare, hvad der sker, f.eks.

    System.out.println("Hej verden!");  // Udskriv en hilsen

Java har også en anden form, som kan være nyttig til kommentarer over flere linjer: Man kan starte en kommentar med /* og afslutte den med */. Al tekst imellem bliver så opfattet som kommentarer. Vi kunne altså også skrive

/*
   Et simpelt program, der skriver "Hej verden" 
   og et citat af Storm P. ud til skærmen
   Denne fil skal have navnet: HejVerden.java
*/

og

    System.out.println("Hej verden!");  /* Udskriv en hilsen */

I denne bog skriver vi kommentarer i kursiv for at lette læsningen af eksemplerne.

2.1.2 Klassedefinitionen

Resten af teksten kaldes en klassedefinition og beskriver selve programmet (HejVerden).

Den består af en fast struktur:

public class HejVerden
{
  public static void main (String[] arg)
  {
    ...
  }
}

og noget programkode – kommandoer, der skal udføres, nærmest som en bageopskrift:

    System.out.println("Hej verden!");

Strukturdelen

Strukturdelen vil ikke blive ændret i de næste to kapitler og det er ikke så vigtigt, at du forstår, hvad der foregår i første omgang.

Al javakode er indkapslet i en klasse mellem { og } (blokstart og blokslut-parenteser). Beskrivelsen af en klasse er altid indkapslet i en blok bestående af:

public class HejVerden
{
  ...
}

Inde i klassen står der en main-metode med nogle kommandoer i.

  public static void main (String[] arg)
  {
    ...
  }

Indholdet af metoden er altid indkapslet i en blok med { og }.

Programudførelsen starter i metoden:
public static void main (String[] arg)

Programkode

I main-metoden giver man instruktioner til computeren:

    System.out.println("Hej verden!");
    System.out.println("Hvornår smager en Tuborg bedst?");
    System.out.println("Hvergang!");

Instruktionerne udføres altid en efter en, ovenfra og ned. Hver instruktion afsluttes med et semikolon.

Disse 3 instruktioner skriver 3 strenge ("Hej verden!", ...) ud til skærmen. En streng er en tekst, som computeren kan arbejde med. Strenge er altid indkapslet i "".

Hver instruktion består af et kald til metoden System.out.println, som betyder, at der skal udskrives noget til skærmen og en streng som parameter. En parameter er en oplysning, som man overfører til metoden. I dette tilfælde hvilken tekst, der skal skrives ud til skærmen.

Vores main-metode kalder altså andre metoder.

2.1.3 Oversættelse og kørsel af programmet

Når man skal udvikle et program, skriver man først en kildetekst (eng.: source code), der beskriver, hvad det er, man vil have programmet til at gøre. Programmet, vi lige har set, er et eksempel på en kildetekstfil.

Instruktionerne, som computeren udfører med, er i en binær kode (kaldet maskinkode eller bytekode), der er umulig at læse for almindelige mennesker.

Kildeteksten skal derfor oversættes (eng.: compile; mange siger også kompilere på dansk) til den binære kode, som så kan udføres af computeren.

I Java kalder man den binære kode for bytekode. Bytekode er platformuafhængigt, dvs. at det kan køre på stort set alle hardware-platforme og alle styresystemer. De fleste andre sprogs binære kode er ikke indrettet til at være platformuafhængigt.

For at oversætte programmet HejVerden skal det gemmes i en fil med navnet "HejVerden.java".

En kildetekstfil skal have .java som filendelse og filnavnet skal passe med navnet på den klasse, der er defineret i filen

Eksempel: Filen med public class HejVerden hedder: HejVerden.java.

2.1.4 Oversættelse og kørsel fra kommandolinjen

Hvis du bruger det kommandolinje-orienterede JDK direkte, skal du åbne en DOS/UNIX-kommandoprompt1 og stå i den samme mappe som kildeteksten findes2. Skriv så3:

  javac HejVerden.java

Dette oversætter programmet til bytekode (filen HejVerden.class skulle nu gerne ligge i samme mappe). Nu kan du køre programmet med kommandoen4:

  java HejVerden

Resultatet udskrives i vinduet:

Hej Verden!
Hvornår smager en Tuborg bedst?
Hvergang!

Oversættelse og udførelse af programmet HejVerden

Oversættelse og kørsel med et udviklingsværktøj

I de fleste udviklingsværktøjer skal du oprette et projekt (f.eks. i NetBeans: File|New Project). Føj derefter din java-fil til projektet. Husk at placere filen i den mappe, som projektet angiver (eller rette projektets egenskaber).

Når man vil oversætte sit java-program, skal man vælge make eller build. Når man har gjort det, kan man køre sit program med run.

2.2 Variabler

Som tidligere nævnt udfører computeren instruktionerne i et program en ad gangen, uden at give det mening eller 'forstå' hvad den foretager sig. Mellem hver instruktion glemmer computeren alt der ikke er gemt i en lagerplads. Det er derfor vores opgave at gemme de data, som vi skal bruge senere i programmet.

Variabler er navne på steder i lageret, som vi vi bruge til at opbevare data. En variabel kan opfattes som en navngiven papirlap, hvor der til enhver tid kan stå netop én ting.

Variabler skal altid erklæres, dvs. at man skal fortælle computeren, at der afsættes plads i lageret til variablen, hvad slags data den skal indeholde og hvad den skal hedde.

En variabel er et navn på et sted i computerens hukommelse, beregnet på at indeholde data af en bestemt type
En variabel erklæres ved at skrive variabeltype variabelnavn;

Det er en god vane, at give variablerne sigende navne. Navnene bør starte med et lille bogstav.

I det følgende gennemgår vi to af Javas variabeltyper: int (heltal) og double (kommatal).

2.2.1 Heltal

En variabel af type


Efter 1. tildeling

n int (et heltal, eng.: integer) erklæres med

    int tal;

Nu er der reserveret plads i hukommelsen til et heltal5. Man får fat i pladsen, ved at bruge variabelnavnet tal. Efter at variablen er erklæret, kan den tildeles en værdi, dvs. man kan skrive data ind i den:

    tal = 22;

Nu er værdien af tal 22 (vist på figuren til højre).

Vi kan bruge tal-variablen i stedet for at skrive 22, f.eks. til at skrive ud til skærmen:

    System.out.println("Svaret på livet, universet og alt det der: " + tal);

Her slår computeren op i hukommelsen, læser indholdet af tal-variablen og skriver det ud til skærmen (+'et vil blive forklaret i næste afsnit).


Efter 2. tildeling

Variabler kan, som navnet siger, ændre værdi. Det gør vi, ved at tildele variablen en ny værdi:

    tal = 42;

Herefter er den gamle værdi fuldstændigt glemt og erstattet med den nye. Når programudførelsen når et punkt, hvor variablen læses, vil det være den nye værdi, 42, der gælder.

I en tildeling læses (eller udregnes) værdien på højre side af lighedstegnet, og denne værdi gemmes i variablen nævnt på venstre side

Herunder er eksemplet i sin helhed (den væsentlige del af koden er fremhævet med fed):

// Eksempel på brug af en variabel
// koden skal være i filen Variabler.java
public class Variabler
{
  public static void main (String[] arg)
  {
    int tal;
    tal = 22;
    System.out.println("Svaret på livet, universet og alt det der: " + tal);

    tal = 42;
    System.out.println("Undskyld, svaret er: " + tal);
  }
}

Svaret på livet, universet og alt det der: 22
Undskyld, svaret er: 42

2.2.2 Sammensætte strenge med +

Som det er vist i ovenstående eksempel, kan vi med tegnet +, sætte strenge sammen med noget andet:

    System.out.println("Svaret på livet, universet og alt det der: " + tal);

Herunder sætter vi to strenge sammen:

// Sammensæt to strenge med +
// koden skal være i filen HejVerden2.java
public class HejVerden2
{
  public static void main (String[] arg)
  {
    System.out.println("Hej " + "Verden!");
  }
}

Hej Verden!

Herunder skriver vi en streng og tallet 42 ud:

public class HejVerden3
{
  public static void main (String[] arg)
  {
    System.out.println("Svaret på livet, universet og alt det der: " + 42);
  }
}

Svaret på livet, universet og alt det der: 42

Det der egentlig sker er, at det hele bliver sat sammen til én streng og den sendes til System.out.println().

En streng + noget andet sættes sammen til en samlet streng

2.2.3 Beregningsudtryk

Man kan erklære flere variabler på samme linje:

    int antalHunde, antalKatte, antalDyr;
    antalHunde = 5;
    antalKatte = 8; 

Tildelinger kan indeholde regneudtryk på højre side af lighedstegnet. Udtrykket antalHunde + antalKatte udregnes og resultatet lægges i variablen på venstre side (det er ikke tilladt at have beregningsudtryk på venstre side):

    antalDyr = antalHunde + antalKatte;

Beregningsudtrykkene undersøges af Java ved at indsætte værdien af variablerne. Her indsætter Java 5 + 8 og får 13, som lægges i antalDyr.

public class Dyreinternat
{
  public static void main(String[] arg) 
  {
    int antalHunde, antalKatte, antalDyr;
    antalHunde = 5;
    antalKatte = 8; 

    //udregn summen
    antalDyr = antalHunde + antalKatte;

    // udskriv resultatet
    System.out.println("Antal dyr: " + antalDyr);

    antalHunde  = 10;

    // antalDyr er uændret
    System.out.println("Antal dyr nu: " + antalDyr);
  }
}

Antal dyr: 13
Antal dyr nu: 13

Beregningen sker én gang på det tidspunkt, hvor kommandoen udføres6. Derfor er antalDyr's værdi ikke påvirket af at, vi sætter antalHunde til noget andet efter udregningen.

Ligesom i almindelig matematik har * (multiplikation) og / (division) højere prioritet end + og -.

I Java skrives
”9 divideret med 3” som 9/3
”3 gange 3” som 3*3

Man kan ikke, som i almindelig matematisk notation, undlade at skrive gangetegn.

Resultatet af en heltalsudregning er også et heltal. Det skal man være opmærksom på ved division, hvor eventuelle decimaler efter kommaet smides væk. Heltalsudregningen 13 / 5 giver altså 2, fordi 5 går op i 13 to gange7.

Et heltal divideret med et heltal giver et heltal
95 / 100 giver 0

Ønsker man at få et kommatal som resultat af divisionen, skal et eller begge af tallene være kommatal. Eksempelvis giver 95.0 / 10 kommatallet 9.5.

2.2.4 Kommatal

Der findes mange andre variabeltyper end heltalstypen int. Hvis man vil regne med kommatal, bruger man typen double. En variabel af typen double erklæres med:

  double højde;

De følgende afsnit bruger noget matematik, mange lærer i gymnasiet. Hvis du ikke kender så meget til matematik, gør det ikke noget. Præcis hvad der udregnes og formlerne bag det, er ikke så vigtigt i denne sammenhæng. Det vigtige er at forstå hvordan man arbejder med tal i Java.

Her er et eksempel på beregning af en cylinders rumfang:

//
// Beregning af rumfang for en cylinder
//
public class Cylinderberegning
{
  public static void main(String[] arg) 
  {
    double radius;
    radius = 5.0;

    double højde = 12.5;

    //beregn rumfang
    double volumen = radius * radius * højde * 3.14159;

    System.out.println("Cylinderens højde: " + højde);
    System.out.println("Cylinderens radius: " + radius);
    System.out.println("Cylinderens volumen: " + volumen);
  }
}

Cylinderens højde: 12.5
Cylinderens radius: 5.0
Cylinderens volumen: 981.7468749999999

Læg mærke til, at man godt kan erklære en variabel og tildele den værdi i samme linje:

  double højde = 12.5;

er altså det samme som:

  double højde;
  højde = 12.5;

Her er et eksempel på en skatteberegning, der viser nogle flere fif:

//
// Skatteberegning for 2014
//
public class Skatteberegning 
{
  public static void main(String[] arg) 
  {
    double indkomst = 300000;
    double arbejdsmarkedsbidrag, bundskat;

    arbejdsmarkedsbidrag = indkomst * 0.08;
    indkomst = indkomst - arbejdsmarkedsbidrag;
    bundskat = (indkomst - 42800) * 0.0683;
    System.out.println("Arbejdsmarkedsbidrag: " + arbejdsmarkedsbidrag);
    System.out.println("Personlig indkomst: " + indkomst);
    System.out.println("Bundskat: " + bundskat);
  }
}

Arbejdsmarkedsbidrag: 24000.0
Personlig indkomst: 276000.0
Bundskat: 15927.56

Udregninger sker normalt fra venstre mod højre, men ligesom i den almindelige matematik kan man påvirke udregningsrækkefølgen. ved at sætte parenteser:

    bundskat = (indkomst - 42800) * 0.0683;

2.2.5 Matematiske funktioner

Dette afsnit handler om de matematiske funktioner som sinus, cosinus, kvadratrod osv. som man lærer om i f.eks. den matematiske gren af gymnasiet. Kender du ikke disse begreber så spring let hen over afsnittet, da de ikke er nødvendige for at lære at programmere.

Funktionerne kaldes i Java med Math.sin(x) for sinus, Math.cos(x) for cosinus, Math.sqrt(x) for kvadratrod, Math.pow(x, y) for xy (potens), Math.max(x, y) for at finde det største tal osv. - x og y kan være faste tal, variabler, eller beregningsudtryk.

Vi kan f.eks. lave en tabel over værdierne af kvadratrod-funktionen Math.sqrt() for x=0 til x=10 med programmet (senere, i afsnit 0.5 om løkker vil vi se en smartere måde).

public class Kvadratrod
{
  public static void main(String[] arg) 
  {
    System.out.println("kvadratroden af 0 er " + Math.sqrt(0));
    System.out.println("kvadratroden af 1 er " + Math.sqrt(1));
    System.out.println("kvadratroden af 2 er " + Math.sqrt(2));
    System.out.println("kvadratroden af 3 er " + Math.sqrt(3));
    System.out.println("kvadratroden af 4 er " + Math.sqrt(4));
    System.out.println("kvadratroden af 5 er " + Math.sqrt(5));
    System.out.println("kvadratroden af 6 er " + Math.sqrt(6));
    System.out.println("kvadratroden af 7 er " + Math.sqrt(7));
    System.out.println("kvadratroden af 8 er " + Math.sqrt(8));
    System.out.println("kvadratroden af 9 er " + Math.sqrt(9));
    System.out.println("kvadratroden af 10 er " + Math.sqrt(10));
  }
}

kvadratroden af 0 er 0.0
kvadratroden af 1 er 1.0
kvadratroden af 2 er 1.4142135623730951
kvadratroden af 3 er 1.7320508075688772
kvadratroden af 4 er 2.0
kvadratroden af 5 er 2.23606797749979
kvadratroden af 6 er 2.449489742783178
kvadratroden af 7 er 2.6457513110645907
kvadratroden af 8 er 2.8284271247461903
kvadratroden af 9 er 3.0
kvadratroden af 10 er 3.1622776601683795

Her er et program, der udregner længden af den skrå side (hypotenusen) af en retvinklet trekant ud fra længden af dens to lige sider (kateter) a og b (kvadratroden af a²+b²):

public class Trekant
{
  public static void main(String[] arg) 
  {
    double a, b, hypotenuse;
    a = 3;
    b = 4;
    hypotenuse = Math.sqrt(a*a + b*b);
    System.out.println("En retvinklet trekant med sider "+a+" og "+b);
    System.out.println("har hypotenuse "+hypotenuse);
  }
}

En retvinklet trekant med sider 3.0 og 4.0
har hypotenuse 5.0

Her er et program, der udregner, hvor meget 1000 kroner med 5 % i rente i 10 år bliver til:

public class Rentesregning
{
  public static void main(String[] arg) 
  {
    System.out.println("1000 kr med 5 % i rente på 10 år giver "
                       + 1000*Math.pow(1.05 ,10) + " kroner.");
  }
}

1000 kr med 5 % i rente på 10 år giver 1628.8946267774422 kroner.

Ud over de almindelige matematiske funktioner findes også Math.random(), der giver et tilfældigt tal mellem 0 og 0.999999...

2.2.6 Kald af metoder

Math.sqrt(), Math.sin() og de andre matematiske funktioner og andre kommandoer, f.eks. System.out.println(), kaldes under et metoder.

En metode er en navngiven programstump, der kan gøre et eller andet eller beregne en værdi. F.eks. gør System.out.println() det, at den skriver tekst på skærmen og Math.sqrt() beregner en kvadratrod. Når en metode nævnes i teksten, skriver vi altid ”()” bagefter, så man kan se, at det er en metode.

Nedenstående linje indeholder et metodekald:

    hypotenuse = Math.sqrt(a*a + b*b);

Math.sqrt er navnet på metoden og man kalder det, der står inde i ”()”, for argumentet eller parameteren.

Et metodekald er en nævnelse af en metodes navn efterfulgt af de rigtige parametre. Parametrene er omgivet af parenteser.

Ved et metodekald kan man som parameter indsætte ethvert udtryk, der giver et resultat af den rigtige type

Alt, der giver et resultat af den rigtige type, er altså tilladt: Konstanter, variabler, regneudtryk og resultatet af et andet metodekald:

    double v,x;
    x = Math.sqrt(100);             // konstant som parameter
    x = Math.sqrt(x);               // variabel som parameter
    x = Math.sin(Math.sqrt(0.3));  // værdi af andet metodekald som parameter

Ved et kald uden parametre skal man stadig have parenteserne med. Her er et eksempel på et metodekald af Math.random(), som er en metode, der skal kaldes uden parametre:

    double tilfældigtTal; 
    tilfældigtTal = Math.random();

Vi vil i kapitel 4 se, hvad der sker, når computeren udfører et metodekald samt lære, hvordan man kan lave sine egne metoder.

2.2.7 Logiske variabler

En boolesk8 variabel (eng.: boolean), også kaldet en logisk variabel, kan indeholde værdien sand eller falsk. Den bruges mest til at huske, om noget er sandt eller ej, men kan også repræsentere noget, der kun har to tilstande, f.eks. om en lampe er tændt eller slukket.

Variabeltypen hedder boolean og den erklæres med f.eks.:

    boolean detErForSent;

En boolesk variabel kan kun sættes til værdierne true eller false. F.eks.:

    detErForSent = false;

På højre side af lighedstegnet kan stå et logisk udtryk, dvs. et udsagn, der enten er sandt eller falsk, f.eks. "klokken er over 8" (her forestiller vi os, at vi har variablen klokken).

    detErForSent = klokken > 8;

Udtrykket klokken > 8 undersøges af Java, ved at indsætte værdien af variablen i regneudtrykket og derefter afgøre, om udsagnet er sandt. Hvis f.eks. klokken er lig 7, står der 7>8, det er ikke sandt og detErForSent får værdien false. Hvis klokken er lig 10, står der 10>8, det er sandt og detErForSent får værdien true.

2.2.8 Opgaver

  1. Skriv et program, som ud fra længde og bredde på et rektangel udskriver dets areal.

  2. Skriv et program, som for ligningen y=3*x*x+6*x+9 udskriver værdien af y for x=7.

  3. Skriv et program, som omregner et beløb fra dollar til euro (f.eks. kurs 95).

  4. Skriv et program, som udskriver tre tilfældige tal (lavet med Math.random()), deres sum og gennemsnittet.

  5. Hvad skriver følgende program ud? Hvis du kan regne det ud, uden at køre programmet, har du forstået idéen i tildelinger.

public class Tildelinger
{
  public static void main(String[] arg)
  {
    int a, b, c, d;
    a = 5;
    b = 6;
    c = 7;
    d = 8;
    System.out.println("a er "+a+", b er "+b+", c er "+c+" og d er "+d);

    a = b + d;
    d = c + a;
    System.out.println("a er "+a+", b er "+b+", c er "+c+" og d er "+d);

    b = a;
    d = c;
    System.out.println("a er "+a+", b er "+b+", c er "+c+" og d er "+d);
  }
}

2.3 Betinget udførelse

Indtil nu har vores programmer været fuldstændig forudsigelige. Vi har bedt computeren om at udføre den ene kommando efter den anden uanset udfaldet af de tidligere kommandoer.


Logikken i en if-sætning

I programmer kan man påvirke programudførelsen, ved at indføre betingelser, der fortæller, at en del af programmet kun skal gennemløbes, hvis betingelsen er opfyldt.

Det består af et udtryk, der enten er sandt eller falsk og noget, der afhænger af dets sandhedsværdi (se rutediagrammet til højre).

Alle kender betingelser fra deres dagligdag, f.eks.:

I Java er syntaksen

    if (betingelse) kommando;

For eksempel:

if (alder >= 18) System.out.println("Du er myndig");

if (alkoholpromille > 0.5) System.out.println("Lad bilen stå");

if (pris < 500) System.out.println("Jeg køber den!");

if (alder == 18) System.out.println("Du er præcis atten år.");

if (alder != 18) System.out.println("Du er ikke atten.");

Udtrykkene i parenteserne er logiske udtryk (eller booleske udtryk). På dansk er sætningen "over 18" tvetydig: skal man være OVER 18, dvs. 19, for at være myndig? Java har derfor to forskellige sammenligningsoperatorer: a >= b undersøger, om a er større end eller lig med b, mens a > b undersøger om a er større end b. I appendiks afsnit 0.11.6 findes en oversigt over sammenligningsoperatorerne.


Rutediagram for Alder

Herunder et komplet eksempel på et program, der afgør, om man er myndig. Programkoden, udtrykt på dansk, kunne være: hvis alder er større end 18, så skriv "Du er myndig". I Java skriver man:

public class Alder
{
  public static void main(String[] arg) 
  {
    int alder;
    alder = 15;

    if (alder >= 18) System.out.println("Du er myndig.");

    System.out.println("Du er " + alder + " år.");
  }
}

Du er 15 år.

Kommandoen System.out.println("Du er myndig") bliver kun udført, hvis betingelsen (alder >= 18) er sand. I dette tilfælde er alder lig 15 og der bliver ikke skrevet noget ud.

Hvis vi ændrer i programmet, så alder er 18, er betingelsen (alder >= 18) sand og vi får:

Du er myndig.
Du er 18 år.

Programudførelsen fortsætter under alle omstændigheder efter betingelsen, så uafhængigt af udfaldet, vil den sidste linje blive udført.

2.3.1 Indlæsning fra tastaturet

Et program bliver selvfølgelig først rigtigt sjovt, hvis brugeren kan påvirke dets udførelse, f.eks. ved at programmet kan bede brugeren om at indtaste sin alder. Det kan gøres med:

public class AlderMedTastaturindlaesning
{
  public static void main(String[] arg) 
  {
    java.util.Scanner tastatur = new java.util.Scanner(System.in);  // forbered

    System.out.println("Skriv din alder herunder og tryk retur:");
    int alder;
    alder = tastatur.nextInt();                     // læs et tal fra tastaturet

    if (alder >= 18) System.out.println("Du er myndig.");
    System.out.println("Du er " + alder + " år.");
  }
}

Programmet vil nu stoppe op og vente på, at der bliver indtastet noget efterfulgt af tryk på retur-tasten. I den øverste linje (med kommentaren forbered) definerer vi variablen tastatur, og den skal kun forekomme én gang øverst i programmet (i kapitel Fejl: Henvisningskilde ikke fundet vil vi se nærmere på, hvad der sker i de to specielle linjer).

Du kan også få et grafisk indtastningsvindue, som brugeren kan udfylde, til at dukke op (se afsnit 0.12.1).

2.3.2 if-else


Logikken i en if-else-sætning

Hvis vi ønsker at gøre én ting, hvis betingelsen er sand og en anden ting, hvis betingelsen er falsk, kan vi føje en else-del til vores if-sætning. Denne del vil kun blive udført, hvis betingelsen er falsk. Syntaksen er:

    if (betingelse) kommando1;
    else kommando2;

Eksempelvis:

public class Alder2
{
  public static void main(String[] arg) 
  {
    int alder;
    alder = 15;

    if (alder >= 18)
      System.out.println("Du er myndig.");
    else
      System.out.println("Du er ikke myndig.");

    System.out.println("Du er " + alder + " år.");
  }
}

Du er ikke myndig.
Du er 15 år.

Ændrer vi alder = 15 til alder = 18, er betingelsen (alder >= 18) sand og vi får i stedet udskriften:

Du er myndig.
Du er 18 år.

Kædede if-else-sætninger

Bemærk at man med fordel kan kæde if-else-sætninger sammen. F.eks.:

    if (alder >= 18) System.out.println("Du er myndig.");
    else if (alder >= 13) System.out.println("Du er teenager og ikke myndig.");
    else if (alder >= 2) System.out.println("Du er et barn og ikke myndig.");
    else System.out.println("Du er et spædbarn!");

2.3.3 Opgaver

  1. Skriv Alder2 om til at indeholde flere aldergrænser.

  2. Lav et veksleprogram fra dollar til euro. Det skal påregne en kommission på 2 %, dog mindst 0,5 euro.

  3. Skriv et program, der beregner porto for et brev. Inddata er brevets vægt (i gram). Uddata er prisen, for at sende det som A-post i Danmark.

  4. Skriv et program, som finder det største og det mindste af tre tal.

Afprøv programmerne med forskellige værdier, ved at indlæse værdierne fra tastaturet.

2.4 Blokke

En blok er en samling af kommandoer. Den starter med en blokstart-parentes { og slutter med en blokslut-parentes}.9

En blok grupperer flere kommandoer, så de udføres samlet

Blokke bruges blandt andet, hvis man vil have mere end førstkommende linje udført i en betingelse. Herunder udføres to kommandoer, hvis betingelsen er opfyldt og to andre kommandoer, hvis betingelsen ikke er opfyldt:

public class Alder3
{
  public static void main(String[] arg) 
  {
    int alder;
    alder = 15;

    if (alder >= 18) 
    {                                                   // blokstart
      System.out.println("Du er " + alder + " år.");
      System.out.println("Du er myndig.");
    }                                                   // blokslut 
    else 
    {                                                   // blokstart
      System.out.println("Du er kun " + alder + " år.");
      System.out.println("Du er ikke myndig.");
    }                                                   // blokslut
  }
}

Du er kun 15 år.
Du er ikke myndig.

2.4.1 Indrykning

Læg mærke til, hvordan programkoden i blokkene i ovenstående eksempel er rykket lidt ind. Det gør det lettere for programmøren at overskue koden, så han/hun kan se, hvilken {-parentes der hører sammen med hvilken }-parentes10.

Det er god skik at bruge indrykning i en blok
Indrykning gør programmet meget nemmere at overskue

Her er det samme program uden indrykning. Det er sværere at overskue nu (man kunne måske komme til at tro, at de nederste to linjer bliver udført uafhængigt af if-sætningen):

public class Alder3UheldigIndrykning{
public static void main(String[] arg) 
{int alder;
alder = 15;
if (alder >= 18) { System.out.println("Du er " + alder + " år.");
System.out.println("Du er myndig");
} else {
System.out.println("Du er kun " + alder + " år.");
System.out.println("Du er ikke myndig");
}}}

De fleste udviklingsværktøjer har funktioner til at rykke flere linjers kode ind og ud. Man gør det oftest, ved at markere teksten og trykke på Tab (tabulator-tasten til venstre for Q).

2.5 Løkker

En løkke er en gentaget udførelse af en kommando igen og igen. Hvor mange gange løkken udføres, afhænger af et logisk udtryk.

2.5.1 while-løkken


Logikken i en while-løkke

while-løkken har formen:

    while (betingelse) kommando;

Kommandoen udføres igen og igen, så længe betingelsen er opfyldt. Dvs. før kommandoen udføres, undersøges betingelsen og det kontrolleres, at den er opfyldt (se rutediagrammet til højre).

Oftest vil man udføre mere en én kommando og anvender derfor en blok til samle kommandoerne:

    while (betingelse) {
      kommando1;
      kommando2;
      ...
    }

Her er et eksempel:

public class Alder4
{
  public static void main(String[] arg) 
  {
    int alder;
    alder = 15;

    while (alder < 18)
    {
      System.out.println("Du er "+alder+" år. Vent til du bliver ældre.");
      alder = alder + 1;
      System.out.println("Tillykke med fødselsdagen!");
    }

    System.out.println("Nu er du "+alder+" år og myndig.");
  }
}

Du er 15 år. Vent til du bliver ældre.
Tillykke med fødselsdagen!
Du er 16 år. Vent til du bliver ældre.
Tillykke med fødselsdagen!
Du er 17 år. Vent til du bliver ældre.
Tillykke med fødselsdagen!
Nu er du 18 år og myndig.

Før løkken starter, har alder en startværdi på 15. Under hvert gennemløb tælles den en op.

På et tidspunkt, når alder er talt op til 18, er betingelsen ikke mere opfyldt og programudførelsen fortsætter efter løkken.


Rutediagram for noget af Alder4



Med en løkke kan vi lave Kvadratrod-programmet nemmere: I stedet for at skrive den samme kommando igen og igen, kan vi lave en løkke.

Sammenlign det følgende program med det oprindelige Kvadratrod-program fra afsnit 0.2.5.

public class Kvadratrod2
{
  public static void main(String[] arg) 
  {
    int n;
    n = 0;


    while (n <= 10)
    {
      System.out.println("kvadratroden af "+n+" er " + Math.sqrt(n));
      n = n + 1;
    }
  }
}

kvadratroden af 0 er 0.0
kvadratroden af 1 er 1.0
kvadratroden af 2 er 1.4142135623730951
kvadratroden af 3 er 1.7320508075688772
kvadratroden af 4 er 2.0
kvadratroden af 5 er 2.23606797749979
kvadratroden af 6 er 2.449489742783178
kvadratroden af 7 er 2.6457513110645907
kvadratroden af 8 er 2.8284271247461903
kvadratroden af 9 er 3.0
kvadratroden af 10 er 3.1622776601683795

En tællevariabel er en variabel, der tælles op i en løkke, indtil den når en bestemt øvre grænse, hvorefter løkken afbrydes.

I eksemplerne ovenfor brugte vi alder og n som tællevariabler.

Herunder udskriver vi 7-tabellen, ved hjælp af tællevariablen n:


Rutediagram for Syvtabel

public class Syvtabel
{
  public static void main(String[] arg) 
  {
    int n;
    n = 1;

    while (n <= 10)
    {
      System.out.println(n+" : "+ 7*n);
      n = n + 1;
    }
  }
}

1 : 7
2 : 14
3 : 21
4 : 28
5 : 35
6 : 42
7 : 49
8 : 56
9 : 63
10 : 70

Tællevariabel-formen er den mest almindelige for løkker, men man kan sagtens komme ud for andre former for løkker. Der kan f.eks. godt indgå et regneudtryk i betingelsen.

2.5.2 for-løkken

for-løkken er specielt velegnet til løkker med en tællevariabel. Den har formen

    for (initialisering; betingelse; opdatering) kommando;


Strukturen i en for-løkke



Det kan indenad læses som "for startværdi, så længe betingelse udfør: kommando og opdatering, f.eks. "for alder = 15, så længe alder < 18 udfør: Skriv "du er.." og tæl alder 1 op".


Rutediagram for Syvtabel2
(samme som for Syvtabel)

En for-løkke og en while-løkke supplerer hinanden. De har præcis samme funktion, men for-løkken er mere kompakt og bekvem, når man ønsker at lave en almindelig løkke, der udføres et bestemt antal gange. Dette program gør det samme som Syvtabel-eksemplet, men med en for-løkke:

public class Syvtabel2
{
  public static void main(String[] arg) 
  {
    for (int n=1; n<=10; n=n+1)
    {
      System.out.println(n+" : "+ 7*n);
    }
  }
}

Programmører er dovne væsner og bruger ofte for-løkken til optælling, fordi der skal skrives mindre end i en while-løkke.

Man ser også ofte, at de bruger operatoren ++ til at tælle en variabel op i en løkke: "alder++" svarer altså til "alder=alder+1", men med mindre skrivearbejde.

Tilsvarende findes --, som tæller en variabel én ned, f.eks. alder--.

2.5.3 Indlejrede løkker

En betingelse eller en løkke kan stå ethvert sted i en metode og altså også inden i en anden løkke eller betingelse.

Herunder har vi syvtabellen igen, men denne gang "brokker" programmet sig, når det når op på 6. Efter 8 skriver det "ved ikke", i stedet for at regne resultatet ud.

public class Syvtabel3
{
  public static void main(String[] arg) 
  {
    for (int n=1; n<=10; n++)  // n++ gør det samme som n=n+1
    {
      if (n == 6) System.out.println("puha, nu bliver det svært.");

      if (n < 8) System.out.println(n+" : "+ 7*n);
      else System.out.println(n+" : (ved ikke)");
    }
  }
}

1 : 7
2 : 14
3 : 21
4 : 28
5 : 35
puha, nu bliver det svært.
6 : 42
7 : 49
8 : (ved ikke)
9 : (ved ikke)
10 : (ved ikke)

Man kan lave løkker i løkker. Herunder udregner vi n*7 ved at lægge 7 sammen n gange:

public class Syvtabel4
{
  public static void main(String[] arg) 
  {
    for (int n=1; n<=10; n=n+1)
    {
      int sum = 0;
      for (int j=0; j<n; j++) {
        sum = sum + 7;
        System.out.print(sum+"..");  // print = println, men uden linjeskift 
      }

      System.out.println(" syv gange "+n+" giver: "+ sum);
    }
  }
}

7.. syv gange 1 giver: 7
7..14.. syv gange 2 giver: 14
7..14..21.. syv gange 3 giver: 21
7..14..21..28.. syv gange 4 giver: 28
7..14..21..28..35.. syv gange 5 giver: 35
7..14..21..28..35..42.. syv gange 6 giver: 42
7..14..21..28..35..42..49.. syv gange 7 giver: 49
7..14..21..28..35..42..49..56.. syv gange 8 giver: 56
7..14..21..28..35..42..49..56..63.. syv gange 9 giver: 63
7..14..21..28..35..42..49..56..63..70.. syv gange 10 giver: 70

2.5.4 Uendelige løkker

Hvis programmøren ikke er omhyggelig, kan han komme til at lave en løkke, hvor betingelsen bliver ved med at være sand. Så kører programmet rundt i løkken i al evighed (eller indtil brugeren afbryder programmet).

Lad os f.eks. sige, at programmøren er kommet til at skrive '-' i stedet for '+' i opdateringen af n i while-løkken fra Syvtabel-programmet. Så vil computeren tælle nedad:

public class SyvtabelFejl
{
  public static void main(String[] arg) 
  {
    int n = 1;
    while (n <= 10)
    {
      System.out.println(n+" : "+ 7*n);
      n = n - 1;
    }
  }
}

1 : 7
0 : 0
-1 : -7
-2 : -14
-3 : -21
-4 : -28

... og så videre i det uendelige. Løkken vil aldrig stoppe, fordi n for evigt er være mindre end11 10.

En anden faldgrube er, at komme til at sætte et semikolon efter en while-løkke:

    while (n <= 10);

Compileren vil tro, at der ikke er nogen kommando, der skal udføres og blot undersøge betingelsen igen og igen og igen og igen... Da n ikke ændrer sig, vil programmet aldrig stoppe.

Det er programmørens ansvar at sikre, at betingelsen i en løkke på et tidspunkt ikke mere opfyldes, så programmet ikke går i uendelig løkke12.

2.5.5 Opgaver

Prøv at køre hvert af de foregående eksempler og forvis dig om, at du forstår dem.
Mange værktøjer understøtter trinvis gennemgang til fejlfinding (eng.: debugging). Prøv i dit udviklingsværktøj og hold øje med variablerne (gøres nok med F8-tasten "step over").

  1. Lav et program, der tæller nedad fra 10 til 1.

  2. Lav et program, der udregner værdien af 1+2+3+ ... +20 med en løkke.

  3. Lav et program, der udskriver 2-tabellen, 3-tabellen, .. op til 10-tabellen.

  4. Skriv et program, som for ligningen y=3*x*x+6*x+9 udskriver værdierne af y for x=0, x=1,x= 2, x=3 ... x=10. Ret det derefter til at skrive ud for x=0,x=10,x=20,x=30...x=100.

  5. Lav spillet "Gæt hvilket tal jeg tænker på": Lav et program, der husker et tal fra 1 til 20, som brugeren skal gætte. Her er et forslag til dialogen med brugeren:
    Gæt et tal: 8
    Tallet jeg tænker på er højere.
    Gæt et tal: 13
    Tallet jeg tænker på er lavere.
    Gæt et tal: 11
    Det er det rigtige tal! Du brugte 3 forsøg.

    Vink: Et tilfældigt tal mellem 1 og 20 kan fås med (int) (Math.random()*20 + 1)

2.6 Konvertering af værdier

I Java har alle variabler en bestemt type gennem hele deres levetid og der sætter nogle begrænsninger for, hvilke værdier man kan give en variabel. Når man først har vænnet sig til det, er det en stor hjælp, fordi compileren på denne måde ofte fanger fejl i programmerne (desuden gør det, at computeren hurtigere kan udføre beregninger).

I Java kan man f.eks. ikke lægge en double-værdi ind i en int-variabel:

  int x;
  x = 2.7; // Compilerfejl: Possible loss of precision: double, required: int.

Forsøger man, vil man få en fejl under oversættelsen (compilerfejl). Der er to årsager til, at vi i Java ikke kan gemme 2.7 i x:

  1. Det sted i RAM-lageret som x repræsenterer er der afsat plads til at gemme hele tal. En int fylder 4 byte, mens en double fylder 8 byte.

  2. Da x er erklæret som en int og skal den blive ved med at være en int.
    I de efterfølgende beregninger kan det have stor betydning, om x har en kommadel. Programmøren skal derfor kunne se på, hvordan x er erklæret og derefter være helt sikker på, hvilke værdier x kan indeholde.

For at kunne gemme 2.7 i x bliver man derfor nødt til at lave 2.7 om til en int-værdi. Det kaldes at typekonvertere værdien (eng.: cast). Dette er ikke helt uden problemer:

Af disse årsager bliver man i nogle tilfælde nødt til eksplicit at fortælle compileren, at den skal foretage en konvertering af værdien til en anden type.

2.6.1 Eksplicit typekonvertering

Man konverterer en værdi til en anden type, ved at skrive det eksplicit med:

  int x;
  x = (int) 2.7;

Inde i parentesen skriver man typen, som værdien lige til højre skal konverteres til.

Denne form for typekonvertering runder altid ned13 til nærmeste hele tal14.

2.6.2 Implicit typekonvertering

Implicit typekonvertering af værdien betyder, at compileren selv laver konverteringen, uden at programmøren behøver at skrive noget særligt om, at den skal gøre det.

  double y;
  y = 4;   // OK: Implicit værdi-typekonvertering.

Selvom 4 er en int-værdi, kan y godt indeholde den, da den svarer til double-værdien 4.0. Denne form for konvertering er således ikke nær så problematisk, som i det tidligere eksempel.

En tommelfingerregel i Java er, at når modtagertypen kan indeholde hele intervallet af mulige værdier for afsendertypen, kan den være implicit. I appendiks 0.11.2 sidst i dette kapitel findes en tabel over typerne.

2.6.3 Regler omkring eksplicit typekonvertering

Bemærk at kun er værdien, der bliver konverteret. Variablen bliver ikke ændret.

  int x;
  double y;
  y = 2.7;
  x = (int) y;              // punkt A
  System.out.println(x);
  System.out.println(y);   // y er upåvirket af typekonverteringen

2
2.7

Man kunne måske fristes til at tro, at i punkt A konverteres variablen y til en variabel af typen int, men det ville så betyde, at den sidste linje i uddata skulle være 2. Men husk at:

En variabel kan ikke ændre type – dens type er altid, som den er erklæret

Det, der sker i ovenstående, er, at y's værdi (2.7) læses, en konverteret værdi (2) beregnes og denne værdi lægges ind i x.

Det er en misforståelse er at tro, at compileren kan se, at noget er lovligt ud fra de øvrige programlinjer, f.eks.:

  int x;
  double y;
  y = 4.0;
  x = y;  // Fejl - her stopper compileren med "Possible loss of precision"

I ovenstående tilfælde kunne man tro, at man kan bruge implicit typekonvertering, fordi compileren kan se, at y altid er 4.0 og at der derfor ikke går information tabt. Men så klog er compileren ikke. Når den skal afgøre, om den kan lave implicit typekonvertering, kigger den kun på typerne af variabler og værdier. Den skeler ikke til resten af programmet15.

2.7 Fejlfinding

Som sagt udfører computeren programmet instruktion for instruktion som en kogebogsopskrift. Computeren forstår ikke programmet, men udfører blot det, programmøren (kogebogsforfatteren) har skrevet.

2.7.1 Indholdsmæssige (logiske) fejl

Da maskinen ikke forstår programmet, kan den heller ikke rette op på fejlene i programmørens opskrift eller forstå, hvad programmøren "mener" med det, han skrev. Man kan altså sagtens komme til at lave et program, der gør noget andet end det, programmøren har tilsigtet:

public class ProgramMedFejl
{
  public static void main (String[] arg)
  {
    System.out.println("Hej Verdne!");
    int sum = 2 - 2;
    System.out.println("2 og 2 er "+sum);
  }
}

Hej Verdne!
2 og 2 er 0

Dette eksempel har en stavefejl og en forkert udregning. I afsnit 0.5.4 om uendelige løkker så vi en anden fejl, der gjorde, at programmet aldrig stoppede. Et andet eksempel kunne være et skatteprogram, der glemmer at tage højde for bundfradraget.

2.7.2 Sproglige fejl

Mens computeren ikke har mulighed for, at finde indholdsmæssige fejl i programmerne, kan den godt finde sproglige og syntaksmæssige problemer, dvs. hvis kildekoden gør brug af ukendte variabler eller metoder, eller ikke er gyldig i forhold til sprogets syntaks (den formelle definition af, hvordan man skriver javakode).

Hvis der er sproglige fejl i kildekoden, kan den ikke oversættes til bytekode, så man kan altså overhovedet ikke komme til at prøve sit program. De følgende instruktioner er alle forkerte og vil blive fanget under oversættelsen af programmet. Ofte kan fejlmeddelelsen overraske lidt, men med lidt øvelse kan man lære at forstå den "firkantede" måde, som computeren "tænker" på:

    System.out.println("Hej verden!);

Her mangler en slut-" til at markere, hvor strengen stopper. Compileren skriver unclosed character literal. Den kan ikke regne ud, at strengen slutter lige før ')'.

    System.out.pintln("Hej verden!");

Kaldet til println er stavet forkert. Compileren skriver method pintln(java.lang.String) not found in class java.io.PrintStream. Den kan ikke finde ud af, at man mener println (med r) i stedet for pintln.

    system.out.println("Hej verden!");

System er stavet forkert (med småt). Compileren skriver cannot access class system.out; neither class nor source found for system.out. Den skelner mellem store og små bogstaver og kan ikke se, at man mener System (med stort) i stedet for system.

    System.out.println(Hej verden!);

Der mangler " til at markere, hvor strengen starter og slutter. Compileren skriver ')' expected og peger lige efter Hej. Den forstår ikke at "Hej verden!" er en tekststreng, når "-tegnene mangler og mener derfor, at 'Hej' og 'verden!' skal behandles adskilt.

Når man skal finde en fejl, gælder det om at nærlæse fejlmeddelelsen og programkoden omkring stedet, hvor fejlen er og at huske, at computeren følger faste regler, men ikke forstår, hvad der foregår. F.eks. er den sidste fejlmeddelelse ')' expected ikke særlig sigende, da fejlen formentlig er, at der mangler "-tegn.

Det kan være banaliteter, der er årsag til sprogfejl. Det giver ofte anledning til sprogfejl, at folk glemmer, at der er forskel på store og små bogstaver.

Java skelner altid mellem store og små bogstaver
Det er god stil konsekvent at skrive klassenavne med stort og variabler og metoder med småt

2.7.3 Køretidsfejl

Visse fejl opstår først ved udførelsen af programmet. Selvom alting er syntaktisk korrekt, opstår der alligevel en undtagelse fra den normale programudførelse.

Herunder ses et program, der stopper på grund af division med 0.

public class ProgramMedFejl2
{
  public static void main (String[] arg)
  {
    int a,b,c;

    a = 5;
    b = 6;

    c = b/(a-5);
    System.out.println("c = "+c);
  }
}

Exception in thread "main" java.lang.ArithmeticException: / by zero
        at ProgramMedFejl2.main(ProgramMedFejl2.java:10)

Køretidsfejl forårsager, at der opstår en undtagelse (eng.: exception), som, hvis den ikke håndteres, stopper programudførelsen (programmet 'går ned').

Dette vil blive behandlet grundigere i kapitel Fejl: Henvisningskilde ikke fundet om exceptions.

2.8 Test dig selv

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.9 Resumé

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.9.1 Gode råd om programmering

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.10 Opgaver

Oversæt og kør et af dine egne programmer fra kommandolinjen (se afsnit 0.1.4).

2.10.1 Befordringsfradrag

Lav et program, som udregner befordringsfradraget (det, der kan trækkes fra i skat ud fra, hvor langt der er mellem arbejde og hjem).

  1. Udregn og udskriv fradraget pr. dag fra 25 til 75 km på hver sin linje.

  2. Udregn og udskriv fradraget pr. dag fra 25 til 150 km på hver sin linje.

  3. Udregn og udskriv fradraget pr. dag fra 10 til 150 km på hver sin linje. Kun hver 10. km udskrives (10km, 20km, 30km...). Reglerne for fradraget for år 2013 var:
    De første 24 km intet fradrag
    25 - 120 km 213 øre pr. km
    over 120 km 107 øre pr. km

2.10.2 Kurveprogram

Denne opgave benytter begreber, som man lærer i f.eks. den matematiske gren af gymnasiet. Kender du ikke i forvejen disse begreber, bør du springe opgaven over, de er ikke nødvendige for at lære at programmere.

  1. Skriv et program, der udskriver grafen over kvadratrod-funktionen (Math.sqrt()).
    Vink: Når du vil skrive en "*" uden linjeskift, kan du bruge System.out.print("*") (dvs. uden 'ln'). Når du vil skifte linje, kan du bruge System.out.println() uden parametre.

  2. Lav kurveprogrammet om, så det i stedet viser kurven over polynomiet 0.2*x*x +0.5*x +2. Lav programmet, så det er nemt at se, hvor man skal rette, for at ændre funktionen, intervalstart, intervalslut, skalering og forskydning af y-aksen. Dvs. lav det til variabler og brug kommentarer, til at markere stederne i programmet.

  3. Lav om på kurvetegningsprogrammet, så kurven ikke er udfyldt, men tegnes som en streg.

  4. Eventuelt: Udvid kurveprogrammet til at udregne det totale antal af stjerner, der skrives ud (udregn integralet af funktionen numerisk ved at summere arealet under grafen). Er det nemmest at gøre løbende, mens stjernerne tegnes, eller bagefter? Hvordan ville du gøre på den ene og på den anden måde?

2.11 Appendiks

Dette afsnit sætter det, du har lært i kapitlet, i system og kan senere bruges som opslagsværk. Enkelte steder står der noget, som ikke er gennemgået endnu, men som er med for helhedens skyld.

2.11.1 Navngivningsregler

Variabler og metoder bør starte med et lille bogstav.
Eksempler: n, alder, tal, talDerSkalUndersøges, main(), println(), sqrt().

Klasser bør starte med et stort startbogstav.
Eksempler: HejVerden, Cylinderberegning, Syvtabel2

Består navnet af flere ord, stryger man normalt mellemrummene og lader hvert af de efterfølgende ord starte med stort (nogen bruger også understreg _ som mellemrum).

Da filer med æ, ø og å i navnet kan være svære at flytte mellem Mac, Windows og Linux, bør man undgå æøå i klassenavne. De kan godt bruges i kommentarer, variabler og metoder, men måske skal du ændre tegnindkodningen i dit udviklingsværktøj (i Netbeans er det Project Properties|Sources|Encoding) mellem UTF-8 (Unicode) og ISO-8859-1 (vesteuropæisk).

2.11.2 De simple typer

Her er en oversigt over alle de simple variabeltyper i Java.

Type

Art

Antal bit

Mulige værdier

Standardværdi

byte

heltal

8

-128 til 127

0

short

heltal

16

-32768 til 32767

0

int

heltal

32

-2147483648 til 2147483647

0

long

heltal

64

-9223372036854775808 til 9223372036854775807

0

float

kommatal

32

±1.40239846E-45 til ±3.40282347E+38

0.0

double

kommatal

64

±4.94065645841246544E-324 til

±1.79769313486231570E+308

0.0

char

Unicode tegn

16

\u0000 til \uffff (0 til 65535)

\u0000

boolean

logisk

1

true og false

false

De vigtigste er int, double og boolean. I enkelte tilfælde bliver long og char også brugt, mens byte, short og float meget sjældent bruges.

2.11.3 Værditypekonvertering

Konvertering til en anden type sker automatisk (implicit) i tilfælde, hvor der ikke mistes information (forstået på den måde, at intervallet af de mulige værdier udvides), dvs.

  • fra byte til short, int, long, float eller double

  • fra short til int, long, float eller double

  • fra int til long, float eller double

  • fra long til float eller double

  • fra float til double.

Den anden vej, dvs. hvor der muligvis mistes information, fordi intervallet af mulige værdier indsnævres, skal man skrive en eksplicit typekonvertering.

Det gøres ved at skrive en parentes med typenavnet foran det, der skal konverteres:

int x;
double y;
y = 3.8;
x = (int) y

Her skæres kommadelen af 3.8 væk og x får værdien 3.

Eksplicit typekonvertering sikrer, at programmøren er bevidst om informationstabet (glemmes det, kommer compileren med fejlen: possible loss of precision: double, required: int).

Det skal ske

  • fra double til float, long, int, short, char eller byte

  • fra float til long, int, short, char eller byte

  • fra long til int, short, char eller byte

  • fra int til short, char eller byte

  • fra short til char eller byte

  • fra byte til char

  • fra char til short eller byte.

Der kan ikke typekonverteres til eller fra boolean.

2.11.4 Aritmetiske operatorer

Operator

Brug

Forklaring

+

a + b

a lagt sammen med b

-

a - b

b trukket fra a

*

a * b

a gange b

/

a / b

a divideret med b

%

a % b

rest fra heltalsdivision af a med b

-

-a

den negative værdi af a

++

a++

a = a+1; værdi før optælling

++

++a

a = a+1; værdi efter optælling

--

a--

a = a-1; værdi før nedtælling

--

--a

a = a-1; værdi efter nedtælling

Operatorerne giver altid samme type som operanderne, der indgår. Det skal man være specielt opmærksom på for / (divisions) vedkommende, hvor resten mistes ved heltalsdivision (f.eks er 4/5 = 0). Resten kan findes med % (f.eks er 4%5 = 4, mens 6%5 = 1). Ønskes division med kommatal, skal mindst en af operanderne være et kommatal (f.eks er 4.0/5 = 0.8).

Operatoren ++ tæller en variabel op med én : a++ svarer til a=a+1. Tilsvarende er a-- det samme som a=a-1.

2.11.5 Regning med logiske udtryk

u1 og u2 er to logiske udtryk eller logiske variabler

Operator

Brug

Forklaring

&&

u1 && u2

både u1 og u2 er opfyldt

||

u1 || u2

u1 eller u2 er opfyldt

!

! u1

negation af u1

I andre programmeringssprog skrives AND for &&, OR for || og NOT for !

Operator && udtrykker, at både 1. og 2. udtryk skal være opfyldt:

1. udtryk

2. udtryk

1. udtryk && 2. udtryk

false

false

false

false

true

false

true

false

false

true

true

true

F.eks. er udsagnet a > 5 && a < 10 opfyldt, hvis a er større end 5 og a er mindre end 10.

Operator || udtrykker, at 1. eller 2. udtryk skal være opfyldt.

1. udtryk

2. udtryk

1. udtryk || 2. udtryk

false

false

false

false

true

true

true

false

true

true

true

true

F.eks. er udsagnet a > 5 || a == 0 opfyldt, hvis a er større end 5, eller a er 0.

Operator ! udtrykker, at udtrykket skal negeres, dvs. at !u1 er opfyldt, hvis u1 er false, og ikke opfyldt, hvis u1 er true. F.eks. læses udsagnet !(a>5) som 'hvis det ikke gælder, at a er større end 5'. Det er i øvrigt det samme som a<=5 og bør omskrives så det er enklere.

Tommelfingerregel for forenkling af udtryk

En negering kan ophæves ved at bytte om på && og || og negere udtrykkene indeni: Generelt gælder at !(u1||u2) = (!u1)&&(!u2) …. og at !(u1&&u2) = (!u1)||(!u2).

F.eks. kan 'a er ikke mellem 5 og 10', altså !(5<=a && a<=10), omskrives til 'a er mindre end 5 eller større end 10', altså 5<a || a>10.

2.11.6 Sammenligningsoperatorer

Operator

Brug

Forklaring

>

a > b

a større end b

>=

a >= b

a større end el. lig med b

<

a < b

a mindre end b

<=

a <= b

a mindre end el. lig med b

==

a == b

a er lig med (identisk med) b

!=

a != b

a forskellig fra b

2.12 Avanceret

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.1 Grafiske indtastningsvinduer

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.2 Formatere tal og datoer

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.3 Primtal

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.4 Klassemetoder

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.5 Kombination af logiske operatorer

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.6 Alternativudtryk

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.7 Brug af ++ og -- (optælling og nedtælling)

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.8 Brug af += og -=

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.9 Komma i for-løkker

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.10 do-while-løkken

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.11 break

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.12 continue

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.13 break og continue med navngivne løkker

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.14 switch

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

2.12.15 Opremsninger (Enumerations)

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

1I Windows åbner du en DOS-prompt ved at klikke i menuen Start, vælge 'Kør...' og skrive 'cmd'.

2Er HejVerden.java i mappen C:\javafiler så skriv 'cd C:\javafiler' (og tryk retur-tasten).

3Måske skal du angive den fulde sti til javac, f.eks. C:\jdk1\bin\javac HejVerden.java

4Kan klassen HejVerden ikke findes (NoClassDefFoundError) så prøv: java -cp . HejVerden

5Egentlig kun til et tal mellem -2147483648 og 2147483647, da der kun er reserveret 32 bit (4 byte).

6Der er altså ikke tale om en matematisk ligning, der altid skal gælde, men om en tildeling, hvor variablen på venstre side får tildelt værdien af udtrykket på højresiden.

7Man kan med operatoren % finde resten af divisionen. 13 % 5 giver altså 3, fordi 13 - 5*2 = 3.

8Opkaldt efter den britiske matematiker George Boole, 1815-64.

9De, som kender Pascal, vil genkende { som BEGIN og } som END.

1030-50 % af de problemer, nybegyndere har med at få deres programmer til at virke, skyldes dårlig indrykning, som gør koden uoverskuelig.

11På et tidspunkt når n til -2147483648. Variablens 32-bit kapacitet vil være opbrugt og n vil faktisk skifte til 2147483647, som er større end 10, hvorved løkken vil stoppe, men der er næppe nogen, der gider vente så længe!

12hvilket er noget ganske andet end uendelig lykke!

13Med metoden Math.round(x) kan man få den normale afrunding, hvor 3.5 rundes op til 4 og 3.4999 rundes ned til 3.

14Man skal være opmærksom på, at hvis det konverteres fra et meget stort tal, kan det være, at den nye type ikke kan repræsentere tallet. F.eks. vil konvertering fra 10000000000000.0 til int ikke give det forventede, da det største tal, int kan rumme, er 2147483647.
Ved typekonverteringen fra int til float mistes også noget præcision (de mindst betydende cifre).

15 Den ser ikke engang, om en konstant værdi uproblematisk kan konverteres: int x; x=4.0; //Fejl

javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen
http://javabog.dk/ - Forord af Jacob Nordfalk.
Licens og kopiering under Åben Dokumentlicens (ÅDL) hvor intet andet er nævnt (79% af værket).

Ønsker du at se de sidste 21% af dette værk (267325 tegn) skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.