Skip to content

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

2.1. Introdução

Trataremos o VB.NET, inicialmente, como uma linguagem de programação clássica. Abordaremos os objetos posteriormente.

Em um programa, encontramos dois tipos de elementos

  • dados
  • as instruções que os manipulam

Geralmente, procura-se separar os dados das instruções:

2.2. Os dados de VB.NET

VB.NET utilizam os seguintes tipos de dados:

  1. números 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).
Caractere
System.Char
2 bytes
0 a 65.535 (sem sinal).
Data
System.DateTime
8 bytes
0:00:00 do dia 1º de janeiro de 0001 às 23:59:59 do dia 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; o menor número diferente de zero é +/-0,0000000000000000000000000001 (+/-1E-28).
Duplo
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.
Objeto
System.Object
4 bytes
Qualquer tipo pode ser armazenado em uma 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 bilhões de caracteres Unicode.

Na tabela acima, percebe-se que há 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 aos outros tipos VB e seus equivalentes na plataforma .NET. Aqui está um exemplo de programa:


Module types
    Sub Main()
        ' números inteiros
        Dim var1 As Integer = 100
        Dim var2 As Long = 10000000000L
        Dim var3 As Byte = 100
        Dim var4 As Short = 4
        ' números reais
        Dim var5 As Decimal = 4.56789D
        Dim var6 As Double = 3.4
        Dim var7 As Single = -0.000103F
        ' data
        Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
        ' booleano
        Dim var9 As Boolean = True
        ' caractere
        Dim var10 As Char = "A"c
        ' cadeia de caracteres
        Dim var11 As String = "abcde"
        ' objeto
        Dim var12 As Object = New Object
        ' exibições
        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

Integer
145, -7, &FF (hexadecimal)
Long
100000L
Double
134,789, -45E-18 (-45 × 10⁻¹⁸)
Single
134.789F, -45E-18F (-45 × 10⁻¹⁸)
Decimal
100000D
Char
"A"c
String
"hoje"
Boolean
verdadeiro, falso
date
New Date(2003, 1, 1) para 01/01/2003

Observe os seguintes pontos:

  • 100000L, o L significa que o número é considerado um inteiro longo
  • 134.789F, o F significa que o número é considerado um real de precisão simples
  • 100000D, o D significa que o número é considerado um real decimal
  • "A"c, para converter a sequência de caracteres "A" no caractere 'A'
  • A sequência de caracteres é delimitada pelo caractere ". Se a sequência precisar conter o caractere ", este deve ser repetido duas vezes, como em "abcd""e", para representar a sequência [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. Esses dados são armazenados na memória. No momento da compilação do programa, o compilador atribui a cada dado um local na memória caracterizado por um endereço e um tamanho. Ele faz isso com base nas declarações feitas pelo programador. Além disso, essas declarações permitem que o compilador detecte erros de programação. Assim, a operação x=x*2 será declarada como errada se x for uma sequência 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]. Por que declarar constantes?

  1. A leitura do programa será mais fácil se dermos à constante um nome significativo: [const taux_tva as single=0.186F]
  2. A modificação do programa será mais fácil caso a “constante” venha a mudar. Assim, no caso anterior, se a alíquota do IVA passar para 33%, a única alteração a ser feita será modificar a instrução que define seu valor: [const taux_tva as single=0.336F]. Se tivéssemos usado 0,186 explicitamente no programa, seria necessário modificar várias instruções.

2.2.3.3. Declaração de variáveis

Uma variável é identificada por um nome e está associada a um tipo de dados. VB.NET não faz distinção entre maiúsculas e minúsculas. Assim, as variáveis FIN e fin são idênticas. As variáveis podem ser inicializadas no momento de sua declaração. A sintaxe para declarar uma ou mais variáveis é:

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

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

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

nombre -> chaîne
nombre.ToString ou "" & número ou CType(número, String)
objet -> chaîne
objet.ToString
chaine -> Integer
Integer.Parse(cadeia) ou Int32.Parse
chaîne -> Long
Long.Parse (cadeia) ou Int64.Parse
chaîne -> Double
Double.Parse (cadeia)
chaîne -> Single
Single.Parse (cadeia de caracteres)

