Lezione 12 (28 marzo 2012) funzioni memoria - puntatori
1. Passaggio per valore
● Al momento del richiamo della funzione il valore
dei parametri attuali sono ricopiati nello spazio
di memoria allocato ai parametri formali
2. Passaggio per valore
main(){
int x, y;
x=5;
y=f(x);
printf(“%d %d”,x,y);
}
int f(int a){
int b;
a=a+1;
b=a*a;
return b;
}
3. Passaggio per valore
main(){ main
int x, y; x y
5 ?
x=5;
y=f(x);
printf(“%d %d”,x,y);
}
int f(int a){
int b;
a=a+1;
b=a*a;
return b;
}
4. Passaggio per valore
main(){ main f
int x, y; x y rv a
5 ? ?
x=5; 5
y=f(x);
printf(“%d %d”,x,y);
}
int f(int a){
int b;
a=a+1;
b=a*a;
return b;
}
5. Passaggio per valore
main(){ main f
int x, y; x y rv a b
5 ? ?
x=5; 5
y=f(x); ?
printf(“%d %d”,x,y);
}
int f(int a){
int b;
a=a+1;
b=a*a;
return b;
}
6. Passaggio per valore
main(){ main f
int x, y; x y rv a b
5 ? ?
x=5; 5
y=f(x);
?
printf(“%d %d”,x,y);
6
}
int f(int a){
int b;
a=a+1;
b=a*a;
return b;
}
7. Passaggio per valore
main(){ main f
int x, y; x y rv a b
5 ? ?
x=5; 5
y=f(x);
?
printf(“%d %d”,x,y);
6
}
int f(int a){
int b;
a=a+1;
b=a*a;
return b; Passaggio per valore:
} le modifiche effettuate nella
funzione restano confinate
nell'ambiente locale
8. Passaggio per valore
main(){ main f
int x, y; x y rv a b
5 ? ?
x=5; 5
y=f(x);
?
printf(“%d %d”,x,y);
6
}
36
int f(int a){
int b;
a=a+1;
b=a*a;
return b;
}
9. Passaggio per valore
main(){ main f
int x, y; x y rv a b
5 ? ?
x=5; 5
y=f(x);
?
printf(“%d %d”,x,y);
6
}
36
int f(int a){ 36
int b;
a=a+1;
b=a*a;
return b;
}
10. Passaggio per valore
main(){ main
int x, y; x y
5 ?
x=5;
y=f(x);
printf(“%d %d”,x,y);
}
int f(int a){
int b; 36
a=a+1;
b=a*a;
return b; Al termine della funzione
} l'ambiente locale viene
eliminato
11. Passaggio per valore
main(){ main
int x, y; x y
5 ?
x=5;
y=f(x);
printf(“%d %d”,x,y);
}
int f(int a){
int b; 36
a=a+1;
b=a*a; standard output
return b; 5 36
}
12. Valori di ritorno
p1
... f rType f(type1 p1, type2 p2 ... typeN pN)
pN
p1 void f(type1 p1, type2 p2 ... typeN pN)
... f
pN
rType f(void)
f
rType f()
void f(void)
f main
f()
14. Valori di ritorno e passaggio per
indirizzo
● nell'istruzione return può essere specificato una
espressione di tipo atomico (int, float, char ecc)
● se la funzione deve restituire più di un risultato
non si può utilizzare il return
● la tecnica utilizzata è quella del passaggio dei
parametri per riferimento (indirizzo)
● più in generale il passaggio per riferimento
consente alla funzione di modificare i parametri
attuali
15. Puntatori
● Se la funzione conoscesse la posizione
(indirizzo) in memoria dei parametri attuali
potrebbe accedervi per modificarli
● La tecnica è implementata in C mediante
l'utilizzo del puntatore
● Un puntatore è un indirizzo di memoria
● Una variabile di tipo puntatore può contenere
l'indirizzo di memoria di un'altra variabile
16. Puntatori
... Variabile intera
int x;
int *px;
Variabile puntatore a intero
... (asterisco)
17. Puntatori
...
int x; Indirizzo Contenuto variabile
int *px; ... ...
... 0x00000100 ? x
0x00000104 ? px
px = &x; 0x00000108
*px = 5; 0x0000010C
... 0x00000110
...
Supponiamo che sia un intero che un
puntatore occupino 4 byte
18. Puntatori
...
int x; Indirizzo Contenuto variabile
int *px; ... ...
... 0x00000100 ? x
0x00000104 0x00000100 px
px = &x; 0x00000108
*px = 5; 0x0000010C
... 0x00000110
...
& : operatore di estrazione di indirizzo
19. Puntatori
...
int x; Indirizzo Contenuto variabile
int *px; ... ...
... 0x00000100 0x00000005 x
0x00000104 0x00000100 px
px = &x; 0x00000108
*px = 5; 0x0000010C
... 0x00000110
...
* : operatore di dereferenziazione di un
indirizzo (estrazione del contenuto)
21. Passaggio per indirizzo
● Se alla funzione A forniamo l'indirizzo di una
variabile della funzione chiamante B, la funzione
A può modificare il valore della variabile di B
void A(int *x){
*x = *x + 1;
}
27. Passaggio per indirizzo
main(){ main
int x; x
5
x=5; 6
f(&x);
printf(“%d”,x);
}
void f(int *a){
*a = *a + 1;
standard output
} 6
28. scanf
main(){ main scanf
int x; x *...
scanf(“%d”,&x);
....
Nella scanf si usa il simbolo & perchè le
variabili da leggere sono passate per indirizzo
29. scanf
main(){ main lettura scanf
int x; x *z *...
lettura(&x, ...);
...
}
void lettura(int *z, ...){
... Nella scanf non è
scanf(“%d”,z); necessario l'operatore &
... in quanto z è già un
} indirizzo