Heltal(int) Programmeringsteknik 54



Relevanta dokument
3.3 for-satsen. Programmering, grundkurs, 8.0 hp, Elektro, KTH, hösten Föreläsning 3

7 GRUNDERNA I PROGRAMMERING

Föreläsning 4: for, while, do-while

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

Roboten Karel lär sig Java

PROV. 10 Uppräknade datatyper

Introduktion till MATLAB

For-sats/slinga. Notis

Barnhack! kom igång med Scratch del 1

An enrichment and extension programme for primary-aged children

Word och Excel. - en kort handledning Av Dag Kihlman och Martin Gellerstedt

Detta är ett PM som Anders Engquist ibland ger deltagarna i utbildningar eller föreläsningar som hjälp att komma ihåg några väsentliga kunskaper

UTBILDNINGSFÖRVALTNINGEN IKT-FUNKTIONEN

Att ta fram en tidsplan

Texas Instruments Sverige 1997 Printed in Sweden by Gumm essons Tryckerier AB

Mer om reella tal och kontinuitet

Referentiell transparens. Programmeringsmetodik DV1 Programkonstruktion 1. Moment 10 Om sidoeffekter In/utmatning och imperativ programmering

Talmönster och algebra. TA

Nedan skapar vi klassen Person innehållande datamedlemmar för förnamn, efternamn, ålder, längd och vikt:

C Höstterminen Matematik. Elevhäfte KURSPROV. Elevens namn

Komma igång med TI-82 STATS

DiVA Digitala Vetenskapliga Arkivet

Träningsprogram för att förstärka ett önskvärt beteende hos små barn

PÅ UPPDRAG AV REV Ulf

KDiff3 är ett verktyg för jämförelser och sammanfogning av filer och kataloger, som

Det som inte mäts finns inte

Den tar slut i tomma intet, den rör sig och den låter GUNGBRÄDAN. Av Emelie Johnson Vegh & Eva Bertilsson Publicerad i Canis 2004

Provet består av Del I, Del II, Del III samt en muntlig del och ger totalt 75 poäng varav 28 E-, 23 C- och 24 A-poäng.

Pythonkramaren del två

Att skriva en teknisk rapport

Transkript:

Heltal(int) Datatypen int används tillsammans med char, short int och long int för att lagra heltal i C. Matematisk sett finns det oändligt många heltal. På en dator måste det införas en begränsning på hur stora heltalen kan bli. Normalt sparas ett heltal i ett maskin-ord, oftast 4 byte (4 * 8 = 32 bitar). I limits.h så finns definitioner på hur stora värden man kan lagra i int. Programmeringsteknik 54

Heltal forts. Om int lagras som 4 bytes, betyder det att den kan anta 2 32 olika värden. Hälften av värdena används för att lagra negativa heltal och hälften för att lagra positiva heltal. Om i är en variabel av typen int, kan i anta heltalsvärden inom intervallet [-2 31,2 31-1]. Eftersom variabler har begränsad lagringskapacitet kan man drabbas av overflow, t.ex. om man försöker multiplicera två variabler vars produkt blir större än det maximala värdet som en variabel kan lagra. Programmeringsteknik 55

Övriga heltalstyper short lagras oftast med 2 byte (vanligen mindre intervall än int). long lagras oftast med 4 eller 8 byte. (vanligen större intervall än int). unsigned framför en heltalstyp (ex. unsigned int) innebär att enbart positiva tal kan lagras. Detta innebär också att intervallet för tal (positiva) som kan lagras fördubblas. Programmeringsteknik 56

Heltalsexempel void main(void) { int i; unsigned short us; long l; i = 4; us = -1 /* VARNING!! Ger konstigt resultat. */ l = 3067825167823; } Programmeringsteknik 57

Tecken Tecken lagras i C som tal, där varje tecken motsvaras av ett heltal. Normal använder man char för lagra tecken men i C kan tecken representeras av variabler av vilken heltalstyp som helst. ASCII är en standard för vilka tecken som motsvarar vilket tal. Tecken är inte bara de skrivbara (t.ex. a, b,...) utan även kontrolltecken som används för att byta skrivrad (return), ljudsignal, tabulatortecken osv. Programmeringsteknik 58

