Entender Apontadores em C

Antes de mais o que é um apontador em português corrente? É algo que aponta para alguma coisa, certo? Ok… Então vejamos este exemplo:

O que é o ponteiro de um relógio? É o que aponta para as horas, minutos ou segundos. Em programação é muito semelhante temos as variáveis e o ponteiro vai apontar para o local da memória onde elas se encontram armazenadas que veremos mais à frente chamar-se de endereço da memória.

Arquitectura

“Ponteiros são uma abstracção da capacidade de endereçamento fornecidas pelas arquitecturas modernas. Em termos simples, um endereço de memória é definido para cada unidade de memória no sistema, no qual a unidade é tipicamente um byte ou um char, o que em termos práticos transforma toda a memória num grande vector. Logo, a partir de um endereço, é possível obter o valor armazenado na memória correspondente a esse endereço.”

Fonte: Wikipedia

Resumidamente: O ponteiro é uma variável como qualquer variável mas que armazena um endereço de uma outra variável.

Variáveis e Memória

Explicação de Memória

Quando declaramos int i=2450; estamos a indicar ao compilador para reservar um espaço na memória para poder armazenar valores do tipo inteiro, com o número de bits associado a este para cada compilador e/ou arquitectura. Simultaneamente é atribuído o valor 2450 à variável i, o que significa que no endereço de memória associado à variável i é armazenado o valor 2450.

Apontadores e Memoria Nota: este gráfico não está relacionado com o anterior apesar do valor de i ser o mesmo.

Declarar apontadores

Antes de começar com a declaração de apontadores quero alertar para um erro muito comum quer em programadores novatos quer em programadores mais experientes, nunca se deve usar um ponteiro sem antes inicializa-lo pois ele estará a tentar aceder a um valor da memória desconhecido e dará erro “Segmentation Fault“.

Declarar um apontador é muito simples:

int *ap  ;        /* declara um ponteiro para um inteiro */

A instrução anterior indica que ap é um apontador do tipo inteiro. Por outras palavras, ap é uma variável cujo valor é um endereço de uma variável do tipo int.
Existem dois operadores unários que são utilizados com os ponteiros.
Um é o operador (*) através dele é possível obter o valor do endereço de memória do ponteiro, o outro é o operador (&) que permite obter o endereço de memória.
De forma mais simples:

  • & significa “endereço de”;
  • * significa “conteúdo do endereço para onde aponta”.
*ap = 33;  /* atribui o valor 33 à variável que está contida no ponteiro */

Exemplos de Operações com Ponteiros

main()  {
int a=33;
int *ap=&a; // &a, devolve o endereço de memória de uma variável
printf("Valor a: %d\n", a);
printf("Endereço a: %d\n", &a);
printf("Valor apontador: %d\n", ap);
printf("Endereço apontador: %d\n", &ap);
printf("Valor na memória apontada pelo apontador: %d\n", *ap);
}
int *ap1, *ap2;
ap1 = ap2; /* isto fará com que ap1 aponte para o mesmo endereço que ap2 logo usar ap1 é o mesmo que usar ap2 */
int *ap1, *ap2;
*p1 = *p2;/* altera o valor apontado por ap1 para o apontado por ap2 */
int *ap;
(*ap)++; /* incrementa o valor armazenado no endereço para o qual ap aponta*/
int *ap;
ap++; /* se temos um ponteiro para um inteiro e o incrementamos, ele passa a apontar para o próximo inteiro */

Resumindo e Concluindo

  • Uma variável tem sempre um endereço e um valor;
  • Um apontador é uma variável cujo valor é o endereço de uma outra variável;
  • Se a for uma variável então &a é o endereço de a;
  • Se ap for um apontador, *ap é o valor que é indicado por ap;

Qualquer dúvida ou sugestão sintam-se à vontade em comentar, a perguntar é que se pode evoluir, não ficando com as dúvidas só para nós sem serem esclarecidas!

Deixo-vos com um vídeo do Binky a explicar apontadores, penso que será mais interessante e divertido…

11 comments

  1. ja k nao mordes lool
    o artigo tá mt esclarecedor obrigado
    se quiseres escrever algo sobre vectores está à vontade lool

  2. Não sei se entendi bem mas na parte “Variáveis e memória”, na primeira tabela, se tivermos declarado *ap = i e ele ficar na memória em 1003, se fizermos &ap = 1003, ap = 1002, e *ap = 2450…? É isso?

Leave a Reply to PCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.