38
PUNTATORI Un puntatore è una variabile destinata a contenere l’indirizzo di un’altra variabile Vincolo di tipo : un puntatore a T può contenere solo l’indirizzo di variabili di tipo T. Esempio: int x = 8; int* p; p = &x; /* OK */

PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

Embed Size (px)

Citation preview

Page 1: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

• Un puntatore è una variabile destinata a contenere l’indirizzo di un’altra variabile

• Vincolo di tipo: un puntatore a T può contenere solo l’indirizzo di variabili di tipo T.

• Esempio:

int x = 8;int* p;p = &x; /* OK */

Page 2: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

int x = 8;int* p;p = &x; /* OK */

Da questo momento, *p e x sono due modialternativi per denotare la stessa variabile

xp

8

Page 3: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

int x = 8;int* p = &x;*p = 31; x--;

Il valore di *p, alias x, è ora 30.

Il valore di p, invece, rimane immutato.

xp

8 30

Page 4: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

In questo momento, p punta a x, e perciò*p è un alias per x.

Ma un puntatore non è legato per semprealla stessa variabile: può puntare altrove.

int x = 8, y = 66;int *p = &x;(*p)++; /* incrementa x */p = &y; /* ora p punta a y */(*p)--; /* decrementa y */

Page 5: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

In questo momento, p punta a x, e perciò*p è un alias per x.

Ma un puntatore non è legato per semprealla stessa variabile: può puntare altrove.

int x = 8, y = 66;int *p = &x;(*p)++; /* incrementa x */p = &y; /* ora p punta a y */(*p)--; /* decrementa y */

Le parentesi intorno a (*p)sono necessarie per modi-

ficare l’oggetto puntato da pe non p stesso.

Page 6: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

• Un puntatore a T può contenere solo l’in-dirizzo di variabili di tipo T: puntatori a tipi diversi sono incompatibili tra loro.

• Esempio:

int x=8,*p; float *q;p = &x; /* OK */q = p; /* NO! */

MOTIVO: il tipo del puntatore serve per dedurre iltipo dell’oggetto puntato, che è una informazioneindispensabile per effettuare il dereferenziamento.

Page 7: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

Forzare un assegnamento fra puntatori a tipidiversi è possibile mediante un cast esplici-to, ma è molto pericoloso!

int x=8,*p; float *q;q = (float*)&x;

ATTENZIONE!! • È facile scriverlo…• … ma quasi sempre si ottengono solo guai!

Aggirare il type system non è (quasi) mai una buona idea!!

Page 8: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

IL SOLITO ESEMPIO

void scambia(int* pa, int* pb) { int t; t = *pa; *pa = *pb; *pb = t;}

main(){ int y = 5, x = 33; int *py = &y, *px = &x; scambia(px, py);} Variazione sul tema: gli indirizzi

di x e y sono posti in due puntatoripx e py prima di passarli.

Page 9: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

• Un puntatore è una variabile destinata a contenere l’indirizzo di un’altra variabile

• Vincolo di tipo: un puntatore a T può contenere solo l’indirizzo di variabili di tipo T.

• Esempio:

int x = 8;int* p;p = &x; /* OK */

Page 10: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

int x = 8;int* p;p = &x; /* OK */

Da questo momento, *p e x sono due modialternativi per denotare la stessa variabile

xp

8

Page 11: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

int x = 8;int* p = &x;*p = 31; x--;

Il valore di *p, alias x, è ora 30.

Il valore di p, invece, rimane immutato.

xp

8 30

Page 12: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

In questo momento, p punta a x, e perciò*p è un alias per x.

Ma un puntatore non è legato per semprealla stessa variabile: può puntare altrove.

int x = 8, y = 66;int *p = &x;(*p)++; /* incrementa x */p = &y; /* ora p punta a y */(*p)--; /* decrementa y */

Page 13: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

In questo momento, p punta a x, e perciò*p è un alias per x.

Ma un puntatore non è legato per semprealla stessa variabile: può puntare altrove.

int x = 8, y = 66;int *p = &x;(*p)++; /* incrementa x */p = &y; /* ora p punta a y */(*p)--; /* decrementa y */

Le parentesi intorno a (*p)sono necessarie per modi-

ficare l’oggetto puntato da pe non p stesso.

Page 14: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

• Un puntatore a T può contenere solo l’in-dirizzo di variabili di tipo T: puntatori a tipi diversi sono incompatibili tra loro.

• Esempio:

int x=8,*p; float *q;p = &x; /* OK */q = p; /* NO! */

MOTIVO: il tipo del puntatore serve per dedurre iltipo dell’oggetto puntato, che è una informazioneindispensabile per effettuare il dereferenziamento.

Page 15: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

