Baixe o app para aproveitar ainda mais
Prévia do material em texto
Ponteiros BCC702-Programação de Computadores II Emiliana Mara Lopes Simões simoes.eml@gmail.com Universidade Federal de Ouro Preto março 2010 Ponteiros Definição: Um ponteiro é uma variável que contém um endereço de memória como valor. Normalmente trata-se do endereço de outra variável na memória Observações: Uma variável faz referência direta para um valor específico Um ponteiro contém o endereço de uma variável que possui um valor armazenado Ponteiros Ponteiros Estrutura geral de uma declaração de ponteiro: <tipo> *<nome_da_variavel>; Exemplos: Declarando um ponteiro para um tipo int: int *ptr; Declarando um ponteiro para um tipo double e declarando uma variável double: float *ptr, numero; Declarando e inicializando um ponteiro para um tipo int: int *ptr1 = NULL; Ponteiros Atenção Ponteiros apontam para variáveis do mesmo tipo. Isto é, ponteiro para um int aponta para o endeço de um número inteiro (int) Inicialize os ponteiros para evitar resultados indesejados (importantíssimo!!!) Um ponteiro com o valor 0 ou NULL não aponta para NADA (Ponteiro nulo) Ponteiros Razões para o bom entendimento da utilização de ponteiros: Aumenta a eficiência do código (mais rápido!); Utilizado para que funções modifiquem os valores de seus argumentos; Usados em rotinas que trabalham com alocação dinâmica de memória Atenção A manipulação de ponteiros requer muito cuidado! Operadores de Ponteiros & (operador de endereço): Operador unário que retorna o endereço de memória do seu operando Exemplo: int x = 0; //declara a variável x int *px; //declara um ponteiro para inteiro px = &x; /* coloca em px o endereço de memória da variável x */ Operadores de Ponteiros Operadores de Ponteiros Atenção: O operador & não pode ser aplicado a expressões e constantes Exemplos: int x = 0; int *px; px = &(x + 1); //Errado! px = &3; //Errado! Operadores de Ponteiros * (operador de indireção): Operador unário que manipula um ponteiro. Retorna um sinônimo para a variável apontada Exemplo: int x = 0; //declara a variável x int *px; //declara um ponteiro para inteiro px = &x; /* coloca em px o endereço de memória da variável x */ (*px) = 10; /* atualiza o valor armazenado na variável x para 10 */ Passagem de ponteiro como argumento de uma função Se uma função deseja alterar variáveis da função chamadora, podemos usar ponteiros NO QUADRO: Função que calcula o cubo de um valor Alocação dinâmica de memória A alocação dinâmica de memória permite ao programador o controle total sobre o tempo de vida das variáveis Através dos operadores new e delete, o programador consegue criar e destruir (respectivamente) variáveis de um determinado tipo Ao criar uma nova variável com o operador new esta variável não está sujeita às regras de escopo das variáveis locais. A variável criada com o operador new apenas pode ser destruída através do operador delete Alocação dinâmica de memória O operador new pode ser usado para alocar dinamicamente memória para: 1 Tipos básicos (int, double, char... etc) 2 Vetores 3 Tipos definidos pelo usuário (Classes) Alocação dinâmica de memória Exemplo 1: Alocação dinâmica de memória para um tipo básico int main(){ int *x; x = new int; //aloca memória para um inteiro *x = 10; cout<<*x<<endl; delete x; //desaloca memória system(“pause”); return 0; } Alocação dinâmica de memória O operador new “recebe como parâmetro” o tipo de dados da variável que se quer criar e devolve um ponteiro para a nova variável criada Ao operador delete é passado o ponteiro para uma variável criada com o operador new (o que é destruído é o apontado pelo ponteiro e não o próprio ponteiro!) Alocação dinâmica de memória Exemplo 2: Alocação dinâmica de memória para um vetor de inteiros de 5 elementos int main(){ int *y; y = new int[ 5 ]; for(int i=0; i < 5; i++) y[i] = i; for(int i=0; i < 5; i++) cout<<y[i]<<“ ”; delete y; //ERRO: Desaloca a memória //apenas do primeiro elemento do array system(“pause”); return 0; } Alocação dinâmica de memória Exemplo 3: Alocação dinâmica de memória para um vetor de inteiros de 5 elementos int main(){ int *y; y = new int[ 5 ]; for(int i=0; i < 5; i++) y[i] = i; for(int i=0; i < 5; i++) cout<<y[i]<<“ ”; delete [] y; //CORRETO system(“pause”); return 0; } Alocação dinâmica de memória: Tipo definido pelo usuário Classe Data: Criar uma classe para representar uma data qualquer no formato: dia/mês/ano class Data{ public: Data(); Data(int d, int m, int a); void print(); void setData(int d, int m, int a); private: int dia; int mes; int ano; }; Arquivo: Data.h Alocação dinâmica de memória: Tipo definido pelo usuário #include “Data.h” #include <iostream> #include <iomanip> using namespace std; void Data::setData(int d, int m, int a){ //insere dia if(d > 0 && d <= 31) dia = d; else{ cout<<“Dia invalido. Transformado em 1”<<endl; dia = 1; } ... Arquivo: Data.cpp Alocação dinâmica de memória: Tipo definido pelo usuário ... //insere mês if(m > 0 && m <= 12) mes = m; else{ cout<<“Mes invalido. Transformado em 1”<<endl; mes = 1; } //insere ano if(a >= 0) ano = a; else{ cout<<“Ano invalido. Transformado em 0”<<endl; ano = 0; } } Arquivo: Data.cpp Alocação dinâmica de memória: Tipo definido pelo usuário Data::Data(){ setData(1, 1, 0); } Data::Data(int d, int m, int a){ setData(d, m, a); } void Data::print(){ cout<<setw(2)<<setfill(’0’)<<dia <<“/”<<setw(2)<<mes<<“/”<<ano<<endl; } Arquivo: Data.cpp Alocação dinâmica de memória: Tipo definido pelo usuário #include <iostream> #include “Data.h” using namespace std; int main() { Data *d = new Data; d->print(); delete d; system(“PAUSE”); return 0; } Arquivo: Principal.cpp Alocação dinâmica de memória: Tipo definido pelo usuário Saída: 01/01/0 Press any key to continue... Alocação dinâmica de memória: Tipo definido pelo usuário #include <iostream> #include “Data.h” using namespace std; int main() { Data *d = new Data(5, 10, 2009); d->print(); delete d; system(“PAUSE”); return 0; } Arquivo: Principal.cpp Alocação dinâmica de memória: Tipo definido pelo usuário Saída: 05/10/2009 Press any key to continue... Vetor de ponteiros para objetos do tipo Data #include <iostream> #include “Data.h” using namespace std; int main(){ Data *vet[10]; //vetor de ponteiros do tipo Data int i; for(i=0; i < 10; i++) vet[i] = new Data(i+1,1,2010); for(i=0; i < 10; i++) vet[i]->print(); for(i=0; i < 10; i++) delete vet[i]; system(“PAUSE”); return 0; } Vetor de ponteiros para objetos do tipo Data Saída: 01/01/2010 02/01/2010 03/01/2010 04/01/2010 05/01/2010 06/01/2010 07/01/2010 08/01/2010 09/01/2010 10/01/2010 Press any key to continue... Método Destrutor O destrutor é um método especial chamado quando um objeto da classe é destruído. Ele possui as seguintes propriedades: Tem o mesmo nome da classe precedido por ~ ; Não tem valor de retorno, nem mesmo void; Não possui parâmetros; Uma classe só pode ter um destrutor. Método Destrutor Método Destrutor para a classe Data class Data{ public: Data(); Data(int d, int m, int a); ~Data(); //destrutor void print(); void setData(int d, int m, int a); private: int dia; int mes; int ano; }; Arquivo: Data.h Método Destrutor ... Data::~Data(){ cout<<“Destrutor Data... ” << endl; } ... Arquivo: Data.cpp Método Destrutor #include <iostream> #include “Data.h” using namespace std; int main() { Data *d = new Data; d->print(); delete d; system(“PAUSE”); return 0; } Arquivo: Principal.cpp Método Destrutor Saída: 01/01/0 Destrutor Data... Press any key to continue... Método Destrutor O destrutor pode ser usado, por exemplo, para desalocar memória que foi alocada dinamicamente na classe Exemplo: Método Destrutor Implementação da classe Evento. Um evento tem uma data de realização e um nome. #include <string> #include “Data.h” using namespace std;’ class Evento{ public: Evento(string n, int d, int m, int a); ~Evento(); //destrutor void print();private: Data *data; //ponteiro para um tipo Data string nome; }; Arquivo: Evento.h Exemplo: Método Destrutor #include “Evento.h” #include <iostream> Evento::Evento(string n, int d, int m, int a){ nome = n; data = new Data(d, m, a); //alocação dinâmica de memória } Evento::~Evento(){ cout<<“\n\nDestrutor Evento...\n”; delete data; //desalocação de memória alocada com new } void Evento::print(){ cout << “Evento: ” << nome << endl; data->print(); } Arquivo: Evento.cpp Exemplo: Método Destrutor #include <iostream> #include “Evento.h” using namespace std; int main() { Evento *e = new Evento(“Carnaval”, 16, 2, 2010); e->print(); delete e; system(“PAUSE”); return 0; } Arquivo: Principal.cpp Exemplo: Método Destrutor Saída: Evento: Carnaval 16/02/2010 Destrutor Evento... Destrutor Data... Press any key to continue... Dúvidas? Próxima Aula Aula tira dúvidas
Compartilhar