Pagina didattica di G. Servizi
Home >> Linguaggio C++


livello minimale

Per cominciare...

per andare oltre...

Ogni documento di questo percorso di conoscenza corrisponde a un diverso livello di apprendimento del linguaggio C++, secondo la scaletta indicata appresso. Il livello di pertinenza del documento sarà riportato al suo esordio.

BUON LAVORO: si comincia.

Avvertenze: iniziando questo viaggio alla scoperta del C++, resistete, durante la prima lettura, e magari anche durante la seconda, o la terza, alla tentazione di disperdervi inseguendo i diversi link che incontrerete e la cui presenza, peraltro, si cercherà di contenere il più possibile. Limitatevi a seguire la traccia e a cercare di comprendere compiutamente ciò che vi vien detto man mano che procedete; IMPADRONITEVI del lessico, così da cominciare a riconoscere locuzioni che avete già incontrato e a capire di che cosa si sta parlando; ponete attenzione alle sottolineature e agli elenchi puntati, piuttosto che ai link: sono lì apposta per attirare la vostra attenzione.
Solo quando avrete terminato il percorso completo, e ammesso che sia un percorso netto, comincerete ad approfondire i concetti seguendo i link e/o andando a leggere direttamente altre pagine di questo sito.
Dovrebbe essere scontato che, visto che la lettura di questa guida presuppone il fatto di essere seduti davanti a un calcolatore, sia ALTISSIMAMENTE RACCOMANDABILE che eseguiate i codici che via via sono proposti; il che significa che è ALTRETTANTO ALTISSIMAMENTE RACCOMANDABILE, direi anzi INDISPENSABILE, che il vostro calcolatore sia capace di consentirvelo, ossia che sia configurato in maniera adeguata.
Questo implica, tanto per esser chiari, che abbiate a disposizione un sistema operativo SERIO, ossia Linux o in versione nativa o almeno virtualizzato e che lavoriate in modo altrettanto SERIO, tenendovi a disposizione sul monitor NON PIÙ DI TRE SOLE finestre: quella in cui state leggendo, quella di un editor (cfr. appresso) in cui ricopierete e salverete i codici e quella di una shell, vale a dire una finestra in cui sia in esecuzione l'interprete dei comandi bash alla quale darete l'incombenza di compilare ed eseguire i vostri programmi.

Canto zero: dal nulla all'esecuzione del PRIMO programma



int main(   ){   }

Questo è il programma C++ più breve che possa essere scritto senza che il compilatore segnali alcunché di errato, e che può essere formalmente eseguito con successo quantunque non faccia assolutamente nulla. Come tale presenta quanto ci deve essere di irrinunciabile in un normale documento di testo per poter affermare che si tratta di un programma scritto in C++, vale a dire:


L'unica spaziatura necessaria è quella che separi la parola int dalla parola main; oltre a questa ne possono essere inserite quante altre se ne vogliano in qualsiasi posizione purché non si spezzino le due uniche parole presenti nel testo, che devono essere considerate a tutti gli effetti come gli atomi di Democrito. In altri termini, se il testo presente si riscrive così:

int        main

(

                 ){



}

al compilatore va altrettanto bene, anche se vien da chiedersi quanto abbia bevuto l'autore del codice, mentre non verrebbe accettato se fosse scritto:

int ma    in(  ){  }

a causa della spaziatura illecita che spezza la parola main.
Il programma nullafacente fin qui introdotto va scritto, ovviamente, in un documento di testo usando esclusivamente un normalissimo text editor, assolutamente NON un word processor. Per intendersi si rifugga dall'idea di scrivere codici C++ usando programmi comunemente denominati suites per ufficio (word, wordpad, office et similia) dato che questi introducono nel documento pletore di bytes di formattazione che il compilatore rifiuterebbe come la peste, e lo fanno alla piena insaputa dell'autore del codice.
Un text editor (gedit, emacs, kate et similia) invece, introduce nel documento solo ed esclusivamente i caratteri che la mente del programmatore, guidando i polpastrelli delle sue stesse dita sulla tastiera, intende effettivamente e volontariamente che siano inseriti.

