Introdução ao C++ 
Estruturas de Dados
Visão Geral 
● Histórico da Linguagem 
● Programa C++: header, source – função main() 
● GCC/G++ 
● Arquivos objeto, bibliotecas dinâmicas e estáticas 
● #include, #define, namespaces, typedefs 
● Ponteiros, Referências, arrays, primitivas, 
estruturas de controle.
Características do C++ 
● Linguagem multi-paradigma 
● Programação Procedural 
● Orientação a objetos 
● Meta Programação 
● Desalocação memória – Decisão cabe ao 
programador
Histórico 
● Criada por Bjarne Stroustrup em 1979 no Bell Labs 
da AT&T e inicialmente chamada de “C with classes”. 
● Em 1983 passou a ser chamada C++. 
● Ao longo do tempo incorporou novas funcionalidades 
como: 
– herança múltipla, 
– sobreescrita de operadores, 
– templates 
– entre outras coisas que veremos ao longo do curso.
Histórico 
● Possui compatibilidade com C 
– um compilador C++ deve compilar um programa 
escrito em C. 
● Em 1998 foi definido um padrão ISO para a 
linguagem, revisado em 2003 e novamente 
revisado em 2011.
GCC/G++ 
● GNU Compiler Collection 
● Compilador originalmente desenvolvido 
focando a linguagem C, chamava-se GNU C 
Compiler. 
● Ao longo do anos passou a contemplar 
outras linguagens, como C++.
Programa C++ - Arquivos 
● Header – Definições / Visível a outros headers 
● Sources – Corpo de métodos e funções 
● Função Main – Função inicial evocada pelo 
executável
Programa C++ - Hello World 
//file – hello_world.cc 
#include <iostream> 
int main(){ 
std::cout<<”Hello World!”<<std::endl; 
return 0; 
}
Programa C++ - Compilando o Hello 
World 
$ g++ hello_world.cc -o hello_world 
$ ./hello_world #executando 
$ Hello World! #resultado
Bibliotecas Estáticas e Dinâmicas 
● Estática: 
– o código executável copia os trechos com 
instruções que utiliza. O executável pode ficar 
grande. 
● Dinâmica: 
– A linkagem ocorre em tempo de execução. O 
executável acessa a biblioteca durante as 
chamadas de funções.
Diretivas 
● Informações sobre arquivos, símbolos e tipos 
interpretadas no pré-processamento da compilação. 
● #include 
– Avisa ao compilador quais headers ele precisa carregar para 
pré-processar as instruções do arquivo em questão, mais ou 
menos como o import do Java 
– Pode ser utilizado tanto no header quanto no source. Evite 
incluir includes desnecessário no header, torna a etapa de 
análise mais custosa.
Diretivas - Include 
#include “structs/my_struct.h” 
int main(){ 
myStruct ms; 
} 
$ g++ include.cc 
#include “my_struct.h” 
int main(){ 
myStruct ms; 
} 
$ g++ include.cc -I structs
Diretivas - Include 
● #include <list> 
– Procura o header nos diretórios do sistema e 
aqueles passados como parâmetro ao compilador. 
● #include “my_struct.h” 
– Procura o header primeiro no diretório que contém 
o arquivo sendo compilado, e depois nos diretórios 
do sistema e aqueles passados como parâmetro ao 
compilador.
Diretivas: #define 
● Atribui um valor a um símbolo. 
● Cada vez que o pré-processador encontra este 
símbolo no código ele substitui o símbolo por 
esse valor. 
#define max_iterations 1000
Diretivas: #define 
● Também pode ser usado para definir “macros”, pequenos 
trechos de código que são colados cada vez que o pré-processador 
identifica o símbolo associado. 
#define getmax(a,b) ((a)>(b)?(a):(b)) 
int main(){ 
int x = 10; 
int y = getmax(x,5); 
//y vale 10 
}
Diretivas: #define 
#define getmax(a,b) ((a)>(b)?(a):(b)) 
/*int main(){ 
int x = 10; 
int y = getmax(x,5); 
//y vale 10 
}*/ 
int main(){ 
int x = 10; 
int y = ((x)>(5)?(x):(5)); 
//y vale 10 
}
Diretivas: #define 
● Quando e por que usar Macros? 
– Quando o código é pequeno e existe um real 
conhecimento do fluxo das instruções. 
– Desgraças podem acontecer e o código colado pelo 
pré-processador pode tomar um rumo inesperado. 
– Como o código é “colado”, não existe ônus de ter que 
colocar o endereço da instrução na pilha como em 
uma chamada de função. Em uma próxima aula 
discutiremos isso ao ver funções inline.
namespace 
● Estabelecem o domínio ao qual declarações 
(classes, structs, metaclasses) fazem parte. 
● É utilizado para organizar o código em 
diferentes domínios, que dependendo da 
estrutura de diretórios do código fonte, podem 
apresentar uma semelhança com a 
organização em pacotes do java. 
● Também serve para eliminar ambigüidades.
namespace 
#include <list> 
#include “my_list.h” 
int main(){ 
std::list<int> list1; 
list<int> list2; 
}
using 
● Usada para suprimir a declaração de namespaces no código 
#include <list> 
#include <iostream> 
#include “my_list.h” 
using namespace std; 
int main(){ 
cout<<”hello world”<<endl; //ok! 
list<int> list1; //ambigüidade 
list<int> list2; //ambigüidade 
}
Diretivas: namespace 
#include <list> 
#include “data_structure/my_list.h” 
#include <iostream> 
using namespace std; 
int main(){ 
cout<<”hello world”<<endl; //ok! 
std::list<int> list1; //ok 
data_structure::list<int> list2; //ok 
}
typedef 
● Define um tipo a partir de outro existente. 
#include <list> 
#include “data_structure/my_list.h” 
#include <iostream> 
using namespace std; 
typedef data_structure::list<int> mylist; 
int main(){ 
cout<<”hello world”<<endl; //ok! 
list<int> list1; //ok - std::list 
mylist list2; //ok - data_structure::list 
}
Tipos Primitivos 
● Inteiros com e sem sinal e bits de 
representação: 
– char, unsigned char: 8 bits 
– short, unsigned short: 16 bits (mínimo) 
– int, unsigned int: 32 bits (mínimo) 
– long, unsigned long: 32 bits (mínimo) 
– long long, unsigned long long: 64 bits (mínimo)
Tipos Primitivos 
● Ponto flutuante e bits de representação: 
– float: 32 bits 
– double: 64 bits
Ponteiros e referências 
● int a = 10; //aloca espaço para a variável a 
● int * b = &a; 
● /*cria um ponteiro b para números inteiros. 
Um ponteiro aloca espaço para e o reserva 
para armazenar um endereço. */ 
● Memória: 
10 
6
Variáveis, Ponteiros e Referências 
#include <iostream> 
int main(){ 
int a = 5; 
int * b = &a; 
std::cout<<”O valor de a é”<<a<<” o endereço de a é“<<&a<<std::endl; 
std::cout<<”b contém o endereço”<<b<<” o conteúdo do endereço de b 
é:”<<*b<<std::end; 
}
Variáveis, Ponteiros e Referências 
*b += a; 
a *= (*b); 
std::cout<<a<<std::endl; 
//O que foi impresso??
Variáveis, Ponteiros e Referências 
● Uma referência é como um “apelido” a uma outra 
variável. 
● Tal qual um ponteiro, a referência apenas 
“referencia” algum endereço de memória. 
● Uma vez criada, não há como distinguir entre uma 
referência e o dado por ela referenciado. 
● Adicionalmente, uma referência só pode “apontar 
para” um único dado durante sua existência.
Variáveis, Ponteiros e Referências 
● int main(){ 
int a = 3; 
int b = 4; 
int * p = &b; 
int & r = b; 
r += 2; // b agora vale 6 
p = &a; // p aponta para “a” 
r = a; // b agora vale 3; r ainda referencia b. 
}
Arrays – Alocação Estática 
int main(){ 
int a[5]; 
a[0] = 0; 
a[4] = -3; 
}
Arrays – Alocação dinâmica 
● int main(){ 
int a =5; 
int * b = new int[a]; 
}
Arrays - Iterando 
int main(){ 
int a = 5; 
int * b = new int[a]; 
int * it = &b[0]; 
(*it++) = 8; //Quais operações são executadas 
nessa linha? 
}
Arrays - Iterando 
int * it = &b[0]; //faz o iterador apontar para o endereço da 
posição 0 de b; 
//int * it = b; 
(*it++) = 8; 
//(*it) = 8 atribui o valor 8 a posição 0 do array b incrementa o 
iterador, fazendo-o apontar para a posição 1 de b
Arrays - Iterando 
int * it = &b[0]; //faz o iterador apontar para o 
endereço 9; 
(*it) = 8; //atribui o valor 8 ao dado contido no 
endereço 9 
it++;//incrementa o iterador, fazendo-o apontar 
para o endereço 10 
it
Statements 
if( expressão booleana ){ 
//se a expressão é verdadeira executa este bloco 
} else{ 
//se a expressão é falsa executa este bloco 
}
Statements 
while( expressão booleana ){ 
//enquanto a expressão for verdadeira executa este bloco 
} 
do{ 
//enquanto a expressão for verdadeira executa este bloco 
}while( expressão booleana );
Statements 
for( inicialização de variáveis ; expressão ; 
operação executada a cada loop ){ 
//Para cada vez que a expressão for verdadeira, 
executa esse bloco. Se a expressão for falsa, sai 
do bloco. 
}
enumerations 
● Coleção de constantes definidas pelo usuário 
enum Paises{ 
Argentina, 
Brasil, 
China, 
Estados Unidos, 
Inglaterra 
}
enumerations 
● Coleção de constantes definidas pelo usuário 
enum Paises{ 
Argentina=9, 
Brasil=6, 
China=5, 
Estados Unidos=13, 
Inglaterra=10 
}
switch case 
int a; 
switch (a){ 
case:1 
//se a vale 1, executa este bloco 
break; 
case:2 
//se a vale 2, executa este bloco 
break; 
default: 
//se a vale qualquer outro inteiro, executa este bloco 
}

