INFORMATICA Tipi strutturati Tipi strutturati I tipi considerati

  • Slides: 47
Download presentation
INFORMATICA Tipi strutturati

INFORMATICA Tipi strutturati

Tipi strutturati • I tipi considerati finora hanno la caratteristica comune di non essere

Tipi strutturati • I tipi considerati finora hanno la caratteristica comune di non essere strutturati: ogni elemento è una singola entità. • Se il programma deve trattare collezioni di dati, anche se sono dello stesso tipo, a ognuno deve essere associato un identificatore. • Supponendo di dover gestire le paghe in una ditta di 3000 dipendenti sarebbe necessario definire 3000 variabili diverse, del tipo: operaio 1, operaio 2, . . , impiegato 1, impiegato 2, . . . , ecc. © Piero Demichelis 2

Tipi strutturati • I linguaggi ad alto livello permettono di ovviare a questo inconveniente

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. • Il linguaggio C, anche in questo caso, si presenta ambivalente: permette di creare dati aggregati, senza peraltro che questi costituiscano dei tipi nell'accezione classica. • Infatti l'organizzazione strutturale dei dati e le modalità di accesso ai singoli elementi che costituiscono la struttura non vengono nascoste all'utente, che invece può interagire con esse in piena libertà. © Piero Demichelis 3

