Strutture condizionali

Le strutture condizionali, anche dette strutture di controllo “alternative”,  consentono di specificare che un dato blocco di istruzioni venga eseguito “(solo) se” vale una certa condizione. Le principali e più utilizzate strutture condizionali sono:

  • Struttura if-then e if-then-else
  • Struttura alternative case

Queste due strutture sono sostanzialmente molto simili. La struttura if-then (se-allora) può essere parafrasata con la frase “se vale la condizione C, allora esegui il blocco di istruzioni I“. Il controllo della condizione avviene, naturalmente, prima dell’esecuzione del blocco di istruzioni. La maggior parte dei linguaggi di programmazione ammette anche la struttura if-then-else che consiste in una catena di strutture if-then controllati in sequenza. Può essere parafrasata con la frase “se vale la condizione C esegui il blocco di istruzioni I1, altrimenti esegui il blocco di istruzioni I2“. Questa struttura può ulteriormente essere complicata aggiungendo, nel blocco else un ulteriore struttura if-then-else, permettendo quindi di controllare più condizioni in sequenza.

L’alternative case può essere visto come una catena di if-then-else con certe restrizioni. In sostanza si tratta di una struttura if-then dove il blocco di istruzioni eseguito si basa sul valore di una determinata variabile o espressione (che normalmente assume valore intero). Può essere parafrasata con la frase “valuta l’espressione N: se il suo valore è V1 esegui il blocco di istruzioni I1; altrimenti se il suo valore è V2 esegui il blocco di istruzioni I2; …” e così via con quante condizione sono necessarie.

Queste due strutture sono entrambe supportate in C# e VB.net. In entrambi i linguaggi seguono la stessa struttura, con le differenze sintattiche tipiche dei due linguaggi. Di seguito sono riportati gli esempi del codice con cui queste strutture sono scritte nei due linguaggi.

VB.net

La struttura if-then-else in VB.net è codificata come segue:

If condition [ Then ]

    [ statements ]

[ Else

    [ elsestatements ] ]

End If

Inoltre, in VB.net è molto semplice (e immediato) l’utilizzo di una struttura if-then-elseif-then che permette di annidiare più condizioni if insieme, interrompendo il loro controllo alla prima condizione vera trovata. Viene codificata con la seguente sintassi:

If condition [ Then ]

    [ statements ]

[ ElseIf elseifcondition [ Then ]

    [ elseifstatements ] ]

[ Else

    [ elsestatements ] ]

End If

Naturalmente è possibile concatenare più elseif insieme.

La struttura alternative case invece segue la seguente sintassi:

Select [ Case ] testexpression  

    [ Case expressionlist  

        [ statements ] ]

    [ Case expressionlist  

        [ statements ] ]   

    [ Case Else  

        [ elsestatements ] ]  

End Select

C#

La struttura if-then-else in C# è codificata come segue:

if (condition)
{
    [ statements ];
}
else
{
    [ statements ];
}

Anche in questo caso è possibile concatenare abbastanza agilmente più condizioni if-else, anche se C# non ha una struttura dedicata appositamente a questo.

if (condition)
{
    [ statements ];
}
else
{
    if (condition)
    {
        [ statements ];
    }
    else
    {
        [ statements ];
    }
}

L’alternative case invece viene codificato come segue:

switch (caseSwitch)
      {
          case 1:
              [ statements ];
              break;
          case 2:
              [ statements ];
              break;
          default:
              [ statements ];
              break;
      }

Strutture Do, While in VB.net e C#

In programmazione, esistono diversi tipi di strutture di controllo iterative che consentono di specificare che una data istruzione (o blocco di istruzioni) deve essere eseguita ripetutamente sotto delle condizioni che, se false, ne consentono l’uscita. Le principali strutture di controllo iterative sono:

  • Ciclo for
  • Ciclo while
  • Ciclo loop-until

