Questo sito contribuisce alla audience di Il Messaggero
Scopri le migliori offerte sul canale Telegram ufficiale. Guarda su Telegram

Come programmare in C

di

Sei affascinato dal mondo della programmazione e, visto che ultimamente hai un po’ di tempo libero da dedicarvi, hai deciso di imparare qualcosa in più in merito. Seguendo il consiglio di un tuo amico già esperto nel settore, hai scelto come punto di partenza il linguaggio C, sicuramente uno dei più versatili e tutt’oggi utilizzati sulla scena informatica.

Risoluto e deciso a portare avanti la tua idea, hai aperto il tuo ormai fidato amico Google e, cercando istruzioni su come programmare in C, sei finito dritto sulla mia guida, con la speranza di ottenere le informazioni necessarie su come iniziare a scrivere del codice funzionante. Ebbene, sono lieto di comunicarti che questo è proprio il posto che stavi cercando: nelle righe a venire, infatti, ti fornirò un’infarinatura generale sul linguaggio C, spiegandoti tutto quanto necessario per scrivere i primi programmi funzionanti.

Prima di andare avanti ed entrare nel vivo della questione, però, voglio farti un’importante premessa: la programmazione in C è un argomento piuttosto vasto, che sicuramente non entra completamente nella pagina che ti appresti a leggere. Anzi, ti dirò di più: non basterebbe l’intera struttura di questo sito per trattarlo in modo approfondito! Non temere, però, poiché sarà mia cura indirizzarti, nelle battute finali di questo tutorial, verso risorse utili e approfondimenti per arricchire, se lo vorrai, la tua conoscenza in merito. A questo punto, direi di mettere al bando le ciance e iniziare: non mi resta che augurarti buona lettura e buon divertimento!

Indice

Informazioni preliminari

Come programmare in C

Prima di buttarti a capofitto nell’apprendimento dei concetti di base per programmare in C, lascia che ti dia qualche informazione in più su questo linguaggio così potente. Innanzitutto, il C è un linguaggio imperativo procedurale, in grado cioè di effettuare manipolazione dei dati attraverso operazioni matematiche, raggruppate in procedure specifiche definite funzioni (di cui ti parlerò più in là in questa guida).

Si tratta di un linguaggio ad alto livello, che utilizza cioè una sintassi vicina al linguaggio umano e relativamente distante dal linguaggio assembly e dal linguaggio macchina: in altre parole, una gran parte delle istruzioni esistenti in C prende origine dalla lingua inglese.

