Eserciziari di C++ e Java

 Eserciziari di C++ e Java

Da oggi anche in Java!!!

Da oggi, 15 novembre 2015, l'eserciziario è liberamente disponibile anche in linguaggio Java.

Esercizi di C++ e Java

Questo sito ospita due eserciziari dedicati ai linguaggi C++ e Java. Ogni eserciziario presenta circa 50 esercizi orientati alla scrittura di classi e di semplici algoritmi. La seconda parte degli eserciziari contiene tutte le soluzioni. È possibile scaricare anche i files con le soluzioni in forma di codice sorgente, per includerli nei propri progetti di prova all'interno dell'ambiente di sviluppo.

L'autore può essere contattato all'indirizzo esposito.marce [chiocciola] gmail.com

Prefazione del testo su Java

Gli esercizi presentati in questo eserciziario sono stati originariamente assegnati ad un corso universitario di Programmazione I al secondo e terzo anno di Ingegneria delle Telecomunicazioni. Il corso richiedeva di realizzarne le soluzioni in linguaggio C++. Successivamente sono tradotti in linguaggio Java dal testo 50 esercizi di C++ con soluzioni.

Il corso aveva lo scopo di introdurre alla programmazione orientata agli oggetti. Una rilevante parte del programma affrontava lo studio dei tipi di dati astratti, con particolare enfasi sulle strutture dati di tipo contenitore, stressandone i concetti di incapsulamento ed interfaccia. Gli esercizi dedicati all'approfondimento di questi concetti sono stati raccolti in questo eserciziario, insieme con le relative soluzioni.

A chi è rivolto questo testo

Gli studenti che approcciano allo studio del linguaggio Java, in occasione di corsi di studi superiori, troveranno utile studiare e risolvere gli esercizi contenuti in questo testo. Se da un lato questi favoriscono l'acquisizione delle ricorrenti tecniche legate alla realizzazione ed all'uso di contenitori, dall'altro rappresentano un pretesto per mettere in pratica approcci algoritmici alla risoluzione di problemi più generici. Il libro si focalizza sulla progettazione degli algoritmi più che sulla sintassi e sull'uso esteso dello specifico linguaggio.

Non essendo questo un libro di teoria, lo studio di uno dei numerosi testi dedicati alle nozioni della programmazione, alle regole ed alla sintassi del linguaggio Java, risulta propedeutico. Un diffuso testo orientato all'apprendimento del linguaggio è Thinking in Java di Bruce Eckel.

Questo eserciziario contiene differenti tipologie di esercizi: alcuni richiedono la realizzazione di una struttura dati di tipo contenitore, mediante uso del costrutto class del linguaggio, fornendo allo studente la specifica in forma di interfaccia dei classici metodi di cui tali strutture sono dotate (aggiunta di un elemento, conteggio degli elementi, svuotamento, visita, etc.). Altri esercizi, basandosi sulle suddette implementazioni, richiedono la realizzazione di funzionalità finalizzate ad effettuare particolari elaborazioni sugli elementi contenuti (per esempio inserimenti o eliminazioni condizionate, somme, spostamenti, conteggi, etc.). Infine, alcuni esercizi richiedono la realizzazione di strutture dedicate a risolvere specifici problemi, e quindi prive dei classici requisiti di generalità.

Per ogni metodo da implementare, una traccia fornisce le seguenti informazioni:

  •   - il nome del metodo;
  •   - l'insieme dei parametri di ingresso;
  •   - l'insieme dei parametri di uscita;
  •   - la descrizione della funzionalità che il metodo deve realizzare.

Per esempio, la specifica di un ipotetico metodo di eliminazione di elementi da una lista, potrebbe apparire come segue.

elimina int int
Elimina dalla struttura tutte le occorrenze dell'elemento specificato dal parametro di ingresso. Restituisce il numero delle eliminazioni effettuate.

Nel caso in cui l'insieme dei parametri di ingresso e/o di uscita fosse vuoto, si utilizzerà il simbolo di insieme vuoto. Talvolta può accadere che nella descrizione del funzionamento del metodo non si prenda in considerazione la totalità dei casi che possono verificarsi (pre-condizioni), limitandosi a descrivere il comportamento del metodo nei casi d'uso più comuni. In questo caso, il programmatore può scegliere arbitrariamente un comportamento per tutti i casi non esplicitamente considerati.

