Vous êtes sur la page 1sur 39

Aula 06

Vetores
Namespaces
Biblioteca fstream
VETORES
Usando Vectors
A classe vector define um tipo de container provido pela STL.
Ele atende a descrio geral de um array dinmico - uma array
que pode crescer e diminuir de tamanho conforme
necessrio.
Alm disso, vetores definem funes membro para manipular
seus elementos.
Essa matriz pode precisar ser realocada para aumentar de
tamanho quando novos elementos so inseridos, o que implica
alocar uma nova matriz e mover todos os elementos para ela.
Esta uma tarefa relativamente dispendiosa em termos de tempo
de processamento e, portanto, os vetores no realocam todas as
vezes que um elemento adicionado ao continer.
#include <iostream>
#include <vector>
#include <string>

Usando vetores
using namespace std;

Existem algumas formas de se int main()


inicializar um vetor, Veja: {
vector<string> minhasCoisas(10,"aux"); // vetor auxiliar

[1] Essa linha declara um vetor de vector<string> inventario1(10); // [1] 1 Forma


strings que tem seu tamanha vector<string> inventario2(10,"nada"); // [2] 2 Forma
definido inicialmente em 10. vector<string> inventario3(minhasCoisas); // [3] 3 Forma
[2] Essa linha declara um vetor de
tamanho inicial 10. Depois, inicializa
todos os elementos do vetor para o for(unsigned int i =0; i < inventario1.size(); ++i)
mesmo valor especificado no segundo {
parmetro. cout << inventario1[i] << endl;
cout << inventario2[i] << endl;
[3] Essa linha declara um vetor e
cout << inventario3[i] << endl << endl;
inicializa seus elementos com o
contedo de um outro vetor.

return 0;
}
Output do programa
Note que o vetor inventario1 foi inicializado com 10 espaos vxios,
o vetor inventrio2 foi inicializado com 10 strings nada e o
vetor inventrio3 foi inicializado como uma cpia do vetor
minhasCoisas.
Vetores x Listas

Diferente das listas, h o operador [] definido para


vetores;
Utilizao mais intuitiva;
Vetores so melhores para quando se adicionam e retiram
elementos no final do container;
Cada elemento requer somente espao para o elemento
em si;
Pode-se facilmente conseguir a array interna do vetor.
Vector x Array
Vetores tem algumas vantagens sobre arrays:
Vetores podem crescer conforme o necessrio enquanto arrays no
podem;
Isso significa que voc precisar recriar arrays para inicializ-los com
tamanhos maiores conforme a necessidade.
Vetores podem ser usados com os algoritmos da Standard Template
Library enquanto arrays no;
Isso significa que usando vectors voc pode usar funcionalidades
complexas j existentes na STL como por exemplo algoritmos de
ordenao e pesquisa. Se voc usar arrays voc ter que escrever
suas prprias funcionalidades.
Vector x Array
Porm, nem tudo so flores para os usurios de vectors;
Existem algumas desvantagens na comparao com os
arrays, elas incluem:
Vectors requerem um pouco mais de memria extra como
sobrecarga;
Isso significa que em comparao com os arrays, os vetores consomem
mais memria em troca da capacidade de gerenciar o armazenamento e
crescer dinamicamente de forma eficiente.
H um custo em performance envolvido com o crescimento de vetores em
um programa.
#include <iostream>
Usando vetores #include <locale.h>
#include <vector> // [1]
[1] Nessa linha h instrues para o
using namespace std; // [2]
pr-processador incluir o arquivo que
contm as definies de vetores;
int main()
[2] Todos os componentes da STL
{
vivem no namespace std, assim usando
setlocale(LC_ALL,"Portuguese");
essa linha podemos nos referir a vector
vector <string> inventario; // [3]
sem a necessidade do operador std::;
inventario.push_back("espada"); // [4]
[3] A declarao de um vector dessa inventario.push_back("armadura");
forma. Usa-se a palavra chave vector
inventario.push_back("escudo");
seguida pelo tipo das variveis que iro cout << "Seu inventrio tem: ";
ser contidas no vetor <tipo> e,
cout << inventario.size(); // [5]
finalmente, o seu identificador;
cout << " itens" << endl;
[4] Aqui foi utilizada a funo membro cout << "Voc trocou sua espado ";
push_back(adiciona_isso), essa cout << "por um machado\n";
funo adiciona um novo elemento no inventario[0] = "Machado"; // [6]
final do vetor;
[5] - Aqui foi utilizada a funo membro cout << "Seus itens:\n";
size() essa funo retorna o tamanho for( int i = 0; i < inventario.size(); ++i)
do vetor; {
[6] Aqui foi utilizao o operador cout << "\t" << inventario[i] << endl;
de subscrio para atribuir um novo }
valor a um elemento j existente; return 0;
}
Output do programa
Note que o lao for uma boa maneira de apresentar os elementos de um
vector.
Usando vetores
#include <iostream>
#include <vector>
[1] - Apesar de que vectors so
dinmicos, voc no pode incrementar #include <string>
um vetor apenas utilizando
operador de subscrio.
Assim quando trabalhar com vectors using namespace std;
voc deve ter cuidado com o acesso
de elementos em posies no
existentes. Isso pode potencialmente int main()
ter resultados desastrosos. {
O presente cdigo muda alguma parte
desconhecida da memria do seu
vector<string> inventario; // Cria um vector
computador e pode fazer o programa inventario[0] = "espada"; // [1]
fechar abruptamente.
inventario[1] = escudo";
Para adicionar um novo elemento
sempre melhor utilizar a funo return 0;
membro push_back().
}
Output do programa
Note que o programa retornou -1073741819. E no 0. Isso significa que algo
errado aconteceu com seu programa.
Quando usar cada
container?

Muitos outros containers esto


definidos no C++;
Cada um tem suas vantagens e
desvantagens;
O fluxograma ao lado pode te
ajudar a escolher o mais
adequado para a sua aplicao.
NAMESPACES
Introduo
Se, em um mesmo escopo, declaramos entidades com o
mesmo nome, temos um conflito de nomes;
Em muitos casos, no entanto, queremos ter mais de uma
verso da mesma entidade;
Sem namespaces, somos obrigados a dar nomes diferentes a
cada verso da mesma constante, funo, classe...
Com namespaces, podemos ter entidades com o mesmo
nome em um mesmo escopo, desde que elas faam parte de
namespaces distintos;
Mais do que isso, podemos agrupar entidades de mesma
natureza (como constantes, por exemplo), em um mesmo
namespace.
Conflito de nomes
Os cdigos abaixo ilustram um conflito de nomes da varivel
valor_produto, que foi declarada em dois momentos diferentes. Dupla declarao da
varivel valor_produto
#include <iostream>

double valor_produto(10); // Valor em dolares


double valor_produto(31.60); // Valor em reais

int main ()
{
/*
Como nao adicionamos:
using namespace std
Devemos escrever std::cout e std::endl
*/
std::cout<< valor_produto <<std::endl;

return 0;
}
Conflito de nomes

Erro ao tentar compilar o cdigo do slide anterior:


O Namespace

Apenas uma entidade pode existir com um dado nome


em um dado escopo.
Isto raramente um problema para nomes locais, j que os
blocos de instrues tendem a ser relativamente curtos e os
nomes tendem a ter propsitos particulares dentro deles;
Porm, variveis no-locais (como as importadas de
bibliotecas) do mais possibilidades coliso de nomes.
Namespaces nos permitem agrupar entidades nomeadas
que de outro modo teriam um escopo global (no-local) em
um escopo mais limitado, dando a essas entidades um
escopo de namespace.
O Namespace
A sintaxe de declarao de um namespace a seguinte:
namespace identificador
{
entidades
}

Onde o identificador qualquer identificador vlido e entidades o


conjunto de variveis, tipos e funes inclusas dentro do namespace. Por
exemplo:
namespace myNamespace
{
int a, b;
}

Neste caso, as variveis a e b so variveis normais declaradas dentro


do namespace chamado myNamespace. Essas variveis podem ser
acessadas no interior de seu namespace normalmente pelos seus
identificadores (a ou b). Mas se acessadas por fora do namespace
myNamespace, elas devem ser usadas com o operador de escopo ::.
Os cdigos abaixo mostram a varivel um_numero declarada em
O Namespace dois namespaces diferentes, a fim de evitar um conflito de nomes.
#include <iostream>

namespace first O operador de escopo ::


{
int um_numero = 5; tem precedncia sobre a
} palavra chave using.
namespace second
{
int um_numero = 10;
}

int main ()
{
{
using namespace first;
std::cout<<second::um_numero<<std::endl; //deve imprimir o valor 10
std::cout << um_numero << std::endl; // deve imprimir o valor 5
} O using pode introduzir
{ somente uma funo ou
using first::um_numero;
std::cout<<um_numero<<std::endl; //deve imprimir o valor 5 varivel do namespace.
}

std::cout<<second::um_numero <<std::endl; //deve imprimir o valor 10

return 0;
}
Cdigo do slide anterior
A varivel um_numero no teve problemas de conflito de nomes.
O namespace std

Todas as entidades (variveis, tipo, constantes e


funes) da biblioteca padro do C++ esto declaradas
dentro do namespace std.
Assim bem comum aparecer a linha de cdigo: using
namespace std;
Sejam os elementos do namespace std introduzidos com a
keyword using ou totalmente qualificados com o operador de
escopo, isso no muda o comportamento ou a eficincia
do programa.
apenas uma questo de preferncia, embora para projetos
que misturem bibliotecas, a qualificao total dos
elementos tende a ser mais utilizada.
BIBLIOTECA fstream
Introduo

Uma stream alguma estrutura de programao que


permite a transferncia de um nmero de bytes;
J estudamos as streams de input e output via console,
presentes na biblioteca iostream;
Ainda assim, podemos estar interessados em ler e escrever
em arquivos de texto, por exemplo;
Nesse caso, usamos a biblioteca fstream e, mais
especificamente, o ofstream e o ifstream.
Classes para escrita e leitura em arquivos

O C++ concede as seguintes classes para a escrita/leitura de


stream em arquivos:

fstream -> Classe para leitura e escrita em arquivos;

ifstream -> Classe para leitura em arquivos;

ofstream -> Classe para escrita em arquivos;


A funo membro Open()
A primeira operao geralmente realizada em um objeto de uma dessas
classes associ-la a um arquivo real.
Este procedimento conhecido como abrir um arquivo.
Um arquivo aberto representado dentro de um programa por um fluxo
(ou seja, um objeto de uma dessas classes) e qualquer operao de
entrada ou sada executada neste objeto de fluxo ser aplicada ao
arquivo fsico associado.
Para abrir um arquivo com um objeto de fluxo, usamos sua funo
membro open():

open (Nome_do_arquivo, Modo_de_abertura);

Representa o modo como o arquivo


String que representa o nome do vai ser aberto.
arquivo.
Modo Significado
ios::in Permite o input (operaes de leitura)
de um fluxo em um arquivo.

ios::out Permite o output (operaes de


escrita) em um fluxo de arquivo.

ios::binary Permite a abertura no modo binrio.


ios::ate Define a posio inicial no final do
arquivo.
ios::app Todas as operaes de sada so
realizadas no final do arquivo, anexa ao
contedo atual do arquivo.

ios::trunc O contedo anterior ser excludo e


substitudo pelo novo.
Todas esses modos podem ser combinadas usando o operador
OU (|).
Por exemplo, se quisermos abrir o arquivo arquivo.bin no modo
binrio para adicionar dados:

ofstream meuArqui;
meuArqui.open(arquivo.bin", ios::out | ios::app | ios::binary);

Cada uma das funes do membro open() nas classes ofstream,


ifstream e fstream tem um modo padro que usado se o
arquivo for aberto sem um segundo argumento:
fstream -> ios::in | ios::out;
ifstream -> ios::in;
ofstream -> ios::out;
Operao de escrita em arquivos
As operaes de escrita em arquivos de texto so realizadas da
mesma maneira que operamos com cout:
// Escrita em um arquivo de texto
#include <iostream> //cout, cin, etc...
#include <fstream> //fstream, ifstream, ofstream
using namespace std;

int main () {
ofstream meuArquivo ("examplo.txt");
if (meuArquivo.is_open())
{
meuArquivo << "Isso uma linha.\n";
meuArquivo << "Essa outra linha.\n";
meuArquivo.close();
}
else cout << "No foi possvel abrir o arquivo";
return 0;
}
Operao de leitura em arquivos
As operaes de leitura em arquivos de texto::
// Leitura de um arquivo de texto
#include <iostream> //cout, cin, etc...
#include <fstream> //fstream, ifstream, ofstream
#include <string> //strings
using namespace std;

int main () {
string linha;
ifstream meuArquivo ("examplo.txt");
if (meuArquivo.is_open())
{
while ( getline (meuArquivo,linha) )
{
cout << linha << '\n';
}
meuArquivo.close();
}
else cout << "No foi possvel abrir o arquivo";
return 0;
}
Exerccio 1
Crie dois namespaces que contenham uma constante do tipo double chamada VEL_LUZ. Essa constante
deve estar em m/s no primeiro namespaco e em mph no segundo namespace. Em seguida faa um
programa que imprima essa constante tanto em m/s quanto em mph utilizando o dois namespaces
diferentes (c = 2.99792 x 108 km/h = 6.70617 x 108).
Exerccio 2
Crie um programa que solicite menes de alunos (SR, II, MI, MM, MS e SS) de uma turma de CPE at
que o usurio pressione ENTER sem inserir nenhum texto. O programa deve tambm checar a validade
das menes inseridas, e solicitar reinsero caso seja fornecido texto que no corresponde a uma
meno. As menes devem ser salvas em um vetor.
Exerccio 3
Modifique o programa do exerccio 2 para que ele imprima todas as menes, uma por linha, em um
arquivo chamado notas.txt. O seu programa deve, tambm, imprimir o ndice de reprovao da
turma (qualquer meno abaixo de MM representa uma reprovao).
Exerccio 4
Faa um programa que leia quantos nmeros houver em um arquivo de texto e mostre a mdia e o
desvio padro dos nmeros na tela. O desvio padro dado por:

Onde xi o i- simo nmero obtido, a media e N o nmero de elementos


Gabarito Exerccio 1
Crie dois namespaces que contenham uma constante do tipo double chamada VEL_LUZ. Essa constante
deve estar em m/s no primeiro namespaco e em mph no segundo namespace. Em seguida faa um
programa que imprima essa constante tanto em m/s quanto em mph utilizando o dois namespaces
diferentes (c = 2.99792 x 108 km/h = 6.70617 x 108).

#include <iostream>

namespace kmh {
const double VEL_LUZ(2.99792e8);
}

namespace mph {
const double VEL_LUZ(6.70617e8);
}

int main(){

std::cout<< "A velocidade da luz e: " << kmh::VEL_LUZ << "km/h" << std::endl;
std::cout<< "A velocidade da luz e: " << mph::VEL_LUZ << "mp
h" << std::endl;

return 0;
}
Gabarito Exerccio 2
Crie um programa que solicite menes de alunos (SR, II, MI, MM, MS e SS) de uma turma de CPE at
que o usurio pressione ENTER sem inserir nenhum texto. O programa deve tambm checar a validade
das menes inseridas, e solicitar reinsero caso seja fornecido texto que no corresponde a uma
meno. As menes devem ser salvas em um vetor.
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

int main(){
// Inicializando vetor com array
string mencao_atual = "";
string init_array[7] = {"SR", "II", "MI", "MM", "MS", "SS", ""};
vector<string> mencoes_validas(init_array, init_array + sizeof(init_array) / sizeof(init_array[0]));
vector<string> mencoes;

do{
cout << "Insira uma mencao: ";
getline(cin,mencao_atual);
while(find(mencoes_validas.begin(),mencoes_validas.end(),mencao_atual) == mencoes_validas.end()){
cout << "Mencao invalida. Insira novamente: ";
getline(cin,mencao_atual);
}
mencoes.push_back(mencao_atual);
}while(mencao_atual != "");

return 0;
}
Gabarito Exerccio 3
Modifique o programa do exerccio 2 para que ele imprima todas as menes, uma por linha, em um
arquivo chamado resultado.txt. O seu programa deve, tambm, imprimir o ndice de reprovao da
turma (qualquer meno abaixo de MM representa uma reprovao).

#include <string>
#include <vector>
#include <algorithm> // Funcao find()
#include <iostream>
#include <fstream>

using namespace std;

int main(){
string mencao_atual = "";
// Inicializando vetor com array
string init_array_1[7] = {"SR", "II", "MI", "MM", "MS", "SS", ""};
vector<string> mencoes_validas(init_array_1, init_array_1 + sizeof(init_array_1) / sizeof(init_array_1[0]));
// Inicializando vetor com array
string init_array_2[7] = {"SR", "II", "MI"};
vector<string> reprovacao(init_array_2, init_array_2 + sizeof(init_array_2) / sizeof(init_array_2[0]));
unsigned int reprovados(0);
vector<string> mencoes;
Gabarito Exerccio 3
Modifique o programa do exerccio 2 para que ele imprima todas as menes, uma por linha, em um
arquivo chamado resultado.txt. O seu programa deve, tambm, imprimir o ndice de reprovao da
turma (qualquer meno abaixo de MM representa uma reprovao).

do{
cout << "Insira uma mencao: ";
getline(cin,mencao_atual);
// Testar se mencao e invalida
while(find(mencoes_validas.begin(),mencoes_validas.end(),mencao_atual) == mencoes_validas.end()){
cout << "Mencao invalida. Insira novamente: ";
getline(cin,mencao_atual);
}
// Caso nao seja uma string vazia:
if(mencao_atual != "") {
mencoes.push_back(mencao_atual); // Armazenar valor
// Testar reprovacao
if(find(reprovacao.begin(),reprovacao.end(),mencao_atual) != reprovacao.end()){
reprovados++;
}
}
}while(mencao_atual != "");
Gabarito Exerccio 3
Modifique o programa do exerccio 2 para que ele imprima todas as menes, uma por linha, em um
arquivo chamado resultado.txt. O seu programa deve, tambm, imprimir o ndice de reprovao da
turma (qualquer meno abaixo de MM representa uma reprovao).

// Escrever em arquivo
ofstream escrita;
escrita.open("resultado.txt");

escrita << "As mencoes sao:\n\n";


for(int k = 0; k < mencoes.size(); k++){
escrita << mencoes[k] << '\n';
}
escrita << "Reprovados: " << reprovados << endl;
escrita << "O indice de reprovacao e: " << (double)reprovados/mencoes.size() << endl;

return 0;
}
Gabarito Exerccio 4
Faa um programa que leia quantos nmeros houver em um arquivo de texto e mostre a mdia e o
desvio padro dos nmeros na tela. O desvio padro dado por:

Onde xi o i- simo nmero obtido, a media e N o nmero de elementos


#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

int main(){
ifstream leitura;
vector<double> numeros;
double media(0),std_dev(0);

// Limpar vetor: mais seguro!


numeros.clear();

leitura.open("numeros_interessantes.txt");
Gabarito Exerccio 4
Faa um programa que leia quantos nmeros houver em um arquivo de texto e mostre a mdia e o
desvio padro dos nmeros na tela. O desvio padro dado por:

Onde xi o i- simo nmero obtido, a media e N o nmero de elementos


// Ler numeros do arquivo
while(!leitura.eof()){
double num;
leitura >> num;
numeros.push_back(num);
}

// Calcular a media
for(int k = 0; k < numeros.size(); k++){
media += numeros[k];
}
media /= numeros.size();

cout << "A media dos numeros e: " << media << endl;
Gabarito Exerccio 4
Faa um programa que leia quantos nmeros houver em um arquivo de texto e mostre a mdia e o
desvio padro dos nmeros na tela. O desvio padro dado por:

Onde xi o i- simo nmero obtido, a media e N o nmero de elementos

// Calcular o desvio padrao


for(int k = 0; k < numeros.size(); k++){
std_dev += pow((numeros[k]-media),2);
}
std_dev = sqrt(std_dev/(numeros.size()-1));

cout << "O desvio padrao e: " << std_dev << endl;

return 0;
}

Vous aimerez peut-être aussi