Linguagem de Programação I -...

53
Linguagem de Programação I Carlos Eduardo Batista Centro de Informática - UFPB [email protected]

Transcript of Linguagem de Programação I -...

Linguagem de Programação I

Carlos Eduardo Batista

Centro de Informática - UFPB [email protected]

Templates

Sobrecarga de funções ◦ Mesmo nome

◦ Mesma semântica

◦ Diferentes tipos de dados

As vezes a mesma sintaxe...

2

int soma(int x, int y) {

return x + y;

}

Ponto soma(Ponto x, Ponto y) {

return x + y; //supondo operador + sobrecarregado

}

Templates em C++

Templates = modelos, padrões

Genericidade: a partir do momento em que o tipo parâmetro fornece tudo o que é usado no símbolo template, é possível passar qualquer tipo.

Simplicidade: só é possível codificar um símbolo, independentemente dos tipos passados em parâmetro, o que torna o código mais fácil de manter.

3

Templates em C++

Templates para funções

T representa um tipo de dados qualquer ◦ Tipos primitivos (int, float, char ...)

◦ Classes definidas pelo usuário

4

template <class T>

T fun(T parametros, ...)

{

//faça coisas usando um tipo T

}

template <class T>

T soma(T x, T y) {

return x + y;

}

Templates C++ 5

int sumVector(int *array, int n)

{

int sum(0);

// mais eficiente que: int sum=0;

for (int idx = 0; idx < n; ++idx)

sum += array[idx];

return (sum);

} template <typename T>

T sumVector(T *array, int n)

{

T sum=0;

for (int idx = 0; idx < n; ++idx)

sum += array[idx];

return (sum);

}

Templates em C++

Tipos a serem usados podem ser restringidos ◦ Otimiza a compilação (são geradas “versões” do código que usa o template para os tipos definidos)

6

template <typename T> // um tipo genérico

T sumVector(T *array, int n)

{ ... }

template int sumVector<int>(int *, int);

template double sumVector<double>(double *, int);

int main() { ... }

Templates em C++ - Classes 7

template <class T>

class Camaleao {

public:

Camaleao();

Camaleao(T novaVariavel);

~Camaleao();

T getVariavel();

void setVariavel(T novaVariavel);

private:

T variavel;

};

Templates em C++ - Classes 8

template <typename T>

class Vector

{

int d_size; T *d_v;

public:

Vector(int size):d_size(size){d_v=new T[d_size];}

~Vector(){delete d_v;}

T operator[](int index) const{return d_v[index];}

int size() const { return d_size;}

T &operator[](int index){ return d_v[index];}

void enlarge(int newsize)

{

T *aux=new T[newsize];

for(int i=0;i<d_size;i++) aux[i]=d_v[i];

delete []d_v; d_v=aux; d_size=newsize;

}

friend ostream &operator<<(ostream &o, Vector<T> const &t)

{

for(int i=0;i<t.d_size;i++) o << t.d_v[i] << " ";

return o << "\n";

}

};

Templates em C++ - Herança 9

template<typename T>

class Base

{

T d_t;

public:

Base(T const &t):d_t(t);

};

template<typename T>

class Derived: public Base<T>

{

public:

Derived(T const &t) : Base(t){}

};

class Ordinary: public Base<int> //

{

public:

Ordinary(int x) : Base(x) {}

};

Exceções

Tratamento de erros hierarquizado Erros que:

◦ Comprometem dados do usuário.

◦ Impedem a boa execução do programa.

◦ Erros que devem ser evitados e avisados aos usuários

Palavras chave try, throw e catch. try

◦ Inicia um bloco passível de lançar exceção

throw ◦ Arremessa uma exceção

catch ◦ Captura uma exceção

10

Exceções em C++ 11

void fun() { throw 1337; }

int main() {

try {

fun();

}

catch (...){

//faça algo com a exceção

}

}

Exceções em C++ 12

class DivideByZeroException {

public:

string message;

DivideByZeroException() {

message = “DIVISION BY ZERO”;

}

}

int divide(int a, int b)

{

if (b==0)

throw DivideByZeroException();

return a/b;

}

Exceções em C++ 13

int main()

{

try {

divide(3,0);

}

catch (DivideByZeroException e) {

cout << “Erro: ” << e.message << endl;

}

}

Exceções em C++

catch(...) ◦ Qualquer tipo

◦ catch(X var)

Objetos da classe X e de suas derivadas

