Arrays Dinâmicos no Delphi

Veja neste artigo como trabalhar com arrays dinâmicos no Delphi, uma forma de manipular essas estruturas de dados sem que seja necessário definir suas dimensões no momento da declaração.

As variáveis são os elementos básicos que um programa manipula e representam espaços reservados na memória do computador para armazenar valores de um determinado tipo de dados.

O tipo de dados para uma variável é escolhido de acordo com a natureza da informação analisada e define que valores a variável pode assumir (representação interna da memória desses valores) e que operações podem ser realizadas com essa variável.

De forma resumida, os tipos de dados podem ser classificados em dois grupos:

Guia Completa Acesse Programador Delphi

Em uma variável declarada a partir dos tipos de dados simples é permitido o armazenamento de um único valor por vez. Para agrupar e manipular diversos valores em uma mesma estrutura deve-se utilizar os tipos de dados estruturados, como por exemplo, os vetores.

Vetores (ou arrays)

Os vetores são estruturas de dados que armazenam usualmente uma quantidade fixa de valores do mesmo tipo (estrutura homogênea). Em variáveis do tipo vetor podem ser armazenados um grupo de valores, cada um associado a um número que se refere à posição de armazenamento. O número de posição do valor é conhecido como índice ou subscrito do valor. Portanto, os vetores são estruturas indexadas, em que cada valor que pode ser armazenado em certa posição (índice) é chamado de elemento do vetor.

Aplicações que utilizam vetores implementam uma forma de agrupar e manipular diversos valores (ou elementos) em uma mesma estrutura de dados. A individualização é feita associando a cada elemento do vetor um número que se refere à posição de armazenamento (variáveis indexadas), por exemplo: a[i], de forma geral se refere ao i-ésimo elemento do vetor a.

Na declaração de vetores deve-se obedecer a seguinte sintaxe:

Onde:

Na Listagem 1 pode-se observar as declarações das seguintes variáveis do tipo vetor:

const n = 100; // tamanho da variável "vetorC" nl = 4; // número de linhas da variável "matrizB" nc = 5; // número de colunas da variável "matrizB" type rg = record campo1: integer; campo2: string[35]; end; // vetores unidimensionais var vetorA: array[1..10] of integer; vetorB: array[10..20] of real; vetorC: array[1..n] of rg; // vetores bidimensionais (matrizes) matrizA: array[1..3, 1..3] of integer; matrizB: array[1..nl, 1..nc] of integer; // índices ou subscritos i, j: integer; // Fazendo referência a um determinado elemento: vetorA[i]: i-ésimo elemento do vetor "vetorA" vetorC[3].campo1: denotando o campo "campo1" do 3 º registro do vetor "vetorC" vetorC[3]. campo1: denotando o campo "campo2" do 3 º registro do vetor "vetorC" matrizA[i, j]: elemento da i - ésima linha e j - ésima coluna da matriz "matrizA"
Listagem 1. Declarando variáveis do tipo vetor

Vetores dinâmicos

Na declaração de um tipo de dados usando a construção de arrays, é necessário especificar o número de elementos do array. Para criar um vetor dinâmico também deve-se utilizar a declaração array, informando o tipo dos elementos do vetor (ou tipo base). A diferença é que, neste caso, não é necessário informar os índices que definem o tamanho. Essa informação é fornecida em tempo de execução, fazendo alocação dinâmica de memória, através do procedimento SetLength como pode ser observado na Listagem 2.

// Na declaração dos arrays dinâmicos não é necessário informar os índices var vetor: array of integer; matriz: array of array of integer; // 1. Criando um vetor com 10 elementos indixados de 0 até 9 SetLength(vetor, 10); // 2. Redimensionando o vetor para 20 elementos indexados de 0 até 19. // Neste caso, os 10 elementos anteriores do vetor são mantidos. SetLength(vetor, 20); // 3. Criando uma matriz 2 X 4 SetLength(matriz, 2); SetLength(matriz[0], 4); SetLength(matriz[1], 4);
Listagem 2. Declarando e criando arrays dinâmicos

Como na criação de um array dinâmico especifica-se apenas o tamanho do vetor, os índices por default são definidos sempre no intervalo do 0 (zero) até tamanho do vetor menos 1.