Tecken Att tecken har en motsvarighet i siffror kan ses i följande exempel: #include <stdio.h> void main(void) { printf("%c %c %d %d\n", A, 65, A, 65); } Vilket ger utskriften: A A 65 65 Programmeringsteknik 59

Specialtecken Name Written in C Integer value null character \0 0 alert \a 7 backspace \b 8 horizontal tab \t 9 newline \n 10 vertical tab \v 11 formfeed \f 12 carriage return \r 13 double quote \ 34 single quote \ 39 backslash \\ 92 Programmeringsteknik 60

Flyttal(reella tal) Det finns tre flyttalstyper: float, double och long double. Variabler av denna typ kan innehålla reella värden som 0.001, 2.0 eller 3.14159. Hur stor precision en variabel av float, double eller long double har är systemberoende. Oftast är precisionen för en double bättre än en float och long double bättre än double. Programmeringsteknik 61

Flyttalskonstanter Vi kan lagra heltal som flyttalskonstanter men vi måste ange dom i formen 1.0 och 2.0. 3 däremot är en heltalskonstant. Flyttal kan också anges som 1.234567e5 vilket motsvarar 1.234567 10 5 Ett suffix kan läggas till som anger vilken typ konstanten är. f eller F anger att konstanten är float och l eller L anger att den är long double. Ett flyttal utan suffix är av typen double. T.ex. 3.7F säger att vi har en flyttalskonstant av typen float. Programmeringsteknik 62

Övriga flyttal En float har vanligtvis en ungefärlig precision av 6 signifikanta siffror och ett ungefärlig omfång (range) på 10-38 till 10 38. Representationen i maskinen blir (i bas 10 i.s.f. 2): 0.d 1 d 2 d 3 d 4 d 5 d 6 10 n där -38<n<38. En double har vanligtvis en precision av 15 signifikanta siffror och ett omfång på 10-308 till 10 308. x i satsen double x = 123.45123451234512345 /* 20 signifikant digits */ resulterar att x blir tilldelat ett värde som lagras enlig 0.123451234512345 10 3 (15 signifikanta siffror) Programmeringsteknik 63

Exempel Att reella tal inte lagras exakt kan ge upphov till vissa problem. Om vi antar att vår dator kan lagra en float med maximalt 5 signifikanta siffror. float x = 12345F; float y = 1e-1F; float z = 0 / (x + y - 0.12345e5F); /*problem*/ När uttrycket i nämnaren skall evalueras måste exponenten av de tre talen vara av samma storlek. x=0.12345e5 y=0.00000e5 x+y- 0.12345e5==0 Programmeringsteknik 64

Typdeklarationer, typdef Med typedef kan en datatyp associeras med en identifierare. typedef unsigned int coord_t; typedef double temp_t; Variabler kan därefter deklareras med identifieraren. coord_t x, y; temp_t inside, outside; Fördelarna är kortare typdeklarationer, men framför allt att datatypen antyder den avsedda användningen av variabler. Programmeringsteknik 65

Typstorlek, sizeof Operatorn sizeof används för att veta hur många bytes som krävs för att lagra ett objekt. Objekt kan vara en datatyp (float), ett uttryck (a+b), en vektor, eller en struktur (se senare kap.). sizeof(int) sizeof(a+b) sizeof returnerar ett heltal som anger hur många bytes som krävs för lagringen. C är flexibelt när det gäller storlekarna på datatyper vilket kan leda till dålig portabilitet av kod. Användandet av sizeof kan delvis undvika detta problem. Programmeringsteknik 66

Lagring Följande gäller alltid på alla system. sizeof(char) == 1 sizeof(unsigned) == sizeof(signed) == sizeof(int) sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) sizeof(float) <= sizeof(double) <= sizeof(long double) Enlig definitionen kan alltså en long vara lagrad med 1 byte (256 olika värden), men oftast lagras en long med 8 byte (2 64 olika värden). Programmeringsteknik 67

