Propaganda

Quer você perceba ou não, a grande maioria dos programas que você usou utiliza ponteiros de alguma forma. Talvez você tenha experimentado um Null Pointer Exception em algum ponto. Como programador, o código que você escreve provavelmente usará ponteiros, mesmo que você não os tenha implementado.

Hoje vou mostrar como os ponteiros funcionam, então você pode conferir como matrizes e listas funcionam Como matrizes e listas funcionam em PythonMatrizes e listas são algumas das estruturas de dados mais úteis na programação - embora poucas pessoas as utilizem em todo o seu potencial. consulte Mais informação para um iniciador de programação. Este artigo será mais baseado em teoria do que o habitual, mas fique com ele, os ponteiros são muito complexos!

Código de compilação

Antes de procurar nos ponteiros, você precisa entender como o código é criado e executado - talvez você já saiba disso. Esta seção terá declarações bastante gerais - coisas que se aplicam ao maioria de idiomas, mas não necessariamente todos eles.

instagram viewer
Ponteiros

Vamos levar as coisas de volta ao início. Todo computador usa binário O que é binário? [Tecnologia explicada]Dado que o binário é tão absolutamente fundamental para a existência de computadores, parece estranho que nunca tenhamos abordado o assunto antes - então hoje eu pensei em dar uma breve visão geral do que é binário ... consulte Mais informação , uma série de uns e zeros que compõem a tecnologia moderna como a conhecemos. É extremamente difícil codificar qualquer coisa em binário (os arquivos seriam muito confusos), pois essas são as instruções brutas necessárias ao seu unidade central de processamento ou CPU para funcionar O que é uma CPU e o que ela faz?Acrônimos de computação são confusos. O que é uma CPU, afinal? E preciso de um processador quad ou dual-core? E quanto à AMD ou Intel? Estamos aqui para ajudar a explicar a diferença! consulte Mais informação . Isso é conhecido como Código da máquina.

A próxima etapa do código da máquina é Montagem. Este é um formato legível para humanos. Embora ainda seja complexo programar, é possível. O assembly é composto de uma série de comandos simples para executar tarefas e é conhecido como um nível baixo linguagem de programação. É possível escrever programas complexos, mas é difícil expressar conceitos abstratos e requer muita consideração.

Muitos videogames e aplicativos de alto desempenho possuem parte da lógica escrita em assembly, pois alguns aumentos reais de velocidade podem ser encontrados se você souber o que está fazendo. No entanto, para a grande maioria dos projetos de programação, você não precisa conhecer nenhuma montagem.

Ponteiros

Portanto, se o código da máquina é muito difícil de escrever e a montagem é muito difícil de programar, com o que você escreve o código? Aqui é onde alto nível idiomas entram. Linguagens de alto nível facilitam a gravação de programas. Você pode programar algo semelhante ao seu idioma nativo e é fácil expressar algoritmos complexos. Você já deve ter ouvido falar de muitos idiomas de alto nível (e definitivamente usará um programa escrito neles):

  • BASIC
  • C ++
  • Lisp

Essas línguas são muito antigas agora e muitas foram desenvolvidas no início dos anos 50! Quase toda linguagem de programação moderna é uma linguagem de alto nível, incluindo PHP e Python. Há mais idiomas sendo inventados todos os dias (embora provavelmente exista o suficiente agora), mas como exatamente seu código ainda funciona corretamente se os computadores exigirem código de máquina?

Aqui é onde entra a compilação. Um compilador é um programa que converte seu código de alto nível em um formulário que pode ser executado. Pode ser outro idioma de alto nível, mas geralmente é assembly. Algumas linguagens (como Python ou Java) convertem seu código em um estágio intermediário chamado bytecode. Isso precisará ser compilado novamente posteriormente, o que geralmente é feito sob demanda, como quando o programa é executado. Isso é conhecido como na hora certa compilação e é bastante popular.

Gerenciamento de memória

Agora que você sabe como as linguagens de programação funcionam, vejamos o gerenciamento de memória em linguagens de alto nível. Para esses exemplos, eu usarei pseudo-código - código escrito não em nenhum idioma específico, mas usado para mostrar conceitos em vez de sintaxe exata. Hoje, isso se parecerá com o C ++, pois é a melhor linguagem de alto nível (na minha opinião).

