itop Läsanvisning: kap 2+13 F5 Metoder - en funktion: medel metodhuvud, funktionshuvud, signatur modifierare formella resultatvärdets typ parametrar metodens namn! Metoder, parameteröverföring! Fält Nästa gång: Nästa föreläsning (F6) handlar om ett exempel där vi använder det vi lärt oss hittills och ser på att att tolka felutskrifter från kompilatorn. Grupp B, C kan antagligen skippa nästa föreläsning. public static double medel(int v1, int v2){ return (v1+v2)/2.0; // end medel metodkropp metodens resultat metodens resultat kan vara av vilken typ som helst, även en klass. Anrop tex: int c = 52; int a = 10; double medel1, medel2; medel1 = medel(5, 10); medel2 = medel(a, c); aktuella parametrar F5 1 F5 2 Ett program med metoder import java.util.scanner; public class EnkelMatematik1 { Antag inmatning av 2.0 och 3.0 ovan public static double medel(double v1,double v2){ return (v1 + v2)/2.0; // end medel; //--------------------- public static void main(string[] args){ Scanner myinput = new Scanner...; double tal1, tal2, mv; System.out.println("Ange 2 tal"); tal1 = myinput.nextdouble(); tal2 = myinput.nextdouble(); S...print("Medelvärdet är: "); S...println(mv); // alternativ till 3 sista raderna S...print("Medelv igen är: "); S...println(medel(tal1, tal2)); <=> mv = medel(2.0, 3.0)); <=> mv = 2.5; 2.0 3.0 <=> mv = 2.5; medel // end main // end EnkelMatematik F5 3 F5 4
Parameteröverföring I Java överförs alltid parametrarna via värdeanrop dvs värdet av den aktuella parametern kopieras över till den formella parametern. public static int sqr(int x) {... detaljer ointressanta int tal = 5; int resultat; resultat = sqr(tal); aktuell parameter 5 tal 5 x formell parameter värdet av tal beräknas och kopieras till x tal och x är olika fysiska objekt Det spelar ingen roll om dom har samma namn, det är ändå två olika variabler: public int sqr(int tal) {... osv int tal = 5; int resultat; resultat = sqr(tal); Metoder=Funktioner och procedurer Använd en funktion om du kan en procedur om du måste Skall göra en sak bra. Funktioner beräknar värden. De utvidgar uttrycksdelen av språket. Ett funktionsanrop! är ett uttryck! och har en (retur)typ! void! beräknas till ett värde som returneras tal1 =...; tal2 =... Procedurer utför åtgärder De utvidgar satsdelen av språket Ett proceduranrop är en sats returnerar inget värde (returtyp = void) System.out.print("Störst är: "); F5 5 F5 6 Synbarhet (Scope) En variabel syns från det den deklareras tills dess att blocket den deklarerats i tar slut. int global = 4; if (<Villkor>) { int drömmoms = 3; // här finns drömmoms och global... else { // här finns inte drömmoms // men global finns... // här finns inte drömmoms // men global finns ------------------------------ static double sqr(double x){ double tmp = x*x; return tmp; // return x*x; // end sqr; // här finns inte tmp och inte x Overloading (Överlagring) Två eller flera metoder kan ha samma namn om dom skiljer sig åt i sina parametrar. public static int max (int a, int b) { if (a>b) { return a; else { return b; public static int max (int a, int b, int c) { if (a>b) {... public static double max (double a, double b) { if (a>b) {... F5 7 F5 8
Fält, vektorer, matriser, arrays! Har numrerade komponenter.! Komponenterna selekteras med index av diskret typ, indexeras från noll till length-1! Alla komponenter är av samma typ.! Komponenterna kan vara objekt. temp Skapa fält: Deklarera ett fält med 6 reella variabler: double[] temp = new double[6]; Deklaration och Snabbtilldelning int[] tmp = {0,1,2,3,4,5; med Array initializer Fungerar bara vid deklarationen dvs tmp ={0,1,2,3,4,5; GÅR INTE 0 1 2 3 4 5 temp[2] Tilldela och läsa fältvärden antag: int[] tmp = {0, 1, 2, 3, 4, 5; Tilldelning av *ett* fältvärde tmp[1] = 8; //{0,8,2,3,4,5 Tilldelning av *hela* fältet i en loop for(int i = 0; i<tmp.length; i++){ tmp[i] = 2*i; //{0,16,4,6,8,10 Läsa ett fältvärde int value = tmp[1]; // fältet ändras inte vid läsning Fältets längd = tmp.length (är ingen metod) Index kan vara ett (heltals-)uttryck Fältet initialiseras automatiskt till 0 Längden på ett fält kan inte ändras F5 9 F5 10 Bearbeta fältets värden antag: double[] tmp = new double[6]; Mönster: for(int i = 0; i < tmp.length; i++) { // bearbeta enskilda fältvärden här Fyll fältet med ettor for(int i = 0; i < tmp.length; i++) { tmp[i] = 1.0; Multiplicera alla element med 2 for (int i = 0; i < tmp.length; i++) { tmp[i] = tmp[i] * 2; Räkna alla element < 10 int antal = 0; // i, j är vanliga namn på loop-index for (int i = 0; i < tmp.length; i++) { if (tmp[i] < 10) { antal = antal +1; <- Här innehåller antal antalet element <10 F5 11 Fält och metoder Summera innehållet i ett fält double sum = 0.0; for (int i = 0; i < tmp.length; i++){ sum = sum + tmp[i]; System.out.println(sum); Summera innehållet i fältet i en metod ps... double sumarray(double[] arr) { double sum = 0.0; for (int i = 0; i<arr.length; i++){ sum = sum + arr[i]; return sum; Skapa fält genom att anropa en metod ps... double[] fillarray(int size) { double[] tmp = new double[size]; for (int i = 0; i<tmp.length; i++){ tmp[i] = i; // eller nåt return tmp; Tester på tomma fält utelämnade. Loopar som dessa måste man kunna skriva i sömnen! F5 12
Kopiera ett fält int[] f1 = {0,1,2,3,4,5; int[] f2 = new int[6]; f2 = f1; // blir INTE som du tänkt Du måste kopiera element för element: for (int i = 0; i<f1.length; i++){ f2[i] = f1[i]; Ofta gör man detta i en metod: static int[] copyarray(int[] arr) { int[] tmp = new int[arr.length]; for (int i=0; i<arr.length; i++){ --> tmp[i] = arr[i]; --> return tmp; Anrop f2 = copyarray(f1); Parameteröverföring igen: Vad händer om vi gör arr[i] = 5; inuti loopen? (Före resp. efter tilldelningen) F5 13 Parameteröverföring Regeln var: Värdet av den aktuella parametern kopieras över till den formella parametern. int[] f1 = {1,5,3,7,4,5,...; int[] f2 = null; int[] copyarray(int[] arr) { int[] tmp = new int[arr.length];...kopiera... return tmp; f2 = copyarray(f1); aktuell f1 17B27 lokal param. f2 1A23 formell param. arr 17B27 tmp 1A23 värdet av f1 beräknas och kopieras till arr f1 och arr pekar ut samma minnesplats Innehållet i arr kopieras till tmp tmp och f2 refererar till samma fysiska objekt tmp och arr tas bort, f1, f2 finns kvar F5 14 Är fält objekt eller primitiva Några skäl mot:! annan syntax än andra objekt! klassen har inget namn utan bildas genom att ta andra namn och lägga till []! du kan inte ärva fält! du kan inte definiera egna metoder och lägga till klassen! längden är en variabel, inte en funktion! Några saker som talar för att dom är det:! Språkdefinitionen säger att dom är det! fält är referenstyper! allokeras med new...! allokeras på heapen! förälderklassen är Object och Object klassens metoder fungerar Så dom är objekt, men lite speciella objekt. Vanligaste felen med fält null pointer exception int[] f1 = {0,1,2,3,4,5; int[] f2; for (i = 0; i < f1.length; i++){ f2[i] = f1[i]; Test.java:10: variable f2 might not have been initialized f2[i] = f1[i]; ^ 1 error f2 = f1; // funkar men... array index out of bounds double sum = 0.0; for (i = 0; i <= f1.length; i++){ sum = sum + f1[i]; F5 15 F5 16
Flerdimensionella fält (matriser) Är fält med fält som värden Raderna behöver inte vara lika långa int[][] m = new int[3][6]; for( int i=0; i< m.length; i++ ) { for( int j=0; j < m[i].length; j++ ) { m[i][j] = 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 int[][] m2 = { {1, 2, 3, 4, 5, 6, {1, 1, 1, 1, {6, 5, 4, 3, 2, 1 ; En tentauppgift med lösning: Skriv en metod void columnsort(int[][] x) som givet en matris x sorterar varje kolumn. Skriv också en metod print(int[][] x) som skriver ut en matris. Skriv sedan kod som skapar första matrisen nedan, anropar columnsort och sedan print som då skriver den andra matrisen nedan. Exempel: om x är första 5x7 matrisen nedan så skall metoden columnsort arrangera matrisen som andra matrisen nedan. 12 6 7 17 18 19 8 0 14 8 15 5 3 2 7 2 1 6 9 18 21 1 5 9 3 7 11 2 89 12 6 1 0 19 27 ----------------------------------- 0 2 1 1 0 3 2 1 5 6 3 5 11 2 7 6 7 6 7 18 8 12 12 8 15 9 19 21 89 14 9 17 18 19 27 F5 17 F5 18 Talk is cheap. Show me the code. Linus Torvalds Struktur: public class ColumnSort { public static void print(int[][] x) {... public static void columnsort(int[][] x){... public static void main(string[] args) { columnsort(x); Vi bryr oss inte om att hantera tomma matriser i detta exempel men det bör man göra på tentan i både print och columnsort. F5 19 public static void main(string[] args) { int[][] x = {{12, 6, 7, 17, 18, 19, 8, 29, 2, { 0, 14, 8, 15, 5, 3, 2, 1, 18, { 7, 2, 1, 6, 9, 18, 21, 2, 8, { 1, 5, 9, 3, 7, 11, 2, 7, 10, {89, 12, 6, 1, 0, 19, 27, 21, 5 ; //System.out.println("Original array:"); //sort array columnsort(x); //System.out.println("Array Columns Sorted:\n"); 20
public static void columnsort(int[][] x){ // uses bubbelsort, largest to the end // for every column in matrix for(int col = 0; col < x[0].length; col++){ // for all numbers in array i.e. one column for (int i = 0; i < x.length-1; i++) { // bubble largest to the end of unsorted part for (int j = 0; j < x.length-1-i; j++) { if (x[j+1][col] < x[j][col]) { // swap int temp = x[j][col]; x[j][col] = x[j+1][col]; x[j+1][col] = temp; Hur hantera tomma fält i columnsort? if (x==null x[0]==null) { throw new IllegalArgumentException( empty array ); Ordlistan växer... metoder (funktioner, procedurer), parameteröverföring, metodhuvud, funktionshuvud, signatur, formell/aktuell parameter. uttrycksdel, satsdel, värdeanrop, synbarhet, scope, overloading, överlagring, Fält, vektorer, matriser, arrays, deklarera, index av diskret typ, initialisera, allokera, heapen, 23 24 Pseudokod för print: for varje rad loop for varje kolumn loop skriv x(rad, kolumn) + some space end loop radbyte end loop ------------------------------------------------ public static void print(int[][] x) { for(int i = 0; i < x.length; i++){ // varje rad for(int j = 0; j < x[i].length; j++){ // kolumn System.out.print(x[i][j] + "\t"); System.out.println(); System.out.println(); // kanske onödig sortera matrisen: for every column in matrix { sort it (med tex bubbelsort, störst till slutet) sortera en array: for all numbers in array { bubble largest to the end of unsorted part { if (x[j+1] < x[j]) { swap x[j+1] och x[j] (swap=byt plats på) eftersom vi sorterar en matris så måste vi ha ett index till tex if (x[j+1][col] < x[j][col]) {... 21 22