Il linguaggio C -...

70
1 Il linguaggio C Puntatori e dintorni

Transcript of Il linguaggio C -...

Page 1: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

1

Il linguaggio C

Puntatori e dintorni

Page 2: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

2

Puntatori : idea di base

• In C è possibile conoscere e denotarel’indirizzo della cella di memoria in cui èmemorizzata una variabile (il puntatore)

• es :int a = 50; /* una var intera */

int * b; /* una var puntatore a interi */

...b = &a; /* assegna a b l’indirizzo dellacella in cui è memorizzata a */

Page 3: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

3

Puntatori : idea di base (2)

• In C è possibile conoscere e denotarel’indirizzo della cella di memoria in cui èmemorizzata una variabile (il puntatore)

• es :int a = 50;

int * b;

…b = &a;

50350

a è memorizzata nella cella 350

...450

Page 4: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

4

Puntatori : idea di base (3)

• nometype *– è il tipo degli indirizzi delle variabili di tiponometype

• es :int a = 50;int * b;

b = &a;

50350

b è memorizzata nella cella 450 (&b)

...450

tipo dei puntatori a intero

Page 5: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

5

Puntatori : idea di base (4)

• Operatore &– denota l’indirizzo della cella di memoria in cui

è memorizzata una variabile (il puntatore)• es :int a = 50;

int * b;

…b = &a;

50350

Dopo questo assegnamento in b è memorizzato l’indirizzo di a

350450

Page 6: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

6

Puntatori : idea di base (5)

• Operatore di dereferenziazione ‘ * ’– è possibile conoscere e/o modificare il

contenuto di una variabile manipolandodirettamente il suo puntatore

• es :int a = 50;

int * b = &a; …

*b = *b + 4;

54350

Dopo questo assegnamento in a è memorizzato il valore 50 + 4

350450

Denota la variabilea indirizzo b

Page 7: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

7

Puntatori : idea di base (6)• NULL

– costante predefinita (in stdio.h) che denotail puntatore nullo

• È possibile definire puntatori per tutti i tipibase e le strutture con (*)– double *a, *b; /* ripetere ‘*’ */– int *a, b, c[4], **d;– struct studente *t1;

• Segnaposto ( %p )– stampa il valore dell’indirizzo in notazione

esadecimale

Page 8: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

8

Aritmetica dei puntatori

• È possibile scrivere espressioni puntatoreusando alcuni degli usuali operatoriaritmetici (+, -, --, ++)– int a[3], *p = &a[0]; ……IN+12

IN+8IN+4IN

a[2]a[1]a[0]

p contiene l’indirizzo IN

Page 9: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

9

Aritmetica dei puntatori (2)

• È possibile scrivere espressioni puntatoreusando alcuni degli usuali operatoriaritmeticiint a[3], *p = &a[0];p = p + 1;

……IN+12IN+8IN+4IN

a[2]a[1]a[0]

p contiene l’indirizzo IN + 4

Page 10: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

10

Aritmetica dei puntatori (3)

• È possibile scrivere espressioni puntatoreusando alcuni degli usuali operatoriaritmeticiint a[3], *p = &a[0];p = p + 1;p--;

……IN+12IN+8IN+4IN

a[2]a[1]a[0]

p contiene l’indirizzo IN

Page 11: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

11

Aritmetica dei puntatori (4)

• È possibile scrivere espressioni puntatoreusando alcuni degli usuali operatoriaritmetici (+, -, --, ++)int a[3], *p = &a[0];p = p + 1;p--;p += 3;

……IN+12IN+8IN+4IN

a[2]a[1]a[0]

p contiene l’indirizzo IN + 12(sizeof(int) == 4…..)

Page 12: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

12

Aritmetica dei puntatori (5)

• È possibile scrivere espressioni puntatoreusando alcuni degli usuali operatoriaritmetici (+, -, --, ++)int a[3],*p = &a[0],*q;p = p + 1;p--;q = p;p += 3;a[0] = p - q;

……IN+12IN+8IN+4IN

a[2]a[1]a[0]

a[0] contiene 3, numero di intmemorizzabili fra p e q

Page 13: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

13

Puntatori e array…

• Il nome di un array è il puntatore (costante)al primo elemento dell’arrayint a[3], *p = &a[0], *q;q = a; ……IN+12

IN+8IN+4IN

a[2]a[1]a[0]

q contiene l’indirizzo INa == IN

Page 14: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

14

Puntatori e array… (2)

• L’operatore [-] è una abbreviazione …int a[3], *p = &a[0], *q, tmp;/* i due stm che seguono sonoequivalenti */

