Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni...

32
Sono variabili il cui valore corrisponde ad un indirizzo di memoria Puntatori

Transcript of Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni...

Page 1: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Sono variabili il cui valore corrisponde ad un indirizzo di memoria

Puntatori

Page 2: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Dichiarazione di variabile puntatore

• Esistono puntatori per ogni tipo di variabile puntata– Un dato puntatore può puntare solo a un determinato tipo di variabili,

quello specificato nella dichiarazione

• Si usa il qualificatore di tipo (suffisso) *– Es. : int* pointer; (ma anche int *pointer)– dichiara la variabile pointer, puntatore ad una qualunque variabile di

tipo int

Page 3: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Operatore di indirizzo &

• L’operatore unario di indirizzo & restituisce l’indirizzo dellalocazione di memoria dell’operando– Il valore restituito non va usato come l-value– (in quanto l’indirizzo di memoria di una variabile non può essere

assegnato in un’istruzione, ma è predeterminato)

Page 4: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Operatore di indirizzo &

Es.:&a ammesso&(a+1) non ammesso&a = b non ammesso

Perché? (in quanto l’indirizzo di memoria di una variabile nonpuò essere modificato in un’istruzione, ma solo usato comeriferimento in quanto è predeterminato e non modificabile)

Page 5: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Assegnazione di valore a un puntatore

NON si possono assegnare valori a un puntatore, salvo che inquesti tre casi:

1. a un puntatore é assegnato il valore NULL (non punta a “niente”)

2. a un puntatore è assegnato l’indirizzo di una variabile esistente, restituito dall’operatore &( Es. int a; int* p; p=&a; )

3. é eseguita un’operazione di allocazione dinamica della memoria

Page 6: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

L’operatore di dereferenziazione *

Consideriamo

int y=5;int *yPtr;yPtr = &y;

Page 7: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Operazioni sui puntatori

Operazioni fondamentali:

Assegnazione di valore (indirizzo) ad un puntatoreint* pi = &i p = q

Riferimento all’oggetto puntato *pi=3

Confronto tra puntatori (==, !=)

Page 8: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Operazioni sui puntatori

E’ possibile specificare che un dato puntatore non deve essere usato per modificare l’oggetto puntato attraverso la parola chiave const:

int i;const int* p=&i;

Le istruzioni in cui si usa p per aggiornare i vengono segnalate come erronee

Page 9: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

L’operatore di dereferenziazione *

L’operatore unario di dereferenziazione * di un puntatorerestituisce il valore della variabile puntata dall’operando:come r-value, esegue un’operazione di estrazioneEs.: a = *p; assegna ad a il valore della variabile puntata da p

come l-value, esegue un’operazione di inserimentoEs.: *p = a; assegna il valore di a alla variabile puntata da p

Page 10: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

L’operatore di dereferenziazione *

l’operazione di deref. é inversa a quella di indirizzo.

Se assegniamo a un puntatore p l’indirizzo di una variabile a,

p = &a;allora

*p == a cioè la deref. di p coincide con a

Page 11: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

L’operatore di dereferenziazione *

ATTENZIONE: non é detto il contrario !!!

se si assegna alla deref. di p il valore di a,*p = a ;

ciò non comporta automaticamente che in p si ritrovi l’indirizzodi a, ma semplicemente che il valore della variabile puntata da pcoinciderà con a

Page 12: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Attenzione!

la dichiarazione di un puntatore comporta allocazione dimemoria per la variabile puntatore, ma non per la variabilepuntata.

Es.: int* lista;alloca memoria per lista ma non per la variabile puntata dalista

Page 13: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array e puntatori

Il nome di un array è in realtà un puntatorecostante all’indirizzo di partenza dell’arraystesso, per cui non può essere modificatonelle operazioni di aritmetica dei puntatori.

I puntatori possono essere utilizzati in tutte leoperazioni di indicizzazione di un array

Page 14: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array e puntatori

La dichiarazione di un array comporta allocazione di memoriadi una variabile puntatore (il nome dell’array), e dell’areapuntata, di lunghezza predefinitail puntatore é dichiarato const e inizializzato con l’indirizzodell’area puntata (cioè del primo elemento dell’array)

