Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Tipi e polimorfismo<br />
Abbiamo detto che le macro presenti nel file 1iste.h ser-<br />
vono per facilitare l'uso delle funzioni di Exec, in partico-<br />
lare per quanto riguarda il cast sui tipi. È importante no-<br />
tare che la scelta di operare in questo modo ha una certa<br />
base teorica, anche se può produrre in pratica dei risulta-<br />
ti dannosi. Infatti basta riflettere un attimo per rendersi<br />
conto che le operazioni che si compiono sulle liste, sia<br />
quelle descritte fin qui sia altre che potrebbero essere im-<br />
plementate, come il calcolo del numero di elementi nella<br />
lista, non dipendono dal tipo degli elementi contenuti.<br />
Questa caratteristica, che non riguarda solo le liste, ma<br />
anche le altre strutture contenitore (code, stack, ecc.) è<br />
ben nota con vari nomi in diversi linguaggi di program-<br />
mazione: polimorfismo parametrico in ML e Miranda,<br />
package generici in ADA, template in C++.<br />
In tutti questi linguaggi il polimorfismo parametrico (da<br />
non confondere con il polimorfismo per inclusione, che<br />
è collegato alla ereditarietà nei linguaggi object-oriented),<br />
cioè la capacità di uno stesso oggetto di assumere forme<br />
diverse pur mantenendo una sua "identità", è però realiz-<br />
zato in modo che il controllo sui tipi avverta il program-<br />
matore in caso di eventuali errori.<br />
Invece in C, ricorrendo ai cast come abbiamo fatto nelle<br />
macro, si aggira il controllo sui tipi, facendo credere al<br />
compilatore che in una certa zona di memoria si trovi un<br />
certo tipo di struttura.<br />
Se abbiamo fatto tutto con cura, non ci sarà alcun pro-<br />
blema, ma in caso di disattenzioni il compilatore non ci<br />
darà alcun messaggio di errore, mentre avremo compor-<br />
tamenti spiacevoli (guru) del nostro programma durante<br />
l'esecuzione.<br />
Utilizzando le macro si dovrà quindi fare attenzione a<br />
non invertire l'ordine dei parametri, a utilizzare le struct<br />
List e Node se si intende servirsi di Enqueue e FindName<br />
e soprattutto, ci si dovrà ricordare di inserire come primo<br />
campo degli elementi di lista da noi definiti una struct<br />
Node o MinNode.<br />
Liste o vettori?<br />
Prima di concludere questo articolo, è giusto mettere a<br />
confronto le due alternative, per evitare di comprare a<br />
scatola chiusa. i punti a favore delle liste sono: capacità<br />
di crescere e regredire dinamicamente; possibilità per gli<br />
elementi di risiedere ovunque in memoria, dal momento<br />
che sono i puntatori a mantenere la coesione della strut-<br />
tura dati per cui non c'è alcun vincolo di adiacenza, co-<br />
me accade invece per i vettori; nessuna necessità di pre-<br />
vedere in anticipo il numero di elementi da memorizzare<br />
e quindi di allocare più memoria di quanta se ne utilizza<br />
effettivamente. Tutto ciò può essere riassunto nello slo-<br />
gan: maggiore flessibilità.<br />
I punti a sfavore sono non meno importanti: ogni ele-<br />
mento inserito in lista occupa almeno 8 byte in più, per<br />
tenervi i due puntatori, rispetto allo stesso elemento inse-<br />
rito in un vettore; i byte diventano poi 14 se usiamo la<br />
struct Node; inoltre non è possibile accedere direttamen-<br />
te a un certo elemento della lista che non sia quello di<br />
testa o di coda: la lista va scandita elemento per elemen-<br />
to fino a raggiungere quello che ci interessa! Lo slogan a<br />
favore dei vettori è quindi: maggiore efficienza.<br />
Per finire, il programma di esempio presente su disco<br />
può essere lanciato sia da CL1 che da Workbench: in<br />
questo caso clickate sul gadget zoom prima di iniziare gli<br />
esperimenti; l'interfaccia utente è ridotta al minimo.<br />
Come esercizio potreste estendere questo esempio in<br />
modo da utilizzare anche Enqueue e FindName. I più av-<br />
venturosi e tenaci potrebbero invece cercare di realizzare<br />
liste di liste oppure liste contenenti elementi non dello<br />
stesso tipo, ma ai quali è possibile applicare una stessa<br />
funzione, come una procedura di stampa.<br />
A