De presentatie wordt gedownload. Even geduld aub

De presentatie wordt gedownload. Even geduld aub

P. 1 Deel I: Programmeertaal C 6. Arrays en Pointers Prof.Dr.Ir. Filip De Turck.

Verwante presentaties


Presentatie over: "P. 1 Deel I: Programmeertaal C 6. Arrays en Pointers Prof.Dr.Ir. Filip De Turck."— Transcript van de presentatie:

1 p. 1 Deel I: Programmeertaal C 6. Arrays en Pointers Prof.Dr.Ir. Filip De Turck

2 p. 2 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

3 p. 3 Vakgroep Informatietechnologie 1. Arrays: basisconcepten Array = reeks van variabelen van ZELFDE type (een array/rij is homogeen) Declaratie type naam[constante_gehele_uitdrukking]; double neerslag[12]; long postnummer[100]; Gebruik naam[gehele_uitdrukking];  kan overal gebruikt worden waar gewone variabele van zelfde type toegelaten is  0  index < constante_gehele_uitdrukking  [ ] is een C-operator ! (zie boek Appendix E) #define MAANDEN12 … double neerslag[MAANDEN];

4 p. 4 Vakgroep Informatietechnologie 1. Arrays: basisconcepten (2) Initialisatie type naam[constante_gehele_uitdrukking opt ] = { constante_uitdrukking {, constante_uitdrukking} 0+ }; double neerslag[12] = {20.7,23.0,99.0,77.4};  geen automatische initialisatie !  indien bereik niet opgegeven -> compiler vult zelf aantal elementen in int a[4]={1,2,3,4}; ≈ int a[ ] = {1,2,3,4};  karakter - rijen char a[ ] = “Een tekst”; char a[ ] = {‘E’,’e’,’n’,’ ‘,’t’,’e’,’k’,’s’,’t’,’\0’}; elementen 4 … 11 geïnitialiseerd op 0

5 p. 5 Vakgroep Informatietechnologie 1. Arrays: C-idioom voor toegang & behandeling #defineN100 … int a[N]; int i; … for(i=0; i

6 p. 6 Vakgroep Informatietechnologie 1. Arrays: functie-argumenten Formele parameter type naam[ ] Prototype parameter type [ ] /* berekensom.c */ #include int bereken_som(int[ ],int); int main(void) { int a[ ]={1,2,3,4,5}; printf("Som = %d\n",bereken_som(a,5)); return 0; } int bereken_som(int a[ ],int n) { int som=0; int i; for(i=0;i

7 p. 7 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

8 p. 8 Vakgroep Informatietechnologie 2. Pointers: basisconcepten Een pointer (wijzer) is een variabele die een ADRES bevat Voorbeeld int a=7; int* p; p=&a; a p ????1000  Elk type heeft een geassocieerd wijzertype, namelijk type*  Conversie-karakter (hexadecimale voorstelling): p printf(“Wijzer = %p”,p);

9 p. 9 Vakgroep Informatietechnologie 2. Pointers: operatoren Adresoperator: & Dereferentie-operator: *  unaire operatoren  precedentie identiek voor alle unaire operatoren  associatie: R -> L : **&p *(*(&p)) Voorbeeld int a=7; int* p= NULL; int b; p=&a; a=9; *p=12; b = *p; 7a 0p 9 b???12 ENKEL op lvalue 0xFF00

10 p. 10 Vakgroep Informatietechnologie 2. Pointers: operatoren (2) Relationele operatoren >= Interpretatie : vergelijken van numerieke adressen if(p < q) printf("p points to lower memory than q");

11 p. 11 Vakgroep Informatietechnologie 2. Pointers: voorbeeld /* wijzer.c */ #include #define N5 int main(void) { int a[N]={0}; int* p=0; int i; for(i=0;i

12 p. 12 Vakgroep Informatietechnologie 2. Pointers: bewerkingen dereferentie adresbepaling optelling en aftrekking int a=7; int* p=&a; *pointer &pointer “pointer arithmetic” printf(“a= %d”,*p); int** q = &p; printf(“p= %p, a= %d”,*q,**q); void* kan niet gedefereerd worden !

