Documentazione C
Guida di riferimento a C concisa e ricca di esempi. Leggi il concetto, guarda il codice e poi mettilo in pratica in un percorso Coddy.
Inizia un percorso guidato di CGetting Started
- Cos'è CC è un linguaggio compilato, piccolo e veloce, nato nel 1972, che ancora oggi fa girare sistemi operativi, database e quasi ogni dispositivo embedded. Ecco cos'è, dove gira e perché vale la pena impararlo nel 2026.
- Installare C (GCC)Installa un compilatore C funzionante su qualsiasi sistema: MinGW-w64 su Windows, il clang di Apple su macOS e gcc su Linux, più come verificare l'installazione e compilare il tuo primo file.
- Compilare ed eseguireTrasforma un file .c in un programma funzionante: il comando gcc, cosa fanno davvero preprocessore, compilazione e linking, i flag da usare fin dal primo giorno e come leggere gli errori quando qualcosa va storto.
- Sintassi del COgni programma C ha lo stesso scheletro: include, una funzione main, istruzioni che terminano con il punto e virgola e blocchi tra graffe. Ecco cosa fa ogni parte e quali regole il compilatore impone davvero.
- CommentiIl C ha due stili di commento, quello su una riga // e quello su più righe /* */, con storie diverse e una trappola sull'annidamento. Ecco come usarli entrambi e cosa vale la pena commentare e cosa no.
Variables & Types
- VariabiliCome dichiarare una variabile in C, la differenza tra dichiarazione e inizializzazione, le regole per i nomi, dichiararne più di una alla volta e perché una variabile non inizializzata è il bug più comune tra i principianti.
- Tipi di datiOgni variabile C ha un tipo che ne fissa la dimensione e ciò che può contenere. Ecco tutti i tipi base, le loro dimensioni reali, signed e unsigned, sizeof, limits.h e cosa succede in caso di overflow.
- CostantiTre modi per dare un nome a un valore che non cambia mai in C: la parola chiave const, le macro #define e le costanti enum. Cosa sono davvero e quando usare ciascuna.
- OperatoriTutti gli operatori C che vale la pena conoscere, cioè aritmetici, di assegnazione, di confronto, logici e di incremento, più la trappola della divisione intera, come si comporta il modulo con i negativi e una tabella delle precedenze di cui fidarti.
- BooleaniC non ha avuto un tipo booleano fino a C99. Zero è falso, tutto il resto è vero, i confronti restituiscono int e stdbool.h aggiunge bool, true e false. In più il bug = vs == che questa scelta rende possibile.
- CastingIl C converte continuamente tra tipi, a volte perché l'hai chiesto con un cast e più spesso di sua iniziativa. Ecco le regole di promozione, la sintassi del cast esplicito e le conversioni che perdono dati in silenzio.
Control Flow
- if / elseCome decide il C: l'istruzione if, else, le catene di else if, l'annidamento e l'operatore ternario, più la regola della verità (0 è falso, tutto il resto è vero) e il bug `=` contro `==` che rompe le condizioni in silenzio.
- switchCome l'istruzione switch del C sceglie un ramo da un elenco di costanti: etichette case, perché break è importante, fall-through voluto e accidentale, default, switch su char ed enum, e quando switch batte una catena di else if.
- Ciclo forCome ripetere codice con il ciclo for del C: l'intestazione in tre parti, contare in avanti e all'indietro, percorrere gli array con il trucco di sizeof, cicli annidati, cicli infiniti e i bug off-by-one e unsigned che fregano tutti.
- Ciclo whileCome il ciclo while in C ripete finché una condizione cambia: la regola della condizione prima di tutto, i cicli con sentinella, la lettura dell'input fino a EOF, while(1) e come passare da for a while.
- Ciclo do-whileIl ciclo del C che esegue prima il corpo: come do-while garantisce un passaggio prima del test, perché finisce con un punto e virgola, gli schemi di menu e di nuovo tentativo per cui è nato e come si differenzia da un semplice while.
- break e continuebreak esce da un ciclo o da uno switch; continue salta al passaggio successivo. Come si comportano in for, while e do-while, come uscire da cicli annidati con un flag o goto, e gli abusi che rendono i cicli difficili da seguire.
Functions
- FunzioniCome definire e chiamare le funzioni in C: il tipo di ritorno, i parametri, i valori di ritorno, le funzioni void, perché conta la scomposizione e un esempio completo costruito da piccoli pezzi con un nome.
- Parametri delle funzioniIl C passa tutto per valore: le funzioni ricevono copie, mai gli originali. Cosa significa in pratica, come i puntatori simulano il passaggio per riferimento, perché gli array si comportano diversamente e come restituire più risultati.
- Prototipi di funzionePerché il C deve vedere la forma di una funzione prima che tu la chiami: scrivere prototipi, risolvere gli errori di dichiarazione implicita, mettere i prototipi nei file header e la vera differenza tra f(void) e f().
- RicorsioneCome una funzione C chiama se stessa: il caso base che la ferma, fattoriale e Fibonacci svolti passo per passo, perché il Fibonacci ingenuo è disastrosamente lento, cos'è davvero uno stack overflow e quando un ciclo è la risposta migliore.
- ScopeDove è visibile una variabile C e quanto a lungo vive: scope di blocco, parametri delle funzioni, variabili globali a livello di file, variabili locali static che sopravvivono tra una chiamata e l'altra, funzioni static, shadowing e perché le globali creano problemi.
Pointers
- PuntatoriUn puntatore è una variabile che memorizza un indirizzo di memoria. Questa pagina costruisce l'idea da zero: gli operatori & e *, dichiarare e dereferenziare i puntatori, perché il tipo del puntatore conta e la funzione swap() che mostra perché i puntatori esistono.
- Aritmetica dei puntatoriSommare 1 a un puntatore non aggiunge 1 byte: lo sposta sull'oggetto successivo di quel tipo. Questa pagina tratta ptr+1, incremento e decremento, differenza tra puntatori, confronti, come percorrere un array con un puntatore e la regola dell'elemento oltre la fine.
- Puntatori e arrayIn C il nome di un array diventa un puntatore al suo primo elemento quasi ovunque lo usi. Questa pagina spiega quel decadimento, perché arr[i] è letteralmente *(arr+i), perché la dimensione dell'array deve viaggiare a parte nelle funzioni e in cosa un puntatore a un array differisce da un array di puntatori.
- Puntatori a funzioneAnche le funzioni hanno un indirizzo, e un puntatore a funzione lo memorizza. Questa pagina decifra la sintassi della dichiarazione, mostra come typedef la rende leggibile e arriva a callback, qsort con un comparatore personalizzato e tabelle di dispatch.
- Puntatori NULLNULL è l'indirizzo che contiene un puntatore quando non punta a nulla. Questa pagina spiega cos'è davvero NULL, perché dereferenziarlo causa un crash, in cosa differisce da 0 e da un puntatore non inizializzato, e gli schemi difensivi che tengono i bug da null fuori dal tuo codice.
Arrays & Strings
- ArrayCome dichiarare e inizializzare gli array in C, indicizzarli da zero, calcolarne la lunghezza con sizeof, scorrere gli elementi e perché leggere oltre la fine è comportamento indefinito e non un messaggio di errore.
- Array multidimensionaliCome dichiarare, inizializzare e scorrere gli array 2D in C, cosa significa davvero in memoria la disposizione per righe, perché passare un array 2D a una funzione richiede il numero di colonne e un esempio svolto con le matrici.
- StringheIl C non ha un tipo stringa: una stringa è un array di char che termina con un byte '\0'. Questa pagina costruisce questo modello mentale e poi tratta i letterali, la stampa, lo scorrimento e perché non puoi copiare una stringa con =.
- Funzioni sulle stringheUn giro pratico in <string.h>: misurare con strlen, copiare con strcpy e strncpy, unire con strcat, confrontare con strcmp, cercare con strchr e strstr, e come dimensionare i buffer perché nessuna di queste vada in overflow.
- Conversione di stringheConvertire tra testo e numeri in C: perché atoi non può segnalare un errore, come usare correttamente strtol e strtod con endptr ed errno, trasformare numeri in stringhe con snprintf e i trucchi sulle singole cifre con '0'.
Dynamic Memory
- Memoria dinamicaPerché esiste l'heap, come malloc ti dà memoria la cui dimensione si decide a runtime, l'idioma p = malloc(n * sizeof *p), il controllo di NULL, liberare esattamente una volta e un array dinamico dall'inizio alla fine.
- calloc e realloccalloc ti dà memoria azzerata e moltiplica la dimensione in modo sicuro; realloc ingrandisce un blocco che hai già riempito. Questa pagina copre entrambe, l'idioma del puntatore temporaneo che evita perdite quando realloc fallisce e quando calloc batte malloc più memset.
- Memory leakCos'è davvero un memory leak, i tre modi in cui i programmi C li producono, la disciplina della proprietà che li previene e come trovare gli altri con valgrind e -fsanitize=address, per finire con un programma che perde memoria corretto passo dopo passo.
- Stack e heapDove vivono davvero i tuoi dati: memoria automatica sullo stack, memoria dinamica sull'heap e memoria statica come terza regione, con il classico bug del puntatore pendente quando si restituisce una locale e una regola per scegliere.
Structs, Unions & Enums
- StructCome raggruppare valori correlati in un unico tipo con una struct C: dichiararla, accedere ai membri con l'operatore punto, inizializzatori designati, array di struct, annidamento e la regola della copia al passaggio che sorprende tutti.
- Struct e puntatoriCome puntare a una struct in C: l'operatore freccia, perché (*p).x ha bisogno delle parentesi, passare le struct per puntatore per modificarle o evitare copie, allocare una struct con malloc e costruire il nodo di una lista concatenata.
- typedefCome typedef dà un nuovo nome a un tipo C esistente: l'idioma typedef struct con e senza tag, typedef per puntatori a funzione e array, e l'unico caso in cui un typedef fa danni: nascondere un puntatore.
- UnionCome una union in C memorizza più tipi negli stessi byte: perché la sua dimensione è quella del membro più grande, perché devi leggere il membro scritto per ultimo e come una tagged union (enum più union) la rende sicura.
- enumCome definire un enum in C: numerazione automatica, valori espliciti, enum in uno switch perché il compilatore segnali i casi mancanti, conversione di un enum in stringa e le convenzioni di nomi che li mantengono leggibili.
Input & Output
- printfCome funziona davvero printf in C: il modello della stringa di formato, gli specificatori che usi ogni giorno, larghezza e precisione per un output allineato, stampare i float in modo sensato, il valore di ritorno e perché printf(user_input) è una falla di sicurezza.
- scanfCome leggere l'input con scanf in C: perché la & è obbligatoria, come vengono gestiti gli spazi, l'overflow del buffer con %s e la larghezza che lo evita, il controllo del valore di ritorno, il bug dell'a capo rimasto nel buffer e fgets come alternativa robusta.
- Specificatori di formatoTutti gli specificatori di formato del C in un unico posto: cosa significano %d, %s, %c, %f, %p e gli altri, i modificatori di lunghezza l, ll, h e z, larghezza, precisione e flag, e quali cambiano tra printf e scanf.
- Gestione dei fileCome leggere e scrivere file in C: la tabella delle modalità di fopen, il controllo di NULL, scrivere con fprintf e fputc, leggere con fgets, fscanf e fgetc, il ciclo canonico riga per riga e quando usare la modalità binaria.
- Argomenti da riga di comandoCome un programma C legge la sua riga di comando: com'è fatto argc e argv, come scorrere gli argomenti, cosa contiene argv[0], come convertire numeri con strtol invece di atoi e una piccola calcolatrice che mette tutto insieme.
The Preprocessor
- PreprocessoreIl preprocessore modifica il testo del tuo sorgente prima che il compilatore lo veda: incolla gli header, sostituisce le macro e attiva o disattiva parti di codice. Ecco l'intera famiglia di direttive e come guardarne l'output.
- MacroMacro semplici e macro con argomenti con #define: perché ogni argomento e l'intero corpo vogliono le parentesi, la trappola della valutazione multipla, le macro su più righe con do-while(0) e quando una funzione o const è lo strumento migliore.
- File headerCome dividere un programma C su più file: cosa va in un .h, cosa va in un .c, le include guard che impediscono la doppia inclusione, compilare più file insieme e condividere variabili globali con extern.
- Compilazione condizionaleCompila codice diverso per build diverse con #ifdef, #ifndef, #if, #elif e #else: interruttori di debug, rami per piattaforma, macro definite da riga di comando con -D e #if 0 per disattivare codice.
Standard Library
- Funzioni matematicheUn giro in math.h: sqrt, pow, fabs, floor e ceil, round, fmod, le famiglie trigonometriche e dei logaritmi, INFINITY e NAN, più il flag del linker -lm che causa il classico errore undefined reference.
- Numeri casualiCome generare numeri casuali in C con rand() e RAND_MAX, perché si inizializza il seme con srand(time(NULL)) una volta sola, come portare il valore in un intervallo con % e il piccolo sbilanciamento che introduce, double casuali e sequenze riproducibili.
- Libreria standardCosa ti offre ogni header standard, cioè stdio.h, stdlib.h, string.h, math.h, time.h, ctype.h, limits.h, stdbool.h, stdint.h e assert.h, con un breve esempio funzionante per ciascuno.
Errors & Debugging
- Segmentation faultUn segfault significa che il tuo programma ha toccato memoria che non gli appartiene. Ecco le cinque cause che spiegano quasi tutti i casi, ognuna con un esempio minimo e la sua correzione, più come trovare la riga esatta con gdb e AddressSanitizer.
- Errori comuniGli errori che ogni programmatore C fa almeno una volta: punto e virgola mancanti, = al posto di ==, dichiarazioni implicite, scanf senza &, stringhe confrontate con ==, divisione intera, variabili non inizializzate ed errori di uno. Per ognuno sintomo, causa e soluzione.
- Comportamento indefinitoIl comportamento indefinito è codice su cui lo standard C non impone alcun requisito, quindi può succedere di tutto, anche che l'ottimizzatore cancelli i tuoi controlli. Ecco cosa lo causa, perché "sul mio computer funziona" non dimostra niente e quali flag lo intercettano.