Aggregati di dati eterogenei: il tipo...
Transcript of Aggregati di dati eterogenei: il tipo...
-
Aggregati di dati eterogenei: il tipo struct
-
5
Definizione di tipi e variabili struct
Introduzione agli aggregati eterogeneiDefinizione di un tipo structVariabili struct
-
Definizione di tipi e variabili struct
-
7
Perché dati eterogenei ?
Sono frequenti le informazioni composte da parti di tipo diverso (es.: dati studente)
Rossicognome Marionome
123456matricola
27.25media
-
8
matricola: 123456 media: 27.25nome: Mario
Aggregato di dati eterogenei
Più informazioni eterogenee possono essere unite come parti (campi) di uno stesso dato dato (aggregato)
cognome: Rossi
studente
-
9
I tipi struct
Il dato aggregato in C è detto struct. In altri linguaggi si parla di recordUna struct (struttura) è un dato costituito da campi
I campi sono di tipi (base) noti (eventualmente altre struct)Ogni campo all’interno di una struct èaccessibile mediante un identificatore (anziché un indice, come nei vettori)
-
Definizione di tipi e variabili struct
-
11
Come creare un tipo struct
Definire un tipo struct corrisponde a creare un nuovo tipo di dato, caratterizzato da
Parola chiave structUn nome (un identificatore) unico Es. struct studente
I campi di una struct sono definiti alla stregua di variabili locali alla structLe struct sono di solito dichiarate nell’intestazione di un file sorgente CIl nuovo tipo definito potrà essere utilizzato per dichiarare variabili o campi di altre strutture
-
12
Un esempio di tipo struct
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};
-
13
Un esempio di tipo struct
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};
• Il nuovo tipo definito è struct studente• La parola chiave struct è obligatoria• Il nuovo tipo definito è struct studente• La parola chiave struct è obligatoria
Nuovo tipo di dato
-
14
Un esempio di tipo struct
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};
• Stesse regole che valgono per i nomi delle variabili• I nomi di struct devono essere diversi da nomi di altre
struct (possono essere uguali a nomi di variabili)
• Stesse regole che valgono per i nomi delle variabili• I nomi di struct devono essere diversi da nomi di altre
struct (possono essere uguali a nomi di variabili)
Nuovo tipo di dato
Nome del tipo aggregato
-
15
• I campi corrispondono a variabili locali di una struct• Ogni campo è quindi caratterizzato da un tipo (base) e
da un identificatore (unico per la struttura)
• I campi corrispondono a variabili locali di una struct• Ogni campo è quindi caratterizzato da un tipo (base) e
da un identificatore (unico per la struttura)
Un esempio di tipo struct
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};
Nuovo tipo di dato
Nome del tipo aggregato
Campi (eterogenei)
-
Definizione di tipi e variabili struct
-
17
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};...struct studente s, t;
Dichiarazione di variabili struct
Dichiarazione delle variabili s e t di tipo struct studente
-
18
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};...struct studente s, t;
Schemi di dichiarazione alternativi (1/5)
1. Schema proposto
-
19
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
} s, t;
Schemi di dichiarazione alternativi (2/5)
2. Dichiarazione/definizione contestuale di tipo struct e variabili
Tipo struct e variabili vanno definiti nello stesso contesto (globale o locale)
-
20
Schemi di dichiarazione alternativi (3/5)
3. (uso raro) Dichiarazione/definizione contestuale di tipo struct (senza identificatore) e variabili
Il tipo struct viene utilizzato unicamente per le variabili definite contestualmenteNON si possono definire variabili dello stesso tipo in altre istruzioni dichiarative o in funzioni
struct{
char cognome[MAX], nome[MAX];int matricola;float media;
} s, t;
-
21
typedef struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
} Studente;...Studente s, t;
Schemi di dichiarazione alternativi (4/5)
4. Sinonimo di struct studente introdotto mediante typedef
-
22
typedef struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
} Studente;...Studente s, t;
Schemi di dichiarazione alternativi (5/5)
5. Sinonimo introdotto mediante typedef: variante senza identificatore di struct
Identificatore inutilizzato
-
23
Schemi di dichiarazione alternativi (5/5)
5. Sinonimo introdotto mediante typedef: variante senza identificatore di struct
typedef struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
} Studente;...Studente s, t;
Identificatore inutilizzato
-
24
Schemi di dichiarazione alternativi (5/5)
5. Sinonimo introdotto mediante typedef: variante senza identificatore di struct
typedef struct{
char cognome[MAX], nome[MAX];int matricola;float media;
} Studente;...Studente s, t;
-
25
struct data {int g, m, a;
};struct studente {
char cognome[MAX], nome[MAX];int matricola;float media; struct data dataDiNascita;
};
Strutture annidate
Una struttura può includerne una o più altre come campi
-
26
Uso di variabili struct
Si accede ai singoli campi di una variabile structcome a singole variabili, con la notazione: .
Sono possibili assegnazioni (globali) tra strutture
struct studente s, t;...scanf (“%s%s”,s.cognome,s.nome);scanf (“%d”,&s.matricola);scanf (“%f”,&s.media);t = s;...
-
27
Esempio (1/4)
struct studente{
char cognome[MAX], nome[MAX];int matricola;float media;
};
int main(void){struct studente s, t, tmp;. . .
-
28
Esempio (2/4)
. . .
int main(void){struct studente s, t, tmp;
printf(“dati studente: “);scanf (“%s%s”,s.cognome,s.nome);scanf (“%d”,&s.matricola);scanf (“%f”,&s.media);
-
29
Esempio (3/4)
. . .printf(“dati studente: “);scanf (“%s%s”,t.cognome,t.nome);scanf (“%d”,&t.matricola);scanf (“%f”,&t.media);if (s.media < t.media){tmp=s; s=t; t=tmp;
}
-
30
Esempio (4/4)
. . .
printf(“studenti ordinati ”);printf(“secondo media decrescente\n”);
printf(“%s %s ”, s.cognome, s.nome);printf(“%d %f\n”, s.matricola, s.media);
printf(“%s %s ”, t.cognome, t.nome);printf(“%d %f\n”, t.matricola, t.media);
}
-
31
Inizializzazione di variabili struct
Una struct può essere inizializzatanell’istruzione di dichiarazione (come i vettori), mediante elenco esplicito di valoriAssegnazione compatta, non ammessa altrove!
struct studente s = {”Rossi”,”Mario”,123456,27.25
};
-
32
Assegnazione errata
La notazione proposta (compatta) NON èammessa in una qualunque assegnazione
struct studente s;...s = {
”Rossi”,”Mario”,123456,27.25
};
-
33
struct studente s;...s = {
”Rossi”,”Mario”,123456,27.25
};
Assegnazione errata
La notazione proposta (compatta) NON èammessa in una qualunque assegnazione
-
34
Assegnazione corretta
Per inizializzare i campi al di fuori della dichiarazione, sono necessarie assegnazioni ai singoli campi
struct studente s;...strcpy (s.cognome,”Rossi”);strcpy (s.nome,”Mario”);s.matricola = 123456;s.media = 27.25;
-
Aggregati di dati eterogenei: il tipo struct
-
2
Utilizzo avanzato dei tipi struct
struct e funzionistruct e vettori
-
Utilizzo avanzato dei tipi struct
-
4
Parametri struct
Una struct puo essere Passata come parametro a una funzioneRitornata come risultato da una funzione
Il passaggio di parametri avviene “by value”(per valore)Una struct (dato aggregato) rappresenta quindi uno strumento per passare ad una funzione più dati in un unico parametro, o per restituire più risultati
-
5
Esempio (1/2)
void stampaStudente(struct studente s){printf(“%s %s ”, s.cognome, s.nome);printf(“%d %f\n”, s.matricola, s.media);
}struct studente leggiStudente(void){struct studente x;printf(“dati studente: “);scanf (“%s%s”,x.cognome,x.nome);scanf (“%d”,&x.matricola);scanf (“%f”,&x.media);return x;
}
-
6
void stampaStudente(struct studente s){printf(“%s %s ”, s.cognome, s.nome);printf(“%d %f\n”, s.matricola, s.media);
}struct studente leggiStudente(void){struct studente x;printf(“dati studente: “);scanf (“%s%s”,x.cognome,x.nome);scanf (“%d”,&x.matricola);scanf (“%f”,&x.media);return x;
}
Esempio (1/2)
Funzione che stampa i dati relativi a uno studente, ricevuto come parametro
(per valore)
-
7
void stampaStudente(struct studente s){printf(“%s %s”, s.cognome, s.nome);printf(“%d %f\n”, s.matricola, s.media);
}struct studente leggiStudente(void){struct studente x;printf(“dati studente: “);scanf (“%s%s”,x.cognome,x.nome);scanf (“%d”,&x.matricola);scanf (“%f”,&x.media);return x;
}
Esempio (1/2)
Funzione che restituisce una struttura, dopo averne acquisito i
dati in input
-
8
Esempio (2/2)
int main(void){struct studente s, t, tmp;
s = leggiStudente();t = leggiStudente();if (s.media < t.media){tmp=s; s=t; t=tmp;
}printf(“studenti ordinati ”);printf(“secondo media decrescente\n”);stampaStudente(s);stampaStudente(t);
}
-
Utilizzo avanzato dei tipi struct
-
10
struct e vettori a confronto
Analogia Sono entrambi tipi di dati aggregati
DifferenzeDati eterogenei (struct) / omogenei (vettori)Accesso per nome (struct) / indice (vettori)Parametri per valore (struct) / per riferimento (vettori)Accesso parametrizzato non ammesso (struct) / ammesso (vettori)
-
11
Accesso parametrizzato a vettori
I vettori sono frequentemente utilizzati per accesso parametrizzato a dati numerati (es. in costrutti iterativi)
for (i=0; i
-
12
Accesso parametrizzato a struct (1/3)
Ai campi di una struct NON si può accedere in modo parametrizzato
char campo[20];...scanf(“%s”,campo);printf(“%s”,s.campo);
Errore !
-
13
char campo[20];...scanf(“%s”,campo);printf(“%s”,s.campo);
Accesso parametrizzato a struct (1/3)
Ai campi di una struct NON si può accedere in modo parametrizzato
campo è una variabile !
Errore !
-
14
Accesso parametrizzato a struct (2/3)
Soluzione: utilizzare una funzione (da realizzare) per il passaggio da identificatore (variabile) di campo a struttura
char campo[20];...scanf(“%s”,campo);stampaCampo(s,campo);
-
15
Accesso parametrizzato a struct (3/3)
void stampaCampo(struct studente s, char id[])
{if (strcmp(id,”cognome”)==0)printf(“%s”,s.cognome);
else if(strcmp(id,”nome”)==0)printf(“%s”,s.nome);
else if(strcmp(id,”matricola”)==0)printf(“%d”,s.matricola);
...}
-
16
Vettori come campi di struct
Una struct può avere uno o più vettori come campiEsempio: cognome e nome in struct studente
Attenzione!Una struct viene passata per valore a una funzione, mentre un vettore sarebbe passato per riferimentoSe una struct ha come campo un vettore di MOLTI elementi, passare la struct come parametro richiede molto tempo (per copiare dati)
-
17
Vettori di struct
Un vettore di struct può essere la soluzione migliore, come struttura dati, nei casi di collezioni (numerabili) di aggregati eterogenei
Esempio: gestione di un elenco di studenti
Attenzione!Una vettore (anche se di struct) viene passato per riferimento a una funzioneUna funzione può quindi modificare il contenuto di un vettore (ad esempio ordinare i dati)
-
18
Vettori di struct: esempio
int main(void){struct studente elenco[NMAX];int i, n;
printf(“quanti studenti(max %d)? ”,NMAX);scanf(“%d”,&n);for (i=0; i
-
Aggregati di dati eterogenei: il tipo struct
-
2
Esercizi proposti
Esercizio “Archivio studenti”Esercizio “Punti del piano”
-
Esercizi proposti
-
4
Esercizio “Archivio studenti”
Gestione di un archivio di studenti. Per ciascunostudente l’archivio memorizza: cognome e nome(stringhe prive di spazi), numero di matricola(intero) e votazione media degli esami sostenuti(reale)Il programma effettua le seguenti operazioni:
Lettura (da file) dei dati relativi a tutti gli studenti(la prima riga del file contiene il numero di studenti, al massimo 100)Ordinamento dei dati secondo media decrescenteScrittura dei dati, nell’ordine ottenuto, su file
-
5
Struttura dati (1/2)
Vettore di struct studenteIl vettore è necessario in quanto occorre ordinare i dati. Non è infatti possibile operare sui singoli dati, secondo lo schema (input – manipolazione –output)La dimensione del vettore è 100 (numero massimo di studenti previsto). Il numero effettivo di dati èacquisito dal file in ingresso
-
6
Struttura dati (2/2)
Formato dei fileStesso formato per file di ingresso e uscita. I dati relativi a uno studente sono
Output: su una sola rigaInput: possono essere su più righe, in quanto, usando fscanf(f, "%s%s%d%f“, …), spazi e a-capo sono equivalenti
-
7
Analisi
Algoritmo: si segue lo schemaInput dei dati (tutti) da file a vettoreOrdinamento del vettoreOutput dei dati da vettore a file
Funzioni (scomposizione del programma in sotto-programmi)
Il programma principale (main) non vede i nédettagli di I/O relative ai singoli dati, nél’ordinamentoSottoprogrammi: inputStudente, outputStudente, ordinaStudenti
-
8
Archivio studenti (1/5)
#define NMAX 100#define MAXRIGA 30struct studente {
char cognome[MAXRIGA], nome[MAXRIGA];int matricola; float media;
};...int main(void){
char nomefile[MAXRIGA];FILE *fp;...printf(“nome file in ingresso: “);scanf(“%s”, nomefile);fp = fopen(nomefile,”r”);fscanf(fp, “%d”, &n);...
}
studenti.c
-
9
Archivio studenti (2/5)
...struct studente inputStudente(FILE *f);void ordinaStudenti(
struct studente el[],int n);...int main(void){
...struct studente elenco[NMAX];int i, n;...for (i=0; i
-
10
Archivio studenti (3/5)
...void outputStudente(struct studente s, FILE *f);...int main(void){
...printf(“nome file in uscita: “);scanf(“%s”, nomefile);fp = fopen(nomefile,”w”);fprintf(f, “%d\n”, n);for (i=0; i
-
11
Archivio studenti (4/5)
struct studente inputStudente(FILE *f){struct studente x;fscanf (f,“%s%s%d%f”,x.cognome,x.nome,
&x.matricola,&x.media);return x;
}void outputStudente(struct studente s, FILE *f)
{fprintf(f, “%s %s %d %f\n”, s.cognome, s.nome, s.matricola, s.media);
}
-
12
Archivio studenti (5/5)
/* ordinamento per media decrescentemediante algoritmo di selection sort */
void ordinaStudenti(struct studente el[],int n){
int i, j, max;struct studente tmp;
for (i=0; i
-
Esercizi proposti
-
14
Esercizio “Punti del piano” (1/2)
Data una struct che rappresenta un punto nelpiano cartesiano a due dimensioni:typedef struct point {
double x; double y;
} Point;
Scrivere le seguenti funzioni che operano suoggetti di tipo Point:
double distanzaDaOrigine (Point p);
double distanza (Point p1, Point p2);
int quadrante (Point p); /* in qualequadrante si trova il punto */
-
15
Esercizio “Punti del piano” (2/2)
Scrivere un programma principale che, ricevuta in input, da tastiera, una sequenza di punti (di numero non noto a priori, la sequenza termina ripetendo due volte lo stesso punto), calcoli
La lunghezza della spezzata definita dalla sequenza di puntiLa media aritmetica delle distanze dei punti dall’origineIl numero di punti presenti in ognuno dei quadranti
-
16
Funzioni
double distanzaDaOrigine (Point p){
return sqrt(p.x*p.x + p.y*p.y);}double distanza (Point p1, Point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x) +(p1.y-p2.y)*(p1.y-p2.y));
}int quadrante (Point p){
if (p.x >= 0 && p.y >= 0) return 1;if (p.x < 0 && p.y >= 0) return 2;if (p.x 0 && p.y < 0) return 4;
}
punti.c
-
17
Funzioni
double distanzaDaOrigine (Point p){
return sqrt(p.x*p.x + p.y*p.y);}double distanza (Point p1, Point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x) +(p1.y-p2.y)*(p1.y-p2.y));
}int quadrante (Point p){
if (p.x >= 0 && p.y >= 0) return 1;if (p.x < 0 && p.y >= 0) return 2;if (p.x 0 && p.y < 0) return 4;
}
punti.cI quadranti sono numerati da 1 a 4. I punti sugli assi sono arbitrariamente assegnati dando precedenza al quadrante di numero inferiore
-
18
Programma principale: struttura dati (1/2)
Non è necessario un vettore di punti. Il problema può essere risolto utilizzando i punti man mano che vengono acquisiti
2 variabili di tipo Point (p, p0)E’ necessario conoscere il punto appena acquisito e il precedente, per individuare la fine dei dati
-
19
Programma principale: struttura dati (2/2)
2 variabili float (lungh, sommaDist)Per lunghezza della spezzata e per somma/media delle distanze dall’origine
4 contatori di punti (uno per quadrante) e uno globale
Soluzione: vettore di 4 interi (q) e intero (np)
-
20
Programma principale: analisi (1/2)
InizializzazioniIterazione controllata da confronto tra gli ultimi due dati, nella quale si eseguono
Input di un puntoAggiornamento di lungh e sommaDist, mediante calcolo delle distanze
Dall’origineDal punto precedente
-
21
Programma principale: analisi (2/2)
NOTA: Il primo e l’ultimo punto vanno gestiti in modo particolare
Il primo non ha predecessoreL’ultimo (indica fine dati) non va conteggiato
Output finale dei risultati
-
22
Punti del piano: main (1/2)
int main(void){
Point p, p0;double lungh=0.0, sommaDist=0.0;int q[4] = {0,0,0,0}, np=0, i;
printf(“sequenza di punti\n”);printf(“(punto ripetuto = FINE)\n”); );/* input primi 2 dati */scanf(“%lf%lf”, &p0.x, &p0.y); scanf(“%lf%lf”, &p.x, &p.y);/* gestione primo punto */sommaDist += distanzaDaOrigine(p0);q[quadrante(p0)-1]++; np++;
punti.c
-
23
Punti del piano: main (2/2)
int main(void){
...while (p.x!=p0.x || p.y!=p0.y) {
lungh += distanza(p,p0);sommaDist += distanzaDaOrigine(p);q[quadrante(p)-1]++; np++;p0 = p; scanf(“%lf%lf”, &p.x, &p.y);
}printf(“spezzata: %lf\n”, lungh);printf(“media: %lf\n”, sommaDist/np);for (i=0; i
-
24
Esempio di esecuzione
sequenza di punti(punto ripetuto = FINE)1.0 1.0-2.0 1.0-0.5 0.0-0.4 -0.32.5 -2.22.5 -2.2spezzata: 8.585991media: 1.596089pt. in q. 1: 1pt. in q. 2: 2pt. in q. 3: 1pt. in q. 4: 1
-
Aggregati di dati eterogenei: il tipo struct
-
2
Argomenti trattati
Definizione di tipi e variabili structGli aggregati eterogeneiDefinizione di tipi e variabili structUso di variabili struct
Utilizzo avanzato dei tipi structstruct e funzionistruct e vettori
-
3
Tecniche di programmazione
Gestione di dati eterogenei, articolati in campiStili di definizione di un tipo structAggregati come parametri e valori di ritorno di funzioniArchivi di dati eterogenei
-
4
Suggerimenti (1/2)
Utilizzare struct, anziché variabili separate, ogniqualvolta si gestiscano più informazioni (eterogenee) che caratterizzano una stessa informazioneVantaggi
Maggior chiarezza e rappresentazione gerarchica dei dati E’ possibile assegnare (o passare a/da una funzione) tutte le parti di un aggregato in un unico dato
-
5
Suggerimenti (2/2)
Uniformare lo stile di definizione di structtypedef struct… è lo stile più frequente, in quanto più compatto (non richiede di usare ulteriormente la parola chiave struct)struct… (meno frequente) viene utilizzato per evidenziare in modo più esplicito che si tratta di un tipo aggregato.
-
6
Materiale aggiuntivo
Sul CD-ROMTesti e soluzioni degli esercizi trattati nei lucidiScheda sinteticaEsercizi risoltiEsercizi proposti
Esercizi proposti da altri libri di testo
-
Programmazione in C
-
2
Aggregati di dati eterogenei: il tipo struct
Definizione di tipi e variabili structUtilizzo avanzato dei tipi structEsercizi propostiSommario
-
3
Riferimenti al materiale
TestiKernighan & Ritchie: capitolo 6Cabodi, Quer, Sonza Reorda: capitolo 9Dietel & Dietel: capitolo 10
DispenseScheda: “Il tipo struct”
L1.1_v8.pptDefinizione di tipi e variabili structPerché dati eterogenei ? Aggregato di dati eterogeneiI tipi struct Come creare un tipo structUn esempio di tipo structUn esempio di tipo structUn esempio di tipo structUn esempio di tipo structDichiarazione di variabili structSchemi di dichiarazione alternativi (1/5)Schemi di dichiarazione alternativi (2/5)Schemi di dichiarazione alternativi (3/5)Schemi di dichiarazione alternativi (4/5)Schemi di dichiarazione alternativi (5/5)Schemi di dichiarazione alternativi (5/5)Schemi di dichiarazione alternativi (5/5)Strutture annidateUso di variabili struct Esempio (1/4)Esempio (2/4)Esempio (3/4)Esempio (4/4)Inizializzazione di variabili struct Assegnazione errataAssegnazione errataAssegnazione corretta
L1.2_v7.pptUtilizzo avanzato dei tipi structParametri structEsempio (1/2)Esempio (1/2)Esempio (1/2)Esempio (2/2)struct e vettori a confrontoAccesso parametrizzato a vettoriAccesso parametrizzato a struct (1/3)Accesso parametrizzato a struct (1/3)Accesso parametrizzato a struct (2/3)Accesso parametrizzato a struct (3/3) Vettori come campi di structVettori di structVettori di struct: esempio
L1.3_v8.pptEsercizi propostiEsercizio “Archivio studenti”Struttura dati (1/2)Struttura dati (2/2)AnalisiArchivio studenti (1/5)Archivio studenti (2/5)Archivio studenti (3/5)Archivio studenti (4/5)Archivio studenti (5/5)Esercizio “Punti del piano” (1/2) Esercizio “Punti del piano” (2/2)FunzioniFunzioniProgramma principale: struttura dati (1/2)Programma principale: struttura dati (2/2)Programma principale: analisi (1/2)Programma principale: analisi (2/2)Punti del piano: main (1/2)Punti del piano: main (2/2)Esempio di esecuzione
L1.4_v3.pptArgomenti trattatiTecniche di programmazioneSuggerimenti (1/2)Suggerimenti (2/2)Materiale aggiuntivo
L1.0_v5.pptAggregati di dati eterogenei: il tipo structRiferimenti al materiale