13 p. 13 Vakgroep Informatietechnologie 2. Pointers: bewerkingen (2) assignatie pointer = pointer_uitdrukking; p=&a; p=(int*)127888; CAVEAT  “traditional C”: assignatie tussen verschillende wijzertypes mogelijk  ANSI C: assignatie MOET tussen zelfde wijzertypes UITZONDERING: void* int *i; double *d; i=d; int *i; double *d; void* v; i=d; i=v=d; void* GENERIEK POINTERTYPE

14 p. 14 Vakgroep Informatietechnologie 2. Pointers: arithmetiek Rekenkundige bewerkingen op pointers + en - (en variaties) met gehele getallen ! int* p=(int*)1000; p++; p--; p+=2; p-=4; effect hangt af van lengte (sizeof) van het type ! 1000+sizeof(int) 1000-sizeof(int) *sizeof(int) *sizeof(int)

15 p. 15 Vakgroep Informatietechnologie 2. Pointers: arrays vs pointers int a[3]={1,2,3}; int *b=a; a b  a en b bevatten adres  a is CONSTANT, b niet a++b++  element i van de rij ? a[i] *(a+i) *(b+i)

16 p. 16 Vakgroep Informatietechnologie 2. Pointers: arrays vs pointers voorbeeld /* verschil.c */ #include int main(void) { float a[]={1.0,2.0,3.0,4.0,5.0}; float*start,*eind; int i=0; start=a; eind=&a[4]; for(i=0;i<5;i++) printf("a[%d]=%f\n",i,*(start+i)); printf("eind - start = %d\n",eind-start); printf("(int)eind-(int)start = %d\n",(int)eind-(int)start); return 0; }

17 p. 17 Vakgroep Informatietechnologie 2. Pointers: p ointers en arrays Is volgend programma OK ? #include #define SIZE 10 int main(void) { int a[SIZE]; int *p; for(p=&a[0];p<&a[SIZE];) *++p=0; }

18 p. 18 Vakgroep Informatietechnologie Oefening: array & pointer definities int a; int *a; int **a; int a[10]; int *a[10]; int (*a)[10];

19 p. 19 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

20 p. 20 Vakgroep Informatietechnologie 3. Call by reference NIET Waarde doorgeven wijzigt waarde uit oproepende context NIET. Algemene aanpak:  Geef de adressen van variabelen door  De formele parameters zijn van wijzertype  Gebruik dereferentie van parameters om waarde van variabelen uit oproepende context te wijzigen... char a; opvolger(a);... void opvolger(char a) { a++ ; } … char a; opvolger(&a);... void opvolger( char* a ) { (*a )++; }

21 p. 21 Vakgroep Informatietechnologie 3. Call by reference: wisselen /* wisselnaief.c */ #include void wissel(int,int); int main(void) { int a=1,b=2; printf("a=%d b=%d\n",a,b); wissel(a,b); printf("a=%d b=%d\n",a,b); return 0; } void wissel(int a,int b) { int t=a; a=b; b=t; }

22 p. 22 Vakgroep Informatietechnologie 3. Call by reference: wisselen (2) /* wisselints.c */ #include void wissel( int*,int * ); int main(void) { int a=1,b=2; printf("a=%d b=%d\n",a,b); wissel(&a,&b); printf("a=%d b=%d\n",a,b); return 0; } void wissel(int *a,int *b) { int t=*a; *a=*b; *b=t; }

23 p. 23 Vakgroep Informatietechnologie ANSI C Sleutelwoorden CategoryKeyword Data Types char int float double void Data Type Modifiers long short signed unsigned Storage Class Specifiers auto extern register static Access Type Modifiers const volatile

24 p. 24 Vakgroep Informatietechnologie const toegepast op variabele: verhindert wijziging ! const int i=7; i=12; const int i; i=12; initialisatie verplicht ! int main(void) { const int i=7; int* p=&i; *p=12; printf("i=%d\n",i); return 0; } Warning

25 p. 25 Vakgroep Informatietechnologie const int main(void) { const int i=7; const int* p=&i; *p=12; printf("i=%d\n",i); return 0; } ERROR const int *p; int* const p; *p constant p constant

