Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Tipi strutturati
Tipi strutturati
• I tipi considerati finora hanno la caratteristica comune di
non essere strutturati: ogni elemento è una singola
entità.
© Piero Demichelis 2
Tipi strutturati
• I linguaggi ad alto livello permettono di ovviare a questo
inconveniente con i tipi strutturati, caratterizzati sia dal
tipo dei loro componenti che dai legami strutturali tra i
componenti stessi, cioè dal metodo di strutturazione.
© Piero Demichelis 3
Vettori
• Il vettore è una collezione di variabili tutte dello stesso
tipo (detto appunto tipo base) di lunghezza prefissata.
© Piero Demichelis 4
Vettori
• L'intervallo dei valori assunti dall'indice determina la
dimensione del vettore, che deve essere limitata.
© Piero Demichelis 6
Vettori
• Esempi di definizioni di vettore:
#define NUM_MATERIE 20
char s[8];
double giornate[167];
int voti_ottenuti[NUM_MATERIE];
© Piero Demichelis 7
Inizializzazione di un vettore
• E’ possibile assegnare un valore iniziale ad un vettore al
momento della sua definizione.
• Esempio:
int lista[4] = { 2, 0, -1, 5 };
© Piero Demichelis 8
Inizializzazione di un vettore
• NOTA: se vengono specificati meno di N elementi,
l’inizializzazione comincia comunque a partire dal primo
valore e lascia non assegnati i rimanenti.
• Esempi:
© Piero Demichelis 9
Vettori e indici
• L’indice, che definisce la posizione di un elemento di un
vettore, DEVE essere rigorosamente un intero!
• Esempio:
vett_x = vett_y;
© Piero Demichelis 12
Vettori
• Esempio: copia il vettore vett_iniz nel vettore vett_fin
#include <stdio.h>
#define NUMDATI 5
main()
{
for (indice = 0; indice < NUMDATI; indice++)
vett_fin[indice] = vett_iniz[indice];
}
© Piero Demichelis 13
Vettori
• Sugli elementi del vettore agiscono gli operatori previsti
per il tipo_componente. Pertanto è lecito scrivere:
© Piero Demichelis 14
Esempio
• Leggere 10 valori da tastiera e memorizzarli in un vettore;
quindi calcolarne il minimo ed il massimo.
• Pseudocodice:
- Con un indice ind che varia tra 0 e 9:
•legge un dato e lo salva in vettdati[ind];
- Inizializzo la variabile massimo e la variabile minimo col primo
elemento del vettore vettdati[0];
- Con un indice ind che varia tra 1 e 9:
• se vettdati[ind] è più grande di massimo:
massimo vettdati[ind];
altrimenti se vettdati[ind] è più piccolo di minimo:
minimo vettdati[ind];
- Visualizza massimo e minimo
© Piero Demichelis 15
Esempio
#include <stdio.h>
#define NUMDATI 10
main()
{
int minimo, massimo, ind;
int vettdati[NUMDATI];
© Piero Demichelis 17
Esempio
• Scrivere un programma che legga un numero decimale
positivo minore di 1024 e lo converta nella corrispondente
codifica binaria.
• Analisi
© Piero Demichelis 18
Esempio
Analisi (continua):
I resti ottenuti dalle divisioni per 2 vanno però letti al contrario,
conviene pertanto riempire il vettore a partire dall’ultimo
elemento.
© Piero Demichelis 19
Esempio (con while)
#include <stdio.h>
main()
{
int ind, numero, num;
int binario[10];
© Piero Demichelis 20
Esempio (con while)
if ((numero >= 0) && (numero < 1024))
{
num = numero; /* num è il “dato-guida” del ciclo */
ind = 9;
while (num != 0) /* finché num è diverso da 0! */
{
binario[ind] = num % 2; /* calcola un nuovo bit */
num /= 2; /* aggiorna num per il prossimo ciclo */
ind--; /* aggiorna l’indice del vettore */
}
printf ("\nConversione del numero %d: ", numero);
for (ind=0; ind<10; ind++) /* Visualizza il vettore: */
printf ("%1d",binario[ind]); /* un bit per volta */
}
else
printf (“\nNumero non lecito!”);
}
© Piero Demichelis 21
Esempio (con for)
#include <stdio.h>
main()
{
int ind, numero, num;
int binario[10];
© Piero Demichelis 22
Esempio (con for)
if ((numero >= 0) && (numero < 1024))
{
num = numero;
for (ind = 9; ind >= 0; ind--) /* con un indice che va da 9 a 0 */
{
binario[ind] = num % 2; /* calcola un nuovo bit */
num /= 2; /* aggiorna num per il prossimo ciclo */
}
printf ("\nConversione del numero %d: ", numero);
for (ind = 0; ind < 10; ind++) /* Visualizza il vettore: */
printf ("%1d",binario[ind]); /* un bit per volta! */
}
else
printf (“\nNumero non lecito!”);
}
© Piero Demichelis 23
Vettori
• Quando si definisce un vettore il compilatore riserva
un’area di memoria sufficiente per contenerlo e associa
l'indirizzo iniziale di quell'area al nome simbolico
(identificatore) da noi scelto per il vettore.
voti_ottenuti = voti_semestre;
© Piero Demichelis 24
Vettori multidimensionali
• Il concetto di vettore come collezione di elementi
consecutivi, può essere esteso immaginando che gli
elementi siano a loro volta dei vettori: si ottiene così un
vettore multidimensionale o matrice.
Esempio:
matrice bidimensionale di numeri interi formata da tre
righe e 5 colonne:
int a[3][5];
© Piero Demichelis 26
Vettori multidimensionali
• Accesso ad un elemento:
<nome vettore> [<posizione1>] [<posizione2>].............
• Per esempio
matrix [10][20][15]
individua l'elemento di coordinate rispettivamente 10, 20 e 15 nella
matrice a 3 dimensioni matrix.
© Piero Demichelis 27
Vettori multidimensionali e cicli
• Per un vettore a più dimensioni, la scansione va applicata
a tutte le dimensioni: in questo caso si devono in genere
utilizzare “cicli annidati ”.
© Piero Demichelis 28
Stringhe
Vettori di caratteri: le stringhe
• Le variabili di tipo char possono contenere un solo
carattere: per trattare sequenze di caratteri come nomi
o, più in generale, testi il C prevede le stringhe.
© Piero Demichelis 30
Vettori di caratteri: le stringhe
• Il C prevede per le stringhe un vettore di caratteri, il
quale deve quindi avere una lunghezza massima
prefissata.
© Piero Demichelis 31
Stringhe
• Esempio:
‘C’ ‘i’ ‘a’ ‘o’ ‘!’ ‘\0’
const char s[6] = “Ciao!”; s[0] s[1] s[2] s[3] s[4] s[5]
• Il vettore può essere definito più lungo, con gli ultimi elementi
indefiniti, ma non più corto.
‘\0’
char s[] = “”;
s[0]
© Piero Demichelis 32
Stringhe
• Per la definizione di una stringa si può anche utilizzare la
direttiva define:
l u n e d ì \0 giorni[0]
m a r t e d ì \0 giorni[1]
m e r c o l e d ì \0 giorni[2]
g i o v e d ì \0 giorni[3]
v e n e r d ì \0 giorni[4]
s a b a t o \0 giorni[5]
d o m e n i c a \0 giorni[6]
© Piero Demichelis 35
I/O di stringhe
• Le stringhe possono comparire come argomento di printf e
scanf: per esse si utilizza lo specificatore di formato %s.
#include <stdio.h>
main()
{
int indice;
© Piero Demichelis 37
Lettura di stringhe
• La scanf, quando trova nel format lo specificatore %s,
attua un meccanismo di lettura simile a quello usato per i
numeri: scarta tutti gli “spazi neutri ” iniziali (spazio,
<TAB>, <CR>, ecc.), “legge” i caratteri successivi
scrivendoli in locazioni consecutive del vettore indicato e
si ferma non appena incontra un altro carattere
appartenente alla categoria degli “spazi neutri ”,
chiudendo la stringa appena generata nel vettore con il
carattere NULL.
© Piero Demichelis 38
Lettura di stringhe
• Il fatto che non ci siano controlli sul numero di caratteri
introdotti, ad esempio da tastiera, può provocare danni
collaterali non trascurabili: infatti la lettura prosegue fino al
primo “spazio neutro ” in ogni caso e i caratteri letti vengono
memorizzati consecutivamente come se la stringa fosse stata
dimensionata in modo corretto anche quando è più corta di
quanto sarebbe necessario.
© Piero Demichelis 39
Esempio
• Esempio: programma per leggere i nomi (lunghi al massimo 20
caratteri) e le altezze (in cm) di 10 persone e successivamente
visualizzarli incolonnati.
#include <stdio.h>
#define NUM_NOMI 10
#define L_STRING 21
main()
{
/* Definizioni */
char nome[NUM_NOMI][L_STRING];
int altezza[NUM_NOMI];
int ind;
© Piero Demichelis 40
Esempio
printf (“\nIntroduci il nome e l'altezza di 10 persone:\n");
for (ind = 0; ind < NUM_NOMI; ind++)
{
printf (“\nPersona N. %2d: ", (ind + 1)); /* indice a partire da 1 */
scanf ("%s%d", nome[ind], &altezza[ind]);
}
char messag[16];
.....................
messag = "Errore nei dati";
.....................
© Piero Demichelis 42
Confronto tra stringhe: esempio
• Programma che legge da tastiera due parole (lunghe al più 20
caratteri) e verifica se sono uguali o diverse.
#include <stdio.h>
#define VERO 1
#define FALSO 0
main()
{
char parola1[21], parola2[21];
int ind, uguali;
© Piero Demichelis 43
Confronto tra stringhe: esempio
/* verifica se sono uguali */
uguali = VERO; /* ipotizza che siano uguali */
ind = 0;
© Piero Demichelis 44
Confronto tra stringhe
• Essendo i caratteri interpretati come numeri interi, è
lecito confrontarli tra loro per stabilire la precedenza
alfabetica mediante una espressione relazionale.
0 < 1 < 2 <.... < A < B < C <.....< Z ..... < a < b < c <....< z
#define VERO 1
#define FALSO 0
main()
{
char parola1[21], parola2[21];
int ind, finito, prima1;