Sei sulla pagina 1di 49

ndice

Noes Base: .................................................................................................................... 2


Namespaces:..................................................................................................................... 3
Variveis: .......................................................................................................................... 3
Operadores: ...................................................................................................................... 6
Input / Output: ................................................................................................................. 8
Funes/Procedimentos:................................................................................................ 10
Condies (testes): ......................................................................................................... 12
Ciclos: .............................................................................................................................. 14
#define: ........................................................................................................................... 16
Arrays: ............................................................................................................................. 16
Ponteiros: ....................................................................................................................... 19
Funes 2: ....................................................................................................................... 22
Overloads:....................................................................................................................... 24
Templates: ...................................................................................................................... 25
Visibiliade de variveis: .................................................................................................. 26
Alocao dinmica de memria: .................................................................................... 28
Estruturas: ...................................................................................................................... 29
Outros tipos de dados: ................................................................................................... 31
Namespaces/using: ........................................................................................................ 32
Classes: ........................................................................................................................... 34
Herana:.......................................................................................................................... 38
Polimorfismo: ................................................................................................................. 40
Excees: ........................................................................................................................ 42
Pr-Processador:............................................................................................................. 43
Ficheiros:......................................................................................................................... 45
Cdigos teis: ................................................................................................................. 46
Debug:............................................................................................................................. 47

Isto no foi feito com base cientfica. No assumam que tudo est certo,
isto apenas um conjunto de notas que fiz para ajudar o pessoal a
perceber mais sobre programao.
Noes Base:
C++ baseado em C e por isso tem muitas semelhanas.
O inicio do programa determinado pela funo main() e tambm precisam de
librarias/includes, no entanto estas so diferentes das librarias em C (algumas so as librarias
de C mas com nomes diferentes), para mais informaes visitem
http://www.cplusplus.com/reference/
Librarias ou includes so ficheiros que contm funes, definies, etc. j criadas. Estas so
necessrias para poder usar funes especficas, mas no so todas necessrias. Para adicionar
uma include ao programa a sintaxe : #include <LIBRARIA>. Uma grande diferena das librarias
em C para as C++ que as ltimas contm namespaces que por sua vez contm
mtodos/funes, classes, etc.
O fim de uma instruo tem de ser sempre seguido por um ; . Nem sempre corresponde ao fim
de linha.
Um exemplo de um programa hello world (tudo ser explicado mais frente):
#include <iostream>
/*
Comentrio
*/
//Comentrio
using namespace std;
void main()
{
cout << "Hello World!" << endl;
}

Para inserir comentrios no cdigo h duas formas:


- // : a partir destas 2 barras e apenas nessa linha tudo comentrio
- /* */ : tudo entre /* e */ ir ser comentrio.
Mais a frente ira ser mostrado como mostrar mensagens ao utilizador e pedir dados ao
utilizador.
O cdigo no determinado pelas linhas ou tabulaes, estas so apenas para ter um cdigo
mais organizado e mais fcil de perceber. O cdigo executado pela ordem em que as
instrues aparecem. As instrues esta separadas por ; e agrupadas em blocos de chavetas
( {} ).

Namespaces:
Os namespaces como se fossem uns prefixos das funes. As librarias contm vrios
namespaces que por sua vez contm vrios mtodos/funes e/ou classes. Para aceder a uma
dessas funes tem que se dizer em que namespace est.
Existem duas formas de referenciar aos namespaces, que so o modo explcito ou usando a
declaraes using.
O modo explcito escrito usando o namespace seguido por 2 : e a funo/classe desejada. A
declarao using feito usando using namespace name; antes de ser usada a funo e neste
caso no necessrio usar o prefixo antes da funo. Exemplos:

#include <iostream>
using namespace std; //declarao using
void main()
{
std::cout << "Hello"; //modo explicito
cout << " World!"; //using
}

Nota: Por vezes usando o using os namespaces podem entrar em conflito. Por exemplo dois
namespaces diferentes usam duas funes diferentes mas com o mesmo nome. Neste caso
para diferenciar que funo se quer usar necessrio usar o modo explicito.

Variveis:
O modo de criar variveis e inicializa-las e at os tipos no mudam muito do C.
Variveis so expresses onde so guardados valores e, como o nome indica, podem ser
alterados a qualquer momento.
As variveis podem ser globais (criadas fora de uma funo e podem ser usadas/alteradas em
qualquer funo) ou locais (criadas numa funo e apenas existem dentro delas).

-Tipos e declarao:
Ao declarar (criar) uma varivel tem que se dizer qual o tipo de varivel. Os tipos de variveis
bsicas so as seguintes:
Tipo
Caractere
Inteiro
Real
Real preciso dupla
Booleana
Sequncia de caracteres

Declarao
char
int
float
double
bool
std::string

Um tipo de varivel especial so os vetores ou arrays. Arrays so uma cadeia de valores do


tipo especificado e podem ser usados para cada tipo, embora um array de caracteres
chamado string (ou cadeia de caracteres) e tem uma formatao especfica que s.
A sua sintaxe a seguinte:
TipoVar NomeVar[TamanhoArray];
Sendo TipoVar qualquer tipo de varivel, NomeVar o nome que quiseres dar a varivel e
TamanhoArray o nmero total de clulas (valores) desse array.
Os inteiros ainda podem ter alguns prefixos e alguns tambm se podem misturar:
- unsigned : inteiro sem sinal (apenas positivos)
- signed : inteiro com sinal (predefinio)
- short : inteiro pequeno
- long : inteiro longo
- long long : inteiro longo (pelo menos o mesmo tamanho que long, no quer dizer que seja
maior);
Em respeito a isto uma funo til para saber o tamanho de cada tipo sizeof().
Podem ser declaradas vrias variveis do mesmo tipo separando o nome das variveis por
vrgulas
Librarias podem ter outros tipos de variveis para alm destes. Tambm possvel definir
novos tipos de variveis.
NOTAS: Os nomes das variveis podem conter letras maisculas e minsculas, nmeros e
underscore (_). Porm tem que comear por uma letra. Todos os nomes de variveis so case
sensitive (sensveis a maisculas/minsculas). TM QUE SER DECLARADAS ANTES DE USAR.

-Inicializao:
A inicializao dar um valor a uma varivel. importante inicializar uma varivel antes de a
usar para prevenir erros, sem inicializar todas as variveis vo ter um valor que considerado
lixo.
A inicializao de variveis pode ser feita na declarao, depois da declarao ou pedindo ao
utilizador com a funo scanf.
Para atribuir um valor a uma varivel usa-se um =. Para variveis do tipo char e arrays por
favor ver o captulo referente a arrays.
Uma novidade em relao ao C que h 2 novas maneiras de inicializar uma varivel aquando
da declarao, atravs de parenteses ( () ) e atravs de chavetas ( {} ).

Exemplos:
#include <iostream>
using namespace std;
//varivel global
int x=5; //incializao direta.
int x2(6);
int x3{7};
void main()
{
//variveis locais
int a, y;
a=6; //incializao depois da declarao
cin >> y;
cout << "x = " << x << " x2 = " << x2 << " x3 = " << x3 << " a = " << a
<< " y = " << y << endl;
}

-Deduo de tipo:
Em C++ possvel deduzir um tipo de uma varivel a partir de outra, ou seja, atribuir um tipo
dinamicamente dependendo de outra varivel. Isto necessrio quando queremos que uma
varivel tenha o mesmo tipo que outra, mas no nos possvel saber qual de antemo, tentem
no usar noutros casos porque pode tornar o cdigo mais difcil de ler, mas vossa escolha.
Existem duas formas, que so o tipo auto e a funo decltype().
O auto ir criar um varivel com o tipo igual varivel/constante de inicializao, por isso
necessrio usar a inicializao direta neste caso.
O decltype() necessita de uma varivel de entrada e ir retornar o tipo desta varivel e assim
podendo usar como tipo para outra varivel (para quem no souber nada programao isto
pode parecer chines mas isto ser melhor explicado na parte das funes).
Exemplos:
#include <iostream>
using namespace std;
char foo = 'f';
int bar = 18;
void main()
{
auto bah = foo; //o mesmo que: char bah = foo;
decltype(bar) meh; // o mesmo que: int meh;
meh = 11;
cout << foo << " " << bar << " " << bah << " " << meh << endl;
}

-Strings:
Existe uma grande diferena em relao s strings entre C e C++. Em C++ foi introduzida uma
nova classe1 chamada string que facilita a manipulao de strings, no entanto tambm
possvel usar a cadeia de caracteres como em C.
A classe string necessita das librarias <iostream> e <string>.
Inicializao e declarao feito de igual modo a qualquer outro tipo de variveis, exemplo:
#include <iostream>
#include <string>
using namespace std;
void main()
{
string hai = "Hello World";
string bai("Bai world");
string uhm{"Where's the world?"};
cout << hai << endl << bai << endl << uhm << endl;
}

Operadores:
-Matemticos:
Operadores matemticos so operadores que fazem operaes matemticas.

+ : Soma, faz a soma de 2 valores


- : Subtrao, faz a subtrao de 2 valores
* : Multiplicao, faz a multiplicao de 2 valores
/ : Diviso, faz a diviso entres 2 valores
% : Resto da diviso inteira, devolve o valor do resto da diviso entre 2 inteiros
( ) : parenteses, servem a mesma funo que na lgebra. Do prioridade ao que estiver
dentro deles
++ : Incremento (adiciona mais 1 varivel)
-- : decremento (subtrai 1 varivel)

NOTA: o incremento e decremento podem ser feitos de 2 maneiras: ++x ou x++ (sendo x o
nome da varivel). Porm tm diferenas. Para um exemplo pratico: y = ++x; e y = x++; y ir ter
valores diferentes em ambos os casos, isto porque quando o ++ aparece antes da varivel
primeiro incrementada a varivel e depois usada, se for depois da varivel, primeiro
usada e depois incrementada. Os exemplos podiam ser assim escritos: x+=1;y=x; e y=x;x+=1;
respetivamente.
Se for para fazer uma operao com o valor da varivel pode ser usado um = juntamente com
o operador da operao antes do igual. Por exemplo, multiplicar o valor de uma varivel por 2,

