Nuova avventura didattica.
Negli scorsi giorni ho avuto la fortuna di incontrare un gruppo di studenti che hanno una caratteristica molto bella, hanno la voglia di mettersi in discussione e di esplorare nuove frontiere, l’obiettivo è partecipare ad un concorso molto particolare ZeroRobotics.
Le agenzie Spaziali Europea (ESA), Italiana (ASI), il Politecnico di Torino e l’università di Padova, in collaborazione con il Massachusetts Institute of Technology (MIT), lanciano anche quest’anno il concorso Zero Robotics Europe 2012 in cui viene chiesto alle scuole superiori di creare programmi per il controllo di piccoli satelliti collocati nella Stazione Spaziale Internazionale (ISS).
Per poter pilotare i robot bisognerà saper programmare in C ed io avrò la funzione di “mentor”, dovrò supportare la squadra dell’IIS Galilei Ferrari di Torino, una bella responsabilità, ma sicuramente dal punto di vista dell’insegnante una bella sfida e comunque vada sia io che loro impareremo molto.
A causa dei tempi strettissimi per apprendere e partecipare al concorso ho deciso di realizzare un corso “super concentrato” 🙂 di programmazione in C che si svolgerà in circa 4 settimane in cui gli allievi seguiranno lezioni pratiche in laboratorio con studio e sperimentazione a casa, il tutto condito da una buona dose di scambio informazioni via facebook.
Non mi dilungherò sulla storia del C o su paragoni su altri linguaggi, ma la mia attenzione sarà rivolta esclusivamente al linguaggio di programmazione.
Partiamo!
In questa lezione:
- Componenti di un programma C
- Struttura di base di un programma C
- Variabili
- Tipi di dati
- Operatori aritmetici
- Regole di precedenza degli operatori aritmetici
- Esercizi
Qual è l’ambiente di sviluppo di un programma C?
- l’ambiente di sviluppo del programma, quello che viene tipicamente indicato con IDE
- il linguaggio
- la libreria standard del C
Un programma in C prima di essere eseguito deve attraversare 6 fasi:
- editare
scrittura (editing) del programma che si realizza con un editor, nella maggior parte dei casi incluso nell’IDE di programmazione; - preelaborare
in questa fase il preprocessore esegue alcuni comandi detti “direttive” che eseguono delle variazioni sul programma prima che questo venga compilato, in genere le “direttive” consistono nell’inclusione di altri file allinterno del programma che dovrà essere compilato. - compilare
il compilatore traduce il programma C in linguaggio macchina, detto anche codice oggetto. - linkare
ovvero collegare, è l’operazione che consente di collegare il programma da voi scritto con funzioni definite al di fuori del programma ad esempio le librerie standard. Il linker collega il codice oggetto con quello delle funzioni mancanti per creare un programma eseguibile. - caricare
il programma prima di essere eseguito deve essere caricato in memoria, questa operazione sarà eseguita dal loader; - eseguire
il programma verrà eseguito una istruzione alla volta, tutto ciò sotto il controllo della CPU
Il primo programma in C
Il primo esempio che realizzeremo è il classico Hello World!
/* Nome: prg01 Scopo: visualizzare una riga di testo Autore: Michele Maffucci Data creazione: 01.10.2013 */ #include <stdio.h> /* la funzione main è il punto di inizio */ int main (void) { printf("Hello world!\n"); return 0; /* indica che l'esecuzione è terminata con successo */ } /* fine della funzione main */
Quando eseguiamo il programma l’output sarà:
Hello world!
Vediamo in dettaglio cosa fa il programma.
la prima parte del programma:
/* Nome: prg01 Scopo: visualizzare una riga di testo Autore: Michele Maffucci Data creazione: 01.10.2013 */
è un commento. I commenti in C iniziano con */ e terminano con */ ma la maggior parte dei compilatori accettano anche i commenti alla C++ quelli che incominciano con // e terminano con la fine della riga, pertanto il primo commento poteva essere scritto come:
// Nome: primo programma C // Scopo: visualizzare una riga di testo // Autore: nome cognome // Data creazione: 01.10.2013
Quindi potrete scrivere anche:
/* commento in C */ /* questo è un commento in C su più righe */ // mentre questo è un commento su una riga sola in stile C++
Ma cosa bisogna scrivere all’interno di un commento?
Tutte le informazioni necessarie che necessitano al programmatore e al team di sviluppo per comprendere ogni parte del programma. Un esempio potrebbe essere quello indicato sopra, in cui si indicano il nome del programma, eventualmente con la versione, il nome dell’autore o del gruppo di lavoro, data di creazione. Ma in alcuni casi potrebbe essere necessario indicare anche note sul
All’interno di un commento è possibile scrivere informazioni sul programma, o commenti su un copyright o annotazioni sulle modifiche effettuate.
In generale è buona norma commentare il più possibile il programma, soprattutto se il programma dovrà essere analizzato da altre persone.
Errori tipici con i commenti
- inversione dei simboli, iniziare con */ e terminare con /*
- dimenticare di concludere il commento con */
La seconda parte del programma è:
#include <stdio.h>
questa è una direttiva al preprocessore, cioè un’istruzione che dice al computer che nelle istruzioni che seguono verranno utilizzate delle funzioni che sono state definite nel file stdio.h cioè le funzioni che eseguono l’input e l’output standard, ad esempio quelle che permettono di scrivere un messaggio a monitor, di leggere i pulsanti premuti dalla tastiera, manipolare file ecc…
printf ad esempio è una funzione in grado di stampare a monitor il testo incluso tra parentesi e questa funzione è definita in stdio.h.
Quindi se non si inserisse la riga #include <stdio.h> non si potrebbe usare la funzione printf.
La terza parte del programma
la funzione main() che è il punto di inizio di ogni programma C.
int main (void)
int scritto prima del main, indica che il programma restituirà al termine dell’esecuzione a chi lo chiama, nel nostro caso il sistema operativo, un valore intero (da cui int), infatti il programma termina con return 0.
Notate che la parentesi graffa aperta { apre il corpo del main, cioè il nucleo che definisce la funzionalità del programma e la parentesi graffa chiusa } chiude il corpo del main.
La quarta parte del programma:
printf("Hello world!\n");
è una funzione che esegue un’azione, cioè stampa il messaggio incluso tra apici, nel nostro caso “Hello world!\n” sullo standard output, nel nostro caso lo standard output è il monitor.
Il carattere \ è detto escape e la sequenza \n viene detta sequenza di escape, che serve per andare a capo dopo aver scritto ciò che è contenuto prima della sequenza \n.
Quindi dopo aver scritto Hello world! il cursore andrà a capo.
\n vuol dire “new-line“, cioè “nuova riga“.
Queste le principali sequenze di escape usate nel C:
- \n new line. Il cursore viene posizionato all’inizio della riga successiva.
- \t tabulazione orizzontale. Il cursore viene posizionato alla tabulazione successiva.
- \b indietro di un carattere. Corrisponde al tasto backspace.
- \a allarme. fa emettere un suono all’altoparlante di sistema.
- \” stampa i doppi apici “
- \’ stampa un apice singolo ‘
IMPORTANTE:
- tutta la riga compreso il contenuto incluso tra parentesi tonde fino al punto e virgola è detta istruzione;
- tutte le istruzioni in C terminano con un ;
La quinta parte del programma:
return 0; /* indica che l'esecuzione è terminata con successo */
è un’istruzione inclusa alla fine di ogni funzione main e dice al programma di restituire il valore intero 0 al sistema operativo ed uscire dall’esecuzione, ciò indica che il programma si è concluso con successo.
IMPORTANTE
Identare il programma. Per identificare il blocco di istruzioni appartenente ad una funzione è buona norma far rientrare di una stessa quantità di spazi tutte le istruzioni incluse all’interno delle parentesi graffe. Di seguito viene evidenziato il rientro della porzione di codice del programma con il carattere –
.... int main (void) { ----printf("Hello world!\n"); ----return 0; /* indica che l'esecuzione è terminata con successo */ } ...
Programma: utilizzare sei funzioni printf per scrivere una frase su una stessa linea
/* Nome: prg02 Scopo: visualizzare una riga di testo usando 6 printf Autore: Michele Maffucci Data creazione: 01.10.2013 */ #include <stdio.h> /* la funzione main è il punto di inizio */ int main (void) { printf("sono "); printf("un programma "); printf("e tu stai "); printf("imparando "); printf("a programmare in C\n"); return 0; /* indica che l'esecuzione è terminata con successo */ } /* fine della funzione main */
L’output sarà
Ciao io sono un programma e tu stai imparando a programmare in C
In questo caso ogni printf inizia la stampa dove aveva terminato la printf precedente.
Programma: utilizzare sei funzioni printf per scrivere sei frasi su 6 righe diverse
Come avrete intuito per visualizzare diverse righe sarà sufficiente inserire al termine di ogni frase la sequenza escape \n e quindi se variamo il programma precedente come segue:
/* Nome: secondo programma C Scopo: visualizzare 6 righe di testo usando 6 printf Autore: Michele Maffucci Data creazione: 01.10.2013 */ #include <stdio.h> /* la funzione main è il punto di inizio */ int main (void) { printf("Ciao io\n"); printf("sono\n"); printf("un programma\n"); printf("e tu stai\n"); printf("imparando\n"); printf("a programmare in C\n"); return 0; /* indica che l'esecuzione è terminata con successo */ } /* fine della funzione main */
avremo
Ciao io sono un programma e tu stai imparando a programmare in C
VARIABILI
Programma: somma di due numeri interi
/* Nome: prg03 Scopo: visuualizzare la somma di due numeri interi Autore: Michele Maffucci Data creazione: 01.10.2013 */ #include <stdio.h> /* la funzione main è il punto di inizio */ int main (void) { int intero1; /* primo addendo */ int intero2; /* secondo addendo */ int somma; /* somma di intero1 e intero2 */ printf("-SOMMA DI DUE NUMERI INTERI-\n"); /* cosa eseguirà il programma */ printf("Inserisci il primo numero: \n"); /* azione da compiere */ scanf("%d", &intero1); /* legge il primo intero */ printf("Inserisci il secondo numero: \n"); /* azione da compiere */ scanf("%d", &intero2); /* legge il secondo intero */ /* calcola la somma */ somma = intero1 + intero2; /* stampa il risultato */ printf("Somma dei due numeri: %d\n", somma); /* viene stampata la somma */ return 0; /* indica che l'esecuzione è terminata con successo */ } /* fine della funzione main */
Questo il risultato se introduciamo gli interi 4 e 6:
--- SOMMA DI DUE NUMERI INTERI --- Inserisci il primo numero: 4 Inserisci il secondo numero: 6 Somma dei due numeri: 10
Analizziamo il programma tralasciando le sezioni già spiegate in precedenza:
int intero1; /* primo addendo */ int intero2; /* secondo addendo */ int somma; /* somma di intero1 e intero2 */
sono delle dichiarazioni e intero1, intero2 e somma sono i nomi delle variabili.
Le variabili possono essere intesi come dei ”contenitori” che al loro interno possono contenere numeri interi, numeri in virgola mobile, caratteri, ecc… nel programma di esempio le variabili dichiarate conterranno dei numeri interi.
I “contenitori” non sono altro che delle locazioni di memoria dove vengono immagazzinati i numeri che vengono poi utilizzati dal programma.
IMPORTANTE
tutte le variabili DEVONO essere dichiarate con un TIPO ed un NOME DI VARIABILE
e quindi in C avremo sempre:
tipo nome_variabile;
Si noti che la dichiarazione delle variabili poteva anche essere scritta su un’unica linea:
int intero1, intero2, somma;
questa notazione ha il vantaggi di rendere più compatto il programma, ma lo svantaggio di descrivere nella stessa linea ogni variabile.
Tralasciando l’uso delle printf che già conosciamo analizziamo la funzione scanf.
scanf("%d", &intero1); /* legge il primo intero */
la scanf vine utilizzata per ottenere dall’utente un valore, prende un dato dallo standard input che nel nostro caso è la tastiera.
La scanf ha due argomenti
%d &intero1
- il primo argomento indica il tipo di dato che dovrà essere introdotto, in questo caso un intero e viene detta “specifica di conversione“.
- La lettera d specifica che stiamo trattando un numero intero in base 10.
- % è un carattere speciale che indica una specifica conversione
- il secondo argomento incomincia con & (ampersand) ed in C questo carattere è detto “operatore di indirizzo” e quando è seguito dal nome della variabile indica alla funzione che la utilizza (in questo caso la scanf) la locazione di memoria in cui viene memorizzata la variabile intero1.
somma = intero1 + intero2;
calcola la somma delle variabili intero1 e intero2 ed il risultato è immagazzinato tramite l’operatore di assegnamento ”=” nella variabile somma.
analizzaimo la porzione di codice:
printf("Somma dei due numeri: %d\n", somma); /* viene stampata la somma */
la funzione printf ha due argomenti:
- “Somma dei due numeri: %d\n”
- somma
Il primo argomento è costituito dalla:
- stringa di testo “Somma dei due numeri: ” che verrà stampato a monitor
- stringa del formato %d che definisce il formato del numero stampato (numero decimale intero).
Sulla base di quanto imparato fino a questo punto proviamo a realizzare il programma che stampa il precedente e il successivo di un numero.
Programma: precedente e successivo
/* Nome: prg04 Scopo: visualizzare il numero precedente e successivo di un numero dato Autore: Michele Maffucci Data creazione: 01.10.2013 */ #include <stdio.h> /* la funzione main è il punto di inizio */ int main (void) { int numero; /* numero inserito */ int prec; /* precedente */ int succ; /* successivo */ printf("-PRECEDENTE E SUCCESSIVO-\n"); /* cosa esegue il programma */ /* legge il numero */ printf("Inserisci il numero: \n"); /* azione da compiere */ scanf("%d", &numero); /* legge il numero */ /* calcola il numero precedente */ prec = numero - 1; /* calcola il numero successivo */ succ = numero + 1; /* stampa il risultato */ printf("\n"); /* stampa una linea vuota */ printf("Il numero inserito e' %d\n", numero); printf("Il numero precedente a %d e' %d\n", numero, prec); printf("Il numero successivo a %d e' %d\n", numero, succ); return 0; /* indica che l'esecuzione è terminata con successo */ } /* fine della funzione main */
Analizziamo la sezione di programma:
... printf("Il numero precedente a %d e' %d\n", numero, prec); printf("Il numero successivo a %d e' %d\n", numero, succ); ...
Si noti che entrambe le printf sono costituite da una porzione di testo in cui sono inclusi due %d seguite dal nome delle variabili usate nella stringa. L’ordine di scrittura delle due variabili definisce l’ordine di stampa, ovvero il primo %d accoglierà il valore immagazzinato in numero ed il secondo %d per la prima printf accoglierà il valore immagazzinato in prec mentre per la seconda printf accoglierà il valore immagazzinato in succ.
TIPI DI DATI
A questo punto avreste dovuto intuire come vengono utilizzate le variabili nei vostri programmi, ricordate che una variabile in C ha la seguente struttura:
tipo nome_variabile;
è possibile anche assegnare un valore iniziale ad una variabile:
tipo nome_variabile = valore_iniziale;
Ma quali sono i tipi utilizzati in C?
Ecco quelli più utilizzati:
Tipo | Uso tipico | Dimensione (in bit) (riferimento: architettura x86) |
char | Caratteri di testo ASCII, valori binari generici da 1 byte | 8 |
short int | Numeri interi piccoli (da -32768 a 32767) | 16 |
unsigned short int | Numeri positivi interi piccoli (da 0 a 65535) | 16 |
int | Numeri interi (da -2147483648 a 2147483647) | 32 |
unsigned int | Numeri interi positivi (da 0 a 4294967295) | 32 |
long int | Numeri interi (la dimensione coincide con quella di un normale int su una macchina x86) | 32 |
long long int | Numeri interi grandi (da circa -9.22*10^18 a circa 9.22*10^18) | 64 |
unsigned long long int | Numeri interi grandi positivi (da 0 a circa 1.84*10^19) | 64 |
float | Numeri a virgola mobile (precisione singola) | 32 |
double | Numeri a virgola mobile (doppia precisione, notazione scientifica) | 64 |
Esempi sui tipi di variabili:
int x; /* dichiariamo una variabile intera di nome x */ int y=7; /* dichiariamo una variabile intera y che vale 7 */ char z='a'; /* dichiariamo una variabile di tipo char (carattere) che contiene il carattere a */ float w = 6.7; /* dichiariamo una variabile di tipo float w che vale 6.7 */ x=3; /* adesso x vale 3 */ int s=x+y /* s vale la somma di x e y, cioè 10
OPERATORI ARITMETICI
Come avete notato negli esercizi precedenti abbiamo fatto largo uso di operatori aritmetici utilizzandoli così come siamo abituati a fare normalmente, vediamo però in dettaglio nella tabella che segue quali sono i principali operatori aritmetici utilizzati in C:
Operazioni con gli int | Simbolo | Esempio |
Addizione | + | 3 + 21 = 24 |
Sottrazione | – | 53 – 12 = 41 |
Moltiplicazione | * | 3 * 8 = 24 |
Divisione intera | / | 15 / 4 = 3(3 è il n di volte divisibili senza resto) |
Divisione con modulo | % | 11 / 3 = 2(2 è il resto della divisione) |
Se utilizziamo numeri reali (float o double) l’unica operazione che non si utilizzerà sarà la “divisione con modulo” che non ha senso di esistere in quanto la divisione può contenere parti frazionarie:
Operazioni con gli int | Simbolo | Esempio |
Addizione | + | 3.7 + 15.2 = 18.9 |
Sottrazione | – | 57.9 – 19.3 = 38.6 |
Moltiplicazione | * | 3.7 * 5.2 = 19.24 |
Divisione intera | / | 7.0 / 2.0 = 3.5 |
REGOLE DI PRECEDENZA DEGLI OPERATORI ARITMETICI
Le regole adottate sono simili a quelle adottate nell’algebra:
- le espressioni tra parentesi saranno valutati per prima, in questo modo potrete utilizzare le parentesi per forzare l’ordine con cui vengono effettuati i calcoli. Le parentesi hanno la priorità massima rispetto a tutte le operazioni. Nel caso siano presenti parentesi annidate la precedenza di calcolo spetta alle coppie di parentesi più interne: (X+(Y+Z)) l’operazione Y+Z sarà svolta per prima.
- verranno calcolate prima le operazioni di moltiplicazione, divisione e resto che si trovano allo stesso livello di priorità. Nel caso un’operazione contenga più operazioni di moltiplicazioni, divisioni e resto, lavalutazione avverrà da sinistra verso destra.
- verranno valutate in ultimo le operazioni di addizione e sottrazione che si trovano allo stesso livello di priorità però più basso delle operazioni al punto 2, la valutazione avviene da sinistra verso destra.
Programma: media tra due numeri
/* Nome: prg05 Scopo: dato due valori interi visualizzare la loro media Autore: Michele Maffucci Data creazione: 01.10.2013 */ #include <stdio.h> /* la funzione main è il punto di inizio */ int main (void) { int numero1, numero2; /* numeri di cui si vuole calcolare la media */ float somma; /* somma dei due numeri */ float media; /* media dei due numeri */ printf("-CALCOLO DELLA MEDIA DI DUE NUMERI INTERI-\n"); /* cosa esegue il programma */ /* legge i due numeri */ printf("Inserisci il primo numero: \n"); /* azione da compiere */ scanf("%d", &numero1); /* legge il primo numero */ printf("Inserisci il secondo numero: \n"); /* azione da compiere */ scanf("%d", &numero2); /* legge il secondo numero */ /* calcola la somma dei due numeri */ somma = numero1 + numero2; /* calcola la media dei due numeri */ media = somma/2; /* stampa il risultato */ printf("\n"); /* stampa una linea vuota */ printf("La media aritmetica di %d e %d e' %f\n", numero1, numero2, media); return 0; /* indica che l'esecuzione è terminata con successo */ } /* fine della funzione main */
ESERCIZI
Esercizio 1: Realizzare una semplice calcolatrice
Specifiche:
scrivere un programma in grado di eseguire le 4 operazioni (somma, sottrazione, moltiplicazione e divisione) tra due numeri reali inseriti da tastiera.
Dopo che sono stati inseriti i due numeri X e Y il programma dovrà visualizzare i 4 valori: X+Y; X-Y; X*Y; X/Y. Si ipotizzi che Y è diverso da 0.
Esercizio 2: Calcolo di aree
Specifiche:
scrivere un programma che dato un numero reale X inserito da tastiera calcoli e stampi:
- l’area del quadrato di lato X
- l’area del triangolo equilatero di lato X
- l’area del cerchio di diametro X
non ho capito come fare poi per “avviare” e “salvare” questo programma ?
Ciao Giacomo.
Hai bisogno di installare un ambiente di sviluppo per poter compilare i tuoi programmi in C come ad esempio Geany.
Puoi trovare un tutorial al seguente link:
Usare Geany per programmare in C
Ciao.