1 / 36

Krasjkurs i C (pluss litt matlab)

Krasjkurs i C (pluss litt matlab). Innhold. Litt om Matlab Funksjoner Strukturer (Structs) Noen matlab-funksjoner dere kan få bruk for C Kompilatorer Kompilering C syntaks Funksjoner i C Variable i C Operatorer i C Pekere Arrays og Strukturer Makroer

dobry
Download Presentation

Krasjkurs i C (pluss litt matlab)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Krasjkurs i C (pluss litt matlab)

  2. Innhold • Litt om Matlab • Funksjoner • Strukturer (Structs) • Noen matlab-funksjoner dere kan få bruk for • C • Kompilatorer • Kompilering • C syntaks • Funksjoner i C • Variable i C • Operatorer i C • Pekere • Arrays og Strukturer • Makroer • Dynamisk Minne-allokering • Lesing og skriving av binær fil, eksempel på å lese en wav-fil i C. (Nyttig for oppgaven..!) Om du ønsker, kan du sette inn navn, tittel på foredraget, o.l. her.

  3. Matlab • Antar en del kunnskap i matlab: For mer grundig introduksjon henvises til: http://www.iet.ntnu.no/~gjendems/documents/MatlabIntro.pdf • Matlab skiller seg fra språk som java og C ved at matlab prosesserer linje for linje, • Matlab håndterer mange oppgaver, som du selv må ha kontroll på i C! (håndtering av datatyper, minneallokering o.l) • Matlab er bra til simulering pga. enkel syntaks, koden er enkel å debugge, og det finnes mange funksjoner for visualisering av data. • Matlab har mange ferdiglagde funksjoner, men tenk på å skrive matlab kode som uten for store endringer kan skrives om til C ! Om du ønsker, kan du sette inn navn, tittel på foredraget, o.l. her.

  4. Funksjoner i Matlab En funksjon er en “.m” fil som starter med function. Funksjon kan ta variable inn, utføre en eller flere operasjoner, og returnere et vilkårlig antall variable. Akkurat som funksjoner i java eller C Variabel (ev. variable) som skal returneres. “geom()” er en funksjons-navnet. Funskjonen må lagres som geom.m function ssum =geom(a,N) % funksjon som beregner summen til en % geometrisk rekke n=0:N; ssum= sum(a.^n) Funksjons-argumenter Kommentarer i Matlab beynner med %

  5. Strukturer i Matlab struct: Ikke så forskjellig fra et objekt i java, men en struct er uten metoder. En struct består av av felter med tilhørende verdier, der de forskjellige feltene kan inneholde forskjellige datatyper. >>opt=struct('gamma',0.9,'nbits',4,'stepsize',2.0) opt = gamma: 0.9000 nbits: 4 stepsize: 2 >> opt.gamma ans = 0.9000 >> opt.alpha=0.9 opt = gamma: 0.9000 nbits: 4 stepsize: 2 alpha: 0.9000 Felter blir aksessert med ‘.’ notasjon. Nye felter kan enkelt legges til. Struct er en grei datatype å bruke for å samle tilhørende data.

  6. Noen matlab-funksjoner dere kanskje får bruk for • Wavrecord: Ta opp lyd i matlab. • Wavread: Les inn en ’wav’-fil til en vektor i matlab • Wavwrite: skriv en vektor til en ’wav’-fil • Soundsc: Spill av en vektor i matlab • Wavplay: Spill av en wavfil i matlab (Kan også gjøres med først wavread og deretter soundsc) • Randn: Generer normalfordelte tilfeldige tall i matlab, kan brukes når støy-generatoren skal implementeres • Er du usikker på hvordan disse funskjonene brukes, skriv help funksjonsnavn i matlab.

  7. C-Kompilator • C er i motseteting til matlab et kompilatorspråk på samme måte som java (javac). • C-kompilatorer finnes gratis tilgjengelig på internett. I prinsippet kan dere bruke den dere liker best.. • Forslag: • Gnu’s kompilator gcc. • Denne er egentlig laget for unix, men kan kjøres på windows i et program som heter cygwin • Fremgangmåte i windows: • Innstaller Cygwin • Et tips er å legge katalogen hvor bin-filen til cygwin ligger (vanligvis C:/cygwin/bin) i environment-variablen ”system path”, slik at kompilatoren gcc kan kjøres uansett hvilken katalog man er i. • Får du ikke kompilatoren til å fungere, kom å spør oss om hjelp! 

  8. Kompilering med gcc Kjør kompilatoren for å konvertere programmet fra kildekoden til en binær kjørbar fil: $ gcc my_program.c –o my_program Opsjonen –o betyr at det lages en fil som heter my_program.exe i windows, eventuelt my_program.out i unix. Hvis ikke denne brukes lages en fil med navn a.out (som er default) Kan programmet ha mer enn en c fil? Det kan være lurt å lage en makefil som definerer regler for kompilering og lenking av alle filer som inngår i et program. Da kan hele systemet enkelt kompileres med å skrive make. Mer om hvordan man lager en slik makefil neste gang.

  9. Kompilator Kompileringer skjer i to steg: Preprossesering og kompilering. Preprosessering #include <stdio.h> /* The simplest C Program */ int main(int argc, char **argv) { printf(“Hello World\n”); return 0; } • I preprossesering blir kildekoden ekspandert til lengre kode som er enklere for kompilatorene å forstå. Alle linjer som start med # blir tolket av preprosessoren • #include inkluderer en fil. • #define definerer en makro. • Kommentarer blir fjernet ( /* */ , // ) • kodelinjer over flere linjer blir satt sammen til en linje ( \ ) __extension__ typedef unsigned long long int __dev_t; __extension__ typedef unsigned int __uid_t; __extension__ typedef unsigned int __gid_t; __extension__ typedef unsigned long int __ino_t; __extension__ typedef unsigned long long int __ino64_t; __extension__ typedef unsigned int __nlink_t; __extension__ typedef long int __off_t; __extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ; extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ; int main(int argc, char **argv) { printf(“Hello World\n”); return 0; } Program Kompilatoren endrer så teksten til binær kode som CPU’en kan kjøre direkte Kompilering

  10. C Syntax, og Hello World #include setter inn en fil. “.h” filer er såkalte “header-filer”. Header-filer definerer grensenittet (interface i java) til bibliotek og kode i andre c-filer. stdio.h er et av de vanligste biliotekene brukt u C, og inneholder funskjoner for standard input and output. Hva menes med < > ? Kommentarer i C beynner med /* og avsluttes med */. int main() funksjonen er alltid! Det stedet hvor programmet starter å kjøre. (Uavhengig hvor main funksjonen finnes i koden) #include <stdio.h> /* The simplest C Program */ int main(int argc, char **argv) { printf(“Hello World\n”); return 0; } Blokker med kode markeres med { … }. En blokk eller et skop har egne lokale variable, som bare er tilgjengelige innenfor blokken Returner ‘0’. main() returnerer enten 0 eller 1, der programmet kan returnere 1 til operativsystemet hvis det har oppstått en feil. Skriv ut en melding til “stdout”. ‘\n’ betyr ny linje. Alle “Statements” må avsluttes med semikolon.

  11. Funksjoner Funksjoner i C er veldig likt funksjoner i java. Man sender Argumenter til funksjonen og den retunerer en Verdi. Return type, or void “main()” er en funksjon. Funksjons-argumenter #include <stdio.h> /* The simplest C Program */ int main(int argc, char **argv) { printf(“Hello World\n”); return 0; } Å kalle en funksjon “printf()” er bare en annen funksjon, som main(). Den er definert i “biblioteket” stdio.h, en samling funksjoner som kan kalles fra programmet. Returnering av verdi

  12. Initiell verdi til x er udefinert Initiell verdi Navn Hvilke navn kan brukes? Datatypen er en enkelt char (“character”) extern? static? const? Hva er en Variabel Symbol-tabell En Variabel navngir en plass i minnet hvor man lagrer en Verdi av en bestemt Datatype. Man Deklarerer en variabel ved å gi den et navn og ved å spesifisere datatypen, eventuelt kan man sette en initialverdi (startverdi) char x; char y=‘e’; Kompilatoren legger dem et sted i minnet.

  13. Hva er minne? Datamaskin-minne kan sammenlines med en stor tabell med nummererte bokser. Nummeret til boksen er Addressen. En byte kan lagres i hver boks 72? Noen “logiske” datatyper bruker mer enn en boks, slik som strengen “Hello\n” som består av flere “charcters”, altså en tabell av datatypen char. En Datatype navngir en logisk måte å lagre verdier i minnet of memory. Noen datatyper er: en enkelt char(1 slot) En tabell med 10 char’s signed 4 byte integer 4 byte floating point signed 8 byte integer char char [10] int float int64_t Ikke alltid… Signed?…

  14. Mer om datatyper og minne. Forskjellige datatyper bruker forskjellige mengde minne. De fleste datamaskin- arkitekturer lagrer på et heltallig multiplum av størrelsen på en primitiv datatype.(int,char) char x; char y=‘e’; int z = 0x01020304; “padding” En “vanlig” int bruker 4 bytes (dvs 32 bit integer) 0x betyr at konstanten er skrevet i hex (16-tallsystem,0..9,A..,F)

  15. (Returner ingenting) Skopet til en variabel Alle Variable er definert innefor et “skop”. En Variabel kan ikke refereres utenfor dette skopet. void p(char x){ /* p,x */ char y; /* p,x,y */ char z; /* p,x,y,z */ } /* p */ char z; /* p,z */ void q(char a){ char b; /* p,z,q,a,b */ { char c; /* p,z,q,a,b,c */ } char d; /* p,z,q,a,b,d(not c) */ } /* p,z,q */ Skopet til en variabel defineres med klammeparanteser { }, som i java, og tilsvarer begin-end i matlab. Kalles også en blokk Skopet til funksjons-argumentene er kun inne i funskjonen, dvs. innenfor klammeparantesene til funksjonen. Skopet til variablene definert inne i en funksjon starter ved definisjonen og slutter ved slutten av char b? legal? Skopet til variable definert utenfor funksjonen starter ved definisjonen og slutter på slutten av filen, kalt gloable variable.

  16. Sammenligning og matematiske operatorer == equal to < less than <= less than or equal > greater than >= greater than or equal != not equal && logical and || logical or ! logical not • Obs: Deling: • Hvis andre argument er integer, så • vil resultatet bli integer !! (rounded): • 5 / 10  0 , mens 5 / 10.0  0.5 & bitwise and | bitwise or ^ bitwise xor ~ bitwise not << shift left >> shift right • + plus • minus • * mult • / divide • % modulo Obs: Forskjell på & and &&.. 1 & 2  0 mens 1 && 2  <true>

  17. Mer om operatorer i C x = y assign y to x x++ post-increment x ++x pre-increment x x-- post-decrement x --x pre-decrement x x += y assign (x+y) to x x -= y assign (x-y) to x x *= y assign (x*y) to x x /= y assign (x/y) to x x %= y assign (x%y) to x Merk forskjellen på ++x og x++: int x=5; int y; y = ++x; /* x == 6, y == 6 */ int x=5; int y; y = x++; /* x == 6, y == 5 */ Ikke bland tilordningsoperator =, og sammenligningsoperator == int x=5; if (x=6) /* always true */ { /* x is now 6 */ } /* ... */ int x=5; if (x==6) /* false */ { /* ... */ } /* x is still 5 */

  18. “While” og “for” syntaks i C “for” løkka kan ses på som en kortversjon av en while-stuktur float pow(float x, uint exp) { float result=1.0; int i; i=0; while (i < exp) { result = result * x; i++; } return result; } int main(int argc, char **argv) { float p; p = pow(10.0, 5); printf(“p = %f\n”, p); return 0; } float pow(float x, uint exp) { float result=1.0; int i; for (i=0; (i < exp); i++) { result = result * x; } return result; } int main(int argc, char **argv) { float p; p = pow(10.0, 5); printf(“p = %f\n”, p); return 0; }

  19. Ville dette fungere? void pow_assign(float x, uint exp) { float result=1.0; int i; for (i=0; (i < exp); i++) { result = result * x; } x = result; } Kan en funksjon modifisere argumentene? Hva om vi ønsket å implementere en funksjon pow_assign() som modifiserer argumentet, slik at disse er ekvivalente: float p = 2.0; /* p is 2.0 here */ p = pow(p, 5); /* p is 32.0 here */ float p = 2.0; /* p is 2.0 here */ pow_assign(p, 5); /* p is 32.0 here */ Nei! I C, blir alle argumenter sendt som verdier, og skopet til den modifiserte variabelen er bare innenfor funskjonen Men, hva om vi sendte argumentet som adressen til variabelen?

  20. Å sende adresser Hva om vi hadde en måte å finne adressen til en variabel, og så referere til minnet med adressen. address_of(y) == 5 memory_at[5] == 101 void f(address_of_char p) { memory_at[p] = memory_at[p] - 32; } char y = 101; /* y is 101 */ f(address_of(y)); /* i.e. f(5) */ /* y is now 101-32 = 69 */

  21. Dette er akkurat hvordan pekere virker. En “peker type”: peker til char “addressen til”/ referingsoperator: & “verdien til”/ dereference operator: * void f(address_of_char p) { memory_at[p] = memory_at[p] - 32; } void f(char * p) { *p = *p - 32; } char y = 101; /* y is 101 */ f(address_of(y)); /* i.e. f(5) */ /* y er nå 101-32 = 69 */ char y = 101; /* y is 101 */ f(&y); /* i.e. f(5) */ /* y er nå 101-32 = 69 */ En ny datatype: Pekere • Pekere brukes i C for til mange ting: • Sende store objekter uten å kopiere dem • Aksessere dynamisk allokert minne • Referere til funksjoner

  22. Eksempel på pekere Input er en peker til char “addressen til” : & “verdien til”: * void f(address_of_char p) { memory_at[p] = memory_at[p] - 32; } void f(char * p) { *p = *p - 32; } char y = 101; /* y is 101 */ f(address_of(y)); /* i.e. f(5) */ /* y is now 101-32 = 69 */ char y = 101; /* y is 101 */ f(&y); /* i.e. f(5) */ /* y is now 101-32 = 69 */ “Pointers” En tommelfinger-regel er at hvis input-variablene som sendes til funksjonn skal endres i funksjonen, må de sendes som pekere. Hvis de ikke endres bør de sendes til funksjonen som verdier. NB!: Bruker man pekere som input til funksjoner er det veldig viktig å huske å sende adressen og ikke verdien, da man i tilfelle vil endre på en helt tilfeldig plass i minnet, som kan føre til at hele systemet krasjer.

  23. Eksmpel på pekere int *p; er en peker til en integer. En stjerne i forkant av variabelnavnet deklarerer variabelen til å være en peker til den deklarerte typen (her int) int *p , q deklarerer en peker til int (p), og en int (q). p=&q lagrer adressen til q i p int a; a=*p * er også dereferingsoperator, som betyr verdien til p, altså verdien som ligger i addressen p peker på. I dette tilfellet vil altså variablen a få verdien til q

  24. Arrays Arrays i C er en tabell med data av samme datatype, der data blir lagt i minnet etter hverandre. [5] spesifiserer antallet elementer. Initielle verdier kan settes I { }. /* define an array of 10 chars */ char x[5] = {‘t’,’e’,’s’,’t’,’\0’}; /* accessing element 0 */ x[0] = ‘T’; /* pointer arithmetic to get elt 3 */ char elt3 = *(x+3); /* x[3] */ /* x[0] evaluates to the first element; * x evaluates to the address of the * first element, or &(x[0]) */ /* 0-indksert */ #define COUNT 10 char y[COUNT]; int i; for (i=0; i<COUNT; i++) { /* process y[i] */ printf(“%c\n”, y[i]); } Arrays i C er 0-indeksert (her, 0..9) x[3] == *(x+3) == ‘t’ Hva er forskjellen på char x[count] og char *x?

  25. Repetisjon, pekere og arrays int main(int argc,char **argv) { int *p ; int a=5; p=&a printf("Addressen til p: %d\n",p); printf("Addressen til a: %d\n",&a); printf("Verdien i p: %d\n",(*p)); printf("Addressen til p: %d\n",(&p)); a=p; /* Kompilator gir warning!*/ printf("Verdien til a: %d\n",&a); a=3; printf("Verdi til p: %d\n",(*p)); printf("Verdien p[0]!: %d\n",p[0]); int c[5]; c[0]=0; c[2]=2; printf("Verdien til \"c\": %d\n",c); printf("addressen til c: %d\n",&c); printf("addressen c[0]: %d\n",(&c[0])); printf("addressen c[1]: %d\n",&c[1]); printf("addressen c[2] : %d\n",&c[2]); printf("Verdi c[0]: %d\n",c[0]); printf("Verdi c[2]: %d\n",c[2]); return 0;} Når a settes til p, blir a lik adressen lagret i p, som ofte er et veldig stort tall. Kompilatoren vil gi en warning om at et int blir satt til en pekerverdi uten ”casting”. Selv om ikke a er en peker kan addressen refereres med &a Setter a til verdien 3, som også medfører at p peker på verdien 3. (p peker på a). Selv om p ikke er definert som et array kan p tolkes som et endimensjonalt array, og verdien til p kan refereres med p[0]. c=&c=&c[0] som er adressen til det første elementet. c er altså egentlig en peker til det første elementet arrayet .

  26. Lese og skrive til fil Før en fil kan bli aksessert, må den åpnes med fopen. Fopen returner en peker til en definert datatype FILE (eller en null-peker hvis noe går galt) int main(int argc,char **argv) { FILE *f,*f_new; /*2 filpeker2*/ long offset=44; f=fopen("ae_a01.wav","rb"); f_new=fopen(“test.wav",“wb"); fseek(f,offset,0); short value[1]; /*buffer*/ for (int i=0;i<100; i++) { fread(&value,sizeof(short),1,f); printf("%d\n",value[0]) fwrite(&value,sizeof(short),1,f_new); } fclose(f); return 0; } ’rb’ vil si å åpne en binær fil for lesing, ’wb’ for å åpne for skriving. (Og ev. lage filen hvis den ikke eksisterer) En “.wav” inneholder 44 bit som er info om lydfilen. (Samplefrekvenes o.l, som egentlig også burde vært lest). For å lese selve taledataene flyttes “posisjonen” til filpekeren med funksjonen fseek. Dataene I en wav-fil er normalt int16 (16 bits int), dvs. en short i C (2 byte). Funksjonen fread tar inn en adresse/peker (&value), og leser N (i dette tilfellet 1) * size (sizeof(short)) fra filen definert med filpekeren f. fclose lukker filen og sletter filpekeren.

  27. Casting i C Noen ganger ønsker man en variabel av en bestemt type (x bytes), og så tilordne denne til en variabel av en annen datatype (y bytes). Dette kalles “(type)casting”. #include <stdio.h> #include <math.h> int main() { char c; int i; float f; c = 'a'; i = c; f = i; printf("c = %d (%c)\n",c,c); printf("i = %d (%c)\n",i,i); printf("f = %f\n", f); double x=56.8890 int y,y2; y=(int) x; Y2=(int) round(x); printf(”x = %lf\n", x); printf(”y = %d\n", y); printf(”y2 = %d\n", y); int *p; int q=5; q=p; //kompilator gir warning q=(int) p; //ingen warning } Enkle eksempler er å gjøre en char om til en int, og en int om til en float. Dette kan gjøres bare med vanlig tilordning i C. Både i=c og f=i er en ”typecast”-operasjon. Casting gjøres ved å skrive den nye typen i parantes foran variabelnavnet. En casting fra double/float til int gjør at verdien bli rundet av nedover. (kutter desimalene) Selv om c gjør noen “typecasts” automatisk, er det en god regel å “caste” hvis vi er i tvil,som er en måte å si til kompilatoren at vi (tror vi) vet hva vi holder på med.

  28. Strenger i C En string i C er definert som en nullterminert array av char, det vil si en array av typen char med en “0”-char til slutt for å definere slutten på strengen #include <stdio.h> #include <string.h> int main(int argc,char **argv){ FILE *fp; char id[5]; fp = fopen("h000001.wav","rb"); fread(id, sizeof(char), 4, fp); id[4]=’\0’; //id[4]=0x00; id[4]=0; if (strcmp(id, "RIFF")){ printf(“Dette er en Wavfil”) /* Noen flere strenger */ const char* navn1=”Hans”; char navn2[10]={’H’,’a’,’n’,’s’,’\0’} navn2=”Petter”; /* Ikke mulig!’/ navn2[4]=’a’; navn2[5]=’\0’; printf(”%s\n”,navn2); } De 4 første bytene i et en wav-fil, er av typen char og inneholder tegnene: RIFF. Hvis vi ønsker å lese inn de 4 første bytene og lagre dem i en streng trenger vi en tabell av størrels 5, i og med at vi må ha en ”nullbyte” til slutt! Det er flere måter å definere en streng på I C. Men obs! Forskjell på initsialiserig av en streng og tilordning, En streng må håndteres som en array av char..!

  29. Strukturer struct: En måte å sette sammen eksisterende typer til en struktur. Pakking? structen timeval er definert i denne h-filen. #include <sys/time.h> /* declare the struct */ struct my_struct { int counter; float average; struct timeval timestamp; uint in_use:1; uint8_t data[0]; }; /* define an instance of my_struct */ struct my_struct x = { in_use: 1, timestamp: { tv_sec: 200 } }; x.counter = 1; x.average = sum / (float)(x.counter); struct my_struct * ptr = &x; ptr->counter = 2; (*ptr).counter = 3; /* equiv. */ En struct definerer en struktur med fields En struct kan inneholde andre structer Fields kan spesifisere spesifikke bit-størrelser. A ny-definert struct initialiseres med klammeparanteser. Alle felt som ikke blir satt, blir satt til 0 Fields blir aksessert med ‘.’ notasjon. En peker til en struct. Felter blir aksessert med ‘->’ notasjon, eller (*ptr).counter

  30. Input fra kommandolinja main-funksjonen tar inn to variable fra kommandolinja ved definsjon, argc er antall strenger som er blitt skrevet, mens char ** argv er en peker til streng, og kan ses på som en tabell av strenger. ”argv” inneholder alle strenger som er blitt skrevet på kommandolinja, inkludert program- navnet(argv[0]) #include < stdio.h> #include < stdlib.h> int main(int argc, char** argv) /*f.eks c:\ cmdline -a 2 -b 3.0 kjører programmet cmdline*/ /* main vil motta argc=7 argv[0]=cmdline argv[1]=-a argv[2]=2 argv[3]=-b argv[4]=3.0 */ /* Start at i = 1 to skip the cmd name.*/ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') {//check next char switch (argv[i][1]) { case 'a': a_value=atoi(argv[++i]);break; case 'b': b_value=atof(argv[++i]);break; default: fprintf(stderr, "Unknown switch %s\n", argv[i]); } } } En vanlig konvensjon for input-parametre, er å angi en input med en ”switch” som vil si en ”-” og så et navn for opsjonen. Deretter kommer verdien som ønskes som input til programmet. Å navngi input-opsjonene er bra for at programmet skal kunne håndtere input-verdiene på en robust måte, samtidig som det er brukervennlig. Funksjonene atoi og atof er definert i stdlib.h og konverterer en streng til hhv. int og double

  31. Makroer Makroer blir utført av preprosessoren i kompilatoren, som ekspanderer koden ved å sette inn de definerte makroene. Makroer er en måte å gjøre koden lettere å lese gjør koden lettere å lese, men hvis mulig: bruk heller en static inline funksjon. Makroer og static inline funksjoner må inkluders i en hver fil som bruker dem, som regel ved en header-fil. Vanlig bruk for makroer: /* Makroer brukes for å definere kontsanter */ #define FUDGE_FACTOR 45.6 #define MSEC_PER_SEC 1000 #define INPUT_FILENAME “my_input_file” /* Makroer brukes for å gjøre aritmetikk med konstanter */ #define TIMER_VAL (2*MSEC_PER_SEC) /* Makroer brukes for å hente informasjon fra kompilatoren */ #define DBG(args...) \ do { \ fprintf(stderr, “%s:%s:%d: “, \ __FUNCTION__, __FILE__, __LINENO__); \ fprintf(stderr, args...); \ } while (0) /* ex. DBG(“error: %d”, errno); */ Float konstanter må ha et komma, ellers er de av typen int Sett beregningene i parentes. Hvorfor? Makroer over flere linjer må deles opp med \ Sett makroer over flere linje i do{}while(0)

  32. Typedef og noen ”Modifiers” • Det er mulig å definere egne typer ved å bruke typedef • Nye typer kan være helt nye typer som f.eks en struct, eller de kan være en alias for en annen standard type. • Det er regnet som god praksis å bruke store bokstaver for en ny type definert med typedef: f.eks: typedef char* STRING; • ”Auto” og ”Static”: Ved default blir en variabel i en funksjon definert som auto. C genererer autovariable når funksjonen blir kalt, og sletter dem igjen når funksjonen har returnert. • Hvis man ønsker at en variabel definert i en funksjon ikke skal bli slettet, må den defineres som static. Dette må brukes hvis f.eks funksjonen returnerer en peker til en variabel definert inne i funksjonen. • Variable som blir deklarert utenfor en funksjon blir definert som static ved default. • En funksjon som defineres som static betyr noe helt annet. En static funksjon kan bare kalles i den filen hvor den er definert. • En variabel definert som const, betyr at den ikke kan brukes på venstre-siden i en tilordning.

  33. Enkel Makefile Gitt et system med to c-filer og en header fil: hellomake.c, hellofunc.c og hellofunc.h #include “c:/cpath/hellofunc.h" int main() { //Kall en funksjon fra en annen fil myPrintHelloMake(); return(0); } Program som kaller en funksjon fra c-filen hellofunc. Dette systemet kan enkelt kompileres med: gcc hellomake.c hellofunc.c –o hellomake En makefil er en fil som inneholder regler for hvordan systemet skal kompileres. Et program, som heter make, leser filen med navn “makefile” (default),og utfører de kompilerings-reglene som er definert i makefilen. Det vil si at hvis du har laget en makefil, kan du kompilere ved å kjøre make! Den enkleste makefilen som kan lages for dette systemet er: hellomake: hellomake.c hellofunc.c gcc hellomake.c hellofunc.c –o hellomake –I . Den første linjen inneholder alle filer programmet er avhengig av. Dette bruker make til bare å kompilere de filer som er endret siden sist. NB: make krever en tab før hver linje som den skal utføre.

  34. Forts. Makefile En litt mer kompilsert makefil: CC=gcc CFLAGS=-I. hellomake: hellomake.o hellofunc.o $(CC) -o hellomake hellomake.o hellofunc.o $(CFLAGS) Nå er kompilatoren og flaggene definert som makroer (konstanter). Ved å sette kompilatoren til å være avhengig av o-filene, så vet make at den må kompilere c-filene først, og så lenke filene etterpå. Denne typen makefil er bra nok for et lite prosjekt, men en ting mangler…, avhengigheten til h-filen! CC=gcc CFLAGS=-I . DEPS = hellomake.h %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: hellomake.o hellofunc.o gcc -o hellomake hellomake.o hellofunc.o -I. Makroen ($deps) inneholder all h-filene som c-filene avhenger av. Så lager vi en regel som sier at o-filene avhenger av c-filene og h-filene i $(deps), og at make skal generere o-filene som make trenger for å kompilere c-filene. –c flagget i gcc betyr kompiler men ikke link, –o $@ betyr alle filene til venstre for :, og $< betyr den første filen i avh.-listen.

  35. Funksjonen malloc(N) allokerer minne for N bytes NB! Minne som allokeres dynamisk må senere frigjøres med funksjonen free() calloc(N,k) allokerer minne for N elementer av en størrelse k. Dynamsk Minne-allokering Så langt har alle eksemplene allokert variable statisk ved å definere dem i programmet. Men hva om vi ønsker å allokere variable basert på dynamiske hendelser/input mens programmet kjøres? Dette krever dynamisk allokering.

  36. Ved allokering av dynamisk minne, må man planlegge hvordan minnet senere skal bli frigjort. Allokert minne som man mister “kontakt” med kalles “memory leak”, og betyr at programmet “spiser” minne. Garbage collection Det er lett å glemme en peker til dynamisk minne som har blitt frigjort. Når man frigjør dynamisk minne, er det sikrest å slette alle pekere til det. Fordi dynamiske minne alltid bruker pekere, er det ingen måte for kompilatoren å sjekke at bruken av minnet er riktig, dette betyr at feil som kan detekteres med statisk allokering, ikke kan oppdages med dynamisk allokering. Fallgruver med dynamisk minne

More Related