getchar() och putchar() getchar() och putchar() är makron (används som funktioner) definierade i stdio.h som läser tecken från tangentbordet respektive skriver tecken till skärmen. getchar() returnerar en int och putchar() tar en int som argument. I minnet så lagras en char som 1 byte och en int lagras oftast som 4 byte. Därför kan en int lagra alla värden som en char kan. Vi kan tänka oss char som en liten heltalstyp och int som en stor teckentyp. Vi kan alltså lagra tecken i int lika gärna som i char. Programmeringsteknik 68

double_out.c #include <stdio.h> /* i stdio.h finns raden #define EOF (-1) */ int main(void) { int c; while ((c = getchar())!= EOF) { putchar(c); putchar(c); } return 0; } Programmeringsteknik 69

capitalize.c #include <stdio.h> int main(void) { int c; while ((c = getchar())!= EOF) { if (c >= a && c <= z ) putchar( A + c - a ); else putchar(c); } return 0; } Programmeringsteknik 70

Matematiska funktioner Det finns inga inbyggda matematiska funktioner i C utan de tillhandahålls via matematikbiblioteket math.h. Alla matematikfunktioner (förutom pow()) tar ett enda argument av typen double och returnerar en double. Observera att absolutbeloppsfunktionen, abs(), tar heltal som argument, medan fabs() tar flyttal som argument. Detta leder till vanliga fel, speciellt då kompilatorn sällan ger varningar. Programmeringsteknik 71

Exempel #include <math.h> void main(void) { double a = 4.5; double b = 5.1; double c; c = sin(a + b) / fabs(cos(a)); } Programmeringsteknik 72

Konvertering Ett uttryck som x+y har både ett värde och en datatyp. Om både x och y är av typen int, så får x+y typen int. Däremot, om både x och y är av typen short, så kommer x+y att få typen int. Detta på grund av att short alltid konverteras till int. En char eller short (signed eller unsigned) kan användas där en int eller unsigned int förväntas. Ex. Om en funktion tar en int som argument, kan man skicka en char istället. Om däremot funktionen returnerar en int, så bör man inte ta emot det i en char. Programmeringsteknik 73

Aritmetiska konverteringar Om operanderna till en binär operator är av olika typ så kan en av dom konverteras. Anta att i är int och f är float. I uttrycket i+f så konverteras i till en float och hela uttrycket får typen float. Vid tilldelningar kan också konvertering ske. Om vi antar att i är av typen int och d är av typen double, kommer värdet av d = i att konverteras till double och hela uttrycket bli double. En utökning av en variabel, som sker i fallet med d = i går ofta bra men däremot i = d kan orsaka problem. Decimaldelen av d kommer att försvinna och i kommer att tilldelas heltalsdelen. Programmeringsteknik 74

Explicita konverteringar Explicita konverteringar (eng. casts) låter programmeraren byta typ på ett uttryck. Om vi antar att i är av typen int så kommer (double)i att konvertera värdet av i så att uttrycket har typen double. Variabeln i påverkas inte av konverteringen utan är fortfarande av typen int Ex. (long)( A +1.0) f = (float)((int)d + i) d = (double) i/3; (double)(x = 77) Programmeringsteknik 75

Flödeskontroll Satser i ett program utförs en och en efter varandra. Detta kallas sekventiell flödeskontroll. Ofta är det dock nödvändigt att modifiera flödet om ett villkor är uppfyllt eller om vi vill upprepa flera satser. Med if, if-else och switch-satser så kan ett val bland alternativ göras. Med while, for och do-while så kan vi åstadkomma upprepningar i vårt program. Programmeringsteknik 76

Relation, likhet och logiska operatorer Relationsoperatorer < mindre än > större än <= mindre än eller lika med >= större än eller lika med == lika med!= inte lika med Logikoperatorer! negation && logiskt och logiskt eller Programmeringsteknik 77

Relationsoperatorer Alla relationsoperatorer är binära, d.v.s. de tar två uttryck som operander. Som resultat av operatorerna får vi int värdet 0 (falskt) eller 1 (sant). Exempel: a < 3 a > b -1.3 >= (x - -1.2) a < b < 3 /* syntaktiskt rätt, men oväntat resultat, Varför? */ Felaktiga: a =< b /* Fel ordning på = och < */ a < = b /* Mellanslag ej tillåtet */ a >> b /* bitvis skiftning (se senare kap.) */ Programmeringsteknik 78

