Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
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 ProceduralOrientação a objetosMeta ProgramaçãoDesalocaçã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 headersSources – Corpo de métodos e funçõesFunçã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 “my_struct.h”
int main(){ myStruct ms;}
$ g++ include.cc -I structs
#include “structs/my_struct.h”
int main(){ myStruct ms;}
$ g++ include.cc
Diretivas
#include <list>
#include “my_struct.h”
Procura o header nos diretórios do sistema e aqueles passados como parâmetro ao compilador.
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: #defineQuando 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;
}
usingUsada 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üidadelist<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::listmylist list2; //ok - data_structure::list
}
Tipos Primitivos
Inteiros com e sem sinal e bits de representação:
char, unsigned char: 8 bitsshort, unsigned short: 16 bitsint, unsigned int: 32 bitslong, unsigned long: 32 bitslong long, unsigned long long: 64 bits
Tipos Primitivos
Ponto flutuante e bits de representação:
float: 32 bitsdouble: 64 bits
Ponteiros e referências
int a = 10;//aloca espaço para a variável aint * 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
a
b
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
Array “b”
0
8
16
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.
}
enumerationsColeção de constantes definidas pelo usuário
enum Paises{
Argentina,
Brasil,
China,
Estados Unidos,
Inglaterra
}
enumerationsColeçã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:1
//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