Es.: int lista[5];• alloca memoria per il puntatore costante lista;• alloca memoria per 5 valori di tipo int;• inizializza lista con &lista[0]

Page 15: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array e puntatori (1)

Il nome (usato da solo) di un array ha il significato dipuntatore al primo elemento dell’arrayOgni altro elemento é accessibile tramite la deref. delpuntatore-array incrementato di una quantità pariall’indice/offset dell’elemento ovvero le espressioni (dato unarray A):

A[i] e *(A+i)

conducono ad identico risultato anche se sono due formalismi diversi.

Page 16: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array e puntatori (2)

Se A[N] è un array di indirizzo ind,

A[i] il suo elemento i-esimo (i intero),

l’indirizzo di A[i] sarà dato dall’espressione *(ind+i)

Page 17: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

C funzioni à argomenti

passaggio dei parametri per riferimento (per indirizzo): come parametro della funzione viene passato l’indirizzo di una variabile

• L’argomento deve essere di tipo puntatore al tipo del dato su cui si opera

• L’argomento (il suo nome) si comporta come un sinonimo (alias) del corrispondente parametro passato

Record di attivazione

ab

Indirizzo di rientro in foo

r... automatiche

Indirizzo di rientro in main

k...

automatichea2a1 28

12

argomenti

void foo(...) {...k = mcd(&a1,&a2)...

}

funzione chiamante

int mcd(int *a, int *b){int r;...

}

funzione chiamata

