Variáveis Indexadas 1 Variáveis Indexadas As variáveis envolvidas nos programas dos capítulos anteriores eram variáveis do tipo escalar, ou seja, variáveis que apenas podiam assumir um único valor de cada vez. No entanto, é útil em muitas aplicações estabelecer determinadas relações entre um conjunto de dados. Usando apenas variáveis do tipo escalar não é possível estabelecer directamente qualquer relação entre variáveis. Em muitas situações concretas é necessário definir formas mais complexas de representação de dados relacionados entre si e que contenham informação acerca da sua forma de associação. Estas formas de representação são normalmente designadas por tipos de dados estruturados. É importante também que estas estruturas permitam a manipulação de cada conjunto de dados como uma só entidade. Tipos de Dados Estruturados Os tipos de dados discutidos nos capítulos anteriores são tipos de dados simples: valores dos tipos inteiro, real, lógico e carácter. Estes tipos apresentam uma natureza escalar, isto é, cada variável de cada um destes tipos apenas pode assumir um valor de cada vez. Em problemas reais existe muitas vezes a necessidade de operar sobre conjuntos de dados que de alguma forma estão relacionados entre si e que interessa processar como um todo. Alternativamente, poderá ser necessário processar cada elemento do conjunto de forma individual, mas respeitando a sua dependência e associação aos restantes elementos. Estes poderão, por exemplo, estar dependentes da forma como estão ordenados dentro do conjunto ou de possíveis associações lógicas existentes entre os diversos elementos. A resolução de muitos problemas concretos pode ficar facilitada recorrendo a tipos de dados que contenham informação estrutural, ou seja, os tipos de dados estruturados. Estes, não são mais do que conjuntos de variáveis escalares de um dado tipo, mas aos quais se adicionou informação sobre a forma como essas variáveis se associam dentro do conjunto. Na linguagem PE estão definidos dois tipos de dados estruturados: os vectores e as matrizes (por vezes também designados por vectores bidimensionais). Estas entidades são também designadas por variáveis indexadas. Vectores Um vector consiste numa variável dividida num número finito de células de um dado tipo de dados, numeradas sequencialmente e que poderão conter valores distintos entre si e do tipo definido para as células. Na nomenclatura inglesa, os vectores são designados por arrays. Todos os elementos que 2 compõem um vector são igualmente acessíveis, bastando indicar a posição da célula ocupada por cada um dos elementos. A declaração de variáveis indexadas do tipo vector é conseguida indicando o tipo dos valores a guardar nas diversas células, seguido do nome escolhido para o vector. A seguir ao nome é necessário indicar a dimensão do vector, isto é, o número máximo de células que este irá comportar. A definição da dimensão é o processo que permite distinguir uma variável indexada de uma variável escalar. Por exemplo, considere-se a instrução seguinte: carácter nomes[ 5 ]; Esta instrução corresponde à declaração de uma variável do tipo vector de caracteres, com um número máximo de cinco células. O número máximo de células é uma parte fundamental na instrução de declaração, sendo o valor respectivo indicado entre parentesis rectos. Cada célula é identificada por um índice numérico que determina a sua posição no vector. Este índice deve ser sempre indicado quando se pretende aceder ao conteúdo de uma célula específica ou quando a célula é inicializada. Assim, seria possível inicializar o vector de caracteres nomes[], atribuindo valores a cada célula: nomes[ 0 ] = "Manuel"; nomes[ 1 ] = "Maria"; nomes[ 2 ] = "Pedro"; nomes[ 3 ] = "Joana"; nomes[ 4 ] = "Antonio"; Note-se que a primeira célula é acedida definindo o valor 0 para o índice respectivo. Esta convenção é seguida na linguagem PE: o índice numérico de um vector tem sempre início no valor 0. Por exemplo, o terceiro elemento do vector, ou seja, o elemento nomes[2], contém a sequência de caracteres "Pedro". A operação de atribuição obedece à sintaxe seguinte: <nome do vector>[<índice da célula>] = <expressão>; Figura 7.1. Organização Lógica das Células de um Vector. Tal como nas variáveis escalares, cada célula de um vector terá de ser previamente inicializada antes de ser utilizada. Pode-se, no entanto, efectuar operações com um vector tendo inicializado apenas uma parte das células desde que as células restantes não sejam necessárias nessas operações. Analise-se mais uma vez o problema do cálculo das médias das notas dos alunos de uma escola. No programa 6.5 eram consideradas as notas de quatro disciplinas. Se para além disso fosse necessário Variáveis Indexadas 3 apresentar os nomes dos alunos na saída do programa era claramente vantajoso recorrer a um vector contendo o nome dos alunos em questão. /* Função calcula_média */ real calcula_média( n1, n2, n3, n4 ) inteiro n1, n2, n3, n4; { real m; m = (n1 + n2 + n3 + n4) / 4; retorna m; } /* Procedimento escreve_média */ escreve_média( n, x ) carácter n; real x; { escreva( "A média do aluno", n, " e´ ", x ); } /* programa principal */ programa() { constante inteiro número_alunos = 25; carácter nomes[ número_alunos ]; inteiro nota1, nota2, nota3, nota4, aluno = 1; real média; enquanto aluno <= número_alunos faça { leia( nomes[ aluno ] ); leia( nota1, nota2, nota3, nota4 ); média = calcula_média( nota1, nota2, nota3, nota4 ); escreve_média( nomes[ aluno ], média ); aluno = aluno + 1; } escreva("Calculada a média de ", número_alunos, " alunos."); } Programa 7.1. Exemplo de Aplicação de Vectores: Cálculo das Médias das Notas de um Grupo de Alunos. 4 No programa 7.1 foi incluído o vector nomes[] para guardar os nomes dos alunos. Este vector foi definido com uma dimensão indicada pela constante número_alunos. Por sua vez, o procedimento escreve_média() foi alterado de forma a poder apresentar não só a média de cada aluno mas também o nome respectivo. A dimensão de um vector é sempre um valor inteiro, constante e positivo. Não é possível usar variáveis na definição da dimensão de um vector pois estas podem ser alteradas durante a execução do programa. A sintaxe para declaração de um vector é então: <tipo das células> <nome do vector>[ <dimensão> ]; Matrizes Os vectores, tal como ficou claro através do exemplo apresentado, são variáveis indexadas com uma única dimensão (a posição de cada célula dentro do vector). Por vezes, no entanto, é necessário recorrer a variáveis indexadas com mais do que uma dimensão. Por este motivo, existe na linguagem PE (e com correspondência na maior parte das linguagens de programação reais) um outro tipo de dados estruturado, mas com duas dimensões. Este novo tipo designa-se por matriz. Enquanto que no vector era possível entender uma organização interna das células em linhas sucessivas de um único elemento, a matriz sugere uma organização em linhas sucessivas com mais do que um elemento ou, por outras palavras, uma organização em linhas e colunas. Por exemplo, a instrução seguinte permite a declaração de uma matriz, com células do tipo inteiro, designada por linhas_colunas e cuja dimensão é de 5 linhas por 10 colunas: inteiro linhas_colunas[ 5 ][ 10 ]; Esta matriz irá comportar, no máximo, 50 elementos capazes de armazenar valores do tipo inteiro. O primeiro elemento da matriz será linhas_colunas[ 0 ][ 0 ] e o último será linhas_colunas[ 4 ][ 9 ]. Assim, a sintaxe de declaração de uma matriz é, <tipo_das_células> <nome_matriz>[<linhas>][<colunas>]; A operação de atribuição é conseguida indicando, tal como nos vectores, a posição da célula pretendida. A sintaxe desta operação é: <nome matriz>[<índice da linha>][<índice da coluna>] = <expressão>; De notar que na declaração de uma matriz, primeiro indica-se a dimensão correspondente ao número de linhas e depois a dimensão correspondente ao número de colunas. Cada elemento da matriz pode ser identificado individualmente pelos índices respectivos, correspondentes à linha e coluna que ocupam. De Variáveis Indexadas 5 uma certa forma, uma matriz pode ser vista como um vector cujas células são constituídas por vectores de um tipo definido. As considerações apresentadas relativas à inicialização de vectores são igualmente válidas para a inicialização de matrizes. Em problemas concretos é possível encontrar muitas aplicações para as matrizes. Uma aplicação óbvia será a aplicação à Álgebra para automatizar as operações envolvendo entidades matemáticas também designadas por matrizes e que têm uma correspondência directa com a definição apresentada para as matrizes da linguagem PE. /* Calculo das médias recorrendo a vectores e matrizes */ inteiro notas[ 25 ][ 10 ]; real média[ 25 ]; carácter nomes[ 25 ]; leitura_de_dados() { inteiro i, j; para i = 0 até i == 24 faça { leia( nomes[ i ] ); para j = 0 até j == 9 faça leia( notas[ i ][ j ] ); } calcula_médias() { inteiro i, j, soma; para i = 0 até i == 24 faça { soma = 0; para j = 0 até j == 9 faça soma = soma + notas[ i ][ j ]; média[ i ] = soma / 10; } } escreve_médias() { inteiro i; 6 para i = 0 até i == 24 faça escreva( "A média do aluno ", nomes[i], " e´ ",média[i] ); } programa() { leitura_de_dados(); calcula_médias(); escreve_médias(); } Programa 7.2. Exemplo de Aplicação de Vectores e Matrizes: Nova Versão do Programa para Cálculo das Médias das Notas de um Grupo de Alunos. O programa 7.2 destina-se novamente ao cálculo de médias de notas, mas desta vez recorrendo a vectores e matrizes. Neste caso, pretendia-se o cálculo da média de dez notas e portanto não seria prático recorrer a dez variáveis diferentes. Em vez disso, foi definida a matriz notas[][] cujas linhas correspondem ao conjunto dos alunos e cujas colunas correspondem ao conjunto das notas dos diversos alunos. Para guardar as médias calculadas existe definido o vector média[], de dimensão igual ao número de alunos. É de notar que no programa 7.2 estão definidas variáveis globais (a matriz e os vectores). Figura 7.2. Organização Lógica das Células dos Vectores e da Matriz correspondentes ao Programa 7.2. Algoritmos com Variáveis Indexadas As variáveis indexadas têm um um grande número de aplicações no campo da programação. Essas aplicações podem ser muito variadas e dependem obviamente de cada aplicação particular. No entanto, existem duas operações muito importantes e frequentes cuja generalidade justifica o seu estudo neste capítulo. As operações em causa são a ordenação e a pesquisa num vector. Embora estas operações não sejam utilizadas apenas sobre variáveis indexadas, o uso de vectores ocorre com bastante frequência. Os algoritmos existentes recorrendo a vectores podem ser alterados de forma a permitirem a sua aplicação a outras estruturas de dados. A ordenação de um vector consiste em colocar os seus elementos numa determinada ordem, recorrendo a um critério de ordenação. Concretamente, um vector pode ser reorganizado de forma a que os seus elementos apresentem uma ordenação crescente ou então de forma a apresentarem uma organização decrescente. Por exemplo, considere-se a sequência seguinte de elementos de um vector de numeros inteiros: Variáveis Indexadas 7 4, 5, 1, 9, 12, 15, 10, 11, 3, 18. O vector poderia ser rearranjado de forma a que os seus elementos estivessem organizados de forma crescente, ou seja, na sequência 1, 3, 4, 5, 9, 10, 11, 12, 15, 18. Alternativamente, o vector poderia ser ordenado de forma decrescente, obtendo-se a sequência 18, 15, 12, 11, 10, 9, 5, 4, 3, 1. No primeiro caso, a posição 0 do vector seria ocupada pelo valor 1 (menor elemento da sequência) e no segundo caso, a posição 0 iria conter o valor 18 (maior elemento). A operação de pesquisa consiste na exploração de um conjunto dado com o objectivo de localizar um determinado elemento. Por exemplo, um vector pode ser pesquisado a fim de encontrar o maior ou o menor dos seus elementos. No caso de um vector de caracteres, contendo nomes de pessoas, poderia ser feita uma pesquisa de forma a encontrar um determinado nome. As operações descritas, para além de frequentes, são operações que gastam muito do tempo de processamento de um computador. Esse tempo depende logo à partida da forma como os elementos do vector estão organizados inicialmente e, para além disso, dependem do número de elementos do vector e do algoritmo utilizado. Alguns algoritmos revelam-se eficazes se o vector for constituído por um número reduzido de elementos (algumas dezenas) mas tornam-se totalmente inadequados no caso de esse número ser elevado (da ordem das centenas ou milhares). Neste capítulo serão dados alguns exemplos de algoritmos de pesquisa e ordenação, sem entrar em linha de conta com alguns aspectos relacionados com a eficiência de cada um deles. O objectivo é apenas apresentar alguns métodos que permitem a resolução dos problemas de pesquisa e ordenação e também apresentar aplicações práticas de variáveis indexadas. Pesquisa O processo mais simples para encontrar um elemento particular num vector não ordenado consiste em percorrer esse vector sequencialmente até encontrar o elemento pretendido. Este método designa-se por pesquisa linear. pesquisa_linear( valor ) inteiro valor; { lógico encontrado = falso; inteiro índice = 0; enquanto índice < número_elementos e encontrado == falso faça { 8 se vector[ índice ] == valor então encontrado = verdadeiro; senão índice = índice + 1; } se encontrado == verdadeiro então escreva( "O valor foi encontrado." ); senão escreva( "O valor não existe no vector." ); } Programa 7.3. Pesquisa Linear num Vector. O programa 7.3 consiste num procedimento que admite a existência de um vector de números inteiros definido como variável global e cuja dimensão é estabelecida pela constante número_elementos. Neste procedimento, está definida uma variável lógica que determina o fim da instrução cíclica. Esta situação ocorre quando é encontrado o elemento a procurar. Caso contrário, o procedimento termina quando for alcançado o último elemento do vector. Note-se que a condição é índice < número_elementos e não índice <= número_elementos uma vez que o primeiro elemento do vector ocupa a posição 0, o que leva a que ao último elemento corresponda o índice número_elementos - 1. É de salientar que o tempo de pesquisa depende da posição do elemento a procurar e do número de elementos do vector. No programa 7.3, nada foi dito sobre a organização inicial do vector. Considere-se agora a situação de o vector estar ordenado de forma crescente antes de se iniciar a pesquisa. Neste caso, o processo de pesquisa pode ser melhorado, conduzindo a uma técnica designada por pesquisa binária. Este método consiste no seguinte: o vector é dividido em duas partes (aproximadamente), com um elemento central . Se o elemento a procurar for menor do que o elemento central, considera-se apenas a metade inferior do vector e repete-se o processo. Se o elemento a procurar for maior, procede-se de igual forma para a metade superior do vector. Por exemplo, aplicando este método para procurar o elemento 23 na sequência 4, 7, 9, 12, 23, 34, 39, o vector seria dividido em duas partes: a metade inferior, 4, 7, 9 e a metade superior, 23, 34, 39. O elemento central seria o elemento 12. Como este elemento era inferior ao elemento a procurar, considerava-se a metade superior e repetia-se o processo. A sequência a considerar seria 23, 34, 39 e o elemento central passaria a ser o elemento 34. Neste caso era considerada a metade inferior, ou seja, a sequência constituída pelo elemento 23, estando encontrado o valor pretendido (quinta posição da sequência). pesquisa_binária( valor ) Variáveis Indexadas 9 inteiro valor; /* valor a procurar */ { inteiro maximo = número_elementos - 1; /* limite superior */ inteiro minimo = 0; /* limite inferior */ inteiro elemento_central; lógico encontrado = falso; enquanto minimo <= maximo faça { elemento_central = trunca( ( minimo + maximo ) / 2 ); se valor < vector[ elemento_central ] então /* selecciona metade inferior */ maximo = elemento_central - 1; senão se valor > vector[ elemento_central ] então /* selecciona metade superior */ minimo = elemento_central + 1; senão { escreva( "O valor foi encontrado" ); encontrado = verdadeiro; } } se encontrado == falso então escreva( "O valor não existe no vector." ); } Programa 7.4. Pesquisa Binária num Vector Ordenado de Forma Crescente. O programa 7.4 é uma representação em linguagem PE do algoritmo descrito para a pesquisa binária num vector ordenado de forma crescente. O valor a pesquisar é o argumento do procedimento representado no programa, que assume a existência da variável indexada vector[], de dimensão número_elementos. Estudos realizados sobre a eficiência destes dois métodos permitiram concluir que, duma maneira geral, a pesquisa binária apresenta um desempenho superior à pesquisa linear. Ordenação A ordenação de um vector, de forma crescente ou decrescente, pode ser conseguida por vários processos. Existe um conjunto de algoritmos genéricos que executam esta operação e cujo desempenho é conhecido. Nesta secção serão apresentados dois desses métodos. O mais simples consiste em localizar os elementos 10 do vector, sucessivamente na ordem pretendida e colocá-los noutro vector que, terminado o método, irá conter os elementos do vector inicial já ordenados. Concretizando, para ordenar um vector de forma crescente, seria necessário pesquisar o vector até encontrar o menor elemento. Quando este elemento fosse encontrado, seria copiado para outro vector e colocado na primeira posição. Na célula ocupada por esse elemento no vector inicial, seria colocado um valor tal que a célula não fosse considerada nas iterações seguintes (por exemplo, um valor muito grande). O método prosseguiria até todos os elementos do vector terem sido analisados. Considere-se a sequência seguinte 6, 9, 1, 7, 5, 11, 4. Na primeira iteração, o método encontraria o valor 1 (menor valor da sequência). Este elemento seria o primeiro de uma nova sequência. No seu lugar, seria colocado um valor elevado, por exemplo, 999. A sequência ficaria 6, 9, 999, 7, 5, 11, 4. Na segunda iteração, o método localizava o valor 4, ficando a sequência com os valores 6, 9, 999, 7, 5, 11, 999. Por outro lado, a sequência ordenada apresentaria já os valores 1, 4. O método prosseguiria até ser obtida a sequência 1, 4, 5, 6, 7, 9, 11. ordenação_por_pesquisa() { inteiro iteração = 1, índice_minimo, índice; enquanto iteração <= número_elementos faça { índice_minimo = 0; índice = 1; enquanto índice < número_elementos faça { se vector [ índice ] < vector[ índice_minimo ] então índice_minimo = índice; índice = índice + 1 } Variáveis Indexadas 11 vector_auxiliar[ iteração ] = vector[ índice_minimo ]; vector[ índice_minimo ] = 100; iteração = iteração + 1; } } Programa 7.5. Ordenação de um Vector por Pesquisa de Elementos . O programa 7.5 apresenta o algoritmo de ordenação de um vector pelo método de pesquisa de elementos. O procedimento ordenação_por_pesquisa() assume, por uma questão de simplicidade, que as variáveis indexadas vector_auxiliar[] e vector[], de dimensão definida pela constante número_elementos, estão declaradas como variáveis globais. Neste programa considera-se que o vector a ordenar apenas poderia conter números inteiros inferiores a 100, daí que se tenha escolhido este valor para colocar nas células de onde eram retirados os elementos seleccionados. A variável inteira índice_minimo guarda o índice do vector correspondente ao menor elemento encontrado. A variável iteração corresponde ao número de vezes que o vector tem de ser percorrido. Em cada iteração, o algoritmo assume que o menor elemento é o primeiro, ou seja, o elemento vector[ 0 ]. Por esta razão, a variável índice é inicializada no valor 1, correspondente ao segundo elemento do vector (primeiro elemento a ser comparado), antes de o algoritmo iniciar uma nova iteração. A ordenação por pesquisa de elementos implica a utilização de um vector auxiliar. Esta situação não é vantajosa pois leva a que exista uma duplicação de espaço na memória do computador, para a definição desse vector. Um algoritmo que proceda à ordenação sem recorrer a este vector auxiliar será claramente preferencial. Existe outro método de ordenação, que não exige memória adicional e que é conhecido pela designação bubble sort (esta expressão poderá ser traduzida por borbulhante). ordenação_borbulhante() { inteiro j, i = 0, elemento_auxiliar; lógico trocas = verdadeiro; enquanto i <= número_elementos trocas == verdadeiro faça { j = número_elementos - 1; trocas = falso; enquanto j > i faça { se vector[ i ] < vector[ j ] então { trocas = verdadeiro; elemento_auxiliar = vector[ i ]; 12 vector[ i ] = vector[ j ]; vector[ j ] = elemento_auxiliar; } j = j - 1; } i = i + 1; } } Programa 7.6. Ordenação de um Vector pelo Método Borbulhante (Bubble Sort). De acordo com o algoritmo representado pelo programa 7.6 os elementos de menor valor vão assumindo posições inferiores no vector até este estar efectivamente ordenado. Este mecanismo sugere que estes elementos borbulham para o início do vector, vindo daí o nome do método. No final, a variável indexada vector[] ficará ordenada de forma crescente. A variável lógica trocas verifica se em cada iteração é efectuada alguma troca. Se não forem efectuadas trocas, isso significa que o vector está ordenado e o algoritmo termina. Erros mais Comuns Quando se utilizam variáveis indexadas é frequente surgirem erros, de natureza não sintática que constituem causas de mau funcionamento de programas. Nesta secção discutem-se alguns dos erros mais frequentes na manipulação de variáveis indexadas. Ultrapassar os Limites da Variável Ao percorrer as células de uma variável indexada deve-se ter especiais cuidados de forma a garantir que não são ultrapassados os limites inferior ou superior para cada uma das dimensões da variável. Tentar ler o conteúdo de uma célula não existente no vector implica, na generalidade das linguagens de programação, a ocorrência de um erro e a interrupção do programa. Por exemplo, a declaração real coordenadas[ 8 ][ 12 ]; define uma matriz de oito linhas por doze colunas. Para percorrer essa matriz, deve-se usar índices a variar entre 0 e 7 (8 - 1) para as linhas e entre 0 e 11 (12 - 1) para as colunas. A declaração de uma variável indexada define valores para as dimensões da variável que de forma alguma deverão ser ultrapassadas. Localizar a Primeira Célula Na linguagem PE, bem como em muitas linguagens de programação, a primeira célula de uma variável indexada assume o valor 0 para cada uma das dimensões. É frequente surgir o erro de considerar o valor Variáveis Indexadas 13 1 no lugar do valor 0, levando a que seja considerada uma célula diferente da pretendida. Por exemplo, dado o vector nomes[], o primeiro elemento do vector é referenciado nomes[0] por e não por nomes[1]. Conteúdo e Índice de uma Célula Em programadores principiantes surge por vezes alguma confusão entre o conteúdo de uma célula de uma variável indexada e as variáveis usadas como índices para aceder a essa célula. Esta distinção deverá ficar bem clara antes de elaborar programas que recorram a estas variáveis. 14 Exercícios 7.1. Construa uma função que permita calcular a média dos elementos de um vector de números inteiros. Considere que o vector é uma variável global já inicializada. 7.2. Escreva um procedimento que leia uma sequência de 100 números inteiros positivos e escreva o maior valor da sequência. O programa também deverá escrever o número de ocorrências desse valor e as posições de cada uma delas dentro da sequência. Os valores deverão ser armazenados num vector. 7.3. Desenvolver um programa que proceda à inversão da sequência dos elementos de um vector, ou seja, dado um vector na sequência 1, 5, 7, 3, 9, deve-se obter a sequência 9, 3, 7, 5, 1. 7.4. Considere um vector, de dimensão 1000, que armazena números inteiros positivos. Se o número de valores a armazenar for inferior ao máximo, as restantes células estarão preenchidas com o valor 0. Elabore uma função que retorne o comprimento (número de células preenchidas) do vector. Este deve ser definido como argumento da função. 7.5. Escreva um programa que aceite dois vectores de caracteres alfabéticos e verifique se as sequências são palíndromas (um palíndroma é uma palavra que é igual quer seja lida da esquerda para a direita quer seja lida da direita para a esquerda, como por exemplo, S A C A S). 7.6. Construa uma função que, dada uma matriz de números inteiros, permita obter a matriz transposta (a matriz transposta obtém-se por troca de linhas com colunas. Por exemplo, a linha 2 de uma matriz corresponderá à coluna 2 da matriz transposta). 7.7. Construa uma função que permita o cálculo da matriz inversa de uma matriz definida de forma a conter valores reais (ver a definição da Álgebra de matriz inversa). 7.8. Desenvolva um programa que dado um vector de inteiros, proceda à ordenação desse vector de forma decrescente e em seguida localize um valor dado, aplicando o método de pesquisa binária. 7.9. Altere o programa anterior de forma a que o utilizador possa decidir qual o método desejado para a pesquisa de um valor. No caso de pesquisa binária, o vector terá de ser ordenado previamente. Variáveis Indexadas 15 7.10. Escreva uma função que permita calcular o valor médio e o desvio padrão de um vector de números reais. 7.11. Analise a evolução do algoritmo do programa 7.6 para a sequência 1, 9, 3, 12, 5, 16, 21, 7, 9, 2, escrevendo os sucessivos estados do vector. 7.12. Escrever um programa que leia valores para um vector de números inteiros e calcule os valores máximo, mínimo e a média aritmética dos valores lidos. Divida o programa em subprogramas para: a) Ler valores para o vector. b) Calcular o máximo. c) Calcular o mínimo. d) Calcular a média. e) Imprimir os valores calculados. Resumo 1 As variáveis indexadas permitem o processamento de conjuntos de dados relacionados entre si. Estes conjuntos de dados são considerados como uma só entidade. Cada elemento do conjunto pode ser acedido individualmente. 2 As variáveis indexadas representam conjuntos de células que poderão conter valores de um determinado tipo (real, inteiro, lógico ou carácter). A definição do tipo das células de uma variável indexada é conseguida através da declaração respectiva. 3 As variáveis indexadas podem apresentar várias dimensões em oposição às variáveis do tipo escalar. Na linguagem PE foram definidas variáveis indexadas de uma dimensão (vectores) e variáveis indexadas de duas dimensões (matrizes). As células dos vectores e das matrizes necessitam de ser previamente inicializadas antes de se proceder à sua utilização. 4 As variáveis indexadas podem ser aplicadas a múltiplas situações. Destas, destacam-se as aplicações relativas a métodos de pesquisa e ordenação de elementos de um vector. Existem muitos algoritmos que permitem efectuar estas operações mas deve-se proceder a uma análise cuidada da eficiência de cada um deles antes de os aplicar a situações concretas.