Continuiamo la nostra rapida esplorazione sul linguaggio D, sperando di aver svegliato la curiosità dei programmatori. In questa seconda e ultima puntata verranno analizzati alcuni aspetti estremamente importanti che, indubbiamente, stanno decretando il D come il linguaggio del futuro.
Proviamo il linguaggio D online
Nel precedente articolo abbiamo visto le procedure per scaricare, installare e usare il compilatore. Tuttavia, è spesso utile provare e testare i propri listati direttamente online sul proprio browser, senza alcun bisogno di software aggiuntivo. Accedendo, infatti, alla home page localizzata all'indirizzo https://dlang.org/ è possibile digitare e provare immediatamente i propri sorgenti, come visibile in Figura 1. Il seguente semplice listato memorizza, in un array, alcuni numeri primi per poi visualizzarli ciclicamente in un loop di tipo "foreach".
void main() { import std.stdio; int[] vettore=[2,3,5,7,11,13,17,19,23,29,31]; writeln("Salve Mondo. I numeri primi nel vettore sono:"); foreach(primo;vettore) writeln(primo); }
Come si vede, è sufficiente premere il pulsante "Edit", scrivere il proprio codice e provarlo, premendo il pulsante "Run". L'esecuzione è mostrata in Figura 2.
Se si desidera più spazio è possibile premere il pulsante "Open in IDE" per avere a disposizione un ambiente più grande, un vero e proprio ambiente di sviluppo online. E' possibile, addirittura, visualizzare anche il corrispondente listato in Assembly, come mostrato in Figura 3.
Un ambiente, dunque, molto comodo e utile per iniziare a lavorare con il linguaggio D.
Un linguaggio a oggetti
Ormai tutti i linguaggi innovativi devono supportare la programmazione a oggetti. E il D è uno di questi. Non staremo, ovviamente, a spiegare in questa sede cosa sono gli oggetti, per i quali rimandiamo il lettore ai nostri precedenti articoli. Il seguente sorgente crea la classe "Rettangolo" con i suoi attributi pubblici, per poter essere utilizzati dal programmatore. Da tale classe si creano, dunque, i due oggetti "tavolo" e "stanza" che vengono utilizzati in toto nella funzione main del programma. Si esorta a leggere e studiare attentamente il listato poiché tale tipologia di programmazione è, ormai, usata in qualsiasi ambiente informatico.
import std.stdio; //-------------------------------------------- void main() { Rettangolo tavolo,stanza; tavolo = new Rettangolo; stanza = new Rettangolo; tavolo.x = 4; tavolo.y = 7; writeln("Tavolo di ",tavolo.x," x ",tavolo.y," AREA = ",tavolo.area); tavolo.disegna(); stanza.x = 46; stanza.y = 5; writeln("Stanza di ",stanza.x," x ",stanza.y," AREA = ",stanza.area); stanza.disegna(); } //-------------------------------------------- class Rettangolo { public: double x; double y; double area() { return x*y; } void disegna() { foreach (k1; 0..y) { foreach (k2; 0..x) { write("X"); } writeln(""); } writeln(""); } }
Si accede ai membri della classe, come si vede, con l'utilizzo dell'operatore "punto". Se di tipo pubblico, essi possono essere interrogati o inizializzati. Oltre ai normali membri si possono anche implementare le funzioni membro, con cui creare le vere e proprie funzionalità dell'oggetto. La funzione "disegna()", di tipo void, consente di disegnare sul video un rudimentale e testuale rettangolo, formato solo dal simbolo "X", dalle dimensioni dipendenti da quelle assegnate ai rispettivi membri, come si evince dalla Figura 4.
Ovviamente, sugli oggetti ci sarebbe tanto altro da dire. In questa sede ci limitiamo a indicare semplicemente i punti chiave del linguaggio D.
Il ciclo "foreach"
Il linguaggio D ha un set molto ampio per poter implementare i cicli e i loop. Alcuni di essi sono i seguenti: while(), do while(), for() e foreach(). Uno dei più potenti è, sicuramente, proprio quest'ultimo. Esso è specializzato ad applicare la stessa operazione ai vari elementi di un contenitore o di un intervallo. Il ciclo foreach conosce già il numero degli elementi da processare e non è necessario sapere il limite terminale dell'insieme. I contenitori più usati sono:
- gli array;
- le stringhe (o array di caratteri);
- gli array associativi;
- gli intervalli dei numeri naturali;
- le strutture;
- le classi.
La struttura generale del ciclo è la seguente:
foreach(elemento; contenitore) {
operazione(elemento);
}
Vediamo alcuni dei suoi utilizzi più importanti.
Foreach applicato agli array
Per eseguire delle operazioni sugli array, l'utilizzo del ciclo foreach è estremamente fruttuoso. Si supponga d'inizializzare un array e popolarlo con alcuni elementi numerici e di voler visualizzare i rispettivi valori assieme al risultato del loro quadrato più 1. Ecco, di seguito, la semplice ed elegante soluzione.
import std.stdio; void main() { int[] primi=[2,5,11,32,44,78]; foreach(p;primi) writeln(p," ",p*p+1); "Finito".writeln(); }
Si osservi l'ultima riga del programma. Essa visualizza la parola "Finito". In pratica anche una costante è, a tutti gli effetti, un oggetto. La Figura 5 mostra il risultato dell'esecuzione del listato.
Foreach applicato alle stringhe (o array di caratteri)
Poiché le stringhe sono vettori di caratteri, foreach funziona con le stringhe allo stesso modo degli array: l'elemento si riferisce al singolo carattere. Il seguente esempio legge la frase, lettera per lettera, e la stampa spaziata di due posti. Il listato è estremamente semplice, leggibile ed elegante.
import std.stdio; void main() { string frase="Leggete EOS-Book"; foreach(ch;frase) write(ch," "); }
L'output del programma è in Figura 6.
E' interessante notare che, se si aggiungono due parametri al ciclo, il primo si riferisce al contatore e il secondo all'elemento vero e proprio. Ad esempio, il seguente listato visualizza i singoli caratteri di una parola, preceduti dal rispettivo numero d'ordine (che inizia, naturalmente, per zero).
import std.stdio; void main() { string frase="Computer"; foreach(i,ch;frase) writeln(i," ",ch); }
La Figura 7 mostra il relativo risultato.
Ovviamente, è possibile passare direttamente la costante, senza assegnarla ad alcun oggetto, come nell'esempio che segue.
import std.stdio; void main() { foreach(ch;"Computer") writeln(ch); }
Foreach applicato agli array associativi
Ancora più potente risulta l'applicazione del ciclo foreach agli array associativi. Il listato che segue definisce un array associativo di tipo stringa con indici stringa. Quindi, vi assegna dei cantanti famosi con l'associazione del cognome quale chiave e del nome quale valore. Visualizza, dunque, con un'unica funzione, le chiavi (cantante.keys) e i valori (cantante.values) e, infine, attraversa l'array mostrando le informazioni del database. La gestione degli array associativi consente di creare programmi complessi con la massima facilità.
import std.stdio; void main() { string[string] cantante; cantante["Morandi"]="Gianni"; cantante["Tozzi"]="Umberto"; cantante["Dalla"]="Lucio"; cantante["Zanicchi"]="Iva"; cantante["Ligabue"]="Luciano"; writeln("Cognomi ",cantante.keys); writeln("Nomi ",cantante.values); writeln("-----------------------------"); foreach(nome;cantante) writeln(nome); writeln("-----------------------------"); foreach(cognome,nome;cantante) writeln(cognome," ",nome); }
La Figura 8 mostra i risultati dell'esecuzione del listato di cui sopra.
Foreach applicato agli intervalli numerici
Un intervallo numerico, in linguaggio D, è un insieme di valori compresi tra un minimo e un massimo, quest'ultimo escluso. Ad esempio, l'intervallo:
10..15
rappresenta i numeri interi 10, 11, 12, 13 e 14.
Proprio su questa base andiamo a creare un listato che stampi una tabella con il numero progressivo, il suo quadrato, il suo cubo e la sua radice quadrata.
import std.stdio, std.math; void main() { writeln(" n n^2 n^3 sqrt(n)"); writeln("-----------------------"); foreach (n; 1..11) { writefln("%2d %3d %4d %f",n,n*n,n*n*n,sqrt(cast(float)n)); } }
Nel programma ci sono alcune novità:
- si è dovuta importare la libreria matematica (std.math) per poter invocare la funzione della radice quadrata;
- si è formattato l'output per produrre un tabulato elegante utilizzando i simboli di formattazione (%2d %3d %4d %f);
- il parametro della radice quadrata ha subito un'operazione di casting per la conversione di tipo, grazie alla funzione cast(float)n.
La Figura 9 mostra il risultato dell'esecuzione del programma.
L'integrità del contenitore deve essere preservata
Sebbene si possa modificare il valore degli elementi di un contenitore, il reale valore di un contenitore non può essere modificato durante il suo attraversamento, tranne se si passa lo stesso tramite indirizzo, per referenza. Il programma che segue inizializza un array di numeri, applica alcune sue trasformazioni all'interno del ciclo foreach ma, all'uscita, il contenuto è intatto, come mostrano le relative funzioni di visualizzazione.
import std.stdio; void main() { int[] numeri=[4,8,12,16,20]; writeln("Vettore iniziale ",numeri); foreach(p;numeri) { write(p," "); p=p*2; writeln(p); } writeln("Vettore finale ",numeri); }
La Figura 10 conferma tale aspetto.
Iterazioni al contrario con foreach_reverse
Un contenitore può essere attraversato secondo un ordine inverso utilizzando foreach_reverse. Tutti gli esempi precedenti possono essere tranquillamente implementati con tale clausola. Il seguente listato visualizza, a video, un vettore in ordine inverso.
import std.stdio; void main() { string[] animali=["cane","gatto","giraffa","balena"]; foreach_reverse(a;animali) writeln(a); }
Il vettore è visualizzato dall'ultimo al primo elemento. Il seguente output è prodotto dall'esecuzione del programma:
balena
giraffa
gatto
cane
BigInt: la libreria per numeri interi molto grossi
Si tratta di una potente libreria per numeri a precisione arbitraria. Le performances sono ottimizzate per valori fino a 1000 cifre. Per macchine X86 le operazioni sono state scritte anche in linguaggio Assembly. Ad ogni modo per numeri realmente grossi, nell'ordine di milioni di cifre, si dovrebbe optare per le librerie GMP. Le variabili di tipo BigInt supportano tutti i tipi di operazioni aritmetiche e logiche, tranne lo shift a destra. [...]
ATTENZIONE: quello che hai appena letto è solo un estratto, l'Articolo Tecnico completo è composto da ben 2367 parole ed è riservato agli ABBONATI. Con l'Abbonamento avrai anche accesso a tutti gli altri Articoli Tecnici che potrai leggere in formato PDF per un anno. ABBONATI ORA, è semplice e sicuro.