Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

C for Java-programmerere Åsmund Eldhuset for Anne C. Elster / TDT4200 asmunde *at* stud.ntnu.no

Liknende presentasjoner


Presentasjon om: "C for Java-programmerere Åsmund Eldhuset for Anne C. Elster / TDT4200 asmunde *at* stud.ntnu.no"— Utskrift av presentasjonen:

1 C for Java-programmerere Åsmund Eldhuset for Anne C. Elster / TDT4200 asmunde *at* stud.ntnu.no

2 Litt historie C ble utviklet på 70-tallet av Brian W. Kernighan og Dennis M. Ritchie Designet for systemprogrammering under UNIX C++ ble utviklet på 80-tallet av Bjarne Stroustrup Bygger på C; første utgave het "C with classes" Hentet mange ideer fra norskutviklede Simula (verdens første objektorienterte språk) Både C og C++ er åpne og ISO-standardiserte

3 Argumenter for C Raskere enn Java Java kjøres av en Virtual Machine C kompileres til maskinkode Gir nærkontakt med systemet – dermed meget godt egnet til systemprogrammering (operativsystemer, mikrokontrollere etc.) Du kan gjøre så godt som alt som er mulig å gjøre med datamaskinen Nerdefaktor

4 Argumenter mot C Mindre nybegynnervennlig Lett å skyte seg selv så til de grader i foten Uforsiktighet kan føre til obskure minnelekkasjer Portabiliteten varierer med hva man foretar seg Utvikling tar generelt sett lengre tid enn med C++, Java og C# Ikke objektorientert

5 Når bruke C? Når du trenger rå hastighet (spill, grafikk, tungregning, algoritmekonkurranser) Når du driver systemprogrammering Når du arbeider med eksisterende C-systemer Når du har lyst til å leke deg med programmering Når du tar TDT4200

6 Dette finnes ikke i C: Klasser Arv Polymorfi Virtuelle og abstrakte metoder Interfaces Generics/templates Exceptions Referanser (C++-konsept) Reflection/introspection

7 Kompilatorer og IDE'er Kompilator oversetter koden til maskinkode IDE = Integrated Development Environment (kombinerer editor, kompilator og debugger) Linux: Kompilator: gcc / g++ Debugger: gdb Editor: det du foretrekker Windows: Microsoft Visual Studio (http://msdn.microsoft.com/vstudio/express/visualc/) Bloodshed Dev-C++ (http://www.bloodshed.net/devcpp.html)

8 Bruk av gcc Kompilering: gcc kildefil For C99-modus, bruk flagget -std=c99 Kjøring:./a.out Kompilere flere filer: gcc kilde1 kilde2... Endre navnet til outputfilen: gcc -o outputfil kildefil./outputfil Skyte seg selv i foten: gcc -o kildefil kildefil (sletter kildekoden din)

9 Minimalt program int main() { return 0; } Vi legger merke til: Typen til main() er int, ikke void Ingen String [] args (skal programmet ta imot argumenter, skriv int argc, char * argv [] ) main() er ikke public static og står ikke inni noen klasse (klasser finnes jo ikke i C – tilsvarer at alle metodene er static)

10 Del I: Grunnleggende C

11 Hello World // Dette er et Hello World-program #include int main() { printf("Hello World!\n"); return 0; }

12 Hello World Kommentarer lages med // eller /* */ printf(x); tilsvarer System.out.println(x);, men kan bare brukes slik hvis x er en streng #include minner om import, men fungerer ved å "lime inn" en fil (mer om dette senere) stdio.h er et bibliotek som inneholder IO-støtte (f.eks. printf )

13 Output: printf printf baserer seg på formatstrenger – først kommer en streng som beskriver datatypene til det som skal skrives ut, og så kommer dataene som skal skrives ut printf(x) skriver ut en streng – må aldri brukes hvis innholdet i x kan inneholde prosenttegn (f.eks. hvis den inneholder data som kommer fra brukeren) printf("%s", x) skriver ut en streng på trygg måte printf("%d", x) skriver ut en int Formatstrengen kan også inneholde andre tegn. Linjeskift lages med \n

