HTML CSS JAVASCRIPT SQL MYSQL PYTHON JAVA PHP C C++ C# PACKET TRACER CYBERSECURITY REACTTYPESCRIPTNODE.JSGIT & GITHUBDATA SCIENCEBOOTSTRAPGOKOTLINJQUERYDJANGOVUEANGULAR MONGODB POSTGRESQL SASS NUMPY PANDAS SCIPY DSA RUST SWIFT BASHXMLW3.CSSANGULARJSAIAWSPROGRAMMAZIONEEXCEL WORD POWERPOINT
Corso gratuito

Corso di C in italiano

Il tutorial completo per imparare il linguaggio C da zero: il “padre” di tanti linguaggi moderni, veloce e vicino alla macchina. Esempi spiegati passo passo.

Introduzione al linguaggio C

C è un linguaggio di programmazione creato da Dennis Ritchie nei laboratori Bell nel 1972. È uno dei linguaggi più influenti della storia: da lui derivano C++, C#, Java, JavaScript e molti altri. È usato per sistemi operativi (Linux, Windows), driver, sistemi embedded, microcontrollori e tutto ciò che richiede massima velocità ed efficienza.

C è un linguaggio compilato, procedurale e di “basso livello” rispetto ad altri: dà al programmatore il controllo diretto della memoria. È più severo e tecnico, ma capirlo ti fa comprendere davvero come funziona un computer.

📌 C non si esegue nel browser: serve un compilatore (es. GCC). In questo corso gli esempi si leggono e si modificano con la sintassi colorata.
Esempio

Installare C (Get Started)

Per compilare codice C ti serve un compilatore. Il più diffuso è GCC (su Linux/macOS spesso già presente, su Windows tramite MinGW). Come editor si usano VS Code, Code::Blocks o Dev-C++.

Terminale

Sintassi e primo programma

Ogni programma C parte dalla funzione main(). La direttiva #include importa librerie (qui stdio.h per l'input/output). Le istruzioni terminano con ; e i blocchi sono tra { }.

Esempio

Output: la funzione printf

printf() stampa testo a schermo. Usa gli specificatori di formato per inserire valori: %d (interi), %f (decimali), %c (caratteri), %s (stringhe). \n manda a capo.

Esempio

I commenti

Commenti su una riga con //, su più righe con /* ... */.

Esempio

Le variabili

In C ogni variabile va dichiarata con il suo tipo prima dell'uso: tipo nome = valore;.

Esempio

I tipi di dato

I tipi fondamentali di C:

TipoDescrizioneprintf
intIntero%d
float / doubleDecimali%f
charCarattere singolo%c
char[]Stringa%s

C non ha un tipo booleano nativo nelle versioni storiche: si usano gli interi (0 = falso, diverso da 0 = vero) o stdbool.h.

Conversione di tipo (casting)

La conversione di tipo trasforma un valore da un tipo a un altro. Può essere implicita (automatica) o esplicita (cast manuale con (tipo)).

Esempio
💡 La divisione tra due interi dà un intero: 7/2 = 3. Per ottenere 3.5 serve il cast a double di almeno un operando.

Le costanti

Una costante non può cambiare valore. Si dichiara con const oppure con la direttiva #define.

Esempio

Gli operatori

Aritmetici (+ - * / %), di confronto (== != > <) e logici (&& || !).

Esempio

Booleans in C

C non aveva un tipo booleano nativo fino a C99. Includendo stdbool.h si possono usare bool, true e false. Senza la libreria, 0 è falso e qualsiasi altro valore è vero.

Esempio
📌 In C i booleani sono interi: true vale 1, false vale 0. Le funzioni di confronto restituiscono questi valori.

Input: la funzione scanf

scanf() legge dati dalla tastiera. Richiede l'operatore & davanti al nome della variabile (indirizzo in memoria).

Esempio

Le condizioni: if, else if, else

Esempio

Il costrutto switch

Esempio

Il ciclo while

Esempio

Il ciclo for

Esempio

Break e Continue

break interrompe immediatamente il ciclo; continue salta all'iterazione successiva.

Esempio

Gli array

Un array contiene più valori dello stesso tipo, con dimensione fissa. Si accede con l'indice (da 0).

Esempio

Le stringhe

