Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
Linguagem de Programação Estruturada I
Lucas Ferrari de Oliveira
Professor Adjunto
Universidade Federal do Paraná
Ponteiros
2
Prof. Lucas Ferrari de Oliveira
Sumário
Conceitos
Utilidades dos Ponteiros
Operadores para Ponteiros:
Operador &
Operador *
Declarando Ponteiros
Expressões com Ponteiros
Atribuições de Ponteiros
Aritmética de Ponteiros
Comparação entre ponteiros
Ponteiros e Matrizes
Indireção Múltipla
Ponteiro Nulo
Funcao com ponteiros
3
Prof. Lucas Ferrari de Oliveira
Ponteiros
Conceitos:Conceitos:
Um ponteiro é o endereço de uma variável na
memória.
Uma variável de ponteiro é uma variável
especialmente declarada para guardar um ponteiro
para seu tipo especificado.
4
Prof. Lucas Ferrari de Oliveira
Ponteiros
Utilidades dos PonteirosUtilidades dos Ponteiros
São uma maneira rápida de referenciar uma variável
em C;
São o meio pelo qual as funções em C conseguem
modificar seus parâmetros de chamada;
Provêem suporte às listas encadeadas e outras
estruturas de dados dinâmicas.
5
Prof. Lucas Ferrari de Oliveira
Ponteiros
Operadores para PonteirosOperadores para Ponteiros
operador &:
Operador unário;
Devolve o endereço da memória em que se encontra
alocado seu operando;
Exemplo:
m = &count;
atribui a m o endereço da memória em que se encontra
a variável count. Esse endereço não tem nenhuma
relação com o valor de count.
6
Prof. Lucas Ferrari de Oliveira
Ponteiros
Operadores para PonteirosOperadores para Ponteiros
operador &:
Operador unário;
Devolve o endereço da memória em que se encontra
alocado seu operando;
Exemplo:
m = &count;
atribui a m o endereço da memória em que se encontra
a variável count. Esse endereço não tem nenhuma
relação com o valor de count.
Pode-se imaginar & como significando “o endereço de”.
Desta forma, a sentença de atribuição significa
“m recebe o endereço de count”.
Pode-se imaginar & como significando “o endereço de”.
Desta forma, a sentença de atribuição significa
“m recebe o endereço de count”.
7
Prof. Lucas Ferrari de Oliveira
Ponteiros
Operadores para PonteirosOperadores para Ponteiros
operador &:
Exemplo mais concreto, em termos de memória:
assuma que a variável count foi alocada para a
posição de memória 2000. Assuma também que count
tem como valor 100. Então, após a setença de
atribuição anterior, m tem o valor 2000.
endereço memória
...
1999
2000 100
2001
2002
...
8
Prof. Lucas Ferrari de Oliveira
Ponteiros
Operadores para PonteirosOperadores para Ponteiros
operador *:
Operador unário;
Devolve o valor da variável localizada no endereço
que o segue (ou seja, este operador sempre
interpreta seu operando como um endereço de
memória!)
9
Prof. Lucas Ferrari de Oliveira
Ponteiros
Operadores para PonteirosOperadores para Ponteiros
operador *:
Exemplo:
seguindo o exemplo anterior, se m contem o endereço da
variável count,
q=*m;
coloca o valor de count em q. Agora q tem o valor 100
porque 100 está armazenado na posição 2000,
endereço da memória em que está armazenado m.
10
Prof. Lucas Ferrari de Oliveira
Ponteiros
Operadores para PonteirosOperadores para Ponteiros
operador *:
Exemplo:
seguindo o exemplo anterior, se m contem o endereço da
variável count,
q=*m;
coloca o valor de count em q. Agora q tem o valor 100
porque 100 está armazenado na posição 2000,
endereço da memória em que está armazenado m.
Pode-se pensar no * como significando “o conteúdo do
endereço …”. Assim, a sentença poderia ser
lida como “q recebe o conteúdo do endereço m”.
Pode-se pensar no * como significando “o conteúdo do
endereço …”. Assim, a sentença poderia ser
lida como “q recebe o conteúdo do endereço m”.
11
Prof. Lucas Ferrari de Oliveira
Ponteiros
ObservaçãoObservação
Infelizmente, o símbolo de multiplicação e o símbolo
de “o conteúdo do endereço …” são iguais, e o
símbolo para o AND bit a bit e o símbolo de “o
endereço de” também são iguais.
Ambos * e & têm precedência maior que todos os
operadores aritméticos, exceto o menos unário, que
tem mesma precedência.
12
Prof. Lucas Ferrari de Oliveira
Ponteiros
Declarando PonteirosDeclarando Ponteiros
Variáveis que armazenam endereços de memória, os
ponteiros (como são chamadas em C), devem ser
declaradas colocando-se * em frente ao nome da
variável para indicar ao compilador que ela guardará
um ponteiro para aquele tipo de variável.
13
Prof. Lucas Ferrari de Oliveira
Ponteiros
Declarando PonteirosDeclarando Ponteiros
Por exemplo, para declarar uma variável ponteiro ch para
char, escreve-se:
char *ch;
Aqui, ch não é um caractere, mas um ponteiro para
caractere (há uma grande diferença).
14
Prof. Lucas Ferrari de Oliveira
Ponteiros
Declarando PonteirosDeclarando Ponteiros
Pode-se misturar diretivas de ponteiro e de não-
ponteiro na mesma declaração, como por exemplo:
int x, *y, count;
Declara x e count como sendo do tipo inteiro e y
como sendo um ponteiro para o tipo inteiro.
15
Prof. Lucas Ferrari de Oliveira
Ponteiros
Declarando PonteirosDeclarando Ponteiros
E o que faz o programa que segue?
#include <stdio.h>
int main(void)
{
int target, source, *m;
source = 10;
m = &source;
target = *m;
printf(“%d”, target);
}
16
Prof. Lucas Ferrari de Oliveira
Ponteiros
Expressões com PonteirosExpressões com Ponteiros
Em geral, expressões envolvendo ponteiros
concordam com as mesmas regras de qualquer
outra expressão em C.
17
Prof. Lucas Ferrari de Oliveira
Ponteiros
Atribuições de PonteirosAtribuições de Ponteiros
Como qualquer variável, um ponteiro pode ser
usado do lado direito de um comando de
atribuição para se passar seu valor para outro
ponteiro.
#include <stdio.h>
void main(void)
{
int x, *p1, *p2;
p1 = &x;
p2 = p1;
printf(“%p”, p2); //escreve o endereco de x, nao seu valor
}
18
Prof. Lucas Ferrari de Oliveira
Ponteiros
Aritmética de PonteirosAritmética de Ponteiros
Existem apenas duas operações aritméticas que
podem ser feitas com ponteiros:
Adição
Subtração
Regras da aritmética de ponteiros:Regras da aritmética de ponteiros:
Cada vez que um ponteiro é incrementado, ele aponta
para a posição de memória do próximo elemento do
seu tipo base.
Cada vez que um ponteiro é decrementado, ele aponta
para a posição de memória do elemento anterior do
seu tipo base
19
Prof. Lucas Ferrari de Oliveira
Ponteiros
Aritmética de PonteirosAritmética de Ponteiros
Exemplo:
assuma que estamos usando uma máquina na qual um
inteiro ocupa 2 bytes. Então …
int *p1, x;
p1 = &x;
p1++;
Suponha que x estava armazenada na posição de
memória 2000. Então, após p1++, p1 conterá o valor
2002.
20
Prof. Lucas Ferrari de Oliveira
Ponteiros
Aritmética de PonteirosAritmética de Ponteiros
Também é possível somar ponteiros:
p1 = p2 + 100;
Além de adição e subtração entre um ponteiro e um
inteiro, nenhuma outra operação pode ser efetuada
com ponteiros.
Particularmente, NÃO é permitido:Particularmente, NÃO é permitido:
Adicionar ou subtrair o tipo float ou o tipo double a
ponteiros;
Multiplicar ou dividir ponteiros;
Aplicar os operadores de deslocamento ou de
mascaramento bit a bit com ponteiros.
21
Prof. Lucas Ferrari de Oliveira
Ponteiros
Comparação entre PonteirosComparação entre Ponteiros
É possível comparar dois ponteiros em uma expressão
relacional. Exemplo:
if(p<q)
printf(“p aponta para um endereço de memoria
mais baixo que q\n”);
Geralmente, comparações de ponteiros são
utilizadas para verificar se dois ou mais ponteiros
apontam para um mesmo objeto (uso em
estruturas de dados tais
como pilhas, filas etc)
22
Prof. Lucas Ferrari de Oliveira
Ponteiros
Ponteiros e MatrizesPonteiros e Matrizes
Há uma estreita relação entre ponteiros e matrizes.
De fato, os índices das matrizes são uma maneira mais
confortável para se acessar um dado elemento.
char nome[80], *p1, ch;
p1 = nome;
p1 foi inicializado com o endereço do primeiro elemento
da matriz nome:
ch = nome[4];
ou
ch=*(p1+4);
copiam o quinto elemento de nome para ch
23
Prof. Lucas Ferrari de Oliveira
Ponteiros
Ponteiros e MatrizesPonteiros e Matrizes
Acessando uma matriz com índices:
for( i=0; nome[i] != ‘\0’; i++)
putchar(nome[i]);
Acessando uma matriz com ponteiro:
for( p=nome; *p; p++)
putchar(*p);
ou
p=nome;
while(*p)
putchar(*p++);
24
Prof. Lucas Ferrari de Oliveira
Ponteiros
Ponteiros e MatrizesPonteiros e Matrizes
Como qualquer outro tipo básico, ponteiros podem
ser organizados em matrizes:
int *listas[100];
Para se atribuir o endereço de uma variável inteira,
chamada var, ao terceiro elemento da matriz de
ponteiros, deve-se escrever:
listas[2] = &var;
Para encontrar o valor de var, escreve-se:
*listas[2];
25
Prof. Lucas Ferrari de Oliveira
Ponteiros
Indireção MúltiplaIndireção Múltipla
Ocorre quando se tem um ponteiro que aponta para
outro ponteiro que (finalmente) aponta para o valor.
1. Indireção simples (vista até agora)
2. Indireção múltipla
endereço
Ponteiro
Valor
Variável
Valor
Variável
endereço
Ponteiro
Valor
Variável
endereço
Ponteiro
26
Prof. Lucas Ferrari de Oliveira
Ponteiros
Indireção MúltiplaIndireção Múltipla
Exemplo:
#include <stdio.h>
void main(void)
{
int x, *p, **q;
x = 10;
p = &x;
q = &p;
printf(“%d”, **q); //imprime o valor de x
}
27
Prof. Lucas Ferrari de Oliveira
Ponteiros
Ponteiro NuloPonteiro Nulo
Após um ponteiro ser declarado, mas antes que lhe
seja atribuído algum valor, ele contém um valor
desconhecido (lixo de memória);
Usar um ponteiro cujo valor é desconhecido
provavelmente causará uma falha grave de
execução;
Convenção: um ponteiro que não aponta para um
valor válido de endereço da memória recebe o valor
nulo (que é zero);
Pode-se usar um ponteiro nulo para marcar o final de
uma matriz (‘\0’).
28
Prof. Lucas Ferrari de Oliveira
Funções com PonteirosFunções com Ponteiros
// funcao que procura um nome
int search (char *p[], char *name)
{
int i;
for( i=0; p[i]; ++i)
if(strcmp(p[i], name))
return i;
return -1; // so chega aqui se nao encontrou
name
}
Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
Slide 9
Slide 10
Slide 11
Slide 12
Slide 13
Slide 14
Slide 15
Slide 16
Slide 17
Slide 18
Slide 19
Slide 20
Slide 21
Slide 22
Slide 23
Slide 24
Slide 25
Slide 26
Slide 27
Slide 28