A conversão de uma string em um número pode falhar se a string não representar um número válido. Nesse caso, é gerado um erro fatal chamado exceção em VB.NET. Esse erro pode ser tratado pela seguinte cláusula 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, passa-se para a instrução seguinte; caso contrário, passa-se para o corpo da cláusula catch e, em seguida, para a instrução seguinte. Voltaremos mais tarde ao gerenciamento de exceções. Aqui está um programa que apresenta as principais técnicas de conversão entre números e cadeias de caracteres. Neste exemplo, a função exibe na tela o valor de seu parâmetro. Assim, affiche(S) exibe o valor de S na tela.


' diretrizes
Option Strict On

' espaços de nomes importados
Imports System

' o módulo de teste
Module Module1

    Sub Main()
        ' procedimento principal
        ' dados locais
        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

        ' número --> string
        affiche(CType(i, String))
        affiche(CType(l, String))
        affiche(CType(f, String))
        affiche(CType(d, String))

        'booleano --> string
        Const b As Boolean = False
        affiche(b.ToString)

        ' cadeia de caracteres --> inteiro
        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

        ' cadeia de caracteres --> inteiro longo
        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

        ' cadeia de caracteres --> 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

        ' cadeia de caracteres --> 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

    ' exibe
    Public Sub affiche(ByVal S As String)
        Console.Out.WriteLine("S=" + S)
    End Sub
End Module

Os resultados obtidos 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.

Observe-se que os números reais na forma de cadeia de caracteres devem utilizar a vírgula e não o ponto decimal. Assim, escrever-se-á Dim d As Double = -14.98, mas Dim d1 As Double = Double.Parse("100,87")

2.2.5. Matrizes de dados

Uma tabela VB.NET é um objeto que permite agrupar, sob um mesmo identificador, dados do mesmo tipo. Sua declaração é a seguinte:

Dim Tabela(n) as tipo ou Dim Tabela() as tipo = New tipo(n) {}

onde n é o índice do último elemento da matriz. A sintaxe Tableau(i) designa o dado nº i, em que i pertence ao intervalo [0,n]. Qualquer referência ao dado Tableau(i), em que i não pertença ao intervalo [0,n], provocará uma exceção. Uma matriz pode ser inicializada ao mesmo tempo em que é declarada. Nesse caso, não é necessário indicar o número do último elemento.


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

As matrizes possuem uma propriedade Length, que corresponde ao número de elementos da matriz. Veja um programa de exemplo:


Module tab0
    Sub Main()
        ' uma primeira tabela
        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

        ' um segundo quadro
        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 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 Matriz(n,m) as Tipo ou Dim Matriz(,) as Tipo = New Tipo(n,m) {}

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


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

O número de elementos em cada uma das dimensões pode ser obtido pelo método GetLenth(i), em que i=0 representa a dimensão correspondente ao primeiro índice, i=1 a dimensão correspondente ao segundo índice, … Aqui está um programa de exemplo:


Module Module2
    Sub Main()
        ' um primeiro quadro
        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

        ' um segundo quadro
        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 de 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 Matriz(n)() as Tipo ou Dim Matriz()() as Tipo = new Tipo(n)()

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


         ' uma matriz de matrizes
        Dim noms()() As String = New String(3)() {}
         ' inicialização
        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, noms(i) é uma matriz de i+1 elementos. Como noms(i) é uma matriz, noms(i).Length representa o número de elementos dela. Segue um exemplo que reúne os três tipos de matrizes que acabamos de apresentar:


' diretrizes
Option Strict On
Option Explicit On 

' importações
Imports System

' classe de teste
Module test
    Sub main()
        ' um array unidimensional inicializado
        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

        ' um array bidimensional inicializado
        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

        ' uma matriz de matrizes
        Dim noms()() As String = New String(3)() {}

        ' inicialização
        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

        ' exibição
        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

Na execução, 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

Distinguem-se

1 as instruções elementares executadas pelo computador.

2 as instruções de controle do andamento do programa.

As instruções elementares ficam claras quando se analisa a estrutura de um microcomputador e de seus periféricos.

  1. leitura de informações provenientes do teclado

  2. processamento de informações

  3. gravação de informações na tela

  4. leitura de informações de um arquivo em disco

  5. gravação de informações em um arquivo no disco

2.3.1. Gravação na tela

Existem diferentes instruções para gravar na tela:

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

onde expression representa qualquer tipo de dado que possa ser convertido em sequência de caracteres para ser exibido na tela. Nos exemplos vistos até agora, utilizamos apenas a instrução Console.Out.WriteLine(expressão).

