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
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.
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…
Muito bom, obrigado!
ja k nao mordes lool
o artigo tá mt esclarecedor obrigado
se quiseres escrever algo sobre vectores está à vontade lool
Obrigado pela tua participação :).
Um artigo sobre Vectores em C? É uma possibilidade, tenho de ver se vale a pena…
Artigo muito esclarecedor. Finalmente percebi isto 😀
Obrigado
Óptimo José! Fico feliz por saber que conseguiste perceber este assunto através do meu post.
Qualquer dúvida que tenhas, podes perguntar.
Cumprimentos.
És um génio. Obrigado por partilhares connosco o teu conhecimento, estou a falar a sério 😉
abraço
Autocomplete fail!
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?
Tópico muito bom, gostei imenso. Geovany Quissanga (Luanda – Angola)
Excelente artigo! Muito obrigado.