14

Exemplo: ◦ Explorar Templates e Exceções

◦ Incrementar com o uso de STL

15

STL

STL é uma biblioteca padrão com as estruturas de dados mais usadas ◦ Criada para evitar a implementação e teste das mesmas estruturas de dados

◦ Economiza tempo e evita retrabalho

É a biblioteca padrão de C++ Padronizada pelo ANSI em 1997 Por que templates?

◦ Poupam da tarefa de reimplementar o código para cada novo tipo de dado da sua aplicação.

16

STL

Quando usados apropriadamente, templates são bastante eficazes. ◦ Porém, mensagens de erro STL costumam ser pouco elucidativas.

Uma boa fonte sobre a STL é o guia de programação da SGI

17

STL

A STL oferece: ◦ Containers (recipientes). ◦ Iterators (iteradores). ◦ Algorithms (algoritmos).

Recipientes servem para armazenar dados e podem ser classificados como: ◦ Seqüências de dados ◦ Recipientes associativos para pares de objetos

(chave, dado). ◦ Adaptadores que provêem um subconjunto da

funcionalidade de um recipiente. Pilhas, filas, filas de prioridade.

18

Organização da STL

Containers

<vector> Array unidimensional do tipo T

<list> Lista duplamente ligada do tipo T

<deque> Lista ligada ‘double-ended’ do tipo T

<queue> Lista ligada do tipo T

<stack> Pilha do tipo T

<map> Array associativo do tipo T (red-black tree)

<set> Conjunto do tipo T

<bitset> Array de booleanos

Organização da STL

General Utilities

<utility> Operadores

<funcional> Funções

<memory> Funções para manipulação de memória

<ctime> Funções de C para manipulação de data e hora

Iterators

<iterator> Definição e suporte para Iterators

Algorithms

<algorithm> Algoritmos gerais

<cstdlib> bsearch() e qsort()

Organização da STL

Diagnostics

<exception> Definição da classe exception

<stdexception> Exceções da biblioteca padrão

<cassert> Diagnóstico de Erros

<cerrno> Tratamento de erro com as funções de C

Organização da STL

Strings

<string> string do tipo T

<cctype> Classificação de caracteres

<cwctype> Classificação de wide-caracters

<cstring> Funções de C para manipulação de strings

<cwchar> Funções de C para classificação de wide-caracters

<cstdlib> Mais funções de C para manipulação de strings

Organização da STL

Input/Output

<iosfwd> Declarações forward de facilidades de E/S.

<iostream> Objetos e operações padrões de E/S.

<ios> Classes bases de E/S.

<streambuf> Stream buffers.

<istream> Templates de stream de entrada.

<ostream> Templates de stream de saída.

<iomanip> Manipuladores.

<sstream> Stream para E/S com strings.

Organização da STL

Input/Output

<cstdlib> Classificação de caracteres e funções

<fstream> Streams para E/S com arquivos

<cstdio> printf() e scanf()

<cwchar> printf() e scanf() para wide characters

Language Suport

<locale> Representa diferenças culturais

<clocale> Funções de C para representar diferenças culturais

Organização da STL

Language Suport

<limits> Limites numéricos

<climits> Macros de C com os limites numéricos

<cfloat> Macros de C com os limites de ponto flutuante

<new> Gerenciamento de memória dinâmico

<typeinfo> Suporte para identificação de tipos em tempo de execução

<exception> Suporte para o tratamento de exceções

<cstddef> Suporte para a biblioteca da linguagem C

<cstdargs> Criação de funções com lista de argumentos variável

<csetjmp> Funções de C para manipulação de Pilhas

Organização da STL

Language Suport

<cstdlib> Finalização do programa

<ctime> Relógio (Clock) do sistema

<csignal> Manipulação de sinais em C

Numéricos

<complex> Números complexos e seus operadores

<valarray> Vetores numéricos e operações

<numeric> Operações numéricas generalizadas

<cmath> Funções matemáticas de C

<cstdlib> Geração de números aleatórios em C

STL - Iteradores

Criados para permitir uma maneira unificada de percorrer ou recuperar dados de recipientes. ◦ Escondem detalhes de implementação das

aplicações. Diminui o uso de ponteiros

◦ É possível trocar o tipo de recipiente e ainda assim usar o mesmo código.

A STL adota a filosofia de manter os algoritmos fora das classes dos recipientes. ◦ Permitir que o mesmo algoritmo possa agir sobre