A classe System.Console dá acesso às operações de gravação na tela (Write, WriteLine). A classe Console possui duas propriedades, Out e Error, que são fluxos de gravação do tipo StreamWriter:

  • Console.WriteLine() é equivalente a Console.Out.WriteLine() e grava no fluxo Out, normalmente associado à tela.
  • Console.Error.WriteLine() grava no fluxo Error, que também costuma estar associado à tela.

Os fluxos Out e Error estão associados por padrão à tela. Mas eles podem ser redirecionados para arquivos de texto durante a execução do programa, como veremos em breve.

2.3.2. Leitura de dados digitados no teclado

O fluxo de dados proveniente do teclado é designado pelo objeto Console.In do tipo StreamReader. Esse tipo de objeto permite ler uma linha de texto com o método ReadLine:


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

A linha digitada no teclado é armazenada na variável ligne e pode, em seguida, ser processada pelo programme.Le. O fluxo de entrada (In) pode ser redirecionado para um arquivo, assim como os fluxos de saída (Out) e de erro (Error).

2.3.3. Exemplo de entradas e saídas

Aqui está um pequeno programa para ilustrar as operações de entrada e saída do teclado/tela:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
Imports System

' módulo
Module io1
    Sub Main()
        ' gravação no fluxo de saída
        Dim obj As New Object
        Console.Out.WriteLine(("" & obj.ToString))

        ' gravação no fluxo de erros
        Dim i As Integer = 10
        Console.Error.WriteLine(("i=" & i))

        ' leitura de uma linha digitada no teclado
        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)

servem apenas para mostrar que qualquer objeto pode ser exibido. Não vamos explicar aqui o significado do que está sendo exibido.

2.3.4. Redirecionamento de E/S

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

  1. dispositivo de entrada padrão — designa, por padrão, o teclado e possui o nº 0
  2. dispositivo de saída padrão — designa, por padrão, a tela e tem o número 1
  3. dispositivo de erro padrão — designa, por padrão, a tela e possui o nº 2

No VB.NET, o fluxo de gravação Console.Out grava no dispositivo 1, o fluxo de gravação Console.Error grava no dispositivo 2 e o fluxo de leitura Console.In lê os dados provenientes do dispositivo 0. Ao executar um programa em uma janela do DOS no Windows, é possível definir quais serão os dispositivos 0, 1 e 2 para o programa em execução. Consideremos a seguinte linha de comando:

pg arg1 arg2 .. argn

Por meio dos argumentos argi do programa pg, é possível redirecionar os dispositivos de E/S padrão para arquivos:

0<in.txt
o fluxo de entrada padrão nº 0 é redirecionado para o arquivo in.txt. No programa, o fluxo Console.In, portanto, obterá seus dados do arquivo in.txt.
 
1>out.txt
redireciona a saída nº 1 para o arquivo out.txt. Isso faz com que, no programa, o fluxo Console.Out grave seus dados no arquivo out.txt
  
1>>out.txt
o mesmo, mas os dados gravados são adicionados ao conteúdo atual do arquivo out.txt.
  
2>error.txt
redireciona a saída nº 2 para o arquivo error.txt. Isso faz com que, no programa, o fluxo Console.Error grave seus dados no arquivo error.txt
  
2>>error.txt
o mesmo, mas os dados gravados são adicionados ao conteúdo atual do arquivo error.txt.
  
1>out.txt 2>error.txt
Os dispositivos 1 e 2 são ambos redirecionados para arquivos
  

Observe-se que, para redirecionar os fluxos de E/S do programa pg para arquivos, o programa pg não precisa ser modificado. É o programa OS que define a natureza dos dispositivos 0, 1 e 2. Consideremos o seguinte programa:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
Imports System

' redirecionamentos
Module console2
    Sub Main()
        ' leitura do fluxo In
        Dim data As String = Console.In.ReadLine()
        ' gravação no fluxo de saída
        Console.Out.WriteLine(("écriture dans flux Out : " + data))
        ' gravação no fluxo de erros
        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 fazer uma primeira execução:

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 e Error. Agora, vamos redirecionar os três fluxos. O fluxo In será redirecionado para o arquivo in.txt, o fluxo Out para o arquivo out.txt e o fluxo Error para o arquivo error.txt. Esse redirecionamento é feito na linha de comando 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

Percebe-se claramente que os fluxos Out e Error não gravam nos mesmos dispositivos.

2.3.5. Atribuição do valor de uma expressão a uma variável

Aqui, estamos interessados na operação variable=expression.. A expressão pode ser do tipo: aritmética, relacional, booleana ou de caracteres.

