Skip to content

2. Noções básicas da linguagem VB.NET

2.1. Introdução

Começaremos por abordar o VB.NET como uma linguagem de programação tradicional. Abordaremos os objetos mais tarde.

Num programa, existem duas coisas

  • dados
  • as instruções que os manipulam

Geralmente, procuramos separar os dados das instruções:

2.2. Dados VB.NET

O VB.NET utiliza os seguintes tipos de dados:

  1. inteiros, reais e decimais
  1. caracteres e cadeias de caracteres
  2. booleanos
  3. datas
  4. objetos

2.2.1. Tipos de dados predefinidos

Tipo VB
Tipo .NET equivalente
Tamanho
Intervalo de valores
Booleano
System.Boolean
2 bytes
Verdadeiro ou Falso.
Byte
System.Byte
1 byte
0 a 255 (sem sinal).
Char
System.Char
2 bytes
0 a 65 535 (sem sinal).
Date
System.DateTime
8 bytes
0:00:00 em 1 de janeiro de 0001 a 23:59:59 em 31 de dezembro de 9999.
Decimal
System.Decimal
16 bytes
0 a +/-79.228.162.514.264.337.593.543.950.335 sem casas decimais; 0 a +/-7,9228162514264337593543950335 com 28 casas decimais; sendo o menor número diferente de zero +/-0,0000000000000000000000000001 (+/-1E-28).
Double
System.Double
8 bytes
-1,79769313486231E+308 a
-4,94065645841247E-324 para valores negativos; 4,94065645841247E-324 a 1,79769313486231E+308 para valores positivos.
Inteiro
System.Int32
4 bytes
-2.147.483.648 a 2.147.483.647.
Long
System.Int64
8 bytes
-9.223.372.036.854.775.808 a 9.223.372.036.854.775.807.
Object
System.Object
4 bytes
Qualquer tipo pode ser armazenado numa variável do tipo Object.
Short
System.Int16
2 bytes
-32 768 a 32 767.
Single
System.Single
4 bytes
-3,402823E+38 a -1,401298E-45 para valores negativos; 1,401298E-45 a 3,402823E+38 para valores positivos.
String
System.String (classe)
 
0 a aproximadamente 2 mil milhões de caracteres Unicode.

Na tabela acima, vemos que existem dois tipos possíveis para um inteiro de 32 bits: Integer e System.Int32. Os dois tipos são intercambiáveis. O mesmo se aplica a outros tipos VB e aos seus equivalentes na plataforma .NET. Aqui está um programa de exemplo:


Module types
    Sub Main()
        ' whole numbers
        Dim var1 As Integer = 100
        Dim var2 As Long = 10000000000L
        Dim var3 As Byte = 100
        Dim var4 As Short = 4
        ' real numbers
        Dim var5 As Decimal = 4.56789D
        Dim var6 As Double = 3.4
        Dim var7 As Single = -0.000103F
        ' date
        Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
        ' boolean
        Dim var9 As Boolean = True
        ' character
        Dim var10 As Char = "A"c
        ' character string
        Dim var11 As String = "abcde"
        ' object
        Dim var12 As Object = New Object
        ' displays
        Console.Out.WriteLine("var1=" + var1.ToString)
        Console.Out.WriteLine("var2=" + var2.ToString)
        Console.Out.WriteLine("var3=" + var3.ToString)
        Console.Out.WriteLine("var4=" + var4.ToString)
        Console.Out.WriteLine("var5=" + var5.ToString)
        Console.Out.WriteLine("var6=" + var6.ToString)
        Console.Out.WriteLine("var7=" + var7.ToString)
        Console.Out.WriteLine("var8=" + var8.ToString)
        Console.Out.WriteLine("var9=" + var9.ToString)
        Console.Out.WriteLine("var10=" + var10)
        Console.Out.WriteLine("var11=" + var11)
        Console.Out.WriteLine("var12=" + var12.ToString)
    End Sub
End Module

A execução produz os seguintes resultados:

var1=100
var2=10000000000
var3=100
var4=4
var5=4,56789
var6=3,4
var7=-0,000103
var8=01/01/2003 12:08:04
var9=True
var10=A
var11=abcde
var12=System.Object

2.2.2. Notação de dados literais

Inteiro
145, -7, &FF (hexadecimal)
Long
100000L
Duplo
134,789, -45E-18 (-45 × 10⁻¹⁸)
Simples
134,789F, -45E-18F (-45 × 10⁻¹⁸)
Decimal
100000D
Caractere
"A"c
String
"hoje"
Booleano
verdadeiro, falso
data
New Date(2003, 1, 1) para 01/01/2003