14 Formatflagg %s – streng (char *) %d – int %u – unsigned int %ll – long long (pass på: long er 32 bits) %c – enkelttegn (char) %p – peker/minneadresse %x – int på heksadesimal form %f – float %lf – double Antall desimaler kan styres slik: %.3f For faktisk å skrive ut et prosenttegn: %

15 Input: scanf Samme formatstreng-konsept (men her må formatstrengen alltid være med) scanf("%d", &x) leser inn en int Merk &-tegnet – må være med for alle datatyper annet enn for strenger: scanf("%s", x) (som leser inn ett ord) Kan lese inn flere ting etter hverandre: scanf("%d%s%f", &x, y, &z)

16 Variabler Variabler lages og brukes på samme måte som i Java C har følgende primitive datatyper: char (tilsvarer byte og til en viss grad char ) short int long (32 bit!) long long (64 bit) float double float/double complex unsigned kan brukes foran heltallstypene Funksjoner kan også ha void som type

17 If/else, for, while... fungerer på samme måte som i Java! Kun én forskjell: betingelser i if/else og while kan være heltall (0 blir false, alt annet blir true ) og pekere ( NULL blir false, alt annet blir true ) int x, y; scanf("%d%d", &x, &y); if (y) printf("%d\n", x / y); else printf("Nevneren er 0!\n");

18 Deklarasjon av funksjoner Før en funksjon brukes, må kompilatoren vite at funksjonen eksisterer Dette kan gjøres på to måter: Funksjonen kan allerede være definert (dvs. at funksjonskoden står lenger oppe i kodefilen) Definisjonen kan finnes i en annen fil, og funksjonen kan deklareres (dvs. at man bare skriver metodenavnet) Eksempel: funksjonen int square(int n) { return n * n; } kan deklareres slik: int square(int);

19 Biblioteker og headerfiler C-kompilatoren kompilerer én fil av gangen uavhengig av alle de andre Biblioteksfunksjonene ligger i ferdigkompilerte filer Headerfiler inneholder deklarasjoner som forteller hvordan biblioteksfunksjonene ser ut Hvis f.eks. kompilatoren ser int square(int);, stoler den på at det finnes en slik funksjon. Den kompilerer koden som bruker square() og prøver etterpå å koble inn square() sin egen kode Sammenkoblingsprogrammet kalles for en linker, og er som regel en del av kompilatoren

20 Biblioteker og headerfiler Man kan selv lage prosjekter som består av flere kodefiler Koden deles opp i kodefiler (.c) og headerfiler (.h) Headerfilene inneholder deklarasjoner (navn og parameterlister for metoder og klasser) Kodefilene inneholder definisjoner (den faktiske implementasjonen / koden) #include "limer inn" koden fra en fil, og skal bare brukes for å inkludere headere

21 xor.h xor.c math.h main.cpp Headerfiler og linking Originale kilde- og headerfiler før preprosessering: #include "xor.h" #include int main() { printf("%lf\n", sin(0.5)); printf("%d\n", xor(true, false)); return 0; } #include "xor.h" bool xor(bool a, bool b) { return a && !b || !a && b; } bool xor(bool, bool);double sin(double);

22 xor.h xor.c math.h main.c Headerfiler og linking Headerfiler limes inn i kildefiler under preprosessering: bool xor(bool, bool); double sin(double); int main() { printf("%lf\n", sin(0.5)); printf("%d\n", xor(true, false)); return 0; } bool xor(bool, bool); bool xor(bool a, bool b) { return a && !b || !a && b; } bool xor(bool, bool);double sin(double);

23 xor.obj xor.cmain.c Headerfiler og linking Kildefilene kompileres separat: bool xor(bool, bool); bool xor(bool a, bool b) { return a && !b || !a && b; } [Contains bool xor(bool, bool)] main.obj [Contains main()] [References bool xor(bool,bool)] [References double sin(double)] bool xor(bool, bool); double sin(double); int main() { printf("%lf\n", sin(0.5)); printf("%d\n", xor(true, false)); return 0; }