Classes so usadas como tipos de variveis para declarar variveis, o que realmente so e contm
explicado mais frente

pode ser feito das seguintes maneiras:


x = x*2;
X *= 2;
NOTA: A diviso pode ser de 2 tipos, inteira ou real. Se for a diviso entre 2 inteiros ir
retornar um inteiro (aproximao por defeito, isto : 2,9 ir dar 2), se um dos valores for um
float ir retornar um float. Para retornar um real da diviso entre 2 inteiros tem que se
converter pelo menos um em float2

-Lgicos:
Operadores de lgica que retornam verdadeiro ou falso (true/false)

&& : E
|| : Ou
! : Negao

-Relacionais:
Operadores de relao entre 2 valores. Retornam verdadeiro ou falso

< : menor, verdade se o da esquerda for menor


> : maior, verdade se o da esquerda for maior
<= : menor ou igual, verdade se o da esquerda for menor ou igual ao da direita
>= : maior ou igual, verdade se o da esquerda for maior ou igual ao da direita
== : igual, verdade se os 2 valores forem iguais
!= : diferente, verdade se os 2 valores forem diferentes

-Operadores em bits
Os operadores em bit fazem operaes em relao aos bits de uma varivel. Como sabem, ou
deviam saber, o computador interpreta tudo a partir de bits (1 e 0) e por isso toda a
informao est determinada em bits e assim sendo possvel fazer operaes sobre eles:

&: e, faz o e lgico em bits de duas variveis (ex.: 10010011 & 00110010 vai retornar
00010010)
|: ou, faz o ou lgico em bits de duas variveis (ex.: 10010011 | 00110010 vai retornar
10110011)
^: xor, faz o ou exclusivo em bits de duas variveis (ex.: 10010011 ^ 00110010 vai
retornar 10100001)
~: no, faz a negao de uma varivel (ex.: 10010011 ir retornar 01101100)
<<: shift left, move os bits para a esquerda o numero de casas escolhido (ex.:
10010011 << 2 vai retornar 1010000100)
>>: shift right, move os bits para a direita o numero de casas escolhido (ex.: 10010011
>> 2 vai retornar 100100)

Ver Casting

-Operadores com classes:


As classes podem estar preparadas para usar um determinado cdigo para quando usado um
operador. Porm nem todas as classes tm esses mtodos implementados, podem ir
perguntar ao vosso fiel amigo Google para procurar informaes acerca das classes que
querem usar.
Um bom exemplo a classe string, em que se pode usar alguns operadores, como por
exemplo:

#include <iostream>
#include <string>
using namespace std;
void main()
{
string hai = "hello";
string world = " world!!";
string oops = "!!";
string conc = hai + world; //iir ficar "hello world!!"
string correct = conc - oops; //nao possivel usar o - na string
bool x = hai < world; // possivel usar os operadores relacionais e
assim facilitar a comparaao de strings
}

Input / Output:
A parte mais importante de um programa o contacto com o utilizador. Para isso preciso
mostrar-lhe mensagens e receber valores dele. A libraria iostream fornece 2 objetos de stream
para esse fim: cin e cout (standard input e standard output respetivamente).
Estes objetos no funcionam como funes, porque so objetos. Para enviar ou receber
informao desses objetos usam-se >> e << respetivamente.

-std::cin
cin o objeto do standard input, ou seja o objeto onde se pode ir buscar a informao
inserida pelo utilizador.
Sintaxe:
cin >> var;
Var a varivel em qual desejamos guardar os valores, pode ser qualquer tipo de varivel
bsica e alguns dos outros tipos, por exemplo std::string (no entanto o cin ir ler apenas uma
palavra no caso de strings, uma palavra uma qualquer cadeia de caracteres at encontrar
uma nova linha ou qualquer espao).
Exemplos:

#include <iostream>
#include <string>
using namespace std;
void main()
{
int a;
char b;
float c;
string word;
cin >> a; //ir tentar ler um inteiro
cin >> b >> c; //ir tentar ler um caractere e um float
cin >> word; //ir tentar ler apenas uma palavra
cout << "a=" << a << "|b=" << b << "|c=" << c << "|word=" << word <<
endl;
}

-std::getline:
Como j foi mostrado, o cin apenas pode ler uma palavra quando se tenta ler uma string. Para
poder ler uma frase e/ou linha preciso usar uma funo que a getline(). Esta recebe 2
variveis de entrada (ou 3 caso necessrio), em que a primeira o objeto para ler e a segunda
a varivel do tipo string para guardar o valor.
Sintaxe:
istream& std::getline(istream& is, string& str, char delim);
istream& std::getline(istream& is, string& str);
No stressem se no perceberem o que a est, tudo ir ser coberto mais tarde, o que
interessa saber foi o que foi dito antes. A varivel is o objeto para leitura, o mais usual seria o
standard input (cin). A varivel str a varivel na qual queremos guardar a string. A varivel
delim um caracter delimitador do fim da string, ou seja, ir ler a linha at encontrar esse
caracter, caso no seja utilizado ir ler a linha at encontrar o caracter de fim de string ou nova
linha: (\0 ou \n).

Exemplos:
#include <iostream>
#include <string>
using namespace std;
void main()
{
int a;
char b;
float c;
string word;
cin >> a; //ir tentar ler um inteiro
cin >> b >> c; //ir tentar ler um caractere e um float
cin >> word; //ir tentar ler apenas uma palavra
cout << "a=" << a << "|b=" << b << "|c=" << c << "|word=" << word <<
endl;
}

Linha de comandos:
Insira uma string:
This is a message. From the man who sold the world.
Insira outra string:
This is a message. From the man who sold the world.
str1:This is a message. From the man who sold the world.
str2:This is a message
Press any key to continue . . .

-std::cout:
cout o objeto do standard output. bastante parecido com o cin, como tambm um objeto
no usada uma funo para l colocar valores, mas sim um operador, neste caso ser o <<.
Para alm de poder usar variveis tambm possvel usar constantes (isto uma constante
< uma constante, porque inserida hardcoded e no varivel :P ).

-std::endl:
Existem 2 formas de inserir uma nova linha em C++. Uma delas a normal em todas linguagens
usando o caracter reservado nova linha da tabela ASCII (\n). A outra e mais usada o objeto
endl. Basta enviar para o cout com o operador << para adicionar uma nova linha.

Funes/Procedimentos:
Funes so bastante parecidas as funes matemticas, recebem valores (ou no) e retornam
(devolvem) um valor ou no.
A diferena entre funes e procedimentos que um procedimento no devolve valor
nenhum. Para facilitar a coisa vou chamar tudo de funes.

-Declarao:
As funes so declaradas de maneira parecida as variveis. Tem que se especificar o tipo de
varivel a retornar, o nome da funo e os parmetros de entrada:

TipoVar NomeFuno(TipoVar NomePar)


Sendo TipoVar o tipo de valores a retornar (se for um procedimento, ou seja, no retorna
nada, ento no tipo escreve-se void).
As funes tm de ser declaradas antes de poderem ser chamadas.
A parte do cdigo que a funo faz tem que estar entre chavetas ( { } ) mesmo que use apenas
uma linha. Ao fechar chavetas no precisa de ;

-Parmetros:
Os Parmetros de entrada podem ser quantos quiserem, para determinar os parmetros da
mesma forma que so declaradas variveis, s que os parmetros so separados por vrgulas e
cada parmetro tem de ter o tipo especificado.
As funes tambm podem ter parmetros de entrada opcionais. Para isso a inicializao do
parmetro feito quando especificado (Ateno: os parmetros opcionais tm que ser os
ltimos).

-Retorno (Devoluo)
Para retornar um valor numa funo usa-se a palavra reservada return.
Ateno: Depois de um return ser chamado j nenhum cdigo da funo ir ser executado.

-Chamada da funo:
Chamar uma simples, apenas tem que se escrever o nome da funo e depois entre
parenteses colocar as variveis ou constantes que serviram como parmetros de entrada
separadas por vrgula. A sintaxe tem que corresponder a definio da funo. Se no tiver
parmetros de entrada, deixa-se em branco entre os parenteses ou escrever void.
Para atribuir o valor retornado por uma funo a uma varivel apenas tem que se igualar (usar
o = ) a varivel funo.
Para usar como parmetro arrays ou saber mais sobre funes vai ao captulo das Funes
Parte 2.
Um pequeno exemplo de como funcionam as funes:
#include <iostream>
int soma(int a, int b=5)
{
return a+b;
}
void main()
{
int sum1, sum2;
sum1 = soma(5);
sum2 = soma(5,10);
}

Condies (testes):
As condies e/ou testes so uma das partes mais importantes da programao. Isto serve
para verificar valores e determinar o que fazer consoante o valor que for.

-ifelse ifelse
Teste para verificao de valores mais usual. Traduzido para portugus seria seseno se
seno.
O if (se) verifica se uma expresso verdadeira, se for faz o cdigo que for definido para ele
executar atravs de chavetas. Se for apenas uma instruo as chavetas sero desnecessrias.
O else if(seno se) e o else(seno) no so necessrios e sero executados se o if falhar. O
else ser chamado se o if e else if (se houver else if) derem falso. Pode conter quantos else if
quanto for necessrio.
A expresso que o if e else if verificam est dentro de parenteses a seguir a palavra. A
expresso pode conter um qualquer conjunto de instrues desde que o valor devolvido seja
um booleano. Por exemplo pode-se misturar operadores lgicos e relacionais.
Exemplo:
if(x < 500)
cout
else if(x <
cout
else
cout

<< "x menor que 500";


1000)
<< "x menor que 1000 e maior ou igual que 500";
<< "x maior ou igual que 1000";