PUNTATORI

Forzare un assegnamento fra puntatori a tipidiversi è possibile mediante un cast esplici-to, ma è molto pericoloso!

int x=8,*p; float *q;q = (float*)&x;

ATTENZIONE!! • È facile scriverlo…• … ma quasi sempre si ottengono solo guai!

Aggirare il type system non è (quasi) mai una buona idea!!

Page 16: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

IL SOLITO ESEMPIO

void scambia(int* pa, int* pb) { int t; t = *pa; *pa = *pb; *pb = t;}

main(){ int y = 5, x = 33; int *py = &y, *px = &x; scambia(px, py);} Variazione sul tema: gli indirizzi

di x e y sono posti in due puntatoripx e py prima di passarli.

Page 17: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

IL SOLITO ESEMPIO

Osserva: pa e pb sono copie di px e py!

Il C passa davvero tuttosempre e solo per valore!

RADL

X

Y

PA

PB

33

5

5

33

T 33

RADL

px

py

Page 18: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

ESERCIZIO

Scrivere una procedura che, dato un carattere C, lo trasformi in maiuscolo.

Specifica di I° livello:

void maiuscolo(char *pc);restituisce il maiuscolo di C

Specifica di II° livello:

Se *c non è una lettera minuscola, restituiscilo tale e quale. Altrimenti, per calcolare il corrispondente maiu-scolo, sfrutta l’ ordinamento della codifica dei caratteri:– ogni carattere è associato a un intero– le lettere da ‘A’ a ‘Z’ sono in sequenza– le lettere da ‘a’ a ‘z’ sono in sequenza

Page 19: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

ESERCIZIO

void maiuscolo(char *pc) {if (*pc<'a' || *pc>'z') return;else *pc –= 'a' - 'A';

}

o anche:

void maiuscolo(char *pc) {if (*pc>='a' && *pc<='z')

*pc += 'A' - 'a';}

Cosa succede se si dimentica un asterisco?

Page 20: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

COMUNICAZIONE TRAMITE ENVIRONMENT GLOBALE

Una procedura può anche comunicare conil suo cliente mediante aree dati globali: unesempio sono le variabili globali del C.

Esempio: Divisione intera x/y con calcolo di quoziente eresto.• occorre calcolare due valori• che supponiamo di mettere in due variabili

globali.

Page 21: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

COMUNICAZIONE TRAMITE ENVIRONMENT GLOBALE

int quoziente, int resto;

void dividi(int x, int y) { resto = x % y; quoziente = x/y;}

main(){ dividi(33, 6);}

Il risultato è nelle variabili globali quoziente e resto:

il cliente deve andar-selo a prendere!Soprattutto, niente indica

che sia là: bisogna saperlo.

Page 22: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

L’ENVIRONMENT GLOBALE

Le variabili globali in C:• sono allocate nell’area dati globale • esistono già prima della chiamata del main• sono inizializzate automaticamente a 0

salvo diversa indicazione (preferibile!!)• possono essere nascoste in una funzione

da una variabile locale omonima• sono visibili, previa dichiarazione extern,

in tutti i file dell’applicazione

Page 23: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

L’ENVIRONMENT GLOBALE

Il fatto che le variabili globali in C siano visi-bili, previa dichiarazione extern, in tutti i filedell’applicazione pone dei problemi di prote-zione.

Potrebbe essere utile avere variabili globali• permanenti come tempo di vita• ma protette, nel senso che solo una parte

dell’applicazione possa accedervi.

Page 24: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

VARIABILI STATICHE

In C, una variabile può essere dichiaratastatic. In questo modo, essa:• è permanente come tempo di vita• ed è protetta, in quanto è visibile solo

entro il suo scope di definizione.

Nel caso di una variabile globale, ognitentativo di accedervi da altri file, tramitedichiarazioni extern, sarà stroncato dalcompilatore.

Page 25: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

ESEMPIO

static int cont = 3;

int nextValue(){return cont++;

}

• La variabile cont è inaccessibile fuori da questo file (il suo scope di definizione); l’unico modo di accedervi è tramite la funzione nextValue

• se un altro file definisse un’altra variabile globale cont, non ci sarebbe comunque collisione, perché la prima esternamente “non esiste”.

Page 26: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

VARIABILI STATICHE

Una variabile statica può essere definitaanche dentro a una funzione. Così:• è comunque protetta, in quanto visibile solo

dentro alla funzione (come ogni variabile locale)

• ma è anche permanente, in quanto il suo tempo di vita diventa quello dell’intero programma.

È un mezzo per costruire componenti (fun-zioni) dotati di stato.

Page 27: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

ESEMPIO

