Introduzione al C Tipi derivati 1
Strutture semplici Una struttura è una collezione di una o più variabili, anche di tipi diversi, raggruppate da un nome struct tag{ struttura_elementi } istanza; struct è usata per dichiarare la struttura tag è il nome dato alla struttura struttura_elementi sono gli elementi della struttura istanza è la reale dichiarazione di un elementostruttura (nome della variabile struttura) 2
Esempi struct data{ char mese[2]; char giorno[2]; char ora[2]; } data_corrente; struct tempo{ int ore; int minuti; int secondi; } tempo_inizio={8,45,0}; 3
Accesso ad un elemento della struttura-esempio Coordinate di uno schermo: struct coord{ int x; int y; } primo,secondo; l operatore. permette di accedere agli elementi della stuttura: primo.x=50; primo.y=100; secondo=primo secondo=primo;/*le strutture permettono di copiare info velocemente velocemente */ 4
Strutture di strutture Gli elementi di una struttura possono essere variabili, array, puntatori o altre strutture In questo esempio si dichiara una struttura che definisce un rettangolo struct rettangolo{ struct coord alto_sx; struct coord basso_dx; } mio_box; mio_box.alto_sx.x=0; mio_box.alto_sx.y=10; mio_box.basso_dx.x=100; mio_box.basso_dx.y=200; 5
Vedi programma STR_OF_STR.cpp per un esempio di utilizzo di strutture di strutture Area di un rettangolo C non mette limiti al numero di strutture annidate, ma raramente sono utili strutture con più di tre livelli di annidamento 6
Array di strutture Si possono definire array i cui elementi sono strutture. Ad es. in un programma che mantiene una lista di numeri telefonici si può definire una struttura per i dati relativi ad una persona: struct entry{ char nome[10]; char cognome[12]; char telefono[8]; }; E poiché una lista ha molte entrate: struct entry lista[1000]; 7
Per assegnare dati di un elemento dell array ad un altro: lista[1]=lista[5]; Spostare dati tra elementi di membri diversi della struttura: lista[1].telefono=lista[5].telefono; Esercizio: scrivere un programma che utilizzi le strutture precedenti per memorizzare, inserire e visualizzare i dati relativi a 4 persone 8
Puntatori e strutture (1) Strutture di puntatori: se confrontate con strutture di array risultano più flessibili. struct msg{ char p1[10]; char *p2; }mio_msg mio_msg; mio_msg.p1[]= minneapolis minneapolis /*eccede la dimensione!!*/ mio_msg.p2= minneapolis minneapolis /*inizializzato a puntare ad una costante stringa!!*/ 9
Puntatori e strutture (2) Puntatori a strutture: struct parte{ int elemento; char nome[10]; }; struct parte *p_str; Il puntatore può essere inizializzato solo dopo che almeno una istanza della struttura sia stata dichiarata. struct parte str; p_str=&str; 10
Si può accedere ad un elemento di una struttura in tre modi: str.elemento (*p_str).elemento p_str->elemento -> è l operatore freccia 11
Per scandire gli elementi di un array di strutture si ricorre all uso dei puntatori. struct parte{ int elemento; char nome[10]; }; struct parte dati[100]; struct parte *p_parte; p_parte=dati; Le successive istruzioni sono equivalenti: p_parte+=sizeof(parte); p_parte++; 12
Due modi: Passare strutture come argomenti di funzioni Passare il nome della struttura Passare l indirizzo della struttura: in questo caso per accedere agli elementi della struttura si deve usare l operatore -> Esercizio: modificare STR_OF_STR.cpp inserendo una funzione che calcola l area del rettangolo (STR2_OF_STR.cpp) 13
Union union tag{ union_elementi } istanza; Una union è dichiarata e usata allo stesso modo di una struttura. Differisce in quanto i suoi elementi possono essere usati solo uno alla volta, poiché occupano la stessa area di memoria (hanno lo stesso indirizzo). Variabili che possono assumere più tipi e/o dimensioni diversi. 14
5000 int i 2 5000 char c x 5000 float f 3,765 15
Liste struct data{ char name[10]; struct data *next; }; Il secondo elemento della struttura è un puntatore al tipo data La struttura include un puntatore al suo proprio tipo 16
puntatore testa nome puntatore nome puntatore nome 0 Le liste permettono di realizzare strutture dinamiche inserimento e cancellazione in lista ordinata spazio in memoria 17
La funzione malloc malloc() struct data *ptr; ptr=(struct data *) malloc(sizeof sizeof(struct struct data)); ptr->value=1.205; 18
Introduzione al C Puntatori di puntatori 19
Puntatori di puntatori Indirizzamento indiretto multiplo puntatore variabile indirizzo valore Riferimento indiretto singolo puntatore indirizzo puntatore indirizzo Riferimento indiretto multiplo variabile valore 20
Puntatori di puntatori Poiché un puntatore è a sua volta una variabile numerica, è memorizzato in una locazione di memoria ad un particolare indirizzo: int x=12; int *ptr = &x; int **ptr_di_ptr= &ptr; printf( %d %d, **ptr_di_ptr); /*quanto vale?*/ 21
Puntatori di puntatori Scrivere una funzione per l allocazione dinamica di memoria int allocme(int *parray) /*sbagliato*/ { parray= malloc(10*sizeof( (10*sizeof(int int)); if (parray==null) return -1; return 0; } main(){ int *pa;... if (allocme allocme(pa pa)!= )!=-1) /*tutto bene!*/... } 22
Puntatore di puntatore int allocme(int **parray) /*corretto!*/ { *parray= malloc(10*sizeof( (10*sizeof(int int)); if (*parray==null) return -1; return 0; } main(){ int *pa;... if (allocme allocme(&pa &pa)!= )!=-1) /*tutto bene!*/... } 23
Array di puntatori **p *p[0] p[0][0] p[0][1] p[0][2] p[0][3] *p[1] p[1][0] p[1][1] p[1][2] p[1][3] *p[2] p[2][0] p[2][1] p[2][2] p[2][3] int **p; p=(int **)malloc(a*sizeof(int *)); for(i=0;i<a;i++) { p[i] =(int *)malloc(b*sizeof(int)); for(j=0;j<b;j++) p[i][j]=i+j; } 24
Esempio Un programma che costruisce dinamicamente una matrice rettangolare con a righe e b colonne tale che il j-esimo elemento della i-esima riga della matrice deve contenere i+j se i j, altrimenti i j. Esercizio: Scrivere una funzione che, dato un vettore di dimensione n di puntatori a liste di valori interi non negativi minori di n (non ripetuti) con la proprietà che se la k-esima lista contiene l intero j, allora la j-esima lista contiene l intero k, presi come parametri il vettore, e un intero k<n, elimina k da tutte le liste. Nota che la proprietà precedente permette di conoscere quali liste contengono k. 25
Introduzione al C Visibilità di una funzione 26
Scope di una variabile Il termine scope riferito a variabili C significa: Quali parti del programma possono accedere ad una variabile (accessibilità) e dove la variabile è visibile (visibilità) in questo caso interscambiabili Quanto a lungo la variabile persiste in memoria (classe di memoria) 27
Abbiamo già visto la distinzione tra variabili locali (definite dentro la funzione) e variabili globali (definite esternamente alla funzione), quando il programma è costituito da un file lezione 3, vedi demo.cpp Un programma complesso generalmente è costituito da più file 28
Importanza dello scope L importanza dello scope è direttamente collegata alla richiesta di modularità dei programmi. Programmi divisi in funzioni indipendenti ciascuna delle quali con uno specifico compito. L indipendenza è realizzata rendendo le variabili di ciascuna funzione libere dall interferenza causata da altre funzioni. Ma non sempre l isolamento completo dei dati tra funzioni è desiderabile 29
Variabili globali Una variabile globale non esplicitamente inizializzata, viene inizializzata a 0 dal compilatore Il suo scope è l intero programma (Bisogna fare delle precisazioni nel caso in cui il programma è composto da diversi file sorgenti) Quando usare variabili globali? Quando quasi tutte le funzioni del programma usano la variabile 30
Parola chiave: extern dichiarare una variabile globale come extern nelle funzioni che la utilizzano extern extern informa il compilatore che la definizione del simbolo dichiarato extern è presente in un altro file Nota la differenza tra la definizione di una variabile ( mette da parte memoria per la variabile) e la dichiarazione extern 31
32
Variabili locali non è automaticamente inizializzata a 0 dal compilatore Il suo scope è la funzione dove è definita (locale) Distinzione in base alla classe di memoria: Ogni variabile locale è automatica, cioè non mantiene il suo valore tra chiamate alla funzione (è indefinita) Attenzione: se la variabile locale è definita in un blocco della funzione essa è locale al blocco Le variabili automatiche sono allocate nello stack 33
Parola chiave :static Se si vuole che una variabile locale mantenga il suo valore tra chiamate, questa deve essere definita static (o non automatica) Quando può essere utile? ad es. funzione che stampa ha necessità di ricordarsi quante righe ha già stampato, per determinare quando serve una nuova pagina Ovviamente, non c è differenza tra variabili locali statiche e automatiche nel main() Vedi programma uso_static 34
Scope dei parametri di una funzione La lista di parametri nell intestazione di una funzione ha scope locale Non ha senso pensare ad essi come se fossero static o auto 35
static per variabili globali Un altro possibile uso della parola chiave static : se vogliamo che una variabile globale (cioè dichiarata fuori da una funzione) sia visibile solo alle funzioni contenute nello stesso file di dichiarazione, essa deve essere definita static 36
Variabili register La parola chiave register chiede al compilatore di memorizzare una variabile locale automatica in un registro del processore Non può essere usata per array e strutture Quando è utile? Variabili utilizzate frequentemente da una funzione come ad es. contatori per un ciclo 37
Classe di memoria Parola chiave Vita Dove definita Scope Automatica Temporanea In una funzione Locale statica static Temporanea In una funzione Locale registro register Temporanea In una funzione Locale esterna permanente Fuori da una funzione Globale (tutti i file) esterna static permanente Fuori da una funzione Globale (un file) 38
Linee guida Per iniziare, assegna ad ogni variabile la classe di memoria locale automatica Se la variabile deve essere manipolata frequentemente, aggiungi alla definizione register In funzioni diverse dal main(), rendi una variabile static se deve mantenere il suo valore tra chiamate successive alla funzione Se una funzione è usata da tutti o la maggior parte dei programmi, definisci la variabile con la classe di memoria esterna 39