-switch case
O switch permite agarrar o valor de uma expresso e comparar esta com constantes.
Primeiro usa-se switch para ir buscar o valor da expresso e depois abre-se um bloco para ele
(chavetas). Dentro desse bloco vai-se compara essa expresso com constantes atravs do case.
Os case no necessitam de chavetas, mas precisa de um : antes do bloco e sempre preciso
usar um break;3 no fim de cada case, para no executar o cdigo dos seguintes case. Caso
todos os case deem falso ir executar o cdigo do default (semelhante ao else), que
opcional.
Se vrios case forem executar o mesmo cdigo basta no colocar break;

Ver Capitulo Ciclos

Exemplo:
void main()
{
int x=2, y=3, sum;
char op = '-';
switch(op)
{
case '+':
sum = x+y;
break;
case '-':
sum = x-y;
break;
case '/':
sum = x/y;
break;
case '*':
sum = x*y;
break;
}
cout << sum;
}

-Operador Ternrio:
O operador ternrio executado de maneira parecida ao ifelse, porem o que o operador
ternrio faz verificar se uma expresso verdadeira ou falsa e retornar um valor para cada
uma dessas. No serve para verificaes extensas ou com cdigo extenso.
O operador ternrio usa 2 smbolos que so ? e :
A sintaxe a seguinte:
Expresso ? resultado1 : resultado2
Verifica se a Expresso verdadeira, se for devolve o valor do resultado1, se for falso retorna
resultado2.
Exemplo:
void main()
{
int x=2,y;
bool multi = false;
y = multi ? x*2 : x/2; // y = 2/2 = 1
}

Ciclos:
Ciclos so estruturas que repetem um determinado cdigo as vezes que forem definidas, se
forem definidas.

-for:
O ciclo for dos mais usados porque permite fazer a inicializao, verificao e incrementao
numa s linha. Em portugus significa para e ainda em portugus a sintaxe seria algo do
gnero:
para var igual qualquercoisa enquanto expresso incrementa x
A sintaxe em C/C++ a seguinte:
for(var=com; expresso; var += incremento) { }
Como se pode ver o for composto por 3 campos:
1. Inicializao: aqui inicializa-se a varivel(variveis) que necessitem de ser inicializadas
neste ciclo.
2. Verificao: Aqui colocada a expresso que verificada em cada iterao do ciclo,
quando for falsa o ciclo termina.
NOTA: Cuidado com ciclos infinitos
3. Incremento: Aqui determinado o incremento da varivel(variveis) em cada iterao.
Este campo executado no fim de cada iterao antes da verificao.
Nenhum dos campos obrigatrio. Se o ciclo for apenas repetir uma instruo ento no
preciso chavetas, caso contrrio sempre preciso chavetas.
Exemplo: 5=1
void main()
{
int sum = 0;
for(int i=1; i<6; i++)
{ //no necessrio chavetas aqui
sum+=i;
}
cout << "Somatorio = " << sum << endl;
}

-while
Em portugus enquanto, faz a verificao de uma expresso e enquanto for verdadeira
repete a seo de cdigo definida.
Sintaxe:
while(expresso){}
Mais uma vez, se for repetir apenas uma instruo as chavetas no so necessrias.
NOTA: A inicializao das variveis para a expresso tm de ser feitas antes do ciclo e o
incremento desta tem que ser feito dentro da seco do cdigo do ciclo.

Exemplo: 5=1
void main()
{
int sum = 0, i=1;
while(i<6)
sum+=i++;
cout << "Somatorio = " << sum << endl;
}

-dowhile
Em portugus fazenquanto um ciclo como o while apenas com uma diferena: o cdigo
do ciclo sempre executado 1 vez pelo menos, ao contrrio do while e for em que a seco de
repetio pode nunca ser executada caso a expresso seja falsa.
Neste ciclo primeiro executado o cdigo e s depois feita a verificao. bastante usado
para fazer menus em que este tem que ser mostrado pelo menos a primeira vez.
A semelhana do resto, se for apenas executar uma instruo no precisa de chavetas.
Exemplo: 5=1
void main()
{
int sum = 0, i=1;
do
{
sum+=i;
i++;
}
while(i<6);
cout << "Somatorio = " << sum << endl;
}

-For Each;
Os ciclos for ainda contm uma segunda sintaxe para percorrer certos objetos, como por
exemplo arrays. Denominado (pelo menos por mim) foreach pela semelhana com outras
linguagens que em vez de usarem o mesmo ciclo for com 2 sintaxes tm um outro ciclo
diferente denominado foreach. Apenas foi adicionado ao C++ mais tarde, por isso verses mais
antigas no contm este ciclo!
Sintaxe:
for( varit : var)
mais simples de o usar que o for. varit uma varivel do tipo de variveis da var que ir ser a
varivel de cada clula da varivel var. mais simples do que eu fiz parecer bolas var um
array digamos de inteiros, varit tem ento de ser um int, o nome pouco ou nada interessa.
Um exemplo de obter a soma de todos os valores de um array:

int x[] = {2,6,1,4,6,1,7};


int sum=0;
for(int a : x)
sum+=a;
cout << sum;

-Ciclos infinitos:
Ciclos infinitos, como o nome o indica, so ciclos sem fim determinado. So uteis para repetir
uma seco de cdigo sem fim previsto. Para sair dele necessrio usar um break;
muito usual ocorrerem ciclos infinitos por distrao, preciso ter cuidado com a correta
inicializao e incrementao de variveis, especialmente nos ciclos while.
Para criar um ciclo infinito pode-se usar, por exemplo:
for(;;) ou while(1)

-break;
O break uma definio usada para quebrar o cdigo de ciclos e switch case. Assim fazendo
com que um ciclo acabe antes de chegar ao seu fim natural.

-continue;
O que o continue faz continuar o ciclo para a prxima iterao sem acabar o cdigo que falta
da seco. til, especialmente, em ciclos para fazer verificaes em arrays.

#define:
#define uma instruo do pr-processador que pode dar nomes a cdigos. O #define
(sempre em minsculas) define um nome a um valor, instruo ou conjunto de instrues ou
at mesmo expresses.
bastante usado para definir um nome ao tamanho mximo de um array e assim tornando
muito mais fcil alterar o tamanho sem ir procurar e alterar em todo o cdigo, mas alterar
apenas no #define (mas no a nica maneira de o usar).
Exemplo:
#DEFINE MAX_PALAVRA 50
Isto vai sempre, que encontrar no cdigo, a expresso MAX_PALAVRAS pelo valor 50.
Nota: O que o define faz definir uma substituio. Ou seja, quando encontra a expresso
definida ele ir substitui-la no cdigo pela expresso(es) especificadas, por isso funcionam de
maneira diferente de funes e muito til para definir constantes numricas.
VER MACROS!!

Arrays:
J foi explicado mais ou menos o que so arrays. Basicamente so uma cadeia de variveis do
mesmo tipo seguidas.

Os arrays podem ter varias dimenses, podem-se assim formar vetores, matrizes, etc.

-Declarao:
Array unidimensional (vetor):
int x[50];
Array bidimensional (matriz):
int x[4][4];
Array tridimensional:
int x[2][2][2];
Etc.
Para ser mais fcil de perceber pode-se assumir que um array bidimensional um array de
array e o array dimensional um array de matrizes.
Na declarao de arrays o(s) nmero(s) indicam o nmero de clulas (espaos) desse array.
Este nmero tem que ser uma constante e pode usar termos criados com #define

-Cadeia de caracteres (string):


Embora o C++ contenha o std::string, por vezes til usar o velhinho array de caracteres que
bastante usado em C.
char Nome[MAX_NOME];
Ir criar uma string chamada Nome com 50 espaos para caracteres.
As strings so um caso especial de arrays, isto porque se declararmos uma string com 50
clulas apenas podemos ter uma palavra/frase no mximo com 49 caracteres, porque tem que
se reservar sempre uma clula para o caracter \0 que indica o fim da string e por isso o
nmero de caracteres legveis que uma frase numa string pode ter o nmero de clulas -1.
Devido a esta formatao todo o cdigo para trabalhar com strings tem que ser diferente do
resto dos tipos de variveis, a libraria string contm vrias funes para manipular strings,
como copiar, comparar, etc. (para alm das funes para std::string)
Podem usar um array de char sem ser string, por exemplo para guardar alguns caracteres e
nesse caso no preciso usar o \0 nem se usam as funes para strings. Tornam-se arrays
normais como se fosse de int ou float.

-Inicializao:
Para inicializar um array na declarao parecido as variveis, porem tem que se usar
chavetas e separar os valores de cada clula por vrgulas. No necessrio inicializar todas as
clulas, basta apenas algumas, todas as outras iram ter o valor 0 por defeito.
Exemplo:
int x[5] = {1,2,3};
O array x ir ter os valores 1,2,3,0,0 no array.

Caso seja do tipo char inicializado da mesma forma, mas os valores tm de estar entre plicas
().
char nome[5] = {N,o,m,e}; //no string, mas sim um array de char
char nome[] = Kimossab; // uma string, neste caso o \0 adicionado automaticamente
Ao inicializar um array desta forma no preciso indicar o nmero de clulas, por exemplo:
int y[] = {1,2,3};
Neste caso o array y vai ter os valores 1,2,3. Notar que diferente do x!
No caso de arrays bi/tri/whatever dimensionais a inicializao feita da mesma forma, porm
so usadas chavetas e vrgulas para separar as primeiras das outras clulas (da eu antes ter
dito que podia-se chamar de array de array), e s um conjunto que pode no ter um nmero
mximo de clulas.
int mat[][3] = { {1,2,3},{4,5,6}};
O array mat ir criar uma matriz igual a seguinte:
1

(int mat[2][3] = {{1,2,3},{4,5,6}};)


Para se perceber melhor em arrays grandes podem-se usar mais do que uma linha.

