Prosegue il corso collaborativo di programmazione.
Dopo il primo capitolo di introduzione, in cui dovreste aver preparato l'ambiente con cui fare esercizi, entriamo nel vivo dell'argomento parlando di:
- sintassi del C
- la programmazione strutturata
Sintassi del linguaggio C
Riprendiamo un attimo il codice del tanto discusso ( ) hello world proposto la lezione precedente:
void main()
{
printf("Hello World!\n");
system("pause");
}
cosa possiamo dire? il programma è succinto, ma funziona. Abbiamo detto che il C è un linguaggio imperativo, dunque ad ogni riga corrisponde un comando alla CPU (che poi sappiamo essere tradotto dal compilatore in linguaggio a lei comprensibile).
Cosa significa "ad ogni riga"? Nel linguaggio naturale, facciamo corrispondere una riga ad una sequenza di parole fino al ritorno a capo. Tuttavia, sappiamo che una frase normalmente non si conclude col ritorno a capo ma con un punto. In C il discorso è simile: ogni riga di comando si conclude con il punto e virgola ";".
Infatti, osserviamo che due righe su cinque hanno il punto e virgola alla fine: quelli sono effettivamente gli unici due comandi che abbiamo impartito. In base a questa regola sintattica, nulla ci vieta di scrivere così:
void main()
{
printf("Hello World!\n"); system("pause");
}
e infatti questo codice funziona in maniera identica a quello di prima. Possiamo strutturare il testo come preferiamo, l'unica cosa che conta è inserire un punto e virgola alla fine di ogni comando (altrimenti il compilatore da errore).Cos'altro osserviamo? la prima riga dice qualcosa di criptico:
void main()
cos'è void? è presto per dirlo - parleremo dei tipi di dato più avanti - ma void in sostanza rappresenta "il nulla"; vedremo più avanti il suo senso.Il main, come anticipato nella lezione precedente, è il corpo principale del programma, ovvero da dove inizia l'esecuzione. In pratica, quando lanciamo l'esecuzione del programma, lui comincia proprio dal main. Il programma finisce quando raggiunge la conclusione del main.
La programmazione strutturata
Vediamo che il corpo del programma main è racchiuso da parentesi graffe. Questo è un punto importante: tutti i blocchi di istruzioni vanno racchiusi tramite queste parentesi e, quando si inizia ad eseguire un blocco, vengono svolti i comandi che contiene in ordine sequenziale.
Ad esempio, se io volessi fare un programma che prepara la frittata dovrei fare:
main {
sbatti_uova
taglia_patate
combina_ingredienti
scalda_su_fornello
}
(questo codice non è, ovviamente, in C: è detto pseudocodice, e si usa nelle discussioni tra programmatori per dare l'idea di quello che un programma fa). In sostanza, il nostro programma "prepara_frittata" inizia sbattendo le uova e finisce dopo averle scaldate sul fornello. Un esempio di come le graffe facciano riferimento a "blocchi di codice" è il cosidetto costrutto iterativo. Ad esempio, potremmo dire che la procedura taglia_patate deve essere chiamata 3 volte (magari perché abbiamo tre patate da tagliare):
main() {
sbatti_uova;
ripeti 3 volte {
taglia_patate;
}
combina_ingredienti;
scalda_su_fornello;
}
Osserviamo che l'istruzione "ripeti tre volte" utilizza le graffe per delimitare il blocco di istruzioni che dobbiamo ripetere, perché altrimenti non sarebbe chiaro se dobbiamo ripetere solo il taglio delle patate, o anche il combinamento degli ingredienti, eccetera.Un ulteriore esempio di blocco di istruzioni è la cosidetta selezione. Ad esempio, potremmo imporre un controllo sulla scadenza delle uova, prima di sbatterle.
main() {
se ( uova = buone ) {
sbatti_uova;
} altrimenti {
compra_nuove_uova;
sbatti_uova;
}
ripeti 3 volte {
taglia_patate;
}
combina_ingredienti;
scalda_su_fornello;
}
Analizziamo lo pseudocodice. Le condizioni (uova buone) sono racchiuse da parentesi; questo avviene anche in C, e il motivo sarà più chiaro quando vedremo le funzioni.Osserviamo che la struttura è di tipo SE...ALLORA...ALTRIMENTI. In sostanza, eseguiremo il primo blocco tra graffe se la condizione è vera, il secondo nell'altro caso. La sezione "altrimenti" si può anche omettere, e in tal caso abbiamo un semplice SE...ALLORA
Dunque abbiamo visto: sequenza, iterazione e selezione. In base al teorema di Böhm-Jacopini, che abbiamo accennato nella lezione precedente, non ci serve nient'altro per programmare qualsiasi cosa. Qualunque programma abbiate visto nella vostra vita girare in un computer può essere realizzato con questi soli costrutti. Questa è la base della programmazione strutturata.
Esercizio: i più attenti avranno notato che, nello pseudocodice quì sopra, l'istruzione "sbatti_uova" è ripetuta in entrambi i blocchi del costrutto SE...ALLORA...ALTRIMENTI, perché le dobbiamo sbattere sia se usiamo quelle che abbiamo in frigo, sia se le compriamo nuove.
Come si potrebbe modificare il codice affinché non ci sia questo doppione?