26 p. 26 Vakgroep Informatietechnologie const In functieprototype verhindert (onopzettelijke) wijziging van call-by-reference argumenten #include void opvolger(const char*); int main(void) { char a='a'; printf("a=%c\n",a); opvolger(&a); printf("a=%c\n",a); return 0; } void opvolger(const char*a) { (*a)++; } “ERROR : const object”

27 p. 27 Vakgroep Informatietechnologie Oefening: const data definities const int a; int const a; const int *a; int * const a;

28 p. 28 Vakgroep Informatietechnologie volatile  Voorbeelden  Hardware registers: vb.: 8 bit status register op adres 0xFF00 char volatile * reg_ptr = (char volatile *) 0xFF00 ; while (*reg_ptr == 0);...  Variabelen die vanuit een interrupt service routine gewijzigd worden  Gedeelde variabelen in een multitasking applicatie De variabele kan onverwacht van waarde veranderen.

29 p. 29 Vakgroep Informatietechnologie Oefening: volatile  Kan een parameter zowel const als volatile zijn ?  Kan een pointer volatile zijn ?  Wat is het probleem met volgende functie: int square (volatile int * ptr) { return *ptr * *ptr; }

30 p. 30 Vakgroep Informatietechnologie 1D-rijen als functie-argument  adres wordt meegegeven als argument  in parameterlijst zijn rij- en pointernotatie equivalent  verhinderen dat rij gewijzigd wordt -> gebruik const int grootste(int*,int);... int grootste(int a[ ],int n) { int i=0; int m=*a++; for(i=1;im) ? *(a-1):m; return m; } int grootste(int*,int);... int grootste(int* a,int n) { int i=0; int m=*a++; for(i=1;im) ? *(a-1):m; return m; }

31 p. 31 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

32 p. 32 Vakgroep Informatietechnologie 4. Dynamisch geheugenbeheer : functies in stdlib.h Geheugen toewijzen tijdens uitvoering van programma malloc(aantal_bytes) calloc(aantal,aantal_bytes)  Argumenten: type size_t (unsigned int)  Resultaat: type void* (gebruik cast !) NULL indien mislukt !  Prototypes in stdlib.h  malloc versus calloc ? calloc() initialiseert geheugen  maak code systeemonafhankelijk ! malloc(n*N)  calloc(n,N) malloc(n*sizeof(double)) Toewijzen

33 p. 33 Vakgroep Informatietechnologie 4. Dynamisch geheugenbeheer : functies in stdlib.h free(toegewezen_pointer)  fout indien  argument al vrijgegeven  argument geen toegewezen pointer  geheugenlekken moeilijk op te sporen ! Vrijgeven Hergebruik realloc(toegewezen_pointer,aantal_bytes)  poogt geheugenblok te hergebruiken voor aantal_bytes  inhoud begin van blok blijft behouden  resultaat: cf. malloc/calloc

34 p. 34 Vakgroep Informatietechnologie 4. Dynamisch geheugenbeheer : fouten en problemen  Dangling Pointer: free()  Pointer nog gebruiken na een free()  vb. meerdere pointers wijzen naar hetzelfde blok  Memory Leak : free()  geen pointers meer naar het geheugen maar ook geen free()  Memory Fragmentatie:  na veelvuldig alloceren en dealloceren kunnen bepaalde kleine stukjes geheugen niet meer gebruikt worden omdat ze te klein zijn Geen probleem in Java: garbage collection

35 p. 35 Vakgroep Informatietechnologie 4. Dynamisch geheugenbeheer: wisselen (GENERIEK) /* wisselgeneriek */ #include void wissel(void*,void*,int); int main(void) { int a=1,b=2; double c=3.14,d= ; printf("a=%d b=%d\n",a,b); wissel(&a,&b,sizeof(a)); printf("a=%d b=%d\n",a,b); printf("c=%f d=%f\n",c,d); wissel(&c,&d,sizeof(c)); printf("c=%f d=%f\n",c,d); return 0; } void wissel(void *a,void *b,int n){ void* temp= malloc(n); memcpy(temp,a,n); memcpy(a,b,n); memcpy(b,temp,n); free(temp); }