Tenha em atenção os seguintes pontos:

  • 100000L, em que L indica que o número é tratado como um inteiro longo
  • 134,789F, em que F indica que o número é tratado como um número de ponto flutuante de precisão simples
  • 100000D, em que D indica que o número é tratado como um número real decimal
  • "A"c, para converter a cadeia de caracteres "A" no caractere 'A'
  • A cadeia de caracteres é delimitada pelo caractere ". Se a cadeia de caracteres tiver de conter o caractere ", este é duplicado, como em "abcd""e" para representar a cadeia [abcd"e].

2.2.3. Declaração de dados

2.2.3.1. Função das declarações

Um programa manipula dados caracterizados por um nome e um tipo. Estes dados são armazenados na memória. Quando o programa é compilado, o compilador atribui a cada dado uma localização na memória caracterizada por um endereço e um tamanho. Faz isso utilizando as declarações feitas pelo programador. Além disso, estas declarações permitem ao compilador detetar erros de programação. Assim, a operação x = x \* 2 será declarada como um erro se x for uma cadeia de caracteres, por exemplo.

2.2.3.2. Declaração de constantes

A sintaxe para declarar uma constante é a seguinte:

const identificador as tipo=valor

Por exemplo, [const PI as double=3.141592]. Porquê declarar constantes?

  1. O programa será mais fácil de ler se for atribuído um nome significativo à constante: [const VAT_rate as single=0.186F]
  2. Modificar o programa será mais fácil se a «constante» precisar de ser alterada. Assim, no caso anterior, se a taxa de IVA mudar para 33%, a única modificação necessária será alterar a instrução que define o seu valor: [const vatrate como single=0.336F]. Se 0.186 tivesse sido usado explicitamente no programa, seria necessário modificar inúmeras instruções.

2.2.3.3. Declaração de variáveis

Uma variável é identificada por um nome e refere-se a um tipo de dados. O VB.NET não distingue entre letras maiúsculas e minúsculas. Assim, as variáveis FIN e fin são idênticas. As variáveis podem ser inicializadas quando são declaradas. A sintaxe para declarar uma ou mais variáveis é:

dim variável1,variável2,...,variáveln como identificador_de_tipo

onde identificador_de_tipo é um tipo predefinido ou um tipo definido pelo programador.

2.2.4. Conversões entre números e cadeias de caracteres

número -> cadeia de caracteres
number.ToString ou "" & number ou CType(number, String)
objeto -> cadeia de caracteres
objeto.ToString
string -> Integer
Integer.Parse(string) ou Int32.Parse
string -> Long
Long.Parse(string) ou Int64.Parse
string -> Double
Double.Parse(string)
string -> Single
Single.Parse(string)

A conversão de uma cadeia de caracteres num número pode falhar se a cadeia não representar um número válido. Isto resulta num erro fatal, conhecido como exceção no VB.NET. Este erro pode ser tratado utilizando o seguinte bloco try/catch:

try
        appel de la fonction susceptible de générer l'exception
 catch e as Exception
        traiter l'exception e
end try
instruction suivante

Se a função não gerar uma exceção, avançamos para a instrução seguinte; caso contrário, entramos no corpo da cláusula catch e, em seguida, avançamos para a instrução seguinte. Voltaremos ao tratamento de exceções mais tarde. Aqui está um programa que demonstra as principais técnicas para a conversão entre números e cadeias de caracteres. Neste exemplo, a função display imprime o valor do seu parâmetro no ecrã. Assim, display(S) imprime o valor de S no ecrã.


' guidelines
Option Strict On
 
' imported namespaces
Imports System
 
' the test module
Module Module1
 
    Sub Main()
        ' main proceedings
        ' local data
        Dim S As String
        Const i As Integer = 10
        Const l As Long = 100000
        Const f As Single = 45.78F
        Dim d As Double = -14.98
 
        ' number --> string
        affiche(CType(i, String))
        affiche(CType(l, String))
        affiche(CType(f, String))
        affiche(CType(d, String))
 
        'boolean --> string
        Const b As Boolean = False
        affiche(b.ToString)
 
        ' string --> int
        Dim i1 As Integer = Integer.Parse("10")
        affiche(i1.ToString)
        Try
            i1 = Integer.Parse("10.67")
            affiche(i1.ToString)
        Catch e As Exception
            affiche("Erreur [10.67] : " + e.Message)
        End Try
 
        ' chain --> long
        Dim l1 As Long = Long.Parse("100")
        affiche("" + l1.ToString)
        Try
            l1 = Long.Parse("10.675")
            affiche("" & l1)
        Catch e As Exception
            affiche("Erreur [10.675] : " + e.Message)
        End Try
 
        ' chain --> double
        Dim d1 As Double = Double.Parse("100,87")
        affiche(d1.ToString)
        Try
            d1 = Double.Parse("abcd")
            affiche("" & d1)
        Catch e As Exception
            affiche("Erreur [abcd] : " + e.Message)
        End Try
 
        ' chain --> single
        Dim f1 As Single = Single.Parse("100,87")
        affiche(f1.ToString)
        Try
            d1 = Single.Parse("abcd")
            affiche(f1.ToString)
        Catch e As Exception
            affiche("Erreur [abcd] : " + e.Message)
        End Try
    End Sub
 
    ' poster
    Public Sub affiche(ByVal S As String)
        Console.Out.WriteLine("S=" + S)
    End Sub
End Module

Os resultados são os seguintes:

S=10
S=100000
S=45,78
S=-14,98
S=False
S=10
S=Erreur [10.67] : Le format de la chaîne d'entrée est incorrect.
S=100
S=Erreur [10.675] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.

Note que os números reais em formato de cadeia de caracteres devem usar uma vírgula, e não um ponto decimal. Assim, escrevemos Dim d As Double = -14,98 mas Dim d1 As Double = Double.Parse("100.87")

2.2.5. Matrizes de dados

Uma matriz VB.NET é um objeto que permite que dados do mesmo tipo sejam agrupados sob um único identificador. É declarada da seguinte forma:

Dim Array(n) As Type ou Dim Array() As Type = New Type(n) {}

onde n é o índice do último elemento da matriz. A sintaxe Array(i) refere-se aos dados no índice i, onde i pertence ao intervalo [0,n]. Qualquer referência aos dados Array(i) em que i não pertença ao intervalo [0,n] causará uma exceção. Uma matriz pode ser inicializada ao mesmo tempo que é declarada. Neste caso, não é necessário especificar o índice do último elemento.


        Dim entiers() As Integer = {0, 10, 20, 30}

As matrizes têm uma propriedade Length, que corresponde ao número de elementos na matriz. Aqui está um exemplo de programa:


Module tab0
    Sub Main()
        ' a first picture
        Dim tab0(5) As Integer
        For i As Integer = 0 To UBound(tab0)
            tab0(i) = i
        Next
        For i As Integer = 0 To UBound(tab0)
            Console.Out.WriteLine("tab0(" + i.ToString + ")=" + tab0(i).tostring)
        Next
 
        ' a second panel
        Dim tab1() As Integer = New Integer(5) {}
        For i As Integer = 0 To tab1.Length - 1
            tab1(i) = i * 10
        Next
        For i As Integer = 0 To tab1.Length - 1
            Console.Out.WriteLine("tab1(" + i.ToString + ")=" + tab1(i).tostring)
        Next
    End Sub
End Module

e a sua execução:

tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50

Uma matriz bidimensional pode ser declarada da seguinte forma:

Dim Array(n,m) como Tipo ou Dim Array(,) como Tipo = New Tipo(n,m) {}

onde n+1 é o número de linhas e m+1 o número de colunas. A sintaxe Array(i,j) refere-se ao elemento j na linha i da matriz Array. A matriz bidimensional também pode ser inicializada no momento em que é declarada:


        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}

O número de elementos em cada dimensão pode ser obtido utilizando o método GetLength(i), em que i=0 representa a dimensão correspondente ao primeiro índice, i=1 a dimensão correspondente ao segundo índice, …Eis um exemplo de programa:


Module Module2
    Sub Main()
        ' a first picture
        Dim tab0(2, 1) As Integer
        For i As Integer = 0 To UBound(tab0)
            For j As Integer = 0 To tab0.GetLength(1) - 1
                tab0(i, j) = i * 10 + j
            Next
        Next
        For i As Integer = 0 To UBound(tab0)
            For j As Integer = 0 To tab0.GetLength(1) - 1
                Console.Out.WriteLine("tab0(" + i.ToString + "," + j.ToString + ")=" + tab0(i, j).tostring)
            Next
        Next
 
        ' a second panel
        Dim tab1(,) As Integer = New Integer(2, 1) {}
        For i As Integer = 0 To tab1.GetLength(0) - 1
            For j As Integer = 0 To tab1.GetLength(1) - 1
                tab1(i, j) = i * 100 + j
            Next
        Next
        For i As Integer = 0 To tab1.GetLength(0) - 1
            For j As Integer = 0 To tab1.GetLength(1) - 1
                Console.Out.WriteLine("tab1(" + i.ToString + "," + j.ToString + ")=" + tab1(i, j).tostring)
            Next
        Next
    End Sub
End Module

e os resultados da sua execução:

tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50

Uma matriz de matrizes é declarada da seguinte forma:

Dim Array(n)() As Tipo ou Dim Array()() As Tipo = New Tipo(n)()

A declaração acima cria uma matriz de n+1 linhas. Cada elemento Array(i) é uma referência a uma matriz unidimensional. Estas matrizes não são criadas durante a declaração acima. O exemplo abaixo ilustra a criação de uma matriz de matrizes:


        ' a table of tables
        Dim noms()() As String = New String(3)() {}
        ' initialization
        For i = 0 To noms.Length - 1
            noms(i) = New String(i) {}
            For j = 0 To noms(i).Length - 1
                noms(i)(j) = "nom" & i & j
            Next
        Next

Aqui, names(i) é uma matriz com i+1 elementos. Como names(i) é uma matriz, names(i).Length é o número de elementos que ela contém. Aqui está um exemplo que combina os três tipos de matrizes que acabámos de discutir:


' guidelines
Option Strict On
Option Explicit On 
 
' imports
Imports System
 
' test class
Module test
    Sub main()
        ' an initialized 1-dimensional array
        Dim entiers() As Integer = {0, 10, 20, 30}
        Dim i As Integer
        For i = 0 To entiers.Length - 1
            Console.Out.WriteLine("entiers[" & i & "]=" & entiers(i))
        Next
 
        ' an initialized 2-dimensional array
        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
        Dim j As Integer
        For i = 0 To réels.GetLength(0) - 1
            For j = 0 To réels.GetLength(1) - 1
                Console.Out.WriteLine("réels[" & i & "," & j & "]=" & réels(i, j))
            Next
        Next
 
        ' an array°of arrays
        Dim noms()() As String = New String(3)() {}
 
        ' initialization
        For i = 0 To noms.Length°- 1
            noms(i) =°New String(i) {}
            For j = 0 To noms(i).Length - 1
                noms(i)(j) = "nom" & i & j
            Next
        Next
 
        ' display
        For i = 0 To noms.Length°- 1
            For j = 0 To noms(i).Length - 1
                Console.Out.WriteLine("noms[" & i & "][" & j & "]=" & noms(i)(j))
            Next
        Next
    End Sub
End Module

