O Guia Definitivo para Entender Arrays

Fabio LützFabio Lütz
6 min read

Os arrays são estruturas de dados essenciais na programação, servindo como base para o gerenciamento eficiente de múltiplos valores. Seu domínio é crucial para o desenvolvimento de algoritmos e estruturas complexas, especialmente em contextos que demandam alto desempenho. Este artigo explora sua definição, funcionamento e tipos, além de destacar suas vantagens e limitações.

Definição

Um array é uma estrutura de dados que permite trabalhar com vários elementos utilizando apenas uma variável, de maneira simples. Suas principais características são:

  • Coleção de elementos: Permite trabalhar com diversos valores em apenas uma variável.

  • Homogêneo: Todos os valores devem ser de mesmo tipo.

  • Tamanho Predefinido:

    • Arrays estáticos: Têm um tamanho fixo, definido quando são criados, e não podem ser mudados.

    • Arrays dinâmicos: Podem mudar de tamanho quando necessário, mas isso usa muitos recursos do computador.

  • Alocação contígua: Os elementos são alocados todos juntos em sequência na memória.

Vantagens

  • Acesso direto: Os elementos são acessados diretamente por meio de um índice. Isso faz o acesso ter altíssima velocidade, independentemente do tamanho do array.

  • Armazenamento eficiente: Armazena apenas os valores, não necessitando de metadados para trabalhar com os valores.

  • Localidade espacial: Quando o processador carrega um elemento da memória para o cache, ele o extrai em bloco, incluindo espaços vizinhos. Como os valores do arrays são armazenados de forma contígua, se for necessário acessar outro valor logo em seguida, ele já estará no cache.

  • Facilidade de uso: Permite trabalhar com arrays de uma forma muito simples de entender. Principalmente para se trabalhar com estruturas multidimensionais, como tabelas, que são bidimensionais.

Desvantagens

  • Tamanho imutável: O tamanho não pode ser alterado após a declaração, necessitando alocar o tamanho máximo antes da utilização, em arrays estáticos.

  • Alocação prévia: Necessita que a alocação dos valores seja feita no momento da declaração, podendo haver desperdício de espaço.

  • Alocação contígua obrigatória: Exige que os valores estejam sempre juntos na memória, limitando quando é necessário trabalhar com tamanhos muito grandes.

  • Homogeneidade: Não permite trabalhar com valores diferentes em um único array.

  • Custo de gerenciamento no meio: Para operações de inserção e remoção de valores no meio do array, é necessário deslocar todos os valores, tendo um grande custo.

Funcionamento

Armazenamento contíguo

Os elementos de um array são armazenados sequencialmente na memória, ocupando posições adjacentes e sem espaços vazios entre eles. Isso significa que, se um array tem 5 elementos, eles serão alocados em 5 blocos de memória consecutivos.

Alocação

Ao declarar um array, dois parâmetros são definidos:

  • Tipo de dado: Define o tipo de dados que todos os elementos no array terão. Isso é muito importante para que possa ser alocado o tamanho, em bytes, que cada elemento ocupará.

  • Tamanho do array: Define quantos elementos o array terá, para poder alocar o tamanho total na memória.

É importante de saber isso previamente, pois, quando o array é declarado, a memória é reservada imediatamente e mantida até o fim de seu escopo.

Acesso

Índice

Os elementos são identificados por um índice, que é um valor numérico, que inicia-se em zero, ao invés de um. É utilizado para o desenvolvedor indicar qual elemento do array se deseja acessar.

É importante ter cuidado para não tentar acessar valores fora do intervalo do array, como passar o índice 4 para um array de 4 elementos, pois isso causará um erro ou comportamentos inesperados.

Cálculo

Como os valores ficam em sequência na memória, é possível acessar qualquer elemento apenas fazendo um simples cálculo matemático, permitindo acesso em velocidade altíssima para qualquer tamanho de array.

