Blocchi di Codice in C#

I blocchi di codice sono un concetto fondamentale della programmazione in C# e, in generale, di tutti i linguaggi di programmazione.

In questa lezione, vedremo come utilizzare i blocchi di codice per raggruppare più istruzioni in un'unica istruzione. In particolare, vedremo come utilizzare i blocchi di codice con l'istruzione if.

Blocco di Istruzioni

Nella lezione precedente abbiamo visto che l'istruzione if permette di eseguire un'istruzione soltanto se si verifica una certa condizione.

Riprendiamo l'esempio fatto nella lezione precedente:

Console.WriteLine("Inserisci il voto medio del film:");
int voto = Convert.ToInt32(Console.ReadLine());

/* Convertiamo il voto in stelle */
if (voto == 100)
    Console.WriteLine("Il film ha ottenuto ★★★★★");

Supponiamo, ora, di volere modificare il programma in maniera tale da scrivere anche il messaggio Punteggio Perfetto! se il voto è uguale a 100.

A prima vista potremmo pensare di poter scrivere il programma in questo modo:

Console.WriteLine("Inserisci il voto medio del film:");
int voto = Convert.ToInt32(Console.ReadLine());

/* Convertiamo il voto in stelle */
if (voto == 100)
    Console.WriteLine("Il film ha ottenuto ★★★★★");
    Console.WriteLine("Punteggio Perfetto!"); /* ERRORE */

Tuttavia, questo codice non funziona nel modo in cui ci aspettiamo. Se proviamo ad eseguire il programma, vedremo che il messaggio Punteggio Perfetto! viene stampato a prescindere dal valore del voto.

Questo accade perché l'istruzione if considera soltanto la prima istruzione che segue il blocco di codice. Se vogliamo che più di un'istruzione venga eseguita in caso la condizione sia vera, dobbiamo introdurre un nuovo concetto: il blocco di istruzioni.

Un blocco di istruzioni permette di raggruppare più istruzioni in un'unica istruzione. La sintassi per realizzare un blocco è la seguente:

{
    istruzione1;
    istruzione2;
    istruzione3;
}

Quindi, possiamo raggruppare le due istruzioni di sopra in una sola istruzione:

{
    Console.WriteLine("Il film ha ottenuto ★★★★★");
    Console.WriteLine("Punteggio Perfetto!");
}

E applicare l'istruzione if al blocco appena creato come se si trattasse di un'unica istruzione:

Console.WriteLine("Inserisci il voto medio del film:");
int voto = Convert.ToInt32(Console.ReadLine());

/* Convertiamo il voto in stelle */
if (voto == 100)
{
    Console.WriteLine("Il film ha ottenuto ★★★★★");
    Console.WriteLine("Punteggio Perfetto!");
}
Definizione

Blocchi di Istruzioni in C#

Un Blocco di Istruzioni, chiamato anche blocco di codice, è un insieme di istruzioni racchiuse tra parentesi graffe {}.

Il linguaggio considera un blocco di istruzioni come se fosse un'unica istruzione. Pertanto possiamo raggruppare più istruzioni laddove la sintassi del linguaggio ne preveda soltanto una.

La sintassi è la seguente:

{
    istruzione1;
    istruzione2;
    istruzione3;
}

I blocchi di istruzione non sono utilizzati soltanto con l'istruzione if, ma possono essere combinati con le istruzioni di ciclo e con i metodi come vedremo nelle prossime lezioni.

L'utilizzo dei blocchi congiunto con l'istruzione if è molto più comune rispetto all'utilizzo singolo di un'istruzione. Infatti, per motivi di leggibilità del codice, la maggior parte dei programmatori preferisce usare i blocchi anche quando l'istruzione annessa alla condizione è una sola. Per cui, si preferisce scrivere:

if (voto == 100)
{
    Console.WriteLine("Il film ha ottenuto ★★★★★");
}

Anziché:

if (voto == 100)
    Console.WriteLine("Il film ha ottenuto ★★★★★");

In questo modo, il codice risulta più chiaro e leggibile.

Nota

Utilizzare i Blocchi di Istruzioni con l'istruzione if

Il consiglio che diamo è di utilizzare sempre i blocchi di istruzioni con l'istruzione if, anche quando l'istruzione annessa alla condizione è una sola.

In questo modo si hanno due benefici:

  1. Il codice risulta più chiaro e leggibile.
  2. Si evitano errori di programmazione, come nel caso in cui si dimentichi di inserire il blocco e si scriva più di un'istruzione.
if (condizione)
{
    istruzione;
}

L'unico caso in cui conviene evitare il blocco di istruzioni per il caso a singola istruzione è quando quest'ultima è talmente breve da poter essere scritta su una sola riga.

Ad esempio, potrebbe convenire scrivere:

if (condizione) istruzione_corta;

Blocchi e visibilità delle variabili

Un importante concetto associato ai blocchi di istruzioni è la visibilità delle variabili, chiamato anche, in inglese, scope.

In questa lezione introduciamo questo concetto ma, data la sua importanza, lo approfondiremo in lezioni successive.

All'interno di un blocco di istruzioni, infatti, possiamo dichiarare delle variabili. Queste ultime, tuttavia, sono visibili esclusivamente all'interno del blocco in cui sono state dichiarate.

Ad esempio:

string input = Console.ReadLine();
int voto = Convert.ToInt32(input);

if (voto == 100)
{
    string messaggio = "Il film ha ottenuto ★★★★★";
    Console.WriteLine(messaggio);
}

Console.WriteLine(messaggio); /* ERRORE */

