C++ Standard Template Library
Upcoming SlideShare
Loading in...5
×
 

C++ Standard Template Library

on

  • 1,162 views

 

Statistics

Views

Total Views
1,162
Views on SlideShare
1,161
Embed Views
1

Actions

Likes
0
Downloads
11
Comments
0

1 Embed 1

http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

C++ Standard Template Library C++ Standard Template Library Presentation Transcript

  • Introdução à STL (Standard Template Library) Felipe Sampaio, Robson Dornelles, Gerson Geraldo H. Cavalheiro
  • Templates
    • É uma ferramenta da linguagem C++ para a geração de código genérico
    • template<class tipo>
    • tipo soma(tipo a, tipo b) {
    • return a + b;
    • }
    • printf(“%d”, soma<int> (1,2));
    • printf(“%f”, soma<float> (1.4,2.6));
    • O código acima funciona para qualquer tipo que tenha o operador “+” sobrecarregado
  • Templates
    • typedef struct minha_string {
    • char *str;
    • minha_string(char* s) {
    • str = (char*) malloc(sizeof(strlen(s)));
    • strcpy(str,s);
    • }
    • minha_string operator+(minha_string b) {
    • minha_string n(strcat(str,b.str));
    • return n;
    • }
    • }MINHA_STR;
    • int main() {
    • MINHA_STR a(&quot;abc&quot;);
    • MINHA_STR b(&quot;def&quot;);
    • printf(&quot;%s &quot;, soma<MINHA_STR> (a,b).str);
    • return 0;
    • }
  • Afinal, o que é?
    • Parte do ISO Standard C++ Library
    • STL = Standard Template Library
    • A STL implementa várias estruturas de dados, no formato de classes, utilizando templates
    • Assim, é possível guardar qualquer tipo nessas estruturas
    • Documentação oficial:
    • www.sgi.com/tech/stl
  • Por que usar?
    • Redução do tempo de desenvolvimento.
      • Código pronto e depurado.
    • Legibilidade de código
      • Além de utilizar código padrão, o programa desenvolvido fica mais enxuto.
    • Robustez
      • As estruturas de dados de STL crescem automaticamente.
    • Código portável
      • Usa um padrão.
    • Facilita a manutenção
      • As estruturas de dados são, até certo ponto, intercambiáveis
    • É fácil!
  • Componentes básicos
    • Trata-se de uma biblioteca que define:
    • Containers
      • Estruturas de dados
    • Iterators
      • Iteradores para percorrer as estruturas de dados
    • Algoritmos
      • Oferecem serviços (funcões) para as estruturas de dados (busca, ordenação...)
  • Containers “top of mind”
    • map
      • Possui dois campos, uma chave e um valor, ambos campos podem ser de qualquer tipo e de qualquer valor
      • O conteúdo é mantido ordenado
    • vector
      • Semelhante a um vetor em C/C++, mas cresce automáticamente.
    • list
      • Semelhante ao vetor, mas implementada como uma lista encadeada
  • Uso do vector
    • Métodos
      • unsigned int size();
        • Retorna o número de elementos de um vetor
      • push_back(type element);
        • Insere, no fim, um novo elemento
      • bool empty();
        • Retorna true se o vetor esta vazio
      • void clear();
        • Remove todos os elementos do vetor
      • type at(int n);
        • Retorna o elemento que está na posição indicada, fazendo o teste de limites
  • Uso do vector
    • Operadores
      • =
        • Substitui o conteúdo do vetor destino com o conteúdo do vetor informado
      • ==
        • Compara o conteúdo (elemento a elemento) do vetor
      • []
        • Acesso à uma posição do vetor – sem teste de limites!
  • Uso do vector
    • Alocação prévia da área de dados
    • vector<int> v(100);
    • v[80] = 1; // Funciona!
    • v[200]= 1; // Ups...
    • Crescimento automático
    • vector<int> v2;
    • int i;
    • while( std::cin >> I )
    • v.push_back(i);
  • Uso do vector
    • #include <iostream>
    • #include <vector>
    • using namespace std;
    • int main() {
    • int i;
    • vector <int> example;
    • example.push_back(3);
    • example.push_back(10);
    • example.push_back(33);
    • for( i = 0 ; i < example.size() ; i++)
    • cout << example[i] << &quot; &quot;;
    • ...
    • }
  • Uso do vector
    • #include <iostream>
    • #include <vector>
    • using namespace std;
    • int main() {
    • vector <int> example;
    • vector <int> another_vector;
    • another_vector.push_back(10);
    • example.push_back(10);
    • if( example == another_vector )
    • example.push_back(20);
    • for( i = 0 ; i < example.size() ; i++)
    • cout << example[i] << &quot; &quot;;
    • return 0;
    • }
  • Uso de list
    • Métodos
      • unsigned int size();
        • Retorna o número de elementos de um vetor
      • push_back/front(type element);
        • Insere, no fim/início, um novo elemento
      • pop_back/front();
        • Retira o último/primeiro elemento
      • back/front();
        • Retorna o último/primeiro elemento
      • iterator insert(iterator pos, const T& x);
        • Insere um elemento após a posição indicada
      • empty, clear, swap, resize, split, merge, ...
  • Uso de list
    • Operadores
      • =
        • Substitui o conteúdo do vetor destino com o conteúdo do vetor informado
      • ==
        • Compara o conteúdo (elemento a elemento) do vetor
      • <
        • Comparação lexicográfica
  • Uso de list
    • int i;
    • list<int> lst;
    • for( i = 1 ; i <= 5 ; ++i )
    • lst.push_back(i);
    • for( i = 10 ; i > 5 ; ++i )
    • lst.push_front(i);
    • ...
  • Uso de map
    • Estrutura de dados que faz uma associação entre valores de dois tipos de dados distintos
      • Chave
      • Dado
    • Não pode haver dois dados com a mesma chave!
  • Uso de map
    • Métodos
      • size, empty, clear, swap, ...
      • iterator find(const key_type& k)
        • Retorna a posição onde o elemento identificado pela chave se encontra
      • size_type count(const key_type& k)
        • Retorna o número de elementos que possui a chave indicada (que deve ser, no map, 1 ou 0)
  • Uso de map
    • Operadores
      • []
        • Onde é informada a chave
      • =
        • Operação de atribuição
      • ==
        • Compara dois maps
      • <
        • Teste lexicográfico
  • Uso de map
    • long aux;
    • map<long,int> raiz;
    • raiz[4] = 2;
    • raiz[1000000] = 1000;
    • std::cin >> aux;
    • if( root.count(aux) != 0 )
    • std::cout << root[l]
    • else
    • std::cout << &quot;Nao tem raiz perfeita!&quot;;
  • Uso de map #include <map> double bancaSaoJoao( const caipira& caipa ) { map<char*,float,ltstr> preco; char item[20]; double conta = 0.0; price[&quot;carapinha&quot;] = 0.75; preco[&quot;quentao&quot;] = 1.5; preco[&quot;pinhao&quot;] = 1.25; preco[&quot;pipoca&quot;] = 0.75; while( std::cin >> item ) { item = caipa.whatYouWantBaby(); conta += price[item]; } return conta; }
  • Uso de map #include <map> struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; double bancaSaoJoao( const caipira& caipa ) { map<char*,float,ltstr> preco; char item[20]; double conta = 0.0; preco[&quot;carapinha&quot;] = 0.75; ...
  • Uso de map int main() { map<const char*, int, ltstr> months; months[&quot;january&quot;] = 31; months[&quot;february&quot;] = 28; months[&quot;march&quot;] = 31; months[&quot;april&quot;] = 30; months[&quot;may&quot;] = 31; months[&quot;june&quot;] = 30; months[&quot;july&quot;] = 31; months[&quot;august&quot;] = 31; months[&quot;september&quot;] = 30; months[&quot;october&quot;] = 31; months[&quot;november&quot;] = 30; months[&quot;december&quot;] = 31; cout << &quot;june -> &quot; << months[&quot;june&quot;] << endl; map<const char*, int, ltstr>::iterator cur = months.find(&quot;june&quot;); map<const char*, int, ltstr>::iterator prev = cur; map<const char*, int, ltstr>::iterator next = cur; ++next; --prev; cout << &quot;Previous (in alphabetical order) is &quot; << (*prev).first << endl; cout << &quot;Next (in alphabetical order) is &quot; << (*next).first << endl; }
  • Iterators
    • Declaração
      • Identificação do container.
    • list<int> lst;
    • list<int>::iterator li;
    • Acesso ao início da lista:
    • li = lst.begin();
    • Acesso ao fim da lista:
    • li = lst.end();
    • Acesso ao elemento
    • int aux;
    • aux = *li;
  • Iterators
    • Permite “passear” nos containers
    • list<int> lst;
    • list<int>::iterator li;
    • for( li = lst.begin() ;
    • lst != lst.end() ;
    • lst++ )
    • std::cout << *it << std::endl;
    • // também pode:
    • li = lst.begin();
    • *li = 313;
  • Algoritmos
    • Permitem percorrer containters executando operações pré-definidas
    • Existem vários, diversos e variados.
      • Exemplo
    • list<int> lst;
    • vector<int> vet;
    • copy(lst.begin(), lst.end(), vet.begin());
    • copy(lst.begin(), lst.end(),
    • ostream_iterator<int>(cout, &quot;,&quot;));
    • sort(lst.begin(), lst.last() );
  • Criando classes para serem incluidas em containers
    • Obrigatório:
      • Definir o operador de cópia:
    • operator=(const T&)
      • Implementar o construtor default:
    • T()
      • Implementar o construtor de cópia:
    • T(const T&)
    • Caso o container desejado seja ordenado, ex: map<>
      • Deve ser definido o operador “menor-que”:
    • operator<()
      • Alguns tipos primitivos possuem:
        • int, char, string
      • Outros não:
        • char *
  • Exemplo de tipo definido pelo usuário
    • Agenda de nomes
    • struct Nome {
    • char* prenome;
    • char* sobrenome;
    • bool operator<(const Nome& n) {
    • return strcmp(prenome, n.prenome) < 0;
    • }
    • }
    • map<Nome,int> agenda;
  • Cuidados
    • Acesso à posição inválida de vector<> .
    • vector<int> v;
    • v[100] = 1; // Ups!
    • Solução:
      • Utilizar a interface prevista:
        • push_back()
        • reserve()
        • capacity()
      • Pré-alocar no construtor.
  • Cuidados
    • Cuidar para não criar elementos no map<> de forma inadvertida
    • if( toto[&quot;bob&quot;] == 1 ) ...
      • Se bob não existia em toto , agora existe!
    • Evite utilizando count() para verificar se a entrada existe.
    • if( toto.count(&quot;bob&quot;) ) ...
  • Cuidados
    • Utilizar a interface de serviços observando o desempenho:
      • Exemplo:
        • empty() em list<> .
      • Muito lento
    • if( lst.count() == 0 ) { ... }
      • Bem mais rápido
    • if( lst.empty() ) {...}
    • Como saber?
      • Estudando a STL...
  • Cuidados
    • Utilizar um iterador invalidado
    • list<int> lst;
    • list<int>::iterator li;
    • li = lst.begin();
    • lst.erase(li);
    • ++li; // Ups!
    • Utilizar o retorno do erase para avançar
    • li = lst.erase(li); // Ok!
  • Erro de compilação comum!
    • Erro de compilação comum!
    • vector<vector<int>> vet;
    • Falta de espaço!
    • O analisador léxico entende como right-shift.
  • Muitos outros containers
    • set , multiset , multimap
    • queue , priority_queue
    • stack , deque
    • slist , bitset , valarray