36 p. 36 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

37 p. 37 Vakgroep Informatietechnologie 5. Strings in C  1D-rij van char’s  Start van de string = wijzeruitdrukking  Eind van de string : karakter ‘\0’ (sentinel !) ASCII-conventie #defineEOS‘\0’  Geheugenruimte = (aantal_karakters+ 1 )*sizeof(char)  Constanten - tussen: “ “ - compiler voegt zelf ‘\0’ toe  Conversiekarakter: s EOS char *t=“een tekst”; printf(“t bevat = %s”,t);

38 p. 38 Vakgroep Informatietechnologie 5. Strings: string vs char[] char* s= “abc”; char a[ ] = {‘a’,’b’,’c’,’\0’}; a a b c \0 s a b c #include int main(void) { char a[ ]={'a','b','c','\0'}; char *s="abc"; printf("%c %c\n",a[0],s[0]); printf("%c %c\n",*(a+1),*(s+1)); /* a+=2; niet toegelaten !*/ s+=2; printf("%c %c\n",*(a+2),*s); return 0; }

39 p. 39 Vakgroep Informatietechnologie 5. Strings: string functies concatenatie char *strcat(char *s1, const char *s2); vergelijken int strcmp(const char *s1,const char *s2); kopiëren char *strcpy(char *s1,const char *s2); lengte bepalen size_t strlen(const char *s);/* exclusief EOS */ Klassieke stringbewerkingen (prototypes in string.h ) Deze functies alloceren GEEN geheugen !!! De gebruiker moet zorgen voor voldoende ruimte.

40 p. 40 Vakgroep Informatietechnologie 5. Strings: string functies invoer int sscanf(const char* s, const char* ctrl, …); uitvoer int sprintf(char *s, const char* ctrl, …); Geformatteerde I/O van/naar string (prototypes in stdio.h ) allocatie van s niet binnen sscanf/sprintf !!!

41 p. 41 Vakgroep Informatietechnologie 5. Strings: vergelijken van strings /* compare.c */ #include int my_strcmp(const char*,const char*); int main(void) { printf("gelijk = %d\n",my_strcmp("abcd","abcd")); printf("niet gelijk = %d\n",my_strcmp("abcd","abcD")); return 0; } int my_strcmp(const char* s1,const char*s2) { int gelijk=1; if (strlen(s1)!=strlen(s2)) return 0; else while(*s1) if((*s1++)!=(*s2++)) return 0; return 1; }

42 p. 42 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

43 p. 43 Vakgroep Informatietechnologie 6. Meerdimensionale rijen algemeen principe : meerdimensionele rij = rij van rijen elementen worden NA elkaar opgeslagen in geheugen 2D rijen declaratie 3D rijen type naam[P][Q];type naam[P][Q][R]; initialisatie type naam[P][Q]={a 00,…,a 0Q-1,a 10,…}; type naam[P][Q]={{a 00,…a 0Q-1 },{a 10 …},…}; type naam[ ] [Q]={{a 00,…a 0Q-1 },{a 10 …},…}; type naam[P][Q][R]={a 000,…,a 00R-1,a 010,…}; type naam[P][Q][R]={{{a 000,…a 00R-1 },{a 010 …}},…}; type naam[ ] [Q][R]={{{a 000,…a 00R-1 },{a 010 …}},…}; ontbrekende -> op 0 geplaatst

44 p. 44 Vakgroep Informatietechnologie 6. Meerdimensionale rijen 2D rij: a[P][Q] Elementtoegang 3D rij: a[P][Q][R] naam[i][j] *(naam[i]+j) *((*(naam+i))+j) *(naam+Q*i+j) naam[i][j][k] *(naam[i][j]+k) *(naam+(Q*R)*i+R*j+k) “storage mapping function”

