Lektion 4. Datateknik A, Java I, 5 poäng



Relevanta dokument
Föreläsning 7. Nyckelord I Java. Uttryck. Uttryck, Operatorer Och Kontrollflöden

Klassdeklaration. Metoddeklaration. Parameteröverföring

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Parameteröverföring. Exempel. Exempel. Metodkropp

TDIU01 - Programmering i C++, grundkurs

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

Programmering A. Johan Eliasson

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

Visual Basic, en snabbgenomgång

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Användarhandledning Version 1.2

Föreläsning 3: Typomvandling, villkor och val, samt textsträngar

F4. programmeringsteknik och Matlab

Programmeringsteknik I

Tentamen OOP

Språket Python - Del 1 Grundkurs i programmering med Python

1 Datorn som miniräknare. 1.1 Räkneoperationer. 1.2 Variabler

TDIU01 - Programmering i C++, grundkurs

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

Föreläsning 2. Variabler, tilldelning och kodblock{} if-satsen Logiska operatorer Andra operatorer Att programmera

F5 Selektion och iteration. ID1004 Objektorienterad programmering Fredrik Kilander

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Övning2. Variabler. Data typer

Objektorienterad Programmering (TDDC77)

I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program

LÖSNINGSFÖRSLAG TENTAMEN

SMD 134 Objektorienterad programmering

Objektorienterad Programmering (TDDC77)

Innehållsförteckning

Operatorer Tilldelning Kodblock { } if satsen Logiska uttryck Att programmera

Data, typ, selektion, iteration

Programmeringsteknik med C och Matlab

Programstruktur och terminologi. Programmet producerar följande utskrift i terminalfönstret: Ett Javaprogram består av en eller flera klasser

OOP Objekt-orienterad programmering

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Föreläsning 3: Booleans, if, switch

F2 Datatyper och variabler. ID1004 Objektorienterad programmering Fredrik Kilander

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy. Funktioner / metoder. Punktnotation. Evalueringsordning

