Você está na página 1de 38

Curso de Especialização Tecnológica:

Aplicações Informáticas de Gestão

Estruturas de Dados Estáticas

Doutora Ana Maria Madureira

Fevereiro de 2009

FORESP – Associação Para a Formação e Especialização Tecnológica


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

ÍNDICE:
1. INTRODUÇÃO ................................................................................................................................... 1
2. CONCEITOS GERAIS....................................................................................................................... 1
3. ESTRUTURAS DE CONTROLO DE REPETIÇÃO....................................................................... 1
3.1. ESTRUTURAS DE REPETIÇÃO CONTADAS ........................................................................................... 2
3.1.1. A estrutura de repetição For ... Next ........................................................................................ 2
3.1.2. A estrutura de repetição For Each … Next .............................................................................. 3
3.2. ESTRUTURAS DE REPETIÇÃO CONDICIONAIS...................................................................................... 4
3.3. ESTRUTURAS DE REPETIÇÃO ENCAIXADAS ........................................................................................ 7
4. SUBROTINAS E FUNÇÕES.............................................................................................................. 8
4.1. SUBROTINAS ...................................................................................................................................... 8
4.2. FUNÇÕES ............................................................................................................................................ 9
4.3. PASSAGEM DE ARGUMENTOS ........................................................................................................... 10
5. ESTRUTURAS DE DADOS INDEXADAS .................................................................................... 12
5.1. VECTORES OU ARRAYS UNIDIMENSIONAIS ...................................................................................... 12
5.1.1. Declaração de vectores .......................................................................................................... 13
5.1.2. Inicializar um array................................................................................................................ 14
5.1.3. Obtenção do último índice de um vector: GetUpperBound() ................................................. 14
5.1.4. Redimensionamento de vectores - Instrução ReDim .............................................................. 14
5.1.5. Processamento de vectores..................................................................................................... 14
5.1.6. Passagem de vectores como argumentos de funções e rotinas............................................... 16
5.1.7. Pesquisa em Vectores ............................................................................................................. 18
5.1.8. Ordenação de vectores ........................................................................................................... 20
5.2. MATRIZES – ARRAYS BIDIMENSIONAIS ............................................................................................ 22
5.2.1. Declaração de matrizes.......................................................................................................... 23
5.2.2. Declaração sem indicação das dimensões ............................................................................. 23
5.2.3. Redimensionamento................................................................................................................ 23
5.2.4. Passagem de matrizes como argumentos de funções e rotinas .............................................. 24
5.2.5. Obtenção do limite máximo (índice)....................................................................................... 24
5.2.6. Processamento de Matrizes .................................................................................................... 24
6. STRINGS ........................................................................................................................................... 28
6.1. FUNÇÕES DE MANIPULAÇÃO DE STRINGS ........................................................................................ 28
6.1.1. Trim, LTrim e RTrim .............................................................................................................. 28
6.1.2. Len.......................................................................................................................................... 28
6.1.3. Right(), Left().......................................................................................................................... 29
6.1.4. Mid()....................................................................................................................................... 29
6.1.5. InStr() ..................................................................................................................................... 29
6.1.6. UCase(), LCase().................................................................................................................... 30
6.2. EXEMPLOS RESOLVIDOS ................................................................................................................... 30
6.3. EXERCICIOS COMPLEMENTARES ...................................................................................................... 32
6.3.1. 1. Estruturas de Dados Mono-indexadas (Vectores).............................................................. 32
6.3.2. Estruturas de Dados Bi-indexadas (Matrizes)........................................................................ 32
6.3.3. Strings..................................................................................................................................... 33
7. BIBLIOGRAFIA ............................................................................................................................... 34
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

1. Introdução
O Visual Basic em geral e a versão 2008, em particular, possui um conjunto de características que
visam ajudar tanto o programador principiante como o experiente a desenvolver aplicações de forma
simples, rápida e divertida.
Neste contexto e no âmbito do módulo Estrutura de Dados Estáticas, pretende-se que, no final
da frequência da disciplina, os alunos sejam capazes de:
• compreender os conceitos fundamentais das Ciências da Computação e aplicá-los em
exemplos concretos;
• compreender a importância das estruturas de repetição na programação de computadores;
• saber quando usar as diferentes estruturas de controlo de repetição;
• analisar problemas, conceber algoritmos através de uma abordagem modular descendente e
desenvolver os algoritmos através de uma metodologia de programação procedimental
estruturada e recorrendo a estruturas de controlo de repetição e estruturas de dados
indexadas;
• reconhecer a importância da utilização de vectores;
• compreender os algoritmos de manipulação de vectores e strings;
• codificar os programas em Visual Basic e testar as aplicações resultantes.

Refira-se que nos exemplos apresentados as aplicações são do tipo consola considerando-se ser
esta a melhor forma de se aprender uma linguagem de programação , uma vez que o objectivo
principal está nos elementos da linguagem de programação.

2. Conceitos Gerais
Um dos aspectos fundamentais na definição de estruturas de controlo de repetição está relacionada
com a garantia de término. Uma das características de um programas é este deve ser finito.
Por iteração consideramos repetição. Em programação, o termo iteração é usado para designar cada
uma das vezes que as instruções do corpo de um ciclo são executadas.
Um contador ou variável contadora é uma variável que realiza uma contagem, normalmente
associada ao nº de vezes que o ciclo é executado. A variável contadora é iniciada a zero fora do ciclo e
incrementada dentro do ciclo. O contador pode ou não ser usado na condição de término do ciclo.
Um acumulador ou variável acumuladora permite efectuar ao soma de um conjunto de valores,
armazenando somas ou totais parciais. A semelhança do contador é iniciada a zero fora do ciclo sendo-
lhe adicionado um valor (positivo ou negativo), normalmente, em cada iteração. O acumulador pode
ou não ser usado na condição de término do ciclo.

3. Estruturas de Controlo de Repetição


A capacidade de repetir instruções por parte do computador está directamente ligada à capacidade
de tomada de decisões.

Ana Madureira -1-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Enquanto as estruturas de controlo condicional permitem alterar o fluxo do programa mas sem
deixar de executar de forma linear uma dada sequência de instruções, as estruturas de controlo de
repetição (também conhecidas por ciclos) permitem repetir um dado conjunto de instruções o número
de vezes que for necessário.
Existem diversas variantes de ciclos, diferindo umas das outras pela forma como é controlada a
execução das instruções contidas no corpo do ciclo.
Genericamente, pode dizer-se que uma estrutura de controlo repetitiva (ou ciclo) assegura a
execução repetida de um dado conjunto de instruções dependendo do resultado do teste de uma
determinada condição de funcionamento.

Figura 1 - Diagrama de fluxo possível de um ciclo

As estruturas de controlo de repetição permitem a execução repetida de um bloco de instruções


definidas no seu corpo. A continuação da execução do corpo do ciclo depende da avaliação do valor
uma expressão lógica. Normalmente classificam-se em estruturas de repetição contadas (For … Next
e For Each … Next) e condicionais (Do While … Loop e Do Until … Loop).

3.1. Estruturas de Repetição Contadas


Este tipo de controlo de repetição permite repetir um dado conjunto de instruções um número
predeterminado de vezes. Nem sempre é possível saber à partida quantas vezes as instruções contidas
no corpo do ciclo devem ser repetidas. Nesse caso, deverão ser utilizadas outras estruturas de controlo
de repetição.

3.1.1. A estrutura de repetição For ... Next


A sintaxe desta estrutura de controlo de repetição é a seguinte:
For contador = início To fim [Step passo]
< Instruções >
Next [contador]

Esta estrutura baseia-se na existência dum contador que incrementa automaticamente o conteúdo
de variável, chamada variável de controlo do ciclo, cada vez que o ciclo funciona, isto é, cada vez que as
instruções contidas no corpo do ciclo são executadas. O valor inicial dessa variável é início.
A inicialização da variável contadora, o seu incremento/decremento e a verificação da condição de
funcionamento do ciclo (variável <= fim) é da responsabilidade da própria estrutura de controlo. O

Ana Madureira -2-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