Il ciclo while, in particolare, può presentarsi con due strutture diverse: do-while e while-do. Nonostante sembrino molto simili, queste due strutture hanno una differenza importantissima. Il primo, infatti, garantisce l’esecuzione di una iterazione poiché il controllo per la permanenza nella parte iterativa avviene solo dopo l’esecuzione del blocco di comandi. La seconda struttura, di contro, prima di eseguire iterativamente il blocco di comandi, controlla che siano rispettate le condizioni di continuazione del ciclo, implicando quindi che il blocco di comandi potrebbe non essere eseguito neanche una volta.

In generale, la struttura while-do è indicata quando la condizione di permanenza in un ciclo è una generica condizione booleana, indipendente dal numero di iterazioni eseguite. Le forme tradizionali di ciclo while possono essere parafrasate come “ripeti (il codice controllato) fintantoché resta vera la condizione C“. Questa condizione, come precedentemente detto, viene controllata prima di eseguire la prima iterazione del ciclo stesso; se essa risulta immediatamente falsa, le istruzioni nel ciclo non vengono eseguite.

In C# e VB.net i cicli while presentano codifiche diverse, ma i comandi rappresentano le stesse funzioni. Di seguito sono riportati i codici nei due linguaggi per i cicli while

VB.net

Il do-while in VB.net può essere codificato in due modi diversi, ma equivalenti.

Do { While | Until } condition  
    [ statements ]  
    [ Continue Do ]  
    [ statements ]  
    [ Exit Do ]  
    [ statements ]  
Loop  
' -or-  
Do  
    [ statements ]  
    [ Continue Do ]  
    [ statements ]  
    [ Exit Do ]  
    [ statements ]  
Loop { While | Until } condition

Alternativamente, è possibile utilizzare la struttura while-do:

While condition  
    [ statements ]  
    [ Continue While ]  
    [ statements ]  
    [ Exit While ]  
    [ statements ]  
End While 

C#

Anche in C# è possibile utilizzare sia la struttura do-while, sia la struttura while-do. La struttura do-while può essere scritta come segue:

do 
{
    [ statements];
} while (condition);

Mentre la struttura do-while presenta la seguente struttura:

while (condition) 
{
    [ statements];
}

Reference type e value type

In Visual Basic vengono trattati solo due diversi types: i reference type e i value type. La principale (e fondamentale) differenza consiste nel fatto che i value type allocano una porzione di memoria direttamente riempita con il valore d’interesse, mentre i reference type contengono contengono un puntatore ad un oggetto (e quindi al relativo valore). Questa differenza è fondamentale, in quanto stravolge completamente il funzionamento dei due types. Ad esempio, infatti, quando si copia il valore di una variabile in una seconda è fondamentale conoscere il type della prima. Nel caso si trattasse di un value type, nella seconda variabile verrà copiato direttamente il valore contenuto nella prima e le due variabili lavoreranno indipendentemente. I reference type, invece, se copiati in una seconda variabile, creano una seconda copia del puntatore allo stesso oggetto. Questo implica che una modifica al valore di una delle due variabili comporta una variazione all’oggetto identificato dal puntatore e quindi qualsiasi variabile conterrà il puntatore a quell’oggetto vedrà il valore di quest’ultimo modificato.

Alcuni esempi di value type sono i seguenti:

  • Tutti i tipi di dati numerici
  • BooleanCharDate
  • Tutte le strutture, anche se i relativi membri sono reference type

Alcuni esempi di reference type sono i seguenti:

  • String
  • Tutte le matrici, anche se i relativi elementi sono value type
  • Tipi di classe, ad esempio Form
  • Delegati

Per quanto riguarda la definizione di questi due type in C# e VB.net, in entrambi i linguaggi, i reference type sono dichiarati attraverso l’istruzione Class, mentre i value type vengono dichiarati attraverso l’istruzione Structure. Di seguito sono riportati i codici di esempio per dichiarare i due type descritti finora nei due linguaggi:

VB.net

C#

Reference Type

Public Class Studente_C 
       Public Eta As Double
       Public Peso As Double
End Class
class Studente_C
{
      public double Eta;
      public double Peso;
}

Value Type

Public Structure Studente_S 
       Public Eta As Double
       Public Peso As Double
End Structure
struct Studente_S
{
      public double Eta;
      public double Peso;
}