-Aceder a clulas:
Para aceder ao valor de uma clula bastante simples, apenas se tem que escrever o nome do
array e entre parenteses retos colocar o ndice da clula que se quer aceder.
NOTA: os ndices dos arrays comeam sempre no 0 e vo at ao nmero de clulas menos 1.
Cada clula funciona da mesma maneira que qualquer varivel do tipo do array.
Quando preciso aceder a varias clulas do array usa-se um ciclo para no estar a usar vrias
linhas de cdigo desnecessariamente.
Dito assim at parece complicado, por isso esto aqui alguns exemplos:
#define MAX_BAR 20
int foo[][3] = {{1,2,3},{4,5,6}};
void main()
{
int bar[MAX_BAR];
for(int i=0; i<MAX_BAR; i++)
bar[i] = i*i;
printf("foo[1][2] = %d * bar[10] = %d = %d\n", foo[1][2],bar[10],
foo[1][2]*bar[10]);
}

Output:
foo[1][2] = 6 * bar[10] = 100 = 600

-Outras consideraes:
Nos arrays nem sempre se vai usar todas as clulas a toda a hora, por isso convm usar uma
varivel com o tamanho do array a parte e usa-la para funes por exemplo.
As vezes queremos inserir ou remover um valor numa determinada posio, para isso
importante compreender que temos que movimentar todas as clulas a frente da que
queremos para a frente ou trs e para isso tem que se usar variveis auxiliares para guardarem
temporariamente um valor.

-Curiosidades:
Os arrays bidimensionais (seja qual for) pode sempre ser criado e representado por um array
unidimensional, chamados por alguns de arrays pseudo-multidimensional.
Exemplo:
int x[2][5]; exatamente o mesmo que int y[2*5]; Notar que 2*5=10 e podia-se usar o 10 ali.
Para ser um pseudo-multidimensional para aceder as clulas faz-se da mesma maneira que um
multidimensional, mas em vez de usar parenteses retos usa-se uma multiplicao, por
exemplo:
usando os arrays criados anteriormente, x[1][4]; exatamente o mesmo que y[1*5+4]; quando
digo iguais no me refiro ao valor mas sim clula a que se referem, vejamos a tabela que esse
array cria:
0
1

0
0
5

1
1
6

2
2
7

3
3
8

4
4
9

A vermelho est a clula a que [1][4] se refere. Que o mesmo que [1*5+4]. A primeira linha
refere-se ao nmero da coluna. A primeira coluna refere-se ao nmero da linha. So 5 colunas
por isso preciso multiplicar o numero da linha a que se quer aceder pelo numero de colunas
e somar o numero da coluna a que se quer aceder.
Parece uma confuso porque , mas com a tabela podem tirar a lgica da batata.
Desemerdem-se.
Nota: C++ contm librarias com classes feitas para facilitar muita coisa, s pesquisar um
bocado, uma delas a classe e libraria Array. No captulo dos Cdigos teis irei falar um pouco
dela.

Ponteiros:
Agora que comea a confuso.
Ponteiros so variveis (dos vrios tipos que existem) em que o valor o endereo de
memria que esta ocupa.
Basicamente num ponteiro no temos o valor da varivel mas sim a sua localizao na
memria. Por isso que se chamam ponteiros (ou apontadores, ou como um ou outro stor diz
ponteros), porque apontam para a memria.

preciso ter cuidado a trabalhar com ponteiros porque estamos a trabalhar com a memria e
no com valores, por isso fcil enganarmo-nos e irmos para endereos que no devemos e
crashar tudo.
Antes que haja confuso (ou para confundir mais) convm eu explicar uma cena. Os ponteiros
podem ser dos mais variados tipos (int, char, float, whatever), mas este tipo apenas indica o
tipo de valores que iram ser guardados na memria, porque na realidade o ponteiro sempre
um inteiro (pode ser hexadecimal ou octal se preferirem) porque ele tem como valor o
endereo!
Explicado mais ou menos isto, vamos para o porque de ponteiros: os ponteiros so usados
para poder alterar valores de variveis dentro de funes. Os parmetros de entrada das
funes so apenas uma cpia da verdadeira varivel para prevenir que esta se altere na
funo. Os ponteiros fazem com que a varivel seja a original.

-Declarao:
Para criar um ponteiro igual a criar uma varivel. A nica diferena que entre o tipo de
varivel e o nome tem que se colocar um asterisco (*).
int *ptrx;

-Inicializao:
Os ponteiros podem ser inicializados com o valor nulptr ou 0, isto indica que o ponteiro
naquele momento no aponta para nenhuma varivel. Lembrem-se tudo tem que ser
inicializado, nem que seja a nullptr ou 0. Em C era NULL, e muitas librarias definem o NULL
como 0 ou nullptr, por isso normal que tambm d.
Tambm se pode dar o endereo de memria de uma varivel diretamente a qualquer altura

Ainda se pode alocar um espao de memria dinamicamente para o ponteiro.4

-Aceder ao endereo de uma varivel:


possvel saber o endereo de memria de uma varivel e atribu-la a um ponteiro tendo
assim 2 varivel que na realidade so a mesma.
bastante fcil, apenas tem-se que usar um e comercial (&) antes do nome da varivel e isto
ir retornar o endereo de memria.

-Aceder ao valor de um ponteiro:


Os ponteiros apontam para um endereo de memria, mas como sabemos o valor que esse
endereo guarda? Simples: usa-se um asterisco (*) antes do nome da varivel e assim obtmse o valor que est nesse espao de memria. de notar que assim age como se fosse uma
varivel normal, portanto pode-se alterar o valor.

Ver Alocao Dinmica de Memria

-Ponteiro de ponteiro:
Os ponteiros ocupam espao na memria, portanto possvel criar ponteiros de ponteiros
assim apontar para a memria que aponta para outra memria, mas no vou sequer
aprofundar isso, deixo isso para vocs experimentarem.

-Ponteiros e arrays:
Como j foi dito os arrays usam vrias partes da memria seguidas (sejam uni, bi, tri, n
dimensionais, sempre tudo seguidinho) e por isso tm vrios endereos.
Os arrays e os ponteiros so bastante parecidos. Os arrays apontam para o primeiro endereo
que usam (o endereo da clula 0) e depois entre parenteses retos determina-se em que clula
se quer ir buscar a informao (a memria dos arrays est seguida). Os ponteiros funcionam
da mesma forma, eles apontam para o primeiro endereo e depois para apontar para os
outros pode-se usar parenteses retos ou somar o nmero de clulas a frente.
Para mostrar que so essencialmente o mesmo:
void main()
{
int v[4] = {0,1,2,3};
int *ptrv = v;
cout << *ptrv << endl;
cout << *(ptrv+2) << endl;
cout << ptrv[2] << endl;
}

Output:
0
2
2

-Ponteiro para void


possvel ter funes que devolvam um tipo qualquer de dados e assim sendo tambm
possvel criar variveis que possam ser de qualquer tipo.
O void * diz que vai ser um ponteiro e sem um tipo especfico definido podem ser receber
qualquer tipo de variveis, tendo assim uma funo/varivel genrica.
Basicamente assim pode-se usar uma varivel para receber qualquer tipo de variveis. Para
derrefrencia-la (saber o seu valor) tem que se especificar o tipo de ponteiro (exemplo: (int *) ).

-Ponteiros para funes:


possvel usar ponteiros para funes como parmetros de entrada de outras funes.
Por exemplo queremos uma funo que possa fazer o mesmo cdigo para vrias outras
funes mas s para uma especifica de cada vez.

Exemplo:
int multiplicacao(int x, int y)
{
return x*y;
}
int soma(int x, int y)
{
return x+y;
}
void calculo(int (*func)(int,int), int a, int b)
{
cout << (*func)(a,b) << endl;
}
void main ()
{
int (*sum)(int,int) = soma; //cria a varivel sum que um ponteiro
para a funo soma
calculo(sum,2,3);
calculo(multiplicacao, 2,3);
}

Neste exemplo criamos a funo calculo que o que faz mostrar o resultado retornado por
uma funo que devolve um int e tem como parmetros de entrada 2 int.

Funes 2:
Depois de perceber como funcionam os ponteiros e vetores vamos complicar as funes.

-Ponteiros como parmetros de entrada:


Os parmetros de entrada so variveis locais que iram receber os valores de outras variveis,
ou seja, estas so cpias das originais, por isso qualquer valor que aqui seja alterado apenas e
s alterado nesta funo, a original mantm-se como estava.
As funes apenas podem retornar 1 varivel! Por isso uma maneira de poder alterar vrios
valores dentro de uma funo usando ponteiros como parmetros de entrada, assim
alteramos a varivel original e no uma cpia.
Como j foi dito, arrays e ponteiros so fundamentalmente semelhantes e por isso ao alterar
um array numa funo ir ser alterado o original.
Exemplo que mistura varias coisas ditas anteriormente:

//adicionar um valor a um array de inteiros de maneira ordenada e devolve a


posio
int addordenado(int *v, int add, int *tam)
{
int i=0, n, aux, aux2;
while(i < *tam && v[i] < add)
i++;
aux = v[i];
(*tam)++; //sem parenteses seria como *(tam++)
for(n=i+1; n<*tam; n++)
{
aux2 = v[n];
v[n] = aux;
aux = aux2;
}
v[i]=add;
return i;
}
void main()
{
int arr[20] = {1,2,4,5}, t=4, pos;
pos = addordenado(arr,3,&t); //adiciona o valor 3 ao array
cout << "Array de tamanho : " << t << endl << "Valor 3 adicionado na
posicao " << pos << endl << endl;
for(int i : arr)
cout << "|" << i << "|";
}

Output:
Array de tamanho: 5
Valor 3 adicionado na posicao: 2.
|1||2||3||4||5|

-Parmetros por referncia:


Para alm dos ponteiros h uma outra forma de passar os valores por referncia. Isto feito
substituindo o * por & na funo, na chamada usar as variveis normais sem adicionar nada.
Para aceder aos valores das variveis de entrada tambm no preciso usar mais nada.
As variveis de entrada por referencia no so uma cpia da varivel real, mas sim no mximo
uma cpia do ponteiro, e assim podem ocupar muito menos espao como por exemplo com
std::string, no entanto os valores tambm podem ser alterados, para prevenir isso pode-se
marcar as variveis como const que previne que os valores sejam alterados, mas isto s til
em certos casos como variveis com classes como tipos ou estruturas. Mas Vou falar disto
mais tarde.
Um exemplo bastante bsico:

