A maior rede de estudos do Brasil

Grátis
87 pág.
apostila-alg-prog-uergs

Pré-visualização | Página 21 de 23

71 Copyright  2002,03 João Carlos Gluz
Capítulo 9
Apontadores (ou Ponteiros)
Uma variável nada mais é do que o nome que damos a uma posição na memória de um
computador que deverá armazenar um determinado valor. O tipo de dados da variável, quer
seja caracter (char), número inteiro (int), ponto flutuante (float), ou outro, define o formato
e o tamanho que o dado irá ocupar na memória.
Até agora trabalhamos com variáveis estáticas que designam uma posição fixa na memória.
O que “varia” nestas variáveis é o seu conteúdo, não a posição ou lugar que ela ocupa na
memória. Uma analogia que ajuda a entender este conceito, é imaginarmos que o nome de
uma variável é o nome de uma espécie de “caixa” |(que está em algum lugar) que serve para
guardar dados.
Estas variáveis fixas na memória não são, entretanto, tudo o que nós podemos fazer em
termos de manipulação de dados. Existe, na verdade, uma técnica muito poderosa de
manipulação que nos permitirá trabalhar diretamente com as posições ou lugares onde se
armazenam dados na memória.
Para tanto é necessário trabalhar com os apontadores para variáveis (ou para posições de
memória, o que é a mesma coisa). Estes apontadores (também denominados de ponteiros)
são variáveis como as outras, isto é, tem um nome e guardam um valor dentro deles. Porém
seus valores tem um significado completamente diferente dos valores comumente
guardados em variáveis inteiras, caracter, etc.
Uma variável apontadora guarda dentro de si um apontador de uma outra variável que está
na memória:
Figura 4 - Apontador para Variável
No exemplo acima a variável apontadora ap1 aponta para uma variável “comum” var1.
Além de “apontador”, também se denomina o valor guardado dentro de ap1 de ponteiro
para a variável var1, ou de referência à variável var1 ou ainda de endereço da variável
var1. Em C todas estas denominações são equivalentes e podem ser intercambiadas sem
maiores problemas, porque em C, um apontador, ponteiro ou referência a uma dada
variável nada mais é do que o endereço (ou posição) desta variável na memória principal do
computador.
ap1: var1:
UERGS - Algoritmos e Programação Capítulo 9 - Apontadores
72 Copyright  2002,03 João Carlos Gluz
9.1. Declaração de Variáveis Apontadoras
Em C os apontadores, não apontam apenas para uma variável, mas pode-se mudar o lugar
(ou posição de memória) onde eles irá apontar. Assim não faz sentido em falar no
apontador apenas para uma variável. O que se tem que definir é um apontador para um tipo
de dados específico, que pode, então, ser usado para apontar para variáveis dàquele mesmo
tipo de dados. Assim se definirmos um apontador para inteiro poderemos usá-lo para
apontar para variáveis do tipo inteiro e assim por diante.
Um apontador, ou seja, uma variável apontadora, é definido através de declarações com o
seguinte formato:
<tipo-de-dados-apontado> *<nome-da-variavel-apontadora>;
onde <tipo-de-dados-apontado> é qualquer tipo de dados de C, e <nome-da-variável-
apontadora> é o nome da variável que irá conter o apontador. O operador ‘*’ quando
aplicado ao nome da variável é que diz ao compilador que ela será um apontador para o
tipo de dados <tipo-de-dados-apontado> e não apenas uma varável comum deste tipo.
Exemplos:
// Apontadores para caracteres (strings)
char *ps1;
char *ps2;
char *ps3;
// Apontadores para inteiros
int *pvar1;
int *pvar2;
// Apontadores para numeros ponto-flutuante
float *px;
float *py;
9.2. Inicialização de Apontadores
Normalmente, um apontador é inicializado obtendo-se o endereço (referência ou posição de
memória) da variável comum que se quer que ele aponte. Isto é feito através do operador
‘&’ que, quando aplicado sobre uma variável retorna um apontador para esta variável.
Tecnicamente este operador apenas retorna o endereço (ou posição) na memória principal
onde esta variável está localizada.
Exemplos:
Assim para inicializar os vetores que vimos anteriormente poderiamos ter o seguinte
código:
// Supondo os apontadores anteriores, definimos algumas
// variáveis comuns:
char c1, c2;
UERGS - Algoritmos e Programação Capítulo 9 - Apontadores
73 Copyright  2002,03 João Carlos Gluz
char str1[100], str2[200];
int i,j,k;
int vet1[10], vet2[30];
float x,y,z;
// Codigo que inicializa os vetores que definimos anteriormente:
ps1 = &c1;
ps2 = &str1[0];
ps3 = str2;
pvar1 = &i;
pvar2 = vet1;
px = &x;
py = &y;
Alguns comentários sobre o código acima:
Para inicializar um apontador para uma variável basta usar o operador ‘&’ sobre o nome da
variável, como nas linhas:
ps1 = &c1;
...
pvar1 = &i;
...
px = &x;
py = &y;
No caso de apontadores para vetores,entretanto, é necessário dizer qual posição do vetor
iremos apontar. No exemplo o apontador ps2 irá apontar para posição 0 do vetor (string)
str1.
...
ps2 = &str1[0];
...
Porém, no caso de apontadores para a posição 0 de um vetor o compilador C aceita a
seguinte simplificação:
...
ps3 = str2;
...
pvar2 = vet1;
,,,
onde não é necessário dizer o índice do array nem colocar o operador ‘&’ na frente dele.
Mais imporante do que isto, é necessário entender que em C apontadores para vetores e
variáveis array são formalmente equivalentes, exceto pelo fato que ao declararmos uma
variável array será reservado na memória uma área para guardar o array, enquanto que a
declaração de um apontador não reserva memória. Apenas abre espaço para guardar o
endereço do início de um array, por exemplo, e não o array todo.
UERGS - Algoritmos e Programação Capítulo 9 - Apontadores
74 Copyright  2002,03 João Carlos Gluz
9.3. Uso dos Apontadores
Um apontador é usado justamente quando fazemos referência a variável ou posição de
memória que ele aponta, tanto para ler os dados que estão lá quanto para guardar novos
valores.
Para isto é usado o operador ‘*’ que ao ser aplicado a uma variável apontadora retorna o
próprio objeto sendo apontador. Assim se quizermos ler o valor apontado por um apontador
basta colocar o ‘*’ na frente do nome do apontador e usar esta construção como se fosse
uma variável comum do tipo apontado pelo apontador.
Da mesma forma se queremos atribuir um novo valor basta usar o nome da variável
apontadora precedido do ‘*’ à esquerda do operador de atribuição de C.
Exemplos:
// Supondo os apontadores e variaveis definidos anteriormente
c1 = ‘a’;
c2 = *ps1;
j = 1;
*pvet1 = j;
k = *pvet1 * *pvet1 + 12
*px = 2.5;
*py = *px + 5.7;
9.4. Manipulação de Apontadores
Além de ser usado como referência ou para atribuir um valor, também podemos manipular
apontadores como se fossem variáveis comuns, isto é, podemos atribuir o valor de um
apontador para outro e fazer algumas operações sobre diretamente sobre os operadores.
A operação mais simples é a cópia ou atribuição do valor de um operador para outro. A
única restrição nesta operação é que ambos operadores tenham o mesmo tipo. Isto é não
podemos atribuir um apontador de caracteres para um de inteiros e vice-versa. E nem as
outras combinações.
pvet2 = pvet1;
py = px;
pstr3 = pstr1;
Outra operação que pode ser feita com os apontadores é o incremento ou decremento deles.
A lógica aqui é bastante simples: se um apontador aponta para um objeto de um dado tipo
que está localizado na memória, ao incrementar este apontador teremos um novo
apontador para a próxima posição na memória principal que pod guardarum objeto de
mesmo tipo.
// Preenche o string str2 com “abc”, usando o
UERGS - Algoritmos e Programação Capítulo 9 - Apontadores
75 Copyright  2002,03 João Carlos Gluz
// apontador ps2
ps2 = str2;
*ps2 = ‘a’;
ps2++;
*ps2 = ‘b’;
ps2++;
*ps2 = ‘c’;
ps2++;
*ps2 = ‘\0’;
De forma similar ao decrementar um apontador, teremos um apontador para a posição
prévia ou anterior na memória para um objeto de mesmo tipo.
// Agora trocamos os caracteres do string str2 para “XYZ”, usando