Nesta seção, ajudará se você tiver um entendimento de como funciona a RAM Um guia rápido e sujo da RAM: o que você precisa saberA RAM é um componente crucial de qualquer computador, mas pode ser confusa. Nós a dividimos em termos fáceis de entender que você entenderá. consulte Mais informação .

A maioria dos idiomas possui variáveis ​​- contêineres que armazenam alguns dados. Você precisa definir explicitamente o tipo de dados. Algumas linguagens de tipo dinâmico, como Python ou PHP, lidam com isso para você, mas ainda precisam fazer isso.

Digamos que você tenha uma variável:

int myNumber;

Este código declara uma variável chamada meu numeroe fornece um tipo de dados de inteiro. Uma vez compilado, o computador interpreta esse comando como:

“Encontre memória vazia e reserve um espaço grande o suficiente para armazenar um número inteiro”

Depois que esse comando é executado, esse bit de memória não pode ser usado por outro programa. Ainda não contém dados, mas está reservado para sua variável myNumber.

Agora atribua um valor à sua variável:

myNumber = 10;

Para concluir esta tarefa, seu computador acessa o local reservado da memória e altera qualquer valor armazenado nele para esse novo valor.

Agora, tudo está bem, mas como os locais de memória ficam sem reserva? Se os programas reservassem toda a memória que quisessem, a RAM seria preenchida imediatamente - o que tornaria muito sistema lento.

Ponteiros

Para evitar esse possível problema, muitos idiomas implementam um coletor de lixo, usado para destruir variáveis ​​(e, portanto, liberar os locais de memória reservados) que foram fora de escopo.

Você pode estar se perguntando o que é escopo e por que é tão importante. O escopo define os limites e a vida útil das variáveis ​​ou de qualquer memória usada por um programa. Uma variável está "fora do escopo" quando não pode mais ser acessada por nenhum código (é quando o coletor de lixo entra em ação). Aqui está um exemplo:

função maths () {int firstNumber = 1; } int secondNumber = 2; print (primeiroNúmero + segundoNúmero); // não funciona

Este exemplo não será compilado. A variável firstNumber está dentro do Matemáticas função, então esse é o seu escopo. Ele não pode ser acessado de fora da função em que foi declarado. Este é um importante conceito de programaçãoe entender que é crucial trabalhar com ponteiros.

Essa maneira de lidar com a memória é chamada de pilha. É assim que a grande maioria dos programas funciona. Você não precisa entender os ponteiros para usá-lo, e é bem estruturado. A desvantagem da pilha é a velocidade. Como o computador precisa atribuir memória, acompanhar as variáveis ​​e executar a coleta de lixo, há uma pequena sobrecarga. Isso é bom para programas menores, mas e as tarefas de alto desempenho ou os aplicativos com muitos dados?

Digite: ponteiros.

Ponteiros

Na superfície, os ponteiros parecem simples. Eles fazem referência (aponta para) um local na memória. Isso pode não parecer diferente das variáveis ​​"regulares" na pilha, mas confie em mim, há uma enorme diferença. Os ponteiros são armazenados no amontoar. É o oposto da pilha - é menos organizado, mas é muito mais rápido.

Vamos ver como as variáveis ​​são atribuídas na pilha:

int numberOne = 1; int numberTwo = numberOne;

Esta é uma sintaxe simples; A variável número dois contém o número um. Seu valor é copiado durante a atribuição do número um variável.

Se você queria obter o endereço de memória de uma variável, em vez de seu valor, você deve usar o sinal "e" comercial (&). Isso é chamado de endereço de operador e é uma parte essencial do seu kit de ferramentas de ponteiro.

int numberOne = 1; int numberTwo = & numberOne;

Agora o número dois variável pontos para um local de memória, em vez de copiar o número um para o novo local de memória. Se você produzisse essa variável, ela não seria a número um (mesmo que esteja armazenada no local da memória). Ele produziria a localização da memória (provavelmente algo como 2167, embora varie dependendo do sistema e da RAM disponível). Para acessar o valor armazenado em um ponteiro, em vez do local da memória, é necessário desreferência o ponteiro. Isso acessa o valor diretamente, que seria o número um nesse caso. Veja como você desfere um ponteiro:

int numberTwo = * numberOne;

o operador de desreferência é um asterisco (*).

Esse pode ser um conceito difícil de entender, então vamos repassá-lo novamente:

  • o endereço de O operador (&) armazena o endereço da memória.
  • o operador de desreferência (*) acessa o valor.

A sintaxe muda um pouco ao declarar ponteiros:

int * myPointer;

O tipo de dados de int aqui se refere ao tipo de dados que o ponteiro pontos para e não o tipo do ponteiro em si.

Agora que você sabe o que são ponteiros, pode fazer alguns truques realmente legais com eles! Quando a memória é usada, o sistema operacional inicia sequencialmente. Você pode pensar na RAM como buracos de pombo. Muitos furos para armazenar algo, apenas um pode ser usado de uma só vez. A diferença aqui é que esses buracos de pombo estão todos numerados. Ao atribuir memória, o sistema operacional inicia no número mais baixo e funciona. Nunca vai pular entre números aleatórios.

Ponteiros

Ao trabalhar com ponteiros, se você tiver atribuído uma matriz, poderá navegar facilmente para o próximo elemento, incrementando seu ponteiro.

Aqui é onde fica interessante. Quando você passa valores para uma função (usando variáveis ​​armazenadas na pilha), esses valores são copiados para sua função. Se essas são grandes variáveis, o programa agora está armazenando-as duas vezes. Quando sua função é concluída, você pode precisar de uma maneira de retornar esses valores. As funções geralmente podem retornar apenas uma coisa - e se você quiser retornar duas, três ou quatro coisas?

Ponteiros

Se você passar um ponteiro para sua função, apenas o endereço da memória será copiado (o que é minúsculo). Isso economiza muito trabalho para sua CPU! Talvez seu ponteiro aponte para uma enorme variedade de imagens - sua função não só pode funcionar exatamente da mesma maneira dados armazenados no mesmo local de memória, mas, uma vez feito, não há necessidade de retornar qualquer coisa. Arrumado!

Você precisa ter muito cuidado. Os ponteiros ainda podem ficar fora do escopo e serem coletados pelo coletor de lixo. Os valores armazenados na memória, no entanto, não são coletados. Isso é chamado de vazamento de memória. Você não pode mais acessar os dados (pois os ponteiros foram destruídos), mas eles ainda estão usando memória. Esse é um motivo comum para muitos programas travarem e pode falhar espetacularmente se houver uma grande quantidade de dados. Na maioria das vezes, seu sistema operacional mata o seu programa se você tiver um vazamento grande (usando mais RAM do que o sistema), mas isso não é desejável.

Ponteiros

Ponteiros de depuração podem ser um pesadelo, especialmente se você estiver trabalhando com grandes quantidades de dados ou trabalhando em loops. Suas desvantagens e dificuldade de entender realmente valem as compensações que você obtém no desempenho. Embora lembre-se, eles nem sempre podem ser necessários.

Por hoje é isso. Espero que você tenha aprendido algo útil sobre um tópico complexo. Obviamente, não cobrimos tudo o que há para saber - é um tópico muito complexo. Se você estiver interessado em aprender mais, eu recomendo C ++ em 24 horas.

Se isso foi um pouco complexo, dê uma olhada nosso guia para as linguagens de programação mais fáceis 6 idiomas de programação mais fáceis de aprender para iniciantesAprender a programar é encontrar o idioma certo tanto quanto o processo de edificação. Aqui estão as seis principais linguagens de programação mais fáceis para iniciantes. consulte Mais informação .

Você aprendeu como os ponteiros funcionam hoje? Você tem dicas e truques que deseja compartilhar com outros programadores? Entre nos comentários e compartilhe seus pensamentos abaixo!

Joe é graduado em Ciência da Computação pela Universidade de Lincoln, Reino Unido. Ele é um desenvolvedor de software profissional e, quando não está pilotando drones ou escrevendo músicas, pode ser encontrado tirando fotos ou produzindo vídeos.