main {

Page 18: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Stringhe

In memoria le stringhe sono degli array di tipo char, con unaparticolarità in più, che le fa riconoscere da operatori efunzioni come stringhe e non come normali array:

l’elemento dell’array che segue l’ultimo carattere della stringadeve contenere il carattere NULL o ‘\0’ (detto in questo casoterminatore); si dice pertanto che una stringa é un “array ditipo char null terminated“.

Page 19: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Inizializzazione di variabili stringa

Se nella dichiarazione-inizializzazione si omette ladimensione dell’array, questa viene automaticamente definitadalla lunghezza della costante stringa aumentata di uno, perfar posto al terminatore (in questo caso la stringa non può piùessere “allungata”!):

char Saluto[] = “Ciao”;allocato in memoria array con 5 elementi

Page 20: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Dichiarazione di stringhe

Es.: char MiaVar[30];

Dichiara la variabile MiaVar come array di tipo char con massimo 30elementi. Affinché MiaVar sia identificata (in lettura) da operatori efunzioni come stringa, dobbiamo inserire nell’array una serie dicaratteri terminati da un NULL.

Se vogliamo che MiaVar presenti a operatori e funzioni la stringa“Ciao”, dobbiamo scrivere invece le istruzioni:MiaVar[0]=’C’; MiaVar[1]=’i’;MiaVar[2]=’a’; MiaVar[3]=’o’;MiaVar[4]=’\0’;

impegnando così 5 elementi dell’array dei 30 disponibili (irimanenti 25 saranno ignorati).

Page 21: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Considerazioni

ATTENZIONE:In caso che si creino delle stringhe con un numero di caratteri

(compreso il terminatore) maggiore di quello dichiarato, ilprogramma non produce direttamente messaggi di errore, mainvade zone di memoria non di sua pertinenza, conconseguenze imprevedibili (spesso si verifica un errore fatalea livello di sistema operativo).

Page 22: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

C libreria string.h

La libreria string (string.h) contiene funzioni di manipolazione di stringhe

Prototipo Descrizione

char *strcpy(char *s, char *cs); copia cs in s e ritorna s

char *strcat(char *s, char *cs); concatena cs ad s e ritorna sint strcmp(char *cs1, char *cs2); confronta cs1 e cs2; se cs1 < cs2 il valore di

ritorno è < 0; se cs1 > cs2 il valore di ritorno è > 0; se le due stringhe sono uguali il valore di ritorno è 0

char *strstr(char *cs1, char *cs2); restituisce un puntatore alla prima occorrenza in cs1 della stringa cs2

size_t strlen(char *cs); restituisce la lunghezza di cs

... …

Page 23: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array di puntatori

I puntatori, come qualsiasi altra variabile, possono essereraggruppati in array e dichiarati come:

Es.: int* A[10] ;dichiara un array di 10 puntatori a int

Come il nome di un array equivale a un puntatore, così unarray di puntatori equivale a un puntatore a puntatore (con inpiù l’allocazione della memoria puntata, come nel caso diarray generico)

Page 24: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array di Stringhe

Il caso più frequente di array di puntatori é quello dell’array distringhe, che consente anche l’inizializzazione (atipicamente)delle stringhe che costituiscono l’array

Es.: char* colori[3] = {‘’Blu’’, ‘’Rosso’’, ‘’Verde’’} ;

Le stringhe possono essere di differente lunghezza; inmemoria sono allocate consecutivamente e, sono riservatitanti bytes quant’è la rispettiva lunghezza (terminatorecompreso).

Page 25: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Array di puntatori

suit[4] indica un array di 4 elementichar* suit[4] = {“Heart”, “Diamond”, “Clubs”, “Spades”}

Ogni elemento dell’array è un puntatore ad un char, l’array contiene in realtà soltanto i puntatori al primo carattere di ogni stringa. Pur avendo l’array suitdimensione fissa, si può accedere a stringhe di qualsiasi lunghezza.

Page 26: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

C libreria utilità stringhe

Problema: Data una stringa qualsiasi verificare se è palindromaUna stringa è palindroma quando ha uguali i caratteri che hanno la stessa

distanza dal centro della stringa. Per esempioPalindromi NON palindromiANNA AMARAADA AROMADEOED ODEbaccdccab abcab

detta n la lunghezza della stringa, se è palindroma sarà:s[i]=s[n-1-i] per ogni i=0,…,n-1

Page 27: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Esercizi su funzioni e array

Esercizi: usare le funzioni di utilità per vettori e per stringhe1. Generato in modo random un vettore contenente N interi relativi compresi

tra –M ed M mediante una procedura, risolvere i seguenti problemi :scrivere un programma che stampi tutti i numeri positivi e la loro posizionescrivere un programma che stampi tutti i numeri minori o uguali a zeroscrivere un programma che stampi il più grande ed il più piccolo e le loro

posizioniscrivere un programma che stampi tutti i numeri maggiori di un valore dato

e le posizioniscrivere una procedura che restituisca tutte le posizioni dei numeri negativi

2. Definire una funzione Uguali2 che prenda in input un vettore V di interi di lunghezza n, e restituisca:true se il vettore contiene almeno due numeri uguali, false altrimentiEsempi: Se V=[1,22,13,24,5] allora Uguali2(V) à false

Se invece V=[1,2,6,24,2] è Uguali2(V) à true

Page 28: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Esercizi su funzioni e array

3. Definire una procedura PrecSegueX che abbia in input un vettore V di interi di lunghezza n, ed un numero X, e:inserisca all’inizio di V i valori di V minori o uguali ad X (preservandone

l’ordine);inserisca in seguito tutti i valori di V maggiori di X (preservandone

l’ordine).Esempio: Sia V= [56,35,4,2,22]. L’output di PrecSegueX(V,40) deve

essere: V=[35,4,2,22,56]4. Definire una funzione ContaCifre che prenda in input un vettore V di

interi di lunghezza n, ed un numero X e conti quante volte tutte le cifre di X siano contenute negli elementi che compongono il vettoreEsempio: Siano V=[484,325,12,8489,48,12487,1284] e X=48;

ContaCifre(V,7,48) à 4(sono evidenziati i numeri che contengono al loro “interno” il numero 48).

5. Definire una procedura GoDestra, che, assegnato un vettore V di nelementi ed un intero m, 0£ m £ n, sposti verso destra di m passi tutti gli elementi del vettore VEsempio: Sia V=[7,8,9,0] ed n=4 otteniamo

GoDestra(V,3) fa diventare V=[8,9,0,7]

Page 29: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Esercizi su funzioni e array

6. Scrivere una procedura Comuni, che assegnati due vettori V1, V2 di dimensioni rispettivamente n1 ed n2, ponga in un altro vettore V3 tutti e soli gli elementi di V1 che compaiono anche in V2, conservando l’ordine con cui compaiono in V1Esempio: Siano V1=[1,2,3,4,5], V2=[5,0,3,0,1], V3 qualunque.

Eseguiamo Comuni(V1, V2,V3). Allora V3 diventa [1,3,5]7. Definire una procedura PariDispari che dato un vettore V di interi di

lunghezza n:ponga all’inizio di V i valori di V pari, nello stesso ordine in cui si

trovavano in V;li faccia seguire dai valori di V dispari, di nuovo nello stesso ordine in cui

si trovano in V.Esempio: Sia V= [5,3,4,2,1]. Eseguiamo PariDispari si deve

avere: V = [4,2,5,3,1]8. Scrivere una funzione che dato un array V di interi di dimensione n

restituisce true se nell’array V c’è un valore che è uguale alla somma di tutti i valori che lo precedono, false altrimentiEsempio. V=[1, 4, 4, 9, 3] la funzione restituisce true perché

V[3]=9=1+4+4V=[1,3,5,8,3] la funzione restituisce false

Page 30: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Esercizi su funzioni e array

9. Scrivere una procedura che dati 2 array di interi V1 e V2 di dimensione nrestituisce nell’array V3 gli elementi che appartengono a V1 ma non a V2non ripetuti e in N3 il numero di tali elementiEsempio: V1= [2, 4, 4, 5, 3] e V2= [7, 3 ,10 ,6 ,7] si deve ottenere

V3= [ 2, 4, 5] con N3 =310. Scrivere una funzione che data una stringa s ed un carattere car restituisce

il numero massimo di caratteri car consecutivi presenti nell’arrayEsempio: s = ‘abcaacaaabaa', car=’a’ la funzione deve restituire 3

11. Scrivere una procedura che dato un array a ordinato di dimensione Ninserisce nell’array il valore x in modo tale che l’array dopo l’inserimento sia ancora ordinatoEsempio: Siano a = [2, 3, 7, 11, 24] e x =5 si deve ottenere

a = [2, 3, 5, 7, 11,24 ]

Page 31: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Esercizi su funzioni e array

12. Scrivere un programma che, dati due vettori di interi di dimensione N, ne costruisca un terzo di dimensione 2N i cui elementi di posizione pari siano gli elementi del primo vettore e gli elementi di posizione dispari siano gli elementi del secondo vettore. Strutturare il programma in procedure e funzioni

13. Scrivere un programma che, dato un vettore V1 di reali di dimensione N, ne generi un altro V2 così definito: il primo elemento di V2 è dato dal prodotto degli elementi 1 e 2 di V1, il secondo elemento di V2 è dato dal prodotto degli elementi 3 e 4 di V1, e così via

Page 32: Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni tipo di variabile puntata – Un dato puntatore può puntare solo a un determinato

Esercizi su funzioni e array

14.Scrivere una procedura che genera un vettore V di numeri reali di dimensioni N (N£100). Con tale procedura scrivere un programma che stampi prima tutti gli elementi di posto dispari e poi quelli di posto pari,letto un indice h stampi l’indice ed il valore del più piccolo fra i numeri maggiori di

V[h];stampi l’indice ed il valore dei numeri di valore dispari massimo e minimo;si costruisca e quindi si stampi un secondo array di N elementi tali che il primo

elemento contenga la somma di tutti gli N numeri, il secondo la somma dei numeri dal secondo in poi, il terzo la somma dal terzo in poi e così via;

si stampi l’indice ed il valore dell’elemento massimo fra gli elementi di posto dispari, quindi l’indice ed il valore del minimo fra gli elementi di posto pari;

letto un indice h, si costruisca e quindi si stampi un array di N elementi tali che il primo sia quello specificato dall’indice, il secondo sia quello precedente e così fino al primo, poi proseguendo dall’ultimo retrocedendo fino a completare l’array.

15.Scrivere un programma che prenda in input un vettore già ordinato di interi e stampi in output l’istogramma delle occorrenze di ogni elemento del vettore. Esempio. dato il vettore V=[1,1,1,3,5,5,7,7,7,7,10,10], deve stampare:

1 ***3 *5 **7 ****10 **