Sem medo dos Ponteiros #1 - Introdução
Tags: codequality, c, pointers
Published: 2020-04-11 22:18:57

Na linguagens C e C++ é muito comum ouvirmos sobre ponteiros, referências e entregas de valor em um programa ou subprograma, mas o que de fato é um ponteiro e como consigo usar?

O objetivo desse artigo é trazer uma introdução sobre ponteiro na linguagem C (sim C, não se assuste), ao contrário do que muitos pensam C não é um bicho de sete cabeças e é uma linguagem bem bacana para se entender conceitos difíceis.

**Vale lembrar que o objetivo desse artigo não é ensinar sobre C ou C++, é para ensinar ou aguçar suas pesquisas sobre ponteiros :)**

> Para este artigo existem algumas coisas que você já deve saber:
> * Programação básica
> * Conceitos de gerenciamento de memória
> * Variáveis
> * Passagem de parâmetros

## Pré Requisitos
Vamos "colocar na mesa" alguns assuntos para que o que for falado sobre ponteiros não fique tão complicado.

**Memória** : Podemos definir como um conjunto de elementos que tem por sua função armazenar uma informação, esse armazenamento pode ser em vários níveis. Podemos usar como exemplo as palvavras, que são elementos marcados com um único valor, e ele valor é guardado em bytes à partir de um endereço de memória:


| Endereço   | Palavras   |   
| ------------- |:-------------:| 
| 1000 [0]  | primeiro| 
| 1001 [1]  | segundo  |  
| 1002  [2] | terceiro | 
| 1003  [3] | quarto |  
| 1004  [4] | quinto |  
| 1005  [5] | sexto |

Beleza, sabendo disso podemos dizer então que a memória é composta por palavras, Strings, e que cada uma delas possui seu espaço, e esses espaços são organizados da seguinte forma:

**Organização da memória**: No último artigo eu trouxe uma introdução ao gerenciamento de memória, mais especifiamente na JVM (Java Virtual Machine), se você quiser lê-lo só [clicar AQUI](https://dev.to/anabneri/jvm-por-debaixo-dos-panos-2-vmproperties-e-introducao-a-memoria-2llm).
No C não muda muito do Java, até por que Java é linguagem que foi baseada no C++, então veja como é realizada a organização da memória.

- Heap: é como uma área de alocação dinâmica, onde seu espaço é reservado para guardar as váriaveis e dados que são criados durante a execução do programa;
- Stack ou Pilha: é uma região também dinâmica da memória que é utilizada para armazenar o endereço de funções que foram chamadas e interrupções de chamadas de parâmetro;
- Dados: onde variáveis globais e estáticas são armazenadas;
- Programa: onde armazena as isntruções.


## Ponteiros,  que são, onde vivem, o que comem
Ponteiros são váriáveis que guardam endereços dentro da memória. 

Vejam no exemplo abaixo, temos a variável "A", e essa variável é um ponteiro e o "A" vai armazenar um endereço de "F".
Voltando na nossa tabela de endereços, vê-se então que "A", tem o valor de 1005

| Endereço   | Palavras   |   
| ------------- |:-------------:| 
| 1000 [1005]  | A| 
| 1001   | B  |  
| 1002   | C | 
| 1003   | D |  
| 1004   | E |  
| 1005   | F | 

Sendo assim podemos dizer que a variável "A" aponta pra variável "F" ou **A ---> F**

## Como declarar ponteiros
Ponteiros são declarados como ````tipo  *nome;```` , o asterisco identifica essa variável como ponteiro, por isso é muito importante o use, para identificar que será recebido um endereço.

Mesmo sendo endereços de memória precisamos usar os tipos, pois cada tipo tem tamanho diferente, e quando estamos seperando espacinhos da memória para serem endereçados, os mesmos dependem do tipo que for escolhido. Cada tipo ```float, Int, String..```, tem tamanhos diferentes, assim como a memória. 

## Operadores 

& <- usamos para trazer o endereço da variável
Por exemplo:

```int A; &A```
 estamos pegando o endereço que a variável "A" traz.

(*) <- pega o valor que os ponteiros trazem
Por exemplo:
```A``` , temos apenas o endereço
```*A``` estamos pegando o valor que a variável "A" traz.

## Exemplificando
Vamos supor que temos essas três variáveis: ```int count; int q; int *m;```

Nesse caso m recebe o endereço de count ```m = & count;``` , alocado na memória ficaria assim:

| Endereço   | Referência |    
| ------------- |:-------------:| 
| 1000   | count| 
| 1001   |   |  
| 1002   | | 
| 1003 [1000]  | *m |  

O que podemos dizer do quadro acima?

Que a variável ```*m``` está apontando para count, por isso ela esta armazenando o valor 1000 na sua posição, quando formos chamar por ```*m``` estaremos chamando pelo valor de 1000 não de 1003

Agora vamos colocar o valor de count igual a  6000 ```count=6000;``` , e dizer que a variável q é apontado por *m ```q=*m```

| Endereço   | Referência     
| ------------- |:-------------:| 
| 1000 [6000] | count| 
| 1002 [6000]  | q | 
| 1003 [1000]  | *m |  

Se ```*m``` está apontando para ```count``` e o mesmo tem o valor de 6000 então como ```q``` esta atribuindo o valor de ```*m``` então o valor à qual ```q``` aponta é 6000.

## TOMA CUIDADO COM OS PONTEIROS
Usar ponteiros em sistemas de larga escala pode ser muito perigoso, pois como duas ou mais variáveis não têm um valor, mas sim um endereço de memória, então quando o tamanho da memória é mudado, impactada as demais variáveis que estavam fazendo referência ao mesmo.

Next Steps: No próximo artigo vamos usar código, realizando um programa em C, vamos ver como funcionam os ponteiros através de um desafio :D, animou?

> Deixa seu feedback e possíveis dúvidas nos comentários

Referências:
https://www.embarcados.com.br/ponteiro-em-c-definicao/
https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/

![thank you next, gif do videoclip da ariana grande](https://media.giphy.com/media/MT9MOLJXrXfVvMJ34C/giphy.gif)