using namespace std;


void soma(int &a, int b)
{
a+=b;
}
void main()
{
int x = 25;
cout << x << endl;
soma(x,5);
cout << x << endl;
}

Output:
25
30

-Ponteiros ou referncias?
Escolhe tu. Tenta usar um e outro, v qual o te d mais jeito e pode ter a ver com a situao.
So praticamente o mesmo.

Overloads:
Uma coisa bastante til em C++ o overload. Overload pode ser traduzido como sobrecarga
e comum a todas (que eu conhea) linguagens orientadas a objetos.
Basicamente o que a sobrecarga faz sobrecarregar o nome de uma funo/mtodo com 2
cdigos diferentes e parmetros de entrada diferentes. Simplificando, podes ter 2 funes com
o mesmo nome mas parmetros entrada/sada diferentes.
Porm apenas mudar o parmetro de sada no chega, tens forosamente de mudar os
parmetros de entrada, podes adicionar, remover ou alter-los.
Portanto, isto podes facilitar em muito o uso de parmetros opcionais ou cdigos diferentes
para diferentes parmetros, ou at usar o mesmo cdigo para tipos de variveis diferentes.
Exemplo:
int soma(int a, int b)
{
return a+b;
}
string soma(string a, string b)
{
return a+b;
}
void main()
{
cout << soma(2,5) << endl;
cout << soma("Kimo","ssab") << endl;
}

Output:
7
Kimossab

Templates:
Template usar um cdigo que pode receber/devolver um tipo qualquer de variveis
dependendo da situao. Por exemplo, o exemplo anterior com templates ficaria mais fcil,
porque ambas as funes tm exatamente o mesmo cdigo, apenas os tipos que mudam.
Usando templates criamos funes/mtodos genricos.
Para criar uma funo genrica temos que preceder a declarao da funo com a keyword
template.
Sintaxe:
template <param-temp>
Sendo param-temp o nome dado ao tipo de parmetros da template e a definio da
funo. O param-temp pode ser mais do que um tipo, tm que ser separados por vrgulas,
por exemplo quando queremos criar uma matriz em que pode-se ligar um nmero a uma
string, nessa funo seriam necessrios 2 parmetros de template, pois o int e o string podiam
ser quaisquer valores iguais ou diferentes.
Para os param-temp serem genricos necessrio preceder o nome com a keyword class ou
typename (em template significam exatamente o mesmo).
Ao chamar a funo/mtodo/whatever vai mudar. A seguir ao nome da funo (ou o que for,
digo funo para generalizar) e antes dos parenteses necessrio colocar o tipo de variveis
que queremos usar entre < > .No entanto no sempre necessrio; em casos no ambguos o
compilador descobre automaticamente que tipo , mas nem sempre resulta, no custa nada
usar o < > mas vossemecs que sabeides.
Exemplo igual ao anterior mas desta vez com templates:
template<class T>
T soma(T a, T b)
{
return a+b;
}
void main()
{
cout << soma<int>(2,5) << endl;
cout << soma<string>("Kimo","ssab") << endl;
}

Output:
7
Kimossab

-Parmetros Template com tipo definido:


Como disse atras, para definir um tipo genrico necessrio usar class, mas no sempre
necessrio/preciso usar um tipo genrico. Pode-se usar um tipo especfico e usar esse
parmetro como um parmetro da funo. A grande diferena que isto no pode receber
variveis, apenas pode receber constantes.
Um exemplo seria algo do gnero:
template <class T, int N>

Visibilidade de variveis:
Este captulo pode ser chamado variveis 2

-Visibilidade (scopes):
Anyway, as variveis iram ter diferentes tipos de visibilidades consoante onde so declaradas e
propriedades que lhe so dadas.
Como sabem existem as variveis globais e locais, ambas tm visibilidades diferentes, pois as
globais podem ser vistas em todo o lado daquele ficheiro, enquanto as locais apenas podem
ser vistas naquele bloco em que so criadas.
As variveis podem ter o mesmo nome, desde que sejam declaradas num bloco diferente, por
exemplo podes criar uma varivel local com o mesmo nome que uma varivel global, mas no
podes criar 2 variveis locais no mesmo bloco com o mesmo nome.
NOTA: podes criar blocos de cdigo, cada bloco constitudo por { } e as ariveis locais apenas
existem no bloco em que so criadas e nos blocos que estejam dentro desse bloco. Blocos.
Exemplo:
int x=1;
void main()
{
int x=2;
int y=3;
{
int y=4;
cout << "x = " << x << " y = " << y << endl;
}
cout << "x = " << x << " y = " << y << endl;
}

Output:
x=2y=4
x=2y=3

-static:
A static um especificador que pode ser usado quando criado um objeto. O que acontece
que este objeto alocado no incio do programa e desalocado no incio do programa.
Basicamente a varivel fica esttica (diferente de constante), ou seja, quando criada pela
primeira vez fica com o valor 0 (sempre), quando alterada guarda esse valor at ser chamada
novamente, seja onde for (desde que seja visvel) e ignora quando declarada de novo.
Como alocada memria para esta varivel no incio do programa e s desalocada no fim
esta est sempre no mesmo endereo e sempre a ocupar memria e por isso quando o bloco
onde est inserida termina esta no perde o seu valor. E assim sendo se declararmos uma
static num ciclo for esta apenas criada 1 vez e ignorada todas as outras.
As variveis globais so static por defeito.
Como exemplo um programa que mostra quantas vezes uma funo foi chamada.
int contagem()
{
static int cont; //criada no inicio do programa e ignorada todas as
outras vezes porque j foi criada
return ++cont;
}
void main()
{
for(int i=0; i<1234; i++)
contagem();
cout << contagem() << endl;
}

Output:
1235

-const:
O const mais uma propriedade que se pode dar a objetos. O que o const diz, que o valor
desse objeto ir ser constante, ou seja, uma varivel com o tipo const ter que ser dado um
valor quando declarada e esse valor no poder ser mudado (da maneira convencional, acho
que podes alterar o valor do endereo em que ela est guardada, nunca testei, nem tenciono).
Bastante til quando se usa com ponteiros para prevenir que mudes o endereo ao qual estes
apontam.

Nota que se criares um ponteiro const, no podes alterar o seu valor nem o seu endereo. No
entanto se o valor desse ponteiro for outro ponteiro, o valor desse outro ponteiro pode ser
mudado se no for const (o ponteiro pode ser um array).
struct foo
{
int *bar;
};
void main()
{
foo b; //nao const
b.bar = new int[5]; //inicializaao
const foo *c = &b; //constante
const int k = 5 ; //int constante
c->bar[0] = 5; //ok, est aceder a um ponteiro nao const
c->bar = 2141231; //tentar altear o endereo do ponteiro bar ERRO
c=123121; //tentar altear o endereo do ponteiro c ERRO
k=125; //erro
}

-const e funes:
Na declarao de uma varivel a posio do const no interessa, mas numa funo interessa:
Usado antes do nome da funo (antes ou depois do tipo, indiferente) indica que ir retornar
um const.
Usado depois do nome da funo e antes do bloco de cdigo indica que o bloco const. E no
poder alterar valores no static nem chamar funes cujos blocos no sejam cosnt.
Ver Classes > const e classes.

Alocao dinmica de memria:


Um dos problemas com arrays que eles no so dinmicos, isto tem sempre um nmero
mximo de clulas definido e muitas vezes esse nmero pode ser em demasia ou no chegar.
Com alocao dinmica esses problemas deixam de existir, no desperdiada memria
desnecessariamente e se for preciso mais pode-se alocar.
semelhana de C necessrio usar ponteiros para alocar a memria.
Para fazer a alocao de memoria preciso usar as keywords new para alocar e delete para
desalocar (ou new[] e delete[] para arrays).
Sintaxe:
int *x = new int;
delete x;
int *y = new int[5];
delete[] y;
IMPORTANTE

A memria no infinita e pode nem sempre haver espao e nesse caso a alocao
no feita. Quando falha a alocao lanada a exceo bad_alloc.5
A memria depois de alocada tem que ser desalocada quando j no necessria.
Cada vez que usamos o new usem logo o delete para no se esquecerem!

Para quem no gosta de excees possvel que a memria no seja alocada e no atire
excees ou termine o programa, para isso tem que se usar o objeto (std::nothrow) entre o
new e o tipo de varivel. O que isto faz atribuir o valor nullptr ao ponteiro e no atirar uma
exceo. necessrio a libraria <new>
Exemplo:
using namespace std;
void main()
{
int *matriz = new (nothrow) int[2*3];
if(matriz == nullptr)
return;
for(int i=0; i<2; i++)
for(int n=0; n<3; n++)
matriz[i*3+n] = i*3+n; //aceder como um array ([])
for(int i=0; i<2; i++)
{
for(int n=0; n<3; n++)
cout << *(matriz+i*3+n) << " "; //aceder sem []
cout << endl;
}
delete[] matriz;
}

possvel usar as funes de C, mas no misturem new e malloc, pode dar erros.

Estruturas:
Para alm dos outros tipos de dados que j foram falados existe o tipo struct. As estruturas
podem conter varias variveis de vrios tipos diferentes e assim sendo fcil de guardar vrios
tipos de dados numa s varivel.

-Declarao
A sintaxe simples:
struct NomeStruct
{
declarao_campos;
};
O NomeStruct o nome da estrutura que se quer dar. Dentro do bloco feita a declarao dos
campos (variveis) que iram fazer parte da estrutura. possvel fazer a inicializao destas na
declarao. O ponto e vrgula no fim do bloco necessrio.
5

Ver Excees

