Aula 17: Array


Array

Imagine queríamos fazer um programa para calcular a média de uma lista de 10 números. Com a matéria que aprendemos até agora, terias de fazer qualquer coisa deste estilo
  Var a1, a2, a3, a4, a5, a6, a7, a8, a9, a10: real;
      average: real;
e depois o cálculo:
  average := (a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) / 10;
Isto é uma grande chatice. Ainda pior, imagine queremos pedir ao utilizador o número de números a usar no cálculo da média:
  Var n: integer;
     |
  ReadLn(n);
  Case n of
     1: average := a1;
     2: average := (a1 + a2) / 2;
     3: average := (a1 + a2 + a3) / 3;
          |
    10: average := (a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) / 10;
  end;
É aqui que surge o conceito de array. Um array pode guardar muitas variáveis do mesmo tipo com acesso fácil, através um índice. Tal como em matemática, onde ai é elemento número i de um vector ou série a, a[i] é elemento i de um array a.
 
 Um array é uma colecção indexada de variáveis do mesmo tipo


Declaração de um array

Para declarar um array usamos a seguinta sintaxe:
 
 Var name: array[startindex .. endindex] of type

name é o identificador (nome) do array, da mesma forma dos nomes paras as outras variáveis.
startindex e endindex definem os limites dos índices do array. Nota que, em PASCAL, o começo do array não é necessariamente igual a 0. Em vez disso, o array pode começar à vontade. Isto é simpático, porque pessoas normalmente gostam de trabalhar com índices começando com 1 em vez de 0. Al«em disso, o array pode começar com qualquer outro índice (13, 100, -100, tanto faz).
type é qualquer tipo da variável que nós já conhecemos, por exemplo real ou integer, mas pode também ser um outro array.

Exemplos:

   Var account: array[1..100] of real;
Isto podia guardar a informação de 100 contas bancárias.

   Var prime: array[1..10] of longint;
Isto podia guardar os primeiros 10 números primos.

   Var propinas: array[1000..2000] of boolean;
Isto podia guardar alguma informação (do tipo boolean) sobre a condição dos alunos com números entre 1000 e 2000, por exemplo se eles pagáram propinas este ano. Com certeza, a nossa universidade tem um array deste tipo no algum sítio.


Usar um array

Dentro do programa podemos usar um elemento de um array através
 
 name[index

name[index] retornerá o valor do elemento index do array name. A declaração do array determine o tipo de valor do cada elemento
Exemplos: Os array da secção anterior:

   account[20]
é o valor - do tipo real - do elemento 20 do array com nome account.

   prime[8]
é o valor ' do tipo longint ' do elemento 8 do array com nome prime. Os números aqui ao lado direito podiam representar este array. Então, elemento 8 seria igual a 17. Está claro que o nosso programa deve preencher este array do qualquer modo. Senão o array não conterá os números primos.

   propinas[1055]
é TRUE ou FALSE (tipo boolean). Elemento 1055 do array propinas. O aluno 1055 já pagou as propinas? Sim ou não?

Podemos também usar uma variável para o índice do array. Evidentemente, esta variável deve ser de um tipo inteiro, porque o ídice é alguma coisa contável; índice 3.4981 não faz sentido. Índice 3 faz, enderecerá o terceiro elemento do array. O código a seguir mostrará o conteúdo do array account (20 elementos):

  for i := 1 to 20 do
    WriteLn(account[i]);
 


Arrays com mais de uma dimensão

Tal como em matemática, onde temos vectores (tensores de uma dimensão) e matrizes (tensores de duas dimensões) em programação existem arrays de uma ou duas ou mesmo mais dimensões. Por exemplo, a declaração de um 'double array' (um array de duas dimensões):
 
 Var name: array[startindex1 .. endindex1, startindex2 .. endindex2] of type

Na verdade, é também possível declarar este array assim:

  Var name: array[startindex1..endindex1] of array[startindex2..endindex2] of type;

o que mostra bem o que é um array de duas dimensões, nomeademente um array de arrays. Neste maneira o computador arranja os arrays. Por outro lado, o primeiro método de declarar um array de duas dimensões é mais lógico para as pessoas. Por isso, este modo de declaração é preferido.

O uso do um array de duas dimensões é parecido com o uso de um array de uma dimensão. Temos de seperar os índices com uma virgula ou com parênteses quadradras:
 

 name[index1, index2
 name[index1][index2

 
  Um exemplo: para mostrar a matriz aqui ao lado esquerde o código a seguir pode ser usado. Nota que o array consiste de 9 (3x3) elementos do tipo integer.

PROGRAM ShowMatrix;

Var matrix: array[1..3, 1..3] of integer;

begin
  matrix[1, 1] := 1;
  matrix[1, 2] := 0;
  matrix[1, 3] := 1;
  matrix[2, 1] := 2;
  matrix[2, 2] := 2;
  matrix[2, 3] := 0;
  matrix[3, 1] := 1;
  matrix[3, 2] := 0;
  matrix[3, 3] := 1;
  for i := 1 to 3 do
    begin
       for j := 1 to 3 do
         Write(matrix[i, j],' ');
      WriteLn;
    end;
end.
 


     Aviso

  Com os arrays temos de haver sempre cuidade de usar índices válidos. Isto significa usar índices no gama especificado na altura de declaração. O computador só vai reservar espaço na memória suficiente para guardar esses variáveis. nada mais e nada menos. Se usamos um ídice 'out of bounds' (fora da gama) o resultado do programa pode tornar-se muito estranho. 
Para esclarecer isto num exemplo: O programa a seguir declara um array de 4 integers r[1..4] e uma variável normal do mesmo tipo (integer) a. A figura ao lado mostra como a memória está organizada depois desta declaração. Agora, o que vai acontecer na linha onde vai atribuir um valor a r[5]? Se r[5]existeria, este r[5] ficaria no lugar que agora está ocupado por a. A maioria das linguagens de programação não preocupam-se com isso e vão escrever neste lugar, e vamos perder o valor de a.

  PROGRAM Test;

  Var r: array[1..4] of integer;
  Var a: integer;

  begin
    a := 0;
    WriteLn('a=',a);
    r[5] := 1;
    WriteLn('a=',a);
    ReadLn;
  end.

O output do programa provavelmente será

  a=0
  a=1

Há lingaugens de programação que deixam nos especificar que nós queremos que o programa vai sempre verificar se os índices são válidos. Por exemplo o Turbo PASCAL. Mas, o Dev-PASCAL não tem este opção. Com este verificação o programa fica mais lente e ocupa mais espaço na memória e no disco, mas pode ajudar nos em eliminar erros do nosso programa. A verificação do índices chama-se range-checking (verificação do gama) e se o programa encontra um índice inválido vai gerar um 'range-check error' (erro na verificação do gama).



"Hurray! Sei tudo dos arrays!"

Quick Test

Para testar o seu conhecimento, sobre o que aprendeu nesta aula, clique aqui para um teste on-line.

Peter Stallinga. Universidade do Algarve, 13 Abril 2002