System.out.println("Jaså du har "+ antalhusdjur+ " husdjur"); if ( antalhusdjur > 5 ) System.out.println("Oj det var många);

Hej Då, Karel! Programmering. Vårt första Javaprogram. hh.se/db2004. Java. Grundtyper, variabler och arrayer

Objektorienterad programmering Föreläsning 4

Lite logik. Kap 6: Sid 2

Objektorienterad programmering i Java

Beräkningsvetenskap föreläsning 2

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Föreläsning 2. Täcker material från lektion 1, 2, 3 och 4:

Föreläsning 2 Programmeringsteknik och C DD1316

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Strukturdiagram. Styra. Algoritmer. Val

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

C++ Slumptalsfunktioner + switch-satsen

PROGRAMMERING 2 GRUNDLÄGGANDE SEMANTIK 4

Föreläsning 3-4 Innehåll

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Laboration 1. Utgåva 1 Gäller från

LÖSNINGSFÖRSLAG TENTAMEN

Outline. For. I istället för att följa det normala ordningen, man ändra den. I i Java får man inte göra hopp hur som helst

Inledande programmering med C# (1DV402) Summera med while"-satsen

Inledande programmering med C# (1DV402) 27+15=42 1 (22)

JavaScript del 3 If, Operatorer och Confirm

Programmering för språkteknologer I, VT2012. Rum

TDDC77 Objektorienterad Programmering

TDDC77 Objektorienterad Programmering

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

Heltalsrepresentation. Fler byggstenar. Overflow och Underflow. TvŒ-komplement. FlyttalsvŠrden. Fyra heltalstyper. Tecken-bit

Logik och kontrollstrukturer

Typkonvertering. Java versus C

Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?

Grundläggande programmering med C# 7,5 högskolepoäng

C++ - En introduktion

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.

Introduktion C-programmering

Digitalitet. Kontinuerlig. Direkt proportionerlig mot källan. Ex. sprittermometer. Elektrisk signal som representerar ljud.

Introduktion till programmering SMD180. Föreläsning 2: Variabler, uttryck och satser

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Variabler och konstanter

JAVAUTVECKLING LEKTION 3

Datastrukturer. Erik Forslin. Rum 1445, plan 4 på Nada

Föreläsning 3. Iteration while-satsen

Java, klasser, objekt (Skansholm: Kapitel 2)

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

Iteration while-satsen

E02 "The Review" Föreläsning 2, HT2013 Grunderna, repetition. Johan Leitet. Kurs: 1dv403 Webbteknik I

i LabVIEW. Några programmeringstekniska grundbegrepp

Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk

Uttryck och villkor. Föreläsning 2

Lektion 7. Datateknik A, Java I, 5 poäng

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

OOP Objekt-orienterad programmering

För att skriva data till skärmen ( konsolen) används objektet System.out tillsammans med metoden println eller print.

Metodanrop - primitiva typer. Föreläsning 4. Metodanrop - referenstyper. Metodanrop - primitiva typer

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Objektorienterad programmering D2

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

PROGRAMMERING-Java Omtentamina

Transkript:

Datateknik A, Syfte: Att lära sig använda de primitiva typerna och olika operatorer för att bygga upp uttryck. Att använda kontrollflödeskonstruktioner för att styra flödet i programmet. Att stifta bekantskap med klassen Math. Att läsa: Kursboken, Kapitel 1 (sida 23 39) Kursboken, Kapitel 3 (sida 102 109) http://java.sun.com/docs/books/tutorial/java/nutsandbolts/index.html

Vi ska i denna lektion titta på något som många andra programmeringskurser börjar med, nämligen uttryck, operatorer och kontrollflöden. Vi tar även en titt på hur vi konverterar mellan olika datatyper och hur vi använder metoder i klassen Math för att utföra mer avancerade beräkningar. Robert Jonsson Sida 1

Vi börjar lektionen med att titta de reserverade nyckelord Java har (för närvarande 50 st). Dessa används för att uttrycka konstruktionen i språket, och får således inte användas som identifierare (namn på klasser, metoder eller variabler). Alla dessa nyckelord har en betydelse och syntaxen i Java beskriver hur dessa nyckelord får användas och kombineras med varandra. Nyckelorden const och goto används inte i språket men är ändå reserverade för att kompilatorn uttryckligen ska säga att dessa ord inte finns i Java (bägge finns i C++). En del av dessa (inte alla) kommer att förklaras under kursens gång (det är svårt att lära sig nyckelorden i någon slags bokstavsordning från abstract till while, vilket ni inte heller behöver kunna). Dessa nyckelord kan vi INTE använda som namn på identifierare till klasser, metoder och variabler. Man skulle kunna tro att false, true och null är nyckelord, men så är inte fallet. Robert Jonsson Sida 2

Ett uttryck i Java (och andra programmeringsspråk) beskriver någon form av bearbetning eller jämförelse och har alltid ett givet resultat. Resultatet är av en viss (data)typ och har ett värde. Uttrycket beskrivs genom att en operator appliceras på en eller flera s.k. operander. Ett exempel på uttryck är 5 + 2 som består av den aritmetiska operatorn + (addition) som appliceras på operanderna 5 och 2. Resultatet av uttrycket är av typen heltal och har värdet 7. Robert Jonsson Sida 3

Ett uttryck kan vara sammansatt av flera uttryck. Uttrycket x = 5 + 2 består dels av uttrycket på föregående bild och dels av ett uttryck bestående av operatorn = (tilldelning) som appliceras på operanderna x och uttrycket 5 + 2. Ett uttryck kan alltså vara en operand i ett annat uttryck. Även ett sammansatt uttryck har alltid ett resultat som är av en viss typ och som har ett visst värde. Detta resultat kan återigen användas vidare i andra former av uttryck. Ett krav som tilldelningsoperatorn har på sina operander är att de är av kompatibla typer. Som exempel måste x och z i bilden ovan vara av lämpliga typer som kan lagra den typ (heltal) som uttrycket 5 + 2 samt 3 + ( x = 5 + 2) har. Robert Jonsson Sida 4

För att ett givet uttryck i Java alltid ska ge ett bestämt resultat finns regler för hur ett uttryck ska evalueras (d.v.s hur uttrycket ska utvärderas och beräknas, normalt i vilken ordning sammansatta uttryck ska beräknas). Till detta finns det olika prioritets- och associativitetsregler. I Java tillämpas i första han prioritering av operatorerna så att i ett sammansatt uttryck så utför de deluttryck med operatorer av högre prioritet först. I exemplet 5 * 6-5 har * (multiplikation) högre prioritet än - (subtraktion) och kommer alltså att utföras först. Det korrekta resultatet för detta uttryck i Java är alltså 25. När operatorerna har samma prioritet används en regel om associativitet. För alla operatorer utom tilldelning gäller vänsterassociativitet vilket innebär att ett uttryck evalueras (beräknas) från vänster till höger. För exemplet 60 / 6 * 5 har divisionsoperatorn och multiplikationsoperatorn samma prioritet. Det korrekta resultatet här är 50 eftersom 60 delat med 6 står till vänster och alltså beräknas först innan multiplikation med 5 sker. Det är endast tilldelningsoperatorn som har högerassociativitet. Eftersom tilldelningen har högerassociativitet kommer värdet 42 i exemplet a = b = c = 42 först att tilldelas till variabeln c (c = 42 står längst till höger). Värdet av c, d.v.s 42, kommer sedan att tilldelas b, som slutligen tilldelas a. På detta sätt kan vi initiera flera variabler (av samma typ) till samma värde. Genom att flitigt använda parenteser kan programmeraren direkt i koden uttrycka evalueringsordningen. Om uttrycket i det nedersta exemplet i bilden skulle skrivas utan parenteser (x = a + b * c / d 42) så hade b och c multiplicerats först. Produkten skulle därefter divideras med d. Genom att använda parenteser ändrar vi ordningen på beräkningen så att a adderas med b först. Därefter divideras c med d och resultatet av denna division multipliceras med summan av a och b. Till sist dras 42 bort från produkten. Att använda parenteser ger inte bara fördelen att programmeraren är säker på hur uttrycket beräknas, utan också att andra programmerare får lättare att se vad ett visst uttryck innebär (hur det ska beräknas). Att använda fler parenteser än vad som egentligen är nödvändigt kostar dessutom ingenting i fråga om kodstorlek eller prestanda på programmet utan bidrar enbart till en mer lättläst kod. Robert Jonsson Sida 5

Java har som vi redan tidigare nämnt ett antal fördefinierade typer, som kallas språkets primitiva typer. De är fördefinierade genom att deras namn är reserverade och genom att de hanteras speciellt av kompilatorn. Som du vid det här laget säkert ha förstått kan vi genom klassbegreppet definiera egna typer (Person, Punkt etc). Samtliga typer är definierade i detalj och det är inte upp till kompilatorn att bestämma vilken storlek eller implementation en viss typ ska ha (ett problem som bl.a C och C++ lidit av). I Java är ett heltal (int) alltid 32 bitar oavsett plattform och kompilator. I C/C++ kan storleken variera beroende på plattform/kompilator. Tecken (char) representeras med 16-bitars Unicode, vilket innebär att en stor mängd tecken kan användas i Java. Heltal finns i fyra olika storlekar: byte, short, int och long. Flyttal representeras som någon av typerna float eller double. Robert Jonsson Sida 6

För samtliga primitiva typer finns också en klass som uttrycker den primitiva typen i form av en klass, en s.k wrapper. En wrapper för en viss typ kan ta en variabel av den primitiva typen och konvertera den till ett objekt. Detta objekt kan sedan enkelt användas tillsammans med andra klasser. Wrapper-klasserna innehåller också konverteringsmetoder för att konvertera mellan olika typer, för att konvertera till och från strängformat, och för konverteringar mellan olika talsystem. I dessa wrapper-klasser finns det statiska metoder (som vi tittade närmare på i lektion 3) vilket innebär att vi inte behöver något objekt av t.ex. klassen Integer för att anropa dessa metoder. För att konvertera en sträng till en primitiv får vi använda motsvarande wrapper-klass och på den anropa en metod som heter parseprimitivtyp(). T.ex. Integer.parseInt("33") för att konvertera strängen "33" till heltalet 33, eller Double.parseDouble("3.1415") för att konvertera strängen "3.1415" till decimaltalet 3.1415. Vill göra tvärtom, dvs konvertera en primitiv typ till en sträng, kan vi anropa metoden tostring() på någon av wrapper-klasserna och som argument skicka med den primitiva typen vi vill konvertera. T.ex. String s = Integer.toString(1); Ta nu en titt i Javas API för någon av wrapper-klasserna (t.ex. klassen Integer). Undersök vilka olika sätt det går att skapa ett objekt av klassen på (vilka konstruktorer finns det). Undersöka vilka metoder som finns och vad de gör. Hittar du några som kan tänkas vara användbara? Som der ser är merparten av metoderna statiska vilket innebär att det är sällan vi skapar ett objekt genom att t.ex. skriva:. Integer i = new Integer("10"); Bland exemplen finner du Person.java, Namn.java och PersonTest.java öppna dessa. Person.java och Namn.java är samma som i förra lektionen men med dokumentationskommentarer borttagna. I PersonTest använder jag nu BufferedReader för att läsa in åldern från användaren och konverterar sedan strängen till en int med klassen Integer. Robert Jonsson Sida 7

Vi börjar nu med att titta närmare på Javas primitiva typer och börjar med boolean. Denna typ har endast två möjliga värden, true eller false (sant eller falskt). Ett booleskt uttryck producerar alltid ett resultat som också antingen är sant eller falskt. Booleska variabler och uttryck används framför allt i kontrollflödeskonstruktioner (kommer senare i lektionen) eller som en s.k. flagga för att komma ihåg om en viss operation eller del av koden har exekverats eller inte. Ett exempel på när en flagga kan vara användbar är i en texteditor. Har man gjort förändringar i sitt dokument och försöker stänga programmet, innan man sparat sina förändringar, får man ofta en fråga om man inte vill spara sina förändringar. Här kan en boolean användas (t.ex. med namnet issaved) som sätts till true så fort man sparat sitt dokument. När man sen gör en förändring (räcker med att skriva en bokstav) sätts denna variabel till false vilket indikerar att vi gjort en förändring och att dokumentet inte är sparat. Innan programmet avslutas så kollar vi denna variabel, issaved, och är den satt till true vet vi att dokumentet är sparat och vi kan stänga ner utan risk. Är däremot variabeln false frågar vi användaren om denne vill spara sitt dokument innan vi stänger. Robert Jonsson Sida 8

För att bygga upp ett booleskt uttryck kan någon/några av de logiska operatorerna och, eller, icke och exklusivt-eller användas. Det booleska uttrycket AND är ett uttryck som kräver två operatorer (t.ex. op1 och op2). Om både op1 och op2 är sanna så är uttrycket ( op1 && op2) också sant. Om någon av op1 eller op2 är falsk eller om bägge är det, är också hela uttrycket falskt. Det är endast om bägge operanderna är sanna som uttrycket är sant. Det booleska uttrycket OR är också ett uttryck som kräver två operander (op1 och op2). Är båda operanderna falska är också uttrycket falskt. Om någon av op1 eller op2, eller om bägge är sanna är uttrycket också sant. Det booleska uttrycket EXCLUSIVE-OR (xor) är ett uttryck som kräver två operander, men som trots namnet skiljer sig stort från operatorn OR. Om en av operanderna är sann och den andra falsk kommer uttrycket att vara sant. Har de både operanderna samma värde (båda är sanna eller om båda är falska) kommer uttrycket att vara falskt. Det booleska uttrycket NOT är ett uttryck som, tillskillnad mot de tidigare, enbart kräver en operand. NOT ändrar ett uttrycks värde från falskt till sant eller från sant till falskt. Utropstecknet (!) sätts framför den variabel eller uttryck vars värde ska ändras. I Person2.java har jag utökat klassen med en boolesk flagga som indikerar om vi satt personnummer redan eller inte. Är personnumret väl satt en gång ska vi inte kunna ändra det genom att anropa setpersnr(). Denna metod returnerar nu en boolean som indikerar om det var tillåtet att ändra personnummer eller inte (returnerar true om vi fick eller false om vi inte fick). I PersonTest2.java provar jag att ändra personnummer på två skapade Person-objekt. Observera att det i koden förekommer konstruktioner som vi ännu inte gått igenom. Robert Jonsson Sida 9

För att beräkna och ställa upp egna komplexa booleska uttryck är det nödvändigt att förstå vilken ordning den virtuella Javamaskinen utför/beräknar booleska uttryck, dvs vilken prioritetsordning de booleska operatorerna har. Vet vi inte prioritetsordningen kan ett och samma uttryck ibland få olika resultat beroende på hur vi utför beräkningen. Resultatet av uttrycket (true true && false) beror t.ex. på om OR utförs först eller om AND utförs först. Med hjälp av parenteser kan vi alltid tvinga det ena eller det andra uttrycket att beräknas först. I Java har &&-operatorn högre prioritet än vilket gör att det andra alternativet (&& först) är det alternativ Java skulle utföra om inga parenteser skulle användas. Som bilden visar har de booleska operatorerna i Java en inbyggt prioriteringsordning. I ett sammansatt uttryck skulle NOT utföras före AND, vilket skulle utföras före XOR, som i sin tur utförs före OR. Förutom prioritetsordningen för de booleska operatorerna är det viktigt att ha kännedom om en operators associativitet för att kunna beräkna uttryck av formen (op1 && op2 && op3)? Ska detta beräknas som ((op1 && op2) && op3) eller som (op1 && (op2 && op3))? Alla booleska operatorer har vänsterassociativitet vilket medför att det första alternativet är riktigt. I BooleanTest.java visas exempel på hur metoder som har parametrar av typen boolean och som även returnerar en boolean. Robert Jonsson Sida 10

Java har två olika typer av numeriska data; heltal (som inte har någon decimal del) och flyttal (som har en decimal del). Java har fyra olika heltal; byte, short, int och long. Dessa skiljs åt av antalet bitar de innehåller och således hur stora tal de kan innehålla. De två olika flyttalen är; float och double. Återigen är det antalet bitar de innehåller som skiljer dem åt (precisionen). En bit kan innehålla två olika värden, 1 och 0, som kan användas som sant eller falskt. Två bitar kan representera fyra olika värden, fyra bitar kan innehålla åtta olika värden etc. Generellt sett så kan n-bitar innehålla 2 n olika värden. Som tabellen visar så är ett heltal i Java ett negativt eller positivt nummer. Och kanske den mest använda typen i Java är int som representeras av 32-bitar. Det betyder att Java kan representera 2 32 olika heltalsvärden mellan -2.147.483.648 och 2.147.483.647, d.v.s från 2 31 till (2 31 )-1. För decimaltal kan en 32-bits float representera 2 32 olika värden i intervallet i tabellen. En 64-bits double kan representera 2 64 olika värden i intervallet i tabellen. Med andra ord så kan inte alla olika tal representeras i Java eftersom det finns ett begränsat antal tal som kan representeras av t.ex. 64 bitar och att det för ett decimaltal finns oändligt många tal mellan t.ex. 0.1 och 0.2. För att hantera tal som är större och/eller har högre precision än vad de primitiva typerna klarar av kan klasserna BigInteger och BigDecimal användas. Ta en snabb titt på dessa i Javas API (jag kommer inte ge någon närmare förklaring på hur dessa används). Robert Jonsson Sida 11

Javas numeriska typer är representationer eller modeller av heltal och flyttal precis som klassen Person är en representation eller modell av en riktig person. Det är svårt, om inte omöjligt, att i en klass till fullo representera en riktig person så vi får göra vissa begränsningar för att få en praktisk implementation av en person. På samma sätt har det gjorts med Javas numeriska typer, vissa begränsningar har införts. En begränsning är att antal heltal är oändligt, men att typen int i Java bara kan representera ett ändligt antal av dessa värden. På samma sätt kan Java inte representera de oändligt många tal som finns mellan t.ex 0,45 och 0,46. Så vissa flyttal kan inte representeras alls i java. Ytterligare något man måste tänka på när man håller på med numeriska data är dess brist på precision. T.ex så kan ett flyttal av typen double som mest ha 17 värdesiffror, och en float kan max ha åtta värdesiffror. Så försöker man lagra ett värde som 12345.6789 eller 0.123456789 i en variabel av typen float skulle talet avrundas till 12345.679 och 0.12345679. Detta kan orsaka problem vid beräkningar. Så när man ska använda numeriska data i sina program ska man vara säker på att den typ man väljer på sin variabel har tillräcklig precision för att representera värdet programmet behöver. I exemplet NumeriskaData.java har jag bl.a. använd wrapper-klassen Integer för att ta reda på det hösta värdet en int kan hålla. Jag provar även att addera 1 till detta max-värde för att se vad som händer. Robert Jonsson Sida 12

De operationer som kan utföras på numeriska data i Java är samma som i vanlig algebra, nämligen addition, subtraktion, multiplikation och division, samt modolusoperatorn. Dessa använder vi även precis som vi använder oss av vanlig algebra. Värt att notera är att symbolen för multiplikation är * och inte x. De aritmetiska operatorerna kräver alla två operander. Precis som med de booleska uttrycken så har parenteser den högsta prioriteten i beräkningar. Därefter kommer multiplikation, division och modolus, som följs av addition och subtraktion. För de operatorer som har samma prioritet gäller vänsterassociativitet. Även om de operationer Java utför ser likadan ut som algebrans så finns det vissa skillnader. För att ge exempel på detta har vi i bilden dividerat värdet 3 med 2. Men olika resultat av uttrycket ges beroende på vilken typ av operander som används. När båda operanderna är av typen int (som i första fallet) så måste resultatet också vara ett heltal. Så uttrycket 3/2 ger resultatet 1, ett heltal. P.g.a att heltal inte kan ha en decimaldel så struntas helt enkelt den. En division med enbart heltal ger alltså alltid ett heltal som svar. Så, 6/2 är 3 vilket också 7/2 är (7 / 2 = 3.5 men decimaldelen används inte). Är någon av operanderna ett flyttal (float eller double) så är resultatet också ett flyttal. Så, även om det är samma symbol som används så är det egentligen två olika operationer: heltalsdivision och flyttalsdivision. Precis som för metoder kan även operatorerna överlagras (dock inget som vi programmerare kan styra). Robert Jonsson Sida 13

Java har några speciella operatorer för att öka och minska ett värde med ett. T.ex så använder uttrycket k++ inkrementeringsoperatorn ++ för att öka värdet på k med 1. Inkrementeringsoperatorn kan placeras både efter variabeln (postfix) och före variabeln (prefix). Skillnaden mellan de två operatorerna är när ökningen av variabeln sker. Om operatorn står efter variabeln så kommer variabeln först att användas i sitt sammanhang och därefter ökas. Om operatorn står före variabeln så kommer först variabeln att ökas och sedan användas i sitt sammanhang Tabellen i bilden visar hur de olika varianterna av inkremeteringsoperatorerna ska tolkas. Exemplet j = ++k innebär att k först ökar sitt värde med 1. Därefter tilldelas variabeln j det värde k har. Exemplet j = k++ innebär att variabeln j först tilldelas det värde k har. Därefter ökas värdet på k med 1. Robert Jonsson Sida 14

Utöver den vanliga tilldelningsoperatorn (=) som tilldelade ett värde till en variabel, finns det i Java ett antal genvägs -tilldelningsoperatorer. Dessa tillåter att man kombinerar ett aritmetiskt uttryck med en tilldelning i ett enda uttryck. Dessa uttryck kan utföras på både heltal och decimaltal. T.ex kommer operatorn += att kombinera addition och tilldelning i ett enda uttryck. För alla dessa olika exempel är tolkningen den samma. Tilldela variabeln som står till vänster om operatorn till det värde den aktuella variabeln har + det som står till höger om operatorn. Robert Jonsson Sida 15

Jamförelseoperatorerna används naturligtvis för att jämföra variabler och uttryck med varandra. Resultatet av en jämförelseoperator är av typen boolean och kan anta något av värdena true eller false beroende på utfallet av jämförelsen. Operatorerna används normalt i testuttryck där det resulterande värdet styr programmets fortsatta exekvering. Robert Jonsson Sida 16

Tabellen visar de olika jämförelseoperatorerna som finns och exempel på användande. Observera att vi kan använda operatorerna för att jämföra annat än tal, vi kan jämföra olika uttryck mot varandra. Ex: boolean resultat = 10 + 2 / 2 < (3-1) * 2; Vilket värde kommer variabeln resultat att innehålla? True eller false? Robert Jonsson Sida 17

Tabellen visar en summering av alla de numeriska operatorerna som finns att tillgå och vilken prioritet de har när de används tillsammans. Robert Jonsson Sida 18

De operatorer vi hittills har tittat på har alla tagit två operander. I Java (och många andra språk) finns det en speciell operator som tar tre operander. Detta är villkorsoperatorn som består av tre stycken operander som var och en är ett eget uttryck. Det första uttrycket är ett booleskt uttryck och beroende på om utfallet av detta uttryck är true eller false, så kommer hela uttrycket att få det resultat som något av de övriga uttrycken har. Villkorsuttryck kan liknas med en if-sats, men skillnaden är att villkorsuttryck kan användas direkt i beräkningar eller utskrifter m.m. I VillkorsOperator.java ges några exempel på användning av villkorsoperatorn. Robert Jonsson Sida 19

Vi har i många av exemplen använt String för att hantera strängar som består av många tecken. I Java finns datatypen char som kan lagra ett enda tecken. En char i Java är en 16-bitars positivt heltal vilket gör att hela 65536 olika tecken kan representeras i Java. Tillskillnad från strängar som omsluts av tecknet " används ' för att omsluta en char. Robert Jonsson Sida 20

Som nämnts tidigare har alla uttryck en typ och ett värde. Om en variabel ska tilldelas värdet av ett uttryck så krävs i Java att variabeln antingen är av samma typ som uttrycket eller av en typ som uttrycket kan konverteras till. Om inte en exakt match uppstår, så krävs en typkonvertering av det resulterande uttryckets värde och typ. Liknande typkonverteringar krävs också inom ett uttryck om operanderna är av olika typ, eller när en parameter till en metod anropas med ett uttryck av annan typ. De flesta typkonverteringar sker automatiskt, s.k. implicita typkonverteringar. Grundregeln för de konverteringar som sker automatiskt vid behov är att ett tal konverteras till en typ som stödjer ett större värdeområde (en char kan konverteras till en int, en int till en float, en float till en double o.s.v.) När en datatyp inte implicit kan konverteras till en annan typ kan detta istället ske explicit. En explicit typkonvertering måste beordras av utvecklaren. En explicit konvertering genoförs genom en s.k. cast (omtypning). Robert Jonsson Sida 21

I vissa tillfällen utför Java s.k. implicita typkonverteringar, d.v.s. att ett tals typ konverteras automatiskt till en annan typ innan den används i ett uttryck. I ett uttryck där en operand är av typen int och den andra av typen float så konverteras int till en float innan beräkningen utförs. Resultatet av denna beräkning kommer således också att bli av typen float. Sådana automatiska konverteringar är tillåtna i Java när konverteringen kan utföras utan informationsförlust. En konvertering från andra hållet går inte att utföra automatiskt eftersom det då finns risk för informationsförlust (tappar decimaldelen t.ex. vid konvertering från flyttal till heltal). Robert Jonsson Sida 22

Vid de tillfällen då vi måste konvertera en variabel med högre precision till en variabel med lägre, måste vi tvinga fram denna. Detta gör vi genom att inom parenteser ange till vilken datatyp vi vill konvertera. I Konvertering.java ges exempel på både automatisk och påtvingad typkonvertering. Robert Jonsson Sida 23

Som tidigare nämnts så består den exekverbara delen av ett Javaprogram av s.k. programsatser i metoder. Dessa satser är antingen deklarationssatser som deklarerar klasser, variabler eller objekt, eller så är det exekveringssatser som utför något aktivt beteende i programmet (läser in data, skriver till skärm, utför en beräkning etc). Ofta kan dessa programsatser skrivas och exekveras sekventiellt, d.v.s. utföras en och en i turordning. Men in många fall krävs någon annan form av flöde bland programsatserna, när exempelvis en viss sats ska upprepas eller endast utföras om något givet villkor är uppfyllt. För detta syfte finns det i Java (och andra språk) ett antal konstruktioner som styr detta flöde, s.k. kontrollflödeskonstruktioner. Robert Jonsson Sida 24

Ett block grupperar ihop ett antal programsatser till en sammansatt sats. Ett block kan användas överallt där en enda programsats är tillåten, men termineras inte med en satsterminator (semikolon). Ett block påbörjas med en vänsterklammer och avslutas med en högerklammer. Block måste alltid användas för att rama in innehållet i en klass- och metoddeklaration som vi redan tidigare sett. Block används även för att rama in de programsatser som ska exekveras i de olika kontrollflödeskonstruktionerna (if-satser, for-loopar m.m). Vi kan även använda block direkt i ett annat block. Följande kod är alltså helt ok (tänk på variablers räckvidd): public void minmetod() { int a = 10; { int a = 5; System.out.println(a); // Skriver ut 5 } System.out.println(a); // Skriver ut 10 } Robert Jonsson Sida 25

Inom en klass så begränsas åtkomsten av variabler av blocken. En variabel deklarerad i ett block lever endast så länge blocket exekveras. Så snart vi kommer utanför blocket kommer vi inte åt de variabler som deklarerades inuti blocket. Det är viktigt att tänka på var vi deklarerar våra variabler så att vi har åtkomst till dem där vi har tänkt oss. I exemplet ovan försöker vi sist i metoden skriva ut variablerna a och x. Variabeln x går alldeles utmärkt att skriva ut eftersom vi har deklarerat den i samma block som vi använder den i. Däremot kan vi inte skriva ut variabeln b eftersom den är deklarerad i ett block som ligger en nivå djupare så att säga. Robert Jonsson Sida 26

Vi ska nu titta närmare på de olika flödeskontrollerna som finns i Java. Dessa kan delas in i följande typer: Villkorskonstruktioner: beroende på utfallet av ett villkorstest väljs vilka programsatser som ska exekveras. Iterationskonstruktioner: skapar en upprepning där en programsats exekveras upprepat till dess att ett visst villkor för att avbryta iterationen är uppfyllt. Avbrottskonstruktioner: avbryter exekveringen av ett block, en iteration eller en metod. Robert Jonsson Sida 27

If-konstruktionen tillhör en av de absolut mest grundläggande flödeskonstruktionerna. Beroende på utfallet av ett booleskt uttryck (som även kan bestå av ett sammansatt uttryck) så exekveras en eller flera (block) programsatser, eller så exekveras de inte. Uttrycket som testas i if-satsen kan vara vilket giltigt uttryck som helst, kravet är att resultatet ska returnera sant eller falskt (true eller false). Om det endast är en programsats som ska exekveras i en if-sats är det inget krav att använda klammer, men det rekommenderas att göra detta ändå eftersom man senare kanske kommer på att fler programsatser ska exekveras. Glömmer man då att lägga till klammer runt blocket så kan programmet bete sig på ett sätt som inte var tänkt. Följande if-sats är exempel på hur vi kan skriva om det endast är en sats som ska exekveras: if (tal < 10) System.out.println("Talet är mindre än 10"); Robert Jonsson Sida 28

En if-else konstruktion tillhör också en av dom mest grundläggande konstruktionerna. Beroende på utfallet av ett booleskt uttryck så exekveras en av två möjliga programsatser (alternativt så exekveras eller exekveras inte en möjlig programsats). Else-grenen av en if-else konstruktion är frivillig (som vi såg i förra bilden), och kan i många fall uteslutas. En if-else konstruktion kan nästlas med varandra. En else-gren tillhör alltid den senaste if-uttrycket, om inget block anges. Robert Jonsson Sida 29

När vi nästlar flera if-else med varandra får vi en konstruktion där en enda programsats (eller block) kommer att utföras, utifrån flera olika alternativ. Vi kan även koppla på en avslutande else-sats om vi vill att något ska utföras om inget av de övriga alternativen kördes. Robert Jonsson Sida 30

I exemplet ovan har vi fyra möjliga utfall. If-satsen börjar med att kolla om värdet i variabeln tal är större än värdet 0. Om så är fallet utförs koden i första blocket. Om inte första uttrycket stämmer kontrolleras om tal är mindre än 0 och i så fall utförs andra kodblocket. Skulle inte heller detta uttryck stämma så kontrolleras om tal är lika med 0, och i så fall utförs koden i tredje blocket. Skulle ingen av dessa uttryck stämma (dvs tal är inte 0, inte större än 0 och inte mindre än 0) så utförs det sista kodblocket (tillhörande else). Av dessa fyra utfall så är det ett och endast ett kodblock som kommer att exekveras. Skulle vi inte ha med den avslutande else-grenen så finns möjligheten att inget av kodblocken exekveras. I exemplet IfTest.java frågar programmet efter ett heltal. Därefter utför några tester med if för att t.ex se om talet är positivt eller inte. Robert Jonsson Sida 31

En variant på if-else-if är switch konstruktionen som innehåller ett heltalsuttryck som evalueras och vars resultat sedan jämförs mot en uppsättning konstanta värden (s.k case-grenar). När resultatet matchar en case-gren så överförs exekveringskontrollen till den kod som ligger ansluten till case-grenen. Om ingen case-gren matchar överförs kontrollen till en default-gren, förutsatt att en sådan finns. Switch-konstruktionen evaluerar uttrycket, som i detta fal är en variabel med ett heltal, och jämför uttryckets värde mot sina case-grenar (som alltså måste innehålla konstanta värden, d.v.s de kan inte innehålla variabler eller uttryck som ska beräknas). Den gren som matchar, eller default-grenen om ingen case-gren alls matchar, erhåller exekveringen och programmet kör de programsatser som finns i grenen. En break-sats avslutar hela switch-satsen, och används även för att avsluta varje casegren. Om ingen break-sats skrivs så fortsätter exekveringen i nästa gren. I exemplet exekveras samma rader om vi skriver 4 eller 5. I exemplet SwitchTest.java ges ett kort exempel på en switch där char har används som jämförare. Robert Jonsson Sida 32

For-loopen används för att skapa en iteration (upprepning av en eller flera programsatser) där man börjar på ett startvärde och fortsätter fram till ett slutvärde. Den används alltså när man vet hur många gånger upprepningen ska utföras. For-loopen innehåller tre uttryck: initieringsdel, testdel och förändringsdel. Initieringsdelen initierar nödvändiga loopvariabler, testdelen testar om ett visst slutvärde har nåtts varpå i så fall loppen avslutas, och slutligen förändringsdelen som påverkar loopvariablerna. En eller flera delar i for-konstruktionen kan utelämnas (varpå endast ett semikolon anges), men kan också innehålla flera uttryck separerade med kommatecknet. Detta är aktuellt när flera loop-variabler behövs. For-loopen kan nästlas, vilket innebär att vi inuti en for-loop har en annan for-loop. Utgår vi ifrån exemplet ovan (som skriver ut talen 0, 1, 2,, 10) så är det första som sker att initieringsdelen körs. Dvs int i = 0. Därefter kommer testdelen där det kontrolleras om i är mindre än eller lika med 10 (om inte ska loopen avbrytas). Första varvet vi kör loopen kommer i att vara 0 vilket resulterar i att testuttrycket är sant och koden i blocket körs. När all kod utförts i blocket går vi upp i förändringsdelen där vi ökar på värdet på i med 1 (dvs nu är i = 1). Därefter går vi återigen in i testdelen för att se om i fortfarande är mindre än eller lika med 10, vilket är fallet. Därför körs kodblocket igen och när det är klar så ökar vi i med 1 (så att i nu är 2). Så här håller det på ända till dess att i ökas på så att i har värdet 11. När vi nu går in i testdelen så uppfylls inte längre villkoret (11 är inte mindre eller lika med 10) och därför avbryts for-loopen och raden direkt under loopen kommer att exekveras. I exemplen ForTest.java och ForTest2.java ges exempel på användning av for-loopen. I ForTest frågar programmet efter hur många tal som ska adderas. Därefter får användaren ange lika många tal och summan skrivs ut. I ForTest2 frågar programmet efter en bredd och höjd. Därefter ritas en rektangel ut med hjälp av nästlade for-loopar. Robert Jonsson Sida 33

While-loopen upprepar en programsats (eller ett block) till dess att ett givet uttryck blir falskt. Så länge det givna uttrycket är sant, upprepas exekveringen av programsatsen. Skillnaden här mot for-loopen är att vi framför allt använder while när vi inte i förväg vet exakt hur många gånger vi ska upprepa någonting. While fungerar som så att ett logiskt uttryck testas och beroende på utfallet (true eller false) så exekveras eller exekveras inte det underliggande kodblocket. Exemplet ovan frågar användaren efter ett heltal och delar därefter detta tal med 2 ända till dess att kvoten blir noll (observera att det är heltalsdivision som utförs). Uttrycket som testas i while är om n (vårat tal) är större än 0, om detta är sant så exekveras koden i blocket. Vi skriver ut värdet på n och därefter delar vi n med 2. När koden i blocket är slut testas återigen om n är större än 0. Är så fallet utförs kodblocket en gång till. Skulle n vara noll (eller negativt) är uttrycket inte längre sant och while-loopen avbryts. Värt att notera är att i en while-loop så utförs en kontroll om loopen, ska köras eller inte, innan koden i blocket exekveras. Detta betyder att det inte är säkert att koden i blocket alltid körs. Skulle användaren i exemplet ovan skriva in 0 vid inmatningen resulterar det i att uttrycket är falskt och loopen skippas helt. I exemplet WhileTest.java har vi en loop som frågar användaren efter tal att addera. Detta görs så länge som användaren inte skriver 0 som tal. Robert Jonsson Sida 34

En variant på den vanliga while-loopen är do-while. Skillnaden är att programsatsen i blocket alltid utförs minst en gång. Testet av villkoret utförs helt enkelt efter programsatsen, istället för före som är fallet med den vanliga while-loopen. Denna variant är att föredra när man är säker på att programsatsen i loopen måste exekveras åtminstone en gång. I exemplet ovan vill vi tvinga användaren att mata in ett tal mellan 1 och 5 (inklusive 1:an och 5:an) innan vi fortsätter exekveringen av programmet. I loopen ber vi användaren att mata in ett tal mellan 1 och 5. Vårat testuttryck (för att fortsätta i loopen eller inte) blir då tal >=1 && tal <= 5. På detta använder vi icke-operatorn (!) så att uttrycket blir: om inte talet är större än eller lika med 1 och mindre än eller lika med 5 ska vi fortsätta i loopen. Här hade vi även kunnat använda följande testuttryck i while: while (tal < 1 tal > 5); Kör loopen så länge som tal är mindre än ett eller om tal är större än 5. Ta en titt på exemplet DoWhileTest.java. Robert Jonsson Sida 35

Break-satsen användes tidigare till att avsluta en switch-sats. Break kan också användas för att avsluta en loop eller något annat block. En break avbryter den switch-, for-, while eller do-sats den befinner sig i. Det är också möjligt att avbryta mer än den närmaste omkringliggande loopen. Då måste en s.k label definieras för det aktuella blocket. En label placeras framför ett block eller en loop-konstruktion och kan användas av break och continue-satser. OBS!!! Det finns ingen goto-sats som kan användas för ett hopp till en label. I exemplet i bilden har vi en for-loop som är tänkt att loopa så länge som i är mindre än 10. I loopen görs en kontroll om i är lika med 5. När så är fallet körs break och loopen avbryts. Resultatet av loopen sen i bilden. Endast 0 4 skrivs ut. Robert Jonsson Sida 36

En continue-sats används liksom break inom loopar. Den avbryter dock inte loopen utan hoppar endast över kvarvarande kod i blocket och fortsätter med nästa iterationsvärde. Den används typiskt när ett visst värde i iterationen ska ignoreras. Även en continue-sats kan ange en label på en omslutande yttre loop som gör att continue-satsen orsakar ett hopp till denna yttre loop istället för den närmast omkringliggande. I bilden används samma for-loop som tidigare, men att det i ifsatsen görs en continue i stället för en break. I stället för att helt avbryta loopen när i == 5 avbryts nu endast resten av koden i blocket för for-loopen. I exemplet BreakCountinue.java visas skillnaden mellan att använda break och countinue Robert Jonsson Sida 37

En return-sats avslutar exekveringen av en metod. Kontrollen överförs till anroparen av metoden. Om metoden har en returtyp måste return-satsen innehålla ett uttryck som genererar ett värde kompatibelt med denna retur-typ. En metod kan ha flera retursatser, även om det sett ur god programmeringsstil är rekommendabelt att endast ha en utgång ur programmet. För de fall att retur-typen är void (inget returvärde alls) så behövs inget uttryck anges i return-satsen. Exemplet ovan testar om ett tal som skickas som argument till metoden är negativt eller inte. Är talet mindre än 0 returnerar vi true, annars returnerar vi false. Istället för att använda en if-sats hade vi även kunnat skriva: return number < 0; men jag vill visa att det i en metod är möjligt att ha flera olika ställen där vi kan returnera. Robert Jonsson Sida 38

För alla de grundläggande aritmetiska beräkningarna finns det inbyggda operatorer (+, -, *, /, %). Vill vi däremot utföra mer avancerade beräkningar, som att ta kvadratroten på ett tal, finns det inga operatorer för detta. Därför finns det en klass som kan utföra mer avancerade matematiska beräkningar. Denna klass heter Math. Klassen ligger i paketet java.lang vilket innebär att vi inte behöver importera något för att använda klassen. Klasserna i detta paket importeras automatiskt åt oss. (i detta paket ligger även bl.a. klasserna System, Integer och String vilket förklarar varför vi inte behöver importera något för att använda oss av dessa klasser). Denna klass innehåller endast statiska metoder (s.k. klassmetoder) vilket innebär att vi inte behöver något objekt av klassen Math för att anropa metoderna (det går heller inte att skapa något objekt av klassen då dess konstruktor är deklarerad som private). Istället anropar vi metoderna direkt på klassen. Ex: int maxtal = Math.max(10, 20); System.out.println(maxTal); // Skriver ut 20 Metoden random() returnerar ett slumptal mellan 0.0 och 0.99999. Ofta vill vi ha ett slumptal som ett heltal och dessutom gärna mellan vissa värden. För att slumpa ett heltal mellan 1 och 5 kan vi skriva följande: int slump = (int)(math.random() * 5) + 1; Math.random() * 5 slumpar tal mellan 0.0 och < 4.999999. (int) konverterar det slumpade talen till heltal mellan 0 och 4 och till detta adderar vi 1 så att vi får tal mellan 1 och 5 Ta en titt i Javas API för klassen Math. Försök att läsa dig till hur de olika metoderna fungerar och ska användas. Skriv gärna en egen testklass som provar några olika metoder i Math. I det sista exemplet, GissaTal.java, har jag skrivit ett litet gissa-det-gömda-talet spel. Robert Jonsson Sida 39