-Criao de variveis:
Uma estrutura no uma varivel, mas sim um tipo. Assim sendo primeiro criamos uma
estrutura e depois criamos variveis com essa estrutura, estas podem ser, variveis normais,
ponteiros ou arrays.
Para isso do mesmo modo que a declarao de uma varivel mas substituindo o tipo por
NomeStruct .
Duas variveis com a mesma struct como tipo sero variveis diferentes e portanto os campos
da estrutura iram ter valores e endereos diferentes!
Tambm se podem criar as variveis quando se define a estrutura, pondo o nome das variveis
a frente do } e antes da ;

-Aceder a campos da estrutura.


Para aceder aos valores da estrutura de uma varivel preciso colocar um ponto a seguir ao
nome da varivel e colocar o nome do campo que se quer. Se a varivel for um ponteiro usa-se
uma seta -> (tracinho + >), se usarmos os parenteses retos (array ou ponteiro) ento usa-se
um ponto.
Caso a varivel seja um ponteiro tem que se verificar se este no NULL. Tentando aceder a
um campo de um ponteiro NULL ir crashar o programa.
Exemplo:
Este programa ira criar uma turma de quantos aluno o utilizador desejar.

using namespace std;


#define MAX_NOME 100
#define MAX_ALUNO 25
struct aluno
{
string nome;
int idade;
int numero;
float nota;
};
void AdicionarDadosAluno(aluno *a)
{
if(a == nullptr) // ponteiro nulo
return;
cout << "\nInsira o numero do aluno: ";
cin >> a->numero;
cout << "Insira o nome do aluno: ";
cin >> a->nome;
cout << "Insira a idade do aluno: ";
cin >> a->idade;
cout << "Insira a nota do aluno: ";
cin >> a->nota;
}
void main()
{
aluno turma[MAX_ALUNO];
int tam;
cout << "Insira o numero de alunos: ";
cin >> tam;
for(int i=0; i<tam; i++)
AdicionarDadosAluno(&(turma[i]));
}

Outros tipos de dados:


-Aliases:
H 2 tipos principais de aliases: typedef e using.
O que isto faz criar um novo tipo baseado num j existente. Por exemplo se quiserem criar
um tipo que crie automaticamente um ponteiro de um tipo (chamar int* como pint por
exemplo).
Ambos fazem o mesmo mas usam sintaxes diferentes:
typedef tipo_existente novo_tipo;
using novo_tipo = tipo_existente;

Sendo tipo_existente um tipo de dados j existentes e novo_tipo o nome que queremos dar
ao novo tipo.
Usando a estrutura do exemplo anterior como exemplo:

typedef struct aluno


{
string nome;
int idade;
int numero;
float nota;
}ALUNO;
//OU
using OALUNO = aluno
{
string nome;
int idade;
int numero;
float nota;
};
//variveis
ALUNO turma[MAX_ALUNO];
//OU
OALUNO oturma[MAX_ALUNO];