A differenza di numerosi linguaggi di programmazione ad oggi conosciuti, il linguaggio C non prevede l’utilizzo degli oggetti: ciascuna struttura dati complessa (ad es. arrayrecord e qualsiasi altra entità che non rappresenti un tipo di dato primitivo) deve essere manualmente dichiarata e allocata in memoria. Tuttavia, alcuni “derivati” del C (come il C++, il C# o l’Objective-C) sono invece linguaggi a oggetti.

Come scoprirai più avanti in questa guida, il C è un linguaggio compilato: ciò significa che, prima di poter funzionare, il codice sorgente del programma scritto deve essere “tradotto” in linguaggio macchina da un software definito compilatore, che genera un file eseguibile in grado di essere elaborato dal processore e dall’hardware della macchina, grazie al coordinamento del sistema operativo.

In generale, il linguaggio C è estremamente flessibile e viene tutt’oggi utilizzato in un gran numero di scenari: ad esempio, è possibile utilizzare il C per scrivere un intero sistema operativo, programmare dispositivi connessi, creare librerie dedicate ai giochi, effettuare complessi calcoli matematici distribuiti e così via.

Se desideri capire meglio il ciclo di vita di un generico programma e approfondire i “passaggi” da effettuare per scriverne uno in modo efficiente, ti consiglio di dare un’occhiata al mio approfondimento su come  creare un programma.

Sintassi di base

Allora, pronto a partire? Perfetto! Nelle sezioni a venire, intendo spiegarti i concetti di base della sintassi del linguaggio C, fornendoti le nozioni necessarie sulle componenti fondamentali di di quest’ultimo: così facendo, acquisirai le competenze necessarie per scrivere, in completa autonomia, un piccolo programma funzionante.

Innanzitutto, un programma in C viene scritto avvalendosi di uno o più file sorgenti, nei quali vengono specificate le istruzioni da eseguire per elaborare i dati nel modo scelto. A meno di non intervenire attraverso salti, condizioni o cicli di controllo speciali (te ne parlerò più avanti), il C utilizza un approccio sequenziale: ciò significa che, in linea generale, le istruzioni vengono eseguite nel medesimo ordine in cui sono specificate nel codice sorgente.

Statement

Lo statement è l’entità di base del linguaggio C: in parole povere, si tratta di un’istruzione completa che, in qualche modo, elabora dei dati. Uno statement in C termina sempre con un ; (punto e virgola) e può effettuare qualsiasi tipo di operazione: può addizionare due numeri, paragonare due stringhe di caratteri, richiamare una funzione, dichiarare o assegnare un valore a una variabile e molto, molto altro. In altre parole, ciascuno statement contiene un “comando” di manipolazione dati. Per convenzione, ciascuno statement in C dovrebbe risiedere su una riga diversa del codice sorgente.

Tanto per farti un esempio, lo statement printf(“Ciao a tutti!”); contiene il comando per stampare a video la frase “Ciao a tutti”.

La direttiva #include

Come ti ho già detto, un programma in C può snodarsi su diversi file sorgenti: questo capita, in modo particolare, per tenere un certo ordine in progetti molto grandi. Digitare tutto in un solo file di decine di migliaia di righe di codice, potrebbe far impazzire anche il programmatore più paziente: sarebbe un’impresa soltanto effettuare la modifica di una singola istruzione!

Proprio in base a questo criterio, il C prevede una speciale direttiva, tale #include, che viene specificata all’inizio di ciascun codice sorgente e comunica al compilatore gli altri file da “includere” nel programma in fase di compilazione. Tanto per farti un esempio, quasi tutti i programmi scritti in C iniziano con la direttiva #include <stdio.h>: in questo modo, è possibile utilizzare tutti i comandi C specificati nella cosiddetta libreria di standard Input/Output, residente nel percorso di installazione del compilatore stesso.

La libreria stdio.h contiene le definizioni dei comandi di base e delle costanti, per permettere al programmatore la manipolazione dell’input/output (cioè ciò che si vede sullo schermo, ciò che si acquisisce attraverso tastiera e mouse) e la gestione dei file. Di seguito ti elenco quelli più utilizzati.

  • printf()fprintf()sprintf() – si tratta di comandi che permettono, rispettivamente, di scrivere dati sul dispositivo di output standard (cioè lo schermo), su file e su stringhe di caratteri.
  • scanf(), fscanf() e sscanf() – queste funzioni, invece, prelevano dati rispettivamente dallo standard input (la tastiera), da file e da stringhe di caratteri.
  • fopen() freopen() – questi comandi permettono di aprire un file all’interno di un programma C, così da poter leggere dati al suo interno o scriverne altri.
  • fread() fwrite() – tali funzioni permettono, rispettivamente, la lettura e la scrittura da un file.

Insieme a stdio.h, viene spesso inclusa nei codici sorgenti la libreria stdlib.h, anch’essa inclusa nell’ambiente di sviluppo C: questa contiene funzioni e costanti di carattere generale, tra cui le istruzioni da utilizzare per allocare la memoria e manipolare i dati presenti al suo interno.

La direttiva include può essere specificata in due modi: #include <libreria.h> denota l’inclusione di una libreria presente nell’ambiente di sviluppo predefinito, mentre #include “libreria.h” specifica l’inclusione di una libreria scritta dal programmatore e presente nella stessa cartella del file sorgente in cui è dichiarata.

Tipi di dati

Come ti ho già spiegato, il C non è un linguaggio a oggetti, dunque le strutture dati più complesse vanno dichiarate e strutturate in memoria manualmente. Ciò non toglie, però, che tale linguaggio sia in grado di gestire e manipolare nativamente numerosi tipi di dati elementari, che possono essere assegnati alle variabili necessarie per il funzionamento del programma, acquisiti come valori in input o resi come valori di ritorno delle funzioni. Di seguito ti elenco i tipi di dati più utilizzati e le informazioni necessarie su ciascuno di essi.

  • char – è il tipo di dati che denota un singolo carattere e occupa 8 bit in memoria. Per specificare una variabile di questo tipo, è sufficiente impartire lo statement char nomeVariabile;, mentre per le funzioni di input/output è necessario specificare il codice %c affinché il compilatore interpreti correttamente la variabile a cui si punta.
  • int – questo tipo di dati denota i numeri interi. Occupa 16 bit di dati e può contenere valori che vanno da -32767 +32767. Il suo identificatore, nelle operazioni di input/output, è %i.
  • float e double – identificano i numeri in virgola mobile semplici e i numeri in virgola mobile doppi. Occupano rispettivamente 32 e 64 bit di dati e possono rappresentare decimali con precisione di 6 cifre (float) e di 10 cifre (double). Gli identificatori da assegnarvi sono %f %fd.
  • void – in C, questo tipo di dati identifica il non valore, cioè un’entità che non occupa alcuno spazio in memoria. In genere, il void viene specificato come valore di ritorno o come input nelle funzioni che non io prevedono (come a voler dire al compilatore “fai attenzione, questa funzione o questa operazione non ritorneranno valore alcuno o non accettano valori in input”). Il void, come è semplice immaginare, non ha un identificatore caratteristico per l’input/output.

Definizione di variabili

Sono sicuro che, in qualche modo, conosci già il concetto di variabile: volendo formalizzarlo, una variabile altro non è che un “contenitore”, situato in memoria, che deve contenere valori che possono essere modificati durante il flusso di esecuzione di un programma.

Prima di andare avanti, vorrei specificare la differenza tra la dichiarazione di una variabile e la sua definizione assegnazione: nel primo caso, si avvisa il compilatore che bisogna allocare una porzione di memoria per contenere dei dati; nel secondo caso, invece, si va a riempire la memoria con i dati richiesti. È possibile dichiarare una o più variabili senza definirle, ma non è possibile definire una o più variabili senza dichiararle (il compilatore, in tal caso, non saprebbe dove piazzare i dati in memoria).

Dichiarare una variabile in C è semplicissimo: basta digitare uno statement che specifichi il tipo di dato che la variabile deve contenere, il suo nome e, se necessario, il valore iniziale (specificato con l’operatore di assegnazione =). Per esempio, puoi dichiarare una variabile intera vuota attraverso lo statement int variabile;, oppure assegnarle il valore iniziale di 10 impartendo invece int variabile = 10.

Una volta dichiarata una variabile, è possibile manipolarla nelle parti successive del codice utilizzando l’assegnazione con l’operatore = (ad es. variabile=51;), gli operatori di incremento, di decremento e tutto quanto previsto dal tipo di dati specificato. Tieni sempre ben presente che, per essere utilizzata, una variabile deve essere necessariamente dichiarata in una parte precedente del codice: il C, come ti ho spiegato, è un linguaggio sequenziale, dunque non puoi chiedere a uno statement di operare su un dato che non conosce!

In genere, in C è possibile riferirsi alle variabili in due modi differenti: per le operazioni di assegnazione tramite l’operatore = o le funzioni di manipolazione dell’output (ad es. printf()), si utilizza semplicemente il suo nome (ad es. printf(“%i”, variabile); oppure somma = aggiungi(a,b);); se, invece, bisogna scrivere dati in una variabile utilizzando determinate funzioni di manipolazione dell’input, come ad esempio la funzione scanf(), è necessario farvi riferimento attraverso un puntatore al contenuto in memoria: per farlo, è sufficiente anteporre al nome della variabile il carattere & (ad es. scanf(“%i”, &variabile);).

Operatori principali

Come un po’ tutti i linguaggi di programmazione esistenti al mondo, anche la programmazione in C richiede l’utilizzo degli operatori, cioè di alcuni caratteri che, all’interno di uno statement, possono acquisire un significato “speciale”, combinando dunque i dati dello statement stesso. Il linguaggio C prevede un gran numero di operatori per la gestione dei più disparati casi: il più importante è l’operatore di assegnamento, cioè =,  che permette di assegnare un valore (o un’espressione più o meno complessa) a una variabile o una serie di variabili. Per esempio, digitare lo statement int a = 1+2+3+4; significa dichiarare una variabile intera a e attribuirle il valore iniziale di 10.

Oltre all’operatore di assegnamento, esistono numerosi altri operatori in C: essi si dividono in quattro categorie ben distinte, che mi accingo a spiegarti di seguito.

  • Operatori aritmetici – come il nome stesso lascia intendere, sono quelli che permettono l’esecuzione di operazioni aritmetiche di base: il + denota l’addizione, il – la sottrazione, il * la moltiplicazione, il / la divisione, il ++ l’incremento di uno (può essere posto a destra o a sinistra della variabile da incrementare), il  il decremento di uno (stessa regola precedente) e, infine, il % restituisce il resto della divisione intera tra i valori.
  • Operatori relazionali – sono utili per mettere in relazione un valore rispetto all’altro, e sono: > e(maggiore/minore), >= <= (maggiore/minore uguale a), == != (uguale e diverso). Essi si basano sul concetto di vero/falso: per esempio, in uno statement, l’espressione var = 10>5 assegna a var il valore true 1, poiché il numero 10 è maggiore del numero 5.
  • Operatori logici – seguono lo stesso approccio vero/falso visto poc’anzi, ma vengono utilizzati per confrontare il collegamento tra due relazioni, tipico dell’algebra booleana. Essi sono && (and logico), || (or logico) e (il not).
  • Operatori bit a bit – essi permettono di intervenire sui singoli byte dei tipi di dato char e int, effettuando esclusioni, spostamenti a destra/sinistra e confronti. Principalmente, questi vengono impiegati nella scrittura di moduli per sistemi operativi o di driver di periferica, in quanto permettono di intervenire singolarmente sui byte (o sulle word di file scritti in assembly).

Controlli condizionali

Come ti ho spiegato all’inizio, il C è un linguaggio sequenziale, cioè in grado di eseguire istruzioni nello stesso ordine in cui compaiono nel codice sorgente del programma. Esistono tuttavia delle direttive che permettono di modificare il flusso di esecuzione del programma, modificandone l’ordine al verificarsi/non verificarsi di determinate condizioni: queste direttive prendono l’ordine di controlli condizionali. Nelle righe a venire ti illustro i più utilizzati.

If/else

Se mastichi un po’ di inglese, ti sarà semplice comprendere del controllo condizionale if: impartire questa istruzione significa, di fatto, comunicare al programma qualcosa di simile a “se si verifica una precisa condizione, allora esegui questa/e istruzione/i”. Sintatticamente, il controllo si presenta nella forma

if (condizione) {
  istruzioni
}

Se lo desideri, puoi specificare un’ulteriore condizione avvalendoti della clausola else: unita all’if, essa permette infatti di astrarre il concetto “se si verifica una precisa condizione, allora esegui queste istruzioni, altrimenti (else) esegui queste altre)”.