Outro aspecto importante na utilização de arrays dinâmicos diz respeito à liberação da memória alocada que deve ser realizada usando o procedimento Finalize.

Para obter informações sobre uma estrutura de dados array tem-se as seguintes funções:

Estudo de caso 1- Vetor e Matriz

Nesta primeira aplicação, apresentada na Figura 1, o usuário final escolhe através de um componente RadioGroup o tipo do array (vetor ou matriz), informa o tamanho do vetor e através do botão com a legenda "Criar o Vetor" ou "Criar a Matriz", definida conforme a escolha. Será criado o array dinamicamente.

Figura 1. Criando dinamicamente uma matriz

A Listagem 3 apresenta o código completo da unit do formulário da aplicação (Figura 1) desenvolvida para demonstrar a utilização de arrays dinâmicos (variáveis "vetor" e "matriz").

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Buttons; type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Button1: TButton; Button2: TButton; RadioGroup1: TRadioGroup; Memo1: TMemo; procedure RadioGroup1Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation { $R * .dfm } var vetor: array of integer; matriz: array of array of integer; n: integer; // tamanho do vetor // RadioGroup para selecionar o "Tipo do Array" procedure TForm1.RadioGroup1Click(Sender: TObject); begin if (RadioGroup1.ItemIndex = 0) then begin Button1.Caption: = "Criar o Vetor"; Label1.Caption: = "Tamanho do Vetor:"; end else begin Button1.Caption: = "Criar a Matriz "; Label1.Caption := " Ordem da Matriz: "; end; end; // Botão "Criar Vetor" procedure TForm1.Button1Click(Sender: TObject); var i, j: integer; s: string; begin try n: = StrToInt(Edit1.Text); randomize; if (RadioGroup1.ItemIndex = 0) then begin SetLength(vetor, n); // cria o vetor dinamicamente for i:=low(vetor) to high(vetor) do begin vetor[i] := random(100); Memo1.Lines.Add(Format("vetor[%2d] = % 2 d ", [i, vetor[i]])); end; end else begin SetLength(matriz, n); // cria a matriz dinamicamente for i:=low(matriz) to high(matriz) do begin s: = Format("%2da. linha = ", [i + 1]); // cria a i-ésima linha da matriz dinamicamente SetLength(matriz[i], n); for j: = low(matriz[i]) to high(matriz[i]) do begin matriz[i, j]: = random(100); s: = s + Format("%2d ", [matriz[i, j]]); end; Memo1.Lines.Add(s); end; end; Button1.Enabled: = False; Button2.Enabled: = True; except end; end; // Botão "Liberar Memória" procedure TForm1.Button2Click(Sender: TObject); begin if (RadioGroup1.ItemIndex = 0) then Finalize(vetor) else Finalize(matriz); Button1.Enabled: = True; Button2.Enabled: = False; Memo1.Clear; end; end.
Listagem 3. Aplicação para criar arrays dinâmicos

Estudo de caso 2 - Controle de Notas Escolares

Nesta segunda aplicação, apresentada na Figura 2, é possível realizar um controle de notas escolares. O usuário final deverá informar o nome do aluno e suas respectivas notas escolares. O botão "Gravar Aluno" adiciona o aluno informado no final do array. Já o botão "Limpa Campos" deverá ser utilizado para limpar os componentes de entrada de dados. Para mostrar todos os alunos do conjunto no componente Memo deve-se pressionar o botão "Ler Alunos".

Figura 2. Realizando um controle de notas escolares

A Listagem 4 apresenta o código completo da unit do formulário da aplicação (Figura 2) desenvolvida para realizar o controle de notas escolares a partir das informações "nome", "nota1" e "nota2", previstas no registro de dados "rgAluno". No vetor dinâmico "aluno" será armazenado os registros de alunos informados pelo usuário.