2.3.5.1. Lista de operadores

Ação
Elemento da linguagem
Arithmétique
^, –, *, /, \, Mod, +, =
Assignation
=, ^=, *=, /=, \=, +=, -=, &=
Comparaison
=, <>, <, >, <=, >=, Like, Is
Concaténation
&, +
Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse
Opérations diverses
AddressOf, GetType

2.3.5.2. Expressão aritmética

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

Arithmétique
^, –, *, /, \, Mod, +, =

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


' operadores aritméticos
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

retorna 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 diversas funções matemáticas. Aqui estão algumas delas:


Public Shared Function Sqrt(ByVal d As Double ) As Double
raiz quadrada

[Visual Basic]
Public Shared Function Cos(ByVal d As Double ) As Double
Cosseno

Public Shared Function Sin(ByVal a As Double) As Double
Senus

[Visual Basic]
Public Shared Function Tan(ByVal a As Double) As Double
Tangente

[Visual Basic]
Public Shared Function Pow(ByVal x As Double,ByVal y As Double) As Double
x elevado a y (x > 0)

[Visual Basic]
Public Shared Function Exp(ByVal d As Double) As Double
Exponencial

[Visual Basic]
Overloads Public Shared Function Log( ByVal d As Double ) As Double
Logaritmo natural

Overloads Public Shared Function Abs(ByVal value As Double ) As Double
valor absoluto
....
 

Todas essas funções estão definidas em uma classe chamada Math. Ao utilizá-las, é necessário antepor o nome da classe em que estão definidas. Assim, escreveremos:

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

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

E 
Representa a base do logaritmo natural especificada pela constante e.
  
PI 
Representa a razão entre a circunferência de um círculo e seu diâmetro, especificada pela constante π.
  
Abs 
Sobrescrito. Retorna 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 integral de dois números de 32 bits.
 
Ceiling 
Retorna o menor número inteiro maior ou igual ao número especificado.
 
Cos 
Retorna o cosseno do ângulo especificado.
 
Cosh 
Retorna o cosseno hiperbólico do ângulo especificado.
 
DivRem
Sobrescrito. Retorna 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 especificado por outro.
 
Log 
Sobrescrito. Retorna o logaritmo de um número especificado.
 
Log10 
Retorna o logaritmo em base 10 de um número especificado.
 
Max 
Sobrescrito. Retorna o maior de dois números especificados.
 
Min 
Sobrecarga. Retorna o menor dos dois números.
 
Pow 
Retorna um número especificado elevado à potência especificada.
 
Round 
Sobrescrito. Retorna o número mais próximo do valor especificado.
 
Sign 
Sobrescrito. Retorna 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 ela existe para diversos 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 desses tipos, existe uma definição separada da função Abs. Diz-se, então, que ela está sobrecarregada.

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

A prioridade dos operadores na avaliação de uma expressão aritmética é a seguinte (da mais alta à mais baixa):

Categoria
Operadores
Primaire
Todas as expressões sem operadores: funções, parênteses
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -

2.3.5.4. Expressões relacionais

Os operadores são os seguintes:

Comparaison
=, <>, <, >, <=, >=, 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 de objetos. Todos esses operadores têm a mesma prioridade. Eles são avaliados da esquerda para a direita. O resultado de uma expressão relacional é um valor booleano.

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


' espaços de nomes
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 de sua execução:

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

Sejam dois caracteres C1 e C2. É possível compará-los com os operadores: <, <=, =, <>, >, >=. Nesse caso, são comparados os valores Unicode dos caracteres, que são números. De acordo com a ordem Unicode, temos as seguintes relações:

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

As cadeias de caracteres são comparadas caractere por caractere. A primeira desigualdade encontrada entre dois caracteres implica uma desigualdade no mesmo sentido nas cadeias. Com essas explicações, o leitor é convidado a analisar os resultados do programa anterior.

2.3.5.5. Expressões booleanas

Os operadores são os seguintes:

Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse

Not: e lógico, Or: ou lógico, Not: negação, Xor: ou 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 prioridade desses operadores entre si é a seguinte:

NOT logique
Not
AND logique
E, AndAlso
OR logique
Ou, OrElse
XOR logique
XOR

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

2.3.5.6. Operações com bits

Por um lado, encontramos os mesmos operadores que os booleanos, com a mesma prioridade. Também há dois operadores de deslocamento: << e >>. Sejam i e j dois inteiros.

