aula c++ estruturas de dados
TRANSCRIPT
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.
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; //okdata_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)
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 - 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
}