Quando executado, obtemos os seguintes resultados:

entiers[0]=0
entiers[1]=10
entiers[2]=20
entiers[3]=30
réels[0,0]=0,5
réels[0,1]=1,7
réels[1,0]=8,4
réels[1,1]=-6
noms[0][0]=nom00
noms[1][0]=nom10
noms[1][1]=nom11
noms[2][0]=nom20
noms[2][1]=nom21
noms[2][2]=nom22
noms[3][0]=nom30
noms[3][1]=nom31
noms[3][2]=nom32
noms[3][3]=nom33

2.3. Instruções básicas do VB.NET

Distinguimos entre

1 as instruções básicas executadas pelo computador.

2 instruções que controlam o fluxo do programa.

As instruções básicas tornam-se claras quando se considera a estrutura de um microcomputador e dos seus periféricos.

  1. Leitura de informações a partir do teclado

  2. Processamento de informação

  3. Gravação de informações no ecrã

  4. Leitura de informações de um ficheiro em disco

  5. Gravação de informações num ficheiro de disco

2.3.1. Escrever no ecrã

Existem várias instruções para escrever no ecrã:

Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)

onde expressão é qualquer tipo de dados que possa ser convertido numa cadeia de caracteres para ser apresentado no ecrã. Nos exemplos vistos até agora, utilizámos apenas a instrução Console.Out.WriteLine(expressão).

A classe System.Console permite aceder a operações de escrita no ecrã (Write, WriteLine). A classe Console possui duas propriedades, Out e Error, que são fluxos de escrita do tipo StreamWriter:

  • Console.WriteLine() é equivalente a Console.Out.WriteLine() e escreve no fluxo Out, que está normalmente associado ao ecrã.
  • Console.Error.WriteLine() escreve no fluxo Error, que também está normalmente associado ao ecrã.

Os fluxos Out e Error estão associados ao ecrã por predefinição. No entanto, podem ser redirecionados para ficheiros de texto em tempo de execução, como veremos em breve.

2.3.2. Ler dados digitados no teclado

O fluxo de dados proveniente do teclado é representado pelo objeto Console.In do tipo StreamReader. Este tipo de objeto permite-lhe ler uma linha de texto utilizando o método ReadLine:


        Dim ligne As String = Console.In.ReadLine()

A linha digitada no teclado é armazenada na variável line* e pode então ser utilizada pelo programa. O fluxo In pode ser redirecionado para um ficheiro, tal como os fluxos Out e Error*.

2.3.3. Exemplo de Entrada/Saída

Aqui está um pequeno programa que ilustra operações de entrada/saída do teclado/ecrã:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
' module
Module io1
    Sub Main()
        ' write to Out feed
        Dim obj As New Object
        Console.Out.WriteLine(("" & obj.ToString))
 
        ' write to the Error stream
        Dim i As Integer = 10
        Console.Error.WriteLine(("i=" & i))
 
        ' reading a line entered on the keyboard
        Console.Out.Write("Tapez une ligne : ")
        Dim ligne As String = Console.In.ReadLine()
        Console.Out.WriteLine(("ligne=" + ligne))
    End Sub
End Module

e os resultados da execução:

System.Object
i=10
Tapez une ligne : ceci est un essai
ligne=ceci est un essai

As instruções


        Dim obj As New Object
        Console.Out.WriteLine(obj.ToString)

estão aqui apenas para mostrar que qualquer objeto pode ser exibido. Não tentaremos aqui explicar o significado do que é exibido.

2.3.4. Redirecionamento de E/S

No DOS/Windows, existem três dispositivos de entrada padrão chamados:

  1. dispositivo de entrada padrão — por predefinição, refere-se ao teclado e é numerado como 0
  2. dispositivo de saída padrão — por predefinição, refere-se ao ecrã e é numerado como 1
  3. dispositivo de erro padrão — por predefinição, refere-se ao ecrã e é numerado como 2

No VB.NET, o fluxo de saída Console.Out escreve no dispositivo 1, o fluxo de saída Console.Error escreve no dispositivo 2 e o fluxo de entrada Console.In lê dados do dispositivo 0. Quando executa um programa numa janela DOS no Windows, pode especificar quais os dispositivos que serão 0, 1 e 2 para o programa em execução. Considere a seguinte linha de comando:

pg arg1 arg2 .. argn

Após os argumentos argi do programa pg, pode redirecionar os dispositivos de E/S padrão para ficheiros:

0<in.txt
O fluxo de entrada padrão n.º 0 é redirecionado para o ficheiro in.txt. No programa, o fluxo Console.In irá, portanto, ler os seus dados a partir do ficheiro in.txt.
  
1>out.txt
redireciona o fluxo de saída n.º 1 para o ficheiro out.txt. Isto significa que, no programa, o fluxo Console.Out irá escrever os seus dados no ficheiro out.txt
   
1>>out.txt
Igual ao anterior, mas os dados gravados são anexados ao conteúdo atual do ficheiro out.txt.
   
2>error.txt
redireciona a saída n.º 2 para o ficheiro error.txt. Isto significa que, no programa, o fluxo Console.Error irá gravar os seus dados no ficheiro error.txt
   
2>>error.txt
Igual ao anterior, mas os dados gravados são anexados ao conteúdo atual do ficheiro error.txt.
   
1>out.txt 2>error.txt
Os dispositivos 1 e 2 são ambos redirecionados para ficheiros
   

Note-se que, para redirecionar os fluxos de E/S do programa pg para ficheiros, não é necessário modificar o programa pg. É o sistema operativo que determina a natureza dos dispositivos 0, 1 e 2. Considere o seguinte programa:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
' redirections
Module console2
    Sub Main()
        ' lecture flux In
        Dim data As String = Console.In.ReadLine()
        ' write Out feed
        Console.Out.WriteLine(("écriture dans flux Out : " + data))
        ' écriture flux Error
        Console.Error.WriteLine(("écriture dans flux Error : " + data))
    End Sub
End Module

Vamos compilar este programa:

dos>vbc es2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.

dos>dir
24/02/2004  15:39                  416 es2.vb
11/03/2004  08:20                3 584 es2.exe

Vamos executá-lo pela primeira vez:

dos>es2.exe
un premier test
écriture dans flux Out : un premier test
écriture dans flux Error : un premier test

A execução anterior não redireciona nenhum dos fluxos de E/S padrão In, Out ou Error. Vamos agora redirecionar os três fluxos. O fluxo In será redirecionado para um ficheiro chamado in.txt, o fluxo Out para um ficheiro chamado out.txt e o fluxo Error para um ficheiro chamado error.txt. Este redirecionamento é realizado na linha de comandos da seguinte forma

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

A execução produz os seguintes resultados:

dos>more in.txt
un second test

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

dos>more out.txt
écriture dans flux Out : un second test

dos>more error.txt
écriture dans flux Error : un second test

É evidente que os fluxos Out e Error não escrevem nos mesmos dispositivos.

2.3.5. Atribuir o valor de uma expressão a uma variável

Aqui, estamos interessados na operação variável=expressão. A expressão pode ser dos seguintes tipos: aritmética, relacional, booleana ou de cadeia de caracteres.

2.3.5.1. Lista de operadores

Ação
Elemento da linguagem
Aritmética
^, –, *, /, \, Mod, +, =
Atribuição
=, ^=, *=, /=, \=, +=, -=, &=
Comparação
=, <>, <, >, <=, >=, Like, Is
Concatenação
&, +
Operações lógicas/bit a bit
Não, E, Ou, XOR, E também, Ou então
Operações diversas
AddressOf, GetType

2.3.5.2. Expressão aritmética

Os operadores para expressões aritméticas são os seguintes:

Aritmética
^, –, *, /, \, Mod, +, =

+: adição, -: subtração, *: multiplicação, /: divisão em ponto flutuante, \: quociente da divisão inteira, Mod: resto da divisão inteira, ^: elevação à potência. Assim, o seguinte programa:


