DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio –...
-
Upload
angiolo-leo -
Category
Documents
-
view
214 -
download
0
Transcript of DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio –...
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
PuntatoriPuntatori
Marco D. Santambrogio – [email protected]. aggiornata al 21 Marzo 2013
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
ObiettiviObiettivi
• Puntatori
2
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Pointer Fun with BinkyPointer Fun with Binky
3
This is document 104 in the Stanford CS Education Library. Please see http://cslibrary.stanford.edu/ for this and other free educational materials. Copyright Nick Parlante 1999.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio dei parametriPassaggio dei parametri
• Il passaggio dei parametri consiste nell’associare, all’atto delle chiamata di un sottoprogramma, ai parametri formali i parametri attuali Se il prototipo di una funzione è
float circonferenza (float raggio); Invocare questa funzione significa eseguire l’istruzione
c = circonferenza(5.0); In questo modo la variabile raggio (il parametro formale) assumerà per
quella particolare invocazione il valore 5 (il parametro attuale).
• Lo scambio di informazioni con passaggio dei parametri tra chiamante e chiamato può avvenire in due modi: Passaggio per valore Passaggio per indirizzo
4
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio per VALOREPassaggio per VALORE
• All’atto della chiamata il valore del parametro attuale viene copiato nelle celle di memoria del corrispondente parametro formale. Il parametro formale e il parametro attuale si
riferiscono a due diverse celle di memoria
• Il sottoprogramma in esecuzione lavora nel suo ambiente e quindi sui parametri formali
• I parametri attuali non vengono modificati
5
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: passaggio per Esempio: passaggio per valorevalorefloat circonferenza(float raggio)
{
float circ;
circ = raggio * 3.14;
raggio = 7; /*istruzione senza senso, voglio solo vedere cosa succede modificando il valore di un paramentro formale*/
return circ;
}
/* nel main */
float c,r=5;
c=circonferenza(r);
/*Attenzione! r vale sempre 5 */
6
Ambiente della funzione circonferenza
raggio circ
Ambiente della funzione main
r c
Quando invoco la funzione in raggio viene copiato il valore di r
Quando la funzionetermina il valore di circ in circonferenza viene copiato in c nel main
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio per INDIRIZZOPassaggio per INDIRIZZO
• All’atto della chiamata l’indirizzo dei parametri attuali viene associato ai parametri formali il parametro attuale e il parametro formale si
riferiscono alla stessa cella di memoria
• Il sottoprogramma in esecuzione lavora nel suo ambiente sui parametri formali (e di conseguenza anche sui parametri attuali) ogni modifica sul parametro formale è una modifica
del corrispondente parametro attuale
• Gli effetti del sottoprogramma si manifestano nel chiamante con modifiche al suo ambiente locale di esecuzione
7
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio dei parametri in Passaggio dei parametri in CC• In C non esiste un costrutto sintattico per
distinguere tra passaggio dei parametri per valore e per indirizzo
• Il passaggio è sempre per valore
/*passaggio per valore*/float circonferenza(float raggio);
• Per ottenere il passaggio per indirizzo è necessario utilizzare parametri formali di tipo indirizzo (puntatori)
/*passaggio per indirizzo*/float circonferenza(float *raggio);
8
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Puntatori – premessa Puntatori – premessa
• Dichiarare una variabile significa riservare una zona di memoria composta da diverse celle
• Il numero di celle dipende dal tipo di dato (short int 2 byte, float 4 byte, …)
• Ogni cella di memoria ha un indirizzo fisico e: il nome della variabile indica il contenuto della
cella di memoria l’operatore & permette di ottenere l’indirizzo di
memoria della cella associata alla variabile cui l’operatore è applicato
9
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Variabili e indirizziVariabili e indirizzi
• Supponiamo che la dichiarazione riservi la zona di memoria all’indirizzo 1
• var indica il contenuto della cella di memoria• &var indica l’indirizzo della cella di memoria
10
int var;
0
1
2
3
var&var
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
PuntatorePuntatore
• È un tipo di dato che ammette tra i suoi valori un indirizzo di memoria La zona di memoria viene detta “puntata” dalla
variabile puntatore La variabile puntatore viene detto che “punta” ad
una cella di memoria• Quando dichiaro un puntatore si deve anche
specificare che tipo di dato viene ospitato nella cella puntata
• Sintassi:
int *p;
• Una variabile puntatore occupa solitamente 2 byte o 4 byte a seconda delle architetture
11
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
SignificatoSignificato
• p è una variabile come tutte le altre quindi p indica il contenuto della cella di memoria &p indica l’indirizzo di memoria
• Quello che caratterizza una variabile di tipo puntatore è il fatto che il suo valore è esso stesso un indirizzo di memoria
12
int *p;
0
1
2
3
p&p
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
DeferenziazioneDeferenziazione
• Ad una variabile di tipo puntatore posso applicare l’operatore di deferenziazione *
• *p indica il contenuto della cella puntata da p• Se p è un puntatore ad un intero allora *p è
una semplice variabile intera
int *p;
*p=5; /* OK. *p è un intero */p=5; /* errore. p è un puntatore */
• Attenzione! Il simbolo * lo uso sia nella dichiarazione che nella deferenziazione
13
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
OperazioniOperazioni
• A una variabile di tipo puntatore posso assegnare un indirizzo di memoria
int x;int *p;
x=5;p=&x; /* *p vale 5 */
• p punterà alla zona di memoria in cui è memorizzato il valore di x
• Ad una variabile puntatore non viene mai assegnato una costante
14
1
5
0
1
2
3
x
&p
&x
p
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio parametri per Passaggio parametri per indirizzoindirizzo
• Si utilizza: il costruttore di tipo puntatore per la definizione
dei parametri formali della funzionefloat circonferenza(float *raggio)
l’operatore di dereferenziazione all’interno della funzionecirc = *raggio * 3.14;
alla chiamata della funzione, si passa un indirizzo di variabile come parametro attualec=circonferenza(&r);
• Attenzione! Gli array sono SEMPRE passati per indirizzo. Una variabile di tipo array, infatti, è per definizione un puntatore
15
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: passaggio per Esempio: passaggio per indirizzoindirizzo
float circonferenza(float *raggio) { float circ;circ = *raggio * 3.14;*raggio = 7; /*istruzione senza
senso, voglio solo vedere cosa succede modificando il valore di un paramentro formale*/
return circ;}
/* nel main */float c,r=5;
c=circonferenza(&r);/*attenzione! D’ora in poir vale 7 */
16
Ambiente della funzione circonferenza
raggio circ
Ambiente della funzione main
r c
Quando invoco la funzione in raggio viene copiato l’indirizzo di r.Quindi *raggio e r sono la stessa cosa
Quando la funzionetermina il valore di circ in circonferenza viene copiato in c nel main
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interi Esempio: scambio di 2 valori interi
void swap (int p, int q) {int temp;temp = p; p = q;q = temp;
}
• Nel main: swap(a,b)
17
a
b
3
7
p
q
temp
3
7
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interi Esempio: scambio di 2 valori interi
void swap (int p, int q) {int temp;temp = p; p = q;q = temp;
}
• Nel main: swap(a,b)
18
a
b
3
7
p
q
temp
3
7
3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interi Esempio: scambio di 2 valori interi
void swap (int p, int q) {int temp;temp = p; p = q;q = temp;
}
• Nel main: swap(a,b)
19
a
b
3
7
p
q
temp
7
7
3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interi Esempio: scambio di 2 valori interi
void swap (int p, int q) {int temp;temp = p; p = q;q = temp;
}
• Nel main: swap(a,b)
20
a
b
3
7
p
q
temp
7
3
3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interi Esempio: scambio di 2 valori interi
void swap (int p, int q) {int temp;temp = p; p = q;q = temp;
}
• Nel main: swap(a,b)
21
a
b
3
7
p
q
temp
7
3
3Al termine dell’esecuzione di swap le variabili nel main restano inalterate!
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interiEsempio: scambio di 2 valori interi
void swap (int *p, int *q){int temp;temp = *p; *p = *q;*q = temp;
}
• Nel main: swap(&a, &b)
22
a
b
3
7
p
q
temp
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interiEsempio: scambio di 2 valori interi
void swap (int *p, int *q){int temp;temp = *p; *p = *q;*q = temp;
}
• Nel main: swap(&a, &b)
23
a
b
3
7
p
q
temp3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interiEsempio: scambio di 2 valori interi
void swap (int *p, int *q){int temp;temp = *p; *p = *q;*q = temp;
}
• Nel main: swap(&a, &b)
24
a
b
7
7
p
q
temp3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interiEsempio: scambio di 2 valori interi
void swap (int *p, int *q){int temp;temp = *p; *p = *q;*q = temp;
}
• Nel main: swap(&a, &b)
25
a
b
7
3
p
q
temp3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: scambio di 2 valori interiEsempio: scambio di 2 valori interi
void swap (int *p, int *q){int temp;temp = *p; *p = *q;*q = temp;
}
• Nel main: swap(&a, &b)
26
a
b
7
3
p
q
temp3
Al termine dell’esecuzione di swap le variabili nel main vengono modificate
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
1 /* Cubo di una variabile */
2
3
4
5 #include <stdio.h>
6
7 void cuboRiferimento( int * nPtr ); /* prototype */
8
9 void main()
10 {
11 int number = 5;
12
13 printf( "The original value of number is %d", number );
14 cuboRiferimento( &number );
15 printf( "\nThe new value of number is %d\n", number );
16
17
18 }
19
20 void cuboRiferimento( int *nPtr )
21 {
22 *nPtr = *nPtr * *nPtr * *nPtr;
23 }
The original value of number is 5The new value of number is 125
In cuboRiferimento, viene usato *nPtr (*nPtr è l’intero number).
cuboRiferimento si aspetta un indirizzo!!
CuboCubo
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Intercambiabilità tra procedure e Intercambiabilità tra procedure e funzionifunzioni
• Funzione:
int f(int par1)
{
… (calcola valore di variabile “risultato”) ...
return (risultato);
}
• Chiamata:
y=f(x);
• Procedura:
void f(int par1,int *par2)
{
… (calcola valore di variabile “risultato”)...
*par2=risultato;
}
• Chiamata:
f(x,&y);
28
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Parametri di tipo arrayParametri di tipo array
• Per usare in una funzione una variabile di tipo array occorre passare il suo indirizzo di base, perciò di fatto l’array è passato per locazione (indirizzo)
• Una funzione C non restituirà un array (come contenuto), ma solo un puntatore a un array (cioè il suo nome come suo indirizzo)!!
29
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: Esempio: prodotto degli elementi prodotto degli elementi di un array di tipo doubledi un array di tipo double
30
double mul (double a[ ], int n) {/* n porzione occupata dell'array che viene passato */
int i;double ris;
ris = 1.0;for ( i = 0; i < n; i = i + 1 )
ris = ris * a[i];return ris;
}
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Parametri di tipo arrayParametri di tipo array
• Due testate equivalenti:double mul(double *a, int n)double mul(double a[], int n)
• N.B.: non c’è la dimensione, e n è la porzione occupata dell'array
• Supponiamo di avere un array V[50]. Possibili chiamate:
mul(V,50) restituisce V[0]*V[1]*…V[49]mul(V,30) restituisce V[0]*V[1]*…V[29]mul(&V[5],7) restituisce V[5]*V[6]*…V[11]mul(V+5,7) restituisce V[5]*V[6]*…V[11]
31
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Fonti per lo studio + Fonti per lo studio + CreditsCredits• Fonti per lo studio
Binky Pointer Fun Video: http://cslibrary.stanford.edu/104/
• Credits Gianluca Palermo