Likhetsoperatorer Likhetsoperatorerna är == och!=. Exempel: c == A k!= -2 x + y == 3 * z -7 Felaktiga a = b /* tilldelning */ a = = b /* mellanslag ej tillåtet */ (x + y) =! 44 /* syntax fel: samma som (x + y) = (!44) */ Programmeringsteknik 79

Logiska operatorer Logiska operatorer är!, && och. Exempel:!a!(x+ 7.7)!(a < b c < d) a && b a b Felaktiga a && /* operand saknas */ a b /* extra mellanslag */ a & b /* bitvis operation (se kap 7) */ & b /* minnesadressen till b */ Programmeringsteknik 80

Semantik expr1 expr2 expr1 && expr2 expr1 expr2 noll noll 0 0 noll icke noll 0 1 icke noll noll 0 1 icke noll icke noll 1 1 Programmeringsteknik 81

Kortslutning När datorn utvärderar sanningen i ett uttryck så slutar evalueringen så snart utkomsten är känd. Om vi har expr1 && expr2, så kommer inte expr2 att utvärderas om expr1 är falskt. int cnt = 0; while (++cnt <= 3 && (c = getchar())!= EOF) { /* something */ } När uttrycket ++cnt <= 3 är falsk kommer inte nästa tecken att läsas från stdin. Programmeringsteknik 82

Block Ett block är en mängd deklarationer eller uttryck som är omgivna av krullparenteser {}. Där man kan sätta in en sats så är det tillåtet att lägga in ett block. Blocket är i sig själv en sats. Block används är i samband med if, switch, for, do och while. int a = 1, b = 2; if (a > b) { printf("a is bigger than b\n"); } Programmeringsteknik 83

if och if-else Generella formen är if (expr) statement Satsen statement utförs endast om uttrycket expr är icke noll, d.v.s. sant. Exempel: if (score >= 75) printf("grattis!\n"); printf("du har fått %d poäng på tentan.\n", score); Grattis skrivs ut endast om grade har ett värde större än 75. Programmeringsteknik 84

if och if-else En if-else-sats ser ut som if (expr) then-statement else else-statement Satsen then-statement utförs endast om uttrycket expr är icke noll, d.v.s. sant. Satsen else-statement utförs endast om uttrycket expr är noll, d.v.s. falskt. Programmeringsteknik 85

if och if-else Exempel: printf("du har "); if (score >= 50) printf("godkänt "); else printf("underkänt "); printf("på tentan med %d poäng!\n", score); Beroende på om studenten nått upp till 50 poäng skrivs antingen Du har godkänt på tentan med xx poäng eller Du har underkänt på tentan med xx poäng ut. Programmeringsteknik 86

if och if-else if (y!= 0.0) z = x/y; if (j < min) min = j; /* är detta rätt eller? */ if (a < b) if (a < c) printf(" a < b && a < c\n"); else printf(" a < b && a >= c\n"); Ha för vana att använda {} vid nästlade if-satser. Om antalet nivåer med if-satser börjar bli stort (>4) fundera på att bryta upp dem i flera separata if-satser istället Programmeringsteknik 87

while Repetition av sekvenser är en av fördelarna med datorer. En dator blir, till skillnad från en människa, aldrig less på att upprepa samma saker hela tiden. Den generella formen är while (expr) statement Satsen statement utförs endast om och alltmedan uttrycket expr är sant. i = 1; while(i < n) factorial = factorial * i++; while ((a = getchar())!= EOF) { if (a >= a && a <= z ) lower_cont++; } total_cnt++; Programmeringsteknik 88

for for-satsens generella form for(expr1; expr2; expr3) statement next statement är semantiskt ekvivalent med expr1 while(expr2) { statement expr3 } next statement Programmeringsteknik 89

Exempel for (i = 1; i < n; i++) factorial = factorial * i; for (i = 2; i < k/2; i++) { if (k % i == 0) printf("%d is a divisor of %d\n", i, k); } Felaktig syntax: for (i = 0, i < 5, i+=3) {/*semikolon saknas!!*/ sum += i; } Programmeringsteknik 90