-Enumeraes:
O enum uma maneira fcil de criar expresses com um valor especfico.
Um exemplo as variveis booleanas. Apenas em verses mais recentes o bool j vem
implementado, mas antes disso para podermos ter o true e false usava-se um enum:
typedef enum {true;false}bool;
A sintaxe praticamente igual s estruturas. Porem os elementos no tm um tipo definido,
so apenas expresses. Se no lhes dermos um valor por predefinio so lhes atribudos os
valores a comear em 0 at ao numero de elementos -1. Se por exemplo quisermos os meses
do ano em nmero a comear em 1 bastava fazer um enum{janeiro =1, fevereiro,maro,
Deste modo o enum comea no numero 1 e vai dar o resto dos valores automaticamente.
Para aceder do mesmo modo que a varivel bool e no com pontos ou setinhas como nas
estruturas.

Namespaces/using:
Um problema com includes e variveis globais ou locais que podem entrar em conflito. As
variveis locais previnem esse problema, mas globais no. As librarias definem muitas funes,
tipos, variveis, etc. de modo global e assim no ser possvel usar variveis/funes/whatever
com o mesmo nome globais (no tenho a certeza se o overload poder prevenir isto, mas
mesmo assim a coliso de nomes pode ser um problema).

Para resolver isso decidiram tornar essas variveis/mtodos locais, para isso define-se um
espao onde eles existem com a keyword namespace. Isto cria um espao com um nome
especfico que aloja variveis/mtodos que podem depois ser usados global ou localmente.
Para criar um namespace usa-se a seguinte sintaxe:
namespace identificador { objetos }
Sendo identificador o nome para o namespace e objetos os vrios objetos que o namespace
ir conter.
Para usar um objeto de um namespace usa-se a seguinte sintaxe:
identificador::objeto;
Sendo o identificador o nome do namespace e objeto o objeto ao qual queremos aceder.

-Using:
Usar os :: sempre que queremos aceder a um objeto de uma namespace pode ser chato, por
isso h uma forma de usar os objetos sem especificar o namespace, usando o using
namespace identificador.
Isto diz que ir usar o namespace identificador quando no for nenhum especificado. Pode-se
usar vrios using namespaces, mas quando houver dois using com 2 namespaces com objetos
com o mesmo nome necessrio especificar qual o namespace que queremos. ( automtico
e tal, mas no sabe o que queres xD)
Exemplo:
namespace foo{
int x=5;
int y=2;
int valor()
{
return x*y;
}
}
namespace bar{
int valor()
{
return 5;
}
}
using namespace std;
using namespace foo;
using namespace bar;
void main()
{
int x =
cout <<
cout <<
cout <<
cout <<
cout <<
}

25;
"x = " << x << endl;
"foo::x = " << foo::x << endl;
"y = " << y << endl;
"foo::valor() = " << foo::valor() << endl;
"bar::valor() = " << bar::valor() << endl;

Output:
x = 25
foo::x = 5
y=2
foo::valor() = 10
bar::valor() = 5

Classes:
Classes so praticamente o mesmo que struct, so declarados e acedidos da mesma maneira.
Embora as class e struct podem conter variveis (dados) e mtodos (funes).
Sintaxe:
class class_nome {
objetos;
};
Onde class_nome o nome dado classe, objetos so os vrios objetos que a classe contm,
podem estes ser variveis ou (declaraes de) funes/mtodos.

-Especificadores de acesso:
Os objetos das classes podem ter vrios tipos de acessibilidade:

private: tipo de objeto privado, ou seja, apenas pode ser acedido por objetos da
prpria classe ou seus amigos.
protected: tipo de dados protegido, ou seja, s pode ser acedido por objetos da
prpria classe, seus amigos e classes derivadas desta.
public: tipo de dados pblicos, ou seja, pode ser acedido onde quer que o objeto seja
visvel.

Por defeito todos os objetos de uma class so private, por defeito todos os objetos de uma
struct so public. Para determinar o tipo de acesso a sintaxe parecida do case, especifica-se
que tipo de acesso se quer seguido de : e todos os objetos seguidos tero esse tipo de acesso,
at ser especificado outro.

-Mtodos:
Usualmente quando se declara uma classe tambm se declara apenas os objetos e no se
adiciona o cdigo que esses mtodos executam. costume usar 2 ficheiros para cada classe,
um ficheiro tipo header (.h) com as declaraes e um ficheiro de cdigo (.cpp) que contm o
cdigo de cada mtodo. Isto porque pode-se conter dezenas de classes cada uma com dezenas
de objetos e mtodos e assim sendo mais fcil de organizar.
Os mtodos que apenas foram declarados numa classe pode apenas ser dado o cdigo a esses
mtodos em qualquer altura (depois de ser declarada a class obvio). Para isso usa-se o nome
da classe como se fosse um namespace e depois dos :: coloca-se o nome da funo e abre-se o
bloco para o seu cdigo.

-Construtores:
Uma funo que existe sempre e sempre chamada quando criada uma class (quer tenha
sido declarada essa funo ou no) e essa funo denominada de construtor.

til para especificar cdigo a ser executado quando uma classe criada, como por exemplo a
inicializao de variveis da classe.
O construtor no tem um tipo, por isso ao declarar no se especifica o tipo. O nome da funo
sempre igual ao nome da class. Os parmetros de entrada por ser o que se quiser.
Graas ao overload pode-se ter mais do que um construtor com parmetros de entrada
diferentes.
H uma maneira mais simples de inicializar as variveis de entrada sem ser pelo bloco de
cdigo, para isso basta colocar o prottipo do construtor depois meter : e iniciar as variveis
usando parentese com o valor e separar as variveis por vrgulas.
Sintaxe:
class foo{
int a;
public:
foo(int x) : a(x) {}
}

-Destrutores:
Para alm dos construtores h os destrutores. O nome desta funo sempre precedida por
um ~ e no tem parmetros de entrada.
bastante til para destruir/desalocar objetos/memria alocada.

Exemplo disto tudo:


class foo
{
//private:
int bar; //privado
public:
foo(); //construtor genrico
foo(int); //construtor com um inteiro
~foo(); //destrutor
//mtodos
int GetBar();
};
foo::foo()
{
cout << "construido" << endl;
bar = 5;
}
foo::foo(int x)
{
cout << "construido" << endl;
bar = x;
}
foo::~foo()
{
cout << "destruido" << endl;
}
int foo::GetBar()
{
return bar;
}

void main()
{
foo k; //cria k
{//abre um novo bloco
foo i(25); //cria i com valor 25
cout << i.GetBar() << endl; //mostra valor 25
}//acaba bloco (destroi i)
cout << k.GetBar() << endl;//mostra k e destroi k
}

-Overload Operadores:
Nas classes possvel fazer overload dos operadores para assim executarem uma funo que
ns queiramos.
A lista dos operadores que se podem fazer overload so:
+ - * / = < > += -= *= /= << >> <<= >>= == != <= >= ++ -- % & ^ ! | ~
&= ^= |= && || %= [] () , ->* -> new delete new[] delete[]

Sintaxe:
tipo_ret operator op (var);

Sendo tipo_ret o tipo de varivel a retornar da funo, op o smbolo(s) do operador desejado e


var a varivel a ser usada com o operador.

-keyword this:
As classes contm uma keyword denominada this que devolve um ponteiro para a prpria
classe. Pode ser usado para saber se uma classe enviada por um parmetro ela prpria, ou
para quem gosta de o usar para mostrar que mesmo a varivel daquela class.

-Objetos static e class:


Como j foi visto cada varivel com uma classe ou struct como tipo ir ter valores diferentes
porque um objeto diferente, no entanto possvel criar uma varivel que ir ter o mesmo
valor em todas as variveis com a mesma class declarando essa varivel como static. til para
fazer um contador de quantos objetos com essa class como tipo h.

-const e class:
Variveis declaradas com um const class como tipo no podem chamar funes que no
tenham o seu bloco como const. Isto porque esta varivel ir ser apenas como read only, e no
poder alterar os seus valores, apenas os construtores/destrutores que podem alterar.
importante isto porque usual usarem const quando enviam objetos por parmetros e se
no tiver funes com blocos como const no ir acede-las.

-Templates e class:
J foi falado em templates em funes, mas tambm podem ser usadas em classes do mesmo
modo. fixe para criar por exemplo uma classe lista diferente do list e vector, como em C mas
mais fcil.
H uma coisa diferente. possvel especializar a class consoante o tipo de varivel passado
pelo template. Imaginemos que temos uma classe para praticamente todo o tipo de variveis,
mas queremos que seja diferente caso seja do tipo char. Podemos criar a classe com o
template normalmente e depois para o do char fazer o seguinte:
template<class T>
class myclass {.};
template<>
class myclass<char>{};

Pequeno exemplo:
template <class T>
class Kimochi
{
T num;
public:
Kimochi() : num(5) {}
Kimochi(int a) : num(a) {}
T operator + (T x)
{
return num+x;
}
};
template <>
class Kimochi<char>
{
char num;
public:
Kimochi() : num('a') { }
Kimochi(char a) : num(a) { }
string operator + (char x)
{
return string(1,num)+string(1,x);
}
};
void main()
{
Kimochi<int> K(5);
Kimochi<char> C('K');
cout << K + 10 << endl;
cout << C + 'i' << endl;
}

Herana:
-friend (Amigos):
Como foi falado h bocado membros de uma class como private apenas pode ser acedidos por
ela prpria e amigos.
possvel criar uma funo que no pertena class mas que possa aceder s variveis private
para isso temos que a definir como friend na class.
Sintaxe:
friend tipo_ret nome(var);
A funo com o nome nome fica definida como amiga da classe onde foi colocado a linha
anterior. Tipo_ret o tipo de retorno da funo e var as variveis de entrada. Uma varivel
com a classe como tipo criada ou entrada por parmetros nessa funo poder aceder a
atributos private.
Tambm possvel adicionar classes amigas. Basta usar a keyword friend seguido do nome
da classe que quer que seja amiga desta.
Exemplo:

class Kimochi
{
int Kim;
string Ochi;
public:
Kimochi(int a, string b) : Kim(a), Ochi(b) {}
friend Kimochi Cop(Kimochi &co);
friend void Print(Kimochi &co);
};
Kimochi Cop(Kimochi &co)
{
return Kimochi(co.Kim,co.Ochi);
}
//OK:
void Print(Kimochi &co)
{
cout << co.Kim << " " << co.Ochi << endl;
}
//ERRO:
/*void Print2(Kimochi &co)
{
cout << co.Kim << " " << co.Ochi << endl;
}*/
void main()
{
Kimochi K1(5,"Kimossab");
Kimochi K2 = Cop(K1);
Print(K1);
}

-Herana entre classes:


As classes podem ser extenses de outras classes atravs da herana. Uma analogia pensar
numa classe como uma base, com vrias peas, e depois cria-se uma outra classe baseada na
base que adiciona ainda outras peas. Portanto a base contm objetos comuns a vrias outras
e as outras contm os objetos da base mais os especficos dessa classe.
Para marcar a herana na declarao da classe. Depois de escrever o nome da classe metese: seguido de public e o nome da classe base:
class nome_c : public nome_base
O public pode mudar. Isto indica o nvel de acesso aos objetos da classe base atravs da classe
nome_c. Por exemplo se se usa-se protected em vez de public por fora das classes, no se
podia aceder aos objetos public do classe base atravs do nome_c. Lembrar que public o
nvel menos seguro. Tipo, imaginemos que a nome_base tem uma funo public chamada
print() e que estamos fora da funo:

usando herana public:


o nome_base::print() > funciona
o nome_c::print() > funciona
usando herana private ou protected:
o nome_base::print() > funciona
o nome_c::print() > no funciona

Na herana o que no partilhado apenas, o construtor/destrutor, objetos private, os


amigos e operadores.
Tambm possvel herdar mais do que uma classe, basta separ-las por vrgulas.
Exemplos:
class Print
{
public:
static void
{
cout
}
static void
{
cout
}
};

print(string s, int a, int b)


<< s << " " << a << " " << b << endl;
print(int a, int b)
<< a << " " << b << endl;

class Poligono
{
public:
int comp,larg;
Poligono(int a, int b) : comp(a), larg(b) {}
};
class Retangulo : protected Poligono, public Print
{
string nome;
public:
Retangulo(string n, int w, int h) : nome(n),Poligono(w,h) {}
int Area() { return comp*larg; }
void show() { print(nome,comp,larg); }
};
void main()
{
Retangulo Ret("Kimossab",1,2);
//Ret.print(Ret.comp,Ret.larg); //inacessivel graas ao protected
Poligono
Ret.show();
}

Output:
Kimossab 1 2

Polimorfismo:
-Ponteiro para a classe base:
Pegando no exemplo anterior mais fcil de explicar, mas vamos assumir que a class
Retangulo tem herana public Poligono em vez de protected.
Podemos ir buscar o ponteiro para uma das classes base da classe Retangulo. Para fazer isto
preciso que seja public, da a assuno anterior.

Sintaxe:
Poligono *p = &Ret;
//OU
Print *p = &Ret;
Isto ir dar resultados diferentes, o primeiro ir dar um ponteiro para o Poligono de Ret e o
segundo um ponteiro para o Print de Ret. Como apontam para a base apenas se pode aceder a
elementos dessa classe base e no da Retangulo neste caso.

-Objetos virtual:
possvel criar funes na classe base que possam ser alteradas na funo que a herda e
deixar que estas sejam chamadas. Por exemplo a funo rea, podia-se cria-la na classe base
como virtual e assim quando se cria-se a classe Triangulo ter uma funo igual mas que usa um
cdigo diferente.
Porque usar o virtual e no apenas criar uma nova funo em cada um. Bom, como a funo
Area() j existe (imaginemos que existe, meus irmos) na classe Poligono como virtual, quando
a chamarmos atravs de um ponteiro para o polgono que se obteu do mtodo referido
anteriormente ela ir executar o cdigo especificado pela classe que a herdou. Sem o virtual
isto no possvel. E se usarmos o virtual no necessrio reescrevermos a funo na outra
classe.

-Classes base abstratas:


Classes abstratas so classes base que no podem criar objetos e que as funes virtuais no
esto totalmente definidas:
virtual int Area() = 0;
Isto um mtodo abstrato puro e todas as classes que tenham pelo menos um mtodo assim
so classes abstratas e por isso no podem definir objetos com esse tipo, porque no tm
construtor. Porm podem usar os ponteiros de igual modo, at possvel criar um novo
retngulo diretamente para um ponteiro para polgono.

Exemplo:
//classe abstrata pura
class Poligono
{
protected:
int comp,larg;
public:
void set(int c, int l)//j nao se pode usar Poligono(w,h) logo
precisa desta funo
{
comp=c;
larg=l;
}
virtual int Area()=0; //puramente virtual
};
class Retangulo : public Poligono
{
public:
Retangulo(int w, int h) { set(w,h); } //j nao se pode usar
Poligono(w,h)
int Area() { return larg*comp; } //obrigatorio
};
void main()
{
Retangulo Ret(1,2); //novo retangulo
Poligono *p = &Ret; //ponteiro para o poligono do novo ret
cout << Ret.Area() << endl;
cout << p->Area() << endl; //do igual
Poligono *p2 = new Retangulo(3,4); //novo ponteiro diretamente
cout << p2->Area() << endl;
delete p2;
}

Output:
2
2
12

Excees:
Durante a criao de um programa h sempre problemas, seja por esquecimento ou
problemas de outros, mas h sempre excees (erros). Muitas vezes eles podem fazer o
programa crashar, para prevenir isso h a hiptese de apanhar os erros, saber o que se
passou e tentar corrigir ou reajustar a situao.
Para isso h 34 keywords importantes : try, catch e throw.
Um bloco que queiramos tentar executar tem que ser precedido por try. No fim desse bloco
sempre preciso ou um bloco precedido por pelo menos um catch.
Se ocorrer um erro dentro do bloco try uma exceo pode ser levantada (se a funo que o
provocou estiver preparada para o lanar) e apanhada pelo bloco(s) catch.

Para lanar uma exceo usado a keyword throw. O throw seguido por um parmetro que
pode ser de qualquer tipo. O throw no precisa de estar dentro de um bloco try, por exemplo
pode ser colocado numa funo e o bloco try estar no local onde a funo foi chamada.
O catch tem um parmetro de entrada e pode ter overloads. Este parmetro de entrada
recebido pelo throw.
O namespace std contm algumas excees standard que esto na libraria exception.
Exemplos:
int teste()
{
throw 1; // ir mostrar 1
throw 'a'; //ir mostrar a
throw exception("erro"); //ir mostrar erro
}

void main()
{
try
{
teste();
}
catch(int e)
{
cout << e << endl;
}
catch(char c)
{
cout << c << endl;
}
catch(exception &e)
{
cout << e.what() << endl;
}
}

Pr-Processador:
Diretivas de pr-processador so diretivas que so lidas pelo processador que passa pelo
cdigo antes de o compilar.
As Macros so pores de cdigo que so substitudas pelo pr-processador antes de o
compilador passar pelo cdigo.
O #define que j foi falado usado para criar macros, pode ser usado em qualquer linha e
indica ao processador que a partir daquela linha uma expresso que l colocarmos ir ser
substituda por outra expresso que l colocarmos.
Normalmente os macros so conhecidos no pela definio de constantes como foi falado mas
sim de funes.
Exemplo:
#define Multi(x,y) (x*y)

A primeira parte do define funciona como uma funo, procura a palavra Multi que tenha 2
parmetros entre parenteses (independentemente do tipo) e depois vai substituir toda essa
expresso pela 2 parte do define, por exemplo:
int x = Multi(2,3); // o que o pr processador faz isto: int x=(2*3)
Neste caso esta funo no retorna um valor mas substituda pelo que est a frente.
Para poder escrever em mais do que uma linha, no fim da linha coloca-se \.
possvel remover uma definio atravs do #undef seguido pelo macro.

-#
Num macro o smbolo # um smbolo que diz que coloca um dos parmetros entre aspas.
Deste modo convertendo uma expresso no seu equivalente em string.
Exemplo:
#define getstring(x) #x
void main()
{
cout << getstring(Sem aspas ( "" )) << endl;
}

-##
## um concatenador, ou seja junta duas expresses, a da esquerda com a da direita. Lembrar
que os macros so expresses e no valores.
Exemplo:
#define getvar(x) var ## x
void main()
{
int var1=2,var2=3,var3=4,var4=5;
cout << getvar(3) << endl;
}

No output ir mostrar o nmero 4.

-Pr definies
J existem macros pr definidas, entre algumas esto:

__FUNCTION__ : substituda pelo nome da funo atual


__TIME__ : substituda por uma string com o tempo atual hh:mm:ss
__DATE__ : substituda por uma string com a data atual Mmmm dd yyyy

-#ifdef
possvel verificar se algum macro est j est definido. Isto bastante til para evitar que um
header file seja includo mais do que uma vez e assim prevenir erros como o de criar estruturas

j criadas. Tambm til para executar cdigos diferentes dependendo do sistema que for
(por exemplo em Linux algumas funes tm que ser diferentes por o sistema no as suportar
e as barras na direo de ficheiros so diferentes para Linux e Windows (\ e /))
Para verificar se um macro j existe usa-se o #ifdef ou #if defined e colocar o macro que se
deseja verificar a frente. Pode-se usar tambm #elseif e #else. Para terminar um bloco #if
preciso usar o #endif.
A negao do #ifdef ou #if defined #ifndef e #if !defined respetivamente.
Exemplos:
//windows
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
&& !defined(__CYGWIN__)
#include <direct.h>
#define GetCurrentDir _getcwd
#define SetCurrentDir _chdir
#else //unix
#include <unistd.h>
#define GetCurrentDir getcwd
#define SetCurrentDir chdir
#endif
#ifndef MyLib_h
#define MyLib_h
//INCLUDES
//typdef
//structs
//headers de funoes
#endif

Este ultimo vai verificar se um header file j foi includo e assim prevenindo que seja includo
outra vez.

Ficheiros:
Os ficheiros funcionam de modo igual ao cin e cout.
Para ler ou escrever preciso usar um stream, e a include fstream contem 3 streams
diferentes:

fstream : leitura e escrita;


ofstream : escrita;
ifstream : leitura;

Antes de poder usar o stream preciso associa-lo a um ficheiro para isso temos que criar uma
varivel com a class de stream e depois usar a funo open com o parmetro de entrada uma
string com o caminho para o ficheiro. No fim preciso usar a funo close().
Para escrever ou ler igual ao cin ou cout, usando << para escrever e >> para ler.

-open(filename, mode);
O open para alm do nome do ficheiro tem um parmetro opcional que o parmetro para o
modo de abertura, pode-se selecionar mais do que um usando o operador OU em bitwise:

ios::in : input; por defeito em ifstream e fstream

ios::out : output; por defeito em ofstream e fstream


ios::binary : binrio;
ios::ate : abre o ficheiro e aponta para o fim dele;
ios::app : append (adiciona tudo ao fim do ficheiro);
ios::trunc : se for de output e j existir ser apagado.

Para saber mais informaes sobre o ficheiro h umas funes booleanas uteis:

is_open() : true: aberto || false : fechado


bad() : true: a leitura/escrita falhou || false: tudo o resto
fail(): true: o mesmo que o anterior e caso haja erro de formatao (tentar ler uma
letra para um numero) || false: tudo o resto
eof(): true: chegou ao fim || false: ainda no chegou ao fim
good(): true: nenhuma das outras funes deu true || false: qualquer uma das outras
deu true

A funo getline tambm pode ser usada para ficheiros.


Com ficheiros em binrio usa-se as funes write e read, ambas tm 2 parmetros sendo um
bloco de memria (ponteiro ou array) e o segundo o tamanho que ocupa.

Cdigos teis:
Vou tentar atualizar isto conforme que me lembro.

-class list:
A class list faz parte do namespace std e da libraria <list>. uma classe de lista ligada genrica.
Esta pode conter qualquer tipo de variveis nela. Para adicionar um elemento (no fim) usa-se a
funo push_back(), para saber o tamanho pode-se usa a funo size(). Para remover pode-se
usar o remove() que remove um elemento ou o remove_if() que se pode usar como parmetro
uma funo que devolva um bool para remover vrios de uma s vez.
O grande problema da lista a pesquisa, para percorrer a lista preciso usar uma varivel
auxiliar iteradora. Por exemplo, para uma lista de ints pode-se fazer
for(list<int>::iterator it : lista)
Mas fora isso com um pouco de prtica fcil de usar e d bastante jeito.

-class vector:
A class vector faz parte do namespace std e da libraria <vector> bastante parecido ao list,
mas muito mais fcil de usar.
Em vez de ser uma lista o vector como se fosse um array. Para aceder a alguma clula, basta
usar como num array normal, de resto praticamente igual list.
Um exemplo de como partir uma string para um vector<string>:

vector<string> SplitString(string st, string separator)


{
vector<string> res;
auto start = 0; //inicio da string
auto end = st.find(separator); //procura a primeira vez que aparece o
separador
while (end != string::npos) //enquanto nao for o fim da string
{
res.push_back(st.substr(start, end - start)); //adiciona ao fim uma
substring da st
start = end + 1; //avana no inicio
end = st.find(separator, start); //procura a proxima a comear no
inicio
}
res.push_back(st.substr(start, end - start)); //adiciona a ultima
return res; //retorna o vector
}

-Classe pair:
A classe pair d bastante jeito, por exemplo quando precisamos de uma list com 2 variveis (ou
mais, pode-se pr o pair do pair do pair do pair do pair de qualquer coisa com qualquer coisa
com qualquer coisa)
A classe tem o template para 2 tipos.
Se for para usar numa list ou vector pode-se adicionar como exemplo:
vetor.push_back(pair<int,int>(1,2));
Para aceder primeira ou segunda varivel preciso usar a funo get que funciona do
seguinte modo:
get<0>(nome_pair);
//OU
get<1>(nome_pair);
E para os usar basta saber isto.

Debug:
ESTE CAPITULO FOI FEITO BASEADO NO VISUAL STUDIO 2013. TAMBEM FUNCIONA PARA
OUTRAS VERSES DO VS, MAS PARA OUTROS COMPILADORES PODEM MUDAR ALGUMAS
COISAS, MAS A LGICA A MESMA.
Exemplos de cdigo em C, mas basicamente o mesmo, exceto que mais fcil graas ao try
catch das excees
Muitas vezes o cdigo no faz o que queremos ou simplesmente o programa crasha e ns no
sabemos porqu. No modo debug tudo isto pode ser facilmente solucionado.
Para entrar no debug pressionem F5 e o cdigo ser compilado e depois executado no modo
debug.

-Crash:
Quando ocorre um crash no programa no modo debug normalmente aparece uma mensagem
de erro do gnero:

A maior parte das vezes que esta message box aparece porque tentmos aceder a um
ponteiro que est a NULL, mas nem sempre o caso. Nesta situao pode-se ver que o erro diz
que tentou aceder memria na localizao 0x00000000, por isso neste caso foi mesmo por
causa de um NULL. Mas apenas isto no nos diz onde ocorreu.
Pressionem Break e no cdigo poderam ver a linha onde ocorreu o erro assinalada com uma
setinha:

Neste caso fcil de perceber o que correu mal. A varivel L est a NULL. Mas isso nem
sempre fcil de perceber no meio de muitas linhas e funes, por isso h outras duas
ferramentas importantes no debug no Visual Studio, o break points e a janela Locals.

-Locals:
A melhor ferramenta que podem ter no debug. Para a ligarem durante um debug podem ir na
barra de tarefas a Debug > Windows > Locals ou ento ALT+4.
Esta janelas mostra as variveis e os valores destas naquele momento e assim tornando-se
ainda mais fcil de perceber o que se pode passar de errado ao verificar os valores.

Como se pode ver esta janela d o nome da varivel, o seu valor e o seu tipo. Neste casp est
confirmado que o valor de L NULL e isso foi o que fez o programa crashar.

-Break Points:
Por vezes o programa no crasha mas o cdigo no faz o que pensvamos que iria fazer e
portanto existem erros lgicos no programa. Por isso s vezes d jeito saber em que partes do
programa que o cdigo passa, ou saber os valores das variveis em certas linhas do cdigo,
para isso podemos usar break points.
No modo de debug quando o programa passa por uma linha que tenha um break point este
para nessa linha at o mandarmos seguir.
Para colocar um break point apenas temos que carregar no lado esquerdo da linha que
queremos que tenha um break:

O ponto a vermelho assinala o break. A setinha a amarelo indica a linha onde o programa est
parado.

-Mensagens de debug:
Para outros IDEs onde isto ou algumas coisas no sejam possveis uma boa maneira de saber o
que se vai passando no cdigo com mensagens de debug. Fazer uns printf para mostrar os
valores de variveis ou saber se o cdigo passou por uma seco que no devia ou coisas do
gnero. Desse modo tambm fcil de saber o que se passa de errado com um cdigo e assim
corrigi-lo.

Potrebbero piacerti anche