programador deve, apenas, especificar qual o valor de início e de fim (ou, por outras palavras, o número
de vezes que o ciclo vai funcionar) e quais as instruções que o ciclo vai repetir (o corpo do ciclo).
O conteúdo da variável de controlo do ciclo pode ser utilizado por instruções contidas no corpo do
ciclo, mas não deve, sob pretexto algum, ser modificado por estas instruções, sob pena de se perder o
controlo do funcionamento do ciclo.
A estrutura de controlo verifica no início de cada iteração (repetição) do ciclo se a condição de
funcionamento do ciclo é ainda verdadeira. Caso seja falsa, o ciclo terminará, e o programa passará a
executar as instruções que se seguem.
A inclusão de Step é opcional: caso se pretenda que o conteúdo da variável contadora seja
incrementada uma unidade de cada vez, é desnecessário especificar passo, caso contrário, passo permitirá
incrementar o valor de variável de um valor diferente da unidade (positivo ou negativo).
Caso o valor de passo seja positivo a variável contadora será incrementada. Se pretendermos, no
entanto, efectuar um decremento, deverá ser utilizado um valor negativo para passo. Obviamente, nesse
caso, a condição de funcionamento do ciclo passará a ser variável >= fim.

Exemplos:
Factorial de um Numero com incremento Factorial de um Numero com decremento
Factorial = 1 Factorial = 1
For num = 1 To Numero For num = Numero To 1 Step -1
Factorial = Factorial * num Factorial = Factorial * num
Next num Next num

3.1.2. A estrutura de repetição For Each … Next


À semelhança do ciclo For ... Next o ciclo For Each … Next também permite repetir um bloco
de instruções um nº predefinido de vezes. Enquanto o For ... Next é controlado por uma variável
contadora o For Each … Next é mais vocacionado para a repetição de um bloco de instruções para
todos os elementos de um grupo ou colecção (como por exemplo um vector).
Neste caso, o conceito de valor inicial e de valor final deixa de ter significado e na maiorias dos
casos é desconhecido o número de elementos que compõem essa colecção.
A sintaxe genérica é a seguinte:

For Each elemento [As tipo_dado] In grupo


< Instruções >
Next [elemento]

Uma colecção é um conjunto ou grupo de elementos relacionados. Existem dois grupos de


colecções: as predefinidas pelo VB e as definidas pelo programador. Um exemplo de colecção é o tipo
de dados string. Uma string é uma colecção de caracteres.

Ana Madureira -3-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplo:
‘Contar vogais de uma string
Module ContarVogais

Sub Main()
Console.Write("Introduza uma string: ")
Dim str As String = Console.ReadLine
Dim contaVogais As Integer = 0

For Each letra As Char In str


' Compara letras da string em minúsculas.
Select Case Char.ToLower(letra)
Case "a"c, "e"c, "i"c, "o"c, "u"c
contaVogais += 1
End Select
Next
Console.WriteLine("A string possui " &
contaVogais & " vogais")
End Sub

End Module

3.2. Estruturas de Repetição Condicionais


Nem sempre é possível conhecer à partida o número de vezes que o ciclo vai ser executado, ou seja,
quantas vezes as instruções contidas no corpo do ciclo vão ser repetidas. Nesses casos, não é viável a
utilização de ciclos controlados por contador, devendo-se usar uma técnica diferente: estruturas de
repetição condicionais ou também designadas por ciclos controlados por valor sentinela.
Por sentinela deve entender-se um valor limite que assinala o fim de uma dada sequência de valores,
mas que não esteja incluído nesse conjunto de valores.
Por exemplo, se o utilizador estiver a introduzir os dados referentes a um conjunto de alunos
identificados pelos seus números de matrícula, a introdução de um número com menos de 6 dígitos
(no caso do ISEP) como por exemplo o valor 1, permitirá indicar ao programa que a presente
sequência de introdução de dados deve terminar.
A selecção do valor sentinela é da responsabilidade do programador, devendo ser escolhido fora do
intervalo possível de valores a introduzir, podendo ainda, ter-se em atenção a possível ocorrência de
valores fora desse intervalo que possam resultar de algum eventual erro de digitação. O valor sentinela
escolhido não deve pois ser passível de facilmente ocorrer por mero acidente.
As estruturas Do .. Loop repetem um conjunto de instruções enquanto (While) uma condição for
verdadeira ou até (Until) uma condição se tornar verdadeira. O processo de repetição é controlado por
uma condição booleana. A condição de controlo pode estar localizada no inicio ou no fim do ciclo. A
distinção entre uma condição localizada no inicio do ciclo (Do While/DoUntil) refere-se a que neste
caso o bloco de instruções é executado zero ou mais vezes enquanto0 se a condição for colocada no
fim o bloco de instruções é executado pelo menos uma vez. Assim sendo, podemos dizer que em
Visual Basic existem 4 alternativas:

Ana Madureira -4-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

1 - Duas em que a avaliação da expressão lógica é feita à entrada do ciclo


• Do While … Loop (DWL), o teste da expressão lógica no início, o ciclo é executado
enquanto a expressão for verdadeira
Do While < condição >
<bloco de instruções>
Loop

• Do Until … Loop (DUL), teste da expressão lógica no início, o ciclo é executado até
que a expressão seja verdadeira
Do Until < condição >
<bloco de instruções>
Loop

Exemplo:
Programa que determina a soma dos algarismos de um número inteiro:

Do Until … Loop Do While … Loop

Sub Main() Sub Main()


Dim n, alg, s As Integer Dim n, alg, s As Integer
s = 0 n = CInt(Console.ReadLine())
n = CInt(Console.ReadLine()) Do While n <> 0
Do Until n = 0 alg = n Mod 10
alg = n Mod 10 s = s + alg
s = s + alg n = n \ 10
n = n \ 10 Loop
Loop Console.WriteLine("Soma: " & s)
Console.WriteLine("Soma: " & s) End Sub
End Sub

2 - Duas em que a avaliação da expressão lógica é feita à saída do ciclo:


• Do …Loop While (DLW), teste da expressão lógica no fim, executa enquanto a
expressão for verdadeira
Do
<bloco de instruções>
Loop While <condição>

• Do … Loop Until (DLU), teste da expressão lógica no fim, executa até que a expressão
seja verdadeira
Do
<bloco de instruções>
Loop Until < condição >

Ana Madureira -5-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplo:
Programa que determina a soma dos algarismos de um número inteiro:

Do … Loop Until Do … Loop While

Sub Main() Sub Main()


Dim n, alg, s As Integer Dim n, alg, s As Integer
n = n =
CInt(Console.ReadLine()) CInt(Console.ReadLine())
Do Do
alg = n Mod 10 alg = n Mod 10
s = s + alg s = s + alg
n = n \ 10 n = n \ 10
Loop Until n = 0 Loop While n <> 0
Console.WriteLine("Soma: " Console.WriteLine("Soma: "
& s) & s)
End Sub nd Sub

O exemplo apresentado podia ser resolvido de forma satisfatória por qualquer um dos ciclos mas
nem sempre é assim
É possível identificar duas situações distintas:
1 - O ciclo deve ser executado pelo menos uma vez, então o teste deve ser executado no
fim do ciclo, através de DLW e DLU
2 - O ciclo pode não ser executado uma única vez, então o teste deve ser no início do
ciclo, através de DWL e DUL
É possível, transformar um ciclo Do While em Do Until negando a condição de funcionamento. A
escolha entre Do While e Do Until é subjectiva; são equivalentes se a expressão lógica for negada.
Como vimos anteriormente a estrutura de repetição For ... Next permite realizar um ciclo
controlado por um variável contadora que é incrementada ou decrementada até atingir um valor final
pré-fixado. É possível obter este efeito usando estruturas de controlo alternativas, como seja a
estrutura Do While … Loop ou o Do Until … Loop. Dizemos neste caso que os ciclos são
controlados por contador.
Um ciclo controlado por contador baseado na estrutura Do While … Loop pode assumir a
seguinte forma genérica:
contador = valor_inicial
Do While contador <= valor_final
' Corpo do Ciclo
contador = contador + 1
Loop

Questões a ter em conta na construção de um ciclo Do While … Loop controlado por contador:
• Especificar a condição de funcionamento do ciclo
• Inicializar a variável contadora
• Incluir no corpo do ciclo uma instrução que incremente ou decremente a variável
contadora
Estas acções encontram-se asseguradas de forma automática no caso da estrutura
For ... To ... Next. Em todas as outras formas de ciclos, é da responsabilidade do programador
assegurar-se de que tais acções são correctamente executadas.

Ana Madureira -6-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

3.3. Estruturas de Repetição Encaixadas


Á semelhança das estruturas de decisão If e Select Case é possível encadear dois ou mais ciclos.
Vimos anteriormente que o corpo de um ciclo era constituído pelo conjunto de instruções que o ciclo
irá executar repetidamente. Foi também dito que nesse conjunto de instruções se poderiam incluir
qualquer tipo de instruções, mesmo constituindo outras estruturas de controlo repetitivo. Prosseguindo
com os exemplos apresentados na secção anterior, abaixo se pode ver um exemplo de uma utilização
de um ciclo dentro de outro. Diz-se que se encontram encaixados ou emparelhados um dentro do
outro.