Come si può notare, la sintassi è molto simile. L’unica differenza è sulla compattezza del codice, che però rimane una differenza che caratterizza i due codici nel complesso.

Visual Studio e altre piattaforme di sviluppo

Microsoft Visual Studio (più comunemente detto Visual Studio) è un ambiente di sviluppo integrato (IDE) sviluppato da Microsoft. Un IDE è un software che supporta i programmatori il fase di sviluppo del codice, segnalando errori di sintassi direttamente in fase di scrittura, oltre a tutta una serie di strumenti e funzionalità di supporto alla fase di sviluppo e debugging.

Nonostante generalmente gli IDE siano rivolti ad uno specifico linguaggio di programmazione, alcuni degli IDE in uso sono multilinguaggio, tra cui Eclipse e lo stesso Visual Studio. Normalmente è composto da più componenti, da cui appunto il nome integrato:

  • un editor di codice sorgente;
  • un compilatore e/o un interprete;
  • un tool di building automatico;
  • (solitamente) un debugger.

Un editor di testo serve per facilitare la scrittura di un testo. Spesso sono integrati dal suggerimento della sintassi e aiutano anche nel debug. In Visual Studio l’editor inserisce alcuni comandi automaticamente (come la chiusura di un ciclo o della creazione di una classe).

Il compilatore è un programma che traduce una serie di istruzioni scritte in un determinato linguaggio di programmazione (codice sorgente) in istruzioni di un altro linguaggio (codice oggetto). L’interprete, invece, è un programma che riesce ad eseguire altri programmi a partire direttamente dal relativo codice sorgente, scritto in un linguaggio di alto livello (come VB.net e C# , senza la previa compilazione dello stesso (codice oggetto), eseguendo cioè le istruzioni nel linguaggio usato traducendole di volta in volta in istruzioni in linguaggio macchina del processore.

Infine il debugger è un programma specificatamente progettato per l’analisi e l’eliminazione dei bug, ovvero errori di programmazione interni al codice. Il suo compito principale è quello di mostrare il frammento di codice macchina che genera il problema.

Visual Studio comprende tutti gli elementi finora descritti e supporta diversi linguaggi di programmazione tra cui C#, VB.net e C++. In questo blog verranno scritti diversi programmi utilizzando i primi due linguaggi elencati.

Inoltre Visual Studio fornisce nella sua interfaccia grafica anche di una casella degli strumenti, da cui è possibile selezionare e trascinare i vari controlli direttamente nel form del programma che si sta progettando, integrandolo con la possibilità di modificare velocemente, attraverso un’apposita finestra, le caratteristiche grafiche dei vari controlli introdotti.

Primo Homework

Quiz Matematico

Il primo programma è una sorta di piccolo quiz matematico. Qui è presentato scritto sia in C# che in VB.NET. È possibile scaricare i file del codice dei due esercizi nei link presenti dopo i riquadri contenenti il codice.

Soluzione in C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HW1C
{
    public partial class Form1 : Form
    {
        // Creo oggetto chiamato randomizer che è un oggetto Random.
        Random randomizer = new Random();
        // Aggiungo variabili per il problema di somma.
        int addend1;
        int addend2;

        // Aggiungo variabili per il problema di differenza, prodotto e div.
        int sub1;
        int sub2;

        int prod1;
        int prod2;

        int div1;
        int div2;

        // Aggiungo una variabile per il timer
        int timeLeft;

        // Aggiungo il metodo StartTheQuiz() che usa il metodo Next().
        // Inizio il problema riempiendo le caselle e iniziando il timer.

        public void StartTheQuiz()
        {
            // Metto due numeri randomici nei due addendi.
            // Il valore tra parentesi è il valore massimo (non compreso).
            addend1 = randomizer.Next(51);
            addend2 = randomizer.Next(51);

            // Converto i due numeri in stringhe per mostrarli
            // nel label controls.
            plusLeftLabel.Text = addend1.ToString();
            plusRightLabel.Text = addend2.ToString();

            // Imposto il valore del controllo "sum" a 0.
            sum.Value = 0;

            // Stessa cosa per il problema della sottrazione, prod e div.
            sub1 = randomizer.Next(1, 101);
            sub2 = randomizer.Next(1, sub1);

            minusLeftLabel.Text = sub1.ToString();
            minusRightLabel.Text = sub2.ToString();

            difference.Value = 0;

            prod1 = randomizer.Next(2, 11);
            prod2 = randomizer.Next(2, 11);
            
            timesLeftLabel.Text = prod1.ToString();
            timesRightLabel.Text = prod2.ToString();
            
            prod.Value = 0;

            int temp = randomizer.Next(2,11);
            div2 = randomizer.Next(2,11);
            div1 = div2 * temp;
            
            diviedLeftLabel.Text = div1.ToString();
            diviedRightLabel.Text = div2.ToString();

            quoz.Value = 0;
            
            // Inizio il timer.
            timeLeft = 30;
            timeLabel.Text = "30 secondi";
            timer1.Start();
        }

        private bool CheckTheAnswer()
        {
            if ((addend1 + addend2 == sum.Value) 
                && (sub1-sub2 == difference.Value)
                && (prod1*prod2 == prod.Value)
                && (div1/div2 == quoz.Value))
                return true;
            else
                return false;
        }

        private void answer_Enter(object sender, EventArgs e)
        {
            // Select the whole answer in the NumericUpDown control.
            NumericUpDown answerBox = sender as NumericUpDown;

            if (answerBox != null)
            {
                int lengthOfAnswer = answerBox.Value.ToString().Length;
                answerBox.Select(0, lengthOfAnswer);
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void plusLeftLabel_Click(object sender, EventArgs e)
        {

        }

        private void label8_Click(object sender, EventArgs e)
        {

        }

        private void label12_Click(object sender, EventArgs e)
        {

        }

        private void startButton_Click(object sender, EventArgs e)
        {
            StartTheQuiz();
            startButton.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (CheckTheAnswer())
            {
                timer1.Stop();
                MessageBox.Show("Hai risposto bene a tutto!", "Complimenti!");
                startButton.Enabled = true;

            }
            if (timeLeft > 0)
            {
                // Cambio il nuovo tempo rimanente
                timeLeft = timeLeft - 1;
                timeLabel.Text = timeLeft + " secondi";
                if (timeLeft <= 5)
                {
                    timeLabel.BackColor = Color.Red;
                }
            }
            else
            {
                // Se il tempo finisce blocco tutto
                timer1.Stop();
                timeLabel.Text = "Tempo finito!";
                MessageBox.Show("Non hai terminato in tempo.", "Puoi riporvare però!");
                sum.Value = addend1 + addend2;
                difference.Value = sub1 - sub2;
                prod.Value = prod1 * prod2;
                quoz.Value = div1 / div2;
                startButton.Enabled = true;
            }
        }
    }
}

Link per scaricare il programma in C#.

Soluzione in VB.NET

Public Class Form1
    ' Creo un oggetto Random.
    Private randomizer As New Random

    ' Creo variabili di addizione.
    Private sum1 As Integer
    Private sum2 As Integer

    ' Creo variabili per sottrazione, prodotto e quoz
    Private min1 As Integer
    Private min2 As Integer

    Private prod1 As Integer
    Private prod2 As Integer

    Private quoz1 As Integer
    Private quoz2 As Integer

    ' Aggiungo una variabile per il timer
    Private timeLeft As Integer



    ' Aggiungo il metodo StartTheQuiz() che usa il metodo Next().
    ' Inizio il problema riempiendo le caselle e iniziando il timer.

    Public Sub StartTheQuiz()
        ' Metto due numeri randomici nei due addendi.
        sum1 = randomizer.Next(51)
        sum2 = randomizer.Next(51)

        'Metto due numeri randomici anche per sottrazione, prod e div
        min1 = randomizer.Next(1, 100)
        min2 = randomizer.Next(1, min1)

        prod1 = randomizer.Next(1, 11)
        prod2 = randomizer.Next(1, 11)

        quoz2 = randomizer.Next(1, 11)
        Dim temp As Integer = randomizer.Next(1, 11)
        quoz1 = quoz2 * temp

        plusLeftLabel.Text = sum1.ToString()
        plusRightLabel.Text = sum2.ToString()

        minusLeftLabel.Text = min1.ToString()
        minusRightLabel.Text = min2.ToString()

        prodLeftLabel.Text = prod1.ToString
        prodRightLabel.Text = prod2.ToString

        quozLeftLabel.Text = quoz1.ToString
        quozRightLabel.Text = quoz2.ToString


        sum.Value = 0
        dif.Value = 0
        prod.Value = 0
        quoz.Value = 0

        ' Inizio il timer
        timeLeft = 30
        timeLabel.Text = "30 seconds"
        Timer1.Start()

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Label5_Click(sender As Object, e As EventArgs) Handles Label5.Click

    End Sub

    Private Sub startButton_Click() Handles startButton.Click
        StartTheQuiz()
        startButton.Enabled = False
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        If CheckTheAnswer() Then
            Timer1.Stop()
            MessageBox.Show("Hai risposto bene a tutto!", "Complimenti!")
            startButton.Enabled = True
        ElseIf timeLeft > 0 Then
            timeLeft -= 1
            timeLabel.Text = timeLeft & " secondi"
            If timeLeft <= 5 Then
                timeLabel.BackColor = Color.Red
            Else
                timeLabel.BackColor = Color.White
            End If
        Else
            ' Se il tempo finisce blocco tutto
            Timer1.Stop()
            timeLabel.Text = "Tempo finito!"
            MessageBox.Show("Non hai terminato in tempo.", "Puoi riporvare però!")
            sum.Value = sum1 + sum2
            dif.Value = min1 - min2
            prod.Value = prod1 * prod2
            quoz.Value = quoz1 / quoz2
            startButton.Enabled = True
        End If
    End Sub
    Public Function CheckTheAnswer() As Boolean

        If sum1 + sum2 = sum.Value AndAlso
            min1 - min2 = dif.Value AndAlso
            prod1 * prod2 = prod.Value AndAlso
            quoz1 / quoz2 = quoz.Value Then
            Return True
        Else
            Return False
        End If
    End Function

    Private Sub answer_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles sum.Enter, prod.Enter, dif.Enter, quoz.Enter

        Dim answerBox = TryCast(sender, NumericUpDown)

        If answerBox IsNot Nothing Then
            Dim lengthOfAnswer = answerBox.Value.ToString().Length
            answerBox.Select(0, lengthOfAnswer)
        End If

    End Sub
End Class

Link per scaricare il programma in VB.NET.

Principali differenze tra C# e VB.NET

Un linguaggio di programmazione è un linguaggio formale che specifica un insieme di istruzioni che possono essere usate per produrre dati in output. Di solito si utilizza per il controllo del comportamento di una macchina.

Esistono moltissimi linguaggi di programmazione, ognuno differente dall’altro, che possono essere suddivisi in diverse categorie di linguaggi:

  • imperativi: propongono comandi per la manipolazione del contenuto della memoria e le operazioni da eseguire in modo arbitrario. Ogni elemento presente lascia traccia nella memoria centrale;
  • funzionali: danno dei comandi che calcolano risultati partendo dai dati di ingresso e non consentono che le funzioni modifichino la memoria del computer;
  • dichiarativi: descrivono oggetti informatici come la struttura di un database e la sequenza delle loro dichiarazioni non è relazionata al tempo;
  • procedurali: permettono di generare operazioni di alto livello scomponendole in procedure o funzioni;
  • logici: consentono di ideare sistemi matematici logici;
  • orientati agli oggetti: semplificano le realizzazione di schemi predefiniti tramite i quali le problematiche standard della programmazione trovano soluzioni standardizzate.

Un’ulteriore suddivisione va fatta tra linguaggio interpretato, compilato o JIT. Nel primo caso il sorgente viene direttamente interpretato da un software. Nel secondo caso un software compilatore legge il sorgente e lo rende eseguibile. Nel terzo caso, invece, il linguaggio è compilato in modo tale da poter essere eseguito da una macchina virtuale.

Nel nostro caso consideriamo i linguaggi C# e VB.NET. Sono entrambi linguaggi orientati agli oggetti ed entrambi compilati (anche se in verità C# è un ibrido tra compilato e JIT, poiché viene compilato in run time a seconda della macchina dove viene eseguito). Sono due tra i molti linguaggi disponibili per la piattaforma .NET.

Oltre ad una differenza nelle possibilità di programmazione che offrono i due linguaggi, differiscono anche per la sintassi utilizzata:

  • VB.NET risulta essere più lungo rispetto all’equivalente in C#;
  • C# è case sensitive, mentre VB.NET no;
  • in C# ogni istruzione deve terminare con “;” per poter essere eseguita, cosa non necessaria in VB.NET;
  • in C# si usano le parentesi graffe per delimitare i blocchi di codice, mentre in VB.NET si termina  un blocco con la dichiarazione End;
  • in C# è necessario inizializzare le variabili, mentre VB.NET le inizializza direttamente in fase di dichiarazione.

Un esempio nella differenza tra i due linguaggi la sua apprezzare nei due seguenti codice. Entrambi servono per la costruzione del famoso programma “Hello World!”, il primo però utilizza il linguaggio C#, mentre il secondo VB.NET.

Il codice in C# risulta essere:

  using System.Windows.Forms;

  class HelloWorldApp
  {
    public static void Main()
    {
      MessageBox.Show("Hello World");
    }
  }

Mentre quello in VB.NET è:

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click

   MessageBox.Show("Hello, world!", "Titolo esempio", MessageBoxButtons.OK, MessageBoxIcon.Information)

End Sub

Entrambi i programmi servono per stampare il testo “Hello world!” in una Message Box

Anche i tipi di variabili, e il loro codice, differiscono a seconda del linguaggio utilizzato.

In C# esistono due generi di tipi: tipi valore e tipi riferimento. Le variabili dei tipi valore contengono direttamente i propri dati, mentre le variabili dei tipi riferimento archiviano i riferimenti ai propri dati, noti come oggetti.

I tipi valore di C# sono ulteriormente suddivisi in tipi semplici, tipi enum, tipi struct e tipi valore nullable. I tipi riferimento di C# sono ulteriormente suddivisi in tipi classe, tipi interfaccia, tipi matrice e tipi delegato.

  • Tipi valore
    • Tipi semplici
      • Signed Integer: sbyteshortint,long
      • Unsigned Integer: byteushortuint,ulong
      • Caratteri Unicode: char
      • File binario IEEE a virgola mobile: floatdouble
      • Decimale ad alta precisione a virgola mobile: decimal
      • Booleano: bool
    • Tipi enum
      • Tipi definiti dall’utente nel formato enum E {...}
    • Tipi struct
      • Tipi definiti dall’utente nel formato struct S {...}
    • Tipi valore nullable
      • Estensioni di tutti gli altri tipi valore con un valore null
  • Tipi riferimento
    • Tipi classe
      • Classe di base principale di tutti gli altri tipi: object
      • Stringhe Unicode: string
      • Tipi definiti dall’utente nel formato class C {...}
    • Tipi interfaccia
      • Tipi definiti dall’utente nel formato interface I {...}
    • Tipi di matrice
      • Unidimensionale e multidimensionale, ad esempio int[] e int[,]
    • Tipi delegato
      • Tipi definiti dall’utente nel formato delegate int D(...)

Le variabili in VB.NET sono sostanzialmente le stesse, ma differiscono per la sintassi utilizzata nella definizione della variabile. Ad esempio in VB.NET si ha  Doubleinvece di double, Integerinvece di intSingle invece di float e Boolean invece di bool.

Un’altra importante differenza riguarda gli operatori nei due linguaggi. Infatti la sintassi è diversa, sopratutto per quanto riguarda gli operatori logici. Per semplicità, il confronto è riportato nella tabella qui sotto:

OperatoreVB.NETC#
Operatori Aritmetici
Addizione++
Sottrazione
Moltiplicazione**
Divisione/ (divisione decimale)
\ (divisione intera)
/
ModuloMod%
Potenza^Funzione
Math.pow
Incremento= ++ +
Decremento= –– –
Operatori Logici
andAnd&&
orOr||
notNot!