i<<n
desloca i n bits para a esquerda. Os bits que entram 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 a operação lógica ET entre i e j, bit a bit.
i | j
realiza a operação lógica bit a bit entre i e j, conforme definido em OU.
~i
incrementa i em 1
i^j
gera o OU e o EXCLUSIF a partir de i e j

Seja o seguinte programa:


Module operationsbit
    Sub main()
        ' manipulação de bits
        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

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 a uma 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:

combinaison d'opérateurs
^=, *=, /=, \=, +=, -=, &=

2.3.5.8. Prioridade geral dos operadores

Categoria
Operadores
Primaire
Todas as expressões sem operador
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -
Concaténation
&
Déplacement
<<, >>
Relationnel
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is
NOT logique
Não
AND logique
E, AndAlso
OR logique
Ou, OrElse
XOR logique
XOR

Quando um operando é colocado entre dois operadores de mesma prioridade, 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 executadas da esquerda para a direita. A prioridade e a associatividade podem ser controladas por meio de expressões entre parênteses.

2.3.5.9. Conversões de tipo

Existe um conjunto de funções predefinidas que permitem converter de um tipo de dados para outro. A lista delas é a seguinte:

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

Essas funções aceitam como argumento uma expressão numérica ou uma sequência de caracteres. O tipo do resultado é indicado na tabela a seguir:

função
resultado
Intervalo de valores do parâmetro da função
CBool
Booleano
Qualquer sequência de caracteres ou expressão numérica válida.
CByte
Byte
0 a 255; as frações são arredondadas.
CChar
Caractere
Qualquer expressão String válida; o valor pode estar entre 0 e 65.535.
CDate
Data
Qualquer representação válida da data e da hora.
CDbl
Double
-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 sem casas decimais. O intervalo de valores dos números com 28 casas decimais é
+/-7,9228162514264337593543950335. O menor número diferente de zero é 0,0000000000000000000000000001.
CInt
Inteiro
de -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
Single
-3,402823E+38 a -1,401298E-45 para valores negativos; 1,401298E-45 a 3,402823E+38 para valores positivos.
CStr
String
Os valores retornados pela função Cstr dependem do argumento expressão.

Veja um programa de exemplo:


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 de 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 é possível utilizar a função CType(expression, type), conforme mostrado no programa a seguir:


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

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 o controle do andamento do programa

2.4.1. Parar

O método Exit, definido na classe Environment, permite interromper a execução de um programa:


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

interrompe o processo em andamento e retorna o valor exitCode ao processo pai. O valor de exitCode pode ser utilizado por este. No DOS, essa variável de status é retornada como DOS na variável de sistema ERRORLEVEL, cujo valor pode ser verificado em um arquivo em lote. No Unix, é a variável $? que recupera o valor de exitCode.

    Environment.Exit(0)

interromperá a execução do programa com um valor de status igual a 0.

2.4.2. Estrutura de escolha simples

if condition then
    actions_alors
else
    actions_sinon
end if
  • cada ação está em uma linha
  • a cláusula else pode estar ausente.

É possível aninhar as estruturas de seleção, conforme mostra o exemplo a seguir:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
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 de casos

A sintaxe é a seguinte:

select case expression
    case liste_valeurs1
        actions1
case liste_valeurs2
        actions2
...
case else
        actions_sinon
end select
  • O tipo de [expression] 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 estar ausente.
  • [liste_valeursi] são valores possíveis da expressão. [listes_valeursi] representa uma lista de condições: condição1, condição2, ..., condiçãox. Se [expression] verificar uma das condições, as ações associadas à cláusula [liste_valeursi] serão executadas. As condições podem assumir a seguinte forma:
  • val1 to val2: verdadeiro se [expression] pertencer ao domínio [val1,val2]
  • val1: verdadeiro se [expression] for igual a val1
  • is > val1: verdadeiro se [expression] > val1. A palavra-chave [is] pode estar ausente
  • o mesmo vale para os operadores =, <, <=, >, >=, <>
  • somente as ações relacionadas à primeira condição verificada são executadas.

Consideremos o seguinte programa:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
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

Ele apresenta os seguintes resultados:

i est < 15

2.4.4. Estrutura de repetição

2.4.4.1. Número conhecido de repetições


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

As ações são executadas para cada um dos valores assumidos pela variável [counter]. Consideremos o seguinte programa:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
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 número conhecido de iterações é a seguinte:


For Each element [ As datatype ] In groupe
   [ actions ]