' arithmetic operators
Module operateursarithmetiques
    Sub Main()
        Dim i, j As Integer
        i = 4 : j = 3
        Console.Out.WriteLine(i & "/" & j & "=" & (i / j))
        Console.Out.WriteLine(i & "\" & j & "=" & (i \ j))
        Console.Out.WriteLine(i & " mod " & j & "=" & (i Mod j))
 
        Dim r1, r2 As Double
        r1 = 4.1 : r2 = 3.6
        Console.Out.WriteLine(r1 & "/" & r2 & "=" & (r1 / r2))
        Console.Out.WriteLine(r1 & "^2=" & (r1 ^ 2))
        Console.Out.WriteLine(Math.Cos(3))
    End Sub
End Module

dá os seguintes resultados:

4/3=1,33333333333333
4\3=1
4 mod 3=1
4,1/3,6=1,13888888888889
4,1^2=16,81
-0,989992496600445

Existem várias funções matemáticas. Aqui estão algumas:


Função Pública Partilhada Sqrt(ByVal d As Double) As Double
raiz quadrada

[Visual Basic]
Função Pública Compartilhada Cos(ByVal d As Double) As Double
Cosseno

Função pública partilhada Sin(ByVal a As Double) As Double
Sen

[Visual Basic]
Função pública partilhada Tan(ByVal a As Double) As Double
Tangente

[Visual Basic]
Função Pública Partilhada Pow(ByVal x As Double, ByVal y As Double) As Double
x elevado a y (x > 0)

[Visual Basic]
Função Pública Compartilhada Exp(ByVal d As Double) As Double
Exponencial

[Visual Basic]
Sobrecargas Função Pública Partilhada Log( ByVal d As Double ) As Double
Logaritmo natural

Sobrecarga Função Pública Partilhada Abs(ByVal valor As Double) As Double
Valor absoluto
....
 

Todas estas funções estão definidas numa classe .NET chamada Math. Ao utilizá-las, deve antepor-lhes o nome da classe na qual estão definidas. Assim, escreveria:

        Dim r1, r2 As Double
        r2 = Math.Sqrt(9)
        r1 = Math.Cos(3)

A definição completa da classe Math é a seguinte:

E
Representa o logaritmo natural de base especificada pela constante e.
   
PI
Representa a razão entre a circunferência de um círculo e o seu diâmetro, especificada pela constante π.
   
Abs
Sobrecargada. Devolve o valor absoluto de um número especificado.
  
Acos
Retorna o ângulo cujo cosseno é o número especificado.
  
Asin
Retorna o ângulo cujo seno é o número especificado.
  
Atan
Retorna o ângulo cuja tangente é o número especificado.
  
Atan2
Retorna o ângulo cuja tangente é o quociente de dois números especificados.
  
BigMul
Gera o produto inteiro de dois números de 32 bits.
  
Ceiling
Retorna o menor inteiro maior ou igual ao número especificado.
  
Cos
Retorna o cosseno do ângulo especificado.
  
Cosh
Retorna o coseno hiperbólico do ângulo especificado.
  
DivRem
Sobrecargada. Devolve o quociente de dois números, passando o resto como parâmetro de saída.
  
Exp
Retorna e elevado à potência especificada.
  
Floor
Retorna o maior número inteiro menor ou igual ao número especificado.
  
IEEERemainder
Retorna o resto da divisão de um número por outro.
  
Log
Sobrecarregado. Devolve o logaritmo de um número especificado.
  
Log10
Retorna o logaritmo em base 10 de um número especificado.
  
Max
Sobrecarregado. Devolve o maior dos dois números especificados.
  
Min
Sobrecargada. Devolve o menor dos dois números.
  
Pow
Retorna um número especificado elevado à potência especificada.
  
Arredondar
Sobrecargada. Devolve o número mais próximo do valor especificado.
  
Sinal
Sobrecargada. Devolve um valor que indica o sinal de um número.
  
Sin
Retorna o seno do ângulo especificado.
  
Sinh
Retorna o seno hiperbólico do ângulo especificado.
  
Sqrt
Retorna a raiz quadrada de um número especificado.
  
Tan
Retorna a tangente do ângulo especificado.
  
Tanh
Retorna a tangente hiperbólica do ângulo especificado.
  

Quando uma função é declarada como «sobrecarregada», isso significa que existe para vários tipos de parâmetros. Por exemplo, a função Abs(x) existe para x do tipo Integer, Long, Decimal, Single e Float. Para cada um destes tipos, existe uma definição separada da função Abs. Diz-se então que está sobrecarregada.

2.3.5.3. Operadores na avaliação de expressões aritméticas

A precedência dos operadores na avaliação de uma expressão aritmética é a seguinte (da mais alta para a mais baixa):

Categoria
Operadores
Primários
Todas as expressões sem operadores: funções, parênteses
Elevamento à potência
^
Negação unária
+, -
Multiplicação
*, /
Divisão por um número inteiro
\
Módulo
Mod
Adição
+, -

2.3.5.4. Expressões relacionais

Os operadores são os seguintes:

Comparação
=, <>, <, >, <=, >=, Like, Is

=: igual a, <>: diferente de, <: menor que (estritamente), >: maior que (estritamente), <=: menor ou igual a, >=: maior ou igual a, Like: corresponde a um padrão, Is: identidade do objeto. Todos estes operadores têm a mesma precedência. São avaliados da esquerda para a direita. O resultado de uma expressão relacional é um valor booleano.

Comparação de cadeias de caracteres: considere o seguinte programa:


' namespaces
Imports System
 
Module string1
    Sub main()
        Dim ch1 As Char = "A"c
        Dim ch2 As Char = "B"c
        Dim ch3 As Char = "a"c
        Console.Out.WriteLine("A<B=" & (ch1 < ch2))
        Console.Out.WriteLine("A<a=" & (ch1 < ch3))
        Dim chat As String = "chat"
        Dim chien As String = "chien"
        Dim chaton As String = "chaton"
        Dim chat2 As String = "CHAT"
        Console.Out.WriteLine("chat<chien=" & (chat < chien))
        Console.Out.WriteLine("chat<chaton=" & (chat < chaton))
        Console.Out.WriteLine("chat<CHAT=" & (chat < chat2))
        Console.Out.WriteLine("chaton like chat*=" & ("chaton" Like "chat*"))
    End Sub
End Module

e o resultado da sua execução:

A<B=True
A<a=True
chat<chien=True
chat<chaton=True
chat<CHAT=False
chaton like chat*=True

Suponha que existam dois caracteres C1 e C2. Estes podem ser comparados utilizando os operadores: <, <=, =, <>, >, >=. São os seus valores Unicode — que são números — que são comparados. De acordo com a ordem Unicode, verificam-se as seguintes relações:

espaço < .. < '0' < '1' < .. < '9' < .. < 'A' < 'B' < .. < 'Z' < .. < 'a' < 'b' < .. < 'z'

As cadeias de caracteres são comparadas caractere a caractere. A primeira desigualdade encontrada entre dois caracteres implica uma desigualdade do mesmo sinal para as cadeias de caracteres. Com estas explicações, convidamos o leitor a examinar os resultados do programa anterior.

2.3.5.5. Expressões booleanas

Os operadores são os seguintes:

Operações lógicas/bit a bit
Not, And, Or, Xor, AndAlso, OrElse

Not: AND lógico, Or: OR lógico, Not: negação, Xor: OR exclusivo.

op1 AndAlso op2: se op1 for falso, op2 não é avaliado e o resultado é falso.

op1 OrElse op2: se op1 for verdadeiro, op2 não é avaliado e o resultado é verdadeiro.

A precedência destes operadores uns em relação aos outros é a seguinte:

NÃO lógico
NÃO lógico
E lógico
E, E também
OU lógico
OU, OuCaso
XOR lógico
XOR

O resultado de uma expressão booleana é um valor booleano.

2.3.5.6. Operações bit a bit

Por um lado, encontramos os mesmos operadores que os operadores booleanos, com a mesma precedência. Encontramos também dois operadores de deslocamento: << e >>. Sejam i e j dois inteiros.

i<<n
desloca i n bits para a esquerda. Os bits recebidos são zeros.
i>>n
desloca i n bits para a direita. Se i for um inteiro com sinal (signed char, int, long), o bit de sinal é preservado.
i & j
realiza uma operação lógica AND bit a bit entre i e j.
i | j
realiza uma operação OR bit a bit em i e j.
~i
complementa i para 1
i^j
realiza o XOR de i e j

Considere o seguinte programa:


Module operationsbit
    Sub main()
        ' bit manipulation
        Dim i As Short = &H123F
        Dim k As Short = &H7123
        Console.Out.WriteLine("i<<4=" & (i << 4).ToString("X"))
        Console.Out.WriteLine("i>>4=" & (i >> 4).ToString("X"))
        Console.Out.WriteLine("k>>4=" & (k >> 4).ToString("X"))
        Console.Out.WriteLine("i and 4=" & (i And 4).ToString("X"))
        Console.Out.WriteLine("i or 4 =" & (i Or 4).ToString("X"))
        Console.Out.WriteLine("not i=" & (Not i).ToString("X"))
    End Sub
End Module

A sua execução produz os seguintes resultados:

i<<4=23F0
i>>4=123
k>>4=712
i and 4=4
i or k =123F
not i=EDC0

2.3.5.7. Operador associado à atribuição

É possível escrever a+=b, o que significa a=a+b. A lista de operadores que podem ser combinados com a operação de atribuição é a seguinte:

Combinação de operadores
^=, *=, /=, \=, +=, -=, &=

2.3.5.8. Precedência geral dos operadores

Categoria
Operadores
Primária
Todas as expressões sem operadores
Elevamento à potência
^
Negação unária
+, -
Multiplicação
*, /
Divisão por um número inteiro
\
Módulo
Mod
Adição
+, -
Concatenação
&
Deslocamento
<<, >>
Relacional
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is
Lógico NOT
Não
E lógico
E, E também
OU lógico
OU, OuCaso
XOR lógico
XOR

Quando um operando é colocado entre dois operadores da mesma precedência, a associatividade dos operadores determina a ordem em que as operações são realizadas. Todos os operadores são associativos à esquerda, o que significa que as operações são realizadas da esquerda para a direita. A precedência e a associatividade podem ser controladas utilizando expressões entre parênteses.

2.3.5.9. Conversões de tipos

Existem várias funções predefinidas que permitem converter de um tipo de dados para outro. A lista é a seguinte:

CBool,CByte,CChar,CDate,CDbl,CDec,CInt,CLng,CObj,CShort,CSng,CStr

Estas funções aceitam uma expressão numérica ou uma cadeia de caracteres como argumento. O tipo de resultado é apresentado na tabela seguinte:

função
Resultado
Intervalo de valores do parâmetro da função
CBool
Booleano
Qualquer expressão numérica ou cadeia de caracteres válida.
CByte
Byte
0 a 255; as frações são arredondadas.
CChar
Char
Qualquer expressão String válida; o valor pode variar entre 0 e 65 535.
CDate
Date
Qualquer representação válida da data e hora.
CDbl
Duplo
-1,79769313486231E+308 a
-4,94065645841247E-324 para valores negativos; 4,94065645841247E-324 a 1,79769313486231E+308 para valores positivos.
CDec
Decimal
+/-79.228.162.514.264.337.593.543.950.335 para números não decimais. O intervalo de valores para números de 28 dígitos decimais é
+/-7,9228162514264337593543950335. O menor número diferente de zero é 0,0000000000000000000000000001.
CInt
Inteiro
-2 147 483 648 a 2 147 483 647; as frações são arredondadas.
CLng
Long
-9.223.372.036.854.775.808 a 9.223.372.036.854.775.807; as frações são arredondadas.
CObj
Objeto
Qualquer expressão válida.
CShort
Curto
-32 768 a 32 767; as frações são arredondadas.
CSng
Único
-3,402823E+38 a -1,401298E-45 para valores negativos; 1,401298E-45 a 3,402823E+38 para valores positivos.
CStr
String
Os valores devolvidos pela função Cstr dependem do argumento da expressão.

Eis um exemplo de programa:


Module conversion
    Sub main()
        Dim var1 As Boolean = CBool("true")
        Dim var2 As Byte = CByte("100")
        Dim var3 As Char = CChar("A")
        Dim var4 As Date = CDate("30 janvier 2004")
        Dim var5 As Double = CDbl("100,45")
        Dim var6 As Decimal = CDec("1000,67")
        Dim var7 As Integer = CInt("-30")
        Dim var8 As Long = CLng("456")
        Dim var9 As Short = CShort("-14")
        Dim var10 As Single = CSng("56,78")
        Console.Out.WriteLine("var1=" & var1)
        Console.Out.WriteLine("var2=" & var2)
        Console.Out.WriteLine("var3=" & var3)
        Console.Out.WriteLine("var4=" & var4)
        Console.Out.WriteLine("var5=" & var5)
        Console.Out.WriteLine("var6=" & var6)
        Console.Out.WriteLine("var7=" & var7)
        Console.Out.WriteLine("var8=" & var8)
        Console.Out.WriteLine("var9=" & var9)
        Console.Out.WriteLine("var10=" & var10)
    End Sub
End Module

e os resultados da sua execução:

var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78

Também pode utilizar a função CType(expressão, tipo), conforme ilustrado no programa seguinte:


Module ctype1
    Sub main()
        Dim var1 As Boolean = CType("true", Boolean)
        Dim var2 As Byte = CType("100", Byte)
        Dim var3 As Char = CType("A", Char)
        Dim var4 As Date = CType("30 janvier 2004", Date)
        Dim var5 As Double = CType("100,45", Double)
        Dim var6 As Decimal = CType("1000,67", Decimal)
        Dim var7 As Integer = CType("-30", Integer)
        Dim var8 As Long = CType("456", Long)
        Dim var9 As Short = CType("-14", Short)
        Dim var10 As Single = CType("56,78", Single)
        Dim var11 As String = CType("47,89", String)
        Dim var12 As String = 47.89.ToString
        Dim var13 As String = "" & 47.89
        Console.Out.WriteLine("var1=" & var1)
        Console.Out.WriteLine("var2=" & var2)
        Console.Out.WriteLine("var3=" & var3)
        Console.Out.WriteLine("var4=" & var4)
        Console.Out.WriteLine("var5=" & var5)
        Console.Out.WriteLine("var6=" & var6)
        Console.Out.WriteLine("var7=" & var7)
        Console.Out.WriteLine("var8=" & var8)
        Console.Out.WriteLine("var9=" & var9)
        Console.Out.WriteLine("var10=" & var10)
        Console.Out.WriteLine("var11=" & var11)
        Console.Out.WriteLine("var12=" & var12)
        Console.Out.WriteLine("var13=" & var13)
    End Sub
End Module

o que produz os seguintes resultados:

var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
var11=47,89
var12=47,89
var13=47,89

2.4. Instruções para controlar a execução do programa

2.4.1. Parar

O método Exit definido na classe Environment permite-lhe parar a execução de um programa:


[Visual Basic]
Public Shared Sub Exit(ByVal exitCode As Integer )

interrompe o processo atual e devolve o valor de exitCode ao processo pai. O valor de exitCode pode ser utilizado pelo processo pai. No DOS, esta variável de estado é devolvida ao DOS na variável de sistema ERRORLEVEL, cujo valor pode ser verificado num ficheiro batch. No Unix, a variável $? recupera o valor de exitCode.

    Environment.Exit(0)

encerrará o programa com um estado de saída de 0.

2.4.2. Estrutura de decisão simples

if condition then
    actions_alors
else
    actions_sinon
end if
  • Cada ação está numa linha separada
  • A cláusula else pode ser omitida.

É possível aninhar estruturas de decisão, conforme mostrado no exemplo a seguir:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module if1
    Sub main()
        Dim i As Integer = 10
        If i > 4 Then
            Console.Out.WriteLine(i & " est > " & 4)
        Else
            If i = 4 Then
                Console.Out.WriteLine(i & " est = " & 4)
            Else
                Console.Out.WriteLine(i & " est < " & 4)
            End If
        End If
    End Sub
End Module

O resultado obtido:

10 est > 4

2.4.3. Estrutura do caso

A sintaxe é a seguinte:

select case expression
    case liste_valeurs1
        actions1
case liste_valeurs2
        actions2
...
case else
        actions_sinon
end select
  • O tipo de [expressão] deve ser um dos seguintes tipos:
Boolean, Byte, Char, Date, Decimal, Double, Integer, Long, Object, Short, Single et String
  • A cláusula [case else] pode ser omitida.
  • [lista_de_valores] são os valores possíveis da expressão. [listas_de_valores] representa uma lista de condições condição1, condição2, ..., condiçãox. Se [expressão] satisfizer uma das condições, as ações que se seguem à cláusula [lista_de_valores] são executadas. As condições podem assumir a seguinte forma:
  • val1 a val2: verdadeiro se [expressão] pertencer ao intervalo [val1,val2]
  • val1: verdadeiro se [expressão] for igual a val1
  • is > val1: verdadeiro se [expressão] > val1. A palavra-chave [is] pode ser omitida
  • O mesmo se aplica aos operadores =, <, <=, >, >=, <>
  • apenas as ações associadas à primeira condição verificada são executadas.

Considere o seguinte programa:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module selectcase1
    Sub main()
        Dim i As Integer = 10
        Select Case i
            Case 1 To 4, 7 To 8
                Console.Out.WriteLine("i est dans l'intervalle [1,4] ou [7,8]")
            Case Is > 12
                Console.Out.WriteLine("i est > 12")
            Case Is < 15
                Console.Out.WriteLine("i est < 15")
            Case Is < 20
                Console.Out.WriteLine("i est < 20")
        End Select
    End Sub
End Module

Isso produz os seguintes resultados:

i est < 15

2.4.4. Estrutura do ciclo

2.4.4.1. Número conhecido de iterações


For counter [ As datatype ] = start To end [ Step step ]
   actions
Next [ counter ]

As ações são executadas para cada valor assumido pela variável [contador]. Considere o seguinte programa:


' options
Option Explicit On 
Option Strict On

' namespaces
Imports System
 
Module for1
    Sub main()
        Dim somme As Integer = 0
        Dim résultat As String = "somme("
        For i As Integer = 0 To 10 Step 2
            somme += i
            résultat += " " + i.ToString
        Next
        résultat += ")=" + somme.ToString
        Console.Out.WriteLine(résultat)
    End Sub
End Module

Os resultados:

somme( 0 2 4 6 8 10)=30

Outra estrutura de iteração com um número conhecido de iterações é a seguinte:


For Each element [ As datatype ] In groupe
   [ actions ]
Next [ element ]
  • Um grupo é uma coleção de objetos. A coleção de objetos com a qual já estamos familiarizados é a matriz
  • O tipo de dados é o tipo dos objetos na coleção. No caso de uma matriz, este seria o tipo dos elementos da matriz
  • elemento é uma variável local do ciclo que irá assumir sucessivamente os valores da coleção.

Assim, o código seguinte:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module foreach1
    Sub main()
        Dim amis() As String = {"paul", "hélène", "jacques", "sylvie"}
        For Each nom As String In amis
            Console.Out.WriteLine(nom)
        Next
    End Sub
End Module

exibiria:

paul
hélène
jacques
sylvie

2.4.4.2. Número de repetições desconhecido

Existem muitas estruturas em VB.NET para este caso.


Do { While | Until } condition
   [ statements ]
Loop

O ciclo continua enquanto a condição for verdadeira (while) ou até que a condição seja verdadeira (until). O ciclo pode nunca ser executado.


Do
   [ statements ]
Loop { While | Until } condition

O ciclo continua enquanto a condição for verdadeira (while) ou até que a condição seja verdadeira (until). O ciclo é sempre executado pelo menos uma vez.


While condition
   [ statements ]
End While

O ciclo continua enquanto a condição for verdadeira. O ciclo pode nunca ser executado. Todos os ciclos a seguir calculam a soma dos primeiros 10 números inteiros.


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module boucles1
    Sub main()
        Dim i, somme As Integer
        i = 0 : somme = 0
        Do While i < 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do Until i = 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop Until i = 11
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop While i < 11
        Console.Out.WriteLine("somme=" + somme.ToString)
    End Sub
End Module
somme=55
somme=55
somme=55
somme=55

2.4.4.3. Instruções de controlo de loop

sair do
Sai de um ciclo do...loop
exit for
Sai de um for loop

2.5. A estrutura de um programa VB.NET

Um programa VB.NET que não utilize classes ou funções definidas pelo utilizador, além da função principal Main, pode ter a seguinte estrutura:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports espace1
Imports ....
 
Module nomDuModule
    Sub main()
....
    End Sub
End Module
  • A diretiva [Option Explicit on] impõe a declaração de variáveis. No VB.NET, isto não é obrigatório. Uma variável não declarada é, nesse caso, do tipo Object.
  • A diretiva [Option Strict on] proíbe quaisquer conversões de tipos de dados que possam resultar em perda de dados e quaisquer conversões entre tipos numéricos e cadeias de caracteres. As funções de conversão devem, portanto, ser utilizadas explicitamente.
  • O programa importa todos os namespaces de que necessita. Ainda não introduzimos este conceito. Em programas anteriores, deparámo-nos frequentemente com instruções como:
        Console.Out.WriteLine(unechaine)

Na verdade, deveríamos ter escrito:

        System.Console.Out.WriteLine(unechaine)

onde System é o namespace que contém a classe [Console]. Ao importar o namespace [System] com uma instrução Imports, o VB.NET irá procurá-lo sistematicamente sempre que encontrar uma classe que não reconheça. Irá repetir a pesquisa em todos os namespaces declarados até encontrar a classe em questão. Por isso, escrevemos:


' namespaces
Imports System
....
 
        Console.Out.WriteLine(unechaine)

Um programa de exemplo pode ter o seguinte aspeto:


' options
Option Explicit On 
Option Strict On
 
'namespaces
Imports System
 
' main module
Module main1
    Sub main()
        Console.Out.WriteLine("main1")
    End Sub
End Module

O mesmo programa pode ser escrito da seguinte forma:


' options
Option Explicit On 
Option Strict On
 
'namespaces
Imports System
 
' test class
Public Class main2
    Public Shared Sub main()
        Console.Out.WriteLine("main2")
    End Sub
End Class

Aqui, estamos a utilizar o conceito de classe, que será apresentado no próximo capítulo. Quando uma classe deste tipo contém um procedimento estático (partilhado) denominado main, este é executado. Incluímos este código aqui porque o C#, a linguagem irmã do VB.NET, reconhece apenas o conceito de classes — ou seja, todo o código executado deve pertencer a uma classe. O conceito de classes faz parte da programação orientada a objetos. Impor isso ao design de todos os programas é um pouco estranho. Vemos isso aqui na versão 2 do programa anterior, onde somos forçados a introduzir os conceitos de classes e métodos estáticos onde eles não são necessários. Portanto, a partir de agora, só introduziremos o conceito de classe quando for necessário. Nos outros casos, usaremos o conceito de módulo, como na versão 1 acima.

2.6. Compilar e executar um programa VB.NET

A compilação de um programa VB.NET requer apenas o .NET SDK. Considere o seguinte programa:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module boucles1
    Sub main()
        Dim i, somme As Integer
        i = 0 : somme = 0
        Do While i < 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do Until i = 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop Until i = 11
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop While i < 11
        Console.Out.WriteLine("somme=" + somme.ToString)
    End Sub
End Module

Vamos supor que está num ficheiro chamado [loops1.vb]. Para o compilar, procedemos da seguinte forma:

dos>dir boucles1.vb
11/03/2004  15:55                  583 boucles1.vb

dos>vbc boucles1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.

dos>dir boucles1.*
11/03/2004  16:04                  601 boucles1.vb
11/03/2004  16:04                3 584 boucles1.exe

O programa vbc.exe é o compilador VB.NET. Aqui, estava no PATH do DOS:


dos>path
PATH=E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;E:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;E:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin;E:\WINNT\Microsoft.NET\Framework\v1.1.4322;e:\winnt\system32;e:\winnt;

dos>dir E:\WINNT\Microsoft.NET\Framework\v1.1.4322\vbc.exe
21/02/2003  10:20              737 280 vbc.exe

O compilador [vbc] produz um ficheiro .exe que pode ser executado pela máquina virtual .NET:

dos>boucles1
somme=55
somme=55
somme=55
somme=55

2.7. Exemplo de cálculo de impostos

Propomos escrever um programa para calcular o imposto de um contribuinte. Consideramos o caso simplificado de um contribuinte que tem apenas o seu salário para declarar:

  • calculamos o número de escalões de imposto para o trabalhador como nbParts = nbEnfants / 2 + 1 se for solteiro, e nbEnfants / 2 + 2 se for casado, sendo que nbEnfants é o número de filhos.
  • Se tiver pelo menos três filhos, recebe uma meia quota adicional
  • Calculamos o seu rendimento tributável R = 0,72 * S, em que S é o seu salário anual
  • Calculamos o seu coeficiente familiar QF = R / nbParts
  • calculamos o seu imposto I. Considere a seguinte tabela:
12620,0
0
0
13 190
0,05
631
15 640
0,1
1.290,5
24.740
0,15
2.072,5
31 810
0,2
3.309,5
39 970
0,25
4900
48 360
0,3
6.898,5
55 790
0,35
9.316,5
92 970
0,4
12 106
127 860
0,45
16 754,5
151 250
0,50
23 147,5
172 040
0,55
30 710
195 000
0,60
39 312
0
0,65
49062

Cada linha tem 3 campos. Para calcular o imposto I, encontre a primeira linha em que QF <= campo1. Por exemplo, se QF = 23 000, a linha encontrada será

    24740        0.15        2072.5

O Imposto I é então igual a 0,15*R - 2072,5*nbParts. Se QF for tal que a condição QF<=field1 nunca seja satisfeita, então são utilizados os coeficientes da última linha. Aqui:

    0                0.65        49062

o que dá o imposto I = 0,65*R - 49062*nbParts. O programa VB.NET correspondente é o seguinte:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module impots
    ' ------------ hand
    Sub Main()
 
        ' data tables required for tax calculation
        Dim Limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
        Dim CoeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}
 
        ' we recover marital status
        Dim OK As Boolean = False
        Dim reponse As String = Nothing
        While Not OK
            Console.Out.Write("Etes-vous marié(e) (O/N) ? ")
            reponse = Console.In.ReadLine().Trim().ToLower()
            If reponse <> "o" And reponse <> "n" Then
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            Else
                OK = True
            End If
        End While
        Dim Marie As Boolean = reponse = "o"
 
        ' number of children
        OK = False
        Dim NbEnfants As Integer = 0
        While Not OK
            Console.Out.Write("Nombre d'enfants : ")
            reponse = Console.In.ReadLine()
            Try
                NbEnfants = Integer.Parse(reponse)
                If NbEnfants >= 0 Then
                    OK = True
                Else
                    Console.Error.WriteLine("Réponse incorrecte. Recommencez")
                End If
            Catch
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            End Try
        End While
        ' salary
        OK = False
        Dim Salaire As Integer = 0
        While Not OK
            Console.Out.Write("Salaire annuel : ")
            reponse = Console.In.ReadLine()
            Try
                Salaire = Integer.Parse(reponse)
                If Salaire >= 0 Then
                    OK = True
                Else
                    Console.Error.WriteLine("Réponse incorrecte. Recommencez")
                End If
            Catch
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            End Try
        End While
        ' calculating the number of shares
        Dim NbParts As Decimal
        If Marie Then
            NbParts = CDec(NbEnfants) / 2 + 2
        Else
            NbParts = CDec(NbEnfants) / 2 + 1
        End If
        If NbEnfants >= 3 Then
            NbParts += 0.5D
        End If
        ' taxable income
        Dim Revenu As Decimal
        Revenu = 0.72D * Salaire
 
        ' family quotient
        Dim QF As Decimal
        QF = Revenu / NbParts
 
        ' search for tax bracket corresponding to QF
        Dim i As Integer
        Dim NbTranches As Integer = Limites.Length
        Limites((NbTranches - 1)) = QF
        i = 0
        While QF > Limites(i)
            i += 1
        End While
        ' tax
        Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)
 
        ' the result is displayed
        Console.Out.WriteLine(("Impôt à payer : " & impots))
    End Sub