Aula c++ estruturas de dados

  • 1.
    Introdução ao C++ Estruturas de Dados
  • 2.
    Visão Geral ●Histórico da Linguagem ● Programa C++: header, source – função main() ● GCC/G++ ● Arquivos objeto, bibliotecas dinâmicas e estáticas ● #include, #define, namespaces, typedefs ● Ponteiros, Referências, arrays, primitivas, estruturas de controle.
  • 3.
    Características do C++ ● Linguagem multi-paradigma ● Programação Procedural ● Orientação a objetos ● Meta Programação ● Desalocação memória – Decisão cabe ao programador
  • 4.
    Histórico ● Criadapor Bjarne Stroustrup em 1979 no Bell Labs da AT&T e inicialmente chamada de “C with classes”. ● Em 1983 passou a ser chamada C++. ● Ao longo do tempo incorporou novas funcionalidades como: – herança múltipla, – sobreescrita de operadores, – templates – entre outras coisas que veremos ao longo do curso.
  • 5.
    Histórico ● Possuicompatibilidade com C – um compilador C++ deve compilar um programa escrito em C. ● Em 1998 foi definido um padrão ISO para a linguagem, revisado em 2003 e novamente revisado em 2011.
  • 6.
    GCC/G++ ● GNUCompiler Collection ● Compilador originalmente desenvolvido focando a linguagem C, chamava-se GNU C Compiler. ● Ao longo do anos passou a contemplar outras linguagens, como C++.
  • 7.
    Programa C++ -Arquivos ● Header – Definições / Visível a outros headers ● Sources – Corpo de métodos e funções ● Função Main – Função inicial evocada pelo executável
  • 8.
    Programa C++ -Hello World //file – hello_world.cc #include <iostream> int main(){ std::cout<<”Hello World!”<<std::endl; return 0; }
  • 9.
    Programa C++ -Compilando o Hello World $ g++ hello_world.cc -o hello_world $ ./hello_world #executando $ Hello World! #resultado
  • 10.
    Bibliotecas Estáticas eDinâmicas ● Estática: – o código executável copia os trechos com instruções que utiliza. O executável pode ficar grande. ● Dinâmica: – A linkagem ocorre em tempo de execução. O executável acessa a biblioteca durante as chamadas de funções.
  • 11.
    Diretivas ● Informaçõessobre arquivos, símbolos e tipos interpretadas no pré-processamento da compilação. ● #include – Avisa ao compilador quais headers ele precisa carregar para pré-processar as instruções do arquivo em questão, mais ou menos como o import do Java – Pode ser utilizado tanto no header quanto no source. Evite incluir includes desnecessário no header, torna a etapa de análise mais custosa.
  • 12.
    Diretivas - Include #include “structs/my_struct.h” int main(){ myStruct ms; } $ g++ include.cc #include “my_struct.h” int main(){ myStruct ms; } $ g++ include.cc -I structs
  • 13.
    Diretivas - Include ● #include <list> – Procura o header nos diretórios do sistema e aqueles passados como parâmetro ao compilador. ● #include “my_struct.h” – Procura o header primeiro no diretório que contém o arquivo sendo compilado, e depois nos diretórios do sistema e aqueles passados como parâmetro ao compilador.
  • 14.
    Diretivas: #define ●Atribui um valor a um símbolo. ● Cada vez que o pré-processador encontra este símbolo no código ele substitui o símbolo por esse valor. #define max_iterations 1000
  • 15.
    Diretivas: #define ●Também pode ser usado para definir “macros”, pequenos trechos de código que são colados cada vez que o pré-processador identifica o símbolo associado. #define getmax(a,b) ((a)>(b)?(a):(b)) int main(){ int x = 10; int y = getmax(x,5); //y vale 10 }
  • 16.
    Diretivas: #define #definegetmax(a,b) ((a)>(b)?(a):(b)) /*int main(){ int x = 10; int y = getmax(x,5); //y vale 10 }*/ int main(){ int x = 10; int y = ((x)>(5)?(x):(5)); //y vale 10 }
  • 17.
    Diretivas: #define ●Quando e por que usar Macros? – Quando o código é pequeno e existe um real conhecimento do fluxo das instruções. – Desgraças podem acontecer e o código colado pelo pré-processador pode tomar um rumo inesperado. – Como o código é “colado”, não existe ônus de ter que colocar o endereço da instrução na pilha como em uma chamada de função. Em uma próxima aula discutiremos isso ao ver funções inline.
  • 18.
    namespace ● Estabelecemo domínio ao qual declarações (classes, structs, metaclasses) fazem parte. ● É utilizado para organizar o código em diferentes domínios, que dependendo da estrutura de diretórios do código fonte, podem apresentar uma semelhança com a organização em pacotes do java. ● Também serve para eliminar ambigüidades.
  • 19.
    namespace #include <list> #include “my_list.h” int main(){ std::list<int> list1; list<int> list2; }
  • 20.
    using ● Usadapara suprimir a declaração de namespaces no código #include <list> #include <iostream> #include “my_list.h” using namespace std; int main(){ cout<<”hello world”<<endl; //ok! list<int> list1; //ambigüidade list<int> list2; //ambigüidade }
  • 21.
    Diretivas: namespace #include<list> #include “data_structure/my_list.h” #include <iostream> using namespace std; int main(){ cout<<”hello world”<<endl; //ok! std::list<int> list1; //ok data_structure::list<int> list2; //ok }
  • 22.
    typedef ● Defineum tipo a partir de outro existente. #include <list> #include “data_structure/my_list.h” #include <iostream> using namespace std; typedef data_structure::list<int> mylist; int main(){ cout<<”hello world”<<endl; //ok! list<int> list1; //ok - std::list mylist list2; //ok - data_structure::list }
  • 23.
    Tipos Primitivos ●Inteiros com e sem sinal e bits de representação: – char, unsigned char: 8 bits – short, unsigned short: 16 bits (mínimo) – int, unsigned int: 32 bits (mínimo) – long, unsigned long: 32 bits (mínimo) – long long, unsigned long long: 64 bits (mínimo)
  • 24.
    Tipos Primitivos ●Ponto flutuante e bits de representação: – float: 32 bits – double: 64 bits
  • 25.
    Ponteiros e referências ● int a = 10; //aloca espaço para a variável a ● int * b = &a; ● /*cria um ponteiro b para números inteiros. Um ponteiro aloca espaço para e o reserva para armazenar um endereço. */ ● Memória: 10 6
  • 26.
    Variáveis, Ponteiros eReferências #include <iostream> int main(){ int a = 5; int * b = &a; std::cout<<”O valor de a é”<<a<<” o endereço de a é“<<&a<<std::endl; std::cout<<”b contém o endereço”<<b<<” o conteúdo do endereço de b é:”<<*b<<std::end; }
  • 27.
    Variáveis, Ponteiros eReferências *b += a; a *= (*b); std::cout<<a<<std::endl; //O que foi impresso??
  • 28.
    Variáveis, Ponteiros eReferências ● Uma referência é como um “apelido” a uma outra variável. ● Tal qual um ponteiro, a referência apenas “referencia” algum endereço de memória. ● Uma vez criada, não há como distinguir entre uma referência e o dado por ela referenciado. ● Adicionalmente, uma referência só pode “apontar para” um único dado durante sua existência.
  • 29.
    Variáveis, Ponteiros eReferências ● int main(){ int a = 3; int b = 4; int * p = &b; int & r = b; r += 2; // b agora vale 6 p = &a; // p aponta para “a” r = a; // b agora vale 3; r ainda referencia b. }
  • 30.
    Arrays – AlocaçãoEstática int main(){ int a[5]; a[0] = 0; a[4] = -3; }
  • 31.
    Arrays – Alocaçãodinâmica ● int main(){ int a =5; int * b = new int[a]; }
  • 32.
    Arrays - Iterando int main(){ int a = 5; int * b = new int[a]; int * it = &b[0]; (*it++) = 8; //Quais operações são executadas nessa linha? }
  • 33.
    Arrays - Iterando int * it = &b[0]; //faz o iterador apontar para o endereço da posição 0 de b; //int * it = b; (*it++) = 8; //(*it) = 8 atribui o valor 8 a posição 0 do array b incrementa o iterador, fazendo-o apontar para a posição 1 de b
  • 34.
    Arrays - Iterando int * it = &b[0]; //faz o iterador apontar para o endereço 9; (*it) = 8; //atribui o valor 8 ao dado contido no endereço 9 it++;//incrementa o iterador, fazendo-o apontar para o endereço 10 it
  • 35.
    Statements if( expressãobooleana ){ //se a expressão é verdadeira executa este bloco } else{ //se a expressão é falsa executa este bloco }
  • 36.
    Statements while( expressãobooleana ){ //enquanto a expressão for verdadeira executa este bloco } do{ //enquanto a expressão for verdadeira executa este bloco }while( expressão booleana );
  • 37.
    Statements for( inicializaçãode variáveis ; expressão ; operação executada a cada loop ){ //Para cada vez que a expressão for verdadeira, executa esse bloco. Se a expressão for falsa, sai do bloco. }
  • 38.
    enumerations ● Coleçãode constantes definidas pelo usuário enum Paises{ Argentina, Brasil, China, Estados Unidos, Inglaterra }
  • 39.
    enumerations ● Coleçãode constantes definidas pelo usuário enum Paises{ Argentina=9, Brasil=6, China=5, Estados Unidos=13, Inglaterra=10 }
  • 40.
    switch case inta; switch (a){ case:1 //se a vale 1, executa este bloco break; case:2 //se a vale 2, executa este bloco break; default: //se a vale qualquer outro inteiro, executa este bloco }