tmp = a[2];tmp = *(a+2);

……a+3a+2a+1a

a[2]a[1]a[0]

Page 15: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

15

Puntatori e array… (3)• L’operatore [–] è una abbreviazione … e

può essere usato con una qualsiasivariabile puntatoreint a[3],*p = a,*q,tmp;tmp = a[2];tmp = p[2];

……a+3a+2a+1a

a[2]a[1]a[0]

Page 16: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

16

Puntatori e array… (4)• I seguenti frammenti di codice sono

equivalentiint a[N], *p = a, *q, tmp;int sum = 0;/* versione 1 */for(i = 0; i < N; i++) sum += a[i];/* versione 2 */for(i = 0; i < N; i++) sum += *(a+i);

Page 17: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

17

Puntatori e array… (5)• I seguenti frammenti di codice sono

equivalenti (segue)int a[N], *p = &a[0], *q, tmp;int sum = 0;/* versione 3 */for(i = 0; i < N; i++) sum += p[i];/* versione 4 */for(p = a; p < (a+N); p++) sum += *p;

Page 18: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

18

Puntatori e array… (6)• Una riflessione sulle stringhe

– le stringhe sono array di caratterichar a[7] = “ciao”;– le stringhe costanti possono essere definite

anche comeconst char * pp = “ciao”;char * pp = “ciao”;

• attenzione! Se a questo punto cercate di modificareun elemento di pp (es. pp[2] = `f`;) avete unerrore a run time

• mentre a[2] = `f`; è completamente corretto

Page 19: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

19

Passaggio di parametri perriferimento

• Tutti i parametri delle funzioni C sonopassati per valore– il loro valore viene copiato sullo stack– ogni modifica al parametro nel corpo della

funzione non modifica l’originale• È possibile realizzare passaggi per

riferimento utilizzando i puntatori– i passaggi per riferimento permettono di

modificare il valore di una variabilenell’ambiente del chiamante

Page 20: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

20

Passaggio di parametri perriferimento (2)

• Esempio : la funzione che scambia fra loro ivalori di due variabili– si potrebbe pensare di programmarla come ...

void scambia (int x, int y){ int tmp;

tmp = x; x = y; y = tmp;}

– e poi chiamare scambia(a,b)

Page 21: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

21

Passaggio di parametri perriferimento (3)

• Esempio : la funzione che scambia fra loro ivalori di due variabili– si potrebbe pensare di programmarla come ...

void scambia (int x, int y){ int tmp;

tmp = x; x = y; y = tmp;}

– non funziona! Perché lo scambio viene fattosulle copie

Page 22: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

22

Passaggio di parametri perriferimento (3.1)

• Esempio : la funzione che scambia fra loro ivalori di due variabili– esempio di chiamata

int a = 4, b = 5;scambia(a,b);

45

45

Framechiamante

&a&b

Framescambia

&x&y

stack

Page 23: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

23

Passaggio di parametri perriferimento (3.2)

• Esempio : la funzione che scambia fra loro ivalori di due variabili– alla fine dell’esecuzione di scambia (prima di

ritornare al chiamante)int a = 4, b = 5;scambia(a,b); 4

5

54

Framechiamante

&a&b

Framescambia

&x&y

Page 24: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

24

Passaggio di parametri perriferimento (3.3)

• Esempio : la funzione che scambia fra loro ivalori di due variabili– al momento di eseguire la printf (il frame di

scambia non è più significativo)int a = 4, b = 5;scambia(a,b);printf(“%d,%d”,a,b);

45

Framechiamante

&a&b

Page 25: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

25

Passaggio di parametri perriferimento (4)

• Esempio : la funzione che scambia fra loro ivalori di due variabili– la versione corretta è ...

void scambia (int *x, int *y){ int tmp;

tmp = *x; *x = *y; *y = tmp;}

– con chiamata scambia(&a,&b)

Page 26: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

26

Passaggio di parametri perriferimento (4.1)

• Versione corretta di scambia ...– esempio di chiamata

int a = 4, b = 5;scambia(&a,&b);

45

&a&b

Framechiamante

&a&b

Framescambia

&x&y

stack

Ogni modifica a *x modificail valore di a nell’ambiente del chiamante

Page 27: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

27

Passaggio di parametri perriferimento (4.2)

• Esempio : versione corretta di scambia ...– alla fine dell’esecuzione di scambia (prima di

ritornare al chiamante)int a = 4, b = 5;scambia(&a,&b);

54

&a&b

Framechiamante

&a&b

Framescambia

&x&y

Page 28: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

28

Passaggio di parametri perriferimento (4.3)