i = 1; sum = 0; for (; i < 10; ) sum += i++; är ekvivalent med sum = 0; for (i = 1; i < 10; i++) sum += i; Exempel Programmeringsteknik 91

Kommaoperatorn Lägst prioritet av alla operatorer i C har kommaoperatorn, Den är vänster-höger associativ, så i ett uttryck av formen expr1, expr2 kommer expr1 att utvärderas först och sedan utvärderas expr2 En vanlig användning av kommaoperatorn är i for-loopar for (i = 1, sum = 1; i < 10; i++) sum += i; /* samma som ovan */ for (i = 1, sum = 1; i < 10; sum += i, i++) ; /* EJ samma som ovan */ for (i = 1, sum = 1; i < 10; i++, sum += i) ; Programmeringsteknik 92

do-while Istället för att göra test i början som while, gör do-while sitt test i slutet. int age; do { fflush(stdin); printf("ange din ålder: "); scanf("%d", &age); } while (age < 0); En do-while kommer alltid att utföras minst en gång. Programmeringsteknik 93

switch switch är en multi-konditions if. Syntax switch ( uttryck ) { case värde1 : satslista1 case värde2 : satslista2 case värde3 : satslista3... default: satslistan } Programmeringsteknik 94

Exempel if (a == 1) printf("a är 1\n"); else if (a == 3) printf("a är 3\n"); else printf("a är inte 1 eller 3\n"); är ekvivalent med: switch (a) { case 1: printf("a är 1\n"); break; case 3: printf("a är 3\n"); break; default: } printf("a inte 1 eller 3\n"); Programmeringsteknik 95

break och continue För att bryta det normala flödet, kan break och continue användas. break bryter den innersta loopen eller en switchsats. continue hoppar ur ett loop-block och påbörjar nästa varv i loopen. while(1) { scanf("%lf", %x) if (x < 0.0) break; printf("%lf\n", sqrt(x)); } Programmeringsteknik 96

Villkorsoperatorn Villkorsoperatorn? : är ovanlig då den är en tertiär operator (den tar tre uttryck som operatorer). if (a < b) x = a; else x = b; kan skrivas som x = a < b? a : b; Om uttrycket före? är sant returneras uttrycket mellan? och :, annars returneras uttrycket efter :. Programmeringsteknik 97

Funktioner Istället för att försöka lösa ett stort problem på en gång, kan man dela upp det i mindre delproblem. top-down metod för att lösa problemen Försök dela upp programmet i mindre och mindre delproblem. När delproblemen är enkla nog, använd funktioner för att lösa delproblemen (och därmed hela problemet). Program är ofta uppdelade på flera källkodsfiler där varje fil kan innehålla noll eller flera funktioner. En funktion måste alltid finnas (main()) Programmeringsteknik 98

Funktionsdefinition C-källkoden, som beskriver vad en funktion gör, kallas funktionsdefinition. Den ska inte misstas för funktionsdeklarationen (också kallad funktionsprototyp). Funktionsdefinition ser ut så här i den generella formen type functionname ( parameter list ) { declarations statements } Allt innan första krullparentesen kallas funktionshuvud. Allt mellan krullparenteserna kallas funktionskropp. Parameterlistan är en komma-separerad lista med deklarationer. Programmeringsteknik 99

Exempel int square (int n) { return n*n; } Funktionshuvudet talar om att funktionen heter square och att den returnerar ett värde med datatypen int. I parameterlistan syns att funktionen kräver ett argument av datatypen int. Anropet square(7); innebär att funktionen anropas med ett värde 7 av heltalstyp. Detta värde kopieras till den lokala variabeln n som också den får värdet 7. Programmeringsteknik 100

Exempel void address(void) { printf("%s\n%s\n%s\n", "Johan Eliasson", "Dep. of Computing Science", "SE - 901 87 Umeå", "Sweden"); } Denna funktion returnerar ingenting (void). Den tar heller inga argument. Funktionen anropas med: address(); Observera att den inte anropas med address(void); Programmeringsteknik 101