End Module

O programa é compilado numa janela do DOS utilizando:

dos>vbc impots1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573

dos>dir impots1.exe
24/02/2004  15:42                5 632 impots1.exe

A compilação produz um ficheiro executável denominado impots.exe. Note-se que o impots.exe não é diretamente executável pelo processador. Na verdade, contém código intermédio que só é executável numa plataforma .NET. Os resultados obtidos são os seguintes:

dos>impots1
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : 3
Salaire annuel : 200000
Impôt à payer : 16400
dos>impots1
Etes-vous marié(e) (O/N) ? n
Nombre d'enfants : 2
Salaire annuel : 200000
Impôt à payer : 33388
dos>impots1
Etes-vous marié(e) (O/N) ? w
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? q
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : q
Réponse incorrecte. Recommencez
Nombre d'enfants : 2
Salaire annuel : q
Réponse incorrecte. Recommencez
Salaire annuel : 1
Impôt à payer : 0

2.8. Principais argumentos do programa

A função principal Main pode aceitar uma matriz de cadeias de caracteres como parâmetro:


    Sub main(ByVal args() As String)

O parâmetro args é uma matriz de cadeias de caracteres que recebe os argumentos passados na linha de comandos quando o programa é chamado.

  • args.Length é o número de elementos na matriz args
  • args(i) é o i-ésimo elemento da matriz