• Esempio : versione corretta di scambia ...– al momento di eseguire la printf (il frame di

scambia non è più significativo)int a = 4, b = 5;scambia(&a,&b);printf(“%d,%d”,a,b);

54

Framechiamante

&a&b

Page 29: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

29

Passaggio di parametri perriferimento (5)

• ATTENZIONE : gli array sono passatisempre per riferimento perché quello che sipassa è il nome dell’array

void assegna (int x[ ]) { x[0] = 13;}

– con chiamataint a[10];assegna(a);/* qua a[0] vale 13 */

Page 30: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

30

Passaggio di parametri perriferimento (6)

• Inoltre : le due scritturevoid assegna (int x[ ]){ x[0] = 13;}

evoid assegna (int *x){ x[0] = 13;}

– sono del tutto equivalenti– si preferisce usare la prima per leggibilità

Page 31: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

31

Passaggio di parametri perriferimento (7)

• Tipicamente le funzioni che lavorano suarray hanno un secondo parametro chefornisce la lunghezza

int somma (int x[ ], int l){ int i, s = 0; for(i = 0; i < l; i++) s += x[i]; return s;}

– somma tutti gli elementi di un array intero dilunghezza l

Page 32: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

32

Passaggio di parametri perriferimento (8)

• Per gli array multidimensionali la cosa è piùcomplessa!!!!

int somma (int x[ ][4], int l){ int i, j, s = 0; for(i = 0; i < l; i++) for(j = 0; j < 4; j++) s += x[i][j]; return s;}

– invece di 4 posso usare N costante

Page 33: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

33

Passaggio di parametri perriferimento (9)

• Perché dobbiamo specificare l’ampiezza diuna seconda dimensione di un array ?– Dipende dalla strategia di memorizzazione per

gli array multidimensionali• es: int a[2][3]={{1,2,3},{4,5,6}};

123456

a&a[0][1]&a[0][2]&a[1][0]&a[1][1]&a[1][2]

a[i][j] ha come indirizzo a+i*3+j

100104108112116120

Page 34: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

34

Passaggio di parametri perriferimento (10)

• Se non conosco la lunghezza della secondadimensione il compilatore non riesce agenerare codice corretto

int somma (int x[ ][4], int l){ int i, j, s = 0; for(i = 0; i < l; i++) for(j = 0; j < 4; j++) s += x[i][j]; return s;}

Page 35: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

35

Passaggio di parametri perriferimento (11)

• Esiste un modo migliore di quello appenaesaminato per la rappresentazione degli arraymultidimensionali in C : lo vedremo in seguito

Page 36: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

36

E le strutture ???

• Le strutture vengono sempre passate pervalore

• Se una struttura contiene un array, alloral’array viene copiato!– Attenzione quando si passano strutture con

campi array molto grandi!• Se voglio modificare una struttura devo

sempre utilizzare i puntatori!

Page 37: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

37

E le strutture ??? (2)

• Esempio

typedef struct studente { char nom_cogn[40]; unsigned int matricola;} studente;

void scambia (studente * s1,studente * s2);

Page 38: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

38

E le strutture ??? (3)

• Esempio

void scambia (studente * s1,studente * s2) {

…(*s1).matricola = 4; s1->matricola = 4;/*sono equivalenti */}

Page 39: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

39

E le strutture ??? (4)

• Esempio : Come si dichiara una lista in C ?– Usando i puntatori

typedef struct nodo { struct nodo * next; int info;} nodo;

Mi serve il nome dellastruttura !

Page 40: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

40

Allocazione dinamica dellamemoria

• La creazione di nuove variabili a run time(tipo new in Java) viene effettuata in Cutilizzando le funzioni di libreria standardche permettono l’allocazione dinamica diporzioni contigue di memoria– malloc, calloc, realloc– #include <stdlib.h>

Con queste primitive è possibile crearedinamicamente variabili e array di dimensionenon nota a priori

Page 41: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

41

Array dinamici -- malloc( )

• Vediamo come creare dinamicamente un arraydi 10 posizioni

int * a; /*conterrà il puntatore al primo elemento dell’array*/a = malloc(10*sizeof(int));

heap

40 byte

Punta allʼindirizzo iniziale della nuovaarea allocata 100

96

Page 42: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

42

Array dinamici -- malloc( ) (2)

• Vediamo come creare dinamicamente un arraydi 10 posizioni

int * a; /*conterrà il puntatore al primo elemento dell’array*/a = malloc(10*sizeof(int));if (a == NULL) printf(“fallimento!\n”);

heap

