alexandre suaide aula 2 c++ e root. programa aula 1 –introdução ao c++ e root –c++ básico...
TRANSCRIPT
Alexandre Suaideaula 2
c++ e Root
Programa
• Aula 1– Introdução ao c++ e ROOT– c++ básico
• Aula 2– Ponteiros/referências– Usando ponteiros cálculo de cinemática
• Aula 3– Classes e objetos– ROOT como ferramenta de programação/análise
• Aula 4– Classes e objetos no ROOT
• Aula 5– Análise de dados no Pelletron (ScanROOT)
Ponteiros/referências e outros monstros
• Quando criamos uma variável (ou qualquer outra coisa) esta ocupa um lugar na memória do computador– float a = 10;
• Em alguma posição desta memória temos armazenado o valor a e em algum outro lugar da memória temos armazenado que existe a variável a e em que lugar o seu conteúdo está armazenado.
• Como acessar estas informações?• Como acessar esta memória e modificá-la?• Como atuar sobre a variável?
Referências (&)
• Referências são apelidos para as variáveis/objetos criados durante um programa
• Exemplosfloat a = 10;float& b = a;cout <<“a = “<<a<<“ b = “<<b<<endl;a = 10 b = 10a = 20;cout <<“a = “<<a<<“ b = “<<b<<endl;a = 20 b = 20b = b-5;cout <<“a = “<<a<<“ b = “<<b<<endl;a = 15 b = 15
Referências (&)
• Referências não podem ser recriadas• Exemplos
float a = 10;float& b = a;float c = 9;b = c;cout <<“a = “<<a<<“ b = “<<b<<“ c = “<<c<<endl;a = 9 b = 9 c = 9a = 10;cout <<“a = “<<a<<“ b = “<<b<<“ c = “<<c<<endl;a = 10 b = 10 c = 9
Referências (&)
• No caso anterior, a e b correspondem à mesma localização de memória, enquanto c corresponde a outra localização
• Quando fazemos b = c, não estamos mudando a referência em b, estamos copiando o valor de c para a posição de memória que b se refere.
• Trabalhar, no seu programa, com a ou b é a mesma coisa
a
10
b
9
c
a
9
b
9
cb = c
Quando usar referências?
• Quando voce quiser • Uso mais comum é como parâmetros de funções• Quando definimos uma função, por exemplo
float funcao(float a, int b)– Os parâmetros a e b são tratados, pela função,
como variáveis locais – Ex:
void func(float a){ a = a*2; cout << a << endl; return;}float var = 1;func(var);2cout << var << endl;1
Note que o valor de x é alterado localmente. A variável original, var,
neste caso, permanece com o seu valor original
Quando usar referências?
• Porém, caso passemos para a função uma referência para a variável, podemos manipular o seu conteúdo sem problemafloat funcao(float& a, int b)– Neste caso, posso manipular o valor da variável a
enquanto b é tratado localmente – Ex:
void func(float& a){ a = a*2; cout << a << endl; return;}float var = 1;func(var);2cout << var << endl;2func(3);Error: could not convert ‘3’ to float&
Note que o valor de var foi alterado pois eu
passei uma referência desta variável para a
função
Apesar do ROOT aceitar esta sintaxe no prompt de comando, o compilador c+
+ retornará uma mensagem de erro
Ponteiros (*)
• Ponteiros são variáveis que contém endereços de memória para alguma coisa
• Ao contrário de referências estes podem mudar de localização
• Operadores– * define um ponteiro
• Ex: float* a;– ‘a’ contém um endereço de memória para que
contém um número float– * também pode ser utilizado para acessar o
conteúdo de uma posição de memória– & utilizado para obter o endereço de memória
de uma variável/objeto
Ponteiros (*)
• Exemplosfloat x = 10;float *p = &x; cout << x <<endl; 10cout << p <<endl; (float*)0x45daa58cout << *p <<endl; 10*p = 20;cout << x <<endl; 20cout << p <<endl; (float*)0x45daa58cout << *p <<endl; 20
Cria um ponteiro do tipo float cujo valor corresponde ao endereço de memória onde esta armazenada a
variável x
O valor de x
O valor de p. Este corresponde ao endereço de memória onde a variável x
está armazenada
O conteúdo armazenado nesta posição de memória
Mudando o conteúdo da memória
Isto reflete automaticamente na variável x
float a = 10;float b = 15;float *ea = &a;float *eb = &b;cout <<a<<“ “<<*ea<<“ “<<ea<<endl;10 10 0xb26c3e8cout <<b<<“ “<<*eb<<“ “<<eb<<endl;15 15 0xb26c408ea = eb;cout <<a<<“ “<<*ea<<“ “<<ea<<endl;10 15 0xb26c408eb = eb + 1;cout <<b<<“ “<<*eb<<“ “<<eb<<endl;15 1.97565e-36 0xb26c40c
Operações com ponteiros
Incrementa o ponteiro eb de uma unidade. Na prática, move o ponteiro para a
próxima posição de memória após o seu valor inicial
10a
ea
15b
eb
ea = eb
10a
ea
15b
eb
eb = eb+1
ea
15b
eb
?
Faz o ponteiro ea ter o mesmo valor do ponteiro eb. Na prática, ea e eb apontam
para a mesma posição de memória
Arrays são, na verdade, ponteiros
•O c++ trata vetores/arrays como sendo ponteiros
float a[10] = {1,2,3,4,5,6,7,8,9,10};cout << a <<endl;0x95bf5b8cout <<a[0]<<“ “<<*a<<endl;1 1cout <<a[5]<<“ “<<*(a+5)<<endl;6 6
Isto pode ser útil caso queiramos passar um array como argumento de função
Passando arrays como argumentos de funções
• Caso queiramos passar um array para uma função em c++ utilizamos o seu ponteiro
void cinematica(float* M){ cout <<“A_feixe = “<<M[0]<<“ “ <<“A_alvo = “<<M[1]<<“ “ <<“A_1 = “<<M[2]<<“ “ <<“A_2 = “<<M[3]<<endl; return;}float A[4] = {16,10,20,6};cinematica(A);A_feixe = 16 A_alvo = 10 A_1 = 20 A_2 = 6
Referências e ponteiros
• Referências e ponteiros são definições em c++ muito parecidas porém diferentes
• Ambas servem de atalho para objetos/variáveis definidas na memória
• Ambas permitem manipulações dos dados armazenados na memória
• Qual a diferença entre elas?
Ponteiros e referencias
• Referências– Define-se com &– Atalho para uma
variável já definida– A referência está
sempre atrelada a variável inicialmente associada
– Mesmo uso de – Bom para passar
variáveis comuns para funções
• Ponteiros– Define-se com *– Representa uma
posição de memória, tendo ou não informação válida
– Pode mudar livremente de lugar
– Precisa-se utiliar operadores * e &
– Bom para passar arrays para funções
– Ponteiros são ferramenta sindispensáveis na programação O.O.
#include "math.h"#define pi 3.1415926#define RTOD 180.0/pi#define DTOR pi/180.0#define M 931.5
void claski(float *AM,float E,float &THLBO,float &THCMO,float &THLBR, float &THCMR,float &EO,float &ER,float &VR,float &RO, float &RR,float Q){ float AP=AM[0]*M; float AT=AM[1]*M; float AO=AM[2]*M; float AR=AM[3]*M; THLBO=THLBO*DTOR; float A0=sqrt(AO*(AO+AR-AT)/(AT*AR*(1.0+(Q/E)*(AO+AR)/AT))); float AAR=A0*AR/AO; float X=A0*sin(THLBO); THCMO=atan(X/sqrt(1.0-X*X))+THLBO; THCMR=pi-THCMO; THCMR=-THCMR; THLBR=atan(sin(THCMO)/(cos(THCMO)-AAR)); float RAT=AO/AR*pow((sin(THLBO)/sin(THLBR)),2); EO=(E+Q)/(RAT+1.0); ER=E+Q-EO; VR=sqrt(1.930*ER/AR); RO=(A0*cos(THCMO)+1.0)*pow((sin(THLBO)/sin(THCMO)),3); RR=(AAR*cos(THCMO)-1.0)*pow((sin(THLBR)/sin(THCMO)),3); THLBO=THLBO*RTOD; THLBR=THLBR*RTOD; THCMO=THCMO*RTOD; THCMR=THCMR*RTOD; return;}
Exemplo: kineq.h
kineq.c
#include "kineq.h"#include <iostream>using namespace std;
int main(){ float A[4] = {16,10,12,14}; float ELAB = 64, Q = 0; float THETAMIN = 10, THETAMAX = 20, DTHETA =1; float TCMO, TLR, TCMR, EO, ER, VR, RO, RR; for(float T = THETAMIN; T<=THETAMAX; T+=DTHETA) { claski(A,ELAB,T,TCMO,TLR,TCMR,EO,ER,VR,RO,RR,Q); cout <<" T = "<<T<<" TR = "<<TLR <<" EO = " <<EO<<" ER = "<<ER <<" TCMO = "<<TCMO<<" TCMR = "<<TCMR<<endl; }}
Estrutura de dados (struct)
• Muitas vezes é interessante agrupar variáveis em uma estrutura comum– Fácil manipulação– Organização de informações– Primeiro passo para programação
orientada a objetos• struct
– Palavra chave do c que facilita a criação de estrutura de dados
struct
• Uso:struct nome_estrutura{
tipo1 nome;tipo2 nome;etc…
};
Exemplo:struct pessoa{
char nome[50];int idade;float altura;float peso;char sexo;
};
• Criando uma variável int a,b;float x[10];
pessoa p1, p2;pessoa p[100];
• Acessando os dados em uma estrutura
cout << p1.idade <<endl;cout << p[17].peso <<endl;
p[19].altura = 1.7;
Voltando ao exemplo do kineq.
void claski(float *AM, float E, float &THLBO, float &THCMO, float &THLBR, float &THCMR, float &EO, float &ER, float &VR, float &RO, float &RR, float Q)
• Não podemos simplificar com estrutura de dados?– Duas estruturas diferentes:
• struct particula• struct reacao
– Como?
Exemplostruct particula{
float Z;float A;float ELAB;float ECM;float thetaLab;float thetaCM;
};
struct reacao{
particula proj;particula alvo;particula espalhada;particula recuo;float Q;
};
• Criando uma reação
reacao OB;
OB.proj.Z = 8;OB.proj.A = 16;OB.proj.ELAB = 64;
OB.alvo.Z = 5;OB.alvo.A = 10;
OB.espalhada.Z = 6;OB.espalhada.A = 12;
OB.recuo.Z = 7;OB.recuo.A = 14;
OB.Q = 0;
Voltando ao exemplo do kineq.
void claski(float *AM, float E, float &THLBO, float &THCMO, float &THLBR, float &THCMR, float &EO, float &ER, float &VR, float &RO, float &RR, float Q)
• Duas estruturas diferentes:– struct particula– struct reacao
• Como fica a função claski?
void claski(reacao& dados){ …}
Estrutura de dados
• Note que os dados ficam muito melhores organizados nesta estrutura reacao/particula do que simplesmente em uma lista de variáveis– Emcapsulamento
• Todas informações relevantes estão contidas em uma mesma estrutura
– Primeiro passo para programação orientada a objetos• O que está faltando? próxima aula
• Exercício: Modificar o kineq.h e kineq.c para usar as estruturas particula e reacao