if (condizione) {
  istruzioni
} else {
 altre istruzioni
}

Puoi esprimere la condizione avvalendoti degli operatori che restituiscono risultati di tipo true/false, cioè quelli logici e quelli relazionali. Tanto per farti un esempio concreto, ti propongo una parte di codice che può determinare il valore massimo tra due variabili, stampandola a video.

if (a>=b) {
  printf("Il valore della variabile a è maggiore o uguale di quello della variabile b\n");
}
else {
 printf("Il valore della variabile a è minore di quello della variabile b\n");
}

Se necessario, puoi “arricchire” il costrutto visto poc’anzi con la clausola else if: sintatticamente simile all’if, essa permette di specificare ulteriori condizioni specifiche da prendere in considerazione, come spiegato di seguito.

if (condizione1) {
  istruzioni per gestire condizione1
}
else if (condizione2) {
 istruzioni per gestire condizione2
}
else {
istruzioni per gestire tutti gli altri scenari possibili
}

Switch/case

Il costrutto switch/case, esattamente come quello visto in precedenza, può influenzare l’esecuzione sequenziale delle istruzioni presenti nel codice sorgente di un programma. Sebbene il suo funzionamento sia simile a quello dell’if/else (cioè “saltare” a un dato insieme di istruzioni al verificarsi di determinate condizioni), viene utilizzato in scenari abbastanza differenti: lo switch/case, infatti, è adatto nelle decisioni dipendenti dal valore di una variabile e non da un’operazione booleana. Nel linguaggio umano, puoi intenderlo un po’ come “salta al caso (case) X se la variabile da analizzare (switch) assume il valore X, altrimenti esegui l’operazione predefinita (default)”.