Exemplos:
Cálculo do factorial de uma sequência de valores terminada por um valor negativo.
Factorial de uma sequência de valores
Module Module1

Sub Main()
Dim num, contador As Integer
Dim factorial As Long

num = InputBox("Introduza um numero positivo não nulo", "Calculo de factoriais")


Do Until num < 0
'calculo do factorial de num
factorial = 1
contador = 1
Do Until contador > num
factorial = factorial * contador
contador = contador + 1
Loop
MsgBox("factorial de " & num & "=" & factorial)

'Leitura do número seguinte


num = InputBox("Introduza um número positivo não nulo", "Cálculo de
factoriais")
Loop
End Sub
End Module

Este exemplo utiliza apenas ciclos controlados por sentinela. Quando se usa um ciclo controlado
por contador encadeado num outro ciclo controlado por contador, há que ter o cuidado de criar e
utilizar diferentes variáveis de controlo para cada ciclo.
O programa seguinte apresenta todos os números capicuas existentes num intervalo dado pelo
utilizador (os limites do intervalo devem ser validados). Um número é capicua se for igual à sequência
dos seu algarismos, por ordem inversa. É preciso verificar se cada um dos números do intervalo é
capicua.
Números capicuas
Module Module1
Sub Main()
Dim num, aux, cap, alg, inf, sup As Integer
Do
inf = InputBox("Introduza valor inferior:", "Capicuas")
Loop Until inf > 0
Do
sup = InputBox("Introduza valor Superior:", "Capicuas")
Loop Until sup > inf
For num = inf To sup
aux = num
cap = 0
Do While aux > 0
alg = aux Mod 10
aux \= 10
cap = cap * 10 + alg
Loop
If cap = num Then MsgBox("É capicua " & num)
Next
End Sub
End Module

Ana Madureira -7-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

4. Subrotinas e Funções
Um programa em é constituído por um conjunto de módulos, que irão ser resolvidos de forma
independente entre si, com o propósito de contribuírem em conjunto para a realização da tarefa
principal, que é a resolução do problema proposto.
A esses módulos dá-se o nome de funções, subrotinas, subprogramas ou procedimentos.
Uma Subrotinas/Função é então um módulo independente de código, que irá executar uma tarefa
específica. Consoante a especificidade da tarefa atribuída à função, esta terá ou não de devolver um
valor.
Em Visual Basic podemos distinguir dois tipos de rotinas:
• Função (Function)– baseada no conceito matemático de função, em que o resultado é
necessariamente um único valor
• Subrotina (Sub)– implementando um mecanismo de “subcontratação” de tarefas, não sendo
representável por um valor

4.1. Subrotinas
No Visual Basic existem procedimentos que são executados em resposta às acções do utilizador,
como por exemplo quando o utilizador prime um botão (Click). Esses procedimentos são conhecidos
por "event procedures" - procedimentos de evento.
No entanto, existem outros procedimentos que não estão directamente associados a qualquer
evento e que para serem executados têm que ser explicitamente invocados. Estes são procedimentos
mais gerais - “general procedures”.
A principal razão para se usar este tipo de procedimentos tem a ver com o facto de, por vezes,
diferentes procedimentos de evento necessitarem de executar o mesmo conjunto de acções
(instruções). Nestas situações o ideal é colocar esse conjunto de acções num procedimento para evitar
a duplicação de código e tornar a aplicação mais fácil de manter.
A sintaxe para declarar um procedimento é a seguinte:
Sub Nome_subrotina([<lista de parâmetros>])
<instruções>
End Sub

A chamada ou evocação á subrotina é expressa da seguinte forma:


Nome_subrotina([<lista de argumentos>])
A lista de argumentos é o conjunto de variáveis às quais são passados valores no momento da
chamada do procedimento, valores esses que serão usados pelo procedimento durante as suas
operações. Para cada argumento deve ser indicado o seu tipo e no caso de haver mais do que um
argumento devem ser separados por vírgulas.
De cada vez que a subrotina é chamada, as instruções entre Sub e End Sub são executadas.
É possível terminar a execução de uma subrotina e devolver o controlo ao ponto do programa
onde foi feita a chamada antes de se atingir a instrução End Sub: usa-se a instrução Exit Sub.

Ana Madureira -8-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Module Module1
argumento
Sub Main()
Dim n1, n2 As Integer
n1 = 5 soma é uma variável local; o âmbito da
n2 = 2 variável é o do procedimento; a variável só
existe durante a execução da subrotina
' Chamada
MostraSoma(n1, n2)
Console.ReadKey() Tipo de parâmetro
Nome do parâmetro
End Sub
'Declaração
Sub MostraSoma(ByVal num1 As Integer, ByVal num2 As Integer)
Dim soma As Integer
Tipo de valor do parâmetro
soma = num1 + num2

Console.WriteLine(num1 & " + " & num2 & " = " & soma)
End Sub
End Module

4.2. Funções
O Visual Basic tal como qualquer outra linguagem de programação inclui um vasto conjunto de
funções predefinidas. Para além destas funções o VB permite definir outras funções usando para o
efeito a sintaxe seguinte:

Function Nome_função([lista_parâmetros]) As TipoDados


<instruções>
Return <expressão>
End Function

A chamada ou evocação á função é expressa da seguinte forma:

Var = Nome_função([lista_parâmetros])

As funções distinguem-se dos procedimentos porque devolvem um valor. Sendo assim, e tal como
nas variáveis, as funções também têm um tipo de dados que será o tipo do valor a retornar.
O valor, normalmente resultante de algumas operações e/ou cálculos, é devolvido por atribuição a
uma "variável" com o mesmo nome da função.

Ana Madureira -9-


Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Module Module1

Sub Main()
Dim n As Integer
n = InputBox("Valor de n: ")

If n > 0 Then
MsgBox("factorial de " & n & "=" & fact(n))
Else
MsgBox("Erro: dados inválidos!")
End If

End Sub

Function fact(ByVal n As Integer) As Double


Dim f As Double = 1
For k As Integer = 2 To n
f = f * k
Next
Return f ' Retorna valor da função
End Function

End Module

4.3. Passagem de argumentos


Torna-se importante distinguir os conceitos de parâmetros e argumentos. Por argumentos, entende-
se a lista de variáveis, valores ou expressões colocada entre parêntesis aquando da invocação da função.
Por parâmetros entende-se a lista de declaração de variáveis no cabeçalho da função. Há uma
correspondência entre os argumentos e os parâmetros, pois os valores ou endereços dos primeiros
serão atribuídos aos segundos.
Em Visual Basic os argumentos podem ser passados de duas maneiras: por referência ou por
valor. Na prática referem o mecanismo de passagem de argumentos indicando se os métodos 1 podem
ou não alterar o valor dos argumentos.
Numa invocação por referência, o que é passado para os parâmetros da função são os endereços
das variáveis utilizadas como argumentos da invocação da função, o que significa que qualquer
alteração efectuada pela função provoca uma alteração do argumento. Quando uma variável é passada
por referência quaisquer alterações feitas ao conteúdo dessa variável dentro do método far-se-ão
reflectir na variável usada na chamada ao procedimento. Para isso é necessário usar a palavra ByRef
antes de cada argumento, na lista de argumentos quando o procedimento for declarado.
Dado que uma função apenas pode retornar um único valor, a passagem por referência é por vezes
usada para ultrapassar a limitação, permitindo assim devolver mais do um valor por cada evocação da
função.
Numa invocação de uma função cujos argumentos sejam passados por valor, os parâmetros
constituem-se como variáveis autónomas que serão inicializadas com os valores dos argumentos.
Assim sendo, qualquer alteração no valor de um parâmetro não se repercute no valor do respectivo
argumento.
Quando não se pretende que uma determinada variável seja alterada esta deverá ser passada ao
procedimento por valor. Para isso é necessário usar a palavra ByVal antes de cada argumento, na lista
de argumentos quando o procedimento for declarado.

1 Por método pretendemos referir-nos a funções, procedimentos, subrotinas e/ou métodos (na POO).

Ana Madureira - 10 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Passagem por valor Passagem por referência

Module Module1 Module Module1


Parâmetros Argumentos
Sub Main() Sub Main()
Dim a = 10.0, b = 20.0 Dim a = 10.0, b = 20.0
Console.WriteLine("Antes da troca:a={0} b={1}", a, b) Console.WriteLine("Antes da troca : a={0} b={1}", a, b)

Troca(a, b) Troca(a, b)

Console.WriteLine("Depois da troca: a={0} b={1}", a, b) Console.WriteLine("Depois da troca: a={0} b={1}", a, b)


End Sub End Sub

Public Sub Troca(ByVal x As Double, ByVal y As Double) Public Sub Troca(ByRef x As Double, ByRef y As Double)
' Os valores das variáveis a e b são copiados para x e y. ' As variáveis x e y correspondem às variáveis a e b.
Dim tmp As Double Dim tmp As Double
A saída do programa será: A saída do programa será:
tmp = x tmp = x
Antes da troca: a=10 b=20 Antes da troca: a=10 b=20
x = y x = y
Depois da troca: a=10 b=20 Depois da troca: a=20 b=10
y = tmp y = tmp
' Os valores de x e y foram trocados. ' Os valores de x e y foram trocados.
' Os valores de a e b mantêm-se inalterados! ' Os valores de a e b também.
End Sub End Sub

End Module End Module

O exemplo que se segue apresenta o factorial e o valor da fórmula de Stirling (uma aproximação à
função factorial) e ainda a diferença, em percentagem, entre ambos.

Funções Factorial e Fórmula de Stirling.


Module Module1

Sub Main()

' Mostra uma tabela com o factorial e o valor de Stirling.


' (inclui a diferença, em percentagem entre os valores).
Console.WriteLine("{0,2}{1,12}{2,12}{3,8}", "n", "n!", "Stirling", "% Dif.")
For i As Integer = 1 To 12
Console.WriteLine("{0,2}{1,12}{2,12}{3,8:F4}", i, Factorial(i),
FactorialFormulaStirling(i), (Factorial(i) - FactorialFormulaStirling(i)) / Factorial(i))
Next
Console.ReadKey()
End Sub

' Calcula o factorial de um número inteiro.


Public Function Factorial(ByVal n As Integer) As Decimal
' Usa Decimal para armazenar números grandes.
' (a letra D especifica o tipo Decimal).
Dim fact As Decimal = 1D

For i As Integer = 2 To n
fact *= i
Next

Return fact
End Function

' Calcula uma aproximação ao factorial através da fórmula de Stirling.

Public Function FactorialFormulaStirling(ByVal n As Integer) As Decimal


' Fórmula de Stirling:
' n! = sqrt(2*PI*n)*(n/e)^n

' Ao valor é adicionado 0.5 por forma a o arredondar para inteiro.


Return Fix(CDec(Math.Sqrt(2 * Math.PI * n) * (n / Math.E) ^ n + 0.5))
End Function

End Module

Ana Madureira - 11 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

A saída será:

5. Estruturas de Dados Indexadas


5.1. Vectores ou Arrays Unidimensionais
Até agora, temos trabalhado essencialmente com variáveis que podemos classificar como
individuais, isto é, cada variável podendo conter ao mesmo tempo apenas um só valor. Como essas
variáveis não podem conter simultaneamente mais que um dado, a atribuição de um novo valor a essa
variável implica a destruição do valor anteriormente nela contido.
Mediante a utilização de um novo tipo de variáveis, as variáveis do tipo Array (Vector), passa a ser
possível armazenar na mesma variável múltiplos valores desde que sejam do mesmo tipo. Estamos,
portanto, a utilizar agora variáveis que se podem classificar como variáveis múltiplas.
Um vector é um conjunto de elementos do mesmo tipo agrupados numa lista e referenciadas por
um único nome, sendo diferenciados pela posição que ocupam .
Cada um dos elementos de um vector unidimensional é identificado por um índice (posição
sequencial), escrito entre parêntesis rectos . A numeração dos índices começa em 0 e termina em N-
1(sendo N a dimensão do vector). Os elementos de um vector estão armazenados em posições de
memória consecutivas.
Um elemento de um vector pode ser um objecto de qualquer tipo, incluindo outro vector. Por isso
é possível simular vectores bidimensionais.
Um vector é uma lista ordenada de variáveis simples do mesmo tipo. Pode também ser visto como
um conjunto de variáveis simples agrupadas. Todos as variáveis membros desse vector partilham o
mesmo nome (o nome do vector). São identificadas individualmente mediante o valor dum índice,
que determina qual a sua posição dentro do vector.
Os valores do índice devem obrigatoriamente ser do tipo Integer. O primeiro valor do índice é
zero e o último dimensão-1.
Um elemento de um vector é identificado utilizando o nome do vector seguido do valor do índice
dentro de parêntesis:
nome_vector ( índice )

Ana Madureira - 12 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplos:

var_Multipla(3) ‘ 4º elemento do vector ‘var_Multipla’


var_Multipla(7) ‘ 8º e último elemento do vector ‘var_Multipla’
notas(14) ‘ 15º elemento do vector ‘notas’
nomes(0) ‘ 1º elemento do vector ‘nomes’

5.1.1. Declaração de vectores


Como qualquer outra variável, uma variável do tipo Array deve também ser declarada (criada) antes
de poder ser usada. Para tal, deve ser usada a instrução Dim, que reserva espaço em memória
suficiente para armazenar o número previsto de elementos do vector 2 . Uma das formas de utilizar a
instrução Dim para declarar vectores é a seguinte:

Dim <nomeVector>(<indíceSuperior>) As <tipoVar>

Ao ser criado, os elementos do vector são inicializados tal como qualquer variável simples:
• Tipos numéricos com zero
• Strings com a palavra reservada Nothing
• O primeiro elemento do vector ocupa o indíce 0
• Tamanho ou dimensão do vector: <indíceSuperior> + 1

Exemplos:
Dim var_Multipla(8) As Integer
Dim notas(30) As Single
Dim nomes(100) As String
Nota: num_elementos não se refere ao valor máximo que a variável índice pode assumir (7, no caso
do vector var_Multipla) mas sim ao número de elementos do vector (8, neste caso).
Usando esta forma na declaração de vectores, o processo de indicar o limite inferior faz-se de
forma implícita: por defeito assume-se como limite inferior do índice o valor zero (ou 1 se tal for
especificado mediante a instrução Option Base 1).
Uma forma alternativa de utilizar a instrução Dim para declarar vectores implica a utilização da
palavra reservada To, permitindo especificar o menor e o maior valor que o índice pode assumir:

Dim nome_vector(menorÍndice To maiorÍndice) As Tipo

2 Adicionalmente, a instrução Dim atribui valores iniciais a todos os elementos do vector (zeros no caso de vectores numéricos e strings
nulas no caso de vectores alfa-numéricos)

Ana Madureira - 13 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplos:
Dim numeros(100 To 200) As Integer
Dim valores(-100 To 100) As Single

5.1.2. Inicializar um array


Assim como as variáveis simples também os vectores podem ser inicializados na declaração,
indicando-se uma lista de valores entre chavetas separados por vírgulas. Por Ex:
Dim notas() As Integer= {1, 2, 3, 4, 5} declara o vector notas com 5 posições que são
inicializadas com os valores indicados, pela mesma ordem, isto é, notas[0]=1, notas[1]=2 e assim
sucessivamente até notas[4]=5.
1 2 3 4 5
notas[0] notas[1] notas[2] notas[3] notas[4]

5.1.3. Obtenção do último índice de um vector: GetUpperBound()


Permite obter o indíce máximo de um vector previamente declarado: nomeVector.GetUpperBound(0).
É útil quando se usa vectores como argumentos de rotinas

Exemplo:
notas.GetUpperBound(0) vale 4

5.1.4. Redimensionamento de vectores - Instrução ReDim


Permite a alteração da dimensão do vector num momento posterior à sua declaração; no entanto
não é possível alterar o seu tipo. Um vector pode ser declarado sem que seja especificada a sua
dimensão; no entanto, antes da sua utilização a sua dimensão terá que ser definida através da
instrução ReDim.

ReDim nomeVector(m) (m – nova dimensão)

Neste caso, após a instrução ReDim todo o conteúdo do vector é inicializado (tipos numéricos a 0,
strings a Nothing)

5.1.5. Processamento de vectores


Sendo um vector uma variável múltipla composta por elementos do mesmo tipo agrupados na
mesma estrutura, a forma mais adequada de executar uma mesma acção sobre parte ou a totalidade dos
seus elementos é utilizando uma estrutura de controlo repetitivo ou ciclo.

Ana Madureira - 14 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplo 1:
Este programa permite calcular e apresentar sob a forma de uma tabela as raízes quadradas de
todos os números inteiros compreendidos entre 0 e um dado limite superior a especificar pelo
utilizador na TextBox txtMaior (a largura do intervalo não deve exceder 100). Os valores calculados
são armazenados num vector para eventual futura utilização.

Private Sub cmdGo_Click()


Dim vectorSqr(100) As Double
Dim Maior as Integer
Dim i As Integer
Dim res As Single
lstTabela.Clear
Maior = Val(txtMaior.Text)
For i = 0 To Maior
res = Sqr(i)
vectorSqr(i) = res
lstTabela.AddItem Format(res,
"0.000")
Next i
End Sub

Como vimos, o processamento dos elementos de um vector consistiu em operações de escrita (de
atribuição) que modificaram o seu conteúdo. É igualmente possível efectuar operações de leitura sobre
todos ou parte dos elementos dum vector. Nesse caso, como é óbvio, a variável do tipo Array deverá
encontrar-se do lado direito da operação de atribuição:
var = vector(índice)

Exemplo 2:
Escreva um programa que leia as notas de uma turma (número de alunos dado) para um vector,
determine a média e o desvio padrão dessas mesmas notas. O programa deve ainda apresentar numa
ListBox as notas da turma que estejam acima da média.

Const NMax = 100

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)


