2. Noções básicas da linguagem VB.NET
2.1. Introdução
Abordamos o VB.NET, em primeiro lugar, como uma linguagem de programação clássica. Abordaremos os objetos mais tarde.
Num programa, encontramos duas coisas
- dados
- as instruções que os manipulam
Normalmente, procura-se separar os dados das instruções:
![]() |
2.2. Os dados de VB.NET
VB.NET utilizam os seguintes tipos de dados:
- números inteiros, reais e decimais
- caracteres e cadeias de caracteres
- valores booleanos
- datas
- objetos
2.2.1. Os 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 de 1 de janeiro de 0001 a 23:59:59 de 31 de dezembro de 9999. |
Decimal | System.Decimal | 16 octetos | 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). |
Duplo | System.Double | 8 octetos | -1,79769313486231E+308 a -4,94065645841247E-324 para os valores negativos; 4,94065645841247E-324 a 1,79769313486231E+308 para os 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 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 os valores negativos; 1,401298E-45 a 3,402823E+38 para os valores positivos. |
String | System.String (classe) | 0 a cerca de 2 mil milhões de caracteres Unicode. |
Na tabela acima, verifica-se que existem dois tipos possíveis para um inteiro de 32 bits: Integer e System.Int32. Ambos os tipos são intercambiáveis. O mesmo se aplica aos outros tipos VB e aos seus equivalentes na plataforma .NET. Eis 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 dos dados literais
145, -7, &FF (hexadecimal) | |
100000L | |
134,789, -45E-18 (-45 × 10⁻¹⁸) | |
134.789F, -45E-18F (-45 10⁻¹⁸) | |
100000D | |
"A"c | |
"hoje" | |
verdadeiro, falso | |
New Date(2003, 1, 1) para 01/01/2003 |
É importante destacar 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 número real de precisão simples
- 100000D, o D significa que o número é considerado um número real decimal
- "A"c, para converter a cadeia de caracteres "A" no carácter 'A'
- A cadeia de caracteres está entre aspas. Se a cadeia tiver de conter o caractere ", este deve ser duplicado, como em "abcd""e", para representar a cadeia [abcd"e].
2.2.3. Declaração dos 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. 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. Faz-o com base nas declarações feitas pelo programador. Além disso, estas permitem ao compilador detetar erros de programação. Assim, a operação x=x*2 será declarada como errada se x for, por exemplo, uma cadeia de caracteres.
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?
- A leitura do programa será mais fácil se tivermos atribuído à constante um nome significativo: [const taux_tva as single=0.186F]
- A modificação do programa será mais fácil se a «constante» vier a mudar. Assim, no caso anterior, se a taxa de IVA passar para 33%, a única alteração a fazer será modificar a instrução que define o seu valor: [const taux_tva as single=0.336F]. Se tivéssemos utilizado 0,186 explicitamente no programa, seria necessário alterar inúmeras 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 distingue 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 da 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. As conversões entre números e cadeias de caracteres
nombre.ToString ou "" & número ou CType(número, String) | |
objet.ToString | |
Integer.Parse(cadeia) ou Int32.Parse | |
Long.Parse (cadeia) ou Int64.Parse | |
Double.Parse (cadeia) | |
Single.Parse (cadeia de caracteres) |
A conversão de uma cadeia de caracteres num número pode falhar se a cadeia não representar um número válido. Nesse caso, é gerado um erro fatal denominado «exceção» em VB.NET. Este erro pode ser tratado através da 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 então 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 à gestão 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 no ecrã o valor do seu parâmetro. Assim, affiche(S) exibe o valor de S no ecrã.
' diretivas
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 --> cadeia
affiche(CType(i, String))
affiche(CType(l, String))
affiche(CType(f, String))
affiche(CType(d, String))
'booleano --> cadeia
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 --> duplo
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.
Note-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. As tabelas de dados
Uma tabela VB.NET é um objeto que permite agrupar, sob um único identificador, dados do mesmo tipo. A 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 tabela. 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 que é declarada. Nesse caso, não é necessário indicar o número do último elemento.
Dim entiers() As Integer = {0, 10, 20, 30}
Os tabuletos têm uma propriedade Length, que corresponde ao número de elementos do tabuleto. Eis 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 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 Tabela(n,m) as Tipo ou Dim Tabela(,) 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 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 através do 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, …Eis 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 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 Tabela(n)() as Tipo ou Dim Tabela()() 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. Estas matrizes não são criadas durante a declaração acima. O exemplo abaixo 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 com i+1 elementos. Como noms(i) é uma matriz, noms(i).Length é o seu número de elementos. Segue-se um exemplo que reúne os três tipos de matrizes que acabámos de apresentar:
' diretivas
Option Strict On
Option Explicit On
' importações
Imports System
' classe de teste
Module test
Sub main()
' um tabuleiro 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 tabuleiro de duas dimensões 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
' um array de arrays
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
' visualizaçã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
Ao executar o código, 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. As instruções básicas do VB.NET
Distinguem-se
1 as instruções elementares executadas pelo computador.
2 as instruções de controlo do andamento do programa.
As instruções elementares tornam-se evidentes quando se analisa a estrutura de um microcomputador e dos seus periféricos.
![]() |
-
leitura de informações provenientes do teclado
-
processamento de informações
-
gravação de informações no ecrã
-
leitura de informações provenientes de um ficheiro no disco
-
gravação de informações num ficheiro no disco
2.3.1. Escrita no ecrã
Existem várias instruções para escrever no ecrã:
Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)
onde expression representa 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 dá acesso às operações de escrita no ecrã (Write, WriteLine). A classe Console tem 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 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, por predefinição, ao ecrã. No entanto, podem ser redirecionados para ficheiros de texto durante a execução do programa, como veremos em breve.
2.3.2. Leitura de dados introduzidos pelo teclado
O fluxo de dados proveniente do teclado é designado pelo objeto Console.In do tipo StreamReader. Este 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 pode ser redirecionado para um ficheiro, tal como os fluxos de saída e de erro.
2.3.3. Exemplo de entradas e saídas
Eis um pequeno programa que ilustra as operações de entrada e saída do teclado/ecrã:
' opções
Option Explicit On
Option Strict On
' espaços de nomes
Imports System
' módulo
Module io1
Sub Main()
' gravação no fluxo Out
Dim obj As New Object
Console.Out.WriteLine(("" & obj.ToString))
' gravação no fluxo Error
Dim i As Integer = 10
Console.Error.WriteLine(("i=" & i))
' leitura de uma linha introduzida pelo 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:
As instruções
Dim obj As New Object
Console.Out.WriteLine(obj.ToString)
servem apenas para demonstrar que qualquer objeto pode ser exibido. Não pretendemos aqui explicar o significado do que é exibido.
2.3.4. Redirecionamento de E/S
No DOS/Windows, existem três dispositivos padrão denominados:
- dispositivo de entrada padrão — designa, por predefinição, o teclado e tem o n.º 0
- dispositivo de saída padrão — designa, por predefinição, o ecrã e tem o n.º 1
- dispositivo de erro padrão — designa, por predefinição, o ecrã e tem o n.º 2
No VB.NET, o fluxo de escrita Console.Out escreve no dispositivo 1, o fluxo de escrita Console.Error escreve no dispositivo 2 e o fluxo de leitura Console.In lê os dados provenientes do dispositivo 0. Ao iniciar um programa numa 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:
Através dos argumentos argi do programa pg, é possível redirecionar os dispositivos de E/S padrão para ficheiros:
o fluxo de entrada padrão n.º 0 é redirecionado para o ficheiro in.txt. No programa, o fluxo Console.In irá, portanto, obter os seus dados do ficheiro in.txt. | |||
redireciona a saída n.º 1 para o ficheiro out.txt. Isto significa que, no programa, o fluxo Console.Out gravará os seus dados no ficheiro out.txt | |||
o mesmo, mas os dados gravados são adicionados ao conteúdo atual do ficheiro out.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 | |||
o mesmo, mas os dados gravados são adicionados ao conteúdo atual do ficheiro 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, o programa pg não precisa de ser alterado. É 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 do 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. Vamos agora redirecionar os três fluxos. O fluxo In será redirecionado para um ficheiro in.txt, o fluxo Out para o ficheiro out.txt e o fluxo Error para o ficheiro error.txt. Esta redireção é efetuada na linha de comandos da seguinte forma
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. Atribuição do valor de uma expressão a uma variável
Vamos analisar aqui a 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 |
^, –, *, /, \, Mod, +, = | |
=, ^=, *=, /=, \=, +=, -=, &= | |
=, <>, <, >, <=, >=, Like, Is | |
&, + | |
Not, And, Or, Xor, AndAlso, OrElse | |
AddressOf, GetType |
2.3.5.2. Expressão aritmética
Os operadores das expressões aritméticas são os seguintes:
^, –, *, /, \, 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
dá os seguintes resultados:
Existem várias funções matemáticas. Aqui estão algumas delas:
| raiz quadrada |
| Cosseno |
| Senus |
| Tangente |
| x elevado a y (x>0) |
| Exponencial |
| Logaritmo natural |
| valor absoluto |
Todas estas funções estão definidas numa classe .NET chamada Math. Ao utilizá-las, é necessário antepor-lhes o nome da classe onde estão definidas. Assim, escrever-se-á:
A definição completa da classe Math é a seguinte:
Representa a base do logaritmo natural especificada pela constante e. | |||
Representa a relação entre a circunferência de um círculo e o seu diâmetro, especificada pela constante π. | |||
Sobrescrito. Devolve o valor absoluto de um número especificado. | |||
Devolve o ângulo cujo cosseno é o número especificado. | |||
Devolve o ângulo cujo seno é o número especificado. | |||
Devolve o ângulo cuja tangente é o número especificado. | |||
Devolve o ângulo cuja tangente é o quociente de dois números especificados. | |||
Gera o produto integral de dois números de 32 bits. | |||
Devolve o menor número inteiro maior ou igual ao número especificado. | |||
Devolve o cosseno do ângulo especificado. | |||
Devolve o coseno hiperbólico do ângulo especificado. | |||
Sobrescrito. Devolve o quociente de dois números, passando o resto como parâmetro de saída. | |||
Devolve e elevado à potência especificada. | |||
Devolve o maior número inteiro menor ou igual ao número especificado. | |||
Devolve o resto da divisão de um número especificado por outro. | |||
Sobrecarregada. Devolve o logaritmo de um número especificado. | |||
Devolve o logaritmo em base 10 de um número especificado. | |||
Sobrescrito. Devolve o maior de dois números especificados. | |||
Sobrecarga. Devolve o menor de dois números. | |||
Devolve um número especificado elevado à potência especificada. | |||
Sobrescrito. Devolve o número mais próximo do valor especificado. | |||
Sobrescrito. Devolve um valor que indica o sinal de um número. | |||
Devolve o seno do ângulo especificado. | |||
Devolve o seno hiperbólico do ângulo especificado. | |||
Devolve a raiz quadrada de um número especificado. | |||
Devolve a tangente do ângulo especificado. | |||
Devolve a tangente hiperbólica do ângulo especificado. | |||
Quando uma função é declarada como «sobrecarregada», 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, 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. 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 elevada à mais baixa):
Categoria | Operadores |
Todas as expressões sem operadores: funções, parênteses | |
^ | |
+, - | |
*, / | |
\ | |
Mod | |
+, - |
2.3.5.4. Expressões relacionais
Os operadores são os seguintes:
=, <>, <, >, <=, >=, 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 estes operadores têm a mesma prioridade. 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 da sua execução:
Sejam dois caracteres C1 e C2. É possível compará-los com os operadores: <, <=, =, <>, >, >=. São entã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 a caractere. A primeira desigualdade encontrada entre dois caracteres implica uma desigualdade no mesmo sentido nas cadeias. Com estas explicações, convida-se o leitor a analisar os resultados do programa anterior.
2.3.5.5. Expressões booleanas
Os operadores são os seguintes:
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 destes operadores entre si é a seguinte:
Not | |
E, AndAlso | |
Ou, OrElse | |
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 operadores booleanos, com a mesma prioridade. Encontramos também dois operadores de deslocamento: << e >>. Sejam i e j dois inteiros.
desloca i n bits para a esquerda. Os bits que entram são zeros. | |
desloca i n bits para a direita. Se i for um inteiro com sinal (signed char, int, long), o bit de sinal é preservado. | |
realiza a operação lógica ET entre i e j, bit a bit. | |
realiza a operação lógica bit a bit entre i e j, como em OU. | |
incrementa i em 1 | |
cria 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
A sua execução produz os seguintes resultados:
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:
^=, *=, /=, \=, +=, -=, &= |
2.3.5.8. Prioridade geral dos operadores
Categoria | Operadores |
Todas as expressões sem operadores | |
^ | |
+, - | |
*, / | |
\ | |
Mod | |
+, - | |
& | |
<<, >> | |
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is | |
Not | |
E, AndAlso | |
Ou, OrElse | |
XOR |
Quando um operando é colocado entre dois operadores com a 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 através de expressões entre parênteses.
2.3.5.9. As conversões de tipo
Existem várias funções predefinidas que permitem converter um tipo de dados noutro. A lista é a seguinte:
Estas funções aceitam como argumento uma expressão numérica ou uma cadeia de caracteres. O tipo do resultado é indicado na tabela seguinte:
função | resultado | Intervalo de valores do parâmetro da função |
Booleano | Qualquer cadeia de caracteres ou expressão numérica válida. | |
Byte | 0 a 255; as frações são arredondadas. | |
Caractere | Qualquer expressão String válida; o valor pode estar compreendido entre 0 e 65 535. | |
Data | Qualquer representação válida da data e da hora. | |
Double | -1,79769313486231E+308 a -4,94065645841247E-324 para valores negativos; 4,94065645841247E-324 a 1,79769313486231E+308 para valores positivos. | |
Decimal | +/-79 228 162 514 264 337 593 543 950 335 para os 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. | |
Inteiro | -2 147 483 648 a 2 147 483 647; as frações são arredondadas. | |
Número longo | -9 223 372 036 854 775 808 a 9 223 372 036 854 775 807; as frações são arredondadas. | |
| Objeto | Qualquer expressão válida. |
Curto | -32 768 a 32 767; as frações são arredondadas. | |
Single | -3,402823E+38 a -1,401298E-45 para os valores negativos; 1,401298E-45 a 3,402823E+38 para os valores positivos. | |
String | Os valores devolvidos pela função Cstr dependem do argumento expressão. |
Eis 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 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 é possível utilizar a função CType(expression, type), tal como 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
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 controlo 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 curso e devolve o valor exitCode ao processo pai. O valor de exitCode pode ser utilizado por este último. Em DOS, esta variável de estado é devolvida a DOS na variável de sistema ERRORLEVEL, cujo valor pode ser verificado num ficheiro batch. No Unix, é a variável $? que recupera o valor de exitCode.
interromperá a execução do programa com um valor de estado igual a 0.
2.4.2. Estrutura de escolha simples
- cada ação está numa linha
- a cláusula else pode estar ausente.
É possível aninhar as estruturas de escolha, tal como mostra o exemplo seguinte:
' 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:
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:
- 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] sã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 se aplica aos operadores =, <, <=, >, >=, <>
- apenas as ações relacionadas com a 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
Este programa produz os seguintes resultados:
2.4.4. Estrutura de repetição
2.4.4.1. Número de repetições conhecido
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:
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 ]
- groupe é uma coleção de objetos. A coleção de objetos que já conhecemos é o tabuleiro
- datatype é o tipo dos objetos da coleção. No caso de um tabuuleiro, seria o tipo dos elementos do tabuuleiro
- element é uma variável local do ciclo que irá assumir sucessivamente, como valor, todos os valores da coleção.
Assim, o código seguinte:
' 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:
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 ciclo repete-se 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 repete-se 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 repete-se enquanto a condição for verdadeira. O ciclo pode nunca ser executado. Os ciclos seguintes calculam todos 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
2.4.4.3. Instruções de gestão de ciclo
sai de um ciclo do ... loop | |
sai de um ciclo «for» |
2.5. A estrutura de um programa VB.NET
Um programa VB.NET que não utilize uma classe definida pelo utilizador nem outras 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] obriga à declaração das variáveis. Na VB.NET, tal não é obrigatório. 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 abordámos este conceito. Nos programas anteriores, deparámo-nos frequentemente com instruções do tipo:
Na verdade, deveríamos ter escrito:
onde System é o espaço de nomes que contém a classe [Console]. Ao importar o espaço de nomes [System] com uma instrução Imports, o VB.NET irá explorá-lo sistematicamente sempre que encontrar uma classe que não conheça. Irá repetir a pesquisa em todos os espaços de nomes 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 forma:
' 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 capítulo seguinte. Quando uma classe deste tipo contém um procedimento estático (partilhado) chamado main, este é executado. Se introduzimos esta sintaxe aqui, é porque a linguagem gémea do VB.NET, que é o C#, só conhece o conceito de classe, c.a.d, segundo o qual todo o código executado pertence necessariamente a uma classe. A noção de classe pertence à programação orientada a objetos. Impô-la na conceção de qualquer programa é um pouco desajeitado. Vemo-lo 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. Assim, daqui em diante, só introduziremos o conceito de classe quando for necessário. Nos restantes casos, utilizaremos o conceito de módulo, tal 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 se encontre num ficheiro chamado [boucles1.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 executável pela máquina virtual .NET:
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 o seu salário para declarar:
- calcula-se o número de quotas do trabalhador nbParts = nbEnfants/2 + 1 se não for casado, nbEnfants/2 + 2 se for casado, em que nbEnfants é o número de filhos que tem.
- se tiver pelo menos três filhos, tem mais meia quota
- calcula-se o seu rendimento tributável R = 0,72 * S, em que S é o seu salário anual
- calcula-se o seu coeficiente familiar QF = R / nbParts
- calcula-se o seu imposto I. Consideremos a seguinte tabela:
12620,0 | 0 | 0 |
13 190 | 0,05 | 631 |
15640 | 0,1 | 1290,5 |
24 740 | 0,15 | 2072,5 |
31 810 | 0,2 | 3309,5 |
39 970 | 0,25 | 4900 |
48 360 | 0,3 | 6898,5 |
55 790 | 0,35 | 9316,5 |
92 970 | 0,4 | 12106 |
127 860 | 0,45 | 16 754,5 |
151 250 | 0,50 | 23 147,5 |
172 040 | 0,55 | 30710 |
195 000 | 0,60 | 39312 |
0 | 0,65 | 49062 |
Cada linha tem 3 campos. Para calcular o imposto I, procura-se a primeira linha em que QF <= campo1. Por exemplo, se QF = 23000, encontrar-se-á a linha
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 são utilizados os coeficientes da última linha. Neste caso:
o que resulta no imposto I = 0,65*R - 49062*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}
' obtém-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 quotas
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
' rendimento tributável
Dim Revenu As Decimal
Revenu = 0.72D * Salaire
' quociente familiar
Dim QF As Decimal
QF = Revenu / NbParts
' determinaçã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)
' é apresentado o resultado
Console.Out.WriteLine(("Impôt à payer : " & impots))
End Sub
End Module
O programa é compilado numa janela do DOS através de:
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 executável impots.exe. É importante referir que o impots.exe não é diretamente executável pelo processador. Na realidade, 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. 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 comandos aquando da chamada do programa.
- args.Length é o número de elementos da matriz args
- args(i) é o elemento i da matriz
Se executarmos o programa P com o comando: P arg0 arg1 … argn e se a rotina Main do programa P estiver declarada da seguinte forma:
Sub main(ByVal args() As String)
teremos arg(0)="arg0", arg(1)="arg1" … Eis 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:
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 tem de gerir as classificações de um exame. Seriam cinco: Passável, AssezBien, Bom, TrèsBien, 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 codificadas por números inteiros consecutivos, começando por 0 para a primeira constante, 1 para a seguinte, etc. Uma variável pode ser declarada para assumir estes valores na enumeração:
' uma variável que obtém os seus 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. Esta classe possui um método estático GetValues que permite obter todos os valores de um tipo enumerado que seja passado como parâmetro. Este 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 através de v.GetType(). Assim, neste caso, a função maMention.GetType() devolve o objeto Type da enumeração mentions e a função Enum.GetValues(maMention.GetType()) a lista de valores da enumeração mentions.
É isso que o programa seguinte demonstra:
' diretivas
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 obtém os seus 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 o 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:
2.10. Gestão de exceções
Muitas funções VB.NET podem gerar exceções, ou seja, erros. Quando uma função é suscetível de gerar uma exceção, o programador deve gerir essa exceção com o objetivo de obter programas mais resistentes a erros: deve-se evitar sempre o «bloqueio» inesperado de uma aplicação.
A gestão de uma exceção é feita de acordo com o seguinte esquema:
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 então 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. É importante notar 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, indica-se que se pretende gerir 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, pode ser desejável ser mais preciso, gerindo 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
Quer haja ou não uma exceção, o código da cláusula finally será sempre executado.
- Na cláusula catch, pode não se querer 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 contém uma mensagem detalhando o erro que ocorreu. Assim, se se pretender exibir essa mensagem, escrever-se-á:
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 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 seguinte mostra uma exceção gerada pela utilização 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 um tabuleiro
Dim tab() As Integer = {0, 1, 2, 3}
Dim i As Integer
' exibição de um tabuleiro com um «for»
For i = 0 To tab.Length - 1
Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
Next i
' exibição de um tabuleiro 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.
Eis outro exemplo em que se trata a exceção provocada pela atribuição de uma cadeia de caracteres a um número, quando a cadeia 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-se o 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 : 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
Vamos analisar aqui a forma como os parâmetros são passados a 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 é designado como um parâmetro formal. Este parâmetro existe apenas para efeitos da definição da função changeInt. Poderia muito bem ter sido denominado b. Consideremos agora uma 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(idade), age é o parâmetro efetivo que irá transmitir o seu valor ao parâmetro formal a. Estamos interessados na forma como um parâmetro formal recupera o valor do parâmetro efetivo que lhe corresponde.
2.11.1. Passagem por valor
O exemplo seguinte mostra-nos que os parâmetros de uma função/procedimento são, por predefiniçã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 alterar o parâmetro formal, o parâmetro efetivo não sofre qualquer 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:
O valor 20 do parâmetro efetivo foi copiado para o parâmetro formal a. Este foi posteriormente alterado. O parâmetro efetivo, por sua vez, 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 efetivo e o parâmetro formal são uma única e mesma entidade. Se a função alterar o parâmetro formal, o parâmetro efetivo também é alterado. Em VB.NET, o parâmetro formal deve ser precedido pela palavra-chave ByRef. Eis 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:
O parâmetro efetivo acompanhou a alteração do parâmetro formal. Este modo de passagem é adequado para os parâmetros de saída de uma função.

