Capitolo 1: L’Ambiente di Lavoro in Visual
Studio e il Primo Programma in C
Obiettivi del Capitolo
Al termine di questo capitolo, lo studente sarà in grado di:
•Descrivere l'architettura gerarchica di una soluzione in Visual Studio.
•Distinguere i ruoli di Solution, Project e file sorgente.
•Creare e configurare un progetto C puro da zero.
•Scrivere, compilare ed eseguire un primo programma elementare in C.
•Utilizzare i comandi fondamentali del debugger per osservare il flusso di
esecuzione e lo stato delle variabili.
1.1 Struttura dell’Ambiente Visual Studio
Visual Studio è un IDE (Integrated Development Environment), ovvero
un'applicazione che integra tutti gli strumenti necessari per lo sviluppo
software: editor di codice, compilatore, linker, debugger e gestione dei file. Per
utilizzarlo con profitto, è fondamentale comprenderne l'architettura logica e
l'interfaccia utente.
1.1.1 La Gerarchia Solution → Project → Files
Visual Studio organizza il lavoro su tre livelli gerarchici. Immaginatela come una
libreria: la Solution è l'intera libreria, un Project è uno scaffale tematico, e
i File sono i singoli libri.
•Solution (Soluzione): È il contenitore di livello più alto. Può contenere uno o
più progetti. Una soluzione raggruppa tutti gli elementi necessari a sviluppare
un'applicazione completa, che potrebbe essere composta da più moduli (es. un
eseguibile principale, una libreria di funzioni, un progetto di test). I file di una
soluzione hanno estensione .sln.
•Project (Progetto): È un sottocontenitore che rappresenta un singolo modulo
eseguibile (un .exe) o una libreria (.dll o .lib). Un progetto contiene i file
sorgente (.c, .cpp), le impostazioni del compilatore e del linker. I file di progetto
hanno estensione .vcxproj.
•Files (File): Sono i file sorgente (.c, .h) e le risorse (immagini, dati, ecc.) che
compongono il codice del progetto.
Box di Chiarezza: Differenza chiave tra Solution e Project
Un Project produce un singolo output (un programma).
Una Solution è un contenitore che gestisce uno o più progetti
correlati.
Esempio pratico: Se state realizzando un videogioco, avrete un
progetto per il motore grafico (libreria), un progetto per la fisica
(libreria) e un progetto per l'eseguibile finale che le usa. Tutti e tre
risiederanno all'interno di un'unica Solution. Nel nostro corso,
lavoreremo quasi sempre con Solution che contengono un
singolo Progetto.
1.1.2 Layout della GUI: Descrizione di uno screenshot
annotato
All'avvio di Visual Studio e dopo l'apertura o la creazione di un progetto,
l'interfaccia si presenta come nella Figura 1 (descrizione testuale).
Descrizione della figura: Immagine di Visual Studio con quattro aree
principali annotate da riquadri rossi.
[Link] 1 - Solution Explorer (Esplora soluzioni) - a destra (o
sinistra): Una finestra a struttura ad albero. Al vertice c'è l'icona della
soluzione (Solution 'NomeSoluzione' (1 progetto)). Cliccando sulla freccia a
fianco, si espande il nodo del progetto (ad esempio Progetto_C). Sotto il
progetto, vediamo cartelle logiche come Source Files, Header Files, Resource
Files. I nostri file .c andranno in Source Files. Questa è la mappa della nostra
gerarchia.
[Link] 2 - Editor di Codice - al centro: Un'ampia area bianca con righe
numerate. In alto, una linguetta (tab) riporta il nome del file aperto
(es. main.c). Le parole chiave (come int, void, return) sono di colore blu, i
commenti in verde, le costanti letterali in rosso. Questa è la nostra "tela".
[Link] 3 - Error List (Elenco errori) - in basso: Un pannello tabulare. Di
solito contiene quattro schede: Error List, Output, Watch, Call Stack. La Error
List mostra in rosso gli errori di compilazione (con numero di riga e colonna), in
giallo gli avvisi (warning). Un doppio click su un errore porta il cursore
direttamente alla riga incriminata nel codice.
[Link] 4 - Output Window (Finestra di output) - in basso, accanto a
Error List: Mostra i messaggi testuali prodotti dal processo di compilazione e
linking. Qui potete vedere esattamente i comandi inviati al compilatore e il loro
esito (es. 1>main.c, 1>Progetto_C.vcxproj -> C:\...\Debug\Progetto_C.exe).
1.2 Creazione di un Progetto C Puro
Visual Studio è nato per C++, ma supporta il C in modo eccellente, sebbene lo
consideri un sottoinsieme. Per creare un progetto C puro, seguite questa
procedura passo-passo.
1.2.1 Guida Passo-Passo
Passo 1: Avvio e Creazione Nuovo Progetto
•Avviare Visual Studio. Nella finestra di avvio, selezionare "Crea un nuovo
progetto".
•Nella finestra "Crea un nuovo progetto", utilizzare i filtri: linguaggio C++ (non
C, non preoccupatevi), piattaforma Windows, tipo progetto Console. Dalla lista,
selezionare "App console (C++)" o "Console App". Fate attenzione a non
selezionare "Progetto vuoto".
Passo 2: Configurazione del Progetto
•Assegnare un Nome al progetto (es. PrimoProgrammaC).
•Scegliere una Posizione (es. C:\CorsoC\Laboratorio).
•Lasciare il Nome soluzione uguale al nome del progetto (per semplicità).
•Importante: Assicurarsi che l'opzione "Inserisci soluzione e progetto nella
stessa directory" sia DESELEZIONATA (o valutate voi). Cliccare su "Crea".
Passo 3: Aggiunta di un file .c (e rimozione di .cpp)
•Visual Studio avrà creato automaticamente un file [Link]. Non usatelo per
il C. Fate clic con il tasto destro sul nome del progetto (non sulla soluzione)
in Solution Explorer.
•Selezionare Aggiungi -> Nuovo elemento.
•Nella finestra, selezionare File C++ (.cpp).
•Fondamentale: In basso, nel campo Nome, scrivere il nome del file con
l'estensione .c, ad esempio programma.c.
•Cliccare su "Aggiungi". Ora avete un file vuoto con estensione .c. Potete
eliminare il [Link] (tasto destro -> Rimuovi).
Passo 4: Impostazione di Compilazione come C (/TC)
•Questa è l'impostazione cruciale. Fate clic con il tasto destro sul nome del
progetto e selezionare Proprietà.
•Nella finestra delle proprietà, assicuratevi che in alto a sinistra il
campo Configurazione: sia impostato su Tutte le configurazioni.
•Navigate in: Proprietà di configurazione -> C/C++ -> Avanzate.
•Trovate l'opzione "Compila come" (o "Compile As"). Nel menù a tendina,
selezionate "Compila come codice C (/TC)".
•Cliccare su Applica e poi OK.
Box di Spiegazione: Perché /TC?
Visual Studio usa il compilatore C++ ([Link]). In assenza di /TC, il
compilatore interpreta i file .c come C++, applicando regole più
rigide (es. casting obbligatorio, nomi di funzioni "mangled").
L'opzione /TC forza il compilatore a usare lo standard C (ANSI
C89/C99, con limitazioni). Senza questa opzione, potreste scrivere
codice C che compila, ma non è C puro.
Passo 5: Disattivazione del Warning C4996 (opzionale ma consigliata)
•Molte funzioni standard della libreria C (come scanf, strcpy) sono considerate
"deprecate" da Microsoft perché meno sicure (non controllano i limiti dei
buffer). Per usare lo standard C puro senza vedere decine di warning,
disabilitiamo questo specifico avviso.
•Nelle Proprietà del progetto, andare su Proprietà di configurazione -> C/C++ -
> Riga di comando.
•Nel campo Opzioni aggiuntive, scrivere: /wd4996
•Cliccare OK. Ora il compilatore ignorerà il warning C4996.
1.3 Primo Programma in C: "Ciao, Mondo!"
Il programma che segue introduce la struttura minima di un'applicazione in C.
Lo scriveremo nel file programma.c.
// programma.c
// Il mio primo programma in C su Visual Studio
// Includo la libreria standard di Input/Output
// stdio.h contiene le dichiarazioni di printf() e scanf()
#include <stdio.h>
// Punto di ingresso del programma.
// void main(void) indica che la funzione principale non accetta parametri
// e non restituisce alcun valore al sistema operativo.
// In C moderno, si usa preferibilmente 'int main(void)', ma per semplicità
// iniziamo con questa forma valida in molti ambienti (incluso VS).
void main(void)
{
// Dichiarazione di variabili
int numeroIntero = 10; // Un numero intero
float numeroReale = 3.14f; // Un numero a virgola mobile (f indica float)
// Stampa di testo costante
// printf() invia una stringa formattata alla console.
// '\n' è il carattere di newline (a capo)
printf("Benvenuti al laboratorio di Programmazione in C!\n");
// Stampa di variabili intere: %d è il formato per int
printf("Il valore della variabile intera e': %d\n", numeroIntero);
// Stampa di variabili float: %f è il formato per float
// .2 indica di mostrare due cifre decimali
printf("Il valore della variabile float e': %.2f\n", numeroReale);
// Il programma termina. Non c'è un return perché la funzione è void.
}
1.3.1 Spiegazione riga per riga della struttura
[Link] (// e /* ... */) : Il testo dopo // fino a fine riga è un commento,
ignorato dal compilatore. Serve a documentare il codice.
[Link] #include <stdio.h> : Non è un'istruzione C, ma una direttiva
al preprocessore. Dice: "Prima di compilare, prendi l'intero contenuto del
file stdio.h (Standard Input Output) e incollalo qui". stdio.h contiene i prototipi
di printf(), scanf(), ecc.
[Link] di funzione void main(void) :
•void prima di main: specifica il tipo di ritorno della funzione. void significa
"nulla".
•main: nome della funzione. È il punto di ingresso obbligatorio per ogni
programma C. Il sistema operativo chiama main per avviare il programma.
•(void): lista dei parametri. void indica che la funzione non accetta argomenti.
[Link] della funzione ({ ... }) : Le parentesi graffe delimitano il blocco di
istruzioni che vengono eseguite in ordine sequenziale.
[Link] di variabili : int numeroIntero = 10; dichiara una variabile di
tipo int (intero) e la inizializza a 10. float numeroReale = 3.14f; dichiara una
variabile float (virgola mobile).
[Link] di funzione printf(...) : La funzione printf (print formatted) accetta
una stringa di formato (contenente testo normale e specificatori come %d, %f)
e una lista di variabili. Sostituisce gli specificatori con il valore delle variabili e
invia il risultato alla console.
1.4 Debugging in Visual Studio
Scrivere codice è solo metà del lavoro. L'altra metà è trovare e correggere
gli errori (debugging). Visual Studio integra un debugger potente.
1.4.1 Concetti Fondamentali
Il debugger è uno strumento che permette di eseguire il programma paso a
paso, sospendendolo in punti specifici per osservare lo stato della memoria
(valore delle variabili).
Breakpoint (Punto d'interruzione) : Un segnaposto (un pallino rosso) che
dice al debugger: " Fermati qui prima di eseguire questa riga". Si inserisce
cliccando nel margine grigio a sinistra del numero di riga nell'editor di codice.
1.4.2 I Comandi Essenziali (Infografica descritta)
Descrizione della figura: Barra degli strumenti del debugger con quattro
pulsanti evidenziati.
•Pulsante 1 (Icona Play verde, "Avvia debug" o F5): Fa partire il
programma in modalità debug. L'esecuzione procederà normalmente fino al
primo breakpoint o fino alla fine. Da questo momento, l'IDE si "aggancia" al
processo in esecuzione.
•Pulsante 2 (Icona con due frecce che scavalcano un punto, "Step
Over" o F10): Esegue la riga corrente. Se la riga contiene una chiamata a
funzione (es. printf(...)), la eseguisce interamente senza entrare nei suoi
dettagli interni, poi si ferma alla riga successiva.
•Pulsante 3 (Icona con una freccia che entra in un cerchio, "Step Into"
o F11): Simile a F10, ma se la riga corrente è una chiamata a funzione, il
debugger entra all'interno di quella funzione e si ferma alla sua prima riga di
codice. Fondamentale per analizzare funzioni scritte da noi.
•Pulsante 4 (Icona quadrato rosso, "Arresta debug" o
Maiusc+F5): Termina immediatamente la sessione di debug e chiude il
programma.
1.4.3 Utilizzo della Finestra Watch (Controllo)
Mentre si è in modalità debug (programma in pausa su un breakpoint), la
finestra Watch è il vostro miglior amico.
Descrizione della figura: Finestra Watch con due colonne: "Nome" e "Valore".
Nella colonna Nome, lo studente ha digitato "numeroIntero". Nella colonna
Valore, compare "10".
Per aggiungere una variabile:
[Link] il debug, andare su Debug -> Finestre -> Watch -> Watch 1.
[Link] colonna Nome, scrivere il nome esatto di una variabile
(es. numeroIntero).
[Link] debugger mostrerà in tempo reale il valore attuale di quella variabile.
[Link] anche cambiare il valore: fate doppio click sul campo Valore e
modificate il numero. L'esecuzione proseguirà con il nuovo valore (utile per
testare scenari alternativi).
1.5 Istruzioni Visive e Diagrammi di Flusso
1.5.1 Diagramma Mermaid del Ciclo di Vita del Codice
1.5.2 Flusso "Codice → Console" (Descrizione testuale)
Il diagramma mostra un rettangolo principale diviso in tre colonne
verticali: Sviluppatore, IDE/Compilatore, Sistema Operativo.
[Link] Sviluppatore: Un riquadro "Editor di codice" contiene il testo del
programma programma.c. Una freccia esce da questo riquadro ed entra nella
colonna centrale.
[Link] IDE/Compilatore: Un riquadro "Processo di Build (Compila + Link)".
Al suo interno, una freccia da "Compilatore ([Link])" a "Linker ([Link])". Una
freccia esce dalla colonna centrale verso destra.
[Link] Sistema Operativo: Un riquadro "Processo in esecuzione
([Link])". Una freccia doppia collega questo riquadro a un'icona di
una finestra nera (la Console). La freccia verso la console rappresenta printf(),
la freccia verso il programma rappresenta un eventuale input con scanf().
1.5.3 Descrizioni Testuali Dettagliate degli Screenshot
•Screenshot 1 - Creazione progetto: Finestra "Crea un nuovo progetto". A
sinistra, una lista di modelli recenti. Al centro, una barra di ricerca. Sopra la
barra, tre menu a tendina: "Linguaggio" (selezionato C++), "Piattaforma"
(selezionato Windows), "Tipo progetto" (selezionato Console). Il primo risultato,
"App console (C++)", è evidenziato in blu. In basso, i campi "Nome progetto",
"Posizione", "Nome soluzione" sono compilati.
•Screenshot 2 - Impostazioni per C: Finestra "Pagine delle proprietà" del
progetto. A sinistra, l'albero di navigazione espanso su "C/C++" e poi
"Avanzate". A destra, la proprietà "Compila come" è evidenziata con un
riquadro rosso. Il suo valore è "Compila come codice C (/TC)".
•Screenshot 3 - Inserimento breakpoint: Editor di codice centrale con le
prime righe di programma.c. Sul margine grigio sinistro, all'altezza della
riga printf("Benvenuti...");, c'è un cerchio rosso pieno. La riga stessa è
evidenziata da un colore di sfondo rosso chiaro (o bordeaux).
•Screenshot 4 - Uso del Watch: Visual Studio in modalità debug (la barra
degli strumenti è cambiata, con i pulsanti di step di colore arancione). In basso
a destra, è visibile la finestra "Watch 1". Nella colonna "Nome" è stato
digitato numeroIntero, e nella colonna "Valore" appare 10. Accanto, la finestra
"Call Stack" mostra "main()" come unico elemento.
•Screenshot 5 - Avvio del debugger: La barra degli strumenti standard di
Visual Studio. Il pulsante "Avvia debug" (icona Play verde) è evidenziato.
Accanto ad esso, un menu a tendina dice "Debug". A destra, il pulsante
"Release" è selezionato, ma il testo spiega che si deve scegliere "Debug" per
avere tutte le informazioni di debug.
Esercizio di riepilogo del Capitolo 1
[Link] un nuovo progetto C puro chiamato Esercizio_1.
[Link] un programma che dichiari una variabile int età = 20 e una float
altezza = 1.75. Stampatele con printf.
[Link] un breakpoint sulla riga della prima printf.
[Link] il debug con F5. Quando il programma si ferma, usate F10 per
eseguire riga per riga e osservate i valori nella finestra Watch.