recipientes diferentes.

27

STL - Iteradores

Algoritmos são implementados usando iteradores apenas. ◦ Ordenação, busca, contagem, substituição, etc...

◦ Iteradores tem operadores de incremento “++” definidos.

◦ Ponteiros podem ser usados como iteradores.

28

STL - Iteradores 29

#include <vector>

#include <iostream>

using namespace std;

template <class T>

struct print : public unary_function <T, void>

{

print(ostream& out) : os(out), count(0) {}

void operator() (T x) { os << x << ' ';

++count; }

ostream& os;

int count;

};

int main()

{

int A[] = {1, 4, 2, 8, 5, 7};

const int N = sizeof(A) / sizeof(int);

print<int> P = for_each(A, A + N,

print<int>(cout));

cout << endl << P.count << " objects

printed." << endl;

return 1;

}

30

STL - Vector

vector é o recipiente mais simples da STL. ◦ Seqüência que suporta acesso aleatório aos seus elementos.

◦ Inserção e remoção de elementos no final em O(1).

◦ Inserção e remoção de elementos no meio em O(n).

◦ Busca em O(n). ◦ Gerenciamento automático de memória. ◦ Iteradores estão invalidados após realocação de memória, inserção e remoção no meio.

◦ Descrição e implementação

STL - Vector 31

#include <vector>

#include <iostream>

#include <iterator>

#include <ext/algorithm>

using namespace std;

using __gnu_cxx::is_sorted;

int main()

{

vector<int> V;

V.push_back(20);

V.push_back(30);

V.push_back(-1);

V.push_back(-1);

V.push_back(-1);

cout << "V: \n";

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));

stable_sort (V.begin(), V.end());

cout << "\nV: sorted\n";

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));

cout << "\nV: is sorted? ";

cout << is_sorted ( V.begin(), V.end() ) << "\n";

}

STL - Vector 32

template<class InputIterator, class OutputIterator>

inline OutputIterator copy(InputIterator first, InputIterator last,

OutputIterator result) {

for( InputIterator itr = first; itr != last; ++itr, ++result ) {

*result = *itr;

}

return result;

}

33

STL - List

list é de fato uma lista duplamente encadeada. ◦ É uma seqüência que suporta percurso para frente e para trás.

◦ Busca em O(n).

◦ Inserção e remoção de elementos na frente, no meio e no final em O(1).

◦ Iteradores ainda estão válidos após inserção, splicing ou remoção.

STL - List 34

#include <list>

#include <iostream>

#include <iterator>

using namespace std;

int main()

{

list<int> L;

L.push_back(0);

L.push_front(1);

L.insert(++L.begin(), 2);

copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));

cout << "\n";

list<int> M ( L );

L.splice ( ++++L.begin(), M );

copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));

cout << “\n”;

copy(M.begin(), M.end(), ostream_iterator<int>(cout, " "));

}

STL - List 35

#include <iostream>

#include <list>

using namespace std;