Per esempio, è possibile utilizzare lo switch/case nel caso di gestione dell’input: per esempio, il programma assume un comportamento alla pressione del tasto a, un altro alla pressione del tasto b, un altro ancora alla pressione del tasto c e così via. Sintatticamente, questo controllo condizionale è espresso nel modo seguente.

switch(variabile) {
case: valore_variabile1
 istruzione1;
 istruzione2;
 ...
break;
case: valore_variabile2
 istruzione3;
 istruzione4;
 ...
break;
default:
 istruzioni per gestire altre condizioni
 break;
}

Al termine di ogni set di istruzioni per la gestione dei vari casi, è fondamentale specificare la clausola break per uscire dal ciclo di esecuzione e non bloccare il programma in un loop infinito, cioè in una condizione dalla quale non è in grado di uscire.

Ad esempio, questo estratto di codice potrebbe essere utilizzato per un programma che offre più funzioni contemporaneamente, variabili in base all’input da tastiera (in questo caso, all’utente viene chiesto di digitare le lettere a o c per scegliere la funzionalità desiderata).

char scelta;
printf("Scegli la funzione da utilizzare - a per aprire un file, c per chiuderlo\n");
scanf(%c, &scelta);
switch(scelta) {
    case 'a':
      istruzioni per aprire un file;
      break;
    case 'u':
      istruzioni per chiudere un file;
      break;
default
      printf("Comando non riconosciuto!");
      break;
}
 