Vettori • Il vettore è una collezione di variabili tutte dello stesso tipo (detto

Vettori • Il vettore è una collezione di variabili tutte dello stesso tipo (detto appunto tipo base) di lunghezza prefissata. • Questa collezione di variabili è individuata da un unico nome, il nome appunto del vettore. • Ogni elemento del vettore è detto componente ed è individuato dal nome del vettore seguito da un indice posto tra parentesi quadre. • L'indice può essere solo di tipo intero o enumerato e determina la posizione dell'elemento nel vettore. © Piero Demichelis 4

Vettori • L'intervallo dei valori assunti dall'indice determina la dimensione del vettore, che deve

Vettori • L'intervallo dei valori assunti dall'indice determina la dimensione del vettore, che deve essere limitata. • Definizione generale di vettore: tipo_componente nome_vettore [numero_componenti]; • tipo_componente può essere un qualunque tipo semplice, • nome_vettore è il nome da attribuire al vettore, • numero_componenti, racchiuso tra parentesi quadre, è il numero di elementi che costituiscono il vettore e pertanto deve essere un intero o un'espressione costante di tipo intero. © Piero Demichelis 5

Vettori • L'indice del vettore può assumere valori compresi tra 0 e numero_componenti –

Vettori • L'indice del vettore può assumere valori compresi tra 0 e numero_componenti – 1. • L'indice corrisponde pertanto alla posizione nel vettore dell’elemento a cui è associato, rispetto al primo. • Gli elementi del vettore sono memorizzati in celle di memoria contigue (successive)! Vettore a (di 5 elementi): a[0] a[1] a[2] a[3] a[4] © Piero Demichelis 6

Vettori • Esempi di definizioni di vettore: #define NUM_MATERIE 20 char s[8]; double giornate[167];

Vettori • Esempi di definizioni di vettore: #define NUM_MATERIE 20 char s[8]; double giornate[167]; int voti_ottenuti[NUM_MATERIE]; • La variabile s è un vettore di 8 elementi: equivale alle 8 variabili di tipo char: s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]. • La variabile giornate è un vettore di 167 elementi di tipo double il cui indice può variare tra 0 e 166. • La variabile voti_ottenuti è un vettore di 20 elementi di tipo intero il cui indice può variare tra 0 e 19. © Piero Demichelis 7

Inizializzazione di un vettore • E’ possibile assegnare un valore iniziale ad un vettore

Inizializzazione di un vettore • E’ possibile assegnare un valore iniziale ad un vettore al momento della sua definizione. • L’operazione consiste nell’indicare i valori degli elementi del vettore separati tra loro da virgola. • Sintassi (per un vettore di N elementi): = {<valore_0>, <valore_1>, . . . , , <valore_N-1>}; • 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

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: int s[4] = {2, 0, 1}; /* s[0]=2, s[1]=0, s[2]= 1, s[3]=? */ char p[5] = {‘a’, ‘b’, ‘c’}; /* p[0]=‘a’, p[1]=‘b’, p[2]=‘c’, p[3]=? , p[4]=? */ double d[2] = {2. 56}; /* d[0]=2. 56, d[1]=? */ © Piero Demichelis 9

Vettori e indici • L’indice, che definisce la posizione di un elemento di un

Vettori e indici • L’indice, che definisce la posizione di un elemento di un vettore, DEVE essere rigorosamente un intero! • Può ovviamente anche essere un’espressione, più o meno complessa, purché con risultato intero. • Esempio: double x, a[30]; /* a vettore di double */ int i, j, k; . . . x = a[2*i+j k]; /* espressione aritmetica per l’indice */ © Piero Demichelis 10

Vettori e cicli • I cicli sono particolarmente utili per “scandire” un vettore. •

Vettori e cicli • I cicli sono particolarmente utili per “scandire” un vettore. • Utilizzo tipico: applicazione iterativa di un’operazione sugli elementi di un vettore. • Schema: int data[10], ind; . . . for (ind=0; ind<10; ind++) { elaborazione dell’elemento data[ind] } • Ad ogni ciclo è interessato l’elemento individuato dall’indice ind. © Piero Demichelis 11

Vettori • Non ci sono operatori che agiscono sul vettore nel suo complesso: non

Vettori • Non ci sono operatori che agiscono sul vettore nel suo complesso: non è lecito pertanto l'assegnamento di un vettore ad un altro vettore. • Se vett_x e vett_y sono vettori, l'istruzione: vett_x = vett_y; è errata anche se vett_x e vett_y sono dello stesso tipo. • Per trasferire un vettore in un altro occorre copiare un elemento per volta. © Piero Demichelis 12

Vettori • Esempio: copia il vettore vett_iniz nel vettore vett_fin #include <stdio. h> #define

Vettori • Esempio: copia il vettore vett_iniz nel vettore vett_fin #include <stdio. h> #define NUMDATI 5 int vett_iniz[NUMDATI] = {11, 2, 63, 4, 15}; int vett_fin[NUMDATI], indice; 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

Vettori • Sugli elementi del vettore agiscono gli operatori previsti per il tipo_componente. Pertanto è lecito scrivere: valor_fin = vett_x[m 1] + vett_y[m 2]; purché, naturalmente, valor_fin, il vettore vett_x e il vettore vett_y siano dello stesso tipo. • Il tempo necessario per accedere a un elemento di un vettore è indipendente dal valore dell'indice: il vettore è pertanto una struttura ad accesso casuale © Piero Demichelis 14

Esempio • Leggere 10 valori da tastiera e memorizzarli in un vettore; quindi calcolarne

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

Esempio #include <stdio. h> #define NUMDATI 10 main() { int minimo, massimo, ind; int vettdati[NUMDATI]; /* lettura dei dati */ for (ind = 0; ind < NUMDATI; ind++) { printf (“n. Introduci vettdati[%d]: ", ind); scanf ("%d", &vettdati[ind]); } © Piero Demichelis 16

Esempio /* cerca il massimo e il minimo */ massimo = vettdati[0]; minimo =

Esempio /* cerca il massimo e il minimo */ massimo = vettdati[0]; minimo = vettdati[0]; for (ind = 1; ind < NUMDATI; ind++) { if (vettdati[ind] > massimo) massimo = vettdati[ind]; else { if (vettdati[ind] < minimo) minimo = vettdati[ind]; } } printf (“n. Il massimo è %d e il minimo è %dn ", massimo, minimo); } © Piero Demichelis 17

Esempio • Scrivere un programma che legga un numero decimale positivo minore di 1024

Esempio • Scrivere un programma che legga un numero decimale positivo minore di 1024 e lo converta nella corrispondente codifica binaria. • Analisi Per convertire in binario puro un numero decimale occorre eseguire una sequenza di divisioni per 2 prendendo i resti (0 oppure 1): occorre dunque un vettore per memorizzare questi resti. Poiché i numeri devono essere compresi tra 0 e 1023 sono sufficienti 10 bit: il nostro vettore sarà pertanto lungo 10 elementi e in ogni elemento memorizzeremo una cifra. © Piero Demichelis 18

Esempio Analisi (continua): I resti ottenuti dalle divisioni per 2 vanno però letti al

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. Per eseguire le divisioni per due è intuitivo che conviene servirsi di un ciclo il quale, ad ogni iterazione, calcola un nuovo bit (resto della divisione per 2). for o while? È pressochè indifferente usare un ciclo for o un ciclo while: occorre però che le inizializzazioni delle variabili siano adattate al ciclo prescelto. Se usiamo il for avremo come “dato guida” del ciclo l’indice del vettore; Se usiamo il while il “dato guida” sarà il resto delle divisioni per 2. © Piero Demichelis 19

Esempio (con while) #include <stdio. h> main() { int ind, numero, num; int binario[10];

Esempio (con while) #include <stdio. h> main() { int ind, numero, num; int binario[10]; /* inizializza il vettore risultato con tutti zeri */ for (ind = 0; ind < 10; binario[ind++]=0); /* equivale a : for (ind=0; ind<10; ind++) binario[ind] = 0; */ printf (“n. Introduci un numero intero positivo minore di 1024: "); scanf ("%d", &numero); © Piero Demichelis 20

Esempio (con while) if ((numero >= 0) && (numero < 1024)) { num =

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 ("n. Conversione del numero %d: ", numero); for (ind=0; ind<10; ind++) /* Visualizza il vettore: */ printf ("%1 d", binario[ind]); /* un bit per volta */ } else printf (“n. Numero non lecito!”); } © Piero Demichelis 21

Esempio (con for) #include <stdio. h> main() { int ind, numero, num; int binario[10];

Esempio (con for) #include <stdio. h> main() { int ind, numero, num; int binario[10]; /* non è necessario inizializzare il vettore in quanto il ciclo for deve */ /* scrivere comunque tutti gli elementi del vettore */ printf (“n. Introduci un numero intero positivo minore di 1024: "); scanf ("%d", &numero); © Piero Demichelis 22

Esempio (con for) if ((numero >= 0) && (numero < 1024)) { num =

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 ("n. Conversione del numero %d: ", numero); for (ind = 0; ind < 10; ind++) /* Visualizza il vettore: */ printf ("%1 d", binario[ind]); /* un bit per volta! */ } else printf (“n. Numero non lecito!”); } © Piero Demichelis 23