int main() {

list<string> l;

l.push_back("Hello, ");

l.push_back(“Bro! ");

l.push_back("Fine? ");

for (list<string>::const_iterator i = l.begin(); i != l.end(); ++i) cout << *i;

}

36

STL - Set

set é uma coleção ordenada de objetos do tipo “key” sem duplicatas. ◦ Operações de conjunto como interseção, união e diferença são eficientes.

◦ Implementado por uma árvore balanceada de busca (Red Black, Splay).

◦ Busca em O(log n).

multiset é a versão que permite duplicatas.

STL - Set 37

#include <set>

#include <iostream>

using namespace std;

struct ltstr // função objeto. Compara duas seqüências de caracteres.

{

bool operator()(const char* s1, const char* s2) const

{

return strcmp(s1, s2) < 0;

}

};

int main()

{

const int N = 6;

const char* a[N] = {"isomer", "ephemeral", "prosaic",

"nugatory", "artichoke", "serif"};

const char* b[N] = {"flat", "this", "artichoke",

"frigate", "prosaic", "isomer"};

set<const char*,ltstr> A(a, a + N);

set<const char*,ltstr> B(b, b + N);

set<const char*,ltstr> C;

STL - Set 38

cout << "Set A: ";

copy(A.begin(), A.end(), ostream_iterator <const char*>(cout, " "));

cout << endl;

cout << "Set B: ";

copy(B.begin(), B.end(), ostream_iterator <const char*>(cout, " "));

cout << endl;

cout << "Union: ";

set_union(A.begin(), A.end(), B.begin(), B.end(),

ostream_iterator<const char*>(cout, " "), ltstr());

cout << endl;

cout << "Intersection: ";

set_intersection(A.begin(), A.end(), B.begin(), B.end(),

ostream_iterator<const char*>(cout, " "), ltstr());

cout << endl;

set_difference(A.begin(), A.end(), B.begin(), B.end(),

inserter(C, C.begin()), ltstr());

cout << "Set C (difference of A and B): ";

copy(C.begin(), C.end(), ostream_iterator <const char*>(cout, " "));

cout << endl;

}

39

STL - Map

map associa objetos do tipo “key” a objetos do tipo “data”. ◦ Nenhum par de elementos possui a mesma chave.

◦ Percurso é ordenado. ◦ Indicada para implementação de dicionários. ◦ Implementada por uma árvore balanceada de busca (Red Black, Splay).

◦ Busca em O(log n). multimap é a versão que permite

duplicatas.

STL - Map 40

#include <map> #include <string> #include <iostream> using namespace std; typedef map < long, string > mapType; typedef mapType::value_type ValuePair; int main() { mapType Map; Map[836361136] = "Andrew"; Map[274635328] = "Berni"; Map[974635328] = "Ulisses"; Map[277735328] = "Paulo"; Map[277825328] = "Pedro"; Map[266735328] = "Peter"; Map[275734328] = "Paula"; Map[275839328] = "Paulos"; Map.insert(ValuePair(260736622, "John")); Map.insert(ValuePair(720002287, "Karen")); Map.insert(ValuePair(138373498, "Thomas")); Map.insert(ValuePair(135353630, "William")); // insertion of Xaviera is not executed, because // the key already exists. Map.insert(ValuePair(720002287, "Xaviera")); mapType Map2 ( Map.begin(), Map.end() ); cout << "equality operator " << (Map2 == Map) << endl;

STL - Map 41

cout << "Output:\n";

Map.erase ( 720002287 );

Map2.swap ( Map );

mapType::const_reverse_iterator iter = Map.rbegin();

while( iter != (mapType::const_reverse_iterator)Map.rend() ) {

cout << (*iter).first << ':'

<< (*iter).second

<< endl;

++iter;

}

cout << "Output of the name after entering the number\n"

<< "Number: ";

long Number;

cin >> Number;

mapType::const_iterator it = Map.find(Number);

if(it != Map.end()) {

cout << (*it).second << ' ' // O(1)

<< endl;

} else

cout << "Not found!" << endl;

}

42

class cool

{

private: int serial;

private: string longname;

public: cool() {} // try to comment this out to see the error

public: cool(int i, string s)

{

serial = i;

longname = s;

}

public: int get_serial() { return serial; }

public: string get_name() { return longname; }

public: void set_name(string n) { longname = n; }

};

int main()

{

cool c(5,"Five Young Canibals");

cool d(8,"Eighteen");

map<string,cool> m; // This container stores pair of objects string and cool

// I mean: copies of the objects I give to it

map<string,cool*> m2; // One could store pointers to objects in a container

m["Five"]=c;

m["Eight"]=d;

m["new"] = cool(78,"New object"); // short for m.insert(m.begin,make_pair(const string("Eight"),d));

map<string,cool>::iterator i;

for (i=m.begin(); i!= m.end(); ++i)

cout << (*i).second.get_serial() << " " << (*i).second.get_name() << endl;

// elements in the map are pairs, whose fields are first and second

cout << “One of the elements: " << m["new"].get_name() << endl;

}

43

STL - Hash Map

hash_map associa objetos do tipo “key” a objetos do tipo “data”. ◦ Nenhum par de elementos possui a mesma chave.

◦ Não há ordem de percurso. ◦ Implementada por uma hash table. Há uma função de hash que gera endereços a partir de chaves.

◦ Busca em O(1).

hash_multimap é a versão que permite duplicatas.

44

#include <ext/hash_map> #include <string> #include <iostream> using namespace std; using __gnu_cxx::hash_map; using __gun_cxx::hash; // initial hash table size #define table_size 11 // define your own hash function template <class T> class my_hash: public hash<T> { public: my_hash() {} size_t operator()(const string& p) const { hash<const char*> h; return h(p.c_str()); } }; typedef hash_map<string, string, my_hash<string> > mapType; typedef mapType::value_type ValuePair; int main() { mapType Map ( table_size, my_hash <string>() ); Map["ANDREW"]="Andrew"; Map["BERNI"]="Berni"; Map["JOHN"]="John"; Map.insert(ValuePair("KAREN", "Karen")); Map.insert(ValuePair("THOMAS", "Thomas")); Map["WILLIAM"]="William"; // insertion of Xaviera is not executed, because // the key already exists. Map.insert(ValuePair("BERNI", "Xaviera"));