Molti text editors, per giunta, non sono affatto stupidi e sono in grado di riconoscere le parole appartenenti al vocabolario del linguaggio e molti dei suoi costrutti sintattici, evidenziandoli con colori convenzionali che sono di considerevole aiuto durante la redazione del codice.
Il nome del documento che contiene il testo del programma è a totale discrezione dell'autore, ma è molto opportuno che termini con una delle sequenze di caratteri preferite dal compilatore che sono:

.c      .C        .cc      .cpp        .CPP      .c++        .cp      .cxx       

Se qualcuno/a volesse fare l'originale e battezzare il proprio documento contenente il programma con lo stesso nome della/del sua/o ragazza/o, si vada a cercare nelle 181 pagine della documentazione del compilatore quale opzione deve fornirgli affinché sia disposto a ignorare il fatto che il nome del documento ha un suffisso sconosciuto.

Siccome io non ho tempo da perdere, e non ho neppure la ragazza, supporrò senz'altro che il nome del documento contenente il programma sia

            pippo.C

e, per compilarlo, ossia per tradurlo in codice binario eseguibile dal processore, sarà sufficiente dare alla shell il comando

             g++    -std=c++11   pippo.C

La shell risponderà ripresentando semplicemente il proprio prompt, ossia disponendosi a ricevere il comando successivo, beninteso se il compilatore C++ è correttamente installato, altrimenti risponderebbe Comando non trovato o altre amenità.

L'opzione -std=c++11 attiva l'interpretazione del codice nello standard 2011 del linguaggio: è disponibile sul compilatore GNU di Linux dalla versione 4.7; se qualcuno ha una versione precedente si suggerisce o un aggiornamento del sistema, oppure NON USARE costrutti sintattici propri di quello standard. La prima opzione è caldamente raccomandata.

Per evitare di dovere scrivere sempre quell'opzione si potrebbe creare un cosiddetto alias del comando che la contempli implicitamente, ad esempio inserendo nel documento di configurazione della propria shell una linea del tipo

alias g++='/usr/bin/g++ -std=c++11'

Frattanto, in un modo o nell'altro, il compilatore avrà creato nella cartella corrente un nuovo documento dal nome criptico

            a.out

che contiene appunto il codice eseguibile e può essere mandato in esecuzione digitando             ./a.out

terminato con Invio: il TASTO Invio, NON la parola I-n-v-i-o, a destra del prompt della shell: non accadrà nulla, se non la reiterazione del prompt.
Evidentemente per ottenere qualcosa occorre inserire delle istruzioni nel programma e queste vanno poste all'interno dell'ambito di main, ossia entro le graffe; ad esempio, per far apparire sul terminale il risultato di 2+2, si potrebbe scrivere

#include <iostream>
int main(   )
{std   ::    cout << "2+2 fa " << 2+2 << '\n';}


Come si vede, la semplice introduzione di un'istruzione, meglio dire: un'espressione, che produca un risultato così banale ha provocato la comparsa sulla scena di parecchi nuovi personaggi:

Compilando novamente pippo.C con l'attuale contenuto e rieseguendo ./a.out (FATELO!) si vedrà apparire sul terminale la confortante affermazione

2+2 fa 4

seguita, a capo, dal prompt della shell.

Naturalmente il linguaggio consente applicazioni migliori di quella appena riportata: tanto per procedere gradualmente si potrebbe fare in modo che il programma sia capace di eseguire qualsiasi addizione i cui due addendi siano, in qualche modo, forniti dall'esterno all'atto dell'esecuzione. Questo, per inciso, è insito nel concetto stesso di programmazione: un programma non dovrebbe mai conoscere a priori il valore numerico dei propri dati. Un modo per farlo è il seguente:

#include <iostream>
using namespace std;

int main(   )
{double a, b;
cout << "fornisci i due addendi ", cin >> a >> b,
cout << a << '+' << b << " fa " << a+b << '\n';}