Handles Button1.Click
Dim vec(NMax) As Integer, n As Integer, nota As Integer
Dim t As Integer, soma As Integer, med As Integer
Dim aux As Single, dp As Single
lstNotas.Items.Clear() ' limpa os valores anteriores
'lstNotas.ClearSelected()
txtDP.Text = ""
txtMed.Text = ""
n = 0
Do
Do
nota = Val(InputBox("Nota do aluno nº " & (n + 1)))
Loop Until nota >= 0 And nota <= 20 Or nota = -1

Ana Madureira - 15 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

If nota <> -1 Then


n = n + 1
vec(n) = nota
soma = soma + nota
lstNotas.Items.Add(n & " - " & vec(n))

End If
Loop While n < Val(txtN.Text) And nota <> -1
If n > 0 Then
med = soma / n
txtMed.Text = med
txtN.Text = n
For t = 1 To n
If vec(t) > med Then
lstSupNotas.Items.Add(t & " - " & vec(t))
End If
Next

For t = 1 To n
aux = aux + (vec(t) - med) ^ 2
Next
dp = Math.Sqrt(aux / n)
txtDP.Text = dp
Else
MsgBox("Não foram introduzidos valores!")
End If
End Sub

A saída será por exemplo:

5.1.6. Passagem de vectores como argumentos de funções e rotinas