Operatori ternari

Un’altra forma della condizione if/else di cui ti ho parlato poco fa prevede l’utilizzo degli operatori ternari :. Questi, di fatto, permettono di “abbreviare” la sintassi del summenzionato condizionale, e sono particolarmente usati se bisogna impartire due differenti istruzioni a seconda del risultato (vero o falso) dell’espressione booleana di confronto.

condizione ? istruzione_se_vera : istruzione_se_falsa

Ad esempio, volendo confrontare due variabili e dare comunicazione all’utente riguardo l’esito, si potrebbe usare il codice seguente.

(a>=b) ? printf("La variabile a è maggiore o uguale a b") : printf("La variabile a è minore di b\n");

Le funzioni

Ora che hai compreso appieno le parti fondamentali del linguaggio C, è il momento di metterle insieme per creare qualcosa che funzioni. Prima di farlo, però, è bene affrontare il concetto di funzione: per definizione, una funzione in C è una parte di codice che esegue l’algoritmo necessario a ottenere il risultato desiderato.

In altre parole, la funzione è l’insieme di statement atti a manipolare i dati in ingresso e produrre dati in uscita che siano in linea con le necessità del programmatore. In C, le funzioni possono essere sia dichiarate che definite: nel primo caso, si “avvisa” il compilatore dei dati in entrata, dei dati in uscita e del nome della funzione stessa (ad es. int aggiungi(int a, int b);), così da permettergli la predisposizione delle varie zone di memoria, mentre nel secondo caso si specificano gli statement necessari all’elaborazione dei dati, come mostrato nell’esempio di seguito.

int aggiungi(int a, int b) { //funzione per eseguire una somma
return a+b;
}

Il valore che la funzione deve restituire è espresso attraverso la clausola return, specificata subito prima della fine del codice della funzione stessa; tutti gli statement che ne fanno parte, inoltre, devono essere racchiusi tra due parentesi graffe. Dopo essere stata dichiarata e definita, la funzione può essere utilizzata in qualsiasi altra parte del codice sorgente, specificando ove necessario gli eventuali valori d’ingresso e, se richiesto, assegnando il valore di uscita a una variabile. Nel codice seguente, il valore della variabile somma viene impostato a 9.

int somma = aggiungi(5, 4);

In linea del tutto generale, le funzioni vengono dichiarate prima del corpo del main (di cui ti parlerò tra breve) e definite subito dopo di esso. Una funzione dichiarata può essere inclusa nel codice che ne precede la definizione ma deve essere obbligatoriamente definita nel codice sorgente in cui viene richiamata, altrimenti verrà generato un errore in fase di esecuzione del programma (che, invece, verrà compilato senza problemi).

