Questo lavoro è dedicato a tutti coloro per i quali la tenacia, la passione e la curiosità per le cose del mondo rappresentano capisaldi della propria esistenza. Carlo A. Mazzone |
La programmazione è una forma di arte, così come possono esserlo la pittura, il disegno o la scultura. Realizzare un programma rappresenta, infatti, un processo di vera e propria creazione di un elemento che prende vita grazie al talento di un essere umano.
L’ente creatore in questione, nel contesto informatico, viene identificato con differenti nomi: programmatore, sviluppatore o anche developer. Si tratta in ogni caso di uno “strano essere” dotato di specifiche capacità e tecniche che gli consentono di istruire la macchina a realizzare ben determinate attività e funzionalità.
Questo testo vuole fornire gli strumenti di base per intraprendere il lungo viaggio che può portare un “umano” dotato di passione per le macchine a diventare un vero programmatore e quindi a dialogare con esse. Per farlo individua quelle che potrebbero essere definite “le chiavi della programmazione” nell’uso di due linguaggi che rappresentano elementi imprescindibili per un qualsiasi programmatore: C e C++.
La prima parte del testo è dedicata appunto al linguaggio C e consente, anche a chi si avvicina per la prima volta alla programmazione, di realizzare dei programmi di media difficoltà. In questa prima parte vengono infatti forniti non solo i rudimenti della sintassi del linguaggio ma anche, passo dopo passo, le indicazioni sui costrutti fondamentali della programmazione ed i concetti di base relativi alle strutture dati, sia di tipo semplice che complesso.
La seconda parte del libro inizia, anche metaforicamente, nel punto in cui si ferma il linguaggio C in termini di potenza e di strumenti dati al programmatore.
Viene presentato, infatti, il linguaggio C++ come logica e naturale conseguenza dei limiti del C e nella direzione di rendere possibile la creazione di programmi sempre più complessi e più facilmente manutenibili. E’ quindi in questa ottica che si espongono i concetti che sono alla base della programmazione orientata agli oggetti ed il loro uso nel contesto del C++.
Carlo A. Mazzone
ACQUISTA IL LIBRO
Il libro pubblicato da EDIZIONI FAG con ISBN 978-88-6604-361-4 è disponibile nelle principali librerie italiane ed acquistabile direttamente sui più importanti store online tra cui:
– AMAZON
– IBS
– HOEPLI
– SITO DELL’EDITORE FAG
ADOZIONE NELLE SCUOLE
Il testo è ideale come strumento didattico nella scuola. Infatti, esso fornisce agli studenti, con assoluta immediatezza, gli strumenti di base ed avanzati per l’acquisizione della teoria e della pratica della programmazione. Per semplificare le procedure per l’impiego del testo nelle proprie classi è disponibile un file in formato PDF con una specifica scheda di proposta di adozione; il link al file è disponibile QUI.
Struttura e contenuti del libro
Il testo è organizzato in due principali sezioni. La prima parte è introduttiva alla programmazione in linguaggio C presentando i concetti di base dello sviluppo software: strutture dati ed algoritmi che su di esse operano. Vengono così forniti i concetti relativi a variabili e costanti e ai principali costrutti di programmazione (sequenza, selezione, ripetizione) con abbondanza di esempi stimolanti anche per il lettore già avvezzo a tali argomenti. La prima sezione si chiude con la presentazione della struttura dati struct del C quale esempio di modalità complessa di gestione di dati ponendo le basi per le successive discussioni relative alla creazione di nuovi tipi di dati ed operatori.
Il capitolo 1 vuole fornire una base sostanziale rispetto ai concetti generali dell’informatica con speciale attenzione relativa a tutto ciò che riguarda lo sviluppo software. Viene innanzitutto presentata la dicotomia analogico-digitale e quindi, rispetto al contesto digitale, si fornisce una panoramica essenziale, ma corposa, relativa alla logica binaria ed alle tecniche di rappresentazione dei dati (ASCII ed Unicode).
Vengono introdotti i concetti e le descrizioni di base riguardanti i principali dispositivi hardware ed una panoramica del mondo del software sia in merito ad una semplice classificazione tipologica sia rispetto a ciò che attiene alla commerciabilità del software stesso.
Si introduce dunque il lettore al mondo dei linguaggi con indicazioni relative alla traduzione del codice: interpretazione, compilazioni e linguaggi bytecode.
Il primo capitolo termina quindi, motivando la scelta del linguaggio C come elemento cardine per tutte le discussioni di tipo operativo che verranno fatte nel prosieguo, con una carrellata in merito ai principali ambienti di sviluppo utilizzabili per produrre codice con tale linguaggio.
Il capitolo 2 introduce alla compilazione, passo dopo passo, del primo semplice programma C proponendo l’ambiente Bloodshed Dev-C++ come strumento principale da utilizzarsi per implementate tutti gli spunti di esempio e di esercizio proposti nella prima parte del testo. In ogni caso si presenta, per coerenza di contenuti e di discussione, anche l’ambiente Code::Blocks fornendo pure per questo secondo sistema le istruzioni di base per compilare un primo semplice programma C. Seppure il consiglio sia quello di utilizzare tale secondo ambiente di sviluppo per i contenuti della seconda parte del testo, relativi al linguaggio C++, nulla osta a sceglierlo come principale strumento sin dall’inizio. Tale scelta può essere obbligata nel caso si utilizzi una macchina del mondo Mac in quanto Dev-C++ è specifico per l’ambiente Windows. Il consiglio di utilizzare come primo ambiente proprio il Dev-C++ è motivato dalla maggiore semplicità d’uso dell’ambiente stesso che consente di meglio concentrarsi sugli aspetti del linguaggio. In ogni caso il lettore più esperto potrà scegliere lo strumento di sviluppo che più preferisce sin dall’inizio.
Nel capitolo 3 vengono introdotti i fondamentali concetti di variabile, costante ed enumerazione presentandone le varie tipologie unitamente ai consigli per una scelta corretta per i loro nomi e modalità d’uso. Per farlo si introduce da subito il lettore all’input ed output di base del linguaggio C. Iniziano già in tale capitolo una serie di suggerimenti di carattere generale che riguardano le buone pratiche di programmazione che, nel contesto specifico, sono relative all’usabilità dell’interfaccia utente.
Il capitolo 4 presenta il concetto cardine di algoritmo e fornisce spunti di esercizio in merito a semplici problemi risolvibili con l’ausilio dei diagrammi di flusso. La necessità di realizzare delle operazioni sui dati è la motivazione per l’introduzione dei principali operatori aritmetici e relazionali e la presentazione delle problematiche relative alla trasformazione di un dato da un certo tipo ad un altro.
Il capitolo si chiude con l’introduzione degli operatori logici e quindi con una panoramica sull’algebra di Boole.
Il capitolo 5 presenta i meccanismi relativi al debugging (verifica degli errori) delle applicazioni software sia in relazione all’ambiente Dev-C++ che all’ambiente Code::Blocks. Vengono così proposti i concetti di punto di interruzione (breakpoint) e poste sotto osservazione specifiche variabili utilizzando esempi concreti.
Nel capitolo 6 vengono fornite indicazioni dettagliate, corredate da esempi d’uso, relative alle istruzioni condizionali consentendo così ai programmi presentati un livello di complessità sicuramente maggiore rispetto agli esempi iniziali.
Il capitolo 7 completa la presentazione relativa ai costrutti fondamentali di programmazione introducendo il costrutto iterazione. Vengono così messi a confronto i cicli for e while cercando di evidenziare al meglio il loro campo di applicazione. In questo ambito si discute quindi di programmazione di tipo strutturato come superamento delle problematiche legate alla cosiddetta spaghetti programming.
Nei capitolo 8 e 9 vengono introdotte le strutture dati di tipo complesso. Vengono così presentati gli array monodimensionali con una dettagliata panoramica relativa alle problematiche connesse al trattamento delle stringhe. Successivamente è il turno degli array bidimensionali subito dopo i quali si coglie l’occasione per illustrare la possibilità di generare numeri casuali. In tal modo si rendono disponibili gli strumenti che consentono la realizzazione di programmi autonomi rispetto all’input del programmatore o dell’utente.
Il capitolo 10 presenta il concetto di algoritmo notevole come esempio di risoluzione di problemi effettuati utilizzando metodologie consolidate nella letteratura e dalla pratica informatica. Nello specifico vengono esaminati in dettaglio gli algoritmi di ordinamento selection sort e bubble sort con accenni a concetti di complessità computazionale.
Il capitolo 11 prende in esame l’approccio alla programmazione software di tipo Top-Down introducendo concetti ed esempi reali relativi a procedure e funzioni. E’ il contesto giusto in cui possono essere quindi definiti diversi dettagli relativi ai concetti di visibilità e ciclo di vita delle variabili presentando inoltre le classi di memorizzazione esterne e statiche.
Nel capitolo 12, ormai noto il concetto di funzione, se ne presenta una tipologia molto particolare: la funzione ricorsiva. Vengono così proposti concetti ed esempi relativi al calcolo del fattoriale ed alle sequenze di Fibonacci.
Il capitolo 13 presenta i puntatori, argomento per sua natura ostico. Data la particolarità del tema si cerca di motivarne il più possibile l’utilizzo analizzando prima i collegamenti tra puntatori ed array e facendo successivamente vedere quale sia il collegamento tra puntatori e funzioni esaminando le chiamate per valore e per indirizzo delle funzioni stesse.
Il capitolo 14 descrive la struttura dati struct del C motivandone l’uso come contenitore fondamentale per raggruppare dati di tipo complesso ma tra di essi omogenei. Tale capitolo rappresenta un punto di snodo dell’intero viaggio nella programmazione in quanto si iniziano a delineare i limiti dello sviluppo del software utilizzando il linguaggio C e l’approccio di tipo procedurale. Vengono così enfatizzati gli aspetti relativi al trattamento dei dati introducendo la parola chiave typedef per la definizioni di nuovi tipi e le strutture dati union e campi di bit.
Con il capitolo 15 si chiude la prima sezione del libro focalizzata sugli elementi del C facendo vedere come vengano gestiti i file utilizzando l’approccio proprio di tale linguaggio di programmazione.
Il capitolo 16 apre dunque la seconda sezione del testo presentando sin da subito le prime discussioni critiche sull’approccio che utilizza il paradigma ad oggetti nella programmazione software. Preparando il lettore per lo sviluppo di applicativi di sempre maggiore complessità si definiscono le problematiche proprie della corretta progettazione del software come momento fondamentale ma preliminare alla scrittura del codice stesso. Si introducono quindi i concetti di ciclo di vita nello sviluppo software e di conseguenza vengono presentati gli ambiti propri dell’ingegneria del software. Il capitolo si chiude con una panoramica sulle modalità di versioning.
I capitoli 17 e 18 introducono nel dettaglio sintassi ed approccio alla programmazione del linguaggio C++. In tale ambito si suggerisce l’utilizzo dell’ambiente di sviluppo Code::Blocks fornendone le specifiche d’uso di massima. Vengono da subito introdotti i concetti di spazio dei nomi delle variabili e come queste possano variare la loro visibilità nei differenti blocchi di codice. Il capitolo 18 è specifico e dettagliato rispetto alle funzionalità di input e output proprie del C++.
Il capitolo 19 presenta finalmente i concetti di classe ed oggetto. E’ un momento fondamentale nel quale si mostra come, a partire da una struct del C, si possa costruire un oggetto di programmazione inserendo al suo interno la possibilità di realizzare delle specifiche azioni attraverso l’utilizzo di apposite funzioni. Si discute quindi di incapsulamento ed occultamento dell’informazione e di come si possa di conseguenza comunicare con gli oggetti.
Il capitolo 20 fornisce la sintassi per la gestione del ciclo di vita degli oggetti relativamente alla loro creazione e successiva distruzione. Il capitolo presenta inoltre le modalità per la cosiddetta compilazione separata ovvero la possibilità di organizzare il proprio codice in differenti file, operazione indispensabile al crescere delle dimensioni dei propri programmi.
I capitoli 21 e 22 completano la descrizione delle proprietà fondanti della programmazione orientata agli oggetti descrivendo polimorfismo ed ereditarietà. Infatti, il capitolo 21 continua l’analisi delle caratteristiche degli oggetti fornendo dettagli sul polimorfismo, contrapponendolo al comportamento monomorfico delle funzioni C, relativamente alla tecnica dell’overloading. Il capitolo 22, d’altra parte, introduce il concetto di ereditarietà e quindi la possibilità di riutilizzare al meglio il codice già scritto per ampliarlo adattandolo a nuove necessità. E’ in questo contesto che si presentano le classi virtuali ed astratte.
Il capitolo 23 presenta la programmazione generica e quindi l’uso dei template. Si illustra così come sia possibile realizzare un approccio alternativo al polimorfismo classico, usando funzioni e classi parametriche, nell’ottica di produrre codice sorgente il più efficiente e generico possibile in merito alle aspettative del programmatore.
Nel capitolo 24 si riprende la discussione già affrontata nel capitolo 15 in relazione alla gestione dei file e degli archivi. In questo contesto si affronta però l’approccio usato dal linguaggio C++ mostrando una diversa metodologia per un comune problema e dando al contempo la possibilità di esplorare dettagli ulteriori della programmazione C++ e della libreria standard. Ancora una volta viene confermato lo spirito pragmatico del testo dando indicazioni dettagliate per la realizzazione di una piccola ma reale applicazione di gestione di un archivio di dati.
Il capitolo 25 affronta le problematiche connesse alla gestione degli errori e propone gli strumenti messi a disposizione dal linguaggio C++ per prevenire e gestire al meglio le condizioni anomale nelle quali possono venire a trovarsi le nostre applicazioni. Viene così proposto il concetto relativo alle eccezioni ed il costrutto try – catch per la loro corretta gestione.
Il capitolo 26 torna sulle questioni attinenti alla gestione della memoria focalizzando l’attenzione sulle corrette procedure da utilizzarsi per superare i vincoli imposti dalle dimensioni fisse richieste nella dichiarazione di variabili statiche automatiche. Si discute quindi di allocazione dinamica della memoria confrontando stack ed heap e dando adeguati suggerimenti per evitare situazioni potenzialmente disastrose come i memory leaks.
Il capitolo 27 chiude il viaggio attraverso la programmazione e nel C/C++ fornendo degli spunti relativamente alla realizzazione di applicazioni con interfaccia grafica. Alle tante possibili declinazioni relative alla creazione di applicazioni di tipo grafico si preferisce l’approccio basato sulle funzioni native di Windows. Tale scelta risulta sufficientemente generica da fornire la giusta panoramica per comprendere i fondamenti dello sviluppo di applicazioni grafiche utilizzando la metodologia nota come programmazione guidata da eventi.
SCARICA IL CODICE DI ESEMPIO
Un file in formato PDF con i principali esempi ed esercizi di codice sorgente proposti nel testo è disponibile QUI.
L’AUTORE: Carlo A. Mazzone
Laureato in Scienze dell’Informazione, è docente di Informatica nella Scuola Superiore e consulente informatico. Programmatore, sistemista e divulgatore informatico, si occupa di sviluppo software da circa trent’anni.
ERRATA CORRIGE
PRIMA EDIZIONE – Novembre 2013
A pagina 192 i nomi degli array x ed y nell’implementazione della funzione int strTest(char x[], char y[]) vanno sostituiti rispettivamente con i nomi a e b.