Se executarmos o programa P com o comando: P arg0 arg1 … argn e se o procedimento Main do programa P for declarado da seguinte forma:


    Sub main(ByVal args() As String)

teremos arg(0)="arg0", arg(1)="arg1" … Aqui está um exemplo:


' guidelines
Option Strict On
Option Explicit On 
 
' namespaces
Imports System
 
Module arg
    Sub main(ByVal args() As String)
        ' number of arguments
        console.out.writeline("Il y a " & args.length & " arguments")
        Dim i As Integer
        For i = 0 To args.Length - 1
            Console.Out.WriteLine("argument n° " & i & "=" & args(i))
        Next
    End Sub
End Module

A execução produz os seguintes resultados:

dos>arg1 a b c
Il y a 3 arguments
argument n° 0=a
argument n° 1=b
argument n° 2=c

2.9. Enumerações

Uma enumeração é um tipo de dados cujo domínio de valores é um conjunto de constantes inteiras. Considere um programa que precisa de gerir notas de exames. Haveria cinco: Aprovado, Razoável, Bom, Muito Bom, Excelente. Poderíamos então definir uma enumeração para estas cinco constantes:


    Enum mention
        Passable
        AssezBien
        Bien
        TrésBien
        Excellent
    End Enum

Internamente, estas cinco constantes são representadas por números inteiros consecutivos, começando por 0 para a primeira constante, 1 para a seguinte e assim por diante. É possível declarar uma variável para assumir estes valores na enumeração:


        ' a variable that takes its values from the enumeration mentioned
        Dim maMention As mention = mention.Passable