In C una stringa è un array di caratteri che termina con il carattere nullo '\0'. La libreria string.h offre funzioni come strlen(), strcpy(), strcat().

Esempio

Le funzioni

Una funzione raggruppa codice riutilizzabile, con un tipo di ritorno, un nome e dei parametri. Si dichiara prima del main (o con un prototipo).

Esempio

Indirizzo di memoria

Ogni variabile è salvata in una cella di memoria con un proprio indirizzo. L'operatore & restituisce l'indirizzo di una variabile, che si stampa con %p.

Esempio
📌 Comprendere gli indirizzi di memoria è il primo passo per padroneggiare i puntatori, il cuore del linguaggio C.

I puntatori

I puntatori sono la caratteristica più potente (e temuta) di C: una variabile che contiene l'indirizzo di memoria di un'altra variabile. Si dichiarano con * e si ottiene l'indirizzo con &.

Esempio

Parametri delle funzioni

Le funzioni ricevono dati tramite i parametri. In C il passaggio è per valore: la funzione riceve una copia. Per modificare l'originale si passa un puntatore (passaggio per riferimento).

Per valore vs riferimento

Scope delle variabili

Lo scope determina dove una variabile è visibile. Le variabili locali esistono solo nel blocco in cui sono dichiarate; le globali sono visibili ovunque.

Esempio

Dichiarazione di funzione (prototipi)

Un prototipo dichiara la firma di una funzione prima del suo uso, separando dichiarazione e definizione. Permette di definire le funzioni dopo main().

Esempio
💡 I prototipi si raccolgono nei file header .h, mentre le definizioni stanno nei file .c: è la base dell'organizzazione del codice in C.

Funzioni matematiche

La libreria math.h offre funzioni matematiche avanzate. Ricorda di compilare con -lm.

Esempio

Funzioni inline

La parola chiave inline suggerisce al compilatore di inserire il corpo della funzione direttamente nel punto di chiamata, eliminando l'overhead della chiamata. Utile per funzioni piccole e frequenti.

Esempio
📌 inline è solo un suggerimento: il compilatore decide se applicarlo. Con l'ottimizzazione (-O2) GCC inlinea automaticamente le funzioni piccole.

Ricorsione

Una funzione ricorsiva chiama se stessa. Serve sempre un caso base che ferma la ricorsione, altrimenti si ha uno stack overflow.

Fattoriale e potenza

Puntatori a funzione

Un puntatore a funzione memorizza l'indirizzo di una funzione, permettendo di passarla come argomento o sceglierla a runtime (callback).

Esempio

Creare file in C

Si apre (creandolo) un file con fopen() in modalità "w" (scrittura). Restituisce un puntatore FILE* da chiudere con fclose().

Esempio
ModalitàSignificato
"r"Lettura (il file deve esistere)
"w"Scrittura (cancella il contenuto)
"a"Append (aggiunge in coda)
"r+"Lettura e scrittura

Scrivere su file

Con fprintf() si scrive testo formattato in un file, esattamente come printf() su schermo.

Esempio

Leggere da file

Con fgets() si legge una riga alla volta finché non si raggiunge la fine del file (EOF).

Esempio
💡 Controlla sempre che fopen() non restituisca NULL prima di leggere: il file potrebbe non esistere o non essere accessibile.

Le struct

Una struct raggruppa più variabili (anche di tipo diverso) in un unico tipo personalizzato: è l'antenato degli oggetti.

Esempio

Struct annidate

Una struct può contenere altre struct come campi. Utile per modellare dati gerarchici (es. uno studente che contiene una data).

Esempio

Struct e puntatori

Con un puntatore a struct si accede ai campi con l'operatore freccia -> invece del punto. È il modo più efficiente per passare struct alle funzioni.

Esempio

Union

Una union è simile a una struct, ma tutti i campi condividono la stessa area di memoria. Occupa lo spazio del campo più grande e può contenere un solo valore alla volta.

Esempio
📌 Differenza chiave: in una struct ogni campo ha la sua memoria; in una union condividono lo stesso spazio.

typedef

typedef crea un alias (un nuovo nome) per un tipo esistente. Si usa spesso per semplificare la sintassi delle struct.

Esempio

Enum

Un enum definisce un insieme di costanti intere con nomi leggibili. Per default partono da 0 e incrementano di 1.

Esempio