unit unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls; type TForm1 = class(TForm) Label1: TLabel; Button1: TButton; BitBtn1: TBitBtn; edAluno: TEdit; edNota1: TEdit; edNota2: TEdit; Label2: TLabel; Label3: TLabel; Memo1: TMemo; Button2: TButton; Button3: TButton; procedure edNota1KeyPress(Sender: TObject; var Key: Char); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); end; var Form1: TForm1; implementation { $R * .DFM } type rgAluno = record nome: string[35]; nota1: real; nota2: real; end; var aluno: array of rgAluno; n: integer = 0; // tamanho do vetor x: rgAluno; // Evento "OnKeyPress" dos Edits "1a. Nota" e "2a. Nota" // Verificando e aceitando somente valores numéricos do tipo real procedure TForm1.edNota1KeyPress(Sender: TObject; var Key: Char); begin if (Key in [".", ","]) then if (pos(",", (Sender as TEdit).Text) = 0) then Key: = "," else Key: = #7 else if (not(Key in ["0".."9", # 8])) then Key: = #7; end; // Botão "Gravar Aluno" procedure TForm1.Button1Click(Sender: TObject); begin { verifica se todos os campos foram informados } if ((edAluno.Text <> "") and (edNota1.Text <> "") and (edNota2.Text <> "")) then begin x.nome := edAluno.Text; x.nota1: = StrToFloat(edNota1.Text); a x.nota2: = StrToFloat(edNota2.Text); n: = n + 1; // redimensiona o vetor "aluno" aumentando uma posição // para adicionar o novo aluno no final do conjunto SetLength(aluno, n); aluno[n-1] := x; Memo1.Lines.Add(x.nome + ", gravado com sucesso."); end; end; // Botão "Ler Alunos" procedure TForm1 .Button2Click(Sender: TObject); var nreg, i: integer; media: real; begin Memo1.Lines.Add(""); nreg: = 0; for i: = 0 to n - 1 do begin x: = aluno[i]; nreg: = nreg + 1; { processando e exibindo os dados recuperados } media: = (x.nota1 + x.nota2) / 2; Memo1.Lines.Add("Registro Nro.: " + IntToStr(nreg)); Memo1.Lines.Add("Nome do Aluno: " + x.nome); Memo1.Lines.Add("1a. nota.....: " + Format("%.2f", [x.nota1])); Memo1.Lines.Add("2a. nota.....: " + Format(" % .2 f ", [x.nota2])); Memo1.Lines.Add(" Média........: " + Format(" % .2 f ", [media])); if (media >= 6.0) then Memo1.Lines.Add("Situação.....: Aprovado") else Memo1.Lines.Add("Situação.....: Reprovado"); Memo1.Lines.Add(""); end; end; // Botão "Limpar Campos" procedure TForm1 .Button3Click(Sender: TObject); begin edAluno.Clear; edNota1.Clear; edNota2.Clear; end; end.
Listagem 4. Aplicação para realizar um controle de notas escolares usando arrays dinâmicos

O código fonte das aplicações encontra-se disponível para download no topo dessa página.


Links Úteis

  • Curso de Xamarin: O Xamarin é uma plataforma para desenvolvimento de aplicações móveis dentro da plataforma .NET, utilizando o C#. A grande vantagem dessa plataforma é a possibilidade de compartilhar código entre as muitas plataformas - iOS, Android e Windows
  • Curso de Django: Neste curso aprenderemos a trabalhar com o Django, o principal framework Python da atualidade. Conheceremos sua arquitetura MTV, seu sistema de rotas, e criaremos uma aplicação de CRUD completa.
  • Segurança de web services em Java com controle de acesso: Neste curso vamos aprender a programar um mecanismo de autorização para controle de acesso às diferentes funcionalidades oferecidas por uma Web API RESTful, configurando para três tipos de usuário (cliente, funcionário e administrador) diferentes tipos de permissão.

Saiba mais sobre Delphi ;)

  • Carreira Programador Delphi: Neste guia de estudos você encontra os conteúdos que precisará para se tornar um programador Delphi completo. Confira a sequência de cursos e exemplos que te guiarão do básico ao avançado em Delphi.
  • Guia Completo de Delphi: Neste Guia de Referência você encontrará o conteúdo que precisa para iniciar seus estudos em Delphi, uma plataforma para desenvolvimento de aplicativos completa, principalmente para soluções desktop e mobile.
  • Como manipular XML em Delphi: Neste curso você aprenderá a ler e gerar arquivos no formato XML. Aprender a manipular arquivos XML é necessário para desenvolver uma aplicação de Nota Fiscal Eletrônica (NF-e), por exemplo, pois toda a transmissão de informações é realizada com arquivos XML.

Artigos relacionados