ponteiros - nca.ufma.brnca.ufma.br/~geraldo/lp/5.1.ponteiros.pdf · detalhes o conceito básico de...

25
Ponteiros Introdução

Upload: dangthien

Post on 12-Dec-2018

242 views

Category:

Documents


0 download

TRANSCRIPT

Ponteiros Introdução

Conceito •  Um PONTEIRO ou APONTADOR é uma variável

usada para armazenar um endereço de memória. •  Normalmente, o endereço armazenado em um

PONTEIRO é a posição de uma outra variável na memória. •  Se uma variável contém o endereço e uma outra,

então a primeira variável é dita apontar para a segunda.

2

Conceito

3

Declaração •  De maneira geral, uma variável ponteiro de nome

ID é declarada assim:

•  ESPECIFICADORES * ID = INICIALIZADOR;

•  onde, o = INICIALIZADOR é opcional (como em toda declaração de variável).

4

Operadores de Ponteiros •  Existem dois operadores especiais para ponteiros:

o * e o &.

5

Operador & •  Um operador unário que devolve o endereço na

memória do seu operando.

6

int m; int * p; p = &m; /* p recebe o endereço onde se localiza a var. m */ ...

Operador * •  É o complemento de &. Quer dizer, devolve a variável

localizada no endereço armazenado em um apontador.

7

p = &m; m = 3; cout << p; /* imprime o endereço de m */ cout << *p; /* imprime 3 que é o conteúdo de m */ ...

Ponteiros e Arranjos •  Há uma estreita relação entre PONTEIROS e

ARRANJOS (vetores, matrizes e strings). O nome de um ARRANJO (vetor, matriz ou string) é sempre um PONTEIRO para o primeiro elemento do ARRANJO.

8

char  str[80],  *pstr;    pstr  =  str;  /*  pstr  aponta  para  str[0]  */    

Ponteiros e Arranjos •  Assim, a décima posição de um ARRANJO (vetor,

matriz ou string) pode ser acessada de duas maneiras:

9

pstr  =  str;  /*  pstr  aponta  para  str[0]  */    cout  <<  str[9];  /*  imprime  o  10o  elemento  de  str  */    cout  <<  *(pstr  +  9);  /*  imprime  o  10o  elemento  de  str  */    

Aritmética de Ponteiros •  Existem apenas duas operações aritméticas que

podem ser usadas com ponteiros: adição e subtração.

•  Cada vez que um ponteiro é incrementado, ele aponta para a posição de memória do próximo elementodo seu tipo base.

•  Cada vez que um ponteiro é decrementado, ele aponta para a posição de memória do elemento anterior.

10

Aplicações •  O correto entendimento e uso de ponteiros é

crítico para uma programação bem-sucedida em C. Há pelo menos três razões para isto: •  ponteiros fornecem os meios pelos quais as

funções podem modificar seus argumentos •  formam a base para a alocação dinâmica

(variáveis no heap) •  aumenta a eficiência de certas rotinas

•  De agora em diante, até o final do curso, iremos explorar em variados graus de detalhes o conceito básico de ponteiros. 11

Atividades •  Escreva um programa em C que preencha um

vetor de 10 números com os valores: 1,2... 10. Depois imprima o valor na posição do vetor e o endereço de memória que se encontra aquele valor.

•  Escreva um programa em C que inicializa uma string de caracteres e percorre essa string usando aritmética de ponteiros.

12

Alocação Dinâmica •  ALOCAÇÃO DINÂMICA é o processo através do

qual um programa pode criar novas variáveis (áreas de memória) em tempo de execução.

•  Variáveis alocadas dinâmicamente são criadas em uma área de memória livre chamada de HEAP e são acessadas através de PONTEIROS.

13

Heap

14

Funções  • use  o  operador  new  para  alocar  

 

 

• use  o  operador  delete  para  desalocar  memória  

15

char  *ptr;    ptr  =  new  char  [50];  

delete  []ptr  

Ponteiro para Funções

16

Ponteiro para Funções - Exemplo 1.  #include  <stdio.h>  

2.  int  compara(int  a,  int  b)  {  3.         if  (b  <  a)  return  1;  4.         return  0;  5.  }  

6.  int  ordenacao  (int  *vet,  int  size,  int  (*  compara)(int  a,  int  b))  {  7.         int  i,  j,  tmp,  sel;  

8.         for  (i=0;  i<size-­‐1;  i++)  {  9.                 sel  =  i;  10.                 for  (j=i+1;  j<size;  j++)  11.                         if  (compara(vet[sel],  vet[j]))  12.                                 sel  =  j;  

13.                 tmp  =  vet[i];  14.                 vet[i]  =  vet[sel];  15.                 vet[sel]  =  tmp;  16.         }  

17.  }  

17

Ponteiro para Funções - Exemplo

1.  int  main()  {  2.         int  vet[7]  =  {5,6,1,2,3,7,4};  3.         int  i;  

4.         ordenacao  (vet,  7,  compara);  

5.         for  (i=0;  i<7;  i++)  prinS("%d  ",  vet[i]);  

6.         return  0;  7.  }  

18

FUNÇÕES  PARA  ALOCAÇÃO  EM  C   19

Funções de Alocação Dinâmica – ANSI - #include <stdlib.h> •  void * calloc(size_t num, size_t size);

•  Aloca uma quantidade de memória igual a num*size. Isto é, aloca memória suficiente para um ARRANJO de num VARIÁVEIS de tamanho size.

•  Devolve o endereço para o primeiro byte da região alocada. Se não houver memória suficiente para satisfazer a solicitação, é devolvido NULL (endereço nulo).

20

Funções de Alocação Dinâmica – ANSI - #include <stdlib.h> •  void * malloc(size_t size);

•  Aloca uma quantidade de memória igual a size. Isto é, aloca memória suficiente para uma VARIÁVEL de tamanho size.

•  Devolve o endereço para o primeiro byte da região alocada. Se não houver memória suficiente para satisfazer a solicitação, é devolvido NULL (endereço nulo).

21

Funções de Alocação Dinâmica – ANSI - #include <stdlib.h> •  void * realloc(void * ptr, size_t size);

•  Modifica o tamanho da memória previamente alocada apontada por ptr para um novo tamanho especificado por size. O valor size pode ser maior ou menor que o original.

•  Retorna o endereço para o primeiro byte da região de memória redimensionada.

•  Se não houver memória suficiente no HEAP para satisfazer a solicitação, é devolvido NULL (endereço nulo) e o endereço originalmente em ptr é deixado inalterado.

22

Funções de Alocação Dinâmica – ANSI - #include <stdlib.h> •  void free(void * ptr);

•  Devolve ao HEAP a memória apontada por ptr, tornando a memória disponível para alocação futura.

•  Deve ser chamada somente com um PONTEIRO ptr cujo endereço de memória foi previamente alocado por meio de uma das funções do sistema de alocação dinâmica (calloc(), malloc(), realloc()).

23

Outras - #include <string.h> •  char * strdup(const char * pstr);

•  Duplica a STRING apontada por pstr. Ou seja, aloca no HEAP strlen(pstr)+1 bytes e copia a STRING começando em pstr para o endereço alocado.

•  Retorna o endereço alocado contendo uma cópia da STRING apontada por pstr ou NULL caso não haja memória suficiente no HEAP.

24

Exemplo Outras •  Ex.: O trecho de código abaixo:

•  É equivalente a:

25

char str[] = "Teste"; char * pstr = strdup(str);

char str[] = "Teste"; char * pstr = calloc(strlen(str) + 1, sizeof char); strcpy(pstr,str);