Unconfigured Ad Widget

Collapse

Anúncio

Collapse
No announcement yet.

Estruturas Personalizadas

Collapse
X
 
  • Filter
  • Tempo
  • Show
Clear All
new posts

  • Font Size
    #1

    Delphi Estruturas Personalizadas

    Estruturas Personalizadas

    Bom, muitas vezes, quando se deseja guardar informações num programa utilizando variáveis vira uma bagunça pois são muitas variáveis para armazenar muita informação. Para isso utilizamos estruturas personalizadas.

    Suponha que você esteja recolhendo dados de um Cliente e deseja armazenar na memória antes de passar para um banco de dados. Vamos criar uma estrutura que permita armazenar o nome, telefone e idade do Cliente.

    Crie um novo projeto e em Interface coloque o seguinte:

    Código:
    type
      TCliente = record
        Nome: string;
        Telefone: string;
        Idade: integer;
      end;
    Agora temos uma estrutura com os subitens Nome, Telefone e Idade, agora vamos armazenar alguma coisa nela. Coloque um botão e 3 edits no form. Agora declare uma variável global Clientes:

    Código:
    var
      Form1: TForm1;
      Clientes: array of TCliente;
    Clientes irá armazenar cada cliente que o usuário entrar e cada cliente irá armazenar Nome, Telefone e Idade.

    Agora no onClick do botão coloque:

    Código:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Cliente: TCliente;
    begin
    Cliente.Nome:=Edit1.Text;
    Cliente.Telefone:=Edit2.Text;
    Cliente.Idade:=strtoint(Edit3.Text);
    SetLength(Clientes,Length(Clientes)+1);
    Clientes[high(Clientes)]:=Cliente;
    end;
    Pronto, agora você tem um vetor contendo todos os clientes com todas as informações. Para pegar o nome de algum cliente utilize, por exemplo:

    Código:
    showmessage(Clientes[0].Nome)
    Existe um jeito para diminuir o tamanho que essa estrutura ocupa na memória. Mas antes de falar disso tenho que explicar a diferença de strings definidas e indefinidas. Strings definidas são strings que têm um tamanho certo. Por exemplo:

    Código:
    var
    s: string[10];
    Essa string têm 10 caracteres mais o null terminator (#0), se você tentar por 15 caracteres nela, ela só vai pegar os 5 primeiros. Como caractere tem apenas 1 byte, essa string tem 10 bytes + 1byte do null terminator = 11bytes... Para ter certeza do tamanho dela utilize a função sizeof:

    Código:
    procedure TForm1.Button2Click(Sender: TObject);
    var
    s: string[10];
    begin
    showmessage(inttostr(sizeof(s)));
    end;
    Agora, uma string indefinida não é um conjunto de caracteres, é um pointer que aponta pra esse conjunto. Tanto que uma string indefinida pode ter o tamanho que você quizer, contanto que não estoure a memória. E o computador sabe até onde vai essa sequencia de caracteres por causa do null terminator, ele indica onde termina uma string indefinida. Mas um pointer tem apenas 4 bytes. Então, independente do tamanho da string, utilizando esse sizeof() obteremos apenas 4bytes, pois é o tamanho do pointer e não da sequencia de caracteres.

    Explicado isso, entendam porque vou utilizar strings definidas na estrutura para pegar o quanto de espaço que ela ocupa na memória. Outra coisa, como o comando "packed" diminui o alinhamento das variáveis na memória, vamos colocar a Idade que eh um integer no meio do Nome e do Telefone q sao strings, para dar uma diferença de alinhamento. Supondo o Nome como uma string com 20 caracteres e telefone como uma string de 10 caracteres (com DDD ), vamos ver o tamanho da estrutura, mas primeiro modifiquem as strings:

    Código:
    type
      TCliente = record
        Nome: string[20];
        Idade: integer;
        Telefone: string[10];
      end;
    Código:
    procedure TForm1.Button2Click(Sender: TObject);
    var
    Cliente: TCliente;
    begin
    showmessage(inttostr(sizeof(Cliente)));
    end;
    Deu 40 bytes certo?? 11 do Nome + 21 do Telefone + 4 da Idade + 4 de alinhamento = 40!! Agora vamos tentar com o packed:

    Código:
    type
      TCliente = packed record
        Nome: string[20];
        Idade: integer;
        Telefone: string[10];
      end;
    Código:
    procedure TForm1.Button2Click(Sender: TObject);
    var
    Cliente: TCliente;
    begin
    showmessage(inttostr(sizeof(Cliente)));
    end;
    Deu 36 bytes certo?? O que ele fez foi eliminar os bytes de alinhamento... Você pode pensar: "Pô, mas 4 bytes é pouca coisa, não??". Imaginem nosso exemplo acima da array de clientes. Suponha que uma empresa tenha 10.000 clientes, isso dá 10000 * 4 = 40000bytes = +- 40kb só de alinhamento na memória. Isso supondo que o nome tem apenas 20 caracteres e ela só tem essas informações dos clientes, numa empresa grande isso pode fazer muita diferença.

    Autor: Ace Ventura
    <<< ENGINEERING CODERZ - HACKING PROGRAMMING GROUP >>>
    msn/mail: azurus21@gmail.com
X
Working...
X