Nel codice di sopra, la variabile messaggio è dichiarata all'interno del blocco di istruzioni dell'istruzione if. Quando usciamo dal blocco, la variabile messaggio non è più visibile, in particolare essa non esiste più. Per cui, se proviamo a stampare il valore della variabile messaggio al di fuori del blocco, otterremo un errore di compilazione.

Da questo concetto possiamo ricavare un importante conseguenza: le variabili hanno un tempo di vita. Finora, non abbiamo mai dovuto preoccuparci di questo aspetto, poiché le variabili che abbiamo dichiarato sono sempre state visibili all'interno del metodo Main.

Nel codice di sopra, infatti, le variabili input e voto sono dichiarate a livello di programma e, pertanto, esse esistono per tutto il tempo di esecuzione del programma. Quindi le possiamo utilizzare all'interno del nostro blocco. Avremmo potuto, ad esempio, scrivere il seguente codice:

string input = Console.ReadLine();
int voto = Convert.ToInt32(input);

if (voto == 100)
{
    string messaggio = "Il film ha ottenuto ★★★★★";
    Console.WriteLine(messaggio);
    Console.WriteLine(voto);
}

In questo caso, la variabile voto è visibile all'interno del blocco, per cui può essere usata.

Se, invece, avessimo voluto usare la variabile messaggio al di fuori del blocco, avremmo dovuto dichiararla a livello di programma:

string input = Console.ReadLine();
int voto = Convert.ToInt32(input);
string messaggio = "";

if (voto == 100)
{
    messaggio = "Il film ha ottenuto ★★★★★";
    Console.WriteLine(messaggio);
}

Console.WriteLine(messaggio);

In questo modo, la variabile messaggio è visibile all'interno del blocco e al di fuori di esso.

Ricapitolando:

Definizione

Visibilità delle Variabili

La Visibilità delle Variabili, chiamata anche scope, indica il contesto in cui una variabile è accessibile.

Le variabili dichiarate all'interno di un blocco di istruzioni sono visibili soltanto all'interno di quel blocco e di quelli annidati al suo interno. Al di fuori del blocco, la variabile non è più visibile e, pertanto, non può essere utilizzata.

Inoltre, quando si esce da un blocco, le variabili dichiarate al suo interno vengono distrutte e non esistono più.

Il fatto che una variabile sia visibile soltanto all'interno di un blocco può essere sfruttato per riutilizzare lo stesso nome di variabile in blocchi diversi.

Ad esempio:

string input = Console.ReadLine();
int voto = Convert.ToInt32(input);

if (voto == 100)
{
    string messaggio = "Il film ha ottenuto ★★★★★";
    Console.WriteLine(messaggio);
}

if (voto == 0)
{
    string messaggio = "Il film ha ottenuto ☆☆☆☆☆";
    Console.WriteLine(messaggio);
}

In questo caso, le variabili messaggio dichiarate nei due blocchi sono indipendenti l'una dall'altra. Anche se hanno lo stesso nome, esse sono due variabili diverse e non interferiscono l'una con l'altra.

In generale, però, è buona pratica evitare di riutilizzare lo stesso nome di variabile in blocchi diversi, poiché ciò può portare a confusione e a errori di programmazione.

Oscuramento delle Variabili

Una conseguenza del concetto di visibilità delle variabili è l'oscuramento o, in inglese, shadowing.

L'oscuramento delle variabili avviene quando una variabile dichiarata all'interno di un blocco ha lo stesso nome di una variabile dichiarata al di fuori del blocco. In questo caso, la variabile dichiarata all'interno del blocco oscura la variabile dichiarata al di fuori del blocco stesso.

Prendiamo un esempio:

int x = 10;
int y = Convert.ToInt32(Console.ReadLine());

if (y == 100)
{
    int x = 20;
    Console.WriteLine(x);
}

Console.WriteLine(x);

In questo caso, la variabile x dichiarata all'interno del blocco oscura la variabile x più esterna. Pertanto, quando stampiamo il valore di x all'interno del blocco, otterremo 20, mentre quando stampiamo il valore di x al di fuori del blocco, otterremo 10.

L'oscuramento delle variabili è una pratica da evitare, poiché può portare a confusione e a errori di programmazione. Per evitare l'oscuramento delle variabili, è buona pratica evitare di dare lo stesso nome a variabili diverse.

Definizione

Oscuramento delle Variabili

L'Oscuramento delle Variabili, chiamato anche shadowing, avviene quando una variabile dichiarata all'interno di un blocco ha lo stesso nome di una variabile di livello superiore.

In questo caso, la variabile dichiarata all'interno del blocco oscura la variabile dichiarata al di fuori del blocco, impedendo l'accesso a quest'ultima.

In Sintesi

In questa lezione abbiamo introdotto un altro tassello fondamentale della programmazione in C#: i blocchi di istruzioni.

Abbiamo deciso di introdurre a questo punto della guida questo concetto perché è strettamente legato all'istruzione if e, in generale, alle istruzioni di controllo e di ciclo. Infatti utilizzeremo i blocchi di codice anche più avanti.

In particolare, abbiamo visto che:

  • Un blocco di istruzioni è un insieme di istruzioni racchiuse tra parentesi graffe {}.
  • I blocchi di istruzioni permettono di raggruppare più istruzioni in un'unica istruzione.
  • I blocchi di istruzioni sono utilizzati con l'istruzione if per eseguire più di un'istruzione in caso la condizione sia vera.
  • Le variabili dichiarate all'interno di un blocco di istruzioni sono visibili soltanto all'interno di quel blocco e di quelli annidati al suo interno.
  • L'oscuramento delle variabili avviene quando una variabile dichiarata all'interno di un blocco ha lo stesso nome di una variabile dichiarata al di fuori del blocco.

Nella prossima lezione studieremo un'altro importante concetto riguardante le istruzioni condizionali: l'istruzione else.