Uma variável pode ser comparada aos diferentes valores possíveis da enumeração:


        ' test avec valeur de l'énumération
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

Pode recuperar todos os valores da enumeração:


        For Each m In mention.GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next

Tal como o tipo simples Integer é equivalente à estrutura Int32, o tipo simples Enum é equivalente à estrutura Enum. Esta classe possui um método estático GetValues que permite recuperar todos os valores de um tipo enumerado passado como parâmetro. Este parâmetro deve ser um objeto do tipo Type, que é uma classe que fornece informações sobre um tipo de dados. O tipo de uma variável v é obtido através de v.GetType(). Assim, aqui, maMention.GetType() devolve o objeto Type para a enumeração mentions, e Enum.GetValues(maMention.GetType()) devolve a lista de valores para a enumeração mentions.

É isso que o programa seguinte demonstra:


' guidelines
Option Strict On
Option Explicit On 
 
' namespaces
Imports System

Public Module enum2
 
    ' an enumeration
    Enum mention
        Passable
        AssezBien
        Bien
        TrèsBien
        Excellent
    End Enum
 
    ' test pg
    Sub Main()
 
        ' a variable that takes its values from the enumeration mentioned
        Dim maMention As mention = mention.Passable
 
        ' variable value display
        Console.Out.WriteLine("mention=" & maMention)
 
        ' test with enumeration value
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If
 
        ' list of literal mentions
        For Each m As mention In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m.ToString)
        Next
 
        ' list of full mentions
        For Each m As Integer In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next
    End Sub