Si osservi che, rispetto alla versione precedente, non compare più alcuna costante numerica ma solo costanti carattere e costanti stringa; si sono invece introdotte due variabili (a, b) che sono state dichiarate appartenenti al tipo double immediatamente dopo l'apertura della parentesi graffa. La virgola che separa a da b e il punto e virgola conclusivo sono obbligatori in una dichiarazione.
I valori numerici delle due quantità sono richiesti direttamente all'utente all'atto dell'esecuzione del programma e sono introdotti nella sua memoria da parte dell'oggetto cin che svolge una funzione speculare rispetto a quella dell'oggetto cout, vale a dire che estrae dati, attraverso l'operatore >>, dal cosiddetto standard input che, salvo avvisi contrari, coincide con la tastiera del calcolatore.
Quando l'esecuzione del programma giunge a elaborare la sottoespressione
cin >> a >> b,
l'esecuzione stessa si arresta in attesa che qualcuno digiti sulla tastiera qualcosa di riconoscibile come due numeri separati da uno spazio e terminati da Invio. I termini qualcosa di riconoscibile sono voluti: significano che se si digita del ciarpame il programma, così com'è scritto, potrebbe arrestarsi o concludersi con esiti fantasiosi.
Si osservi anche la seconda riga qui introdotta (using namespace std;) che consente di riferirsi all'oggetto cout, e anche all'oggetto cin, senza più dovere, ogni volta, citare anche il cosiddetto namespace (std ::) in cui tali oggetti sono stati descritti al compilatore, perché tale namespace si conviene ora che sia sottinteso come, in pratica, recita la seconda riga. Ciò è estremamente conveniente, specialmente quando, come accade sostanzialmente sempre, gli oggetti cout, cin e molti altri debbano essere usati numerose volte: ecco il motivo per cui, di fatto, QUASI TUTTI i programmi C++ iniziano con le due righe qui riportate.
Ricompilando e rieseguendo il programma, come sopra spiegato, si vedrà apparire sul terminale la frase:

fornisci i due addendi

con alla destra il cursore lampeggiante: il programma, a quel punto, sta valutando la sottoespressione:

cin >> a >> b,

e quindi, per poterne venire a capo con successo, occorre appunto fornirgli due numeri, come gli è stato opportunamente detto di richiedere e come già è stato spiegato.
Se si ottempera alla richiesta comparirà, immediatamente dopo la pressione di Invio, il corretto risultato dell'addizione; se invece si digiterà la vispa teresa... provate e vedrete.

NOTA BENE: se si vogliono fornire valori non interi la virgola deve essere in realtà un punto; in altre parole il valore approssimato a due cifre decimali di pi greco va dato come 3.14 NON come 3,14.

È del tutto evidente che le altre operazioni aritmetiche elementari saranno trattabili allo stesso modo utilizzando gli opportuni operatori, dotati già delle corrette regole di precedenza. La doverosa cautela contro l'eventualità delle divisioni per zero è a carico dell'autore del codice: se si provasse a sostituire, nel programma precedente, l'addizione con la divisione e si digitasse apposta, per la variabile b, il valore 0, si avrebbe come risultato inf, abbreviativo di infinito, se il dividendo fosse non nullo e nan, acronimo di Not A Number, se anche il dividendo fosse nullo.

Per concludere quest'introduzione si farà osservare come, in generale, un programma C++ possa essere concepito come un insieme di funzioni che sono eseguite in un certo ordine stabilito dal programmatore, la prima funzione eseguita essendo sempre quella chiamata main, eventualmente, come si è fin qui visto, unica. Come esempio si tratteranno appunto le quattro operazioni artitmetiche elementari, la cui valutazione, piuttosto che effettuata come prima in main, sarà demandata a quattro distinte funzioni dal nome parlante. Ecco il codice (compilatelo ed ESEGUITELO):

#include <iostream>
#include <cstdlib>
using namespace std;

double quoziente(double dividendo, double divisore)
{return dividendo / divisore;}

double prodotto(double moltiplicando, double moltiplicatore)
{return moltiplicando * moltiplicatore;}

double differenza(double minuendo, double sottraendo)
{return minuendo - sottraendo;}

double somma(double addendo_uno, double addendo_due)
{return addendo_uno + addendo_due;}

int main(int narg, const char * * args, const char ** env)
{double a = atof(args[1]), b = atof(args[2]);
cout
<< a << '+' << b << " fa " << somma(a, b) << '\n'
<< a << '-' << b << " fa " << differenza(a, b) << '\n'
<< a << '*' << b << " fa " << prodotto(a, b) << '\n'
<< a << '/' << b << " fa " << quoziente(a, b) << '\n';}

Da questo breve programma si imparano molte cose, ossia:

per continuare...
Torna in cima alla pagina