Você está na página 1de 5

OPERAÇÕES

SOBRE PONTEIROS
Prof. Dr. Juliano Varella de Carvalho
OPERAÇÕES SOBRE PONTEIROS
As variáveis do �po ponteiro serão aprofundadas. Veremos algumas operações possíveis de serem
feitas com ponteiros, bem como u�lizar ponteiros para manipular vetores e matrizes.

Igualando ponteiros

Dois ponteiros dis�ntos, contendo endereços quaisquer, podem apontar para o mesmo local na
memória. Para fazer essa verificação, dois ponteiros p1 e p2, por exemplo, podem ser comparados
u�lizando-se uma estrutura de decisão:

...
if (p1 == p2)
printf(“p1 aponta para o mesmo endereço que p2”);
else
printf(“p1 aponta para um endereço diferente de p2”);
...

Caso seja necessário que p1 aponte para o mesmo endereço de p2, a instrução a seguir pode ser
realizada

...
p1 = p2;
...

float nota = 8.9;


float *p1, *p2;
p1 = &nota;
p2 = p1;
printf("Valores de p1 e p2: %p %p\n", p1, p2);
printf("Conteudo apontado por p1 e p2: %.2f %.2f\n", *p1, *p2);

No código acima, na primeira instrução printf, serão impressos os valores apontados pelos endereços
p1 e p2, por exemplo: 0x7ffeeaf3fa18 para p1 e 0x7ffeeaf3fa18 para p2. Notar que ambos apontam para o
mesmo endereço, que é o endereço onde localiza-se a variável nota. Observar que nesse caso os endereços
foram impressos em hexadecimal, pois u�lizou-se o argumento %p.

O segundo prin� imprime os conteúdos dos endereços apontados por p1 e p2. Como ambos
ponteiros apontam para a variável nota, serão impressos na tela os valores: 8.90 e 8.90.

Incrementando ponteiros

A operação de incremento e decremento pode ser aplicada a um ponteiro. O incremento em um


ponteiro fará com que ele passe a apontar para o próximo endereço do mesmo �po de dado do ponteiro.
Quando se faz uma declaração de variável ponteiro, é necessário informar para qual �po de dado o ponteiro
apontará. Por exemplo, as três instruções abaixo, declaram ponteiros para �pos dis�ntos. O ponteiro carac,
quando incrementado, adicionará ao seu endereço o valor de 1Byte, pois o �po char ocupa 1Byte em
memória. Já a variável contador, quando incrementada, pulará para os próximos 4 Bytes de memória,
enquanto a variável preco, ao ser incrementada, será direcionada para os próximos 8 Bytes.

1
ontador;
double *preco;
char c = 'A';
carac = &c;
printf("%u\t%c\n", carac, *carac);
carac++;
printf("%u\t%c\n", carac, *carac);

O código acima imprime na tela os valores abaixo. Note que o endereço impresso na segunda linha é
um byte a mais em memória do que o primeiro endereço. O valor ‘A’ foi impresso na primeira linha, pois é o
que está con�do na variável c, apontada pelo ponteiro carac. Na segunda linha não foi impresso nenhum
valor, pois como o ponteiro carac passou a apontar para o endereço 3819796992, o conteúdo desse
endereço é desconhecido.

3819796991 A
3819796992

Observe o código a seguir

1 char palavra[21] = "Ponteiros";


2 char *carac = palavra;
3 printf("%u\t%c\n", carac, *carac);
4 carac++;
5 printf("%u\t%c\n", carac, *carac);
6 carac = carac + 5;
7 printf("%u\t%c\n", carac, *carac);
8 (*carac)++;
9 printf("%u\t%c\n", carac, *carac);
10 printf("%s\n", palavra);

As impressões na tela serão as seguintes:

3992041984 P
3992041985 o
3992041990 r
3992041990 s
Ponteisos

Na linha 2 o ponteiro carac passa a apontar para o endereço de memória onde inicia vetor de
caracteres palavra. A primeira impressão imprime o caractere ‘P’. Na linha 4 é realizado o incremento de uma
posição de memória e a impressão realizada posteriormente coloca na tela o valor ‘o’, ou seja, o ponteiro
carac está apontando para a segunda posição de memória do vetor de caracteres palavra.

