Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni...
Transcript of Sono variabili il cui valore corrisponde ad un indirizzo ... · • Esistono puntatori per ogni...
Sono variabili il cui valore corrisponde ad un indirizzo di memoria
Puntatori
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
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)
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)
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
L’operatore di dereferenziazione *
Consideriamo
int y=5;int *yPtr;yPtr = &y;
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 (==, !=)
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
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
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
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
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
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
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]
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.
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)
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 {
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“.
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
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).
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).
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
... …
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)
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).
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.
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
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
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]
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
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 ]
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
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 **