Ambiente di Sviluppo
Installa tutti gli strumenti necessari per programmare in C e C++ sul tuo computer.
Come funziona il processo
Prima di scrivere codice, devi capire il flusso di lavoro fondamentale. Il C non Γ¨ interpretato come Python: devi compilare il tuo codice per ottenere un file eseguibile.
1. Scrivi il codice
Crei un file .c o .cpp con un editor di testo o IDE.
2. Compila
Il compilatore (GCC/G++) trasforma il tuo codice in linguaggio macchina.
3. Esegui
Lanci il file eseguibile generato nel terminale.
4. Debug
Se ci sono errori, li correggi e ricompili.
π§ Installazione su Linux (Ubuntu/Debian)
Su Linux, GCC Γ¨ quasi sempre giΓ disponibile o facilmente installabile.
# Aggiorna i pacchetti
sudo apt update
# Installa GCC, G++ e gli strumenti di sviluppo
sudo apt install build-essential gdb valgrind
# Verifica l'installazione
gcc --version # dovrebbe mostrare: gcc (Ubuntu ...) X.X.X
g++ --version
gdb --version
# Installa anche make e cmake (build system)
sudo apt install make cmake
build-essential installa tutto il necessario: gcc, g++, make, e le header di sistema.
π Installazione su macOS
# Opzione 1: Xcode Command Line Tools (piΓΉ veloce)
xcode-select --install
# Segui le istruzioni nella finestra che si apre
# Verifica
clang --version # su macOS, gcc Γ¨ spesso un alias di clang
# Opzione 2: GCC nativo con Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install gcc
# Con Homebrew, gcc si chiama gcc-13 (o versione corrente)
gcc-13 --version
πͺ Installazione su Windows
Su Windows hai due opzioni principali:
Opzione A: WSL2 (raccomandato)
WSL (Windows Subsystem for Linux) ti dΓ un ambiente Linux completo dentro Windows. Γ la scelta migliore per programmare in C/C++.
# Installa WSL2 con Ubuntu
wsl --install
# Dopo il riavvio, apri "Ubuntu" dal menu Start
# Poi segui le istruzioni Linux sopra:
Opzione B: MinGW-w64 / MSYS2
# 1. Scarica MSYS2 da: https://www.msys2.org/
# 2. Installa e apri "MSYS2 UCRT64"
# 3. Aggiorna e installa GCC:
pacman -Syu
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gdb
# 4. Aggiungi al PATH: C:\msys64\ucrt64\bin
π₯οΈ Visual Studio Code β Setup
VS Code Γ¨ l'editor gratuito piΓΉ usato per C/C++. Γ leggero, veloce e ha ottime estensioni.
Estensioni essenziali
C/C++ (Microsoft)
IntelliSense, autocompletamento, navigazione del codice, debugging integrato.
C/C++ Extension Pack
Pacchetto completo con cmake, themes e altri strumenti utili.
Code Runner
Esegui file C/C++ con un tasto senza configurare task.json.
Clang-Format
Formattazione automatica del codice secondo standard definiti.
Configurazione tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Compila C",
"type": "shell",
"command": "gcc",
"args": [
"-Wall",
"-Wextra",
"-std=c17",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-lm"
],
"group": { "kind": "build", "isDefault": true },
"problemMatcher": ["$gcc"]
},
{
"label": "Compila C++",
"type": "shell",
"command": "g++",
"args": [
"-Wall",
"-Wextra",
"-std=c++17",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-lm"
],
"group": "build",
"problemMatcher": ["$gcc"]
}
]
}
Configurazione launch.json (Debugging)
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug C/C++",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "Compila C"
}
]
}
π© Flag del Compilatore
Comprendere i flag Γ¨ fondamentale per scrivere codice di qualitΓ .
| Flag | Significato | Quando usarlo |
|---|---|---|
| -Wall | Abilita i warning piΓΉ comuni | Sempre |
| -Wextra | Warning aggiuntivi | Sempre |
| -Werror | Tratta i warning come errori | Per codice pulito |
| -std=c17 | Standard C 2017 | Progetti C |
| -std=c++17 | Standard C++ 2017 | Progetti C++ |
| -g | Includi informazioni di debug | Durante lo sviluppo |
| -O0 | Nessuna ottimizzazione (default con -g) | Debug |
| -O2 | Ottimizzazione livello 2 | Release |
| -O3 | Ottimizzazione massima | Performance critica |
| -lm | Collega la libreria math | Quando usi <math.h> |
| -fsanitize=address | AddressSanitizer: rileva memory errors | Debug memoria |
| -fsanitize=undefined | UBSan: rileva undefined behavior | Debug comportamento |
# Compilazione base
gcc hello.c -o hello
# Compilazione con tutti i warning (raccomandato per imparare)
gcc -Wall -Wextra -std=c17 hello.c -o hello
# Compilazione con debug symbols (per gdb)
gcc -Wall -g -std=c17 hello.c -o hello
# Con sanitizer (trova bug di memoria a runtime)
gcc -Wall -g -fsanitize=address,undefined hello.c -o hello
# Build di release (ottimizzata)
gcc -O2 -std=c17 hello.c -o hello
# PiΓΉ file sorgente
gcc -Wall main.c utils.c lista.c -o programma
# Con libreria matematica
gcc -Wall calcoli.c -o calcoli -lm
π» Comandi Terminale Essenziali
Devi saper usare il terminale. Ecco i comandi indispensabili:
# Navigazione
pwd # mostra la directory corrente
ls # lista i file
ls -la # lista dettagliata con file nascosti
cd cartella # entra in una cartella
cd .. # vai su di un livello
cd ~ # vai alla home
cd /percorso/assoluto # vai a un percorso assoluto
# File e cartelle
mkdir miei_programmi # crea una cartella
touch hello.c # crea un file vuoto
cp sorgente.c copia.c # copia
mv vecchio.c nuovo.c # sposta/rinomina
rm file.c # elimina file (ATTENZIONE: non va nel cestino)
rm -rf cartella # elimina cartella e contenuto
# Visualizzare file
cat file.c # mostra il contenuto
less file.c # mostra a pagine (q per uscire)
head -n 10 file.c # mostra le prime 10 righe
# Compilazione ed esecuzione
gcc hello.c -o hello # compila
./hello # esegui
./hello > output.txt # reindirizza l'output su file
./hello < input.txt # leggi input da file
# Varie utili
clear # pulisce lo schermo
history # mostra i comandi precedenti
man gcc # manuale di gcc (q per uscire)
which gcc # dove si trova gcc
π Compilatori Online
Se non vuoi installare nulla subito, puoi iniziare con un compilatore online:
Godbolt β compiler-explorer.com
Il migliore. Mostra anche l'assembly generato. Supporta C, C++, e decine di compilatori.
onlinegdb.com
Compilatore online con debugger integrato. Ottimo per i principianti.
replit.com
IDE online completo. Puoi creare progetti e condividere il codice.
ideone.com
Semplice e veloce. Supporta C, C++ e molti altri linguaggi.
π― Verifica Finale β Il Tuo Primo Programma
Segui questi passi per verificare che tutto funzioni:
mkdir ~/programmazione-c
cd ~/programmazione-c
#include <stdio.h>
int main() {
printf("======================\n");
printf(" L'ambiente funziona!\n");
printf("======================\n");
printf("GCC e' installato correttamente.\n");
return 0;
}
gcc -Wall hello.c -o hello
./hello
====================== L'ambiente funziona! ====================== GCC e' installato correttamente.
file.c:riga:colonna: errore: messaggio. Leggi sempre il primo errore: spesso tutti gli altri sono conseguenza di uno solo. Dopo aver corretto, ricompila.
π Struttura di un Progetto C
mio-progetto/
βββ src/ # Codice sorgente (.c)
β βββ main.c
β βββ utils.c
β βββ lista.c
βββ include/ # Header file (.h)
β βββ utils.h
β βββ lista.h
βββ bin/ # Eseguibile compilato (gitignored)
βββ obj/ # File oggetto .o (gitignored)
βββ test/ # Test automatici
βββ Makefile # Script di build
βββ README.md # Documentazione
CC = gcc
CFLAGS = -Wall -Wextra -std=c17 -g
SRC = $(wildcard src/*.c)
OBJ = $(SRC:src/%.c=obj/%.o)
TARGET = bin/programma
all: dirs $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(OBJ) -o $@ -lm
obj/%.o: src/%.c
$(CC) $(CFLAGS) -Iinclude -c $< -o $@
dirs:
mkdir -p bin obj
clean:
rm -rf obj bin
run: all
./$(TARGET)
.PHONY: all clean run dirs
make # Compila tutto
make run # Compila e lancia
make clean # Pulisce i file generati
π Header File (.h) β Separare Dichiarazioni e Implementazioni
Quando il progetto cresce, dividi il codice in piΓΉ file. Gli header file contengono le dichiarazioni (prototipi, struct, costanti), i file .c contengono le implementazioni.
// Include guard: evita inclusioni multiple
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
// Dichiarazioni delle funzioni
double potenza(double base, int esp);
double radice_quadrata(double n);
int fattoriale(int n);
int mcd(int a, int b);
int mcm(int a, int b);
// Costanti
#define PI 3.14159265358979323846
#define E_NATU 2.71828182845904523536
#endif // MATH_UTILS_H
#include "math_utils.h" // Include il proprio header
#include <math.h>
double potenza(double base, int esp) {
if (esp == 0) return 1.0;
if (esp < 0) return 1.0 / potenza(base, -esp);
return base * potenza(base, esp - 1);
}
double radice_quadrata(double n) {
if (n < 0) return -1.0; // Errore
return sqrt(n);
}
int fattoriale(int n) {
if (n <= 1) return 1;
return n * fattoriale(n - 1);
}
int mcd(int a, int b) { return b == 0 ? a : mcd(b, a % b); }
int mcm(int a, int b) { return a / mcd(a, b) * b; } // Evita overflow
#include <stdio.h>
#include "math_utils.h"
int main() {
printf("2^10 = %.0f\n", potenza(2.0, 10));
printf("sqrt(144) = %.1f\n", radice_quadrata(144));
printf("10! = %d\n", fattoriale(10));
printf("MCD(48,18) = %d\n", mcd(48, 18));
printf("MCM(4,6) = %d\n", mcm(4, 6));
return 0;
}
gcc -Wall -Iinclude src/main.c src/math_utils.c -o programma -lm
Apri il terminale e verifica che gcc, g++ e make siano installati correttamente. Stampa le loro versioni. Poi crea una cartella ~/esercizi-c e al suo interno crea il file hello.c che stampi la tua versione di GCC nel programma (usa __VERSION__ e __STDC_VERSION__).
#include <stdio.h>
int main() {
printf("GCC version: %s\n", __VERSION__);
printf("C Standard: %ld\n", __STDC_VERSION__);
printf("Compilato il: %s alle %s\n", __DATE__, __TIME__);
printf("File: %s\n", __FILE__);
return 0;
}Scrivi intenzionalmente questo codice con 5 errori e prova a compilarlo. Poi leggi i messaggi di GCC e correggi uno alla volta. Il codice: dimentica il ; finale di printf, usa = invece di == in un if, dimentica di includere stdio.h, chiama una funzione inesistente, dimentica le parentesi del main.
/* File con errori intenzionali β da compilare per vedere i messaggi */
// ERRORE 1: manca #include <stdio.h>
int main() { // OK
int x = 5;
printf("x vale %d\n", x) // ERRORE 2: manca ;
if (x = 5) { // ERRORE 3: = invece di ==
printf("cinque\n");
}
funzione_inesistente(); // ERRORE 4: funzione non dichiarata
return 0;
}
/* Dopo aver visto gli errori, ecco la versione corretta: */
#include <stdio.h>
int main() {
int x = 5;
printf("x vale %d\n", x);
if (x == 5) {
printf("cinque\n");
}
return 0;
}Crea un progetto con la struttura src/, include/, bin/. Definisci un header stringhe.h con 3 funzioni su stringhe (conta vocali, capovolgi, conta parole). Implementale in stringhe.c. Usale in main.c. Scrivi un Makefile per compilare tutto.
/* include/stringhe.h */
#ifndef STRINGHE_H
#define STRINGHE_H
int conta_vocali(const char *s);
void capovolgi(char *s);
int conta_parole(const char *s);
#endif
/* src/stringhe.c */
#include "stringhe.h"
#include <string.h>
#include <ctype.h>
int conta_vocali(const char *s) {
int n = 0;
for (; *s; s++)
if (strchr("aeiouAEIOU", *s)) n++;
return n;
}
void capovolgi(char *s) {
char *inizio = s, *fine = s + strlen(s) - 1;
while (inizio < fine) { char t=*inizio; *inizio++=*fine; *fine--=t; }
}
int conta_parole(const char *s) {
int parole = 0, in_parola = 0;
for (; *s; s++) {
if (isspace(*s)) in_parola = 0;
else if (!in_parola) { parole++; in_parola = 1; }
}
return parole;
}
/* src/main.c */
#include <stdio.h>
#include "stringhe.h"
int main() {
char s[] = "Hello World Ciao";
printf("Vocali: %d\n", conta_vocali(s));
printf("Parole: %d\n", conta_parole(s));
capovolgi(s);
printf("Capovolta: %s\n", s);
return 0;
}Scrivi un programma con questi 3 bug di memoria: 1) accesso fuori da array, 2) uso di variabile non inizializzata, 3) memory leak (malloc senza free). Compilalo con -fsanitize=address,undefined e leggi gli output. Poi correggili.
/* buggy.c β DA COMPILARE CON: gcc -g -fsanitize=address,undefined buggy.c -o buggy */
#include <stdio.h>
#include <stdlib.h>
int main() {
// BUG 1: Accesso fuori dall'array
int arr[5] = {1, 2, 3, 4, 5};
// printf("%d\n", arr[10]); // Decommentare per vedere il bug
// BUG 2: Variabile non inizializzata
// int x; printf("%d\n", x); // Comportamento indefinito
// BUG 3: Memory leak
int *p = malloc(100 * sizeof(int));
p[0] = 42;
// free(p); // Manca questo!
/* VERSIONE CORRETTA: */
int arr2[5] = {1, 2, 3, 4, 5};
printf("%d\n", arr2[4]); // Ultimo elemento valido
int y = 0;
printf("%d\n", y); // Inizializzato
int *p2 = malloc(100 * sizeof(int));
p2[0] = 42;
free(p2); // Liberato!
p2 = NULL;
return 0;
}