Next [ element ]
  • groupe é uma coleção de objetos. A coleção de objetos que já conhecemos é o array
  • datatype é o tipo dos objetos da coleção. No caso de um array, seria o tipo dos elementos do array
  • element é uma variável local do loop que assumirá sucessivamente, como valor, todos os valores da coleção.

Assim, o código a seguir:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
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 várias estruturas em VB.NET para este caso.


Do { While | Until } condition
   [ statements ]
Loop

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


Do
   [ statements ]
Loop { While | Until } condition

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


While condition
   [ statements ]
End While

O loop é executado enquanto a condição for verdadeira. O loop pode nunca ser executado. Os loops a seguir calculam a soma dos primeiros 10 números inteiros.


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
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 para gerenciamento de loop

exit do
sai de um loop do ... loop
exit for
sai de um loop for

2.5. A estrutura de um programa VB.NET

Um programa VB.NET que não utilize classes definidas pelo usuário nem funções além da função principal Main poderá ter a seguinte estrutura:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
Imports espace1
Imports ....

Module nomDuModule
    Sub main()
....
    End Sub
End Module
  • A diretiva [Option Explicit on] exige a declaração de variáveis. Na VB.NET, essa declaração não é obrigatória. Uma variável não declarada é, nesse caso, do tipo Object.
  • A diretiva [Option Strict on] proíbe qualquer conversão de tipos de dados que possa resultar em perda de dados, bem como qualquer conversão entre tipos numéricos e cadeias de caracteres. Nesse caso, é necessário utilizar explicitamente funções de conversão.
  • O programa importa todos os espaços de nomes de que necessita. Ainda não abordamos esse conceito. Nos programas anteriores, frequentemente encontramos instruções do tipo:
        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á explorá-lo sistematicamente sempre que encontrar uma classe que não conheça. Ele repetirá a busca em todos os namespaces declarados até encontrar a classe procurada. Escreve-se, então:


' espaços de nomes
Imports System
....

        Console.Out.WriteLine(unechaine)

Um exemplo de programa poderia ser o seguinte:


' opções
Option Explicit On 
Option Strict On

'espaços de nomes
Imports System

' módulo principal
Module main1
    Sub main()
        Console.Out.WriteLine("main1")
    End Sub
End Module

O mesmo programa pode ser escrito da seguinte maneira:


' opções
Option Explicit On 
Option Strict On

'espaços de nomes
Imports System

' classe de teste
Public Class main2
    Public Shared Sub main()
        Console.Out.WriteLine("main2")
    End Sub
End Class

Aqui, utilizamos o conceito de classe, que será apresentado no próximo capítulo. Quando uma classe desse tipo contém um procedimento estático (compartilhado) chamado main, este é executado. Se introduzimos essa sintaxe aqui, é porque a linguagem gêmea do VB.NET, que é o C#, conhece apenas o conceito de classe, c.a.d, segundo o qual todo código executado pertence necessariamente a uma classe. A noção de classe pertence à programação orientada a objetos. Impor isso na concepção de todo programa é um pouco inadequado. Vemos isso aqui na versão 2 do programa anterior, onde somos levados a introduzir um conceito de classe e de método estático onde não há necessidade. Portanto, daqui em diante, só introduziremos o conceito de classe quando for necessário. Nos demais casos, utilizaremos o conceito de módulo, como na versão 1 acima.

2.6. Compilação e execução de um programa VB.NET

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


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
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

Suponhamos que ele esteja em um arquivo chamado [boucles1.vb]. Para compilá-lo, 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, ele 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] gera um arquivo .exe executável pela máquina virtual .NET:

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

2.7. O exemplo IMPOTS

Propõe-se escrever um programa que permita calcular o imposto de um contribuinte. Consideramos o caso simplificado de um contribuinte que tenha apenas seu salário para declarar:

  • calcula-se o número de cotas do empregado nbParts = nbEnfants/2 + 1 se ele for solteiro, nbEnfants/2 + 2 se for casado, onde nbEnfants é o número de filhos.
  • se tiver pelo menos três filhos, ele tem mais meia parcela
  • calcula-se sua renda tributável R = 0,72 * S, onde S é seu salário anual
  • calcula-se seu coeficiente familiar QF = R / nbParts
  • calcula-se seu imposto I. Consideremos a tabela a seguir:
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
4.900
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
49.062

Cada linha possui 3 campos. Para calcular o imposto I, procura-se a primeira linha em que QF ≤ campo1. Por exemplo, se QF = 23000, será encontrada a linha

    24740        0.15        2072.5