Vettori • Quando si definisce un vettore il compilatore riserva un’area di memoria sufficiente

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. • Pertanto il nome vett_dati non è una vera e propria variabile, ma piuttosto un puntatore : in pratica vett_dati è l'indirizzo di memoria del primo elemento del vettore cioè l'indirizzo di vett_dati[0]. • Ecco perché è errata l'istruzione: voti_ottenuti = voti_semestre; © Piero Demichelis 24

Vettori multidimensionali • Il concetto di vettore come collezione di elementi consecutivi, può essere

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. • La definizione di matrice ricalca pienamente quella del vettore: tipo_comp nome [dim 1] [dim 2]. . ; • tipo_comp può essere un qualunque tipo semplice, • dim 1, dim 2, ecc. ; racchiusi tra parentesi quadre, definiscono il numero di elementi di ogni dimensione. © Piero Demichelis 25

Vettori multidimensionali Esempio: matrice bidimensionale di numeri interi formata da tre righe e 5

Vettori multidimensionali Esempio: matrice bidimensionale di numeri interi formata da tre righe e 5 colonne: int a[3][5]; a a[0][0] a[1][0] a[2][0] a[3][0] a[4][0] a[0][1] a[1][1] a[2][1] a[3][1] a[4][1] a[0][2] a[1][2] a[2][2] a[3][2] a[4][2] a[2] © Piero Demichelis 26

Vettori multidimensionali • Accesso ad un elemento: <nome vettore> [<posizione 1>] [<posizione 2>]. .

Vettori multidimensionali • Accesso ad un elemento: <nome vettore> [<posizione 1>] [<posizione 2>]. . . • Per esempio matrix [10][20][15] individua l'elemento di coordinate rispettivamente 10, 20 e 15 nella matrice a 3 dimensioni matrix. • Inizializzazione di un vettore multidimensionale: deve essere effettuata per righe! int vett[3][2] = { }; {8, 1}, /* vett[0] */ {1, 9}, /* vett[1] */ {0, 3} /* vett[2] */ © Piero Demichelis 27

Vettori multidimensionali e cicli • Per un vettore a più dimensioni, la scansione va

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 ”. • Esempio: elaborazione degli elementi di un vettore bidimensionale. int vett [3][5]; … for (i = 0; i < 3; i++) { /* per ogni riga */ for (j = 0; j < 5; j++) { /* per ogni colonna */ . . . elaborazione su vett[i][j] } } © Piero Demichelis 28

Stringhe

Stringhe

Vettori di caratteri: le stringhe • Le variabili di tipo char possono contenere un

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. • Differentemente dagli altri tipi di dato (intero, reale, ecc. ) per le stringhe non è sempre possibile fissare a priori le dimensioni: la loro caratteristica peculiare è proprio la lunghezza variabile. • Per gestire dati di questo tipo occorrerebbe l'allocazione dinamica della memoria, in modo da riservare tutta e solo la memoria che serve. © Piero Demichelis 30

