Continuando o post anterior, damos seqüência mostrando o artigo do HowStuffWorks que fala sobre o porquê de se usar ponteiros e fazendo um paralelo com a sua utilização no Pascal / Delphi.
Ponteiros: por quê?
Imagine que você gostaria de criar um editor de texto: um programa que permite editar arquivos de texto ASCII normal, como o “vi”, do UNIX, ou o “Bloco de notas”, do Windows. Um editor de textos é uma coisa bastante comum para alguém criar, pois é provavelmente o segmento de software mais usado pelo programador. O editor de textos é a ligação íntima de um programador com o computador, pois é nele que o programador digita todas as suas idéias e as organiza. Obviamente, como qualquer coisa que você utilize com tanta freqüência e com a qual trabalhe constantemente, você também vai desejar que o editor de textos funcione perfeitamente. Assim, muitos programadores criam seus próprios editores e os personalizam para atender seus estilos e preferências de trabalho individuais.Então, em um certo dia, você se senta para começar a trabalhar em seu editor. Depois de pensar sobre as características que deseja, você começa a pensar sobre a “estrutura de dados” de seu editor. Quer dizer, começa a pensar sobre como armazenará o documento que está editando na memória, de forma que possa manipulá-lo em seu programa. O que você precisa é de um modo para armazenar as informações inseridas de forma que possam ser manipuladas rápida e facilmente. Você acredita que um modo de fazer isso é organizar os dados com base na linha de caracteres. Visto o que já foi discutido, a única coisa disponível aqui é a matriz. Você pensa: “Bem, uma linha típica tem 80 caracteres de comprimento e um arquivo típico não tem mais do que mil linhas”. Assim, você declara uma matriz bi-dimensional como esta:
char doc[1000][80];
Em Pascal/Delphi, teriamos:
var Doc: array[0..999, 0..79] of Char;
Esta instrução solicita uma matriz de mil linhas com 80 caracteres. Esta matriz tem um tamanho total de 80 mil caracteres.
Enquanto pensa sobre o editor e sua estrutura de dados, você pode se dar conta de três coisas:
Alguns documentos são listas longas. Cada linha é curta, mas há milhares de linhas;Alguns arquivos de texto com finalidade especial possuem linhas muito longas. Por exemplo, certo arquivo de dados poderia ter linhas contendo 542 caracteres, com cada caractere representando um par de aminoácidos do DNA;
Na maioria dos editores modernos, você pode abrir múltiplos arquivos de uma só vez.
Digamos que você determinou um máximo de 10 arquivos abertos por vez, um comprimento máximo de linha de 1 mil caracteres e um tamanho de arquivo máximo de 50 mil linhas. Sua declaração agora se parecerá com:char doc[50000][1000][10];
var Doc: array [0..49999, 0..999, 0..9] of Char;
Não parece uma coisa absurda, até você pegar sua calculadora, multiplicar 50 mil por 1 mil e depois por 10 e constatar que a matriz irá conter 500 milhões de caracteres! Atualmente, a maioria dos computadores tem problemas com matrizes deste tamanho. Eles não têm a memória RAM, ou até mesmo o espaço de memória virtual para suportar uma matriz desse tamanho. Se os usuários tentassem executar três ou quatro cópias deste programa simultaneamente, mesmo num sistema multiusuário maior, isso poderia representar um esforço muito grande a suas instalações.
Mesmo que o computador aceitasse uma solicitação para uma matriz tão grande, você veria que isto seria um desperdício extravagante de espaço. Parece estranho declarar uma matriz de 500 milhões de caracteres se, na maioria dos casos, você executará este editor para pesquisar arquivos de 100 linhas, que consomem no máximo 4 ou 5 mil bytes. O problema com uma matriz é o fato de que você precisa declará-la como tendo o tamanho máximo em cada dimensão, desde o começo. Os tamanhos máximos freqüentemente se multiplicam para formar números muito grandes. Também, se precisar editar um arquivo que ocasionalmente possua 2 mil carcacteres em uma linha, você terá problemas. Não há como prever e manipular o comprimento máximo de uma linha de um arquivo de texto, pois, tecnicamente, este número é infinito.
Os ponteiros são projetados para resolver esse problema. Com eles, você pode criar estruturas dinâmicas de dados. Em vez de declarar o pior caso de consumo de memória com antecedência em uma matriz, você aloca memória da pilha enquanto o programa está sendo executado. Dessa forma, você pode usar a quantia exata de memória que o documento precisa, sem desperdício. Além disso, quando você fecha um documento, pode devolver a memória à pilha para que outros trechos do programa possam usá-la. Com os ponteiros, a memória pode ser reciclada enquanto o programa está sendo executado.
Aqui o autor do artigo explica o porquê de se usar ponteiros, usando como exemplo a questão de alocação dinâmica de matrizes. Assim como a linguagem C, as versões antigas do Pascal e Delphi (até a versão 4), não tinham o conceito de matrizes dinâmicas e eramos obrigados a utilizar ponteiros. A partir a versão 5 do Delphi, permite-se utilizar a seguinte sintaxe:
var Doc: array of string;
e dentro do código basta usar o procedimento SetLength, para definirmos o tamanho da alocação:
SetLength(Doc, 1000);
Veja que o segundo paramêtro pode ser uma variável e com isso temos durante a execução do programa a alocação de quanto queremos de espaço em memória.
A propósito, se você leu a discussão anterior e uma de suas grandes dúvidas continua sendo “o que é, de fato, um byte?”, então o artigo Como funcionam os bits e os bytes irá ajudá-lo a compreender esses conceitos e também coisas como “mega”, “giga” e “tera”. Dê uma olhada nele e depois volte aqui.
0 Respostas para “Ponteiros no Pacal / Delphi - O Porquê”
Deixe uma Resposta