ALGORITMOS E ESRUTRA DE DADOS I Ponteiros Passagem por Valor e Referência Alocação de Memória 2 Agenda • Ponteiros • Conceitos gerais • O que é Ponteiro? • Declaração de Ponteiros • Operadores para Ponteiros • Exemplos • Exercícios • Passagem de argumento por valor • Passagem de argumento por referência • Alocação Dinâmica de Memória 3 PONTEIROS 4 Conceitos Gerais (1/2) Três propriedades que um programa deve manter quando armazena dados: onde a informação é armazenada; que valor é mantido lá; que tipo de informação é armazenada. A definição de uma variável simples obedece a estes três pontos. • A declaração provê o tipo e um nome simbólico para o valor. • Faz também que o programa aloque memória para o valor e mantenha o local internamente. 5 Conceitos Gerais (2/2) Como obter o endereço de uma variável na memória? Aplique o operador de endereço, &, a uma variável para pegar sua posição. Exemplo: 6 O que é Ponteiro? Ponteiros são variáveis que guardam um endereço de memória. • int guarda inteiros. • float guarda números decimais. • char guarda caracteres. Na Linguagem C, quando declaramos ponteiros devemos informar o tipo de variável que será apontada. 7 Declaração de Ponteiros (1/2) Declaração tipo *variavel; Exemplos: char int float *ch; *i; *num; 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. 8 Declaração de Ponteiros (2/2) 9 Operadores para Ponteiros Para trabalharmos com ponteiros, a Linguagem C disponibiliza os seguintes operadores: & Retorna o endereço de memória onde está armazenado uma variável. Lê-se “o endereço de”. * O Valor armazenado na variável referenciada por um ponteiro. Lê-se “o valor apontado por”. 10 Exemplo 1: Operador &: retorna o endereço de memória de seu operando. int count; int *m; Variável Endereço Memória count 1001 5 m 1200 ? count = 5; Variável m = &count; Endereço Memória count 1001 5 m 1200 1001 11 Exemplo 2: Operador *: O valor da variável localizada no endereço de seu operando. Variável int count,q; int *m; Endereço Memória count 1001 5 m 1200 1001 q 1007 ? count = 5; m = &count; q = *m; Variável Endereço Memória count 1001 5 m 1200 1001 q 1007 5 12 Exemplo 3 /*declaração das variáveis */ Variável Memória Endereço int *p, num; /* num recebe o valor 5 */ int num = 5; /* p recebe o endereço de memória de num */ p = &num; p - 206 num 5 202 202 5 206 202 8 206 p num /* conteúdo de p recebe o valor 8 */ *p = 8; p num 202 202 13 Valor de x ? #include "stdafx.h" #include <stdio.h> #include <conio.h> int main(void){ int x; int *i; x = 23; i = &x; *i = 19; printf("x = return 0; } %d",x); 14 Passagem de Argumentos por Valor 15 Passagem de Argumentos por Valor • Quando passamos argumentos a uma função, os valores fornecidos são copiados para as variáveis da função. • Desta forma, alterações nos parâmetros dentro da função não alteram os valores que foram passados. • Exemplos: 16 Passagem de Argumento por Referência 17 Passagem de Argumentos por Referência (1/3) • No exemplo acima, se x e y fossem passados por referência, seu conteúdo seria trocado. 18 Passagem de Argumentos por Referência (2/3) • Alternativa: Passar como argumento para uma função o endereço da variável, e não o seu valor. • Desta forma podemos alterar o conteúdo da variável fazendo passagem por referência. • Exemplo: 19 Passagem de Argumentos por Referência (3/3) Função scanf (“%d”,&variavel); 20 Alocação de Memória 21 Conceitos Gerais • A alocação de memória, permite criar variáveis em tempo de execução, ou seja, alocar memória para novas variáveis em tempo de execução. • Proporciona uma melhor utilização da memória da máquina, pois quando criada em tempo de execução não é necessária a utilização de memória adicional. • As funções de alocação dinâmica são muito eficiente para a implementação de arranjos e estruturas de dados. Esta é outra ferramenta que mostra o poder da Linguagem C. 22 Função Malloc Serve para alocar memória, ou seja, reserva um numero especifico de memoria, dependendo do tipo do ponteiro que chama a função. Sintaxe: (tipo*)(malloc(sizeof(tipo))); • A função malloc reserva o número de bytes que queremos alocar na memória e retorna um ponteiro void * para o primeiro byte alocado. • O ponteiro void * pode ser atribuído a qualquer tipo de ponteiro. Lembre-se que cada tipo de dados possui um numero reservado de byte. • Se não houver memória suficiente para alocar a memória requisitada a função malloc() retorna um ponteiro nulo. 23 Exemplo de Alocação de um tipo int (1/2) int *p = (int*)(malloc(sizeof(int); • Foi declarado um ponteiro p do tipo int, e alocado um endereço de memória (4 bytes). • A primeira referência ao tipo (int *) na instrução esta relacionada a variável de retorno, ou seja, a variável que chama a função malloc, um ponteiro do tipo int. • A primeira referência ao tipo (int) na instrução esta relacionada a alocação solicitada, ou seja, uma solicitação de endereço de tamanho int. 24 Exemplo de Alocação de um tipo int (2/2) #include <stdio.h> #include <stdlib.h> int main (void){ int *p; p=(int *)malloc(sizeof(int)); if (!p){ printf ("** Erro: Memoria Insuficiente **"); exit; }else{ printf ("** Memoria Alocada com Sucesso **"); } return 0; }