Aggregati di dati eterogenei: il tipo...

82
Aggregati di dati eterogenei: il tipo struct

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