24 xor.obj Headerfiler og linking Objektfilene linkes for å produsere programfilen: main.obj math.obj [Contains bool xor(bool, bool)][Contains main()] [References bool xor(bool,bool)] [References double sin(double)] main.exe [Contains double sin(double)]

25 Hvis en headerfil inkluderer en annen og begge to inkluderes i en tredje fil, blir det kollisjoner Include guards hindrer kollisjonene #ifndef FILENAME_H #define FILENAME_H (resten av filen her) #endif Include guards math.h main.cpp main.h #include #include "main.h" #include double sin(double);

26 Del II: Pekere

27 Pekere En variabel som inneholder en minneadresse Bruk * i deklarasjoner for å lage "peker-til-datatype" Bruk & for å finne adressen til en variabel Bruk * for å dereferere en peker (lese innholdet i adressen det pekes til) C bruker NULL i stedet for null Ved deklarasjon av flere pekere må * gjentas for hver peker int a = 42; int * p = NULL; p = &a; printf("%p\n", p); printf("%d\n", *p); p 42 a 0x32 p 42 a 0x040x32

28 pq Triksing med pekere int a = 3; int * p, * q; p = &a; q = &a; *p = 42; printf("%d\n", a); printf("%d\n", *q); 3 a 42

29 Peker-til-peker-til... int a, * p, ** q, *** r; a = 42; p = &a; q = &p; r = &q; printf("%p\n", r); printf("%p\n", *r); printf("%p\n", **r); printf("%d\n", ***r); q p 42 a r

30 Funksjonsargumenter Alle argumenter sendes som kopi Følgende gir dermed ikke det tenkte resultatet: void swap(int a, int b) { int temp = a; a = b; b = temp; } Vi sender pekere i stedet, for da får vi modifisert dataene gjennom pekerne: void swap(int * a, int * b) { int temp = *a; *a = *b; *b = temp; } Sistnevnte funksjon må kalles slik: swap(&a, &b)

31 void * og casting En void * kan peke til hva som helst (omtrent som et Object i Java) Alle slags pekere kan assignes til void * Kan brukes til å lage funksjoner som kan ta inn vilkårlige typer (f.eks. compare-funksjonen man må lage når man vil bruke qsort-funksjonen) Kan caste ting tilbake på samme måte som i Java (int)f vil konvertere f til en int (int*)p vil se på det p peker på og tolke det som en int Men dette er IKKE typesikkert – det sjekkes aldri om casts er "riktige"! float f = 3.14f; int * i = (int *)&f; printf("%d\n", *i);

32 Arrays Et array er bare et sammenhengende minneområde av samme datatype En peker kan derfor brukes til å peke til starten av et array Arrays lages ved å spesifisere hvor mange bytes du trenger: int * array = malloc(sizeof(int) * 4); array

33 Arrays Arrays er 0-indekserte og aksesseres som i Java: array[2] = array[1] + array[0]; Bak kulissene foregår oppslag på array[i] slik: Adressen i array leses Størrelsen til datatypen som array peker til ganges med i og adderes til adressen for å finne hvor dataene ligger array 4 bytes 0x320x360x400x44 0x32

34 Arrays Arrays vet ikke hvor store de er, og du får ingen exception (eksisterer ikke i C) hvis du går utenfor grensene int * array = malloc(sizeof(int) * 8); for (int i = -1; i <= 8; ++ i) printf("%d\n", array[i]); Ingen feilmelding Du får ut data Programmet kan krasje noen ganger, og fortsette andre ganger Etter bruk må et array slettes: free(array);

35 Flerdimensjonale arrays int ** array = malloc(sizeof(int*)*3); for (int i = 0; i < 3; ++ i) array[i] = malloc(sizeof(int)*4); array

36 Del III: Structs, strenger, makroer og minnebehandling

