Ponteiros em C – uma introdução

Ponteiros em C

Vamos começar a tratar hoje de um dos conceitos mais importantes (e provavelmente mais confusos) a se dominar em linguagem C: o conceito de Ponteiros.

O que é um ponteiro em C? Um ponteiro é uma variável especial que contém um endereço de memória armazenado, em vez de dados comuns. Esse endereço é, no geral, a posição na memória de uma outra variável. Desta forma, a variável que contém esse endereço aponta para a outra variável. Daí o nome "ponteiro".

O domínio e o emprego dos ponteiros é extremamente importante para que seja possível programar com eficiência e desenvoltura em C. Eles são úteis em inúmeros contextos, como por exemplo no suporte à rotinas de alocação dinâmica de memória e na construção de ADTs - Abstract Data Types / Tipos de Dados Abstratos - como por exemplo pilhas, listas e filas.

A figura a seguir ilustra a ideia geral de funcionamento de um ponteiro:

Ponteiros em Linguagem C

Na figura, temos representados endereços na memória RAM do computador, e um conjunto de variáveis criadas nesses endereços. podemos ver que no endereço 5000 existe uma variável ponteiro, cujo conteúdo é o endereço de memória 5004 - ou seja, esse ponteiro aponta para a variável que está localizada no endereço 5004 da memória RAM.

Declarando ponteiros

Uma declaração de ponteiro consiste em um tipo, seguido do caractere * (chamado de "operador de indireção" ou de "dereferência") e do nome que se deseja dar à variável. A sintaxe a seguir mostra a forma de se declarar um ponteiro:

tipo *nome;

O tipo, que pode ser qualquer um válido em C, define o tipo da variável que o ponteiro pode apontar. Por exemplo, suponha que se deseje criar um ponteiro de nome "ponteiro", o qual aponte para uma variável do tipo float. Para tal, usamos a seguinte declaração:

float *ponteiro;

Essa declaração cria uma variável ponteiro que aponta para uma variável do tipo float - note que float é o tipo da variável apontada, e não do ponteiro em si.

Os ponteiros devem ser inicializados ao serem declarados ou por meio de uma declaração de atribuição posterior à sua declaração. Podemos inicializar um ponteiro com um endereço de memória, ou os valores 0 ou ainda NULL. Um ponteiro com o valor NULL não aponta para nenhum local. Apontar para 0 é equivalente a apontar para NULL, mas usar a palavra NULL deixa o código mais inteligível.

Operadores de Ponteiros

Em C há dois operadores especiais de ponteiros: os operadores * e &.

O operador & (operador de endereço) é um operador unário que permite retornar o endereço na memória de uma variável. Desta forma:

x = &valor;

esta declaração coloca na variável x o endereço de memória da variável valor, o qual não possui relação com o valor armazenado na variável. Podemos ler essa declaração como "x recebe o endereço da variável valor".

O operador de indireção * é também um operador unário, e retorna o valor contido na variável localizada no endereço informado ao operador. Por exemplo, se a variável x contém o endereço da variável valor, e a variável valor armazena o valor (dado) 30, teremos:

y = *x;

essa declaração coloca o conteúdo da variável valor (30) na variável y. Assim, y conterá também o valor 30, pois 30 é o dado armazenado na posição de memória apontada por x. Podemos ler a declaração como "y recebe o valor armazenado no endereço apontado por x".

Atribuição de ponteiros

Podemos atribuir um ponteiro a outro ponteiro, como fazemos com variáveis comuns. Veja o código a seguir:

#include <stdio.h>
#include <stdlib.h>
int main()
{
  int a;
  a = 30;
  int *pont1, *pont2;
  pont1 = &a;
  pont2 = pont1;
  printf("Endereço de a: %p", pont2);
  return 0;
}

Esse código irá mostrar na tela o endereço da variável a, mas não seu conteúdo armazenado (que é o valor 30). Tanto pont1 quanto pont2 são ponteiros que apontam para a variável a.

Para mostrar o endereço da variável a com a função printf() usamos o modificador de formato %p.

Se quisermos ver o conteúdo da variável, podemos usar a declaração a seguir, que mostra o conteúdo de a a partir do ponteiro pont2:

printf("Conteúdo de a: %d\n", *pont2);

Note o uso do operador *, para indicar que queremos o valor da variável apontada pelo ponteiro, e não seu endereço de memória.

Como retornar o endereço de uma variável

Podemos obter o endereço de uma variável (local da memória onde um dado está armazenado) usando o operador &, conforme vemos no código a seguir:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
  setlocale(LC_ALL, " ");
  int num = 60;
  printf("Endereço da variável num: %p\n", &num);
}

Ao executar esse programa, obteremos o endereço da variável num na memória RAM do computador.

Na próxima parte de nosso estudo sobre ponteiros vamos falar sobre Aritmética de Ponteiros.

Até!

 

Sobre Fábio dos Reis (1182 Artigos)
Fábio dos Reis trabalha com tecnologias variadas há mais de 25 anos, tendo atuado nos campos de Eletrônica, Telecomunicações, Programação de Computadores e Redes de Dados. É um entusiasta de Unix, Linux e Open Source em geral, adora Eletrônica e Astronomia, e estuda idiomas, além de ministrar cursos e palestras sobre diversas tecnologias em São Paulo e outras cidades do Brasil.
Contato: Website

Escreva um comentário

Seu e-mail não será divulgado


*