Métodos de Programação I Departamento de Matemática, FCTUC 51 2005/06 2.10. O TIPO ESTRUTURADO TABELA (ARRAY) A estruturação de informação introduz uma nova dimensão no poder e complexidade dos nossos programas que, ao mesmo tempo que amplia a capacidade de manipulação, também a simplifica e aumenta a sua clareza. Nesse sentido, passamos a apresentar uma das estruturas de informação mais utilizadas em programação - a tabela (array). Como é habitual, uma tabela é um agregado de elementos do mesmo tipo . Cada um desses elementos, pode ser acedido através da indicação da posição que ocupa na tabela. As dimensões de uma tabela representam, por definição, o número de valores (elementos) que a tabela pode conter no total, e é através das dimensões que é possível indicar a posição de um dado elemento. Para referenciar, por exemplo, um elemento da tabela da figura 2.20, que tem dimensão 1x11, isto é, uma única linha e onze colunas, temos apenas que especificar a coluna - o valor do índice que representa as colunas - onde está colocado o elemento, ou seja, a posição deste elemento na linha. Exactamente porque esta tabela só tem uma linha, e portanto só precisamos do índice das colunas para referenciar os elementos, toma o nome de tabela unidimensional (um só índice). índice 0 24 1 7 2 18 3 -6 4 -5 5 0 6 20 7 2 8 34 9 35 10 4 Figura 2.20: tabela unidimensional Para referenciar um elemento duma tabela como a da figura 2.21, com dimensão 4x10 (quatro linhas e dez colunas), já precisamos, não de um, mas de dois índices: um para a posição na linha e outro para a posição na coluna. Por isso mesmo se denomina uma tabela deste tipo por bidimensional. Tabelas com mais do que dois índices dizem-se multidimensionais. índices 1 x 1 2 3 4 2 3 4 5 6 7 8 x 9 10 x x x x Figura 2.21: tabela bidimensional O Pascal, como de resto quase todas as linguagens de alto nível, obriga à declaração das tabelas antes da sua utilização no programa (como é óbvio, a ser feita na parte declarativa do programa). Para declarar tabelas de um tipo particular, temos que caracterizar as suas dimensões, os limites dos seus índices e qual o tipo dos seus elementos. As tabelas são, portanto, tipos estruturados com duas características fundamentais: • • todos os elementos armazenados na tabela são do mesmo tipo os elementos de uma tabela são acedidos através da posição que ocupam nessa tabela. O diagrama de sintaxe para a declaração de uma tabela em Pascal toma a forma, , array [ tipo simples ] of índice(s) tipo Métodos de Programação I Departamento de Matemática, FCTUC 52 2005/06 Este diagrama indica que o(s) índice(s) serão de um tipo simples, que define não só as dimensões máximas da tabela, mas também os limites inferior e superior, como podemos ver nos exemplos que se seguem. Aí são apresentadas três tabelas diferentes: • o tipo vector - unidimensional, com dimensão 100 (1x100), de elementos reais; • a variável texto - unidimensional, dimensão 12 (1x12), de elementos do tipo caracter; • o tipo matriz - bidimensional, com dimensão 100 (10x10), de elementos reais: type vector = array [ 1 .. 100 ] of real; matriz = array [ 1 .. 10, 1 .. 10 ] of real; var v1, v2 : vector; A, B, C : matriz; texto : array [ 0 .. 11 ] of char; Os tipos vector e texto acima declarados são tabelas unidimensionais. Por convenção, passaremos a denominar toda a tabela deste tipo por vector (tabela com uma única variação de índice) e a uma tabela bidimensional chamar-se-à matriz. Como é óbvio, para trabalhar com estes tipos é necessário criar variáveis (identificadores). Após a declaração de uma variável como tabela, podemos referenciar qualquer um dos seus elementos especificando o nome da variável (do tipo tabela) e a posição que o elemento desejado nela ocupa, isto é, o(s) valor(es) do(s) índice(s), como por exemplo, sendo a tabela texto a seguinte, 0 e 1 s 2 t 3 e 4 5 t texto[1] 6 e 7 x 8 t 9 o 10 11 ! texto[6] o nome da tabela seguido da posição K indicada entre parêntisis rectos – texto[K] - referencia o elemento da tabela texto que se encontra no índice de valor K (e, portanto, texto[1] tem o velor 's', enquanto texto[6] tem o valor 'e'). A instrução, texto[11] := ‘?’; tem o efeito esperado, 0 e 1 s 2 t 3 e 4 5 t 6 e 7 x 8 t 9 o 10 11 ? texto[11] Poderemos utilizar todas as instruções conhecidas sobre variáveis sobre estas referências pois, cada uma delas referencia uma variável (só que declarada de um modo especial). Por exemplo, e utilizando ainda os tipos e as variáveis acima declarados, poderemos fazer, v2[56] := 3 + A[1,10] * 8.7; i := 55; j := 5; v2[i+j] := v2[100] - 26; Notas Finais: • Os índices só podem ser de tipo escalar não real e, dentro destes, só são aceites subdomínios (enumeração): type quadro = array [ -10 .. -5, -5 .. 5 ] of integer; Métodos de Programação I Departamento de Matemática, FCTUC 53 2005/06 vencimentos = array [ ‘A’ .. ‘F’ ] of real; • Os limites dos índices têm que ser constantes. • O número máximo de índices depende do computador. • Um array é uma sequência de variáveis do mesmo tipo. • O tipo dos elementos pode ser qualquer, inclusive, outro array: type var cores = (branco, azul, verde, vermelho, amarelo); cubo : array [ 1 .. 3, 1 .. 3, 1 .. 3 ] of cores; digitos : array [ 1 .. 10 ] of 0 .. 9; array [ 1 .. 8 ] of array [ 1 .. 8 ] of quadrados; A última declaração acima é equivalente a declarar uma matriz: tabuleiro : array [1 .. 8 , 1 .. 8] of quadrados; Exemplos de operações elementares com tabelas unidimensionais numéricas Podemos estender a analogia com os vectores algébricos e implementar as operações algébricas mais usuais. Nesse sentido, vamos assumir que, a título de exemplo, temos as seguintes declarações: const DIM = 100; type Vector = array [1..DIM] of real; var i : 1..DIM; k, norma, prod : real; v, u, z : Vector; Consideremos que temos 2 vectores de inteiros, v e u (do tipo Vector), já com valores para os quais podemos querer efectuar operações como sejam, entre outras: somar 2 vectores, calcular o seu produto interno, multiplicar um escalar por um vector ou calcular a norma de um vector. Para todas estas operações é necessário percorrer todas as posições (de 1 a Dim) de cada vector , para o que poderemos usar ciclos “for”: Soma de dois vectores: Produto de um escalar por um vector: for i:=1 to DIM do u[i] := k * v[i]; Produto Interno de dois vectores: prod := 0; for i:=1 to DIM do prod := prod + v[i] * u[i]; Norma de um vector: for i:=1 to DIM do z[i] := v[i] + u[i]; norma := 0; for i:=1 to DIM do prod := norma + sqr( u[i]); norma := sqrt(norma);