La gestione della memoria

In C il programmatore può allocare memoria dinamicamente con malloc() e liberarla con free() (libreria stdlib.h). È potente ma rischioso: dimenticare free() causa memory leak.

Esempio

Gestione errori in C

C non ha le eccezioni: gli errori si gestiscono controllando i valori di ritorno delle funzioni e la variabile globale errno (libreria errno.h).

Esempio
💡 Convenzione C: una funzione restituisce 0 in caso di successo e un valore diverso da zero in caso di errore.

Debugging in C

Il debugging individua e corregge gli errori. In C gli strumenti principali sono printf di controllo, il debugger GDB e l'analizzatore di memoria Valgrind.

  • Errori di compilazione: segnalati da GCC (sintassi, tipi)
  • Errori a runtime: segmentation fault, accessi a memoria non valida
  • Memory leak: memoria allocata e mai liberata (rilevati da Valgrind)
💡 Compila con gcc -g -Wall programma.c: -g abilita il debug con GDB, -Wall mostra tutti gli avvisi. Poi avvia valgrind ./a.out per scovare i memory leak.

NULL e puntatori nulli

NULL è un puntatore speciale che non punta a nulla. Si usa per indicare "nessun valore" e va sempre controllato prima di dereferenziare un puntatore.

Esempio
⚠️ Dereferenziare un puntatore NULL (es. *p quando p == NULL) causa un segmentation fault, il crash più comune in C.

Validazione dell'input

Validare l'input dell'utente previene crash e comportamenti imprevisti. scanf() restituisce il numero di valori letti correttamente: controllalo sempre.

Esempio

Data e ora

La libreria time.h fornisce funzioni per gestire data e ora di sistema.

Esempio

Numeri casuali

Le funzioni rand() e srand() (libreria stdlib.h) generano numeri pseudo-casuali. Si inizializza il seme con srand(time(NULL)).

Esempio

Macro e preprocessore