Exempel void nothing (void) {} double twice (double x) { return (2.0 * x); } int min (int a, int b, int c) { return (a < b? (a < c? a : c) : (b < c? b : c)); } Programmeringsteknik 102

Variabler Variabler i en funktion är lokala för den funktionen. Ändringar av de variablerna kommer inte att påverka andra variabler med samma namn utanför funktionen. En variabel kan också deklareras utanför en funktionskropp. Den blir då global. Globala variabler bör man undvika. #include <stdio.h> int a = 1; int main(void) { int b = 4; printf(" a = %a\n b=%d\n", a, b); return 0; } Programmeringsteknik 103

return return används för att returnera värden från funktioner till den anropande miljön. return; return ++a; return (a * b); Om return-satsen innehåller ett utryck evalueras först uttrycket och värdet av uttrycket returneras. När return påträffas avbryts exekveringen av funktionen och kontrollen ges åter till den anropande miljön. Programmeringsteknik 104

Felaktiga exempel int fkn (int a) { return a++; /* a kommer inte att öka i värde */ /* allting nedanför kommer ej att exekveras */... } void fkn2 () { return 0; /* får inte returnera något */ } int fkn3 () { printf("hello world\n"); /* inget returneras */ } Programmeringsteknik 105

Funktionsprototyper En funktion bör deklareras innan den används. ANSI C tillhandahåller en deklarationssyntax som kallas funktionsprototyp. En funktionsprototyp berättar för kompilatorn antalet argument och av vilken typ argumenten är. Den berättar dessutom vilken typ av värde (om något) som funktionen returnerar. double sqrt(double); Detta berättar för kompilatorn att sqrt är en funktion som tar en double som argument och att den returnerar double. Programmeringsteknik 106

Funktionsprototyper Identifierare som anges i parameterlistan i en funktionsprototyp påverkar inte deklarationen utan är enbart av dokumentationssyfte. void print_time(int hour, int min); Funktionsprototyper är vanligast då program sträcker sig över flera filer. Kompilatorn kompilerar varje fil separat innan länkaren sätter ihop programmet. Om en funktion då är definierad i en annan fil måste man tillhandahålla prototypen (deklarationen). Programmeringsteknik 107

Funktionsanrop Programmet börjar alltid med ett anrop till main(). När en funktion anropas, ges kontroll till den funktionen. Efter att funktionen är klar med sitt jobb, ges kontrollen tillbaka till den anropande funktionen. Om en funktionsprototyp finns, kontrollerar kompilatorn att typerna på argumenten är kompatibla. Argumenten skickas call-by-value. Detta betyder att varje argument utvärderas och värdet av argumentet skickas till funktionen. Värdena lagras i motsvarande lokala variabel. Alltså, om en variabel skickas till en funktion så ändras inte värdet på variabeln i den anropande miljön. Programmeringsteknik 108

Exempel #include <stdio.h> int compute_sum(int n); int main(void) { int n = 3; int sum; printf("n = %d\n", n); sum = compute_sum(n); printf("n = %d\n", n); printf("sum = %d\n", sum); } return 0; Programmeringsteknik 109

Exempel (forts) int compute_sum(int n) { int sum = 0; for ( ; n > 0; n--) sum += n; return sum; } Programmeringsteknik 110

Funktionsanrop Funktionsanrop innebär: Varje uttryck i argumentlistan utvärderas Värdet på uttrycket konverteras, om nödvändigt, till typen på den formella parametern och det värdet ges till den formella parametern i början av funktionskroppen. Alla argument skickas call-by-value Funktionskroppen exekveras (körs). Om en return-sats påträffas, så ges kontrollen tillbaka till den anropande miljön Programmeringsteknik 111

Funktionsanrop Om return-satsen innehåller ett uttryck, utvärderas uttrycket och konverteras, om nödvändigt, till returtypen och det värdet skickas till den anropande miljön. Om en return-sats inte innehåller ett uttryck, skickas inget användbart värde tillbaka till den anropande miljön. Om ingen return-sats påträffas, ges kontrollen tillbaka till den anropande miljön när slutet på funktionskroppen påträffas. Inget användbart värde returneras. Programmeringsteknik 112