Posts Tagueados ‘STL’
Coisas simples de se fazer em C++ que alguns ainda complicam #1 – Imprimir valores de contêineres STL
Bom, vou fazer uma série de posts dizendo sobre coisas simples de se fazer em C++ que muitos ainda complicam. A idéia surgiu do post de um colega.
O primeiro post dessa série é sobre como imprimir facilmente todos os valores de um contêiner STL.
Iremos usar para isso, ostream_iterators que fornecem iterators para escrita em streams de saída. ostream_iterator está declarado em .
Vamos ao nosso exemplo:
#include <iostream> //para cout
#include <iterator> //para ostream_iterator
#include <vector>
using namespace std;
int main()
{
vector<int> v(5);
v[0] = 1;
v[1] = 1;
v[2] = 2;
v[3] = 3;
v[4] = 5;
//copia todo o vetor [begin() -> end()) pro cout com um ", " de delimitador
copy(v.begin(), v.end(), ostream_iterator<int>(cout, ", "));
}
Resultado:
1, 1, 2, 3, 5,
A seguir um exemplo mais funcional, um gerador de arquivos CSV. Ao invés de usarmos o ostream_iterator(cout, ","), utilizaremos ostream_iterator(arquivo, ";") que diz que que queremos passar strings para serem escritas em um arquivo de texto com o delimitador ";":
#include <fstream> //para ofstream
#include <iostream> //para cerr
#include <iterator> //para ostream_iterator
#include <vector>
#include <string>
#define DELIMITADOR ";"
using namespace std;
int main()
{
typedef vector< vector<string> > vvs;
vvs csv(3);
//preenchendo
vector<string> v;
v[0] = "'Murilo Adriano'";
v[1] = "'muriloufg(at)gmail(dot)com'";
v[2] = "8888-8888";
v[3] = "'murilo.wordpress.com'";
csv[0] = v;
vector<string> v2(4);
v2[0] = "'Outra Pessoa'";
v2[1] = "'outoemail(at)outrohost(dot)com'";
v2[2] = "9999-9999";
v2[3] = "'website.com'";
csv[1] = v2;
vector<string> v3(4);
v3[0] = "'Foo Bar'";
v3[1] = "'foo(at)bar(dot)com'";
v3[2] = "0000-0000";
v3[3] = "'foobar.com'";
csv[2] = v3;
//tenta abrir o arquivo
ofstream arquivo("planilha.csv");
if (arquivo.is_open()) {
vvs::iterator it;
for (it = csv.begin(); it != csv.end(); it++) {
//escreve os elementos de cada item do vetor no arquivo
copy((*it).begin(), (*it).end(),
ostream_iterator<string>(arquivo, DELIMITADOR));
//quebra uma linha
arquivo << '\n';
}
arquivo.close(); // fecha o arquivo
}
else {
//se não foi possível abrir o arquivo
cerr << "Falha ao abrir o arquivo\n" << endl;
}
}
Após rodar o programa, abra o arquivo gerado no seu software de planilha eletrônica preferido e veja o resultado:
É isso aí pessoal, nos próximos posts exploraremos mais o C++ e STL.
Até a próxima.
Comparação de desempenho: std::vector vs Array
Comparação entre os códigos assembly gerados para operações de indexação básica, dereferenciação eincremento em std::vectors e arrays/ponteiros.
O código assembly foi gerado pelo gcc 4.1.0 chamado com g++ -03 -S em uma máquina x86_64-suse-linux.
#include
struct S
{
int padding;
std::vector v< int >; //nosso vector
int * p; //nosso ponteiro
std::vector< int >::iterator i; //iterador do vector
};
int indexar_ponteiro(S & s) { return s.p[3]; }
// movq 32(%rdi), %rax
// movl 12(%rax), %eax
// ret
int indexar_vector(S & s) { return s.v[3]; }
// movq 8(%rdi), %rax
// movl 12(%rax), %eax
// ret
// Conclusão: Indexar um std::vector é a mesma coisa de indexar um ponteiro.
int deref_ponteiro(S & s) { return *s.p; }
// movq 32(%rdi), %rax
// movl (%rax), %eax
// ret
int deref_iterador(S & s) { return *s.i; }
// movq 40(%rdi), %rax
// movl (%rax), %eax
// ret
// Conclusão: Dereferenciar um std::vector é a mesma coisa de dereferenciar um ponteiro.
void incrementar_ponteiro(S & s) { ++s.p; }
// addq $4, 32(%rdi)
// ret
void incrementar_iterador(S & s) { ++s.i; }
// addq $4, 40(%rdi)
// ret
// Conclusão: Incrementar um iterador de std::vector é a mesma coisa de incrementar um ponteiro.
Ou seja, além das facilidades do std::vector, algumas operações básicas tem o mesmo custo tanto com std::vector quanto um array/ponteiro.
Surpreso?
Vector? Deque? Stack? Map? List? Como escolher o container STL correto?

- C++ STL Containers
