C++ ... per provare....



Questo non è un corso di C++ perchè non conosco bene questo linguaggio e mai riuscirò ad impararlo, non fosse altro che per un fattore età. Solo per curiosità personale ci metto le mani, tornando un po' ai miei primordi o quasi, condividendo le mie piccole e inutili applicazioni a puro scopo illustrativo, caso mai qualcuno ci trovasse qualche spunto per iniziare. Non aspettatevi niente di particolare. La domanda che vi potrete fare è: perchè? Perchè il C++ ha, per me, il fascino degli strumenti realmente potenti, perchè è veloce, perchè nella versione del nuovo standard, il C++11, appare come un linguaggio quasi nuovo e sicuramente molto più moderno di quanto lo facesse apparire il precedente standard. Da qui lo stimolo per riscoprire uno strumento che mi fa tornare indietro di 20 anni.

Hello, World

Come pensavate che avrei iniziato?

  Esempio 1.1
1
2
3
4
5
6
#include<iostream>
int main()
{
  using namespace std;
  cout << "Hello, World!";
}

La riga 1 include nel nostro programma un file esterno, nel caso specifico iostream tramite la direttiva #include. La sintassi è quella che prevede il nome del file posto all'interno di una coppia < >. In altri casi si usano i doppi apici. Il contenuto del file iostream viene aggiunto al nostro programma. I file come iostream sono chiamati, usando la terminologia inglese, include files o header files. Essi non hanno estensione mentre in passato terminavano con .h (ad esempio iostream.h).
In particolare iostream è una libreria object oriented che prevede molte potenti funzionalità per la gestione dell'input / output.
La riga 2 introduce l'entry point del programma gestito tramite la chiamata ad un metodo, main. Ogni programma vuole la presenza di questo metodo, altrimenti non parte.
La riga 4 dice al compilatore che stiamo usando lo spazio standard dei nomi. Questa istruzione che è una direttiva,  serve per identificare univocamente le classi di iostream. Senza questa istruzione il compilatore si lamenterebbe:
error C2065: 'cout' : undeclared identifier
Tuttavia è possibile indicare ugualmente il namespace std esplicitandolo. Ovvero è possibile eliminare la riga 4 dal programma e scrivere la 5 come:

std::cout << "Hello, World";

La riga 5 presenta un oggetto, cout, appartenente alla classe ostream (in pratica ne è un'istanza) che rappresenta lo standard output. Proprio cout è devoluto al controllo dello standard output, in questo caso, e di solito, si tratta della console. Accanto a cout compare un operatore, ovvero <<. Questi, anch'esso appartenente alla classe ostream,  non fa altro che "inserire" la stringa che segue nell'oggetto che << stesso "punta". Quindi nella riga 5 la stringa "Hello, World!" viene data in pasto tramite l'operatore << all'oggetto cout che, come abbiamo visto, è di tipo ostream. Il nostro << si occupa di output formattato, vedremo altri operatori che si occupano di quello non formattato. Il formato generale:

strm << valore

dove strm è un oggetto di tipo ostream. Nel nostro esempio strm è cout, ovvero lo standard output, quindi il video.

Come potrete intuire esiste anche il modo per gestire l'input e quindi andiamo con l'esempio:

  Esempio 2.1
1
2
3
4
5
6
8
9
10
11
12
#include<iostream>
#include<string>

int main()
{
using namespace std;
cout << "Inserisci il tuo nome: ";
string input = "";
cin >> input;
cout << "ciao, " << input;
}

La riga 2 ci permette di usare le stringhe, come è evidente. Più interessante è la riga 10 dove fa la sua comparsa quel "cin" che, come intuibile, è la controparte di cout relativa alla gestione dell'input. Similmente, cin è un oggetto della classe istream che si occupa, appunto, dell'input. E' presente l'operatore >> che inserisce l'input in ciò che segue, in ciò che viene puntato. Questo "cin" è tanto bello e semplice quanto insidioso. Alcuni problemi sono:

--- non effettua alcun type check
--- si porta dietro il carattere di newline inserito quanto battete il tasto enter
--- se inserite due stringhe separate da un spazio si farà carico solo della prima mentre perderete la seconda. Provare per credere.

Per questo motivo il modo migliore di gestire l'input è quello di usare getline(). A questo comando corrisponde una funzione globale, apparetenente alla libreria string ed è così definita:

getline(param-1, param-2, param-3 (opzionale))

param-1 è un puntatore ad una funzione dalla quale vengono estratti i caratteri, param-2 è ciò in cui i caratteri vengono memorizzati, mentre param-3 è un delimitatore, ovvero un carattere di stop (teniamo presente che se il carattere di stop viene indicato esplicitamente allora deve essere presente). Di default tale carattere è il newline e, nei casi semplici come quelli di questo paragrafo, viene omesso. Quindi tramite getline è possibile gestire una intera linea di input. Modifichiamo quindi l'esempio precedente:

  Esempio 3.1
1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
#include<string>

int main()
{
using namespace std;
cout << "Inserisci il tuo nome: ";
string input = "";
getline(cin, input);
cout << "ciao, " << input;
}

Anticipio subito che getline lavora sulle stringhe quindi se abbaimo bisogno di un valore numerico ci serve una conversione. Tra i vari modi c'è il seguente che effettua la conversione utilizzando la classe stringstream. Tenendo presente che magari non è il modo migliore ecco qua il codice:

  Esempio 4.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main()
{
string input = "";
int myNumber = 0;
cout << "Inserisci un numero: ";
getline(cin, input);
stringstream myStream(input);
myStream >> myNumber;
cout << "Numero inserito: " << myNumber << endl << endl;
return 0;
}

Terminiamo introducendo i commenti_

// per commenti su singola riga
/*....*/ per commenti su più righe. I commenti non possono essere innestati, ovvero non potete fare qualcosa del genere:

/*.... /*......*/....*/