A linha 6 faz com que o ponteiro carac avance 5 Bytes de memória, posicionando-se no endereço
3992041990, local esse da memória cujo conteúdo é o caractere ‘r’. Já a linha 8 é responsável por uma
operação diferente, a instrução dessa linha não incrementa o ponteiro carac, ela incrementa o conteúdo da
posição apontada por carac. Como nesse instante, o conteúdo do endereço de memória apontado por carac
é ‘r’, ele receberá o valor ‘s’, alterando dessa forma o conteúdo do vetor de caracteres palavra. No início do
código, palavra con�nha o valor “Ponteiros” e passa a ter o valor “Ponteisos”.

2
Varrendo vetores com ponteiros

Uma variável do �po ponteiro pode ser u�lizada para varrer um vetor ou uma matriz. Abaixo há um
código que u�liza a variável ponteiro p para varrer um vetor de floats, denominado notas.

1 float notas[5] = {8.2, 9.1, 7.8, 9.5, 10.0};


2 float *p;
3 p = notas;
4 for (int i=0; i<5; i++) {
5 printf("%.2f\t", *p);
6 p++;
7 }

O mesmo código poderia ser implementado u�lizando o código abaixo. A diferença básica é que no
código acima o ponteiro p, que inicialmente aponta para o início do vetor, tem o seu valor alterado, pois a
cada iteração ele aponta para o próximo float na memória. O código abaixo, no entanto, não mexe no valor
do ponteiro p, em nenhum momento ele é alterado.

float notas[5] = {8.2, 9.1, 7.8, 9.5, 10.0};


float *p;
p = notas;
for (int i=0; i<5; i++)
printf("%.2f\t", *(p+i));

Varrendo matrizes com ponteiros

Um ponteiro também pode ser u�lizado para varrer arrays com mais de uma dimensão. O exemplo
abaixo explora três maneira de varrer um array bidimensional, ou seja, uma matriz. A primeira varredura na
matriz notas é realizada conforme tradicionalmente fazemos, u�lizando uma estrutura de repe�ção
aninhada, para indexar cada valor con�do na matriz. Esse procedimento está registrado nas linhas 7, 8 e 9.

No código apresentado entre as linhas 10 e 14, também é u�lizada uma estrutura de repe�ção
aninhada para mostrar os valores da matriz. No entanto, nesse caso, está sendo u�lizada uma variável do �po
ponteiro, denominada p. Essa variável aponta para o início da matriz (linha 11) e acessa cada valor, a par�r da
instrução da linha 14: *(p+i*COLUNA+j). Adiciona-se ao endereço de p o seguinte deslocamento de memória:
i*COLUNA+j.

A terceira maneira de acessar os valores da matriz, u�liza-se de apenas uma estrutura de decisão,
linhas 15, 16 e 17. Embora a estrutura de dados notas seja uma matriz, seus valores estão distribuídos na
memória de forma unidimensional e um após o outro (adjacentes). Logo, sabendo-se onde está o endereço
inicial da matriz (linha 15), é possível varrer posição por posição.
3
1 #define LINHA 3
2 #define COLUNA 2
3 int main() {
4 float notas[LINHA][COLUNA] = { {8.2, 9.1},
5 {7.8, 9.5},
6 {10.0, 9.0} };
7 for (int i=0; i<LINHA; i++)
8 for (int j=0; j<COLUNA; j++)
9 printf("%.2f\t", notas[i][j]);
10 float *p;
11 p = &notas[0][0];
12 for (int i=0; i<LINHA; i++)
13 for (int j=0; j<COLUNA; j++)
14 printf("%.2f\t", *(p+i*COLUNA+j));
15 p = &notas[0][0];
16 for (int i=0; i<(LINHA*COLUNA); i++)
17 printf("%.2f\t", (*(p+i)));

Referências:

MIZRAHI, Victorine V. Treinamento em Linguagem C. Segunda Edição. São Paulo: Pearson Pren�ce
Hall, 2008.

Você também pode gostar