30
Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Embed Size (px)

Citation preview

Page 1: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Estrutura de DadosEstrutura de DadosPonteirosPonteiros

Professor Mário DantasProfessor Mário Dantas

Contribuição: Professor Marcelo DouglasContribuição: Professor Marcelo Douglas

Page 2: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Os ints guardam valores inteiros. Os floats guardam valores de ponto flutuante. Os chars guardam caracteres.

• Ponteiros guardam endereços de memória.

int j;j = 55;

Esta operação pode ser entendida pelo compilador como “carregue o inteiro 55 no

endereço de memória 248440”.

55248440????? ????? ????? ????? ?????

Page 3: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Estamos acostumados a trabalhar com o “conteúdo armazenado nos endereços de memória”, no entanto podemos estender os recursos de nossos programas ao aprendermos a trabalhar com os endereçamentos.

• Quando você anota o endereço de um colega está criando um ponteiro. O ponteiro é o papel.

Paulo RobertoRua Rio de janeiro, nº 3455

Page 4: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Qual é o sentido disto?

• Quando você anota o endereço de um colega, você vai usar este endereço para achá-lo.

• O C funciona assim. Você anota o endereço de algo numa variável ponteiro para depois usar.

• Da mesma maneira, uma agenda, onde são guardados endereços de vários amigos, poderia ser vista como sendo uma matriz de ponteiros no C.

Page 5: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Um ponteiro também tem tipo. No C quando declaramos ponteiros nós informamos ao compilador para que tipo de variável vamos apontá-lo. Um ponteiro int aponta para um inteiro, isto é, guarda o endereço de um inteiro.

• Para declarar um ponteiro temos a seguinte forma geral:

• É o asterisco (*) que faz o compilador saber que aquela variável não vai guardar um valor mas sim um endereço para aquele tipo especificado.

tipo_do_ponteiro = *nome_da_variável

Page 6: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Exemplos de criação de ponteiros:

• O exemplo declara que desejamos criar uma variável ponteiro para armazenar o endereço de um inteiro.

• Eles ainda não foram inicializados (como toda variável do C que é apenas declarada). Isto significa que eles apontam para um lugar indefinido. Este lugar pode estar, por exemplo, na porção da memória reservada ao sistema operacional do computador.

int *ptr;

Page 7: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Usar o ponteiro nestas circunstâncias pode levar a um travamento do micro, ou a algo pior.

• O ponteiro deve ser inicializado (apontado para algum lugar conhecido) antes de ser usado. Isto é de suma importância!

• Se declararmos o ponteiro fora de qualquer função ele é automaticamente inicializado com um valor que garantidamente não aponta para nenhuma posição de memória. Este valor é NULL.

Page 8: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Para atribuir um valor a um ponteiro recém-criado poderíamos igualá-lo a um valor de memória.

• Mas, como saber a posição na memória de uma variável do nosso programa?

• Seria muito difícil saber o endereço de cada variável que usamos, mesmo porque estes endereços são determinados pelo compilador na hora da compilação e realocados na execução.

Page 9: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Para saber o endereço de uma variável basta usar o operador &. Veja o exemplo:

• Criamos um inteiro count com o valor 10 e um apontador para um inteiro pt. A expressão &count nos dá o endereço de count, o qual armazenamos em pt.

• Vejamos o programa completo:

int count=10;int *pt;pt=&count;

Page 10: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

Page 11: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Como nós colocamos um endereço em ptr, ele está agora "liberado" para ser usado.

• Podemos, por exemplo, alterar o valor de count usando ptr.

• Para tanto vamos usar o operador "inverso" do operador &.

• É o operador *. No exemplo acima, uma vez que fizemos ptr=&count a expressão *ptr é equivalente ao próprio count.

• Isto significa que, se quisermos mudar o valor de count para 12, basta fazer *pt=12.

Page 12: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

Page 13: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

tipo *variavel; Cria uma variável ponteiro que apontará

para o endereço de memória do tipo estabelecido.