La funzione “speciale” main()

Ora che hai tutte, ma proprio tutte le nozioni di base di questo linguaggio, è arrivato il momento di spiegarti il funzionamento di una funzione piuttosto speciale, quella da cui parte l’esecuzione di ogni codice sorgente in C: la funzione main(). Essa rappresenta il flusso di esecuzione principale di un codice sorgente e contiene tutte le istruzioni necessarie a elaborare i dati richiesti dal programmatore. In altre parole, la funzione main() è il “motore” di un programma C, che permette di eseguire l’algoritmo principale progettato dal programmatore stesso.

Al suo interno possono essere utilizzate variabili ed espressioni condizionali di ogni tipo, richiamate funzioni appartenenti alle librerie specificate tramite la clausola #include, funzioni dichiarate e definite all’interno dello stesso corpo del codice sorgente e così via. Una funzione main non deve essere dichiarata, ma deve essere definita direttamente all’interno del codice (solitamente questo viene fatto dopo la dichiarazione di variabili e funzioni “globali”, cioè utilizzabili da tutte le funzioni del sorgente, e prima della loro definizione).

A questo punto, è assolutamente semplice intuire che un codice sorgente C, affinché possa essere eseguito, deve contenere una e una sola funzione main(). In linea del tutto generale, la funzione main ritorna un valore intero (che viene utilizzato, di solito, per la gestione degli errori di esecuzione) e non prende valori in ingresso.

int somma(a,b);

int main(void) { 
int x = 5, int y = 6, int somma;
somma = aggiungi(x, y);
printf("Il valore finale è %i", somma);
return 0;
}

int somma(a,b) {
  return a+b;
}

Esempio di codice funzionante

Ora che conosci tutte le informazioni di base su questo affascinante linguaggio, dovresti essere perfettamente in grado di metterle insieme e scrivere un piccolo programma funzionante. Il primo esempio che voglio illustrarti è il classico “Hello World”, cioè un programma che altro non fa che stampare a video il saluto “Ciao, mondo!”. Di seguito ti mostro il codice sorgente HelloWorld.c, che andrà poi compilato per diventare un file pronto per l’esecuzione.

#include <stdio.h> //Include le funzioni definite nella libreria di standard I/O, tra cui printf()

int main(void){ //dichiarazione della funzione principale main
   printf("Ciao, mondo!\n"); //funzione che stampa a video un testo ricevuto come parametro
   return 0; //dichiara il valore di ritorno del main (in genere, il valore 0 denota la terminazione con successo)
}

Sei riuscito a comprendere a fondo il codice illustrato poc’anzi? Ottimo! Allora, come prova aggiuntiva, vorrei proporti un secondo codice sorgente (da chiamare, per esempio, calc.c), leggermente più complesso, che simuli il comportamento di una calcolatrice molto elementare.

In esso, la funzione main si occuperà di raccogliere i dati e darli “in pasto” a una delle quattro funzioni progettate per eseguire le operazioni principali (addizione, sottrazione, moltiplicazione e divisione). Infine, sarà sempre il main a occuparsi di mostrare il risultato finale.

#include <stdio.h>
#include <stdlib.h>

int addizione(int a, int b); //Dichiarazione delle funzioni che eseguono i calcoli
int sottrazione (int a, int b);
long moltiplicazione (int a, int b);
float divisione (int a, int b);

