Datalogi I, grundkurs med Java 10p, 2D4112, 2002-2003 Fiktiv tentamen, svar och lösningar och extra kommentarer till vissa uppgifter 1a) Dividera först talet 37 med 2. Använd heltalsdivision. Det ger kvoten 18 och resten 1, vilket är entalssiffran i den binära representationen. Upprepa förfarandet på kvoten, nästa kvot o.s.v. tills kvoten blir 0. kvot rest 37=2 =18 1 18=2 =9 0 9=2 =4 1 4=2 =2 0 2=2 =1 0 1=2 =0 1 Den första binära siffran som beräknas är entalssiffran, den som står längst till höger i det binära talet. Svaret är 100101 2 1b) 100 8 är ett tal skrivet på oktal form, i basen 8. Siffrorna i talet anger då hur många 8 0, 8 1, 8 2, o.s.v. talet innehåller. I vårt vanliga positionssystem med basen 10 anger siffrorna ental (10 0 ), tiotal (10 1 ), hundratal (10 2 ) o.s.v. 100 8 =1Λ 8 2 +0Λ 8 1 +0Λ 8 0 =64 2) Vid normaliserad lagring av flyttal skrivs talet först om till normaliserad form, till m Λ B e, där B är basen för representationen, e är en exponent och m är taldelen, mantissan. Vid normaliserad lagring gäller att 1=B» m < B. Exempel: normaliserad representation av några tal i basen 10 och basen 2: 935600 = 0:935600 Λ 10 6, 0:0001013 = 0:1013 Λ 10 3, 1110110 2 =(0:1110110 Λ 2 111 ) 2, 0:0001011 = (0:1011 Λ 2 11 ) 2. 3 3a) En algoritm är en entydig beskrivning av hur en uppgift ska lösas. Stegen i algorimen ska vara väldefinierade och algoritmen ska leda till lösningen i ett ändligt antal steg. Exakt hur (i vilket språk, med vilka operationer) en algoritm ska uttryckas beror på vem eller vad som ska tolka den. 3b) Sekvens, val (eller villkor) och repetiton. Exempel på sekvens: Instruktioner utförs i den ordning de står. x = 27; y = 38; g = x*y; Exempel på villkorssats: if (m > 0) x = 13; y = 23; Exempel på repetition while (i < n) t = t*i; sum = sum + t; 1
4) Fel kan vara t.ex. syntaxfel, semantiska fel eller logiska fel. Syntax är språkets fomella regler, hur ett program får se ut. Semantik är språkets betydelse, vad som händer när man använder en viss syntax (språkkonstruktion). Syntaxfel upptäcks (senast) av kompilatorn men kan förstås upptäckas genom granskning innan man försöker kompilera programmet. För att hitta semantiska fel (om man vet att det finns ett fel) kan man använda granskning, spårutskrifter eller debugging. Logiska fel beror på att man inte riktigt förstått vilken uppgift som ska lösas, man har tänkt fel när man skrivit programmet. Sådana fel kan vara mycket svåra att upptäcka men om man vet att ett fel finns är viktigaste att man tänker igenom sina algoritmer på nytt. Man kan ha nytta av debugging eller spårutskrifter även här. 5) 5a) Data + operationer med dolt lagringsformat. Användaren känner till ett typnamn och operationer på typen men får inte veta hur data är lagrade eller hur de metoder som utför operationerna är skrivna. 5b) En klass med dolda instansvariabler och ett väldefinierat gränssnitt som visar de operationer man får göra på objekt av klassen. 6) Reservation av minne för metodens formella parametrar och lokala variabler. Varje anrop har en egen aktiveringspost. Om en metod anropar sig själv flera gånger så har varje anrop en egen aktiveringspost. Detta är viktigt att veta för att kunna förstå hur rekursiva metoder kan fungera. 7) ++ används för att sätta ihop två listor till en, t.ex. [9,7,2,7] ++ [14,24] ger [9,7,2,7,14,24], "PANN" ++ "KAKA" blir "PANNKAKA" 8. c) är rätt svar. Listor är den viktigaste datastrukturen i funktionella språk. I en lista har alla element samma typ men typen får vara vilken som helst som går att definiera i språket. Här är en lista av listor: ["Dearest", "creature","in", "creation"] Här är en lista där varje element är en lista av listor: [["Dearest", "creature","in", "creation"], ["study", "English","pronunciation"], ["I", "will","teach", "you", "in", "my", "verse"], ["Sounds", "like","corpse", "corps", "hearse", "and", "worse"]] 9) Prova med x = 0.5 i definitionen av ex9. Vaktpost nr 2 med villkoret x<1 är den första som ger True. Funktionsvärdet definieras av det som står efter = på samma rad, dvs x och det ger 0.5. På samma sätt ger x = 1.5 att tredje vaktposten är den första som ger True och funktionsvärdet blir då 2 x, alltså 0.5 om x = 1.5. 10) [ x*x x <- [1..5], x/=3] tolkas så att för varje x i listan [1..5], där x uppfyller villkoret x/=3, lägg x*x i resultatlistan. Resultatet blir [1,4,16,25]. 2
11) Om man inte kan se direkt vad en funktion gör, prova med ett eller flera indata. Här kan man prova med t.ex. mystery "a%e". Det ger mystery ("a%e") => mystery ('a':"%e") => x ='a', x == '%' är False => 'a' : mystery ("%e") => 'a': mystery ('%':"e") => x = '%', x == '%' är True => 'a' : mystery ("e") => 'a' : mystery ('e':[]) => x ='e', x== '%' är False => 'a':'e':mystery [] => 'a':'e':[] => 'a':"e" => "ae" Funktionen returnerar en textsträng som innehåller samma tecken som indata men med alla '%' -tecken borttagna. 12) Rätt svar är c). long och int är båda typer för heltal. En variable av typ long tar upp två ord i minnet och envariabel av typ int tar upp ett ord. Således kan man lagra större tal i long än i int. 13) for (int i=0; i<10; i++) System.out.println(''Java-student''); Detta är ett typexempel på repetition 10 gånger. Texten skrivs ut 10 gånger. Rätt svar är c) 14) int x = 0; while (x < 10) x++; System.out.println(x); I en repetition med while repeteras den sats eller det block ( en grupp satser omgivna av och ) som står direkt efter villkoret. Där står endast satsen x++ så det är bara den som repeteras. När repetitionen är klar utförs satsen System.out.println(x);. Den satsen utförs en gång och rätt svar är därför d) 15) En metod som anropar sig själv får man skriva ijava och en sådan kallas rekursiv. Rätt svar är d) 16) int[] resultat = new int[10]; int[] resultat deklarerar en referensvariabel för typen heltalsvektor. new int [10] skapar och reserverar plats för 10 st heltalsvariabler som man kommer åt via referensen resultat. Rätt svar är a). 17) En klassmetod anropas genom att man skriver klassensnamn.metodensnamn (..) Klassmetoden skrivstatistik i klassen Skrivning anropas Skrivning.skrivStatistik(). Någon instans av klassen är inte inblandad då man anropar klassmetoder. Rätt svar är b). 3
18) En instansmetod anropas med referensvariabel.metodnamn(..) (eller lite slarvigare uttryckt: instans.metodnamn(..) ) Om instansen är tyskaht02 och metoden är visaresultat så blir anropet tyskaht02.visaresultat();. Rätt svar: a). 19a) class Raknare private String namn; private int antal; Raknare (String inamn) namn = inamn; nollstall(); public void nollstall () antal = 0; public void rakna () antal ++; public int visaantal () return antal; public String visanamn () return namn; Det står inget i uppgiftslydelsen om dolda instansvariabler. Därför krävs det inte att instansvariablerna är private. Det krävs inte heller att man skrivit public på metoderna. 19b) Raknare besoksraknare = new Raknare("Besökare"); 20a) int index = -1; for (int i=0; i< frukter.length && index == -1; i++) if (frukter[i].equals("päron")) index = i; Längre lösningar, som t.ex. använder en boolsk variabel godkänns också. Det är inte heller nödvändigt att avbryta sökningen efter Pärondå man funnit ett och det godtas att index pekar ut den sista förekomsten om det finns flera Päron"i vektorn. 4
20b) Operatorn == jämför referensvariablers värden, inte innehållet i de objekt referensvariablerna refererar till. 21) public class Question extends Applet implements ActionListener int pos = 20; public void init () Button flytta = new Button("Flytta"); add(flytta); flytta.addactionlistener (this); public void paint (Graphics g) ritabild(g, pos, pos); private void ritabild (Graphics g, int xpos, int ypos) // Den här metoden ritar den vackra bilden // Här skall inget stoppas in. public void actionperformed (ActionEvent e) pos += 10; repaint(); Satsen Button flytta =... kan läggas utanför metoden init. 5