variavel = &n1;Faz com que a variavel do tipo ponteiro aponte para o endereço de memória da

variavel n1 e não ao seu conteúdo.

*variavel = n2;*variavel é a mesma coisa de n1, portanto

alterar *variavel altera n1.

Fixando Conteúdo

Page 14: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• Qual o resultado do programa abaixo?

Page 15: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Introdução ao uso de PonteirosIntrodução ao uso de Ponteiros

• O que faz cada linha do programa abaixo?

Page 16: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de PonteirosEstrutura de DadosEstrutura de Dados

Page 17: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• Existem apenas duas operações aritméticas que podem ser usadas com ponteiros: adição e subtração.

• Quando incrementamos um ponteiro ele passa a apontar para o próximo valor do mesmo tipo para o qual o ponteiro aponta.

• Isto é, se temos um ponteiro para um inteiro e o incrementamos ele passa a apontar para o próximo inteiro.

Page 18: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• Para exemplificar consideremos p1 um ponteiro para um inteiro com o valor atual de 2000. Assuma que os inteiros ocupam 4 bytes de memória.

• Após a expressão:

• Quanto será o valor de p1?

• p1 contém 2004 e não 2001. Cada vez que p1 é incrementado ele aponta para o próximo inteiro.

p1++;

Page 19: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

Page 20: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• se você incrementa um ponteiro char* ele anda 1 byte na memória e se você incrementa um ponteiro double* ele anda 8 bytes na memória.

• Este é mais um motivo pelo qual o compilador precisa saber o tipo de um ponteiro.

• O mesmo princípio da adição é aplicado para a subtração.

Page 21: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

Page 22: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• Você não está limitado a apenas incrementar e decrementar. Você pode também somar ou subtrair inteiros de ponteiros.

• Faz p1 apontar para o décimo segundo elemento do tipo p1 adiante do elemento que ele está atualmente apontando.

p1 = p1 + 12;

p1

1 2 3 4 11 12

…………

13

Page 23: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• É importante compreender que estamos falando de operações com ponteiros e não de operações com o conteúdo das variáveis para as quais eles apontam.

(*ptr)++ Incrementa o conteúdo da variável apontada por ptr.

ptr++ Aponta para a próxima posição onde ptr se encontra.

*(ptr+15) Acessa o conteúdo do ptr quinze posições adiante.

Page 24: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• Além de adição e subtração entre um ponteiro e um inteiro, nenhuma outra operação aritmética pode ser efetuada com ponteiros.

• Você não pode multiplicar ou dividir ponteiros e não pode adicionar ou subtrair o tipo float ou o tipo double a ponteiros.

O que não pode ser feito com ponteiros

Page 25: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Teste o programa e Informe o resultado

Page 26: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

• Uma outra operação, às vezes útil, é a comparação entre dois ponteiros. Mas que informação recebemos quando comparamos dois ponteiros?

• Em primeiro lugar, podemos saber se dois ponteiros são iguais ou diferentes (== e !=). No caso de operações do tipo >, <, >= e <= estamos comparando qual ponteiro aponta para uma posição mais alta na memória.

• Então uma comparação entre ponteiros pode nos dizer qual dos dois está "mais adiante" na memória. A comparação entre dois ponteiros se escreve como a comparação entre outras duas variáveis quaisquer.

Page 27: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Aritmética de PonteirosAritmética de Ponteiros

Page 28: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Exercícios de FixaçãoExercícios de Fixação

Page 29: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Exercícios de FixaçãoExercícios de Fixação

• Supondo que p é um ponteiro para um inteiro, explique a diferença entre:p+; (*p)++;*(p++)

• O que quer dizer *(p+10)?

Page 30: Estrutura de Dados Ponteiros Professor Mário Dantas Contribuição: Professor Marcelo Douglas

Exercícios de FixaçãoExercícios de Fixação

• Qual o valor de y no final do programa? Após descobrir escreva um comentário em cada comando de atribuição explicando o que ele faz.