Variabler, värden och typer Viktigt att förstå på djupet: – För programmering i många språk, t.ex. Java – För kommande objektorientering! [email protected] – 2017 Fråga – kommentera – avbryt! 3 jonkv@ida Intro till variabler (1) 00000 Vad är en variabel? I begynnelsen fanns minnet… ▪ …som var fullt av heltal… 64 kbyte minne …och minnesadressen (ett "index" för varje byte) ▪ STA 49152 // Lagra en byte på adress 49152 // Håll själv reda på att inget annat ska lagras där! ▪ LDA 49152 // Läs in en byte från adress 49152 // Håll själv reda på hur denna byte ska tolkas // (Heltal? Bokstav? Index i lista av färger? …) ▪ JMP 8282 // Hoppa till nästa instruktion på adress 8282 49152 (På denna sida: 6502-assemblerkod) 216 − 1 = 65535 4 jonkv@ida Intro till variabler (2) 00000 37000 En första nivå av abstraktion! Konkret adress, 37000 Abstrakt namn, colornum 65535 64 kbyte minne Sedan uppfanns etiketten (label) ▪ colornum: // Översätts till en adress, kanske 37000, .byte 03 // när man vet var det finns plats ▪ STA colornum // Lagra på namngiven minnesadress ▪ LDA colornum ▪ JMP colornum // Oops, undrar vad färgnumret betyder // när det tolkas som en instruktion! 5 Abstrahera språket mer en variabel: En lagringsplats (en eller flera bytes) Ett symboliskt namn på lagringsplatsen längd höjd 10000–10003 10004–10007 10 5 ▪ längd = 10 höjd = 5 är möjliga… ▪ JMP colornum; Minnesadressen kan bli osynlig i språket! Men den finns ändå där… Minne Bara "vettiga" operationer jonkv@ida Intro till variabler (3) 6 jonkv@ida Intro till variabler (4) Kan stödja fler datatyper: Strängar längd Listor höjd 10000–10003 10004–10007 10 5 hälsning 40000-40024 "hello" … Minne ▪ längd = 10 höjd = 5 hälsning = "hello" färger = [red, green] färger 50000-50020 [red, green] 7 jonkv@ida Intro till variabler (5) Vi kan skriva över gamla värden… ▪ längd = 10 höjd = 5 hälsning = "hello" färger = [red, green] längd höjd 10000–10003 10004–10007 hälsning färger 40000-40024 Minne ▪ längd = 47 # Samma variabel, # samma lagringsplats, # samma minnesadress (som vi oftast inte vet / bryr oss om!), # nytt värde… 47 10 5 "hello" 50000-50020 [red, green] 8 Så: En variabel används för att lagra ett värde, och består av: En lagringsplats i minnet, där ett värde kan placeras Ett symboliskt namn på lagringsplatsen, som används i koden Python Programkod Minne vid körning längd 10 höjd 5 hälsning "Hello" färger [red, green] Variabel = en "låda" för ett värde: Värdet kan bytas ut (längd = 22), men det är fortfarande samma variabel jonkv@ida Variabler: Sammanfattning 10 Varje värde har en typ – heltal, decimaltal, … Vissa språk håller inte reda på den Assembler: Ingen typkontroll Värdetyp "sparas" inte, kontrolleras aldrig Inget fel signaleras Resultat: "Skumma värden" Exempel: Lagra decimaltal 3.5 4 bytes, hex 40 60 00 00 Läs som heltal, 4 bytes, hex 40 60 00 00 heltal 1’080’033’280 jonkv@ida Värdetyper 11 Men de flesta, även Python, håller reda på värdets typ Även om man sällan skriver typnamnet print(längd) print(10) heltalsutskrift print(färger) print([red,green]) listutskrift färger + 2 fel vid körning! Programkod Minne vid körning Symboliskt namn (används i koden) Lagringsplats för ett värde längd int 00 00 00 0A 10 Heltal räknare int 48 65 6A 21 1’214’605’857 Heltal hälsning str 48 65 6A 21 Hej! Sträng färger list … … [red, green] Lista jonkv@ida Värdetyper 12 I många språk har även variabeln en typ Gäller Java, C, C++, Programkod Minne vid körning Symboliskt namn (används i koden) Lagringsplats för ett värde Heltal längd 10 Heltal Heltal höjd 5 Heltal Sträng hälsning "Hello" Sträng Lista färger [red, green] Lista Pascal, Ada, … Men inte Python jonkv@ida Variabeltyper 13 Java: Manifest typsystem (variabeltyp anges explicit i koden) Python: Latent typsystem (bara värdet har en typ) längd är en heltalsvariabel som alltid innehåller ett heltal längd är en vad-som-helst-variabel som just nu innehåller ett heltal Varför variabeltyper? Varför ange dem explicit? jonkv@ida Variabeltyper latent typing manifest typing Latent typsystem: Python Manifest typsystem: Java Kompilatorn vet mer (kan optimera mer effektivare) Vi vet mer (typerna är dokumentation) 14 jonkv@ida När vet man värdetypen? 15 Python: Dynamisk typkontroll Java: Statisk typkontroll Går det att addera? Går det att addera? Kolla värdetyp vid körning Om inte numeriskt: Signalera fel Kolla variabeltyp vid kompilering Om inte numeriskt: Signalera fel dynamic type checking static type checking jonkv@ida Konsekvenser: Typkontroll 16 Python: Dynamisk typkontroll Java: Statisk typkontroll Måste kolla vid körning: x är heltal! Addera direkt x heltal? Addera 10 direkt… x flyttal? Konvertera 10 till 10.0, addera … x annat? Signalera fel! jonkv@ida Konsekvenser: Val av operation 17 Python: Dynamisk typkontroll Java: Statisk typkontroll Hur kolla typen hos b:s värde? Hur kolla typen hos b:s värde? Måste lagra typen med värdet Variabelns typ är int, värdet måste ju ha samma typ… x heltal 10 delvis därför kan ett heltal ta 24 bytes int x 10 Ett heltal tar 4 bytes (int), 8 bytes (long) jonkv@ida Konsekvenser: Minnesutrymme 18 En brasklapp: Terminologin för typsystem är ofta otydlig och omtvistad Många termer brukar blandas ihop ▪ Statisk typning ▪ Statisk typkontroll ▪ Manifest typning ▪ Stark typning ▪ … Det viktigaste är begreppen och dess konsekvenser Även dynamisk typning (Python) har fördelar! Mindre att skriva Mer flexibilitet i vissa fall jonkv@ida Brasklapp 20 Heltalstyper – lika på alla plattformar! Används sällan Vanligast! "L" indikerar "långt heltal" Två flyttalstyper – skiljer i precision och storlek ± ± Övrigt ± ± jonkv@ida Primitiva (grundläggande) typer i Java 21 Operationer på heltal kan ge overflow – "översvämning"! Operander av typ : Multiplikation av 32-bitarstal: ▪ 32 bitar slutresultat jonkv@ida Stora tal Varför overflow i Java, men inte Python? Historiskt… ▪ "Så var det ju i C och C++" Effektivitet! ▪ Java: 32-bitars multiplikation, klar. Annars: ▪ Python: Testa storlek, allokera minne för resultat, … 22 jonkv@ida Overflow 23 Beräkningar använder den största av operandernas typer är en int (inget "L") ▪ 32 bitar slutresultat Sedan expanderas detta till 64 bitar ▪ Kan verka korkat… …men är mer förutsägbart: Resultat beror bara på operandernas typer jonkv@ida Använd större datatyp 24 Beräkningar använder den största av operandernas typer Största operanden är long ▪ Expandera den andra "131072" till long ▪ Utför 64-bitars multiplikation ▪ Expandering tappar aldrig information sker automatiskt! jonkv@ida Använd större datatyp (2) 25 Konstanter och funktioner i Math-klassen Kompileringsfel! Math.sqrt returnerar en double Att konvertera double till int kan tappa information – "farligt" Måste uttryckligen be om konvertering! jonkv@ida ”Farliga" typkonverteringar 26 Konvertera med en cast Beräkning, sedan trunkering (avhuggning) Beräknar värdet: (int) trunkerar detta till: Mer: ▪ ▪ jonkv@ida Typkonvertering: Casting 27 Byt variabeltyp… Beräkningar Beräknar värdet: Skriver ut det jonkv@ida Utan casting 28 Python: Automatisk konvertering Java: Bara boolean-värden Ofta bekvämt Kan leda till misstag Mer att skriva Ibland tydligare Kan förhindra misstag jonkv@ida Vad är sant / falskt? Vissa typer ska bara ha några få fördefinierade värden Day: Monday, Tuesday, …, Sunday Suit: Clubs, Diamonds, Hearts, Spades 30 jonkv@ida Bakgrund Kan emuleras på många sätt, t.ex. med heltalskonstanter ▪ ▪ Inte typsäkert! ▪ ▪ Stödjer nonsensoperationer ▪ Efter kompilering finns bara heltalen kvar – svårare att tolka ▪ Värdet är 4 – betyder det torsdag eller fredag? Eller kanske grönt, spader eller giraff? 31 jonkv@ida Emulering 32 Java har stöd för uppräkningstyper (enumerated types) Man räknar upp vilka värden som finns Sju enumkonstanter Inga nonsens-operationer tillgängliga Namngivningskonvention: ALL_CAPS för konstanter enum-konstant = enum constant jonkv@ida Uppräkningstyper 33 Distinkt typ (inte int) typsäkerhet Håller reda på namn: Skriver ut "THURSDAY", inte 4 jonkv@ida Uppräkningstyper: Typsäkerhet Vi kan få ut index för ett värde 34 jonkv@ida Uppräkningstyper: Index Vi kan få ut ett värde med givet namn och en lista på alla värden 35 jonkv@ida Uppräkningstyper 36 Sämsta lösningen: Konstanter utan namn Gammal lösning: Namngivna heltal Bäst, vid fixerade värden: Uppräkningsbar typ jonkv@ida Jämförelse