6 Loopar och val Lite logik Val mellan två alternativ Val mellan flera alternativ Sammansatta villkor Boolska variabler Jämför strängar While-loopar Do-loopar For-loopar Kortformer
Kap 6: Sid 2 Lite logik Boolska uttryck och selektioner Boolska uttryck (logiska uttryck, villkorsuttryck) behandlade vi i kapitel 2. Vi repeterar: Ett boolskt uttryck är något som antingen har värdet true eller värdet false Exempel: 100 är större än 10 är true 100 är lika med 10 är false Vi använder nedanstående jämförelseoperatorer i dessa uttryck. I tabellen antar vi att a = 100 och b = 10 Betydelse Operator Exempel Värde mindre än < a < b false mindre än eller lika med <= a <= 100 true större än > a > b true större än eller lika med >= b >= 9 true lika med == a == b false ej lika med (skilt från)!= a!= b true Observera att likhet skrivs med dubbelt likhetstecken! (Enkelt likhetstecken betyder ju tilldelning. Exempel: a = 100; betyder att variabeln a får värdet 100) Java6_LooparoVal.doc Ove Lundgren 2
Kap 6: Sid 3 Val mellan två alternativ If-satsen Du är redan bekant med if-satsen: Efter if skriver man ett villkorsuttryck (ett boolskt uttryck, det vill säga något som är true eller false) och därefter ett block med de satser som ska exekveras om villkoret är sant. Så här: if (villkor) Om vi vill att något ska hända om villkorssatsen är falsk så bygger vi på med en else-gren: Så här: if (villkor) else Övning: Betyg Skapa mappen X\java\Betyg Du ska skriva en applet där man kan mata in ett tal (en poäng på ett prov). Efter att man tryckt på en knapp (eller slagit ENTER-tangenten) ska följande ske: Om poängen är minst 50 (d v s större än eller lika med 50)så texten "Godkänd" visas med grön färg annars texten "Underkänd" visas med röd färg. Källkoden ska sparas med namnet Betyg.java. Skriv också en enkel HTML-fil (Betyg.html) som startar appleten. Du behöver importera klasserna: TextField, Button, Label, Color och Graphics Alla finns i paketet java.awt. Med satsen import java.awt.*; får du tillgång till alla klasserna i det paketet. Vi behöver också paketet med klasser för händelsehantering. Skriv alltså: import java.awt.event.*; På nästa sida finns ett lösningsförslag Java6_LooparoVal.doc Ove Lundgren 3
Kap 6: Sid 4 //Övning Betyg import java.awt.*; import java.awt.event.*; import java.applet.*; public class Betyg extends Applet implements ActionListener // Deklarationer Label ledtext; Button butt; TextField inruta1; int poang ; public void init() ledtext = new Label("Skriv in poäng"); inruta1 = new TextField(10); inruta1.addactionlistener(this); butt = new Button("Tryck här"); butt.addactionlistener(this); add(ledtext); add(inruta1); add(butt); poang = 50; public void paint(graphics g) if (poang >= 50) g.setcolor(color.green); g.drawstring("godkänd ",10,90); else g.setcolor(color.red); g.drawstring("underkänd ",10,90); public void actionperformed(actionevent e) poang = Integer.parseInt( inruta1.gettext() ); repaint(); Spara - kompilera - provkör! Om ett block innehåller en enda sats behöver man inte ha med "krullparenteserna". Exempel: if (poang >= 50) g.drawstring("godkänd ",10,90); else g.drawstring("underkänd ",10,90); Java6_LooparoVal.doc Ove Lundgren 4
Kap 6: Sid 5 Konditionaloperatorn Ett annat sätt att skriva närmast ovanstående är följande: g.drawstring( poang >= 50? "Godkänd" : "Underkänd",10,90); Konstruktionen poang >= 50? "Godkänd " : "Underkänd" levererar värdet "Godkänd" om villkoret är sant, annars ges värdet "Underkänd".? : kallas konditionaloperatorn. Du känner kanske igen idén från kalkylprogram: I Excel skulle vi använda formlen =OM( A1 >= 50 ; "Godkänd" ; "Underkänd" ) Nästlade if-satser Studera följande algoritm: Om poängen >= 90 så texten "MVG" visas med blå färg annars om poäng >= 75 så texten "VG" visas med gul färg annars om poäng >= 50 så texten "G" visas med grön färg annars texten "IG" visas med röd färg Om det första villkoret är falskt sker en test på ett nytt villkor, om detta är falskt sker en ny test osv. En sådan här konstruktion kallas för en nästlad if-sats. Java-koden för ovanstående algoritm blir så här: if (poang >= 90) g.setcolor(color.blue); g.drawstring("mvg",10,90); else if (poang >= 75) g.setcolor(color.yellow); g.drawstring("vg",10,90); else if (poang >= 50) g.setcolor(color.green); g.drawstring("g",10,90); else g.setcolor(color.red); g.drawstring("ig",10,90); Övning: Betyg - igen Byt ut if-satsen i Betyg.java mot ovanstående nästlade if-sats. Du får också lägga till några färger. Spara - kompilera - kör Java6_LooparoVal.doc Ove Lundgren 5
Kap 6: Sid 6 Val mellan fler alternativ switch-satsen Med switch-satsen kan man testa värdet hos en variabel (av typ int eller char) mot flera givna värden. Låt oss anta att t är namnet på en char-variabel och att vissa saker ska hända om t har värdet 'A', andra saker ska hända om t har värdet 'B' osv. Syntax: switch (t) case 'A': break; case 'B': break; case 'C': break; Observera att varje "gren" måste brytas med break Övning: SwitchTest Skriv koden på nästa sida. Det är en applet där du i en textruta kan skriva in en bokstav (R, G eller B) och trycka på ENTER. Beroende på vilket tecken du matar in blir bakgrundsfärgen röd, grön eller blå. Switch-satsen ombesörjer det hela. För inmatningen använder vi (som vanligt) en textruta. Metoden gettext ger som bekant en textsträng. Men vi använde ju ett tecken (datatypen char) i switch-satsen. charat() är en metod i klassen String som fungerar så här: Om s är en textsträng så ger s.charat(0) det första tecknet (tecken nummer 0) i strängen s som ett tecken (d v s en char) Om s har värdet "Kalle" så skulle s.charat(0) få värdet 'K' I vårt fall ger således inruta1.gettext().charat(0) det första tecknet i den sträng som matas in i inruta1 Spara koden som SwitchTest.java i mappen X\java\SwitchTest Skriv också en enkel HTML-fil (SwitchTest.html) som startar appleten. Kompilera javafilen - provkör Java6_LooparoVal.doc Ove Lundgren 6
Kap 6: Sid 7 //Övning SwitchTest import java.awt.*; import java.awt.event.*; import java.applet.*; public class SwitchTest extends Applet implements ActionListener // Deklarationer Label ledtext; TextField inruta1; char fargkod; public void init() ledtext = new Label("Skriv R, G eller B "); inruta1 = new TextField(10); add(ledtext); add(inruta1); inruta1.addactionlistener(this); public void paint(graphics g) switch (fargkod) case 'R': g.drawstring("röd färg",10,100); this.setbackground(color.red); break; case 'G': g.drawstring("grön",10,100); this.setbackground(color.green); break; case 'B': g.drawstring("blå",10,100); this.setbackground(color.blue); break; public void actionperformed(actionevent e) fargkod = inruta1.gettext().charat(0); repaint(); Man kan låta flera olika variabelvärden leda till samma "gren". I vårt exempel ovan skulle man exempelvis kunna skriva case 'R': case 'r': så kommer bakgrunden att bli röd även om man skriver in ett gement 'r'. Testa! Java6_LooparoVal.doc Ove Lundgren 7
Kap 6: Sid 8 Sammansatta villkorssatser Ett boolsk uttryck (ett villkorsuttryck) har antingen värdet true eller false. Ibland kan ett villkor vara sammansatt av flera villkor. Exempel: Om ( kön == M OCH ålder > 20) så Hela, det sammansatta, villkoret är sant om båda de ingående villkoren är sanna. Exempel: Om ( bokstav == A ELLER bokstav == B ) så Hela villkoret är sant om minst ett av de ingående villkoren är sanna. Orden OCH och ELLER, som används för att sätta samman flera villkors till en enda, kallas för logiska operatorer. I tabellen nedan är A ett villkor (ett boolskt uttryck) och B ett annat villkor A OCH B och A ELLER B är sammansatta villkor. S = sant, F = falskt A B A OCH B A ELLER B S S F F S F S F S F F F S S S F I de flesta programspråk uttrycks logiskt OCH med AND, och logiskt ELLER med OR (Exempelvis i Pascal: IF (a>10) AND (b>30) THEN ) I Java (och i C++ ) uttrycks logiskt OCH med operatorn && och logiskt ELLER med operatorn ( pipe-tecknet,, hittar du på samma tangent som minde än - och större än -tecknen näst längst till vänster på tangentbordet) Exempel: I ett javaprogram vill vi testa om båda variablerna x och y är positiva. Vi skriver: if ( x > 0 && y > 0 ) kod Om vi vill testa att minst en av variablerna är positiv skriver vi: if ( x > 0 y > 0 ) kod Ytterligare en logisk operator bör du känna till, nämligen ICKE. Denna operator heter NOT på de flesta språk. I Java ser den ut så här:! (ett utropstecken, alltså) Exempel: if (!( a > b) ) kod Villkoret efter if är sant om det inte gäller att a är större än b Vi ska testa sammansatta villkor i ett enkelt konsolprogram (se nästa sida). Java6_LooparoVal.doc Ove Lundgren 8
Kap 6: Sid 9 Övning: IfTest Klassen Prompt har (bl a) metoderna heltal och decimaltal som ger enkel inmatning av tal. class IfTest public static void main( String args[] ) int x,y; x = Prompt.heltal("Ange x"); y = Prompt.heltal("Ange y"); if (x > 0 && y > 0) System.out.println("Båda positiva"); else if (x > 0 y > 0) System.out.println("Ett tal är positivt"); else System.out.println("Inget är positivt"); Skriv koden ovan. Spara den som IfTest.java i mappen X\java\Javagrunder (kap 1) Se till att filen Prompt.class finns i samma mapp (eller i en mapp i classpath-listan) Kompilera. Kör programmet. Ge x och y positiva värden. Kör igen, nu med olika tecken på x och y Kör återigen med negativa värden på x och y Java6_LooparoVal.doc Ove Lundgren 9
Kap 6: Sid 10 Boolska variabler Du har lärt dig dessa primitiva datatyper: int heltal ( t ex 17 ) double flyttal (decimaltal) ( t ex 23.5 ) char tecken ( t ex 'X' ) Ytterligare en ska du lära dig, nämligen datatypen boolean. En variabel av datatypen boolean kallas en boolsk variabel. En sådan variabel kan ha ett av två värden: true eller false Övning: Boolsk variabel I programmet nedan deklareras den boolska variabeln myndig. Användaren matar in ett värde på heltalsvariabeln alder Den boolska variabeln myndig får värdet av villkorsuttrycket alder > 17 det vill säga myndig blir true eller false if-satsen använder myndig för att avgöra vad som ska skrivas ut. class BoolTest public static void main( String args[] ) int alder; boolean myndig; alder = Prompt.heltal("Skriv din alder: "); myndig = alder > 17; if ( myndig ) System.out.println("Du ar myndig!"); else System.out.println("Du ar inte myndig..."); Testa! Spara i X\java\Javagrunder Jämför strängar När vi testar likhet används dubbelt likhetstecken ( == ). Detta gäller för primitiva datatyper (int, double, char och boolean). Om vi vill testa likhet mellan objekt måste vi använda en funktion som heter equals() Övning: Testa likhet mellan strängar Textsträngar är objekt av typen String. Testa detta program som visar hur equals-funktionen används: Spara i X\java\Javagrunder class StringTest public static void main( String args[] ) String ort; ort = Prompt.strang("Var bor du? "); if (ort.equals("hjo")) System.out.println("Du bor i Hjo"); else System.out.println("Du bor inte i Hjo"); Java6_LooparoVal.doc Ove Lundgren 10
Kap 6: Sid 11 While-loopar En loop (en slinga, en iteration) är programsatser som genomlöps flera gånger. Övning: WhileTest Vi vill att strängen "Java är kul" ska skrivas 10 gånger i ett konsolprogram. Så här kan programmet se ut: class WhileTest public static void main( String args[] ) int i; i=0; while (i<10) i = i + 1; System.out.println("Java är kul"); Heltalet i ges värdet 0 Vid while sker en test: Är i<10? Om så är fallet utförs de satser som står i blocket som följer, nämligen satsen i = i + 1, dvs i ökar sitt värde med 1 (i blir 1), och utskriften "Java är kul" sker. Därefter sker en ny test: Är fortfarande i<10? Om så är fallet utförs satserna i blocket igen, i = i + 1, dvs i ökar sitt värde med 1 (i blir 2), och "Java är kul" skrivs ut igen. Det hela upprepas (itereras) tills villkoret inte är sant (dvs till dess i inte längre är mindre än 10) Skriv in koden ovan. Spara som WhileTest.java i mappen X\java\Javagrunder Kompilera och kör. Notera: En while-loop utförs noll, en eller flera gånger. Den utförs så länge while-villkoret är true. Det är viktigt att den variabel som testas i villkorssatsen förändras inne i loopen (annars kommer aldrig villkoret att bli falskt, d v s iterationen tar aldrig tar slut - vi har då hamnat i en oändlig loop!) Två skrivsätt för räknare Satsen i = i + 1 ; visar hur man konstruerar en räknare i dataprogram. För varje "varv" kommer ju variabeln i att öka sitt värde med 1 Du minns kanske (från kapitel 2) att Java (och C++ ) har ett kortare skrivsätt för i = i + 1; Man kan i stället skriva så här: i++ ; Java6_LooparoVal.doc Ove Lundgren 11
Kap 6: Sid 12 Övning: Kapitaltillväxt Hur lång tid tar det för ett kapital som sätts in på bank att växa till ett visst belopp? Vi deklarerar flyttalen kapital, ranta och slutbelopp samt heltalet ar. Vi använder metoderna i Prompt-klassen för att tilldela värden: ar (årtalet då kapitalet sätts in på banken, t ex 1999) kapital (det insatta kapitalets storlek, t ex 1000) ranta (den aktuella räntesatsen, t ex 4.5) slutbelopp (det belopp som vi vill att kapitalet ska växa till, t ex 2000) class Kapital public static void main( String args[] ) double kapital, ranta, slutbelopp; int ar; ar = Prompt.heltal("Vilket år sätts beloppet in? "); kapital = Prompt.decimaltal("Vilket kapital sätts in?"); ranta = Prompt.decimaltal("Hur stor är räntesatsen?"); slutbelopp = Prompt.decimaltal("Vilket är slutbeloppet?"); while (kapital < slutbelopp) ar++; kapital = kapital * ( 1 + ranta/100); System.out.println("År " + ar + "är kapitalet " + kapital); Om kapitalet är mindre än slutbeloppet sker följande: Året räknas upp med 1 Kapitalets värde efter ett år beräknas Kapitalets värde skrivs ut Iterationen fortsätter så länge villkoret är sant, dvs att kapitalet är mindre än slutbeloppet. Skriv in programmet. Spara det som Kapital.java i mappen X\java\Javagrunder Kompilera Provkör några gånger med olika värden. Bestäm t ex: Hur lång tid tar det för ett kapital att fördubblas då räntan är 8.5 % Hur lång tid tar det för ett kapital att fördubblas då räntan är 3 % Java6_LooparoVal.doc Ove Lundgren 12
Kap 6: Sid 13 Do-loopar I while-loopen ligger villkorssatsen före slingan (vilket innebär att satserna i loopen kanske inte alls kommer att utföras) I do-loopen ligger villkoret efter slingan, vilket innebär att loopen genomlöps åtminstone en gång. Så här ser den ut: do... while ( villkor ); Övning: Upprepa beräkning Ta fram filen Summera2.java (kapitel 1) Lägg satser för inmatning, beräkning och utskrift i en do-loop Loopen fortsätter så länge man svarar j eller J class Summera2 public static void main( String args[] ) int x, y, s; char fortsatt; do x = Prompt.heltal("Skriv ett tal: "); y = Prompt.heltal("Skriv ett tal till: "); s = x + y; System.out.println("Summan är " + s); fortsatt = Prompt.tecken( Ny beräkning? ( J/N ) ); while ( fortsatt == j fortsatt == J ); Java6_LooparoVal.doc Ove Lundgren 13
Kap 6: Sid 14 For-loopar while-loopen och do-loopen upprepas så länge ett visst villkor är sant. Ofta vet vi inte från början hur många varv en sådan loop genomlöps. Om man vill bygga en loop där man vet hur många iterationer som ska göras kan man använda en while-loop och en räknare så som visades i övningen WhileTest ovan. Vanligen använder man i sådana fall en for-loop. (Sådana har du träffat på tidigare i kapitel 2 ) Uppgiften att skriva "Java är kul" 10 gånger löses så här med en for-loop: class ForTest public static void main( String args[] ) int j; j räknas upp med 1 varje varv for(j=0; j<10; j++) System.out.println("Java är kul"); j är noll första "varvet" Loopen fortsätter så länge detta villkor gäller, d v s j är 9 sista "varvet" Övning: ForTest Testa programmet ovan. Ändra sedan utskriften till System.out.println( j + " Java är kul"); så ser du värdet hos j för varje varv. Ändra sedan i for-satsen, så att den ser ut så här: for( j=15; j>0; j-- ) Spara det som ForTest.java i mappen X\java\Javagrunder Provkör. Studera hur värdet hos j ändras. Om loopvariabeln I exemplen ovan har vi deklarerat loopvariabeln, j, före loopen. Man kan även deklarera den inne i loopen, så här: for(int j=0; j<10; j++)... Variabeln har då räckvidd (gäller) endast inne i loopen, den existerar inte utanför. Loopvariabeln är oftast ett heltal (int) men kan även deklareras som flyttal (double) Java6_LooparoVal.doc Ove Lundgren 14
Kap 6: Sid 15 Kortformer Vi har tidigare sett att satsen i = i + 1 kan skrivas i++ I övningen ovan ser du att j = j - 1 kan skrivas j-- I Java finns fler kortformer. Du behöver inte använda dem (om du inte vill) men det är bra att känna igen dem. Här är en liten sammanställning: i = i + 1 kan skrivas i += 1 eller i++ j = j - 1 " " j -= 1 eller j-- a = a + 5 " " a += 5 b = b - 7 " " b -= 7 c = c * 3 " " c *= 3 d = d / 2 " " d /= 2 Övning: ForTest - igen Ändra for-satsen i föregående övning till for( j=2; j<=10; j+=2 ) Studera hur värdet på j ändras Nedan följer några övningar där du huvudsakligen använder for-loopen: Java6_LooparoVal.doc Ove Lundgren 15
Kap 6: Sid 16 Övning: Streck Skriv en applet som ritar 6 horisontella, röda streck på en blå bakgrund, så här: Använd en for-loop Spara som Streck.java i mappen X\java\Streck Ungefär så här kanske din for-loop ser ut: for(int i=0; i<6; i++) g.drawline(10, 10 + i*10, 100, 10 + i*10); Lägg till vertikala streck så att ett rutnät bildas. Använd variabler så att du lätt kan ändra placering, antalet rader och kolumner i rutnätet, samt rutans storlek. Så här till exempel: int a =10, b = 10; // Rutnätets övre vänstra hörn punkten (a,b) int r = 5, k = 7; // Antal rader r och antal kolumner k int s = 15; // Rutans storlek s... for(int i = 0; i < r+1 ; i++) // ritar horisontella linjer g.drawline(a, b+s*i, a+k*s, b+s*i); for(int i = 0; i < k +1; i++) // ritar vertikala linjer g.drawline(a+s*i, b, a+s*i, b+r*s); Övning: Rutnätklass Skriv en klass, Rutnat, med instansvariablerna a, b, r, k och s (heltal) Variablerna r, k och s tilldelas värden i konstruktorn. Variablerna a och b tilldelas värden i en metod setposition(int a, int b) Metoden rita(graphics g) ritar rutnätet. Skriv en applet, VisaRutnat, som instansierar ett Rutnat-objekt och ritar det. Försök klara uppgiften själv! Lösningsförslag på nästa sida Java6_LooparoVal.doc Ove Lundgren 16
Kap 6: Sid 17 Lösningsförslag: import java.awt.*; public class Rutnat private int a,b,r,k,s; public Rutnat(int r, int k, int s) // konstruktor this.r = r; this.k = k; this.s = s; public void setposition( int a, int b) this.a= a; this.b = b; public void rita(graphics g) for(int i = 0; i < r+1 ; i++) g.drawline(a, b+s*i, a+k*s, b+s*i); for(int i = 0; i < k +1; i++) g.drawline(a+s*i, b, a + s * i, b+r*s); import java.applet.*; import java.awt.*; public class VisaRutnat extends Applet Rutnat r; public void init() r = new Rutnat( 5, 7, 15); r.setposition( 5, 10 ); public void paint(graphics g) r.rita(g); På nästa sida finns ytterligare övningar. Rita mönstren direkt i en applet, eller skriv klasser och låt sedan en applet skapa och rita objekt Java6_LooparoVal.doc Ove Lundgren 17
Kap 6: Sid 18 Övning: Cirklar och kvadrater Hitta på egna mönster. Rita t ex 20 cirklar med växande radie eller kvadrater i olika storlekar (och färger) Övning: Schackbräde Rita ett schackbräde: Java6_LooparoVal.doc Ove Lundgren 18