Se malloc non riesce ad allocarelʼarea di memoria richiesta restituisce NULL(verificare…)

Page 43: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

43

Array dinamici -- malloc( ) (3)

• Vediamo come creare dinamicamente un arraydi 10 posizioni

int * a; /*conterrà il puntatore al primo elemento dell’array*/a = malloc(10*sizeof(int));if (a == NULL) printf(“fallimento!\n”);else { a[4] = 345;… }

heapLʼarray si può accedere con i consuetioperatori (come se fosse statico)

40 byte10096

Page 44: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

44

Array dinamici -- malloc( ) (4)

• malloc non inizializza la memoria a 0!– Possiamo inizializzarla esplicitamente o– usare calloc

int * a; /*conterrà il puntatore al primo elemento dell’array*/a = calloc(10*sizeof(int));If (a == NULL) printf(“fallimento!\n”);else { a[4] = 345;… }

Page 45: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

45

Array dinamici -- realloc( )

• realloc modifica la lunghezza di un’areaallocata precedentemente

int * a, * b; /*puntatori al primo elemento dell’array*/a = malloc(10*sizeof(int));…b = realloc(a,20*sizeof(int));/* adesso b punta ad un array di 20elementi */

Page 46: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

46

Array dinamici -- realloc( ) (2)

• Meglio usare sempre due puntatori diversi (a,b) !– Altrimenti in caso di fallimento NULL sovrascrive il

vecchio puntatore

Page 47: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

47

Array dinamici -- free( )

• Lo spazio allocato sullo heap non vienedeallocato all’uscita delle funzioni

• La deallocazione deve essere richiestaesplicitamente usando free

int * a;a = malloc(10*sizeof(int));…free(a);/* se qua accedo di nuovo ad apuò succedere di tutto */

Page 48: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

48

tipo puntatore generico: void *

• non si può dereferenziare• è necessario un cast prima di manipolare la

variabile puntata– Es.

void * c;int a;c = &a;*c = 5; /* scorretto*/*(int *)c = 5; /* corretto*/

Page 49: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

49

tipo puntatore generico: void * (2)

• Serve a scrivere funzioni ‘polimorfe’ in unamaniera un po’ brutale

• Esempio– il tipo della malloc è

void * malloc (unsigned int size);

– quando scrivoint * a;a = malloc(10*sizeof(int));

viene effettuato un cast implicito a (int *)

Page 50: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

50

tipo puntatore generico: void * (3)

• Tipi delle altre funzioni di allocazione edeallocazione

void * calloc (unsigned int size);void * realloc (void * ptr, unsigned int size);void free (void * ptr);

Page 51: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

51

I puntatori a funzione

• Consideriamo la funzioneint somma (int x, int y) { return x + y;}

– se proviamo ad eseguireprintf(“%p”, somma);

otteniamo un valore esadecimale cherappresenta un indirizzo legale del nostroprogramma

– ??????????????????????????

Page 52: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

52

I puntatori a funzione (2)

• Consideriamo la funzioneint somma (int x, int y) { return x + y;}

Codice compilato di somma

IND

somma è un puntatore costante con valore pari a IND

Page 53: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

53

I puntatori a funzione (3)

• Consideriamo la funzioneint somma (int x, int y) { return x + y;}

/* variabile di tipo funzione(int,int)->int */

int (*fun) (int,int);int a;

fun = somma;a = fun(3,5);

Page 54: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

54

I puntatori a funzione (4)

• Consideriamo la funzioneint somma (int x, int y) { return x + y;}

/* variabile di tipo funzione(int,int)->int */

int (*fun) (int,int);int a;

fun = somma;a = fun(3,5);

Ma a che serve????????????

Page 55: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

55

I puntatori a funzione (5)• Serve a definire funzioni che prendono

come argomenti altre funzioni (di ordinesuperiore)

void map (int (*fun) (int), int x[ ], int l) { for(i = 0; i < l; i++) x[i] = fun(x[i]);}

è un iteratore che applica la funzione fun atutti gli elementi dell’array x

Page 56: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

56

I puntatori a funzione (6)• Esempio di uso della map

int piu_uno (int x) { return x+1;}int quad (int x) { return x*x;}…int a[3] = {3,4,5};map(piu_uno,a,3); /* somma uno atutti gli elementi */

map(quad,a,2); /* eleva al quadratoi primi due elementi */

Page 57: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

57

Argomenti della linea di comando• Gli argomenti della linea di comando sono

accessibili all’interno della funzione main– il SO li inserisce sullo stack prima di attivare il

processo– il formato in cui sono resi disponibili è fisso

int main (int argc, char * argv[ ]) { …}