Le macro (#define) sono sostituzioni di testo effettuate dal preprocessore prima della compilazione. Si usano per costanti e piccole "funzioni".

Esempio
💡 Metti sempre le parentesi attorno ai parametri di una macro: QUADRATO(x) come ((x)*(x)) evita errori con espressioni come QUADRATO(2+3).

Storage classes

Le storage classes definiscono durata, visibilità e posizione in memoria delle variabili.

ClasseDescrizione
autoVariabile locale (default), durata limitata al blocco
staticConserva il valore tra le chiamate; visibilità limitata al file
externVariabile globale dichiarata in un altro file
registerSuggerisce di tenere la variabile in un registro CPU
static in azione

Operatori bitwise

Gli operatori bitwise lavorano sui singoli bit dei numeri. Sono usati in programmazione di basso livello, embedded e ottimizzazioni.

OperatoreNomeEsempio
&AND5 & 3 = 1
|OR5 | 3 = 7
^XOR5 ^ 3 = 6
~NOT~5 = -6
<<Shift sinistra5 << 1 = 10
>>Shift destra5 >> 1 = 2
Esempio

Esempi pratici C

Esempi reali e completi per consolidare la programmazione in C.

Numeri primi fino a N

Esempio

Ordinamento bubble sort

Esempio

Editor online C

Scrivi e leggi codice C con la sintassi colorata. Per eseguirlo installa GCC (o usa OnlineGDB), salva come programma.c e compila con gcc programma.c -o programma && ./programma.

Il tuo codice C

Quiz C — verifica le tue conoscenze

  1. Qual è la differenza tra = e ==?
    Risposta: = è l'assegnazione, == è il confronto di uguaglianza. Confonderli è un errore classico (es. if(x=5) assegna invece di confrontare).
  2. Cosa fa l'operatore & davanti a una variabile?
    Risposta: Restituisce l'indirizzo di memoria della variabile. Si usa con scanf e con i puntatori.
  3. Perché chiamare free() dopo malloc()?
    Risposta: Per liberare la memoria allocata dinamicamente ed evitare i memory leak. C non ha garbage collector.
  4. Cos'è un segmentation fault?
    Risposta: Un crash causato dall'accesso a una zona di memoria non valida (es. dereferenziare NULL o uscire dai limiti di un array).
  5. Qual è la differenza tra array e puntatore?
    Risposta: Un array è un blocco contiguo di memoria di dimensione fissa; un puntatore è una variabile che contiene un indirizzo. Il nome dell'array "decade" nell'indirizzo del primo elemento.

Esercizi C con soluzioni

Cinque esercizi con soluzione completa. Provaci prima di guardare!

Esercizio 1 — Fattoriale

Soluzione

Esercizio 2 — Inversione di una stringa

Soluzione

Esercizio 3 — Massimo di un array

Soluzione

Esercizio 4 — Conta vocali

Soluzione

Esercizio 5 — Serie di Fibonacci

Soluzione

Sfide C

  1. 🟢 Scrivi una funzione che verifica se un numero è palindromo (es. 12321).
  2. 🟡 Implementa una calcolatrice con menu che usa puntatori a funzione per le operazioni.
  3. 🟡 Crea una lista concatenata (linked list) con funzioni per inserire, rimuovere e stampare i nodi.
  4. 🔴 Implementa uno stack e una coda con allocazione dinamica della memoria.
  5. 🔴 Scrivi un programma che legge un file di testo e conta parole, righe e caratteri (come il comando wc).

Progetti pratici con C

  • 🎮 Gioco indovina il numero: con numeri casuali e conteggio tentativi
  • 📇 Rubrica telefonica: con struct, file e ricerca
  • 🧮 Calcolatrice scientifica: con puntatori a funzione
  • 📊 Gestione magazzino: CRUD su file binario con struct
  • 🔢 Convertitore di basi: decimale, binario, esadecimale
  • 📝 Editor di testo minimale: lettura/scrittura file da terminale

Programma completo del corso C

ModuloArgomentiOre
1 — BasiInstallazione GCC, sintassi, printf, variabili, tipi, conversione, costanti6
2 — ControlloOperatori, booleans, if/else, switch, while, for, break/continue5
3 — Array e stringheArray, stringhe, indirizzi di memoria, puntatori6
4 — FunzioniParametri, scope, prototipi, math, inline, ricorsione, puntatori a funzione7
5 — StruttureStruct, struct annidate, union, typedef, enum6
6 — Memoriamalloc/free, NULL, errori, debugging, validazione input6
7 — FileCreare, scrivere e leggere file4
8 — AvanzatoDate, random, macro, storage classes, bitwise5
9 — ProgettoRealizzazione di un progetto completo8

Piano di studio C (8 settimane)

SettimanaObiettivo
1Installazione GCC, sintassi, printf/scanf, variabili, tipi, conversione
2Operatori, booleans, if/else, switch, cicli, break/continue
3Array, stringhe, indirizzi di memoria, puntatori
4Funzioni: parametri, scope, prototipi, ricorsione, puntatori a funzione
5Struct, struct annidate, union, typedef, enum
6Gestione memoria: malloc/free, NULL, debugging con GDB/Valgrind
7File: creare, scrivere, leggere; gestione errori
8Macro, storage classes, bitwise — progetto finale

Domande da colloquio C

  • 💬 Differenza tra malloc e calloc? — Entrambi allocano memoria; calloc la inizializza a zero e prende numero+dimensione come parametri separati.
  • 💬 Cos'è un dangling pointer? — Un puntatore che punta a memoria già liberata con free(). Per evitarlo, imposta il puntatore a NULL dopo il free.
  • 💬 Differenza tra struct e union? — In una struct ogni campo ha la propria memoria; in una union tutti i campi condividono lo stesso spazio (dimensione = campo più grande).
  • 💬 Cosa significa passaggio per valore e per riferimento? — Per valore si copia il dato (le modifiche non escono dalla funzione); con i puntatori si passa l'indirizzo, modificando l'originale.
  • 💬 Cos'è il preprocessore? — Elabora le direttive #include, #define, #ifdef PRIMA della compilazione, sostituendo testo.
  • 💬 Perché C non ha garbage collector? — Per dare al programmatore il controllo totale e massime prestazioni. La memoria va gestita manualmente con malloc/free.

Riferimento — Parole chiave C

KeywordUso
int, char, float, doubleTipi di dato base
short, long, signed, unsignedModificatori di tipo
if, else, switch, case, defaultControllo condizionale
for, while, doCicli
break, continue, return, gotoControllo di flusso
struct, union, enum, typedefTipi personalizzati
constValore costante
static, extern, auto, registerStorage classes
sizeofDimensione in byte di un tipo
voidTipo vuoto / nessun valore

Riferimento — <stdio.h>

FunzioneDescrizione
printf()Stampa formattata su schermo
scanf()Legge input formattato da tastiera
puts()Stampa una stringa + a capo
gets() / fgets()Legge una riga (usa fgets, sicuro)
getchar() / putchar()Legge/scrive un singolo carattere
fopen() / fclose()Apre / chiude un file
fprintf() / fscanf()Scrive / legge su file
fgets() / fputs()Legge / scrive righe su file
sprintf()Stampa formattata in una stringa

Specificatori di formato

SpecificatoreTipo
%dint
%ffloat / double
%cchar
%sstringa
%ppuntatore (indirizzo)
%xesadecimale
%ldlong

Riferimento — <string.h>

FunzioneDescrizioneEsempio
strlen()Lunghezza stringastrlen("C") → 1
strcpy()Copia una stringastrcpy(dest, src)
strncpy()Copia n caratteri (sicuro)strncpy(d, s, 10)
strcat()Concatena stringhestrcat(s1, s2)
strcmp()Confronta stringhestrcmp("a","b") → -1
strchr()Cerca un caratterestrchr("casa",'s')
strstr()Cerca una sottostringastrstr("casa","sa")
strtok()Divide in tokenstrtok(s, ",")
memset()Riempie memoria con un valorememset(a, 0, n)
memcpy()Copia blocchi di memoriamemcpy(d, s, n)

Riferimento — <math.h>

FunzioneDescrizioneEsempio
sqrt()Radice quadratasqrt(16) → 4.0
pow()Potenzapow(2,10) → 1024
fabs()Valore assoluto (double)fabs(-5.5) → 5.5
ceil()Arrotonda per eccessoceil(4.1) → 5
floor()Arrotonda per difettofloor(4.9) → 4
round()Arrotondaround(4.5) → 5
sin() cos() tan()Trigonometria (radianti)sin(0) → 0
log() / log10()Logaritmo naturale / base 10log10(1000) → 3
exp()e elevato a xexp(1) → 2.718
fmod()Resto in virgola mobilefmod(7.5,2) → 1.5
📌 Per usare <math.h> compila linkando la libreria matematica: gcc programma.c -lm

Certificazione C

Le certificazioni in linguaggio C sono apprezzate nei settori embedded, sistemi e sicurezza:

CertificazioneEnteLivello
CLA — C Programming Language Certified AssociateC++ Institute / Pearson VUEBase/Intermedio
CLP — C Certified Professional ProgrammerC++ InstituteAvanzato
C CertificationW3SchoolsBase

Come prepararsi

  • 📚 Studia il classico The C Programming Language di Kernighan & Ritchie (il "K&R")
  • 💻 Pratica con progetti reali: strutture dati, gestione file, allocazione dinamica
  • 🛠️ Impara a usare GCC, GDB e Valgrind
  • 🧪 Esercitati con mock exam del C++ Institute
  • ⏱️ Tempo medio di preparazione CLA: 2-3 mesi

Conclusione — E ora?

Hai completato il corso di C! Hai imparato la sintassi, i puntatori, le struct, la gestione manuale della memoria, i file e le funzionalità avanzate. C è impegnativo ma formativo: ti dà basi solidissime per qualsiasi altro linguaggio.

E ora cosa fare?

  • 💻 Installa GCC (MinGW su Windows, già presente su Linux/Mac) e compila in locale
  • 🐛 Impara GDB e Valgrind per il debug e la caccia ai memory leak
  • 🐙 Pubblica i progetti su GitHub per il tuo portfolio
  • 🚀 Passa al C++ per la programmazione a oggetti, oppure approfondisci l'embedded (Arduino, microcontrollori)
  • 🔐 Esplora la sicurezza: buffer overflow, gestione memoria sicura
  • 🎯 Punta alla certificazione CLA del C++ Institute
🎯 La tua sfida finale

Scrivi un programma in C che legge 10 numeri in un array, li ordina dal più piccolo al più grande con una funzione separata e calcola media, massimo e minimo. Bonus: salva i risultati in un file di testo.

✏️ Provalo tu — leggi e modifica il codice C
Anteprima