Programmeringsteknik I Föreläsning 2: Grundläggande Java Johan Öfverstedt
Java Grundläggande begrepp Datatyper Selektion if Räckvidd (scope) Iteration while Klasser Objekt Metoder Metodhuvudet Kodstandarden Return Metoder som abstraktion
Primitiva Datatyper byte (8 bit/1 byte): -128..127 short (16 bit/2 byte): -32768..32767 int (32 bit/4 byte): -2147483648..2147483647 long (64 bit/8 byte): -9223372036854775808..9223372036854775807 float (32 bit/4 byte) float och double standardiserade enligt double (64 bit/8 byte) IEEE 754. boolean (maskinberoende ~ 1 byte) char (16 bit/2 byte): Tecken UNICODE a, z
Datarepresentation Streaming av film Låt oss anta: 30 bildrutor per sekund, upplösning HD 1920x1080, färg, en byte per färgkanal per bildpunkt. 30 x 1920 x 1080 x 3 x 8 / (1024 x 1024) = 1423 Mbit / 177 Mb per sekund. (Okomprimerat) Stora datamängder finns överallt i dag. Även om datorerna har mycket minne för det mesta är det alltid lätt att fylla det med det mest vardagliga.
Flyttal - precision Summering av 10 miljoner slumptal [0, 1). dacc = 4999240.368441801 // double facc = 4999314.0 // float Olika resultat. Om vi inte behöver ta hänsyn till datamängd för att vi inte behöver lagra eller överföra stora mängder, använd double.
Logiska uttryck Boolska/logiska uttryck har datatypen boolean, och kan anta värdena false eller true. Logiska uttryck används för att representera villkor. Logiska uttryck har en uppsättning operatorer: && - och - eller == - Lika med!= - Inte lika med < <= > >= - Olikheter
Selektion If-satsen Är lösenordet korrekt? If(pwCorrect(pw)) { showemail(); else { System.out.println( Error! ); Ja Inloggning lyckades Visa e-mailen Nej Inloggning misslyckades Försök igen?
If-satsen i beräkningsprogram Ja Är nämnaren nollskild? Nej If(denom!= 0) { res = numer / denom; else { System.out.println( Div by zero! ); Utför division Rapportera ett fel till användaren
If-satsen i beräkningsprogram Matematiska funktioner har ofta villkor / fall med olika uttryck beroende på dess argument. Exempel: abs(x) = x om x >= 0 -x om x < 0 sinc(x) = 1 om x == 0 sin(x)/x om x!= 0
Nästlade if-satser If() { if() { else { else { if() { else {
If-satsen If( villkor ) { villkor är av typen boolean. boolean villkor = (x < y) && (x > 5); if (villkor) { System.out.println( x < y ); else { System.out.println( x >= y );
If-else-if-else Man kan använda en serie if satser: if(villkor1) { else if(villkor2) { else {
If-satsen De flesta program är fulla av villkor som styr vad som skall hända beroende programmets läge / state, om det inte är rena script där man kan räkna upp en serie kommandon som skall utföras villkorslöst. Även program som inte har explicita if-satser kan använda dem bakom kulliserna: Exempel: Turtle t1; t1.move(20); Kastar ett NullPointerException. Hur vet Java att t1 är en tom referens?
Räckvidd (Scope) { Är viktiga tecken i Java. { - Öppnar en ny lokal miljö/namnrymd Stänger den aktuella lokla miljön/namnrymden if(villkor) { double d = t1.distanceto(t2); System.out.println( Distance: + d);
Nytt scope introduceras vid: Deklaration av: Klass Metod Satser: If-sats While-sats For-sats (speciella regler för räckvidden, som vi får se I nästa föreläsning) Med fler
Iteration while-satsen Ett minst lika centralt begrepp som selektion är iteration. Ofta vet man inte på förhand hur många gånger en operation / sekvens av operationer behöver utföras. Exempel: Flytta paddorna tills dess att de går isär med fler än 200 bildpunkters avstånd. Bestäms av slumpgeneratorns (Math.random) utfall hur många steg som krävs. Kan man garantera att ett program med iteration någonsin avbryts?
while-satsen en slinga med villkor Sant: Gå in I loopen Falskt: Fortsätt programmet, efter loopen
while while( villkor ) { // loopens kropp Precis som med if-satsen så är villkor ett boolskt uttryck.
Break Någonting att undvika om det går Ibland består en loop av flera delar. while (villkor) { x = trytodosomething(y, z, w); if(x == 0) { break; System.out.println( Value is: + x);
Break Användbar om villkoret inte garanterar att vi kommer lyckas med en operation, utan bara säger att vi bör försöka en gång till. Det finns andra sätt (t.ex. Undantag/exceptions) att hantera det som allmänt kan anses bättre, men det är ett sätt att få jobbet gjort.
while-satsen Hur vet vi om programmet kommer köra färdigt? I det allmänna fallet är det omöjligt att bevisa att ett givet program någonsin kör färdigt (läs kursen Automatateori). I det särskilda fallet kan vi bevisa att program kör färdigt genom att se till att det gör en viss mängd framsteg emot att loop-villkoret skall uppfyllas görs varje iteration. int counter = 100000; while(counter > 0) { // This will take a while System.out.println( The counter is at: + counter); --counter; // Glöm inte att minska räknaren
Exempel while Beräkna multiplikation med addition (x = 7, y = 5): long prod = 0; while(y > 0) { prod = prod + x; --y; Är det här rätt? Funkar det för allmänna x och y av typ long?
Beräkna multiplikation med addition (x = 7, y = -5): long prod = 0; while(y > 0) { prod = prod + x; --y; Negativa y? Ger felaktigt resultat
En korrekt version Beräkna multiplikation med addition (x = 7, y = -5): if(y < 0) { y = -y; x = -x; long prod = 0; while(y > 0) { prod = prod + x; --y;
Exempel: Minsta slumptal double minsofar = Double.POSITIVE_INFINITY; int n = 100; while(n > 0) { double r = Math.random(); System.out.println("Value " + n + ": " + r); minsofar = Math.min(minSoFar, r); n = n - 1; System.out.println(String.format("The least random value is: %.7f", minsofar));
Klasser Objekt - Metoder Klasser är datatyper (Turtle/World/String). Objekt är instanser av en klass. // Skapa en ny padda / instans av klassen Turtle Turtle t1 = new Turtle(w); Klasser är också den beståndsdel inom vilken all kod I Java-programmet defineras. Inga fria funktioner är tillåtna (som I C/C++/Matlab/Python/etc).
Metoder Metoder är namngivna funktioner eller procedurer med parameterar och returvärden som tar emot argumenten, utför operationer, och returnerar ett värde. I Java kan man bara returnera ett värde. Math.random() tar inga parameterar men utför en operation och returnerar ett slumptal. Math.sqrt(x) tar en parameter och returnerar ett värde. Negativa x? System.out.println(s) tar emot en parameter och utför en operation, men returnerar inget värde. (Det är en void-metod)
Metoder vid deklaration Klassmetoder deklareras: public static double sqrt(double x) { Objektmetoder deklareras: public double distance(turtle otherturtle) {
Metoder Vid anrop Klassmetoder Metoder som anropas på en klass, alltså förknippade med klassen i sig, inte med dess objekt. Exempel: Math.sqrt(2.0). Objektmetoder Metoder som anropas på en referens till ett objekt/på en objektvariabel. Exempel: t1.move(20). Man kan se skillnad enbart baserat på vad som står före punkten.
Hur kan man se om det före punkten är en klass eller ett objekt? Svaret är:
Kodstandarden Hur kan man se om det före punkten är en klass eller ett objekt? Svaret är: Att vi har (och följer) en kodstandard. Alla klasser börjar med stor bokstav, och varje nytt ord I klassnamnet har stor bokstav. Exempel: StringBuilder. Alla variabler börjar med liten bokstav. Exempel: stringbuilder. Baserat på namnet vet vi att StringBuilder är en klass och stringbuilder är en objektvariabel.
Är det verkligen så noga med kodstilen? Det funkar ju ändå? Ja det är noga. För att kod ska vara läsbar, av dig själv, av oss, av andra, av dig själv om 6 månader, så måste man följa standarder. Det låter oss läsa av ett stycke kod snabbt och få en överblick över vilka variabler som finns, vilka klasser som används. Man måste också indentera koden. Ctrl+A && Tab / Cmd+A && Tab.
Vart kan man hitta kodstandarden? På kurshemsidan: http://www.it.uu.se/edu/course/homepage/prog1/documents/styleguide.html
return-satsen En metod med en returtyp annat än void måste alltid returnera ett värde, längs alla vägar den kan ta (i loopar och if-satser). public static double div(double x, double y) { if(y == 0) { if(x < 0) return Double.NEGATIVE_INFINITY; return Double.POSITIVE_INFINITY; return x / y; return får metoden att avbrytas och hoppa ut omedelbart.
Metoder som abstraktion I Java är det framförallt genom klasser som abstraktioner skapas, men även metoder kan användas för att skapa små återanvändningsbara delar. Exempel: Math.min(x, y). Det är lätt att ersätta Math.min med double minvalue = x; if(y < x) minvalue = y; men Math.min talar om vad som händer på ett sätt som en tilldelning och en if-sats inte gör.
Abstraktioner är bra (upp till en gräns) Med abstraktioner blir det ofta enklare att uttrycka vad man vill att programmet ska göra kortfattat, givet att existerande abstraktioner passer problemet man försöker lösa. Math.min är bra för att beräknade det minsta av två tal, men om man behöver veta vilket av talen som valdes, kan man inte använda Math.min, och ingen abstraktion finns i standardbiblioteket (till min kännedom) för det.
Abstraktioner har olika styrka Ibland kan abstraktion A implementeras med abstraktion B, men inte tvärt om. A: Hitta det minsta värdet i en serie tal. B: Hitta index för det minsta värdet I en serie tal. Om vi använder B och känner till index för det minsta värdet, kan vi lätt hitta det värdet. Om vi istället använder A, och känner till det minst värdet har vi ingen aningen om vilket tal i ordningen som var det minst. Alltså måste vi söka efter det.