In problemi di diversa natura spesso è necessario trattare con tipi di dati strutturati, ovvero una collezione di tipi di dati base. Nel dato strutturato si distingue tra:
Record
Un record o struttura è una struttura dati ottenuta aggregando elementi di tipo diverso detti campi che potrebbero essere anch’essi strutturati.
Esempi.
Complesso
è formato dai due campi di tipo reale.Data
è formato dai tre campi di tipo carattere.Vediamo adesso come sia possibile dichiarare una struttura di tipo record utilizzando il linguaggio di programmazione C.
Bisogna utilizzare una sintassi del tipo:
typedef struct {
t1 s1;
t2 s2;
.........
tn sn;
} nome-tipo;
ovvero un record è definito da un elenco di tipo di dati, i campi, preceduto dalla parola chiave struct
. Le parentesi graffe aperte e chiuse individuano l’inizio e la fine di un record.
Esempio 1. Il record punto nello spazio.
typedef struct
{ float x ;
float y;
float z;
} punto;
Il tipo di dato punto è formato da tre campi di tipo float. Nel programma principale per dichiarare ed allocare una struttura dati di tipo punto è necessaria una dichiarazione del tipo:
punto p;
Esempio 2. Il record data.
typedef struct
{ int giorno;
int mese;
int anno;
} data ;
Il tipo di record data è formato da tre campi di tipo int. Nel programma principale per dichiarare ed allocare una struttura dati di tipo punto è necessaria una dichiarazione del tipo:
data data_esame;
Esempio 2. Il record data.
typedef struct
{ int giorno;
int mese;
int anno;
} data ;
Oppure in maniera equivalente:
struct
{ int giorno;
int mese;
int anno;
} data_esame
Il tipo di record data è formato da tre campi di tipo int. Nel programma principale per dichiarare ed allocare una struttura dati di tipo punto è necessaria una dichiarazione del tipo:
data data_esame;
Il record o struttura è una struttura di dati non omogenei.
Essa è costituita da componenti di tipo differente, inoltre è una struttura ad accesso casuale (random), ovvero è possibile cioè selezionare qualsiasi componente in essa presente.
Ogni componente di un record si chiama campo. Esso deve avere un nome e deve essere associato a un tipo.
Sia x
una variabile di tipo struttura, avente campi:
s1 ... sn
per selezionare (leggere) una sua componente si deve utilizzare l’identificatore della variabile ed il nome del campo separati dal simbolo. ( dot notation )
Se invece si vuole assegnare (scrivere) una sua componente si deve utilizzare l’identificatore della variabile ed il nome del campo separati dal simbolo . Facendo attenzione ad assegnare il tipo di dato appropriato assegnato al rispettivo campo.
La figura riporta come utilizzare la dot notation.
Si supponga di avere a disposizione due struttura dati come in figura. Se si dichiara una variabile del tipo:
studente dati [100];
si ottiene:
dati
è il nome di un vettore di 100 componenti di tipo studentedati [i]
per i che varia da 0 a 99 seleziona la componente i-esima del vettoredati[i].matricola
seleziona il campo matricola della componente dati[i]
dati[i].data_nascita.anno
seleziona il campo anno del campo data_nascita
della componente dati[i]
Si supponga di avere dichiarato due struttura dati:
a e b;
dello stesso tipo. Per assegnare in maniera globale i dati di b a quelli della struttara a basta utilizzare l’istruzione:
a = b;
Riportiamo un esempio di assegnazione globale di strutture in C.
/*dichiarazione delle varibili */
data data_esame, data_odierna;
/* corpo del programma */
...
/*assegnazione globale */
data_esame = data_odierna;
Il linguaggio C prevede tipi di dati non strutturati e strutturati.
Tipi di dati non strutturati.
I 4 tipi base sono char, int, float, double
. Possono essere modificati mediante 4 qualificatori:
short
, per dati di tipo int
, forza la rappresentazione degli interi su 16 bit.long
, per dati di tipo int
e double
, forza la rappresentazione su 32 e 80 bit rispettivamentesigned
e unsigned
, per dati di tipo int
e char
, specificano dati con segno o senza segnoTipi di dati strutturati.
Essi sono generalmente gli array e le stringhe. Altri esempi sono il tipo “enum
” e il tipo “struct
”
Esempio. Si vuole simulare in linguaggio C il tipo di dato booleano.
Soluzione 1. Attraverso una direttiva la preprocessore:
#define TRUE 1
#define FALSE 0
int espressione;
...
if (espressione = = TRUE)
Soluzione 2. Attraverso il tipo di dato strutturato enum
:
enum logical {FALSE, TRUE};
enum logical trovato;
...
if (trovato = = TRUE)
...
Soluzione 3. Attraverso una struttura: typedef enum {FALSE, TRUE} boolean;
boolean trovato;
...
if (trovato = = TRUE)
Il tipo di dato enum:
Questo tipo di dato può essere utilizzato nei seguenti modi:
enum nome_tipo {lista identificatori};
enum nome_tipo variabile;
Nel primo caso si identifica con nome_tipo
la lista dei valori che possono essere assunti.
Nel secondo caso si definisce variabile di tipo enumerativo nome_tipo; variabile
potrà assumere solo i valori precedentemente specificati
enum logical {FALSE, TRUE};
La parola chiave typedef consente di ridefinire il nome di un tipo di dati esistente. La sua sintassi è data da:
typedef tipo_esistente nome_nuovo_tipo;
ESEMPIO. Un programma deve manipolare date nella forma GGMMAA (es. 31 maggio 2000) una possibile organizzazione di questo tipo di dato è:
giorno 31
mese maggio
anno 2000
Questo tipo di dato può essere ottenuto con una STRUTTURA, ossia un insieme di più variabili, anche di tipo diverso,logicamente connesse sotto un singolo nome. In alcuni linguaggi di programmazioni, ad esempio il Pascal questi sono i record. Le strutture:
Per il nostro esempio nel linguaggio C una struttura siffatta viene così dichiarata:
struct data {
int Giorno;
char Mese[9];
int Anno; };
La definizione di una struttura crea un tipo di dato utilizzabile per future dichiarazioni.
In C è possibile dichiarare le strutture nei seguenti modi:
Prima modalità
struct data { /* definizione della struttura data */
int Giorno;
char Mese[9];
int Anno;};
struct data Oggi; /* dichiarazione della
variabile di tipo struct data */
Seconda modalità
struct data { /* definizione della struttura data */
int Giorno;
char Mese[9];
int Anno;} Oggi; /* e dichiarazione della variabile di tipo struct data */
Terza modalità:
struct { /* definizione di una struttura */
int Giorno;
char Mese[9];
int Anno;} Oggi; /* e dichiarazione della variabile di tipo struct data */
Sintatticamente:
struct {……} x; equivale a int x;
Per selezionare gli elementi, detti membri, di una struttura si utilizza:
nomestruttura . nomemembro
Ad esempio: Se Oggi è una variabile di tipo struct data:
Oggi.Giorno
indica il membro Giorno;
Oggi.Mese
indica il membro Mese;
Oggi.Anno
indica il membro Anno.
Le strutture possono essere inizializzate al momento della loro dichiarazione
Esempio 1
struct data Oggi={31, "maggio",2000};
Esempio 2
struct data Oggi;
Oggi.Giorno = 31;
Oggi.Mese = "maggio";
Oggi.Anno = 2000;
Il membro di una struttura può essere a sua volta una struttura.
Esempio
struct persona{
char NomePers[30];
struct {
char Via[30];
int NumCiv;
int CAP;
char Citta[30];} Indirizzo;
double Salario;
struct data NascPers;
struct data AsszPers;};
Se si dichiara Impiegato
come variabile di tipo struct persona
:
Impiegato.NascPers.Mese
è il mese di nascita dell’Impiegato.
Si vuole definire una struttura di tipo studente e sviluppare una funzione che conti i bocciati.
Un programma chiamante delle funzione può essere così abbozzato:
void main()
{
struct studente classe[DIM_CLASSE];
...
}
Ogni operazione possibile sulle strutture può essere eseguita utilizzando i puntatori a strutture
Esempi
struct data *pdata; /*dichiarazione di puntatore a struttura*/
struct data Oggi; /*dichiarazione di istanza di struttura*/
*pdata = Oggi; /*assegna alla struttura puntata da pdata la struttura Oggi */
pdata = &Oggi; /*assegna al puntatore l'indirizzo di Oggi*/
i=(*pdata).Giorno; /*Accesso ai membri di Oggi*/
Per accedere ai membri di una struttura mediante puntatori generalmente si usa la notazione:
pdata ->Giorno
equivalente a (*pdata).Giorno
L’operatore -> è associativo da sinistra a destra:
p ->q->m
equivale a (p->q)->m
Gli operatori (), [], -> sono quelli con precedenza maggiore di tutti gli altri
++p ->x
equivale a ++(p->x)
equivale ad incrementare di 1 il valore del membro x
della struttura puntata da p
Le strutture possono essere passate come argomento a funzioni
Esempio
Se abbiamo una struttura:
struct data {......} Oggi;
La chimamata alla funzione sarà:
in=funz(Oggi, n, ...);
Come per tutti gli altri parametri, il passaggio di una struttura avviene per valore.
Per cui affinché una funzione possa modificare i valori di una struttura occorre passare l’indirizzo della struttura:
in=funz(&Oggi, n, ...);
Le strutture possono essere utilizzate per i valori di ritorno di funzioni. I codici che seguono consentono di costruire un punto a partire dalle sue coordinate inserite come input da un utente.
1. Prolusione
2. Sistemi Operativi – parte prima
3. Sistemi Operativi – parte seconda
6. Il linguaggio C – parte prima
8. Il linguaggio C – funzioni e puntatori
10. Il linguaggio C – parte terza
11. La documentazione del software
12. Dati strutturati
13. Esercizi sui dati strutturati
14. Approfondimenti di C, Stringhe e file
15. Esercizi su stringhe e file
16. La ricorsione
17. Il linguaggio c++ parte prima
18. Il linguaggio C++ - parte seconda
19. Strutture dati di tipo astratto
Collezione di software scientifico (in Inglese)