Baixe o app para aproveitar ainda mais
Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
[1] Ponteiro e Alocação Dinâmica Prof. Rogério Colpani 1 [2] SUMÁRIO Estrutura de Dados Definição de ponteiros. Declaração de ponteiros. Os operadores de ponteiros. Atribuição de ponteiros. Inicialização de ponteiros. Ponteiros e Matrizes. Alocação Dinâmica. [3] Estrutura de Dados Um PONTEIRO é uma VARIÁVEL que contém um ENDEREÇO DE MEMÓRIA. Esse endereço, é normalmente a posição de uma outra variável na memória. Se uma variável contém o endereço de outra, então a primeira variável é dita apontar para a segunda. DEFINIÇÃO [4] Estrutura de Dados Endereço na Memória Variávelna Memória Variável 1000 1003 *p 1001 1002 1003 10 Soma 1004 1005 1006 DEFINIÇÃO [5] Estrutura de Dados Fornecem os meios pelos quais as funções podem modificar argumentos. São usados para suportar as rotinas de alocação dinâmica. Pode aumentar a eficiência de certas rotinas. ALGUMAS RAZÕES PARA USAR PONTEIROS [6] Estrutura de Dados tipo *nome_da_variável; DECLARAÇÃO DE PONTEIROS int *res; // ponteiro para uma variável inteira. float *div; // ponteiro para uma variável de ponto flutuante. [7] Estrutura de Dados OS OPERADORES DE PONTEIROS Há DOIS operadores especiais de ponteiros: &: operador unário que devolve o endereço na memória do seu operando. m = &count Coloca em m o endereço de memória que contêm a variável count. Esse endereço é a posição interna ao computador da variável. O endereço não tem relação alguma com o valor de count. [8] Estrutura de Dados OS OPERADORES DE PONTEIROS O operador & pode ser imaginado como retornando “o endereço de.” Assim, o comando de atribuição anterior significa “m recebe o endereço de count”. Endereço de Memória 1996 2000 count 2004 2008 2012 2016 m= 2000 2020 int count = 100; m = &count; // valor de m = 2000 [9] Estrutura de Dados OS OPERADORES DE PONTEIROS *: é o complemento de &. É um operador unário que devolve o valor da variável localizada no endereço que o segue. O operador * pode ser imaginado como “no endereço”. Se m contém o endereço da variável count e q = *m; coloca o valor de count em q. Portanto, q terá o valor 100, porque 100 estava armazenado na posição 2000, que é o endereço que estava armazenado em m. [10] Estrutura de Dados OS OPERADORES DE PONTEIROS count = 100; m = &count; // valor de m = 2000 int q = *m; // valor de q = 100 Endereço de Memória 1996 2000 count 2004 2008 2012 2016 m= 2000 2020 Endereço de Memória 1996 2000 count 2004 2008 q = 100 2012 2016 m= 2000 2020 [11] Estrutura de Dados EXEMPLO int a = 100; int *p; p = &a; cout << &a; // 2000 cout << a; // 100 cout << p; // 2000 cout << *p; // 100 cout << &p; // 2016 Endereço de Memória 1996 2000 a 2004 2008 2012 2016 p 2020 [12] Estrutura de Dados ATRIBUIÇÃO DE PONTEIROS int x; int *p1, *p2; p1 = &x; p2 = p1; cout << p2 // escreve o endereço de x. Endereço de Memória 1996 2000 x 2004 2008 p1 = 2000 2012 2016 p2 = p1 2020 [13] Estrutura de Dados ARITMÉTICA DE PONTEIROS ADIÇÃO SUBTRAÇÃO Vamos aprender por meio de um exemplo [14] Estrutura de Dados EXEMPLO Seja p1 um ponteiro para um inteiro com o valor atual 2000. Suponha que os inteiros são de 2 bytes. Endereço de Memória 1996 p1 1998 2000 2002 2004 2006 2008 p1++ Endereço de Memória 1996 p1 1998 2000 2002 2004 2006 2008 [15] Estrutura de Dados EXEMPLO Endereço de Memória 1996 p1 1998 2000 2002 2004 2006 2008 p1++ Endereço de Memória 1996 p1 1998 2000 2002 2004 2006 2008 1996 p1 1998 2000 2002 2004 2006 2008 p1++ 1996 p1 1998 2000 2002 2004 2006 2008 [16] Estrutura de Dados EXEMPLO Endereço de Memória 1996 p1 1998 2000 2002 2004 2006 2008 p1-- Endereço de Memória 1996 p1 1998 2000 2002 2004 2006 2008 1996 p1 1998 2000 2002 2004 2006 2008 p1-- 1996 p1 1998 2000 2002 2004 2006 2008 [17] Estrutura de Dados PONTEIROS E MATRIZES int str[ ] = { 1, 2, 3, 4, 5 }; int *p1; p1 = str; cout << *(p1 + 1 ); // 2 cout << str[1]; // 2 Endereço de Memória 1996 p1 2000 2004 1 2008 2 2012 3 2016 4 2020 5 str[0] str[1] str[2] str[3] str[4] [18] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA Pilha Heap Variáveis Globais Código do Programa Um programa ao ser executado divide a memória em 4 áreas: CÓDIGO DO PROGRAMA: região onde contém o código do programa. VÁRIÁVEIS GLOBAIS: região onde as variáveis globais são armazenadas. HEAP: região de memória livre que o programa pode usar via alocação dinâmica. PILHA: diversos usos durantes a execução do programa. Ela possui o endereço de retorno das chamadas de função, argumentos para funções e variáveis locais ... [19] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA É o meio pelo qual um programa pode obter memória enquanto está em execução. [20] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA A alocação e liberação desses espaços de memória é feito por duas funções: malloc ( ): aloca um espaço de memória. free ( ): libera um espaço de memória. [21] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA FUNÇÃO malloc ( ) Abreviatura de memory allocation. Aloca um bloco de bytes consecutivos na memória e devolve o endereço desse bloco. Retorna um ponteiro do tipo void. Deve-se utilizar um cast para transformar o ponteiro devolvido para um ponteiro do tipo desejado. [22] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA FUNÇÃO malloc ( ) void *malloc ( size_t número_de_bytes ) void *malloc: devolve um ponteiro do tipo void, o que significa que você pode atribuí-lo a qualquer tipo de ponteiro. número_de_bytes: é o número de bytes de memória que você quer alocar. size_t: é um inteiro sem sinal. [23] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA Alocando um vetor de n elementos do tipo inteiro. int *p; p = (int*) malloc ( n * sizeof (int) ); [24] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA A memória não é infinita. Se a memória do computador já estiver toda ocupada, a função malloc não consegue alocar mais espaço e devolve NULL. Usar um ponteiro NULL travará o seu computador. ptr = (int*) malloc ( 1000 * sizeof (int) ); if ( ptr == NULL ) { cout << “Sem memoria”; } [25] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA FUNÇÃO free ( ) Libera o uso de um bloco de memória, permitindo que este espaço seja reaproveitado. O mesmo endereço retornado por uma chamada da função malloc ( ) deve ser passado para a função free ( ). A determinação do tamanho do bloco a ser liberado é feita automaticamente. [26] Estrutura de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA Liberando espaço ocupado por um vetor de 100 inteiros. int *p; p = (int*) malloc ( 100 * sizeof (int) ); free (p); [27] Estrutura de Dados EXEMPLO int *v; int TAM; cout << "Qual o tamanho do vetor? "; cin >> TAM; v = (int*) malloc ( TAM * sizeof(int*) ); if ( v == NULL ) { cout << "Sem memoria"; exit(1); } for (int i=0; i<TAM; i++) { cout << "\nVETOR [ " << i << " ]: "; cin >> *(v+i); } for ( int i=0; i<TAM; i++ ) cout << "\nVETOR [ " << i << " ]: " << v[i]; free (v); [28] Estrutura de Dados EXERCÍCIOS
Compartilhar