Tal como acontece com as variáveis simples, os vectores podem ser usados como argumentos de
rotinas.
Argumento na chamada à rotina: nomeVector
Declaração de parâmetros:
• Passagem por valor - ByVal nomeVector() As tipoVar
• Passagem por referência - ByRef nomeVector() As tipoVar

Ana Madureira - 16 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplo:
...
Dim v1() As Integer = {10, 20, 30, 40, 50}, sm As Integer
sm = soma(v1) ‘chamada á função
...
Function soma(ByVal v() As Integer) As Integer
Dim s As Integer
For i As Integer = 0 To v.GetUpperBound(0)
s += v(i)
Next
Return (s)
End Function

Exemplo
Faça a leitura das pontuações que 5 juízes de uma determinada prova atribuíram a um atleta (valores
compreendidos entre 0 e 9 inclusive). Determine e apresente com formato adequado, os seguintes
valores:
• média obtida pelo atleta
• a pior e a melhor pontuação
• a percentagem de pontuações iguais ou superiores a 8 valores
• supondo que a 1ª nota foi atribuída pelo juiz nº1 e assim sucessivamente determine os
números dos juízes que atribuíram a melhor nota do atleta.

Module Module1
Const NJUIZES As Integer = 5
Sub Main()
Dim notas(NJUIZES-1), notmax, notmin As Double
leitura_pont(notas)
Console.WriteLine("Média: {0:F2}", media_pont(notas))
maxmin(notas, notmax, notmin)
Console.WriteLine("Melhor nota: {0:F2}", notmax)
Console.WriteLine("Pior nota: {0:F2}", notmin)
Console.WriteLine("Percentagem de notas > 8: {0:F2}", _
percentag(notas, 8))
juizes_max(notas, notmax)
End Sub
Sub leitura_pont(ByRef pont() As Double)
For i As Integer = 0 To NJUIZES - 1
Do
Console.Write("Introduza nota do juiz " & i + 1 & ": ")
pont(i) = CDbl(Console.ReadLine())
Loop While Not valida(pont(i))
Next
End Sub

Function valida(ByVal pont As Double) As Boolean


If pont < 0 Or pont > 10 Then Return False Else Return True
End Function

Function media_pont(ByVal pont() As Double) As Double


Dim soma As Double = 0
For i As Integer = 0 To NJUIZES - 1
soma += pont(i)
Next
Return soma / NJUIZES
End Function

Sub maxmin(ByVal pont() As Double, ByRef max As Double,


ByRef min As Double)
max = pont(0)
min = pont(0)
For i As Integer = 1 To NJUIZES - 1

Ana Madureira - 17 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

If pont(i) > max Then max = pont(i)


If pont(i) < min Then min = pont(i)
Next
End Sub
Function percentag(ByVal pont() As Double, ByVal n As Double) As Double
Dim cont As Integer = 0
For i As Integer = 0 To NJUIZES - 1
If pont(i) >= n Then cont += 1
Next
Return cont * 100 / NJUIZES
End Function

Sub juizes_max(ByVal pont() As Double, ByVal max As Double)


Console.WriteLine("Juizes que atribuiram a maior classificação:")
For i As Integer = 0 To NJUIZES - 1
If pont(i) = max Then Console.WriteLine("Juiz " & i + 1)
Next
End Sub

End Module

A saída sera:

5.1.7. Pesquisa em Vectores


Vários métodos podem ser seguidos para procurar informação armazenada em vectores. O método
mais simples é o da pesquisa linear (ou sequencial).
Este método consiste em pesquisar sequencial e exaustivamente um vector na procura de um dado
valor. A pesquisa termina quando se tiver encontrado o valor a procurar ou se tenha chegado ao fim
do vector.
Algoritmo
Inicio
i ← 0
Ler (val)
Enq ((i < Max) AND ( vect[i] != val))
i ← i + 1
Se (vect[i] = val)
Escrever(“ Sucesso na Pesquisa”)
Senão
Escrever (“ Insucesso na Pesquisa”)
Fim

Ana Madureira - 18 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplo:
Seja um vector VectQualquer com Max elementos, pretende-se procurar usando o método de
pesquisa sequencial, um valor num em VectQualquer . Para verificar se o valor contido na variável
num se encontra armazenado no vector VectQualquer, podemos usar o programa que a seguir se
descreve.
Este programa encontra-se dividido em dois procedimentos, um associado ao botão de comando
“Go” e o outro ao botão “Pesquisa”. O primeiro serve para preencher o vector VectQualquer com
valores que possam posteriormente ser pesquisados. O segundo destina-se a pesquisar dentro de
VectQualquer a existência de um dado número inteiro a indicar pelo utilizador.
Repare-se nas duas declarações iniciais colocadas fora de qualquer procedimento. Diz-se que estas
declarações são globais, pelo facto de se encontrarem na secção “General” do programa em vez de
inseridas num dado procedimento, são reconhecidas por todos os procedimentos do programa, e
portanto, acessíveis de dentro de qualquer deles.

Pesquisa sequencial
Const N As Integer = 9

Dim VectQualquer (N) As Integer

Private Sub cmdGo_Click()