int nextPrime(void) { static lastprime = 0; if (lastprime>=0 && lastprime<=2)

return ++lastprime; else {

do lastprime += 2;while (!isPrime(lastprime));

return lastprime; }}

Questa funzione restituisce a ogni invocazione il suc-cessivo numero primo.

È un componente dotato di stato: chiamato più volte, dà ogni volta

una risposta diversa

Page 28: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

VARIABILI STATICHE

Quindi, la parola chiave static• ha sempre e comunque due effetti

– rende la variabile permanente– rende la variabile protetta

(invisibile fuori dal suo scope di definizione)

• ma se ne vede sempre uno solo per volta– una variabile definita in una funzione, che è

comunque protetta, viene resa permanente– una variabile globale, già di per sé permanente,

viene resa protetta.

Page 29: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

COMUNICAZIONE TRAMITE ENVIRONMENT GLOBALE

Una procedura può anche comunicare conil suo cliente mediante aree dati globali: unesempio sono le variabili globali del C.

Esempio: Divisione intera x/y con calcolo di quoziente eresto.• occorre calcolare due valori• che supponiamo di mettere in due variabili

globali.

Page 30: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

COMUNICAZIONE TRAMITE ENVIRONMENT GLOBALE

int quoziente, int resto;

void dividi(int x, int y) { resto = x % y; quoziente = x/y;}

main(){ dividi(33, 6);}

Il risultato è nelle variabili globali quoziente e resto:

il cliente deve andar-selo a prendere!Soprattutto, niente indica

che sia là: bisogna saperlo.

Page 31: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

L’ENVIRONMENT GLOBALE

Le variabili globali in C:• sono allocate nell’area dati globale • esistono già prima della chiamata del main• sono inizializzate automaticamente a 0

salvo diversa indicazione (preferibile!!)• possono essere nascoste in una funzione

da una variabile locale omonima• sono visibili, previa dichiarazione extern,

in tutti i file dell’applicazione

Page 32: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

L’ENVIRONMENT GLOBALE

Il fatto che le variabili globali in C siano visi-bili, previa dichiarazione extern, in tutti i filedell’applicazione pone dei problemi di prote-zione.

Potrebbe essere utile avere variabili globali• permanenti come tempo di vita• ma protette, nel senso che solo una parte

dell’applicazione possa accedervi.

Page 33: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

VARIABILI STATICHE

In C, una variabile può essere dichiaratastatic. In questo modo, essa:• è permanente come tempo di vita• ed è protetta, in quanto è visibile solo

entro il suo scope di definizione.

Nel caso di una variabile globale, ognitentativo di accedervi da altri file, tramitedichiarazioni extern, sarà stroncato dalcompilatore.

Page 34: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

ESEMPIO

static int cont = 3;

int nextValue(){return cont++;

}

• La variabile cont è inaccessibile fuori da questo file (il suo scope di definizione); l’unico modo di accedervi è tramite la funzione nextValue

• se un altro file definisse un’altra variabile globale cont, non ci sarebbe comunque collisione, perché la prima esternamente “non esiste”.

Page 35: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

VARIABILI STATICHE

Una variabile statica può essere definitaanche dentro a una funzione. Così:• è comunque protetta, in quanto visibile solo

dentro alla funzione (come ogni variabile locale)

• ma è anche permanente, in quanto il suo tempo di vita diventa quello dell’intero programma.

È un mezzo per costruire componenti (fun-zioni) dotati di stato.

Page 36: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

ESEMPIO

int nextPrime(void) { static lastprime = 0; if (lastprime>=0 && lastprime<=2)

return ++lastprime; else {

do lastprime += 2;while (!isPrime(lastprime));

return lastprime; }}

Questa funzione restituisce a ogni invocazione il suc-cessivo numero primo.

È un componente dotato di stato: chiamato più volte, dà ogni volta

una risposta diversa

Page 37: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

VARIABILI STATICHE

Quindi, la parola chiave static• ha sempre e comunque due effetti

– rende la variabile permanente– rende la variabile protetta

(invisibile fuori dal suo scope di definizione)

• ma se ne vede sempre uno solo per volta– una variabile definita in una funzione, che è

comunque protetta, viene resa permanente– una variabile globale, già di per sé permanente,

viene resa protetta.

Page 38: PUNTATORI Un puntatore è una variabile destinata a contenere lindirizzo di unaltra variabile Vincolo di tipo: un puntatore a T può contenere solo lindirizzo

FUNZIONI STATICHE

Nel secondo significato (protezione enascondimento), la parola chiave static può qualificare anche una funzione.

– rende la funzione protetta(invisibile fuori dal file di definizione)

– può servire per funzioni “a uso interno”, non destinate a essere invocate da altri

static int f(...) {...}