Indhold:
Variabler, tildelinger og regneudtryk
Forgreninger og løkker
Kald af metoder
Kapitlet forudsættes i resten af bogen.
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.
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.
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 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)
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.
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.
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
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.
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).
En variabel af type
Efter
1. tildeling
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
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
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
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.
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;
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...
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.
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.
Skriv et program, som ud fra længde og bredde på et rektangel udskriver dets areal.
Skriv et program, som for ligningen y=3*x*x+6*x+9 udskriver værdien af y for x=7.
Skriv et program, som omregner et beløb fra dollar til euro (f.eks. kurs 95).
Skriv et program, som udskriver tre tilfældige tal (lavet med Math.random()), deres sum og gennemsnittet.
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);
}
}
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
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.:
hvis du er over 18, er du myndig.
hvis din alkoholpromille er større end 0.5, så lad bilen stå.
hvis den koster mindre end 500 kr, så køb den!
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
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.
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).
Logikken
i en if-else-sætning
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.
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!");
Skriv Alder2 om til at indeholde flere aldergrænser.
Lav et veksleprogram fra dollar til euro. Det skal påregne en kommission på 2 %, dog mindst 0,5 euro.
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.
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.
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.
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).
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.
Logikken
i en while-løkke
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.
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
initialisering er en (evt.: erklæring
og) tildeling af en tællevariabel,
f.eks. alder
= 15
betingelse er et logisk udtryk, der
angiver betingelsen for, at løkken skal fortsætte
med at blive udført,
f.eks. alder
< 18
opdatering er ændringen i
tællevariablen,
f.eks. alder
= alder + 1
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)
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--.
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
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.
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").
Lav et program, der tæller nedad fra 10 til 1.
Lav et program, der udregner værdien af 1+2+3+ ... +20 med en løkke.
Lav et program, der udskriver 2-tabellen, 3-tabellen, .. op til 10-tabellen.
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.
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)
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:
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.
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:
Der er åbenlyst et informationstab, da kommadelen af værdien må fjernes.
Derudover kunne double-værdien være et meget stort tal (f.eks. 5 mia. i stedet for 2.7), som ikke kan rummes i en int (der kun kan rumme tal fra -2 mia. til +2 mia).
Konverteringen kan foretages på flere måder. Skal man afrunde korrekt op til 3 eller nedrunde til 2?
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.
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.
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.
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.
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.
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.
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
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.
Oversæt og kør et af dine egne programmer fra kommandolinjen (se afsnit 0.1.4).
Lav et program, som udregner befordringsfradraget (det, der kan trækkes fra i skat ud fra, hvor langt der er mellem arbejde og hjem).
Udregn og udskriv fradraget pr. dag fra 25 til 75 km på hver sin linje.
Udregn og udskriv fradraget pr. dag fra 25 til 150 km på hver sin linje.
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
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.
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.
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.
Lav om på kurvetegningsprogrammet, så kurven ikke er udfyldt, men tegnes som en streg.
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?
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.
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).
Navnet kan bestå af A-Å, a-å, 0-9, $ og _
Det må ikke starte med et tal. Det kan have en vilkårlig længde.
Lovlige navne: peter, Peter, $antal, var2, J2EE, dette_er_en_test
Ulovlige navne: 7eleven, dette-er-en-test, peter#
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).
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.
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.
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.
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.
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
.
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 |
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