Lezione 12 (28 marzo 2012) funzioni memoria - puntatori

Post on 13-Jun-2015

215 views 1 download

Transcript of Lezione 12 (28 marzo 2012) funzioni memoria - puntatori

Passaggio per valore

● Al momento del richiamo della funzione il valore dei parametri attuali sono ricopiati nello spazio di memoria allocato ai parametri formali

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;

}

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;

}

mainx y5 ?

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;

}

main fx y rv a5 ? ?

5

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;

}

main fx y rv a b5 ? ?

5?

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;

}

main fx y rv a b5 ? ?

5?

6

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;

}

main fx y rv a b5 ? ?

5?

6

Passaggio per valore: le modifiche effettuate nella funzione restano confinate

nell'ambiente locale

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;

}

main fx y rv a b5 ? ?

5?

636

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;

}

main fx y rv a b5 ? ?

5?

636

36

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;

}

mainx y5 ?

36

Al termine della funzione l'ambiente locale viene

eliminato

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;

}

mainx y5 ?

36

5 36

standard output

Valori di ritorno

f... rType f(type1 p1, type2 p2 ... typeN pN) p1

pN

f...p1

pN

void f(type1 p1, type2 p2 ... typeN pN)

f

rType f(void) rType f()

f

void f(void) f()

main

Valori di ritorno

f...pIn1

pInN...

pOut1

pOutM

?

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

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

Puntatori

...

int x;

int *px;

...Variabile puntatore a intero

(asterisco)

Variabile intera

Puntatori

...int x;int *px;...

px = &x;*px = 5;...

Indirizzo Contenuto variabile... ...0x00000100 ? x0x00000104 ?0x000001080x0000010C0x00000110

...

px

Supponiamo che sia un intero che un puntatore occupino 4 byte

Puntatori

...int x;int *px;...

px = &x;*px = 5;...

Indirizzo Contenuto variabile... ...0x00000100 ? x0x00000104 0x000001000x000001080x0000010C0x00000110

...

px

& : operatore di estrazione di indirizzo

Puntatori

...int x;int *px;...

px = &x;*px = 5;...

Indirizzo Contenuto variabile... ...0x00000100 0x00000005 x0x00000104 0x000001000x000001080x0000010C0x00000110

...

px

* : operatore di dereferenziazione di un indirizzo (estrazione del contenuto)

Proprietà fondamentale

*&x = x

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;

}

Passaggio per indirizzo

main(){int x;

x=5;f(&x);printf(“%d”,x);

}

void f(int *a){

*a = *a + 1;

}

Passaggio per indirizzo

x5

mainmain(){int x;

x=5;f(&x);printf(“%d”,x);

}

void f(int *a){

*a = *a + 1;

}

Passaggio per indirizzo

main(){int x;

x=5;f(&x);printf(“%d”,x);

}

void f(int *a){

*a = *a + 1;

}

fx *a5

main

Passaggio per indirizzo

main(){int x;

x=5;f(&x);printf(“%d”,x);

}

void f(int *a){

*a = *a + 1;

}

fx *a56

main

Passaggio per indirizzo

main(){int x;

x=5;f(&x);printf(“%d”,x);

}

void f(int *a){

*a = *a + 1;

}

x56

main

Passaggio per indirizzo

main(){int x;

x=5;f(&x);printf(“%d”,x);

}

void f(int *a){

*a = *a + 1;

}

mainx56

6

standard output

scanf

main(){int x;

scanf(“%d”,&x);....

xmain scanf

*...

Nella scanf si usa il simbolo & perchè le variabili da leggere sono passate per indirizzo

scanf

main(){int x;

lettura(&x, ...);...

}

void lettura(int *z, ...){

...scanf(“%d”,z);...

}

letturax *z

main scanf*...

Nella scanf non è necessario l'operatore &

in quanto z è già un indirizzo

Scambio del valore di due variabili

a

5

b

10

Scambio del valore di due variabili

a

5

b

10

aux

5

1

...aux = a;a = b;b = aux;...

Scambio del valore di due variabili

a

10

b

10

aux

5

1

2

...aux = a;a = b;b = aux;...

Scambio del valore di due variabili

a

10

b

5

aux

5

1 3

2

...aux = a;a = b;b = aux;...

Scambio del valore di due variabili

void scambia(int *a, int* b){int aux;

aux = *a;*a = *b;*b = aux;

}