int main(void) {

int val1, val2, res1; //Dichiarazione delle variabili da usare nel main
 long res2;
 float val5, val6, res3;
 char scelta;

 printf("Quale delle quattro operazioni vuoi eseguire?\n");
 printf("+ per addizione, - per sottrazione\n");
 printf("* per moltiplicazione, / per divisione\n");
 scanf("%c",&scelta); //lettura dell'input da tastiera

switch(scelta) { //ciclo switch/case che controlla l'operazione da eseguire

case '+':
 printf("Digita i valori da addizionare, separati da uno spazio\n");
 scanf("%i %i", &val1, &val2);
 res1=addizione(val1, val2);
 printf("Il risultato dell'operazione è %i \n", res1);
 break;

case '-':
 printf("Digita i valori da sottrarre, separati da uno spazio\n");
 scanf("%i %i", &val1, &val2);
 res1=sottrazione(val1, val2);
 printf("Il risultato dell'operazione è %i \n", res1);
 break;

case '*':
 printf("Digita i valori da moltiplicare, separati da uno spazio\n");
 scanf("%i %i", &val1, &val2);
 res2=moltiplicazione(val1, val2);
 printf("Il risultato dell'operazione è %ld \n", res2);
 break;

case '/':
 printf("Digita i valori da dividere, separati da uno spazio\n");
 scanf("%f %f", &val5, &val6);
 if (val6==0)
 printf("Impossibile dividere per 0\n");
 else {
 res3=divisione(val5, val6);
 printf("Il risultato dell'operazione è %f \n", res3); }
 break;

default:
 printf("Scelta non valida!\n");
 break;
 }
 return 0;
}

//Definizione delle funzioni per eseguire le operazioni
int addizione(int a, int b) {
 return a+b;
}

int sottrazione(int a, int b) {
 return a-b;
}

long moltiplicazione (int a, int b){
 return a*b;
}

float divisione (int a, int b) {
 return a/b;
}

Scommetto che sei riuscito a capire alla perfezione il funzionamento di questo programma, ma hai paura di non essere capace di scrivere qualcosa di simile? Non gettare la spugna e continua a esercitarti: sono sicuro che, nel giro di poche ore, sarai in grado di scrivere da te un programma che funzioni!

Come compilare ed eseguire un programma in C

Dopo aver acquisito le nozioni di base sul linguaggio C, oltre che aver dato un’occhiata a un prototipo di programma funzionante, è arrivato il momento di passare alla pratica e capire come compilare ed eseguire un programma in C utilizzando i vari sistemi operativi. Ti annuncio fin da subito che, a differenza di Windows (che necessita di software aggiuntivo), macOS e Linux sono nativamente “predisposti” per la compilazione di codici sorgenti in C: basta conoscere le istruzioni giuste da impartire!

Windows

Come ti ho già accennato poco fa, per trasformare un codice sorgente C in un programma funzionante, c’è bisogno di installare un componente aggiuntivo per predisporre il sistema operativo a questa operazione: sto parlando di Visual Studio Community.

Per farlo, collegati alla pagina Internet del programma, pigia sul pulsante Download gratuito residente nel riquadro Visual Studio Community, avvia il file scaricato (ad es. Community.exe), dopodiché pigia sul pulsante Continua, imposta il segno di spunta accanto alla voce Sviluppo di applicazioni desktop con C++ nella finestra proposta, ripeti l’operazione con la voce Supporto C++/Cli collocata nel riquadro destro e, per terminare, clicca sul pulsante Installa, per poi chiudere la finestra di setup al termine della procedura.

A questo punto, richiama il Blocco Note dalla cartella Accessori Windows del menu Start (a cui puoi accedere cliccando sul pulsante a forma di bandierina, collocato nell’angolo in basso a sinistra dello schermo), digita nella finestra dell’editor il codice del tuo programma e, per procedere al salvataggio, clicca sul menu File collocato in alto a sinistra e seleziona da esso la voce Salva con nome…. Fatto ciò, seleziona la voce Tutti i file dal menu a tendina Salva come, annesso alla schermata di salvataggio che va ad aprirsi, digita il nome del tuo programma, seguito dall’estensione .c (ad es. calc.c), nella casella Nome file, per poi salvarlo sul Desktop.

Per compilare il codice sorgente appena creato, avvia un Prompt dei comandi per sviluppatori richiamandolo dalla cartella Visual Studio del menu Start, digita al suo interno i comandi cd %USERPROFILE%\Desktopcl nomeProgramma.c, entrambi seguiti dal pulsante Invio, per poi avviare il programma appena creato sul desktop (ad es. calc.exe) con un doppio clic.

macOS/Linux

Come ti ho già spiegato in precedenza, macOS e Linux sono nativamente predisposti alla compilazione di programmi scritti in C, in quanto tali sistemi operativi sono fortemente basati su di esso. Dunque, per compilare ed eseguire un programma in C, richiama il Terminale dal Launchpad di macOS oppure dalla Visuale attività/menu principale della distribuzione Linux che stai usando, digita il comando cd ~/Desktop (se sei su macOS) o cd ~/Scrivania (se stai usando invece Linux) seguito dal tasto Invio e, ancora, il comando touch nomeprogramma.c (ad es. calc.c), sempre seguito da Invio.