O imposto I é, então, igual a 0,15*R - 2072,5*nbParts. Se QF for tal que a relação QF <= campo1 nunca for verificada, então serão utilizados os coeficientes da última linha. Aqui:

    0                0.65        49062

o que resulta no imposto I = 0,65 * R - 49.062 * nbParts. O programa VB.NET correspondente é o seguinte:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
Imports System

Module impots
    ' ------------ principal
    Sub Main()

        ' tabelas de dados necessárias para o cálculo do imposto
        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}

        ' recupera-se o estado civil
        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"

        ' número de filhos
        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
        ' salário
        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
        ' cálculo do número de cotas
        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
        ' renda tributável
        Dim Revenu As Decimal
        Revenu = 0.72D * Salaire

        ' quociente familiar
        Dim QF As Decimal
        QF = Revenu / NbParts

        ' identificação da faixa de imposto correspondente a 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
        ' o imposto
        Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)

        ' o resultado é exibido
        Console.Out.WriteLine(("Impôt à payer : " & impots))
    End Sub
End Module

O programa é compilado em uma janela do DOS por meio do comando:

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 gera um executável impots.exe. É importante observar que o impots.exe não é diretamente executável pelo processador. Na verdade, ele contém código intermediário que só é executável em uma 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. Argumentos do programa principal

A rotina principal Main pode aceitar como parâmetro uma matriz de cadeias de caracteres:


    Sub main(ByVal args() As String)

O parâmetro args é uma matriz de cadeias de caracteres que recebe os argumentos passados na linha de comando ao chamar o programa.

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

Se o programa P for executado com o comando: P arg0 arg1 … argn e se a procedimento Main do programa P estiver declarada da seguinte forma:


    Sub main(ByVal args() As String)

teremos arg(0)="arg0", arg(1)="arg1" … Veja um exemplo:


' diretrizes
Option Strict On
Option Explicit On 

' espaços de nomes
Imports System

Module arg
    Sub main(ByVal args() As String)
        ' número de argumentos
        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. As enumerações

Uma enumeração é um tipo de dados cujo domínio de valores é um conjunto de constantes inteiras. Consideremos um programa que precisa gerenciar as notas de uma prova. Seriam cinco: Passável, AssezBien, Bom, TrèsBien, Excelente. Poderíamos, então, definir uma enumeração para essas cinco constantes:


    Enum mention
        Passable
        AssezBien
        Bien
        TrésBien
        Excellent
    End Enum

Internamente, essas cinco constantes são codificadas por números inteiros consecutivos, começando por 0 para a primeira constante, 1 para a seguinte, e assim por diante. Uma variável pode ser declarada para assumir esses valores na enumeração:


         ' uma variável que assume valores da enumeração mencionada
        Dim maMention As mention = mention.Passable

É possível comparar uma variável com os diferentes valores possíveis da enumeração:


         ' teste com valor da enumeração
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

É possível obter todos os valores da enumeração:


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

Da mesma forma que o tipo simples Integer é equivalente à estrutura Int32, o tipo simples Enum é equivalente à estrutura Enum. Essa classe possui um método estático GetValues que permite obter todos os valores de um tipo enumerado passado como parâmetro. Esse parâmetro deve ser um objeto do tipo Type, que é uma classe de informação sobre o tipo de um dado. O tipo de uma variável v é obtido por meio de v.GetType(). Portanto, aqui maMention.GetType() retorna o objeto Type da enumeração mentions e Enum.GetValues(maMention.GetType()) a lista de valores da enumeração mentions.

É o que mostra o programa a seguir:


' diretrizes
Option Strict On
Option Explicit On 

' espaços de nomes
Imports System

Public Module enum2

    ' uma enumeração
    Enum mention
        Passable
        AssezBien
        Bien
        TrèsBien
        Excellent
    End Enum

    ' página de teste
    Sub Main()

        ' uma variável que assume valores da enumeração mencionada
        Dim maMention As mention = mention.Passable

        ' exibição do valor da variável
        Console.Out.WriteLine("mention=" & maMention)

        ' teste com valor da enumeração
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

        ' lista de menções literais
        For Each m As mention In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m.ToString)
        Next

        ' lista de menções completas
        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. Gerenciamento de exceções