Para isso, é necessário saber:

  • Endereço base: O array armazena apenas o endereço do primeiro elemento na variável.

  • Índice: É o valor passado para identificar qual elemento deseja-se que seja acessado.

  • Tamanho do tipo: Tamanho necessário para armazenar o tipo do elemento do array, pois, normalmente, necessitam de mais do que um espaço na memória. Isso é necessário para poder realmente passar para o próximo elemento.

O cálculo para saber o endereço do elemento é feito da seguinte forma:

  • Endereço do elemento = Endereço base + ( Índice * Tamanho do tipo )

Exemplo:

  • Array de inteiros de tamanho 5, onde cada inteiro ocupa 4 bytes.

  • Acesso ao terceiro elemento, que é o índice 2:

    Endereço = 0x1000 + ( 2 * 4)

    Endereço = 0×1000 + 8

    Endereço = 0x1008

  • O sistema "pula" 8 bytes a partir do endereço base para ler o valor.

Acesso por iteração

Para percorrer todos os elementos do array, utiliza-se estruturas de repetição, permitindo filtrar elementos combinando com estruturas condicionais. Isso permite acessar e modificar elementos muito mais rapidamente.

Exemplo em pseudocódigo:

  • imprimir valores positivos em um array de inteiros de -3 a 3.

      números <- [-3, -2, -1, 0, 1, 2, 3]
      PARA índice DE 0 ATÉ 6 FAÇA
          SE (números[índice] > 0) ENTÃO
              ESCREVA(números[índice] + " ")
          FIM_SE
      FIM_PARA
    
  • Saída: 1 2 3

Tipos de arrays

Vetor

Array com apenas uma dimensão, sendo o array utilizado na maioria das vezes.

Matriz

Arrays podem conter outros arrays como elementos, permitindo formar estruturas multidimensionais. Para acessar os elementos, é necessário passar a posição do elemento em cada dimensão.

A estrutura mais comum de se representar são as matrizes, que são arrays bidimensionais.

Array dinâmico

Para superar a limitação de tamanho fixo, os arrays dinâmicos foram desenvolvidos. Elas são estruturas separadas dos arrays estáticos, mas existem na maioria das linguagens.

Seus principais aspectos são:

  • Redimensionamento Automático: Durante a execução, quando necessário, um novo array maior é criado, e os valores do array original são copiados para essa nova estrutura. Dessa forma, o array funciona como se tivesse um tamanho dinâmico.

  • Eficiência no Redimensionamento: Como cada alocação tem um custo alto de processamento, o novo tamanho geralmente aumenta mais do que apenas um espaço, seguindo múltiplos, como o dobro do anterior. Os espaços extras são preenchidos com um valor padrão para evitar erros.

Tupla

Para permitir utilizar valores heterogêneos, foi criado a tupla. Ela é uma estrutura separado do array e pode não ter em todas as linguagens ou, pelo menos, não da mesma forma.

Seus principais aspectos são:

  • Heterogeneidade: Permite que qualquer tipo de dado seja passado para cada elemento, sendo muito mais flexível que os arrays, que permitem apenas um.

  • Imutável: Por conta do cálculo não funcionar com dados heterogêneos, a tupla não permite que os valores presentes nela sejam alterados após a criação.

Conclusão

Entender arrays é fundamental para qualquer programador, pois eles são a base para estruturas de dados mais complexas e são cruciais para otimizar o desempenho dos programas. Com acesso direto, armazenamento eficiente e facilidade de uso, arrays são ferramentas poderosas na programação. No entanto, é importante conhecer suas limitações, como o tamanho fixo e a homogeneidade, para usá-los de forma eficaz. Ao dominar arrays, programadores podem criar soluções mais eficientes e robustas, aproveitando melhor os recursos computacionais disponíveis.

0
Subscribe to my newsletter

Read articles from Fabio Lütz directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Fabio Lütz
Fabio Lütz