A questo punto, lasciando il Terminale aperto (puoi ridurlo a icona, se lo desideri), fai doppio clic sul file .c così creato sul Desktop, digita al suo interno il codice del tuo programma C e salva il file. Per compilarlo, richiama il Terminale e digita il comando gcc nomeprogramma.c -o nomeprogramma seguito dalla pressione del tasto Invio e, per eseguirlo, impartisci il comando ./nomeprogramma, sempre premendo successivamente Invio.

Ti consiglio di leggere con attenzione gli eventuali messaggi d’avviso restituiti dal compilatore: questi, nella maggior parte dei casi, sono un’ottimo punto di partenza per localizzare e correggere eventuali errori presenti nel tuo programma.

Risorse utili

Come programmare in C - risorse utili

Ora che disponi di tutte le nozioni fondamentali del caso e che hai un’idea ben chiara di come programmare in C, sei perfettamente in grado di valutare se questo è il linguaggio di programmazione che fa per te. In caso affermativo, come ti avevo promesso all’inizio di questo tutorial, vorrei indirizzarti verso ulteriori risorse utili che possano aiutarti a migliorare ulteriormente il tuo approccio con il linguaggio in questione, oltre che accrescere le tue conoscenze e aiutarti ad acquisire ulteriori competenze specifiche in merito.

  • Notepad++ – uno dei più piccoli e flessibili editor per scrivere (e indentare correttamente) file sorgenti in linguaggio C in ambiente Windows. Supporta numerosi linguaggi di programmazione.
  • Eclipse – è un intero framework di programmazione, utile a organizzare e tenere ordinati progetti anche particolarmente complessi. Supporta tutti i tipi di file previsti da programmi scritti in C (file sorgenti, file oggetti, header, librerie e quant’altro) e permette, se necessario, di creare grafici UML e file di guida.
  • Guida al C di HTML.it – è sicuramente un’ottima risorsa gratuita. Tra le pagine di questa preziosa guida, accessibile liberamente da chiunque e senza registrazione alcuna, puoi trovare approfondimenti e lezioni mirate a raffinare le tue abilità da programmatore C.
  • Linguaggio C – Principi di programmazione e manuale di riferimento (Kernighan/Ritchie) – è indubbiamente uno dei migliori testi su cui approfondire la propria conoscenza del C, noto agli esperti del settore come il “K&R” (dalle iniziali degli autori). Strutturato in due parti, questo testo offre inizialmente istruzioni su come approcciare al linguaggio in questione, per poi trasformarsi in un vero e proprio manuale che ne definisce tutte (o quasi) le funzioni utilizzabili nei molteplici scenari previsti. I due autori, Kernighan e Ritchie, sono coloro che hanno progettato e sviluppato l’intero linguaggio C.
  • C/C++ Programmer’s Reference (Schildt) – a mio avviso, uno dei testi più completi relativi al linguaggio C, da tenere assolutamente sulla scrivania se si intende approcciare a questo linguaggio per uso professionale. Adatto principalmente a utenti più o meno avanzati, contiene numerosi esempi relativi alle funzioni più utilizzate. Questo manuale può essere utilizzato anche da chi, invece, ha deciso di orientarsi verso la versione “a oggetti” del linguaggio C, il C++.

In qualità di affiliati Amazon, riceviamo un guadagno dagli acquisti idonei effettuati tramite i link presenti sul nostro sito.

Salvatore Aranzulla

Autore

Salvatore Aranzulla

Salvatore Aranzulla ĆØ il blogger e divulgatore informatico piĆ¹ letto in Italia. Noto per aver scoperto delle vulnerabilitĆ  nei siti di Google e Microsoft. Collabora con riviste di informatica e cura la rubrica tecnologica del quotidiano Il Messaggero. ƈ il fondatore di Aranzulla.it, uno dei trenta siti piĆ¹ visitati d'Italia, nel quale risponde con semplicitĆ  a migliaia di dubbi di tipo informatico. Ha pubblicato per Mondadori e Mondadori Informatica.