PROGRAMMAZIONE: LA GUIDA DI LUCIO
Questa introduzione ha lo scopo di presentare, anche attraverso brevi esempi, gli elementi fondamentali della programmazione in linguaggio c++: variabili, funzioni e costrutti di base (if statement e loop).
DAL CODICE ALL’ESECUZIONE
Per eseguire il codice che scriviamo in linguaggio macchina bisogna utilizzare un compilatore, che trasformi tutto in codice binario (0 1). Questo sarà poi eseguito dal computer stesso.
DA DOVE PARTIRE?
Per impostare l’ambiente di programmazione è necessario installare un IDE che ti permetta di eseguire il codice. Qui trovi una breve guida che presenta le principali soluzioni per tutti i sistemi operativi: C++, compilatori e IDE (ambienti di sviluppo).
Anche consigliatissimo il canale (inglese): The Cherno – C++
Per poter eseguire un codice in c++ è sufficiente digitare le istruzioni che vogliamo eseguire all’interno di main():
#include using namespace std; int main() { cout << "ciao a tutti" << endl; return 0; } |
è una libreria con le funzioni fondamentali di c++. Ma la cosa realmente interessante è cout, che permette di restituire alla console (l’output del nostro programma) quello che preferiamo: infatti quando eseguiamo questo codice otteniamo “ciao a tutti”. endl interrompe la linea (si può utilizzare anche n all’interno della stringa).
STRUTTURE FONDAMENTALI: VARIABILI E FUNZIONI
Variabili
Per comprendere l’idea base delle variabili possiamo costruire un’analogia con un contenitore: questo ha un contenuto (diverso a seconda di dimensione e tipo) e un nome (che ci auguriamo ne descriva il contenuto). Per creare una variabile è quindi necessario scegliere il tipo di contenuto che dovrò inserire e attribuire a questo un’etichetta, per renderlo riconoscibile:
Ricordandoci qui che è necessario mettere tra virgolette le informazioni di testo.Qui ho inserito il valore 2 in una scatola che si chiama a e accetta solo contenuti che siano numeri interi (int appunto). Allo stesso modo posso creare una stringa di testo:
int a = 2; |
Qui ho inserito il valore 2 in una scatola che si chiama a e accetta solo contenuti che siano numeri interi (int appunto). Allo stesso modo posso creare una stringa di testo:
string nome = "Lucio"; |
Ricordandoci qui che è necessario mettere tra virgolette le informazioni di testo.
intero | int | int a = 2 |
punto decimale | float | float b = 2.45 |
carattere | char | char lettere[2] = "ab" |
stringa | string | string testo = "informazione" |
liste | tipo nome[x] | int num[3] = {1, 2, 3} |
vero/falso | bool | bool piove = true |
vuoto | void | / |
Alcune osservazioni
- Dichiarare una variabile significa allocare uno spazio nella memoria di tanti bit quanti quelli richiesti dal suo tipo. In altre parole, scrivendo così:
int a; |
è come se dicessimo al computer di tenerci uno spazio per uno scatolone chiamato a che ancora non abbiamo, ma siamo sicuri ci servirà in futuro.
- Assegnare una variabile è l’operazione che ci permette di attribuire un valore a una dichiarazione già fatta, inserire quindi qualcosa all’interno della nostra scatola, così:
a = 2; |
ora a contiene il valore 2, quindi il codice:
cout << a; |
restituirà 2 in console.
- Riassegnare una variabile corrisponde a eliminare il suo contenuto attuale e inserirne uno nuovo:
a = 5; |
ora a vale 5. Bisogna ovviamente fare attenzione a non sbagliare tipo di contenuto:
a = "ciao"; |
si direbbe assegnazione invalida: è chiaro! Non si può mettere una stringa in una scatola fatta per ospitare numeri interi.
- Per creare delle liste è necessario specificarne la lunghezza e il tipo dei contenuti (così come riportato nella tabella). Accedere a un singolo elemento è molto semplice:
int lista[3] = {4, 5, 6}; cout << lista[1]; |
questo codice ritorna 5, infatti in informatica si inizia a contare dallo 0.
È possibile anche creare delle liste a più di una dimensione, fondamentalmente delle matrici. Una matrice 2×2 si può implementare come segue:
int M[2][2] = {{11, 12}, {21, 22}}; |
in questo caso gli argomenti corrispondono agli indici; per ottenere 12, dobbiamo digitare:
cout << M[0][1]; |
Operazioni elementari
È naturale voler calcolare le operazioni elementari matematiche con i numeri interi (int) e i decimali (float).
somma | + |
differenza | – |
prodotto | * |
quoziente | / |
resto divisione | % |
Queste nozioni permettono di scrivere il codice:
int a, b; cin >> a; cin >> b; int somma = a + b; cout << somma << end1; |
che, presi due valori interi immessi dall’utente, ritorna la loro somma.
Per accedere a numerose funzioni matematiche è sufficiente aggiungere come header:
#include |
Un’osservazione
- Abbiamo utilizzato per la prima volta cin : questo comando permette di acquisire un input dall’utente e di inserirlo in una variabile precedentemente dichiarata. Da notare come si scriva cout << “messaggio” e cin >> variabile.
Funzioni
Si possono dividere le funzioni in due categorie:
A. una macchina che, ricevuti dei valori (gli argomenti), effettua un processo con questi e restituisce poi un risultato (return);
B. oppure una macchina che semplicemente effettua un’azione.
Le funzioni hanno a loro volta un nome e un tipo, analogamente alle variabili. Una funzione si può:
- Dichiarare: dire al programma che in futuro ci servirà quel tipo di funzione:
A | B |
int somma(int a, int b); | void saluta(); |
- Definire: scrivere l’operazione che deve svolgere la funzione (questo può essere fatto anche dopo aver definito main())
A | B |
int somma(int a, int b) { return a + b; } | void saluta() { cout << "ciao a tutti" << endl; } |
- Chiamare / eseguire una funzione: all’interno di main() è possibile utilizzare il codice scritto altrove digitando semplicemente:
A | B |
cout << somma(2, 3); // console out 5 | saluta(); //console out "ciao a tutti" |
Alcune osservazioni
- Funzioni con lo stesso nome, ma di tipo diverso o con un numero diverso di argomenti sono indipendenti fra loro e il programma le considera funzioni diverse.
- È possibile inserire un argomento di default, da utilizzare se non viene specificato quando si chiama la funzione:
void saluta(string nome="Lucio") { cout << "Ciao " << nome << endl; } int main() { saluta(); //console out "Ciao Lucio" saluta("Marco"); //console out "Ciao Marco" return 0; } |
In questo caso “Lucio” è l’argomento di default e viene utilizzato a meno che non ne venga fornito un altro (per esempio “Marco”).
ELEMENTI LOGICI E LOOP
IF statement
La prima cosa che potremmo voler fare in programmazione è il confronto: se una condizione è vera, allora fai questo:
int a = 2; if(a > 0) { cout << a << " è maggiore di 0" << endl; } |
Potremmo essere più ambiziosi! Se non è vera, ergo altrimenti, posso eseguire altro codice, anche ponendo ulteriori condizioni qualora volessi:
int a = 2, b; cout << "a vale 2, inserisci b: "; cin >> b; if(a > b){ cout << a << " è maggiore di "<< b << endl; }else if(a == b){ cout << a << " è uguale a "<< b << endl; }else{ cout << a << " è minore di "<< b << endl; } |
Ottimo! Esiste però anche un modo più corto per scrivere la stessa cosa. Se volessimo verificare a>4 e restituire il verdetto, potremmo scrivere:
int a = 2; string testo = (a > 0) ? " è maggiore di 0" : " è minore di 0"; cout << a << testo << endl; |
SWITCH statement
Se conoscessimo già un numero fisso di casi, potremmo preferire questa sintassi a quella condizionale:
int n; risposta: cout << "Sei soddisfatto di queste spiegazioni? (si = 1, no = 0)"; cin >> n; switch(n){ case 0: cout<<"mi dispiace :("<<endl; break; case 1: cout<<"sono contento che il corso ti sia utile!"<<endl; break; default: cout<<"non hai scelto né 1 né 0" <<endl; goto risposta; break; } |
Se sappiamo che le risposte a una domanda sono finite (giorni della settimana, indice di apprezzamento, ecc.) possiamo utilizzare lo switch statement.
Alcune osservazioni
- Per eseguire confronti si possono usare i seguenti simboli:
Operatori condizionali | |||
maggiore | > | minore | < |
maggiore uguale | >= | minore uguale | <= |
uguale | == | diverso | != |
- Se si volessero verificare due o più condizioni allo stesso tempo, è possibile stabilire se entrambe devono essere rispettate (AND):
if(a > 2 && a < 10)
oppure se solo una delle due deve essere vera (OR):
if(a > 2 || a < 10)
- All’interno dello switch statement compare break dopo ogni caso. In pratica, quando un caso è vero, si esce subito dal blocco di codice e si interrompe la verifica. Se nessun caso rispetta l’input, si esegue il caso default.
- Ultima cosa: il goto permette di riprendere l’esecuzione in un punto dove si è lasciato un segnaposto. Nel nostro caso risposta permette di ripetere l’algoritmo se l’utente ha sbagliato a inserire i valori: quando si digita goto nome_del_segnaposto si torna al punto dove abbiamo scritto nome_del_segnaposto: (con un’indentazione, TAB).
FOR loop
Dove la programmazione ci viene molto utile è nel ripetere task ripetitivi, come contare da 1 a 10:
for (int i = 1; i<=10; i++){ cout << i << endl; } |
oppure calcolare il fattoriale di un numero (n!):
int n; cout << "inserisci un valore per calcolare n! : "; cin >> n; int risultato = 1; for (int i=1; i<=n; i++){ risultato *= i; } cout << risultato << endl; |
Questo è possibile appunto grazie ai loop, ne esistono diversi ma l’idea è simile. A seconda di quello che vogliamo fare alcuni sono più comodi di altri. Il FOR loop si può leggere così: fissato un intero i (int i = 1), fino a quando i rispetta una determinata condizione (i <= n), aumenta i di 1 (i++) e esegui questo codice (tra parentesi graffe {}).
WHILE loop
Fino a quando (while appunto) una condizione è vera esegue il codice:
Questo permette sempre di calcolare il fattoriale, ma si presenta più diviso rispetto al FOR loop: int i = 1 è fuori dal loop, la condizione è tra parentesi (i <= n) e infine l’iterazione (i++) si trova all’interno. Può essere utile in casi come:algoritmo che permette di trovare il più grande divisore di un numero n. Decisamente poco efficiente come metodo… ma rende l’idea.
Alcune osservazioni
- Abbiamo sempre aumentato i (nome classico della variabile iterativa, ma si può scegliere quello che si preferisce) di 1, con i++, ma è possibile anche fare i+=2 per aumentarlo di 2 unità. Oppure prendere float i = 0 e aumentarlo di punti decimali, a seconda della necessità. NB: i++ corrisponde a i += 1.
- Break, già incontrato, e continue permettono di uscire dal loop al verificarsi di una condizione:
break: completamente dal loop e prosegue nel codice (come nell’utilizzo sopra)continue: salta soltanto un passo dell’iterazione e rientra nel loop a quella successiva
for(int i=0; i<10; i++){ if(i>3 && i < 8){ continue; } cout << i << endl; }
restituisce in console: 0, 1, 2, 3, 8, 9.
APPLICAZIONI ED ESEMPI
Calcolatrice
char op; float num1, num2; cout << "Inserisci il primo numero: "; cin >> num1; cout << "Inserisci il secondo numero: "; cin >> num2; cout << "Inserisci l'operatore che desideri utilizzare(+, -, *, :) "; cin >> op; switch(op) { case '+': cout << "Il risultato è " << num1 + num2 << endl; break; case '-': cout << "Il risultato è " << num1 - num2 << endl; break; case '*': cout << "Il risultato è " << num1 * num2 << endl; break; case '/': cout << "Il risultato è " << num1 / num2 << endl; break; default: cout << "Non hai inserito un operatore corretto!" << endl; break; } |
Ricorda:
- lo switch statement è utile quando conosciamo già tutte le possibilità che l’utente potrebbe inserire
- cin >> num1 inserisce all’interno della variabile il valore digitato dall’utente (più invio)
- cout permette di concatenare stringhe a numeri con <<
- abbiamo utilizzato char per il singolo operatore (un carattere) e float per i numeri (si possono quindi anche inserire numeri decimali)
Conversione decimale → binario
void converti(int n) { int binario[32]; int i = 0; while (n > 0) { binario[i] = n % 2; n = n / 2; i++; } for (int j = i - 1; j >= 0; j--){ cout << binario[j]; } } int main() { int n; cout << "inserisci il numero che vuoi convertire in binario: "; cin >> n; converti(n); return 0; } |
Ricorda:
- una nota: dal momento che C++ ci obbliga a stabilire la lunghezza di una lista, prendiamo per assunto di lavorare con numeri che non superino i 32 bit di lunghezza.
- all’interno del while loop, aggiungiamo alla lista il valore del resto (di conseguenza il coefficiente di 2^i considerato). Calcoliamo n/2 così da poter continuare lo stesso procedimento fino a quando n>0, infine, essendo in un while loop, aggiungiamo 1 alla variabile iterativa.
- Una volta fatto questo, è sufficiente leggere gli elementi contenuti nella lista al contrario e stamparli in console.
Serie di Fibonacci
int main() { int t1 = 0, t2 = 1, t3 = 0, n; cout << "Quanti termini di Fibonacci vuoi calcolare? "; cin >> n; n = n-2; cout << "Serie di Fibonacci fino a " << n << ":" << t1 << ", " << t2 << ", "; t3 = t1 + t2; for(int i=0; i<n; i++){ cout << t3 ; if(i<n-1){ cout<<", "; }else{ cout << "."; } t1 = t2; t2 = t3; t3 = t1 + t2; } cout<<endl; return 0; } |
Ricorda:
- la serie di Fibonacci ha come termini di partenza 0 e 1 (t1 e t2) e genera il termine successivo con la somma dei due precedenti. Quindi t3 = t1 + t2, t4 = t2 + t3 e avanti così.
- Questo codice non fa altro che, fissato un indice fino a dove arrivare, generare e restituire il valore della serie.
- Si toglie 2 a n perché i primi due elementi della serie vengono stampati prima del loop.
- Inoltre è stata fatta qualche aggiunta per visualizzare meglio il risultato.
Il linguaggio C++ però non finisce qui! Questa guida dovrebbe permetterti di muovere i primi passi all’interno dell’ambiente di programmazione, comprendendo strutture e regole di base. Mentre iniziate ad esercitarvi, annotatevi i prossimi argomenti in lista: strutture, classi e pointer. Coming soon.
Instagram
Facebook
Youtube