45 p. 45 Vakgroep Informatietechnologie 6. Meerdimensionale rijen als functieparameters 2D rijen formele parameter 3D rijen type naam [P][Q] type naam [ ][Q] “storage mapping function” moet gekend zijn (voor statische rijen) ! type naam [P][Q][R] type naam [ ][Q][R] schaadt de algemeenheid van de functie ! gebruik dynamisch gealloceerde rijen !

46 p. 46 Vakgroep Informatietechnologie 6. Meerdimensionale rijen: wijzerrijen a char* a[4]={“abc”,”def”,”ghi”,”jkl”} ‘a’‘b’‘c’ ‘d’‘e’‘f’ ‘g’‘h’‘i' ‘j’‘k’‘l’ a[0] a[1] a[2] a[3] uitdrukkingwaarde *(a[0])‘a’ *(a[1]+2)‘f’ a[2][2]‘i' a[2]=a[0]; a[2][2]‘c’ a[2][2]=‘q’; a[0][2]‘q’ ‘\0’ ‘q’

47 p. 47 Vakgroep Informatietechnologie 6. Voorbeeld: array van pointers void signal_runtime_error (int num){ static char *error[] = { "Ethernet chip not initialised. \n", "Device not ready. \n", "Input Buffer overflow detected. \n", "Transmission problem.\n" }; printf(”SYSTEM> %s.\n",error[num]); }

48 p. 48 Vakgroep Informatietechnologie 6. Meerdimensionale rijen : programma-argumenten /* argumenten.c */ #include int main(int argc,char* argv[ ]) { int i=0; printf("Programma-argumenten : \n"); for(i=0;i

49 p. 49 Vakgroep Informatietechnologie 6. Meerdimensionale rijen: dynamische rijen a 1D-rijen a[0] a[1] a[2] a[3] a[4] int* int #defineP5... int* a; … a=(int*)calloc(P,sizeof(int));... allocatievernietiging … free(a);...

50 p. 50 Vakgroep Informatietechnologie 6. Dynamische rijen (2) a #defineP5 #defineQ2... int** a; int i; … a=(int**)calloc(P,sizeof(int*)); for(i=0;i

51 p. 51 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

52 p. 52 Vakgroep Informatietechnologie 7. Functie-argumenten Functie als argument van andere functie Functie wijzer: type naam(proto_lijst) type (*naam)(proto_lijst) Interpretatie naam  wijzer naar functie *naam  functie zelf (*naam)(actuele_lijst)  functie-oproep  dereferentie gebeurt automatisch in functie zelf  dus : *naam(actuele_lijst) equivalent met naam(actuele_lijst)

53 p. 53 Vakgroep Informatietechnologie 7. Functie-argumenten: gebruik voor UNIT testen. void signal_runtime_error ( int ); void signal_memory_error ( int) ;... int i =0; void (*f_ptr)(int); f_ptr= signal_runtime_error ; for(i=0;i<4;i++) f_ptr(i); f_ptr= signal_memory_error ; for(i=0;i<4;i++) f_ptr(i);

54 p. 54 Vakgroep Informatietechnologie 7. Functie-argumenten oefening: generatie van tabel /* functiewijzer.c */ #include double kwadraat(double); void tabuleer(double f(double),double,double,double); int main(void) { printf("Tabel van sin(x)\n"); tabuleer(sin,0.0,1.57,0.2); printf("Tabel van x*x\n"); tabuleer(kwadraat,0.0,1.0,0.2); return 0; } void tabuleer(double f(double),double s,double e,double stap) { double x; printf(" \n"); for(x=s;x %f\n",x,f(x)); printf(" \n"); } double kwadraat(double x) { return x*x; }

55 p. 55 Vakgroep Informatietechnologie 7. Intermezzo: typedef  Legt verband tussen type en naam  Declareert een naam alsof het een variabele van het type in kwestie was, voorafgegaan door typedef  Een type kan vervangen worden door naam  Dikwijls gedefinieerd in header file Voorbeelden typedefint geheel; typedefint* gehele_wijzer; typedefint (*f)(int,int); typedefdouble (*g)(double); typedefsize_tunsigned;

56 p. 56 Vakgroep Informatietechnologie 7. Functie-argumenten: rijen van functiewijzers Rijen van functie-wijzers typedef functie_type_definitie; functietype naam[bereik]; Voorbeeld typedef int (*discretef)(int,int); discretef f[10];

57 p. 57 Vakgroep Informatietechnologie Generatie van tabel /* functierij.c */ #include double kwadraat(double); void tabuleer(double f(double),double,double,double); typedef double (*realf)(double); int main(void) { realf f[2]={sin,kwadraat}; int i; for(i=0;i<2;i++) tabuleer(f[i],0.0,1.0,0.2); return 0; } void tabuleer(double f(double),double s,double e,double stap) { double x; printf(" \n"); for(x=s;x %f\n",x,f(x)); printf(" \n"); } double kwadraat(double x) { return x*x; }

58 p. 58 Vakgroep Informatietechnologie Overzicht 1. Arrays (rijen) in 1 dimensie 2. Pointers (wijzers) 3. Call by reference 4. Dynamisch geheugenbeheer 5. Strings 6. Multidimensionele arrays 7. Functie-argumenten 8. Structs revisited

59 p. 59 Vakgroep Informatietechnologie 8. Toekenning van strings typedef struct{ char naam[30]; short leeftijd; char code; } persoon;... persoon p1,p2;... p1 p1.naam p1.leeftijd p1.code p2 p1.naam p1.leeftijd p1.code p1.naam[0] p1.naam[29] p1.naam en p2.naam zijn beide STATISCHE rijen: geheugen wordt gealloceerd tijdens creatie van p1 en p2

60 p. 60 Vakgroep Informatietechnologie struct* typedef struct{ char naam[30]; short leeftijd; char code; } persoon;... persoon p; persoon* w; w=&p;... p p.naam p.leeftijd p.code w toegang tot gegevens p.naam p.leeftijd p.code (*w).naam (*w).leeftijd (*w).code w->naam w->leeftijd w->code (*struct_wijzer).veldnaam struct_wijzer->veldnaam p.naam[1](*w).naam[1]w->naam[1] 8. Structs & pointers

61 p. 61 Vakgroep Informatietechnologie 8. Structs: initialisatie  Cfr. syntax voor het initialiseren van een rij  schrijf initialisatie-uitdrukkingen voor elk veld tussen { }  bij expliciete initialisatie: alle niet gespecificeerde velden worden op 0 geplaatst Voorbeelden persoon p={“Jan Janssen”,30,’A’}; persoon q={“Piet Janssen”}; persoon r[5]={{“Mario Puzo”,55,’P’},{“Don Corleone”}}; persoon n[10]={0};/* alles 0 ! */

62 p. 62 Vakgroep Informatietechnologie 8. Structs: wijzervelden #define NAAML30 typedef struct{ char naam[NAAML]; short leeftijd; char code; } persoon1; #define NAAML30 typedef struct{ char *naam; short leeftijd; char code; } persoon2; sizeof(persoon1)  34 sizeof(persoon2)  8 reserveert GEEN geheugen voor inhoud van naam ! reserveert WEL geheugen voor inhoud van naam !

63 p. 63 Vakgroep Informatietechnologie 8. Structs: wijzervelden (2) persoon1 p1={0}; persoon2 p2={0}; p1 p1.naam p1.leeftijd p1.code \0 0 p2 p2.naam p2.leeftijd p2.code 0 \0 NULL p2.naam  Dynamisch te alloceren rij  Type persoon 2 vergt functies voor allocatie en vernietiging

64 p. 64 Vakgroep Informatietechnologie 8. Structs: initialisatie P2 type typedef struct{ char *naam; short leeftijd; char code; } persoon2; void init_persoon2(persoon2*); void free_persoon2(persoon2); int main(void) { persoon2 p2={0}; init_persoon2(&p2); free_persoon2(p2); return 0; } void init_persoon2(persoon2* p) { if(p->naam != NULL) free_persoon2(*p); p->naam=(char*)calloc(NAAML,sizeof(char)); if (p->naam != NULL) p->naam[0]='\0'; } void free_persoon2(persoon2 p) { if (p.naam !=NULL) free(p.naam); } p2 p2.naam p2.leeftijd p2.code 0 \0 NULL \0

65 p. 65 Vakgroep Informatietechnologie 8. Structs: soorten kopieën persoon1 a={“Jan Jansen”,30,’A’}; persoon1 b={0}; b=a; a a.naam a.leeftijd a.code J an\0 30 A b b.naam b.leeftijd b.code \0 0 J an 30 A persoon2 a={“Jan Jansen”,30,’A’}; persoon2 b={0}; b=a; geen init_persoon2 nodig ! b b.naam b.leeftijd b.code 0 \0 NULL a a.naam a.leeftijd a.code 30 A J an\0 30 A ONDIEPE KOPIE DIEPE KOPIE

66 p. 66 Vakgroep Informatietechnologie 8.Structs: soorten kopieën (2) int main(void) { persoon2 a={0}; persoon2 b={0}; init_persoon2(&a,"Jan Jansen",30,'A'); init_persoon2(&b,"Piet Verlinden",35,'B'); print_persoon2(a);print_persoon2(b); b=a;b.code='N'; wijzig_naam(&b,”Mario Puzo"); print_persoon2(a);print_persoon2(b); free_persoon2(a);free_persoon2(b); return 0; } --- void print_persoon2(persoon2 p) { printf("Naam = %s\n",p.naam); printf("Leeftijd = %d\n",p.leeftijd); printf("Code = %c\n",p.code); } void wijzig_naam(persoon2* p,const char* n) { p->naam=(char*)realloc(p->naam, strlen(n)*sizeof(char)); strcpy(p->naam,n); }

67 p. 67 Vakgroep Informatietechnologie 8. Diepe kopie (deep copy) Schrijf een functie die een diepe kopie maakt van een variabele van het type persoon2.

68 p. 68 Vakgroep Informatietechnologie 8. Diepe kopie: oplossing void deep_copy ( persoon2 * toPersoon, const persoon2 * fromPersoon) { int naamlengte =0 ; naamlengte = strlen(fromPersoon->name); toPersoon->name=(char*)calloc(++naamlengte,sizeof(char)); toPersoon->name=strcpy(toPersoon->name, fromPersoon->name); toPersoon->leeftijd=fromPersoon->leeftijd; toPersoon->code=fromPersoon->code; };

69 p. 69 Vakgroep Informatietechnologie 8. Structs: structs en functies Als argument  Wordt behandeld als elk ander type (pass-by-value)  Er wordt een ONDIEPE kopie genomen (shallow copy) (dynamisch gealloceerde variabelen worden niet automatisch in een nieuwe geheugenruimte gekopieerd !) Als resultaat  Wordt behandeld als elk ander type (m.a.w. rijen van structs niet als resultaat toegelaten! wel struct*)

70 p. 70 Vakgroep Informatietechnologie 8. Structs: structs en functies vb #include #define PRINT2(x) (printf("el1=%d, el2=%d\n",x[0],x[1])) void wissel(int[ ]); void wissel_rij2(rij2); typedef struct { int r[2]; } rij2; int main(void) { int a[ ]={1,2}; rij2 b={{1,2}}; PRINT2(a); wissel(a); PRINT2(a); PRINT2(b.r); wissel_rij2(b); PRINT2(b.r); wissel(b.r); PRINT2(b.r); return 0; } void wissel(int a[ ]) { int t; t=a[0]; a[0]=a[1]; a[1]=t; } void wissel_rij2(rij2 s) { int t; t=s.r[0]; s.r[0]=s.r[1]; s.r[1]=t; }

71 p. 71 Vakgroep Informatietechnologie 8. Structs: geneste structuren typedef struct { char*voor; char*fam; } naam; typedef struct { naam n; int leeftijd; char code; } persoon; persoon p; persoon *q; naam* r; … q=&p; r=&(p.n); printf(“Voornaam = %s”,p.n.voor); p.n.voor (*r).voor r->voor (*q).n.voor (q->n).voor


Download ppt "P. 1 Deel I: Programmeertaal C 6. Arrays en Pointers Prof.Dr.Ir. Filip De Turck."

Verwante presentaties


Ads door Google