Vettori di caratteri: le stringhe • Il C prevede per le stringhe un vettore

Vettori di caratteri: le stringhe • Il C prevede per le stringhe un vettore di caratteri, il quale deve quindi avere una lunghezza massima prefissata. • All'interno di questo vettore, la lunghezza reale della stringa è determinata dalla presenza di un carattere delimitatore particolare, '', detto anche NULL. • Come per i tipi base, anche per le stringhe è prevista una notazione particolare per indicarne i valori: la sequenza di caratteri deve essere delimitata da una coppia di doppi apici ("). © Piero Demichelis 31

Stringhe • Esempio: ‘C’ ‘i’ const char s[6] = “Ciao!”; ‘a’ ‘o’ ‘!’ ‘�’

Stringhe • Esempio: ‘C’ ‘i’ const char s[6] = “Ciao!”; ‘a’ ‘o’ ‘!’ ‘’ s[0] s[1] s[2] s[3] s[4] s[5] • Il messaggio è lungo solo 5 caratteri, ma deve essere riservato un carattere in più per il terminatore di stringa, che deve essere sempre presente e viene forzato automaticamente dal linguaggio C. • Il vettore può essere definito più lungo, con gli ultimi elementi indefiniti, ma non più corto. • NOTA: la stringa vuota non è un vettore “vuoto”! char s[] = “”; ‘’ s[0] © Piero Demichelis 32

Stringhe • Per la definizione di una stringa si può anche utilizzare la direttiva

Stringhe • Per la definizione di una stringa si può anche utilizzare la direttiva define: #define MESSAGGIO “Ciao!”; • Attenzione infine a non confondere variabili di tipo carattere con stringhe: per esempio, 'C' rappresenta un unico carattere che è memorizzato in un'unica cella. "C" rappresenta invece una stringa che è memorizzata in due celle consecutive che contengono i caratteri 'C' e ''. © Piero Demichelis 33

Stringhe • Un vettore di nomi si realizza mediante una matrice di tipo carattere

Stringhe • Un vettore di nomi si realizza mediante una matrice di tipo carattere dove ogni riga (vettore) contiene un nome. Ad esempio, per memorizzare i nomi dei giorni della settimana, si può procedere così: const char giorni[7][10] = {"lunedì", "martedì", "mercoledì", "giovedì", "venerdì", "sabato", "domenica"}; • dove la dimensione dei singoli vettori (tutti i vettori!), cioè 10, è determinata sommando 1 alla lunghezza del nome più lungo (mercoledì). • Pertanto un vettore di stringhe è in realtà una matrice di caratteri! © Piero Demichelis 34

Stringhe l u n e d ì � m a r t e d

Stringhe l u n e d ì m a r t e d ì m e r c o l e d g i o v e d ì giorni[3] v e n e r d ì giorni[4] s a b a t o d o m e n i c © Piero Demichelis giorni[0] giorni[1] ì giorni[2] giorni[5] a giorni[6] 35

I/O di stringhe • Le stringhe possono comparire come argomento di printf e scanf:

I/O di stringhe • Le stringhe possono comparire come argomento di printf e scanf: per esse si utilizza lo specificatore di formato %s. • In particolare la printf, quando trova nel format lo specificatore %s, interpreta i valori contenuti nella variabile corrispondente (che dev’essere un vettore di caratteri!) come caratteri e li visualizza finché non trova un carattere ''. • Se non è presente il carattere terminatore la printf continua l’output oltre i confini del vettore fino a che non incontra un '‘ (ovvero una cella di memoria che contiene 0!). • Come per gli altri specificatori, anche in %s si può specificare la lunghezza del campo e gli altri attributi di allineamento. © Piero Demichelis 36

Esempio • Programma per visualizzare i giorni della settimana, uno per riga, allineati a

Esempio • Programma per visualizzare i giorni della settimana, uno per riga, allineati a sinistra (flag - ) in un campo di 15 caratteri. #include <stdio. h> const char giorni[7][10] = { "lunedì", "martedì", "mercoledì", "giovedì", "venerdì", "sabato", "domenica"}; main() { int indice; printf ("n. I giorni della settimana sono: n"); for (indice = 0; indice < 7; indice++) printf ("% 15 sn", giorni[indice]); } © Piero Demichelis 37