End Module

Os resultados da execução são os seguintes:

dos>enum2
mention=0
Peut mieux faire
Passable
AssezBien
Bien
TrèsBien
Excellent
0
1
2
3
4

2.10. Tratamento de exceções

Muitas funções do VB.NET são capazes de gerar exceções, ou seja, erros. Quando uma função é capaz de gerar uma exceção, o programador deve tratá-la para criar programas mais resistentes a erros: deve evitar sempre que uma aplicação «trave» inesperadamente.

O tratamento de exceções segue este padrão:

try
    appel de la fonction susceptible de générer l'exception
catch  e as Exception e)
    traiter l'exception e
end try
instruction suivante

Se a função não lançar uma exceção, o programa prossegue para a instrução seguinte; caso contrário, entra no corpo da cláusula catch e, em seguida, prossegue para a instrução seguinte. Tenha em atenção os seguintes pontos:

  • e é um objeto derivado do tipo Exception. Podemos ser mais específicos utilizando tipos como IOException, SystemException, etc.: existem vários tipos de exceções. Ao escrever catch e como Exception, indicamos que queremos tratar todos os tipos de exceções. Se for provável que o código no bloco try gere vários tipos de exceções, podemos querer ser mais específicos, tratando a exceção com vários blocos catch:
try
    appel de la fonction susceptible de générer l'exception
catch e as IOException 
    traiter l'exception e
catch  e as SystemException
    traiter l'exception e
end try
instruction suivante
  • Pode adicionar uma cláusula finally aos blocos try/catch:
try
    appel de la fonction susceptible de générer l'exception
catch  e as Exception
    traiter l'exception e
finally
    code exécuté après try ou catch
end try
instruction suivante

Quer ocorra ou não uma exceção, o código na cláusula finally será sempre executado.

  • Na cláusula catch, pode não querer utilizar o objeto Exception disponível. Em vez de escrever catch e como Exception, escreve catch.
  • A classe Exception possui uma propriedade Message que contém uma mensagem detalhando o erro que ocorreu. Portanto, se quiser exibir essa mensagem, deve escrever:
catch e as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+e.Message);
    ...
end try
  • A classe Exception possui um método ToString que devolve uma cadeia de caracteres indicando o tipo de exceção e o valor da propriedade Message. Podemos, portanto, escrever:
catch  ex as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
    ...
end try

O exemplo seguinte mostra uma exceção gerada pela utilização de um elemento de matriz inexistente:


' options
Option Explicit On 
Option Strict On
 
' namespaces
Imports System
 
Module tab1
    Sub Main()
        ' declaring & initializing an array
        Dim tab() As Integer = {0, 1, 2, 3}
        Dim i As Integer
 
        ' table display with for
        For i = 0 To tab.Length - 1
            Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
        Next i
 
        ' table display with a for each
        Dim élmt As Integer
        For Each élmt In tab
            Console.Out.WriteLine(élmt)
        Next élmt
 
        ' generating an exception
        Try
            tab(100) = 6
        Catch e As Exception
            Console.Error.WriteLine(("L'erreur suivante s'est produite : " & e.Message))
        End Try
    End Sub
End Module

A execução do programa produz os seguintes resultados:

dos>exception1
tab[0]=0
tab[1]=1
tab[2]=2
tab[3]=3
0
1
2
3
L'erreur suivante s'est produite : L'index se trouve en dehors des limites du tableau.

Aqui está outro exemplo em que tratamos a exceção causada pela atribuição de uma cadeia de caracteres a um número quando a cadeia não representa um número:


' options
Option Strict On
Option Explicit On 
 
'imports
Imports System
 
Public Module console1
  Public Sub Main()
    ' We ask for the name
    System.Console.Write("Nom : ")
 
        ' reading response
    Dim nom As String = System.Console.ReadLine()
 
        ' age requested
    Dim age As Integer
    Dim ageOK As Boolean = False
    Do While Not ageOK
      ' question
      Console.Out.Write("âge : ")
      ' reading-checking response
      Try
        age = Int32.Parse(System.Console.ReadLine())
        If age < 0 Then Throw New Exception
        ageOK = True
      Catch
        Console.Error.WriteLine("Age incorrect, recommencez...")
      End Try
    Loop
 
        ' final display
    Console.Out.WriteLine("Vous vous appelez [" & nom & "] et vous avez [" & age & "] ans")
  End Sub
End Module

Alguns resultados da execução:

dos>console1
Nom : dupont
âge : 23
Vous vous appelez dupont et vous avez 23 ans
dos>console1
Nom : dupont
âge : xx
Age incorrect, recommencez...
âge : 12
Vous vous appelez dupont et vous avez 12 ans

2.11. Passagem de parâmetros para uma função

Aqui, estamos interessados em saber como os parâmetros são passados para uma função. Considere a função:


    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub    

Na definição da função, a é chamado de parâmetro formal. Está presente exclusivamente para definir a função changeInt. Poderia facilmente ter sido chamado de b. Agora, vamos considerar um exemplo de utilização desta função:


    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

Aqui, na instrução changeInt(age), age é o parâmetro real que irá passar o seu valor para o parâmetro formal a. Estamos interessados em saber como um parâmetro formal recupera o valor do parâmetro real correspondente.

2.11.1. Passagem por valor

O exemplo seguinte mostra que os parâmetros de uma função/procedimento são passados por valor por predefinição: ou seja, o valor do parâmetro real é copiado para o parâmetro formal correspondente. Trata-se de duas entidades distintas. Se a função modificar o parâmetro formal, o parâmetro real permanece inalterado.


' options
Option Explicit On 
Option Strict On
 
' passing parameters by value to a function
Imports System
 
Module param1
    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub
 
    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub
End Module

Os resultados são os seguintes:

Paramètre formel a=30
Paramètre effectif age=20

O valor 20 do parâmetro real foi copiado para o parâmetro formal a. O parâmetro formal foi então modificado. O parâmetro real permaneceu inalterado. Este modo de passagem é adequado para os parâmetros de entrada de uma função.

2.11.2. Passagem por referência

Numa passagem por referência, o parâmetro real e o parâmetro formal são a mesma entidade. Se a função modificar o parâmetro formal, o parâmetro real também é modificado. No VB.NET, o parâmetro formal deve ser precedido pela palavra-chave ByRef. Aqui está um exemplo:


' options
Option Explicit On 
Option Strict On
 
' passing parameters by value to a function
Imports System
 
Module param2
    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub
 
    Sub changeInt(ByRef a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub
End Module

e os resultados da execução:

Paramètre formel a=30
Paramètre effectif age=30

O parâmetro efetivo acompanhou a alteração no parâmetro formal. Este modo de passagem é adequado para os parâmetros de saída de uma função.