Numero di argomentinella linea di comando

Array di puntatoriagli argomenti(ciascuno è unastringa, tipo char*)

Page 58: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

58

Argomenti della linea di comando (2)• Esempio

%> a.out una stringa per a.out

5

argc

argv p e r \O

a . o u t \O

s t r i n g

u n a \O

a \O

a . o u t \O

argv[0]

Page 59: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

59

Argomenti della linea di comando (3)• Esempio : Schema di programma che stampa

gli argomenti sulla linea di comandoint main (int argc, char * argv[ ]) { … for(i = 0; i < argc; i++) printf(“arg %d: %s”, i, argv[i]);…

}

Page 60: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

60

Array multidimensionali comearray di puntatori

• Vogliamo permettere la definizione difunzioni su array multidimensionali che nondipendono dal valore delle dimensionisuccessive alla prima

int sum_mat (int ** MAT, int n, int m) {

}

Nome della matriceNumero di righe, colonne

Page 61: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

61

Array multidimensionali comearray di puntatori (2)

• Vogliamo accedere agli elementi dell’arrayusando la solita notazione [-][-]

int sum_mat (int ** MAT, int n, int m) { … MAT[i][j] = …;

}*(MAT + i*m + j)

Il compilatore dovrebbe conoscere il legame fra questidue oggetti

Page 62: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

62

Array multidimensionali comearray di puntatori (3)

• Una alternativa: abbandonare l’allocazionecontigua per righe

MAT

7 2 6 2

1 2 3 4

4 6 1 2

4 5 1 2

MAT[0]

MAT[1]3 5 7 9

MAT[2]

MAT[3]

MAT[4]

MAT[2][2]

Page 63: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

63

Array multidimensionali comearray di puntatori (4)

• Una alternativa: vediamo i tipi ...

MAT

7 2 6 2

1 2 3 4

4 6 1 2

4 5 1 2

MAT[0]

MAT[1]3 5 7 9

MAT[2]

MAT[3]

MAT[4]

MAT[2][2]int**

int*[5]

int[4]

Page 64: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

64

Array multidimensionali comearray di puntatori (5)

• Una alternativa: in memorianon ho più aree contigue ...

MAT

1 2 3 4

4 6 1 2

MAT[0]

3 5 7 9

40 44 48 52

40 120140400 4

70 86827874

120 124 128 132 140 144 148 152

MAT[1] MAT[2]

indirizzo

valore

Page 65: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

65

Array multidimensionali comearray di puntatori (6)

• Perché funziona?

int sum_mat (int ** MAT, int n, int m) { … MAT[i][j] = …;

}

*(*(MAT + i) + j)Questo legame non interessa più!

Page 66: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

66

Array multidimensionali comearray di puntatori (7)

• Funzione di allocazioneint ** mat_new(unsigned int m, unsigned int n) {

int i, ** a, errore = FALSE;a = malloc(m*sizeof(int*));if (a == NULL) return NULL;for(i = 0; (i < m) && (!errore); i++) {

a[i] = malloc(n*sizeof(int)); if (a[i] == NULL) errore = TRUE; } if (errore) /* gestione errori */ else return a;}

Page 67: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

67

Array multidimensionali comearray di puntatori (8)

• Funzione di deallocazione

void mat_free(int ** a, unsigned int m) { int i; /* dealloco tutte le righe */ for(i = 0; i < m; i++) free(a[i]); /* dealloco l’array dei puntatori alle

righe */ free(a);}

Page 68: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

68

assert( )• Permettono di fare controlli di consistenza a

tempo di esecuzione– prevenire meglio che curare …– esempio: un indice i è davvero dentro i limiti

dell’array?int x, a[N], i;……assert(i < N);x = a[i];

Page 69: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

69

assert( ) (2)#include <assert.h>

…assert(expr);– se expr è falsa il sistema stampa un messaggio

di errore e termina– se expr è vera non ha alcun effetto!

Page 70: Il linguaggio C - unipi.itgroups.di.unipi.it/~cardillo/labso/files/lez03/SOL_puntatoriEDintorni.pdf · •La creazione di nuove variabili a run time (tipo new in Java) viene effettuata

70

assert( ) (3)• Le assert costano!• Quando usarle

– per effettuare controlli di consistenza dopochiamate a codice complesso

• tipicamente non abbiamo i sorgenti (se è scritto daaltri)

• … e comunque anche se li abbiamo non è maigarantita la correttezza!

– si controlla se i valori risultanti sonorispondenti alle specifiche fornite

– si controllano invarianti noti dell’applicazioneche stiamo scrivendo