Dim i As Integer
Dim texto As String
lstVector.Items.Clear
For i = 0 To N - 1
texto = "Vec(" + str(i) + "):"
VectQualquer (i) = Val(InputBox(texto "))
lstVector.Items.Add (vec(i))
Next i
End Sub

Private Sub cmdPesquisa_Click()


Dim i As Integer
Dim num As Integer
num = Val(InputBox("Valor a pesquisar:", "Pesquisa em Vector"))
i = 0
Do Until (num = VectQualquer (i)) Or (i > N - 1)
i = i + 1
Loop
If i < N Then
lblBusca.Caption = "Encontrado na posição" + str(i + 1)
Else
lblBusca.Caption = "Não encontrado"
End If
End Sub

Outro método bastante usado para procurar informação armazenada em vectores é o método da
pesquisa binária. Trata-se de uma alternativa mais rápida à procura sequencial mas exige que os
elementos do vector estejam ordenados (por ordem ascendente ou descendente).
Este método consiste em pesquisar sucessivamente os elementos a meio de subintervalos do vector,
subintervalos esses que vão sendo reduzidos a metade. Começa-se então por verificar o elemento a
meio do vector. Se não for o valor procurado, então este só pode estar na metade inferior ou superior
do vector, uma vez que é suposto o vector estar ordenado. Assim, a segunda pesquisa incide apenas
sobre metade do vector. Este processo repete-se até se encontrar o elemento desejado (sucesso) ou

Ana Madureira - 19 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

determinar que não se encontra no vector (insucesso). Repare-se que o número de elementos a
pesquisar vai sendo reduzido sucessivamente a metade. Daí a designação de pesquisa binária e a razão
pela qual é mais rápida que a sequencial.

Exemplo :
Para verificar se o valor contido na variável num se encontra armazenado no vector vec
(considerando que este vector se encontra ordenado de forma ascendente) podemos usar a função
seguinte:
Pesquisa Binária
Module Module1
Sub Main()
Dim v() As Integer = {8, 4, 10, 9, 7, 2}
seleccao(v)
p = p_binaria(v, 9)
If p <> -1 Then
Console.WriteLine("Elemento na posição " & p)
Else : Console.WriteLine("Não encontrado!")
End If
End Sub

Function p_binaria(ByVal v() As Integer, ByVal el As Integer) As Integer


Dim i As Integer, ini As Integer = 0
Dim fim As Integer = v.GetUpperBound(0)
Do
i = (ini + fim) \ 2
If el < v(i) Then
fim = i - 1
Else : ini = i + 1
End If
Loop While el <> v(i) And ini <= fim
If el = v(i) Then Return i Else Return -1
End Function
End Module

5.1.8. Ordenação de vectores


Existem vários métodos para ordenar vectores e essa ordenação pode sempre ser feita de forma
ascendente (do menor valor para o maior) ou descendente (do maior para o menor valor).

1 - Ordenação por troca directa


Consiste em comparar cada posição do vector com todas as outras que se encontram à sua direita.
Sempre que se encontra um elemento menor (no caso de ordenação por ordem crescente) trocam-se
os valores.
Ordenação por troca directa
Sub troca_directa(ByRef v() As Integer)
For i As Integer = 0 To v.GetUpperBound(0) - 1
For j As Integer = i + 1 To v.GetUpperBound(0)
If v(j) < v(i) Then
Temp=v(j)
V(j)=v(i)
V(i)=temp
End If
Next
Next
End Sub

Ana Madureira - 20 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

2 - Ordenação por selecção.

Um dos métodos mais simples é o da ordenação por selecção.


Este método consiste em posicionarmo-nos no primeiro elemento do vector e comparar o seu
conteúdo com todos os outros elementos. Sempre que se encontrar um elemento cujo valor seja
menor que o da primeira posição então os valores são trocados entre si. Quando a comparação do
primeiro elemento do vector com todos os outros termina temos a garantia de que o valor do primeiro
elemento é já o menor de todos.
Nesta altura avança-se para o segundo elemento e compara-se o seu conteúdo com todos os
elementos que lhe seguem no vector (terceiro, quarto, ...) trocando os valores sempre que se encontre
um elemento de menor valor. Este processo repete-se até se chegar ao fim do vector, altura em que se
conclui a ordenação do vector.
O método é bastante eficiente para pequenos e médios vectores.

Ordenação por Selecção


Sub seleccao(ByRef v() As Integer)
Dim min As Integer
For i As Integer = 0 To v.GetUpperBound(0) - 1
min = i
For j As Integer = i + 1 To v.GetUpperBound(0)
If v(j) < v(min) Then min = j
Next
If min <> i Then troca(v(i), v(min))
Next
End Sub

Exemplo:
O programa apresentado de seguida ordena o vector de forma ascendente, tal como se mostrou na
figura anterior. O programa encontra-se dividido em dois procedimentos, o primeiro associado ao
botão de comando “Go” que serve para encher o vector e o segundo ao botão “Ordenar” que efectua
a ordenação ascendente dos valores introduzidos e que ficaram guardados no vector VectQualquer.
Const N As Integer = 9
Dim VectQualquer (N) As Integer

Private Sub cmdGo_Click()


Dim i As Integer
Dim texto As String
lstVector.Items.Clear
lstVectorOrdenado.Items.Clear
For i = 0 To N - 1
texto = "Vec(" + str(i) + "):"
VectQualquer (i) = Val(InputBox(texto,
"Entrada de Dados"))
lstVector.Items.Add (vec(i))
Next i
End Sub

Private Sub cmdOrdenar_Click()


Dim i As Integer
Dim j As Integer
Dim temp As Integer
For i = 0 To N - 2
For j = i + 1 To N - 1

Ana Madureira - 21 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

If VectQualquer (j) < VectQualquer (i) Then


temp = VectQualquer (i)
VectQualquer (i) = VectQualquer (j)
VectQualquer (j) = temp
End If
Next j
Next i
For i = 0 To N - 1
lstVectorOrdenado.Items.Add (VectQualquer (i))
Next
End Sub

3 - Inserção ordenada

Neste método, todos os elementos são tratados um de cada vez, inserindo-se cada um no seu lugar.
O elemento corrente é inserido, movendo-se os elementos de valor superior uma posição para a
direita.
Os elementos que se encontram à esquerda do elemento i são os ordenados, apesar de não se
encontrarem na sua posição definitiva, porque podem ainda ser movidos para a direita.

Inserção ordenada
Sub insercao(ByRef v() As Integer)
Dim i, j, x As Integer
For i = 1 To v.GetUpperBound(0)
x = v(i)
For j = i to 1 Step -1
If v(j - 1) > x Then
v(j) = v(j - 1)
Else : Exit For
End If
Next j
v(j) = x
Next i
End Sub

5.2. Matrizes – Arrays bidimensionais


Um elemento de um array pode ser um objecto de qualquer tipo, incluindo outro array. Por isso é
possível simular um array de arrays, ou seja, arrays bidimensionais (matrizes).
Por vezes torna-se necessário guardar informação que de alguma forma se encontra relacionada
entre si. Por exemplo, quando estamos a trabalhar com sistemas de coordenadas a três dimensões, cada
ponto é referenciado através das suas coordenadas X, Y e Z. Se pretendêssemos guardar 10 pontos
desse sistema de coordenadas poderíamos usar um array bidimensional, tal como se mostra a seguir.

Ana Madureira - 22 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

X Y Z
0 1 2 índice_coluna

Pontos
2

3
4

índice_linha

Exemplo de uma matriz 5 x 3 (5 linhas e 3 colunas)


Os elementos de uma matriz são identificados utilizando o nome da matriz seguido dos índices,
linha e coluna, entre parêntesis:
nome_matriz (índice_linha, índice_coluna)

Exemplos:

Coord(2, 0) ‘ coordenada X do 3º ponto


notas(1, 3) ‘ elemento que se encontra na 2ª linha e 4ª coluna da matriz ‘notas’
nomes(0, 0) ‘ 1º elemento da matriz ‘nomes’ – encontra-se na 1ª linha e 1ª coluna

5.2.1. Declaração de matrizes


Tal como na declaração de vectores, a declaração de matrizes pode ser feita indicando apenas o
número de elementos de cada dimensão (número de linhas e colunas), ou usando a palavra reservada
To, permitindo especificar o menor e o maior valor que os índices de cada dimensão poderão assumir.

Dim <nomeMatriz>(<iSupLin>,<iSupCol>) As <tipoVar>

Exemplos:

Dim Coord(5, 3) As Single


Dim Coord(1 To 5, 1 To 3) As Single

5.2.2. Declaração sem indicação das dimensões


Dim <nomeMatriz>(,) As <tipoVar>

5.2.3. Redimensionamento
ReDim arrayName(<iSupLin>,<iSupCol>)
ReDim Preserve arrayName(<iSupLin>,<iSupCol>)

Ana Madureira - 23 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

5.2.4. Passagem de matrizes como argumentos de funções e rotinas


Tal como acontece com os vectores pás matrizes também podem ser usados como argumentos de
rotinas.

Declaração de parâmetros:
• Passagem por valor - ByVal nomeMatriz( , ) As tipoVar
• Passagem por referência - ByRef nomeMatriz ( , ) As tipoVar

Exemplo:
...
Dim mat(4,4) As Integer
sm = soma(mat) ‘chamada á função
...

Function soma(ByVal m(,) As Integer) As Integer


Dim s As Integer
For i As Integer = 0 To l-1
For j As Integer = 0 To c-1
s += m(i,j)
Next
Next
Return (s)
End Function

5.2.5. Obtenção do limite máximo (índice)


<nomeMatriz>.GetUpperBound(0) ‘ 1ª dimensão (linhas)
<nomeMatriz>.GetUpperBound(1) ‘ 2ª dimensão (colunas)

5.2.6. Processamento de Matrizes


Exemplo 1:
Private Sub Button1_Click(ByVal
sender As System.Object, ByVal e As
System.EventArgs) Handles
Button1.Click
Dim Matriz(100, 100) As Integer
Dim Linhas As Integer
Dim Colunas As Integer
Dim i As Integer
Dim j As Integer
Dim Texto As String
lstTabela.Items.Clear()
Linhas = Val(txtLi.Text)
Colunas = Val(txtCol.Text)
For i = 0 To Linhas - 1
Texto = ""
For j = 0 To Colunas - 1
Matriz(i, j) = i + j
Texto=Texto&Matriz(i,j)
Next j
lstTabela.Items.Add(Texto)
Next i
End Sub

Ana Madureira - 24 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Nas matrizes, tal como nos vectores, a forma mais adequada de executar uma mesma acção sobre
parte ou a totalidade dos seus elementos é utilizando duas estruturas de controlo repetitivo: uma para
processar as linhas e outra para as colunas da matriz.
O programa anterior apresenta uma matriz em que cada elemento é encontrado somando os índices
que o identificam. As dimensões da matriz a ser criada são especificadas pelo utilizador e os valores
calculados são armazenados numa matriz. De notar que neste programa se usaram duas variáveis: i e j,
para controlar os ciclos de repetição e armazenar os valores achados na respectiva matriz. A variável i
percorre todas as linhas e para cada linha é usada a variável j para percorrer as colunas.

Exemplo 2:
O exemplo seguinte declara uma matriz em que o tamanho é especificado pelo utilizador. Cada
elemento da matriz será inicializada com o valor i*10+j.
' Matrizes: tamanho definido pelo utilizador.
Module Module1

Sub Main()
Console.Write("Quantas linhas? ")
Dim linhas As Integer = CInt(Console.ReadLine)
Console.Write("Quantas colunas? ")
Dim colunas As Integer = CInt(Console.ReadLine)
' Declara a matriz.
Dim valores(linhas - 1, colunas - 1) As Integer
' Inicia e visualiza os elementos da matriz.
For i As Integer = 0 To valores.GetUpperBound(0)
Console.Write("Elementos da linha {0}: ", i)
For j As Integer = 0 To valores.GetUpperBound(1)
' Inicia os elementos com o valor i*10+j
valores(i, j) = i * 10 + j
Console.Write("{0,4}", valores(i, j))
Next
Console.WriteLine()
Next
Console.ReadKey()
End Sub
End Module

A saída sera:

Exemplo 3: Escreva um programa que calcule a multiplicação de matrizes

O número de colunas da 1ª matriz tem que ser igual ao número de linhas da 2ª, isto é, nc1 == nl2.
O resultado é uma matriz nl1 x nc2
mij = ∑ maik ⋅ mbkj
k

Ana Madureira - 25 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Module Module1
Sub Main()
Dim ma(,) As Double, mb(,) As Double, mr(,) As Double
ler_matriz(ma)
ler_matriz(mb)
If mult(ma, mb, mr) Then
mostra_matriz(mr)
Else
Console.WriteLine("Não é possível multiplicar matrizes")
End If
End Sub
Sub ler_matriz(ByRef m(,) As Double)
Console.Write("Número de linhas: ")
Dim l As Integer = CInt(Console.ReadLine())
Console.Write("Número de colunas: ")
Dim c As Integer = CInt(Console.ReadLine())
ReDim m(l - 1, c - 1)
For i As Integer = 0 To l - 1
Console.WriteLine("Linha " & i)
For j As Integer = 0 To c - 1
Console.Write("(" & i & "," & j & ")=")
m(i, j) = CDbl(Console.ReadLine())
Next
Next
End Sub
Sub mostra_matriz(ByVal m(,) As Double)
For i As Integer = 0 To m.GetUpperBound(0)
For j As Integer = 0 To m.GetUpperBound(1)
Console.Write("{0,7:F2}", m(i, j))
Next
Console.WriteLine()
Next
End Sub

Function mult(ByVal ma(,) As Double, ByVal mb(,) As Double,


ByRef mr(,) As Double) As Boolean
Dim nl1 As Integer = ma.GetUpperBound(0)
Dim nc1 As Integer = ma.GetUpperBound(1)
Dim nl2 As Integer = mb.GetUpperBound(0)
Dim nc2 As Integer = mb.GetUpperBound(1)
' Nº de colunas da 1ª matriz tem que ser igual ao _ nº de linhas
da 2ª matriz
If nc1 <> nl2 Then Return False
ReDim mr(nl1, nc2)
For i As Integer = 0 To nl1
For j As Integer = 0 To nc2
mr(i, j) = 0
For k As Integer = 0 To nc1
mr(i, j) += ma(i, k) * mb(k, j)
Next
Next
Next
Return True
End Function
End Module

Exemplo 4: Escreva um programa que calcule a soma de matrizes

Para que a operação de adição entre duas matrizes seja possível, estas devem ser da mesma ordem,
ou seja, deverá possuir o mesmo número de linhas e de colunas. A soma entre duas matrizes é

Ana Madureira - 26 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

realizada entre a soma dos elementos da linha 1 da 1ª matriz pelos elementos da linha 1 da segunda
matriz e assim sucessivamente.
Module Module1
Sub Main()
Dim ma(,) As Double, mb(,) As Double, mr(,) As Double
ler_matriz(ma)
ler_matriz(mb)
If soma(ma, mb, mr) Then
mostra_matriz(mr)
Else
Console.WriteLine("Não é possível somar as matrizes")
End If
Console.ReadKey()
End Sub
Function soma(ByVal ma(,) As Double, ByVal mb(,) As Double,
ByRef mr(,) As Double) As Boolean
If ma.GetUpperBound(0) <> mb.GetUpperBound(0) Or _
ma.GetUpperBound(1) <> mb.GetUpperBound(1) Then
Return False
End If
ReDim mr(ma.GetUpperBound(0), mb.GetUpperBound(1))
For i As Integer = 0 To ma.GetUpperBound(0)
For j As Integer = 0 To ma.GetUpperBound(1)
mr(i, j) = ma(i, j) + mb(i, j)
Next
Next
Return True
End Function
Sub ler_matriz(ByRef m(,) As Double)
Console.Write("Número de linhas: ")
Dim l As Integer = CInt(Console.ReadLine())
Console.Write("Número de colunas: ")
Dim c As Integer = CInt(Console.ReadLine())
ReDim m(l - 1, c - 1)
For i As Integer = 0 To l - 1
Console.WriteLine("Linha " & i)
For j As Integer = 0 To c - 1
Console.Write("(" & i & "," & j & ")=")
m(i, j) = CDbl(Console.ReadLine())
Next
Next
End Sub
Sub mostra_matriz(ByVal m(,) As Double)
For i As Integer = 0 To m.GetUpperBound(0)
For j As Integer = 0 To m.GetUpperBound(1)
Console.Write("{0,7:F2}", m(i, j))
Next
Console.WriteLine()
Next
End Sub
End Module

Ana Madureira - 27 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

6. Strings

Uma grande parte das linguagens de programação permitem manipular caracteres e/ou conjuntos
de caracteres.
Uma string, que em português refere-se normalmente por “cadeia de caracteres”, será uma
entidade que representa um conjunto de caracteres. Em Visual Basic, uma string é representada
internamente como um vector de números inteiros, em que cada número representa um carácter.
Sintaxe:
– String Dim <nome> as String

– Vector de Strings Dim <nome>(<nº de elementos>) As String

Exemplo
Dim st1 As String, st As String

st1 = txtMyString.Text
st = "Olá" + " " & st1

6.1. Funções de Manipulação de Strings

6.1.1. Trim, LTrim e RTrim

Retornam uma string idêntica à original, mas com espaços eliminados no início e/ou fim da string.

Exemplo:
Dim st1 As String, st2 As String
st1 = “ Olá Mundo! “
st2 = Trim(st1) st2 = "Olá Mundo!" – Foram eliminados os espaços no início e no fim da string.

st2 = LTrim(st1) st2 = "Olá Mundo! " – Foram eliminados os espaços no início da string (left).

st2 = RTrim(st1) st2 = " Olá Mundo!" – Foram eliminados os espaços no fim da string (right).
Os espaços que esteja entre outros caracteres da string não são afectados por estas rotinas.

6.1.2. Len
Retorna o número de caracteres da string.

Exemplo:

Dim st1 As String, k As Integer


st1 = " Olá Mundo! "
k = Len(st1) 'k = 16 – a string tem 16 caracteres, incluindo espaços.
k = Len(Trim(st1)) ‘ k = 12 – Foram eliminados os espaços

Ana Madureira - 28 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

If Len(st1) = 0 then ‘Verificar se uma string está vazia



Endif

6.1.3. Right(), Left()


Copiam o número de caracteres indicado a partir da string original

Left(<original> as String, <nº_caracteres> as Integer) as String

Exemplos:
Dim st1, st2 As String, k As Integer
st1 = “Olá Mundo!”
k=2
st2 = Left(st1, k) st2 ← “Ol” – os dois primeiros caracteres, a partir da esquerda
st2 = Right(st1, k) st2 ← “o!” – os dois primeiros caracteres, a partir da direita
st1 = Right(st1, Len(st1) – 1) Copia todos os elementos da string, a partir da direita, com excepção
do primeiro → eliminar o primeiro carácter de uma string

6.1.4. Mid()
Copia o número de caracteres indicado a partir da posição inicial passada como parâmetro; o número
de caracteres é opcional; se não for indicado, copia tudo até ao fim da string

Mid(<original> as String,<pos_init>as Integer[,<nº_caracteres> as Integer] ) as String

Exemplos:
Dim st1, st2 As String, k As Integer
st1 = “Olá Mundo!”
st2 = Mid(st1, 2, 3) st2 ← “lá ” – copia 3 caracteres a partir da segunda posição
st2 = Mid(st1, 6, 8) st2 ← “undo!” – copia os caracteres a partir da 6ª posição; como o número de
caracteres ultrapassa o limite da string, apenas são copiados os caracteres existentes

6.1.5. InStr()
Procura uma string dentro de outra; a posição inicial é opcional – se não for indicada a pesquisa é
iniciada na posição 1 (início da string)
InStr([<pos_init> as Integer,] <original> as String, <padrão> as String) as Integer

Ana Madureira - 29 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

Exemplos:
Dim st1 As String, k As Integer
st1 = “Olá Mundo!”
k = InStr(st1, “ “) k← 4 – posição do primeiro espaço
k = InStr(5, st1, “ “) k ← 0 – não existe qualquer espaço a partir da posição 5

6.1.6. UCase(), LCase()


Retorna uma string idêntica à original, mas com os caracteres convertidos para maiúsculas (UCase) ou
minúsculas (LCase); algarismos e caracteres de pontuação não são afectados

UCase(<original> as String) as String


LCase(<original> as String) as String

Exemplos:
Dim st1, st2 As String
st1 = “Olá 1,2,3!”
st2 = UCase(st1) st2 ← “OLÁ 1,2,3!”
st2 = LCase(st1) st2 ← “olá 1,2,3!”

6.2. Exemplos resolvidos


1. Elabore uma função que retorne a simétrica de uma string passada como parâmetro. Utilizando a
função, elabore um programa que verifique se uma string é simétrica.
Module Module1
Sub Main()
Dim sto As String, sti As String
sto = InputBox("String")
sti = invString(sto)
MsgBox(sti)
If sti = sto Then
MsgBox("String Simétrica!")
Else
MsgBox("String Assimétrica!")
End If
End Sub
Function invString(ByVal st As String) As String
Dim c As String, iv As String
Do While st <> ""
c = Left(st, 1)
st = Right(st, Len(st) - 1)
iv = c + iv
Loop
invString = iv
End Function
End Module

Ana Madureira - 30 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

2. Escreva uma função que recebe uma string como parâmetro e retorna o número de palavras que a
string contém.

Function nPal(ByVal st As String) As Integer


Dim n As Integer, p As Integer
st = Trim(st)
If st <> "" Then
Do
p = InStr(1, st, " ")
If p > 0 Then
st = LTrim(Right(st, Len(st) - p))
End If
n = n + 1
Loop While p > 0
End If
nPal = n
End Function

3. Escreva uma função que recebe uma string e um número n como parâmetros e retorna uma string
com as palavras da primeira com menos de n caracteres.

Function truncaPal(ByVal st As String, ByVal n As Integer) As


String
Dim p As Integer, pal As String, stout As String
st = Trim(st)
Do While st <> ""
p = InStr(st, " ")
If p > 0 Then
pal = Left(st, p - 1)
st = LTrim(Right(st, Len(st) - p))
Else
pal = st
st = ""
End If
If Len(pal) < n Then
stout = stout + " " + pal
End If
Loop
truncaPal = Trim(stout)
End Function

Ana Madureira - 31 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

6.3. Exercicios Complementares

6.3.1. 1. Estruturas de Dados Mono-indexadas (Vectores)


1. Escreva um programa que determine a soma dos elementos de um vector de elementos do
tipo Double.

2. Escreva um programa que determine o maior elemento e respectiva posição de um vector de


inteiros.

3. Escreva um programa que ordene um vector de inteiros por ordem decrescente.

4. Escreva um programa que:

• faça a leitura de 10 números e que os guarde em memória central;

• dos 10 números lidos, mostre todos os que são maiores que os seus vizinhos;

• retorne a maior diferença absoluta entre dois números consecutivos; também deverá
retornar a posição destes dois números onde existe a maior diferença;

• retorne a média dos 10 números;

• retorne a mediana dos 10 números; a mediana é o valor central de uma série de números;
quando o número de elementos é par, define-se mediana como a média dos dois números
centrais;

• ordene por ordem decrescente o vector.

Cada pedido deve ser realizado através de uma rotina. O programa deverá testar as rotinas
escritas.

6.3.2. Estruturas de Dados Bi-indexadas (Matrizes)

1. Defina uma rotina para ler a partir da consola uma matriz cujas dimensões são indicadas pelo
utilizador e outra para apresentar na consola o conteúdo de uma matriz cujas dimensões são
indicadas pelo utilizador.

2. Defina uma rotina que multiplique duas matrizes dadas como argumentos (a multiplicação de
duas matrizes só é possível se o nº de colunas da 1ª matriz é igual ao nº de linhas da segunda
matriz).

m ij = ∑ a ik b kj
k
3. Defina uma rotina que determine a transposta de uma matriz dada como argumento.

4. Defina uma rotina que a partir de uma matriz recebida como parâmetro, de dimensões n por
m preencha um vector com um número de células igual a n*m. A primeira linha da matriz será

Ana Madureira - 32 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

transferida para as primeiras n posições do vector, e assim sucessivamente (linearização de


uma matriz).

5. Defina uma rotina que determine a soma dos elementos de cada linha, de cada coluna e da
diagonal principal de uma matriz bidimensional recebida por parâmetro.

6.3.3. Strings

1. Escreva um programa para contar e imprimir o número de dígitos, vogais e consoantes lidas do
teclado.

2. Escreva uma função que, recebendo uma string como parâmetro, inverta essa mesma string.
Elabore um programa que permita testar a função.

3. A complexidade de uma palavra é dada pelo maior número de consoantes consecutivas nessa
mesma palavra (Exemplo: “complexidade” tem complexidade 3).
a) Escreva uma função que retorne a complexidade de uma palavra. A palavra é passada
como parâmetro sob a forma de uma string que contém apenas esta.
b) Utilizando a função anterior escreva um programa que, dada uma frase, mostre a
complexidade média da frase (média das complexidades das palavras que a constituem).

