DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Puntatori
Marco D. Santambrogio – [email protected]
Ver. aggiornata al 11 Ottobre 2014
Obiettivi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• Puntatori
2
Variabili e indirizzi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
3
int var;
&var
2
var
1
0
• 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
3
Puntatori – premessa
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• Dichiarare una variabile significa
riservare una zona di memoria
composta da diverse celle
 Il numero di celle dipende dal tipo di dato
• 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
4
Puntatore
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• È 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;
5
Significato
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
3
int *p;
&p
2
p
1
0
• 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
6
Deferenziazione
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• 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
7
Operazioni
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• A una variabile di tipo puntatore posso assegnare
un indirizzo di memoria
int x;
int *p;
&p
3
&x
2
x=5;
p=&x; /* *p vale 5 */
1
1
5
p
x
0
• p punterà alla zona di memoria in cui è
memorizzato il valore di x
• Ad una variabile puntatore non viene mai assegnato
una costante
8
Passaggio per INDIRIZZO
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• 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
9
Passaggio parametri per indirizzo
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• Si utilizza:
 il costruttore di tipo puntatore per la definizione
dei parametri formali della funzione
float circonferenza(float *raggio)
 l’operatore di dereferenziazione all’interno della
funzione
circ = *raggio * 3.14;
 alla chiamata della funzione, si passa un
indirizzo di variabile come parametro attuale
c=circonferenza(&r);
• Attenzione! Gli array sono SEMPRE passati
per indirizzo. Una variabile di tipo array,
infatti, è per definizione un puntatore
10
Esempio: passaggio per indirizzo
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
float circonferenza(float *raggio) {
Ambiente della funzione
float circ;
circonferenza
circ = *raggio * 3.14;
*raggio = 7; /*istruzione senza
circ
raggio
senso, voglio solo vedere cosa
succede modificando il valore di
un paramentro formale*/
return circ;
Quando la funzione
Quando invoco la funzione
}
/* nel main */
float c,r=5;
c=circonferenza(&r);
/*attenzione! D’ora in poi
r vale 7 */
in raggio viene
copiato l’indirizzo di r.
Quindi *raggio e r sono
la stessa cosa
r
termina il valore di circ in
circonferenza viene
copiato in c nel main
c
Ambiente della funzione main
11
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int p, int q) {
int temp;
a
temp = p;
3
p = q;
b
7
q = temp;
}
p
3
q
7
temp
• Nel main: swap(a,b)
12
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int p, int q) {
int temp;
a
temp = p;
3
p = q;
b
7
q = temp;
}
p
3
q
7
temp
3
• Nel main: swap(a,b)
13
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int p, int q) {
int temp;
a
temp = p;
3
p = q;
b
7
q = temp;
}
p
7
q
7
temp
3
• Nel main: swap(a,b)
14
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int p, int q) {
int temp;
a
temp = p;
3
p = q;
b
7
q = temp;
}
p
7
q
3
temp
3
• Nel main: swap(a,b)
15
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int p, int q) {
int temp;
a
temp = p;
3
p = q;
b
7
q = temp;
}
Al termine
dell’esecuzione di
swap le variabili nel
• Nel main: swap(a,b)
main restano
inalterate!
p
7
q
3
temp
3
16
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int *p, int *q){
int temp;
a
temp = *p;
3
*p = *q;
b
7
*q = temp;
}
p
q
temp
• Nel main: swap(&a, &b)
17
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int *p, int *q){
int temp;
a
temp = *p;
3
b
*p = *q;
7
*q = temp;
}
p
q
temp
3
• Nel main: swap(&a, &b)
18
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int *p, int *q){
int temp;
a
temp = *p;
7
*p = *q;
b
7
*q = temp;
}
p
q
temp
3
• Nel main: swap(&a, &b)
19
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int *p, int *q){
int temp;
a
temp = *p;
7
*p = *q;
b
3
*q = temp;
}
p
q
temp
3
• Nel main: swap(&a, &b)
20
Esempio: scambio di 2 valori interi
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
void swap (int *p, int *q){
int temp;
a
temp = *p;
7
*p = *q;
b
3
*q = temp;
}
Al termine
dell’esecuzione di
swap le variabili nel
• Nel
main: swap(&a,
main
vengono
modificate
p
q
temp
3
&b)
21
scanf: stringhe Vs char
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
22
Parametri di tipo array
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• 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)!!
23
Somma degli elementi di un array di int
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
24
Somma degli elementi di un array di int:
funzioni
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
25
Somma degli elementi di un array di int:
funzioni – con int *valori
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
26
Parametri di tipo array
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• 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]
27
Fonti per lo studio + Credits
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• Fonti per lo studio
 Binky Pointer Fun Video:
http://cslibrary.stanford.edu/104/
• Credits
 Gianluca Palermo
28
Scarica

Document