Lettura di stringhe • La scanf, quando trova nel format lo specificatore %s, attua

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. • E’ importante quindi che nella stringa non siano presenti spazi e che il vettore destinazione sia dimensionato opportunamente poiché, come sempre in C, non ci sono controlli sugli indici. © Piero Demichelis 38

Lettura di stringhe • Il fatto che non ci siano controlli sul numero di

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. • I caratteri “in eccesso” e il NULL vengono comunque memorizzati e possono pertanto andare a ricoprire aree di memoria riservate ad altri dati sporcandoli irrimediabilmente. • Poiché il nome della stringa è proprio l’idirizzo del vettore di caratteri associato nella scanf non si deve usare il carattere & prima del nome. © Piero Demichelis 39

Esempio • Esempio: programma per leggere i nomi (lunghi al massimo 20 caratteri) e

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 (“n. Introduci il nome e l'altezza di 10 persone: n"); for (ind

Esempio printf (“n. Introduci il nome e l'altezza di 10 persone: n"); for (ind = 0; ind < NUM_NOMI; ind++) { printf (“n. Persona N. %2 d: ", (ind + 1)); /* indice a partire da 1 */ scanf ("%s%d", nome[ind], &altezza[ind]); } printf("n Nome Altezza"); for (ind = 0; ind < NUM_NOMI; ind++) { printf (“n. Persona N. %4 d: % 20 s %3 d", (ind + 1), nome[ind], altezza[ind]); } } © Piero Demichelis 41

Confronto tra stringhe • Poiché le stringhe sono vettori, non è lecito assegnare una

Confronto tra stringhe • Poiché le stringhe sono vettori, non è lecito assegnare una stringa ad un'altra. Pertanto il frammento di programma che segue è errato: char messag[16]; . . messag = "Errore nei dati"; . . • Anche il confronto tra stringhe non può essere effettuato mediante un'unica istruzione, come invece avviene per i singoli caratteri, ma occorre confrontare col criterio opportuno i singoli elementi delle due stringhe. © Piero Demichelis 42

Confronto tra stringhe: esempio • Programma che legge da tastiera due parole (lunghe al

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 parola 1[21], parola 2[21]; int ind, uguali; printf (“n. Introduci la prima parola: “); scanf (“%s”, parola 1); printf (“n. Introduci la seconda parola: “); scanf (“%s”, parola 2); © Piero Demichelis 43

Confronto tra stringhe: esempio /* verifica se sono uguali */ uguali = VERO; /*

Confronto tra stringhe: esempio /* verifica se sono uguali */ uguali = VERO; /* ipotizza che siano uguali */ ind = 0; while (uguali && (ind < 20) && (parola 1[ind] != ‘’)) { if (parola 1[ind] != parola 2[ind]) uguali = FALSO; ind++; } if (uguali) printf (“n. Le parole introdotte sono uguali”); else printf (“n. Le parole introdotte sono diverse”); } © Piero Demichelis 44

Confronto tra stringhe • Essendo i caratteri interpretati come numeri interi, è lecito confrontarli

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 • Poiché le stringhe sono vettori di caratteri, e quindi composte da elementi di tipo char, è lecito stabilire l’ordine alfabetico di due stringhe confrontandole fra loro carattere per carattere. • Esempio: programma che legge da tastiera due parole e stabilisce l’ordine alfabetico. © Piero Demichelis 45

Confronto tra stringhe: esempio #include <stdio. h> #define VERO 1 #define FALSO 0 main()

Confronto tra stringhe: esempio #include <stdio. h> #define VERO 1 #define FALSO 0 main() { char parola 1[21], parola 2[21]; int ind, finito, prima 1; printf ("n. Introduci la prima parola: "); scanf ("%s", parola 1); printf ("n. Introduci la seconda parola: "); scanf ("%s", parola 2); finito = FALSO; /* segnala fine dei confronti! */ ind = 0; © Piero Demichelis 46

Confronto tra stringhe: esempio while (!finito && (ind < 20)) { if (parola 1[ind]

Confronto tra stringhe: esempio while (!finito && (ind < 20)) { if (parola 1[ind] == parola 2[ind]) /* caratteri uguali: nessuna decisione */ ind++; else { if(parola 1[ind] < parola 2[ind]) prima 1 = VERO; /* parola 1 precede parola 2 */ else prima 1 = FALSO; /* parola 2 precede parola 1 */ finito = VERO; /* caratteri diversi: fine dei confronti */ } } if (prima 1) printf ("n%s precede %s", parola 1, parola 2); else printf ("n%s precede %s", parola 2, parola 1); } © Piero Demichelis 47