37 Structs Tilsvarer klasser som kun inneholder public- variabler, og ingen metoder Kan ikke arves (men de kan komponeres, altså at en struct inneholder en annen) Constructors og destructors eksisterer ikke, men dette og andre medlemsmetoder kan simuleres ved å lage metoder som tar struct-pekere som parametre

38 Structs struct Person { int age; char * name; }; Merk semikolonet Struct-variabler må deklareres som struct Person p; Hvis man skriver typedef struct { int age; char * name; } Person; kan variablene deklarereres som Person p;

39 Structs Struct-variabler inneholder dataene i stedet for å peke til dem, akkurat som primitive variabler Sender man en struct til en funksjon, får funksjonen en kopi Skal funksjonen modifisere struct'en, må den få en peker Struct-medlemmer kan aksesseres gjennom en peker: p->age

40 Arrays med structs Primitive typer: int * intArray = malloc(sizeof(int) * 4) ; Structs: Car * carArray = malloc(sizeof(Car) * 4) ; Structpekere: Car ** carPointerArray = malloc(sizeof(Car *) * 4) ; for (int i = 0; i < 4; ++ i) carPointerArray[i] = malloc(sizeof(Car)) ;

41 Arrays med structs a a[0]a[1]a[2]a[3] car car[0]car[1]car[2]car[3]

42 Arrays med structs cp cp[0]cp[1]cp[2]cp[3] *cp[0] *cp[1] *cp[2] *cp[3]

43 Strenger Det finnes ingen innebygd streng-datatype En streng er et array av tegn: char * str; eller char [] str; Må bruke funksjoner for å behandle strenger: strcmp – sammenligner to strenger og returnerer 0 (samme som compareTo i java) strcat – konkatenerer strenger strcpy – kopierer en streng Pass på minnet! String literals kan vanligvis ikke modifiseres (kompilatoren kan plassere dem i et spesielt minnesegment) Kan bruke sprintf for å "printe" til en streng

44 Makroer I praksis en søk og erstatt-funksjonalitet Evalueres under preprosesseringsfasen Kan brukes til å deklarere konstanter: #define PI Merk: ingen semikolon – alle forekomster av identifikatoren PI (utenfor strenger) vil bli erstattet med alt som står etter PI i deklarasjonen Kan også brukes til å deklarere en slags funksjoner som automatisk blir inline't (så man slipper overhead ved funksjonskall), men her er det mange feller å gå i

45 Makroer #define lookup(a, r, c, w) (a)[(r) * (w) + (c)] lookup(array, r, c, width) vil da bli skrevet om til (array)[(r) * (width) + (c)] Parentesene er der i tilfelle man f.eks. skriver lookup(array, r + 1, c, width) Man kan referere til variabler i definisjonen, men disse vil bli evaluert der makroen brukes, så dette er potensielt sett veldig farlig: #define lookup(a, r, c) (a)[(r) * width + (c)] er lov hvis width er definert (og har riktig verdi) der man skriver lookup(array, r, c) Argumenter blir ikke evaluert før de sendes til makroen, så hvis man har #define square(a) (a)*(a) vil square(n++) bli til (n++)*(n++) (og det er ikke en gang lov å endre en variabel mer enn én gang i samme statement)

46 Minnebehandling C har ingen garbage collector Du er selv ansvarlig for å frigi minne du ikke trenger lenger, med free Regler for trygg minnebehandling: Ta alltid vare på resultatet fra malloc Hver gang du skriver malloc, husk å plassere en free på et passende sted Vær veldig påpasselig med ikke å free 'e det samme to ganger! Når du free 'er en struct som peker til noe, bør du finne ut om dette også er rett sted å free 'e det den peker til (svaret kan være nei; kanskje andre objekter fortsatt peker til det samme)


Laste ned ppt "C for Java-programmerere Åsmund Eldhuset for Anne C. Elster / TDT4200 asmunde *at* stud.ntnu.no"

Liknende presentasjoner


Annonser fra Google