Per quanto riguarda le strategie di gestione della memoria, la realizzazione delle strutture dati può basarsi su un approccio di tipo statico (uso di vettori allocati sullo stack) oppure dinamico (realizzazione di strutture concatenate con puntatori ed allocate nell'heap mediante costrutto new). Questa scelta, in alcuni casi, è lasciata alla sensibilità dello studente.

Per ognuno degli esercizi, oltre alla traccia, si fornisce la soluzione consistente nell'implementazione dei metodi conformi all'interfaccia specificata dalla traccia. Nel caso in cui la traccia richieda di realizzare una struttura dati completa (e non solo i metodi basati su di essa), nella soluzione viene anche fornito un modulo di test (di solito rappresentato dalla funzione main() della classe Main) utile esclusivamente al collaudo delle funzionalità della classe.

Al fine di preservare una maggiore generalità delle strutture dati realizzate, un esplicito requisito comune a tutti gli esercizi consiste nel vietare l'uso dei meccanismi di I/O nell'implementazione dei metodi della classe. La responsabilità di prelevare i dati da tastiera e mostrare i risultati sulla console viene pertanto delegata al modulo di test, mentre la classe resta indipendente dalla tecnologia utilizzata per l'interfacciamento grafico con l'utente. Pertanto, anziché stampare direttamente, i metodi di visita delle strutture contenitore (per es. stampa degli elementi di una lista) costruiscono e restituiscono una stringa contenente l'insieme degli elementi. Allo scopo utilizzano la classe StringBuilder della libreria standard java.lang, che consente proprio la composizione incrementale ed efficiente di grosse stringhe di testo mediante uso del metodo append(). Non sarà necessario quindi modificare la classe nel caso in cui, in futuro, si decidesse di utilizzare una diversa interfaccia grafica (es. SWT, HTML, ecc.) per acquisire i dati e mostrare i risultati delle elaborazioni.

Compilare i sorgenti

Tutti i sorgenti presentati sono stati compilati con l'ambiente di sviluppo integrato Eclipse per Java, nella sua versione Luna Service Release 2 (4.4.2). L'estrema portabilità del linguaggio Java non dovrebbe rendere complicata la compilazione su altri ambienti di sviluppo.

Uno sguardo al futuro

Quelli che alla fine di questo eserciziario penseranno: Sì, e allora?, probabilmente sono pronti per affrontare uno studio più approfondito della programmazione, che non si esaurisce con il possesso delle nozioni sulla progettazione di generici algoritmi e un'infarinatura sulle basi del linguaggio. Tra un individuo che conosca un linguaggio di programmazione ed un programmatore esperto c'è un differenza analoga a quella che esiste tra un individuo che sappia scrivere ed uno scrittore. Un buon programmatore non è quello che sa affrontare la complessità, ma quello che sa dominarla. Certamente la conoscenza della sintassi del linguaggio è un primo passo indispensabile, ma chi vuole approfondire questa affascinante materia non può fare a meno di acquisire le nozioni della progettazione, le buone prassi per la stesura del codice e gli strumenti forniti dalle librerie standard oggi disponibili. È solo attraverso questa strada che diviene possibile scrivere applicazioni non banali, preservandone le caratteristiche di comprensibilità, estensibilità, manutenibilità, correttezza e, in una sola parola, di qualità. Programmare utilizzando l'incapsulamento, il polimorfismo, i meccanismi delle eccezioni, delle asserzioni, dei generics, le numerose librerie più o meno standard, significa disporre di strumenti semanticamente molto potenti, oltre che ben consolidati; significa delegare al compilatore lo svolgimento di una serie di operazioni e di controlli che, in alternativa, peserebbero sulle spalle del programmatore, oppure non verrebbero messi in essere affatto.

Nell'apprendere le nozioni della progettazione e le buone prassi per la stesura del codice, ascoltare cosa hanno da dirci i giganti al proposito, può servire molto. A questo scopo non si può fare a meno di citare dei testi disponibili in letteratura, universalmente considerati dei classici.

Design Patterns (GoF) è probabilmente il più bel testo mai scritto nell'ambito della progettazione software, considerando anche le profonde ripercussioni che esso ha poi avuto sul concetto di buona progettazione software orientata agli oggetti, tanto da essere ancora oggi il libro di gran lunga più citato nel suo genere. In questo testo gli autori introducono il concetto di pattern progettuale software (design pattern); ad un livello di astrazione superiore a quello di qualsiasi linguaggio di programmazione, presentano poi 55 soluzioni a problemi comuni nell'ambito della progettazione, con esempi in linguaggio C++. Ne esistono varie versioni declinate nel linguaggio Java. Imperdibile.

A livello professionale, è molto utile approfondire altri patterns consolidati. Un importante aspetto riguarda l'interfacciamento delle applicazioni con le basi di dati relazionali. Queste ultime, progettate prima della vasta diffusione della programmazione orientata agli oggetti, male si adattano ad interagire con le moderne applicazioni. Per questo si sono recentemente sviluppati prodotti classificati come object/relational mappers, il cui uso consapevole migliora notevolmente le caratteristiche di correttezza, modularità, portabilità, efficienza di un'applicazione transazionale. Chi invece preferisse un approccio più radicale, estremamente promettente ed in fase di rapida diffusione, può approfondire l'uso dei database documentali, tra i quali attualmente spicca MongoDB per numero di installazioni e tasso di crescita. Un altro interessante pattern trasversale è quello della dependency-injection, che instrada naturalmente ad uno sviluppo delle classi pulito, essenziale, modulare, nel rispetto dei principali parametri di qualità del software. Chi fosse interessato può approfondire la tematica cercando informazioni sui cinque principi della programmazione SOLID.

Dove trovare questo eserciziario

Questo eserciziario è distribuito sotto licenza GNU Free Documentation License all'indirizzo http://esercizicpp.sourceforge.net. Dal sito è possibile prelevare l'ultima versione disponibile, accedere ai forum dedicati ai lettori ed iscriversi alla mailing-list informativa.

Contattare l'autore

Commenti, suggerimenti e segnalazioni sono graditi. L'autore può essere contattato al seguente indirizzo e-mail: esposito.marce[at]gmail.com