PR UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ DE JAVA AO C++ Prof. Cesar Augusto Tacla http://www.dainf.ct.utfpr.edu.br/~tacla JAVAProgParSD/0030-ProgParalelaDistribuida.ppt
Sumário 1. Diferenças básicas a. Método main com Hello World b. Classe e instanciação c. Herança, sobrecarga e sobreposição 2. Ponteiros a. Conceito b. Ponteiros em C++ c. Ponteiros e arrays d. Passagem de argumentos 2
Sumário 1 a Método main com Hello World 3
HELLO WORLD #include <iostream> using namespace std; int main(int argc, char* argv[]) { cout << "Hello World\n"; cout << "Argumentos\n"; // Imprime argumentos... if (argc > 1) { for (int i = 0; i < argc; i++) { cout << i << ": " << argv[i] << "\n"; getchar(); return 0; 4
HELLO WORLD Para rodar um programa no Windows Procurar o programa DEV CPP, c Montar projeto Compilar e executar No Linux Abrir shell g++ hello.cpp o hello.exe 5
EXERCÍCIO Quais as diferenças do programa do slide anterior em relação a um equivalente em Java? Execute o programa fazendo: >hello meu nome eh Joaquim Anote o resultado produzido Compare com uma implementação em Java solução 6
TIPOS DE DADOS Alguns tipos de dados char 1 byte [-128, 127] short int 2 bytes [-32.768, 32.678] int 4 bytes [-2.147.483.648, 2.147.483.647] float 4 bytes [3.4x10-38, 3.4x10 38 ] precisão de 7 dígitos double 8 bytes [1.7x10-308, 1.7x10 308 ] precisão 15 dígitos long double 12 bytes [3.4 x10-4934, 1.1x10 4934 ] precisão 19 dígitos Unsigneds unsigned char unsigned int unsigned long 7
TIPOS DE DADOS: TAMANHO EM BYTES #include <iostream> using namespace std; int main() { cout << sizeof(char) << endl; cout << sizeof(short int) << endl; cout << sizeof(int)<< endl; cout << sizeof(float) << endl; cout << sizeof(double) << endl; cout << sizeof(long double) << endl; getchar(); 8
Sumário 1 b Classe e instanciação 9
CLASSE EM C++ #include <iostream> using namespace std; class Contador { private: unsigned int cont; public: Contador() { cont=0; Contador(int ini) {cont=ini; // destrutora nao aceita parametros ~Contador() {cout << "destrutora"; void incr() {cont++; void decr() {cont--; int get() {return cont; ; VISIBILIDADE DESTRUTORA int main() { Contador a, b(5); // instancia dois objetos = NEW a.incr(); b.decr(); cout << "a=" << a.get() << " b=" << b.get() << endl; a.~contador(); // destroi objeto a b.~contador(); // destroi objeto b getchar(); 10
CLASSE EM C++ Em C++, normalmente divide-se uma classe em dois arquivos: Header file:.h Class file:.cpp 11
CLASSE EM C++ Exemplo: classe carro dividida em dois arquivos, Carro.h, Carro.cpp, e utilizada no main.cpp Carro.h class Carro { private: int ano; char placa[8]; Valor default public: Carro(int ano_, char* placa_ = "AAA0000"); Somente os int calcular_idade(int ano_atual); cabeçalhos int obter_ano(); dos métodos char* obter_placa(); ; 12
CLASSE EM C++ Corpos dos métodos definidos externamente à Classe: observar o nome da classe em vermelho Carro.cpp #include "Carro.h" #include <string.h> Construtoras Carro::Carro(int ano_, char* placa_) { ano = ano_; strcpy(placa, placa_); int Carro::calcular_idade(int ano_atual) { int idade; idade = ano_atual - ano; return idade; int Carro::obter_ano() { return ano; char* Carro::obter_placa() { return placa; 13
main.cpp #include <cstdlib> #include <iostream> #include "Carro.h" INSTANCIAÇÃO using namespace std; int main(int argc, char *argv[]) { int ano; cout << "Informe o ano atual: " << endl; cin >> ano; Carro corsa(2004); Carro meriva(2006, "AXL1020"); cout << corsa.calcular_idade(ano) << endl; cout << meriva.calcular_idade(ano) << endl; system("pause"); return EXIT_SUCCESS; Carro meriva(2006, AXL1020 ) em C++ equivale à Carro meriva = new Carro(2006, AXL1020 ) em JAVA 14
CLASSE EM C++ Arquivos Diretiva ao compilador: busque na pasta atual #include prog.h prog.h Busque na pasta include < > prog.cpp #include <biblio.h> biblio.h compilador prog.obj biblio.lib linker prog.exe 15
CIN >> e COUT<< main.cpp #include <stdio.h> #include Carro.h" int main(int argc, char *argv[]) { int ano; cout << "Informe o ano atual: " << endl; cin >> ano; Carro corsa(2004); Carro meriva(2006, "AXL1020"); cout << corsa.obter_placa() << " anos: " << corsa.calcular_idade(ano) << endl; cout << meriva.obter_placa() << " anos: " << meriva.calcular_idade(ano) << endl; system("pause"); return EXIT_SUCCESS; cin >> var >> operator get from cin = standard input stream cout << var << operador insertion cout = standard output stream 16
EXERCÍCIO 1 Na página do curso, localizar CPPRepositorio/Intro/Carro/ Executar Carro.exe Observar a instanciação do corsa e compreender a definição do valor default para a placa na construtora de carro 17
EXERCÍCIO 2 Fazer uma classe Pessoa em dois arquivos:.h e.cpp Atributos privados: Nome completo Sexo (masculino ou feminino) Dia, mês e ano de nascimento Métodos públicos Pessoa(nome, sexo, dia, mês, ano) Por default, sexo= m, dia=1, mês=1, ano=1970 obter_descricao() retorna <nome>, [homem mulher], nasceu em dd/mm/aa Fazer um setter para dia, mês e ano que faça consistência dos dias em função dos meses Fazer um setter para sexo que só aceita m ou f, caso contrário não efetua o set Em um arquivo main.cpp, Instanciar uma mulher com data de nascimento Instanciar um homem com valores default Imprimir as descrições na tela. 18
Sumário 1 c Herança, sobrecarga e sobreposição 19
HERANÇA Este exemplo mostra Veículo (classe base) e uma classe derivada, Carro. Observar que o mecanismo é idêntico ao Java: Atributos privados não são herdados pelas classes derivadas, por isso ano e placa são protegidos A construtora da classe base é chamada implicitamente pela construtora da classe derivada Diferença sintática em relação à JAVA Para acessar um método da classe base no código da derivada, utilizar a notação <Classe base>::<método> Java: super.<método> 20
HERANÇA e SOBRECARGA class Veiculo { protected: int ano; char placa[8]; int calcular_idade(int ano_atual) { int idade; idade = ano_atual - ano; return idade; void mostrar() { cout << "Placa: " << placa << " ano: " << ano << " idade: " << calcular_idade(2008); public: Veiculo(){ ano = 1970; strcpy(placa, "AAA0000"); Veiculo(int ano_, char* placa_) { // SOBRECARGA ano = ano_; strcpy(placa, placa_); ; 21
Equivale ao extends em Java HERANÇA e SOBREPOSIÇÃO class Carro : public Veiculo { // carro estende publicamente a classe Veículo private: int num_passageiros; int num_cavalos; bool importado; protected: float calcular_ipva(){ float base; base = (float)num_passageiros*num_cavalos/calcular_idade(2008); if (importado)base = base * 2.0; return base; ; public: Carro(int p, int c, bool i) { num_passageiros = p; num_cavalos = c; importado = i; void mostrar() { // sobrepõe o método da classe base Veiculo::mostrar(); // chama o mostrar() da classe base cout << "\ncavalos : " << num_cavalos << " passageiros: " << num_passageiros << "\nipva: " << calcular_ipva() << endl; Fonte: CPPRepositorio/Intro/VeiculoHeranca 22
HERANÇA e ACESSIBILIDADE Carro estende publicamente a classe Veiculo. Outra opção é estender de forma privada (default) Public significa que os métodos de Carro somente podem acessar os membros públicos e protegidos da classe Veículo. Se estendesse de forma privada, também poderia acessar os mesmos membros. Acessos fora da classe (ex. na main) somente podem acessar os membros públicos de Veículo. Se a extensão for private, nada é acessível 23
HERANÇA e ACESSIBILIDADE No exemplo, calcular_idade(int) de Veículo não é acessível a partir da função main por ser definido como protected. int main(int argc, char *argv[]) { Carro c(6, 130, true); c.calcular_idade(2008); // esta linha dah erro de acessibilidade c.mostrar(); system("pause"); return EXIT_SUCCESS; 24
Class Base HERANÇA E ACESSIBILIDADE private protected public class D1: public Base class D2: private Base private protected public private protected public D1 obj1 Não permitido D2 obj2 Em um método/função fora do corpo da classe 25
HERANÇA Algumas diferenças entre C++ e JAVA C++ permite herança múltipla class C : public A, public B C é especialização de A e B C++ permite sobrecarga de operadores Exemplo próximo slide operator é uma palavra reservada 26
SOBRECARGA DE OPERADORES #include <iostream> using namespace std; class Contador { private: unsigned int cont; public: Contador() { cont=0; Contador(int ini) {cont=ini; int get() {return cont; // sobrecarga pré-fixada int operator ++ () { return ++cont; // sobrecarga pós-fixada; int nao eh um arg verdadeiro int operator ++ (int) { return cont++; ; ; int main() { Contador a, b(5); // instancia dois objetos int x, y; x = ++a; cout << "a=" << a.get() << " x=" << x << endl; y = b++; cout << b=" << b.get() << " y=" << y << endl; 27
EXERCÍCIO Fazer duas especializações da classe Pessoa: Aluno Atributos: curso e universidade Ano de ingresso Sobrescrever o método obter_descrição: <nome>, [homem mulher], nasceu em dd/mm/aa, cursa <curso> desde <ano de ingresso> Professor Universidade Ano de contratação Sobrescrever o método obter_descrição: <nome>, [homem mulher], nasceu em dd/mm/aa, professor da <universidade> desde <ano de ingresso> 28
EXERCÍCIO Criar uma classe Turma para fazer o relacionamento entre Alunos e Professores por meio de uma classe associativa Um aluno tem aulas com vários professores Um professor leciona para vários alunos Esta classe deve permitir listar Todos os aluno s que um professor tem ou teve e quando (semestre/ano) Todos os professores que um aluno tem ou teve e quando (semestre/ano) 29
Sumário 2 PONTEIROS 30
Sumário 2 a CONCEITO 31
PONTEIROS: UTILIDADES Acessar elementos de um array Passar argumentos para um método quando este necessita modificar o argumento original Passar arrays e strings para métodos Obter memória do sistema Criar estruturas de dados, tais como listas encadeadas 32
CONCEITO Idéia básica: todo byte na memória do computador tem um endereço; endereços são números que identificam os bytes da memória. 0 programa 1.073.741.823 Memória 1 GB Área de memória ocupada pelo programa conteúdo var 1 shor var 1 var 2 char var 3 int var 3 var 3 var 3 endereço 655.601 = 0xA00F1 655.602 = 0xA00F2 655.603 = 0xA00F3 655.604 = 0xA00F4 655.605 = 0xA00F5 655.606 = 0xA00F6 655.607 = 0xA00F7 655.608 = 0xA00F8 655.609 = 0xA00F9 655.610 = 0xA00FA Ox indica notação em hexadecimal x bin dec 0 = 0000 = 0 1 = 0001 = 1 2 = 0010 = 2 3 = 0011 = 3 4 = 0100 = 4 5 = 0101 = 5 6 = 0110 = 6 7 = 0111 = 7 8 = 1000 = 8 9 = 1001 = 9 A = 1010 = 10 B = 1011 = 11 C = 1100 = 12 D = 1101 = 13 E = 1110 = 14 F = 1111 = 15 33
OPERADOR & Operador & retorna o endereço ocupado por uma variável Endereço é diferente de conteúdo Digite e execute o programa abaixo #include <iostream> using namespace std; int main() { int a = 16; int b = 32; int c = 64; cout << "end. de a: " << &a << endl; cout << "end. de b: " << &b << endl; cout << "end. de c: " << &c << endl; getchar(); 34
OPERADOR & Resultado do programa anterior endereco valor a: 0x22ff74 16 b: 0x22ff70 32 c: 0x22ff6c 64 4 bytes Conteúdo em binário Área de memória ocupada pelo programa conteúdo 0100 0000 0010 0000 0001 0000 endereço 0x22FF6c 0x22FF70 0x22FF74 c = 64 b = 32 a = 16 Observar que a diferença entre os endereços é de 4 bytes. Por que? 35
PONTEIRO Ponteiro é uma variável que armazena um endereço de uma variável Exemplo: p aponta para a variável a Qual o conteúdo da variável p? Área de memória ocupada pelo programa conteúdo endereço 0100 0000 0x22FF6c 0x22FF70 c b 0010 0000 0x22FF74 a 0001 0000 0x 0 0 p 0x 2 2 0x F F 0x22FF78 0x 7 4 36
Sumário 2 b PONTEIRO EM C++ 37
PONTEIRO EM C++ Declaração de uma variável tipo ponteiro para inteiro #include <iostream> using namespace std; int main() { int a = 16; int b = 64; cout << "endereco\tvalor" << endl; cout << "a: " << &a << "\t" << a << endl; cout << "b: " << &b << "\t" << b << endl; int* p; // ponteiro para inteiro p = &a; cout << "ponteiro: " << p << endl; p = &b; cout << "ponteiro: " << p << endl; getchar(); 38
SINTAXE DE DECLARAÇÃO DE PONTEIROS char* cptr; int* iptr; float* fptr; Contador* contptr; char *cptr; int *iptr; float *fptr; Contador *contptr; As duas formas são válidas Mais utilizada //Declaração de vários ponteiros na mesma linha char *p1, *p2, *p3; 39
OPERADOR DE INDIREÇÃO Operador de indireção * serve para acessar o conteúdo apontado por um ponteiro o valor retornado por *p é 16 *p Área de memória ocupada pelo programa conteúdo endereço 0100 0000 0x22FF6c 0x22FF70 c b 0010 0000 0x22FF74 a = 16 0001 0000 0x0 0 0x22FF78 p 0x2 2 0xF F 0x7 4 40
OPERADOR DE INDIREÇÃO #include <iostream> using namespace std; int main() { int a = 16; int b = 64; cout << "valor de p\tconteudo apontado" << endl; int* p; // ponteiro para inteiro p = &a; cout << p << "\t" << *p << endl; p = &b; cout << p << "\t" << *p << endl; getchar(); *p é o conteúdo do endereço apontado por p; este conteúdo é interpretado como um número inteiro por causa do tipo do ponteiro (int*) 41
OPERADOR DE INDIREÇÃO operador * serve para acessar o conteúdo apontado por um ponteiro e também modificá-lo. *p = 15 //atribuição de valor O endereço apontado por p recebe o valor 15 *p Área de memória ocupada pelo programa conteúdo endereço 0100 0000 0x22FF6c 0x22FF70 c b 0010 0000 0x22FF74 a = 15 0000 1111 0x0 0 0x22FF78 p 0x2 2 0xF F 0x7 4 42
OPERADOR DE INDIREÇÃO #include <iostream> using namespace std; int main() { int a = 16; int b = 64; cout << "valor de p\tconteudo apontado" << endl; int* p; // ponteiro para inteiro p = &a; *p = 15; // idêntico: a=15 cout << p << "\t" << *p << endl; b = *p; // idêntico: b=a cout << p << "\t" << *p << endl; getchar(); 43
PONTEIRO PARA VOID O endereço colocado num ponteiro deve ser de uma variável de mesmo tipo do ponteiro Exemplo: int a; int* p = &a; char* pc = &a; // ERRO void *p é uma ponteiro que pode apontar para qualquer tipo de dado 44
EXERCÍCIOS 1. Faça um programa que atribua um endereço de uma variável inteira 1. a um ponteiro para float 2. a um ponteiro para void 2. Marque a opção correta: um ponteiro é... 1. Um endereço de uma variável 2. Uma variável que armazena um endereço 3. Um tipo de dado de uma variável de endereço 3. O código seguinte está correto/errado quanto à lógica? 1. int i = 30; 2. int* ptr; 3. cout << *ptr; 4. Qual a diferença entre as seguintes declarações: 1. int *ptr; 2. *ptr = 10; 45
Sumário 2 c PONTEIROS E ARRAYS 46
PONTEIROS E ARRAYS #include <iostream> using namespace std; int main() { int a[5]={1,2,3,5,8; // acesso normal for (int i=0; i<5; i++) cout << a[i] << " "; cout << endl << endl; // acesso por ponteiro for (int j=0; j<5; j++) cout << *(a+j) << " "; getchar(); a variável a é um ponteiro para inteiro ar[j] similar int *(a+j); 47
PONTEIROS E ARRAYS No exemplo anterior, inclua abaixo da linha indicada pela linha seguinte: cout << a << endl; Em seguida, coloque cout << *a << endl; Agora, coloque cout << a+1 << endl; e compare como valor obtido pela primeira linha Finalmente coloque cout << *(a+1) << endl; CPPRepositorio/Ponteiros/PonteirosArrays.cpp 48
PONTEIROS E ARRAYS Exercício: dado um vetor de char de tamanho qualquer, imprima-o invertido utilizando ponteiro. Exemplo: A B A C A T E \0 E T A C A B A \0 49
Sumário 2 d PASSAGEM DE ARGUMENTOS 50
PASSAGEM DE ARGUMENTOS Argumentos podem ser passados aos métodos por 3 maneiras distintas: Por valor: uma cópia do valor da variável é passado ao método o valor da variável original não é modificado Existe em JAVA Por referência: o endereço da variável é passado ao método o valor da variável original é modificado Alias Existe em JAVA Por ponteiro: o endereço da variável é passado ao método o valor da variável original é modificado Ponteiro NÃO EXISTE EM JAVA 51
PASSAGEM POR REFERÊNCIA // Este programa ilustra passagem de argumentos // por referencia. Observar que o argumento // r em parasegundos e a variavel h sao // simbolos alternativos (alias) e portanto sao a mesma // coisa. #include <iostream> using namespace std; void parasegundos(int &r) { cout << "endereco r = " << &r << endl; r = r*3600; int main() { int h = 5; cout << "endereco h = " << &h<< endl; cout << "h = " << h << endl; parasegundos(h); // passa a referencia da var h na tabela // de simbolos (indice) cout << "h = " << h << endl; getchar(); CPPRepositorio/Ponteiros/PassagemRef.cpp 52
PASSAGEM POR REFERÊNCIA Tabela de símbolos Referência Símbolo Endereço Conteúdo 1 h alias r 0x22FF74 5 (inteiro) 2............... r e h são dois símbolos alternativos r aliás h = r, de outra forma, h 53
// Este programa ilustra passagem de argumentos // por ponteiro. Observar que o argumento // r em parasegundos e a variavel h sao // simbolos que apontam para o mesmo endereco, mas // ocupam posicoes distinas na memoria. #include <iostream> using namespace std; void parasegundos(int *r) { cout << "endereco r = " << &r << endl; *r = *r * 3600; int main() { int h = 5; cout << "endereco h = " << &h<< endl; cout << "h = " << h << endl; PASSAGEM POR PONTEIRO parasegundos(&h); // passa o endereco de h cout << "h = " << h << endl; getchar(); CPPRepositorio/Ponteiros/PassagemPonteiro.cpp 54
PASSAGEM POR PONTEIRO Tabela de símbolos Referência Símbolo Endereço Conteúdo 1 h 0x22FF74 5 (inteiro) 2 r 0x22FF50 0x22FF74......... r e h são dois símbolos diferentes, cada um ocupa uma posição de memória. r é um ponteiro que aponta para h 55
PONTEIROS E ARRAYS Exercício crie uma FILA de encadeamento simples para armazenar objetos da classe pessoa. Um objeto da classe Pessoa aponta para o próximo da lista. O último aponta para NULL. A fila deve ser uma classe com os métodos Incluir (sempre depois do last) Imprimir do first ao last :Pessoa nome: João :Pessoa nome: José :Pessoa nome: Maria NULL first last CPPRepositorio\Ponteiros\ListaPessoa 56