The Cyclops Project Introdução: C++
Aula 1 Visão Geral Histórico da Linguagem Programa C++: header, source função main() GCC 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 usuário
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.
GCC 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.
Diretivas #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 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 <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 int, unsigned int: 32 bits long, unsigned long: 32 bits long long, unsigned long long: 64 bits
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. */ a b 10 6 memória
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 Array b 0 8 16 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 }
int a; switch (a){ case:1 case:1 switch case: //se a vale 1, executa este bloco break; //se a vale 1, executa este bloco break; default: //se a vale qualquer outro inteiro, executa este bloco }
Paises pais = Brasil; std::cout<< O nome do nativo de cada pais <<std::endl; switch (pais){ case : Argentina std::cout<< Argentino <<std::endl; break; case: Brasil std::cout<< Brasileiro <<std::endl; Break; case : China std::cout<< Chinês <<std::endl; break; case: Estados Unidos std::cout<< Americano <<std::endl; Break; case: Inglaterra std::cout<< Inglês <<std::endl; break; default: std::cout<< Nacionalidade não encontrada <<std::endl; }
enumerations enum Paises{ Argentina=1, Brasil, //corresponderá a 2 China, //corresponderá a 3 Estados Unidos=2, Inglaterra //corresponderá a 2 }
FIM AULA 1