Bóson Treinamentos em Ciência e Tecnologia

Ponteiros em C – uma introdução

Ponteiros em linguagem C - 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:

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é!

 

Sair da versão mobile