STL – Hash Map 45

cout << "Output:\n";

mapType::iterator iter = Map.begin();

while(iter != Map.end()) {

cout << (*iter).first << ':'

<< (*iter).second

<< endl;

++iter;

}

cout << "Output of the name after entering the key\n"

<< "Key: ";

char buf[256]; buf[0] = '\0';

fgets ( buf, 256, stdin );

if ( buf[strlen(buf)-1]=='\n' ) buf[strlen(buf)-1] = '\0';

string key ( buf );

iter = Map.find(key);

if(iter != Map.end()) {

cout << (*iter).second << ' '

<< Map[key]

<< endl;

} else

cout << "Not found!" << endl;

}

46

class cool

{

private: int serial;

private: string longname;

public: cool() {} // try to comment this out to see the error

public: cool(int i, string s)

{

serial = i;

longname = s;

}

public: int get_serial() { return serial; }

public: string get_name() { return longname; }

public: void set_name(string n) { longname = n; }

};

int main()

{

char *five="Five";

cool c(5,"Five Young Canibals");

cool d(8,"Eighteen");

hash_map<char*,cool> m;

m[five]=c;

m["Eight"]=d;

// short for m.insert(m.begin,make_pair(const string("Eight"),d));

hash_map<char*,cool>::iterator i;

cool x = m["Five"];

cout << x.get_serial() << " " << x.get_name() << endl;

// elements in the map are pairs, whose fields are first and second

char a;

cout << "Ok?";

cin >> a;

}

47

STL - String

string toma o lugar de um “array of char” (char *) ◦ Não é mais necessário se preocupar com o tamanho do arranjo.

◦ Oferece todas as funções de C pertinentes a strings como membros da classe.

◦ Evita erros relacionados com ponteiros, na chamada de funções que recebem ou retornam strings.

48

#include <string>

#include <iostream>

using namespace std;

int main () {

string str0;

cout << "empty constructor: " << str0 << endl;

cout << "str0 size = " << str0.size() << endl;

string str1("hellow world!");

cout << "const char constructor: " << str1 << endl;

cout << "data = " << str1.data() << endl;

cout << "size = " << str1.size() << endl;

cout << "length = " << str1.length() << endl;

cout << "capacity = " << str1.capacity() << endl;

cout << "max_size = " << str1.max_size() << endl;

cout << "str0 empty = " << str0.empty() << endl;

cout << "str1 empty = " << str1.empty() << endl;

string str2(str1);

cout << “copy constructor: " << str2 << endl;

string str3(str1, 4, 6);

cout << "string&, pos, npos, str3 constructor: "

<< str3 << endl;

string str4("hellow word!", 6);

cout << "char[], npos, str4 constructor: " << str4 << endl;

string str5(12, 'h');

cout << “n, char str5 constructor: " << str5 << endl;

cout << "str5 size = " << str5.size() << endl;

// swap

str5.swap(str1);

cout << "swap str1 and str5" << endl;

cout << "str1 = " << str1 << endl;

cout << "str5 = " << str5 << endl;

}

Exercícios

Crie uma função isPalindromo() que recebe um vetor como parâmetro. Ela deve retornar true se ele é um palíndromo e false caso contrário. ◦ Exemplo: Um vetor contendo 1, 2, 3, 2, 1 é um

palíndromo. E um vetor contendo 1, 4, 3, 2, 1 não é um palíndromo.

Crie uma mapa que associa o nome de uma pessoa a um objeto do tipo Pessoa. Utilize classe map.

Use templates e exceções

49

Referências

Notas de aula – Claudio Esperança e Paulo Cavalcanti (UFRJ)

Notas de aula – Allan Lima (citi/UFPE)

50

Marcação 2ª. Prova e trabalho

51

Próximas aulas

STL

Programação Orientada a Eventos

Programação concorrente (Threads) ◦ (3ª. Prova)

52

Linguagem de Programação I

Carlos Eduardo Batista

Centro de Informática - UFPB [email protected]