4. A dificuldade de uma palavra é definida como a percentagem de consoantes nessa mesma


palavra (Exemplo: “dificuldade” tem dificuldade 55%).
a) Escreva uma função que retorne a dificuldade de uma palavra. A palavra é passada como
parâmetro sob a forma de uma string que contém apenas esta.
b) Utilizando a função anterior escreva um programa que, dada uma frase, mostre a dificuldade
média da frase (média das dificuldades das palavras que a constituem).

Ana Madureira - 33 -
Aplicações Informáticas de Gestão
Estruturas de Dados Estáticas

www.foresp.pt

7. Bibliografia
1. O Guia Prático do Visual Basic 2008, Vítor Pereira, ISBN: 978-989-615-067-9, Centro Atlântico, 2008

2. Programação em Visual Basic .NET, Vasco Capitão, FCA (www.fca.pt)

3. Textos de Apoio da disciplina Algoritmia e Programação, 2006/2007, Engª Mecânica, ISEP.

4. Textos de Apoio da disciplina Algoritmia e Programação, 2006/2007, Luiz faria, Engª Electroptércnica e de
Computadores – Sistema de Energia, ISEP.

5. An Introduction to Programming Using Visual Basic 2005, 6ª Edição, David I. Schneider, Prentice Hall

6. Informação suplementar da Microsoft: http://msdn.microsoft.com/library.

Ana Madureira - 34 -

Você também pode gostar