Muitas funções VB.NET podem gerar exceções, ou seja, erros. Quando uma função pode gerar uma exceção, o programador deve gerenciá-la com o objetivo de obter programas mais resistentes a erros: é preciso sempre evitar que um aplicativo “trave” de forma inesperada.

O gerenciamento de uma exceção é feito de acordo com o esquema a seguir:

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 gerar uma exceção, passa-se para a instrução seguinte; caso contrário, passa-se para o corpo da cláusula catch e, em seguida, para a instrução seguinte. Observe os seguintes pontos:

  • e é um objeto derivado do tipo Exception. É possível ser mais preciso utilizando tipos como IOException, SystemException, etc.: existem vários tipos de exceções. Ao escrever catch e as Exception, indicamos que queremos tratar todos os tipos de exceções. Se o código da cláusula try for suscetível de gerar vários tipos de exceções, podemos querer ser mais precisos, tratando a exceção com várias cláusulas 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
  • É possível adicionar uma cláusula `finally` às cláusulas 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

Haja ou não exceção, o código da cláusula finally será sempre executado.

  • Na cláusula catch, talvez não se queira utilizar o objeto Exception disponível. Em vez de escrever `catch e as Exception`, escreve-se então `catch`.
  • A classe Exception possui uma propriedade Message, que é uma mensagem detalhando o erro ocorrido. Portanto, se quisermos exibi-la, escreveremos:
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 retorna uma sequência de caracteres indicando o tipo da exceção, bem como o valor da propriedade Message. Assim, poderemos escrever:
catch  ex as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
    ...
end try

O exemplo a seguir mostra uma exceção gerada pelo uso de um elemento de tabela inexistente:


' opções
Option Explicit On 
Option Strict On

' espaços de nomes
Imports System

Module tab1
    Sub Main()
        ' declaração e inicialização de uma matriz
        Dim tab() As Integer = {0, 1, 2, 3}
        Dim i As Integer

        ' exibição de matriz com um for
        For i = 0 To tab.Length - 1
            Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
        Next i

        ' exibição de matriz com um for each
        Dim élmt As Integer
        For Each élmt In tab
            Console.Out.WriteLine(élmt)
        Next élmt

        ' geração de uma exceção
        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 se lida com a exceção causada pela atribuição de uma sequência de caracteres a um número, quando a sequência não representa um número:


' opções
Option Strict On
Option Explicit On 

'importações
Imports System

Public Module console1
  Public Sub Main()
    ' Solicitação do nome
    System.Console.Write("Nom : ")

        ' leitura da resposta
    Dim nom As String = System.Console.ReadLine()

        ' solicitação da idade
    Dim age As Integer
    Dim ageOK As Boolean = False
    Do While Not ageOK
      ' pergunta
      Console.Out.Write("âge : ")
      ' Leitura e verificação da resposta
      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

        ' exibição final
    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, vamos nos concentrar na forma como os parâmetros são passados para uma função. Consideremos 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. Ele existe apenas para fins da definição da função changeInt. Ele poderia muito bem ter sido chamado de b. Consideremos agora uma utilização dessa 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(idade), age é o parâmetro efetivo que transmitirá seu valor ao parâmetro formal a. Nos interessa saber como um parâmetro formal recupera o valor do parâmetro efetivo que lhe corresponde.

2.11.1. Passagem por valor

O exemplo a seguir mostra que os parâmetros de uma função/procedimento são, por padrão, passados por valor: ou seja, o valor do parâmetro efetivo é copiado para o parâmetro formal correspondente. Temos duas entidades distintas. Se a função modificar o parâmetro formal, o parâmetro efetivo não sofre nenhuma alteração.


' opções
Option Explicit On 
Option Strict On

' passagem de parâmetros por valor para uma função
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 obtidos são os seguintes:

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

O valor 20 do parâmetro efetivo foi copiado para o parâmetro formal a. Este foi, em seguida, modificado. O parâmetro efetivo, por sua vez, permaneceu inalterado. Esse modo de passagem é adequado para os parâmetros de entrada de uma função.

2.11.2. Passagem por referência

Na passagem por referência, o parâmetro efetivo e o parâmetro formal são uma única e mesma entidade. Se a função modificar o parâmetro formal, o parâmetro efetivo também será modificado. Em VB.NET, o parâmetro formal deve ser precedido pela palavra-chave ByRef. Veja um exemplo:


' opções
Option Explicit On 
Option Strict On

' passagem de parâmetros por valor para uma função
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 modificação do parâmetro formal. Esse modo de passagem é adequado para parâmetros de saída de uma função.