Modelagem e
Simulação em Física
dos Raios X
Linguagens de Programação C/C++
Programação em C/C++
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h>
int main(void) { int a;
float b, c;
printf("digite um valor
inteiro: \n"); scanf("%d",&a);
b = 0.5; c = a+b;
printf("a soma deste valor com 0.5 eh: %f\n",c); return 0;
Programação em C/C++
Tipos de Instrução
Instruções de compilação #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> Instruções de programação int a;Programação em C/C++
Instruções de programação
Comandos de declaração int a; double b, c; Comandos de execução printf("digite um valor inteiro: \n"); scanf("%d",&a);
b = 0.5; c = a+b;
Programação em C/C++
Compiladores C/C++
GNU gcc: linguagem C
GNU g++: linguagem C++
Distribuição nativa em Linux
Portabilidade para Windows
MinGW
Programação em C/C++
Ambientes de Desenvolvimento Integrados
(IDE’s)
C++Builder (comercial, Windows)
Visual C (comercial, Windows)
Code::Blocks (aberto, Windows, Linux)
Programação em C/C++
Tipos de Dados
Tipos definidos
Tipo literal
Tipo numérico inteiro Tipo numérico real
Tipos abstratos
Estruturas de dados Enumerações
Programação em C/C++
Representação de Dados na Memória
Caracteres
8 bits = 1 byte
Representação dos símbolos da tabela ASCII Caracteres = símbolos (grafos e controle)
128 símbolos iniciais da tabela ASCII
Programação em C/C++
Representação de
Dados na Memória
Caracteres de controle
não visíveis e alguns
caracteres que possuem ações específicas em C/C++.
Além destes caracteres,
existe o “símbolo nulo” ‘\0’ (NULL). ‘\a’ “beep” ‘\b’ “backspace” ‘\f’ alimentador de folha ‘\n’ alimentador de linha ‘\r’ retorno de carrilhão ‘\t’ tabulação horizontal ‘\v’ tabulação vertical ‘\\’ grafo “backslash” ‘\’’ grafo apóstrofo ‘\”’ grafo aspas
Programação em C/C++
Representação de Dados na Memória
Os símbolos da tabela ASCII são indexados.
Os índices vão desde 0 até 127.
Uma variável do tipo char não armazena o
caractere em si, mas sim o seu índice.
Portanto, uma variável do tipo char armazena um
Programação em C/C++
Representação de Dados na Memória
Números inteiros
8 bits = 1 byte
Bit mais significativo como bit de sinal
Inteiro sem sinal: 8 bits
Inteiro com sinal: 7 bits + 1 bit de sinal
Agrupamentos de bytes em potência de 2: 1, 2, 4, 8 ...
Programação em C/C++
Representação de Dados na Memória
Inteiro com sinal: [signed] char
1 byte: 7 bits + 1 bit sinal → ±|27-1|
Inteiro sem sinal: unsigned [char]
1 byte: 8 bits → 0..(28-1)
Inteiro com sinal: [signed] int
Programação em C/C++
Representação de Dados na Memória
Inteiro curto com sinal : short [int]
2 bytes: 15 bits + 1 bit sinal → ±|215-1|
Inteiro curto sem sinal: unsigned short [int]
2 bytes: 16 bits → 0..(216-1)
Inteiro longo com sinal : long [int]
8 bytes: 63 bits + 1 bit sinal → ±|263-1|
Programação em C/C++
Representação de Dados na Memória
Números reais
32 bits = 4 bytes (precisão simples) 64 bits = 8 bytes (precisão dupla)
80 bits = 10 bytes (precisão estendida)
Tipo real precisão simples: float
Programação em C/C++
Representação de Dados na Memória
Números reais são armazenados na forma de
mantissa e expoente, ambos na base 2.
A mantissa varia entre no intervalo [1,2).
Na precisão simples, o número real é da ordem
de ±10±38.
Na precisão dupla, o número real é da ordem de
±10±308.
Programação em C/C++
Representação de Dados na Memória
Para todo tipo de dado com mais de 1 byte de
comprimento, é necessário estabelecer-se uma regra de armazenamento deste dado na
memória.
O padrão mais comum é a que recomenda que
os bytes que componham o número sejam
armazenados a partir do byte menos significativo.
Programação em C/C++
Representação de Dados na Memória
A memória RAM pode ser vista como uma lista
indexada em ordem crescente de “caixas” vazias.
Cada “caixa” possui 1 byte de comprimento.
O índice da “caixa” é seu endereço de memória.
memória endereço 0 1 2 3
Programação em C/C++
Representação de Dados na Memória
As variáveis do tipo char e unsigned char
ocupam um único byte na memória.
Seu armazenamento na memória é simples e
direto. Exemplo char a; unsigned char b; a = 15; 15 100 memória endereço 0 1 2 3 a b variável
Programação em C/C++
Representação de Dados na Memória
Cada variável está associada a um endereço de
memória.
O programador vê a variável, o computador vê o
endereço da variável na memória.
É o sistema operacional que determina a partir de
que endereço um programa pode alocar suas variáveis.
Programação em C/C++
Representação de Dados na Memória
Se a variável possui mais de 1 byte, o conteúdo
da variável é armazenado, a partir do byte menos
significativo (lsb, less significant byte).
É comum usar a notação hexadecimal para
representar números inteiros.
Por exemplo, o número 1000 decimal ocupa 2
Programação em C/C++
Representação de Dados na Memória
Se a variável possui mais de 1 byte, o conteúdo
da variável é armazenado, a partir do byte menos
significativo (lsb, less significant byte).
É comum usar a notação hexadecimal para
representar números inteiros.
Por exemplo, o número 1000 decimal ocupa 2
bytes. 3 E 8
Representação de Dados na Memória
O byte menos significativo é E8(h) e o mais
significativo é 03(h). Exemplo char a; short b; a = 15; b = 1000;
Programação em C/C++
0F E8 03 memória endereço base+0 base+1 base+2 base+3 a b variável base+4Programação em C/C++
Representação de Dados na Memória
Apesar da variável ‘b’ conter um número de 2
bytes, ela está associada a um endereço somente.
Dependendo do tipo de variável, o computador
“sabe” quantos bytes adjacentes estão
envolvidos, mas o endereço base é sempre o
Programação em C/C++
Representação Binária de Inteiros com Sinal
Inteiro positivo de 8 bits: 0|xxx xxxx(b)
Inteiro negativo de 8 bits: 1|xxx xxxx(b)
Conversão positivo/negativo
Inverter os valores de bits (0↔1): “complemento a 1” Somar 1 ao número: “complemento a 2”
Programação em C/C++
Representação Binária de Inteiros com Sinal
Exemplo: número +10(d)
(d) significa “representação decimal” +10(d) = 0|000 1010(b)
(b) significa “representação binária”
Programação em C/C++
Representação Binária de Inteiros com Sinal
Exemplo: número −10(d)
(d) significa “representação decimal” +10(d) = 0|000 1010(b)
(b) significa “representação binária”
+10(d) → 0|000 1010(b)
Programação em C/C++
Representação Binária de Inteiros com Sinal
Exemplo: número −10(d)
(d) significa “representação decimal” +10(d) = 0|000 1010(b)
(b) significa “representação binária”
+10(d) → 0|000 1010(b)
1|111 0101(b)
0|000 0001(b) → somar 1 +
Programação em C/C++
Representação Binária de Inteiros com Sinal
Exemplo: número −10(d)
(d) significa “representação decimal” +10(d) = 0|000 1010(b)
(b) significa “representação binária”
+10(d) → 0|000 1010(b)
1|111 0101(b) 0|000 0001(b)
Programação em C/C++
Exemplo: número −127(d) +127(d) → 0|111 1111(b) 1|000 0000(b) 0|000 0001(b) −127(d) ← 1|000 0001(b) Exemplo: número −1(d) +1(d) →0|000 0001(b) 1|111 1110(b) 0|000 0001(b) + +Programação em C/C++
Exemplo: número 0(d) 0(d) → 0|000 0000(b) 1|111 1111(b) 0|000 0001(b) 0(d) ← 0|000 0000(b) Exemplo: número 1|000 0000(b) é −128(d) −128(d) →1|000 0000(b) 0|111 1111(b) −1(d) ← 1|111 1111(b) 0|000 0001(b) −127(d) ← 1|000 0001(b) + + +Programação em C/C++
Sequência de Inteiros de 1 byte
sem sinal com sinal
0 0000 0000 0 1 0000 0001 1 2 0000 0010 2 127 0111 1111 127 128 1000 0000 -128 129 1000 0001 -127 130 1000 0010 -126 254 1111 1110 -2
Programação em C/C++
Operadores
Os operadores se distribuem nas seguintes
categorias: atribuição: ‘=’ aritméticos lógicos relacionais deslocamento binário
Programação em C/C++
Operadores aritméticos
soma: ‘+’ subtração: ‘-’ produto: ‘*’ divisão: ‘/’ resto: ‘%’ (inteiros)Programação em C/C++
Operadores aritméticos concatenados
soma: ‘+=’ ( a += b; → a = a+b; )
subtração: ‘-=’ ( a -= b; → a = a-b; )
produto: ‘*=’ ( a *= b; → a = a*b; )
divisão: ‘/=’ ( a /= b; → a = a/b; )
Programação em C/C++
Operadores aritméticos especiais
soma unitária: ‘++’ ( a++; → a = a+1; )
subtração unitária: ‘--’ ( a--; → a = a-1; )
Estes operadores podem ser pré-ordenados ou
pós-ordenados:
b = a++; (primeiro copia ‘a’→’b’, depois incrementa) c = ++a; (primeiro incrementa ‘a’, depois copia ‘a’→’b’) d = a--; (primeiro copia ‘a’→’b’, depois decrementa) e = --a; (primeiro decrementa ‘a’, depois copia ‘a’→’b’)
Programação em C/C++
Operadores binários
conjunção (e): ‘&’
disjunção (ou): ‘|’
disjunção (ou) exclusivo: ‘^’
Programação em C/C++
Operadores binários concatenados
conjunção (e): ‘&=’ ( a &= b; → a = a&b; )
disjunção (ou): ‘|=’ ( a |= b; → a = a|b; )
Programação em C/C++
Operadores deslocamento binário
a esquerda: ‘<<’
a direita: ‘>>’
Operadores deslocamento binário
concatenado
a esquerda: ‘<<=’ ( a <<= n; → a = a<<n; )
Programação em C/C++
Operadores lógicos
conjunção (e): ‘&&’
disjunção (ou): ‘||’
Programação em C/C++
Operadores relacionais
maior: ‘>’ maior ou igual: ‘>=’ menor: ‘<’ menor ou igual: ‘<=’ igualdade: ‘==’ diferença: ‘!=’Programação em C/C++
Mecanismos de Controle de Execução
Em C/C++, o teste condicional é realizado pela
instrução if:
if (teste) {
bloco de instruções caso
teste seja verdadeiro
} else {
bloco de instruções caso teste seja falso
Programação em C/C++
Mecanismos de Controle de Execução
O início e o fim do bloco de comandos a serem
executados são determinados pelo uso de chaves.
Em C/C++, considera-se falso qualquer coisa
igual a ZERO (nulo) e verdadeiro qualquer coisa
diferente de ZERO (não nulo).
Programação em C/C++
Mecanismos de Controle de Execução
Em C/C++, existe um teste condicional
simplificado chamado “comando ternário”.
A sintaxe é:
(teste) ? resultado1 : resultado2;
Se teste é verdadeiro, a instrução retorna o
resultado1.
Senão, o comando retorna resultado2.
Programação em C/C++
Mecanismos de Controle de Execução
Existe também a instrução de seleção de caso.
Dependendo do conteúdo de uma variável inteira,
a instrução desvia para o caso correspondente.
O comando é o switch:
switch (variável) {
case valor:
Programação em C/C++
Mecanismos de Controle de Execução
switch(variável) { case valor1: bloco de instruções break; case valor2: bloco de instruções break; default:
Programação em C/C++
Mecanismos de Controle de Execução
Pode haver quantos ‘cases’ forem necessários.
O comando break faz com que a execução do
bloco se encerre.
A ausência do break, faz com que a execução
invada outro case.
Caso nenhuma das entradas corresponda ao
Programação em C/C++
Mecanismos de Controle de Execução
Existem 3 comandos de repetição de
instrução/bloco de instruções: for, while e
do/while.
A estrutura do comando for é:
for (var=valor; teste; incremento|decremento) {
bloco de instruções
Programação em C/C++
Mecanismos de Controle de Execução
Exemplo:
for ( i=0; i<10; i=i+1 ) { bloco de instruções
}
for ( j=-1.0; j<1.0; j=j+1e-3 ) { bloco de instruções
Programação em C/C++
Mecanismos de Controle de Execução
Exemplo:
for ( ; ; ) {
laço infinito
}
for ( i=10; i>=-10; i=i-2 ) { bloco de instruções
Programação em C/C++
Mecanismos de Controle de Execução
O comando while executa o bloco de instruções
enquanto o teste de execução for verdadeiro.
Estrutura da instrução while
while (teste) {
bloco de instruções
}
O comando break pode ser usado no bloco de
Programação em C/C++
Mecanismos de Controle de Execução
O comando do/while tem o mesmo
comportamento do comando while com a
diferença do teste estar no final do bloco de instruções.
A estrutura do do/while é
do {
bloco de instruções
Programação em C/C++
Mecanismos de Controle de Execução
Vale a pena observar que as instruções while e
do/while realizam praticamente o mesmo processo lógico.
No entanto, como o teste de continuidade do
comando do/while é no final do bloco, mesmo que
o teste seja falso, pelo menos uma execução do bloco de instruções se realizará.
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>int main(void) {/* inicio */ /* numero aleatorio */
int eps;
/* variavel auxiliar */
int i;
srand(time(NULL));
/* funcao geradora de numeros
aleatorios inteiros: rand() */ /* a funcao rand() gera inteiro
for ( i=0; i<10; i++ ) { eps = rand();
if (eps<RAND_MAX/10) {
printf(“\teps=%5d menor que RAND_MAX/10\n”,eps); } else if (eps<RAND_MAX/2) {
printf(“\teps=%5d menor que RAND_MAX/2\n”,eps); } else {
printf(“\teps=%5d\n”,eps); } } return 0; } /* fim */ gcc –o ex exemplo1.c ./ex
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>int main(void) {
/* numero aleatorio */
float eps;
/* variavel auxiliar */
int i;
/* funcao geradora de numeros
aleatorios inteiros: rand() */ /* a funcao rand() gera inteiro
entre 0 e a constante RAND_MAX */
printf("RAND_MAX: %d\n",RAND_MAX);
/* a funcao srand gera semente para
for ( i=0; i<10; i++ ) {
eps = (float)rand()/RAND_MAX;
if (eps<0.1) {
printf("\teps=%5.3f menor que 0.1\n",eps);
} else if (eps<0.5) {
printf("\teps=%5.3f menor que 0.5\n",eps);
} else {
printf("\teps=%5.3f\n",eps); }
}
return 0; }
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>int main(void) {
/* numero aleatorio */ float eps; /* variavel auxiliar */ int i; /* variaveis contadoras */ int c1, c2, c3, n; /* semente geradora */ srand(time(NULL));
for ( i=0; i<n; i++ ) {
/* numero eps entre 0 e 1*/
eps = (float)rand()/RAND_MAX;
if (eps<0.1) { c1++; /* ++c1; */ } else if (eps<0.5) { c2++; /* ++c2; */ } else { c3++; /* ++c3; */ } } printf(“Prob(eps<0.1)=%5.3f\n", (float)c1/n); printf(“Prob(0.1<=eps<0.5)=%5.3f\n", (float)c2/n); printf(“Prob(0.5<=eps<1)=%5.3f\n", (float)c3/n);
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>int main(void) {
/* numero aleatorio */ float eps; /* variaveis auxiliares */ char f1, f2, f3; int i; /* variaveis contadoras */ int c1, c2, c3, n; float p1, p2, p3; /* semente geradora */ srand(time(NULL));
/* numero eps entre 0 e 1*/
eps = rand()*1.0/RAND_MAX; if (eps<0.1) { c1++; p1 = c1*1.0/n; } else if (eps<0.5) { c2++; p2 = c2*1.0/n; } else { c3++; p3 = c3*1.0/n; } f1 = (fabs(p1-0.1)>1e-3) ? 1 : 0; f2 = (fabs(p2-0.4)>1e-3) ? 1 : 0; f3 = (fabs(p3-0.5)>1e-3) ? 1 : 0; printf("Aguarde... (%d)\n",n); } while(f1 || f2 || f3);
printf("Total de eventos: %d\n",n); printf("P(eps<0.1)=%5.3f\n",p1);
Programação em C/C++
Conversão de Tipo
Quando um dado de um tipo é atribuído a uma
variável do mesmo tipo, não há conversão de tipo.
Quando o dado e a variável são de tipos
diferentes, ocorrerá a conversão do tipo do dado para o tipo da variável.
Numa operação aritmética, dados e variáveis de
Programação em C/C++
Conversão de Tipo
Exemplo:
dados do tipo char com dados do tipo int são
convertidos para o tipo int.
dados do tipo char e int com dados do tipo float são
convertidos para o tipo float.
dados do tipo char, int e float com dados do tipo double são convertidos para o tipo double.
Programação em C/C++
Conversão de Tipo
Uma forma de forçar a mudança do tipo de dado
é através do mecanismo de “typecasting”.
Exemplo: float a; char b; int c; a = (float)b; b = (char)c;
Programação em C/C++
Conversão de Tipo
Conversão de tipo inteiro para tipo real envolve
apenas o acréscimo da parte fracionária nula.
Conversão de tipo real para tipo inteiro envolve
truncamento da parte fracionária.
O arredondamento de dados reais pode ser
obtido através das funções:
floor(dado): arredonda para baixo
Programação em C/C++
Tipos de Dados Abstratos
Vetores (numéricos e literais)
Matrizes
Estruturas
Enumerações Uniões
Programação em C/C++
Vetores e Matrizes
Um vetor é uma lista indexada de dados do
mesmo tipo.
Pode-se construir vetores de qualquer tipo
acrescentando a dimensão do vetor (rank).
Exemplo:
float a[15];
char nome[80];
Programação em C/C++
Vetores e Matrizes
Uma matriz é uma lista multiplamente indexada
de dados do mesmo tipo.
Pode-se construir matrizes de qualquer tipo
acrescentando as dimensões da matriz (ranks).
Exemplo:
float a[15][20]; /*15 linhas, 20 colunas */
char nome[2][80]; /*2 linhas, 80 colunas */
Programação em C/C++
Vetores e Matrizes
Uma forma interessante de olhar para a matriz
bidimensional é encará-la como um vetor (uma lista indexada) de vetores (de listas indexadas).
matriz 2D ↔ vetor de vetores
Programação em C/C++
Vetores e Matrizes
Um vídeo digital é uma sequência temporal de
imagens.
Cada imagem é uma matriz 2D indexada pelo
tempo.
Uma imagem é uma sequência de linhas.
Cada linha é uma sequência de pixels.
O vídeo é uma lista de sequências de linhas de
Programação em C/C++
Vetores e Matrizes
Uma vez definida a dimensão do vetor ou da
matriz, esta não pode ser mais alterada.
A criação de vetores e matrizes sem dimensões
pré-definidas é possível, mas precisa da noção de ponteiros.
Os índices dos vetores e matrizes se iniciam com
Programação em C/C++
Vetores de Caracteres: Strings
Um vetor de caracteres é chamado de string.
Uma string, para ser útil, é necessário inserir um
caractere especial chamado NULL (constante
literal ‘\0’).
Esta constante é definida nos arquivo de
cabeçalho stdlib.h e string.h.
O papel do NULL é marcar o final da sequência
Programação em C/C++
Vetores de Caracteres: Strings
Exemplo:
#include <string.h> #include <stdio.h> #include <stdlib.h>
void main(void) {
char nome[50];
strcpy(nome,“Luis Fernando”); printf(“Meu nome eh: %s\n”,nome);
printf(“Tamanho declarado eh: %d\n”,sizeof(nome)); printf(“Tamanho usado eh : %d\n”,strlen(nome)); }
Programação em C/C++
Vetores de Caracteres: Strings
A função strcpy() copia o conteúdo de uma string
para outra.
O operador de atribuição ‘=‘ não realiza esta
função.
A função sizeof() retorna o comprimento
L u i s F e r n a n d o \0
Programação em C/C++
Vetores de Caracteres: Strings
Pode-se inicializar a string diretamente com seu
conteúdo.
O tamanho é definido automaticamente.
Exemplo:
#include <string.h> #include <stdio.h> #include <stdlib.h>
void main(void) {
char nome[]={“Luis Fernando”};
Programação em C/C++
Estrutura de Dados
A linguagem C permite criar estruturas de dados
compostos.
Funciona como um registro composto por vários
campos que podem ser de tipos distintos, inclusive outras estruturas.
Uma nova estrutura funciona como um novo tipo.
Depois de definida uma estrutura, variáveis
Programação em C/C++
Estrutura de Dados
Uma estrutura é definida através da instrução
struct identificador { };.
No interior do escopo da instrução, declara-se as
variáveis que comporão a estrutura.
Exemplo:
struct vet3d {
double x, y, z; /* campos da estrutura */
Programação em C/C++
Estrutura de Dados
Exemplo:
struct vet3d {
double x, y, z; /* campos da estrutura */
} v1, v2; /* variáveis do tipo struct vet3d */
Uma estrutura de dado pode se tornar
formalmente um tipo através da instrução
Programação em C/C++
Estrutura de Dados
Exemplo:
typedef struct vet3d {
double x, y, z; /* campos da estrutura */
} vetor3D; /* tipo definido da estrutura */
vetor3D v1, v2;
Neste caso, o identificador vet3d é opcional.
Exemplo:
typedef struct {
Programação em C/C++
Estrutura de Dados
Para acessar um campo de uma estrutura, basta
referenciar a variável do tipo da estrutura seguida
do nome do campo separados por um ponto.
Exemplo: vetor3D v1, v2; v1.x = 1; v1.y = v1.z = 0; v2.x = 0.92; v2.y = 1.34e-5; v2.z = v1.x;
Programação em C/C++
Ponteiros
Os ponteiros representam um mecanismo ímpar
na linguagem C.
O ponteiro diz respeito ao endereço de uma
variável e não ao seu conteúdo.
Quando um dado é declarado, ele reside na
memória em algum lugar.
Programação em C/C++
Ponteiros
Quando uma variável é declarada, na linguagem
de alto nível, ela é identificada por um nome: o nome da variável.
Quando o código é compilado, o identificador
passa a ser o endereço da variável.
O programador vê as variáveis, o computador vê
o endereço das variáveis.
Programação em C/C++
Ponteiros
Quando o programador atribui um dado a uma
variável, o computador copia o dado no endereço da variável.
A linguagem C permite o acesso aos endereços
das variáveis através dos ponteiros.
Um ponteiro é uma variável que armazena
Programação em C/C++
Ponteiros
Se o programador modifica o conteúdo apontado
por um ponteiro, ele modifica o conteúdo de uma variável indiretamente.
Um ponteiro é declarado definindo-se o tipo de
dado que ele aponta e seu nome precedido de ‘*’:
int *p; double *dptr; char *str; vetor3D *vptr;
Programação em C/C++
Ponteiros
Para acessar o dado apontado por um ponteiro,
basta colocar o operador conteúdo de memória ‘*’
na frente do ponteiro. Exemplo:
#include <stdio.h>
void main(void) {
unsigned dado = 10;
unsigned *dptr; /* ponteiro unsigned dptr */
dptr = &dado; /* recupera o endereco da variavel dado */
printf(“conteudo apontado por dptr: %d\n”,*dptr);
Programação em C/C++
Ponteiros
O ponteiro é uma variável como outra qualquer.
A diferença é que seu conteúdo é um endereço.
Os endereços de memória dependem da
arquitetura do computador.
Computadores de 64 bits geram endereços de 64
bits, ou seja, são do tipo unsigned long int.
Computadores de 32 bits geram endereços de 32
Programação em C/C++
Ponteiros
O endereço de memória pode ser impresso
usando o código de formatação ‘%p’.
#include <stdio.h>
void main(void) {
unsigned dado = 10;
unsigned *dptr; /* ponteiro unsigned dptr */
dptr = &dado; /* recupera o endereco da variavel dado */
printf(“dptr vale: %p\n”,dptr);
printf(“conteudo apontado por dptr: %d\n”,*dptr);
Programação em C/C++
Ponteiros
unsigned dado, *dptr; dado 0022ff48(h) 0022ff4c(h) dptrProgramação em C/C++
Ponteiros
unsigned dado, *dptr; dado = 10; /* = 0000000a(h) */ 00 00 00 dado 0022ff48(h) 0a 0022ff4c(h) dptrProgramação em C/C++
Ponteiros
unsigned dado, *dptr; dado = 10; /* = 0000000a(h) */ dptr = &dado; 00 00 48 00 dado 0022ff48(h) 0a ff 22 00 dptr 0022ff4c(h)Programação em C/C++
Ponteiros
unsigned dado, *dptr; dado = 10; /* = 0000000a(h) */ dptr = &dado; *dptr = 20;/* = 00000014(h) */ 00 00 48 00 dado 0022ff48(h) 14 ff 22 00 dptr 0022ff4c(h)Programação em C/C++
Ponteiros, Vetores e Matrizes
Os vetores e matrizes estão diretamente ligados
aos ponteiros.
O nome do vetor (matriz) é um ponteiro por
default. char nome[5]; memória endereço variável nome[0] 001a2c3f(h) = nome nome[1] nome[2] nome[3] nome[4]
Programação em C/C++
Ponteiros, Vetores e Matrizes
O nome do vetor (matriz) aponta para o endereço
base da lista de dados (elemento de índice 0).
char nome[5]; memória
endereço variável
nome[0] &nome[0] = 001a2c3f(h) = nome
nome[1] nome[2] nome[3]
Programação em C/C++
Ponteiros, Vetores e Matrizes
O endereço de cada elemento da lista é o
endereço base mais o produto entre o índice do
elemento e o comprimento em bytes do tipo da
lista.
char nome[4];
&nome[0] nome+0*sizeof(char) nome &nome[1] nome+1*sizeof(char)
Programação em C/C++
Ponteiros, Vetores e Matrizes
Mas a linguagem C simplifica a escrita e dispensa
o uso da instrução sizeof() para calcular o
endereço de um elemento da lista.
int v[30], *vptr;
vptr = v+1; /* vptr = &v[1] */ *vptr = 123; /* v[1] = 123; */ vptr = v+10; /* vptr = &v[10] */ *(v+4) = -345; /* v[4] = -345 */
Programação em C/C++
Ponteiros, Vetores e Matrizes
short t, list[3]; /*2 bytes*/ list[0] = -4; /*=0xfffc*/ list[1] = 10; /*=0x000a*/ list[2] = 1200;/*=0x04b0*/ t = *list; *list = *(list+1); *(list+1) = *(list+2); *(list+2) = t; fc ff 0a 00 b0 04 51 d4 e5 02 7c 11 f1 list[0] list[1] list[2] t list list+1 list+2
Programação em C/C++
Ponteiros, Vetores e Matrizes
short t, list[3]; /*2 bytes*/ list[0] = -4; /*=0xfffc*/ list[1] = 10; /*=0x000a*/ list[2] = 1200;/*=0x04b0*/ t = *list; *list = *(list+1); *(list+1) = *(list+2); *(list+2) = t; fc ff 0a 00 b0 04 51 d4 02 7c fc ff list[0] list[1] list[2] t list list+1 list+2
Programação em C/C++
Ponteiros, Vetores e Matrizes
short t, list[3]; /*2 bytes*/ list[0] = -4; /*=0xfffc*/ list[1] = 10; /*=0x000a*/ list[2] = 1200;/*=0x04b0*/ t = *list; *list = *(list+1); *(list+1) = *(list+2); *(list+2) = t; 0a 00 0a 00 b0 04 51 d4 e5 02 7c fc ff list[0] list[1] list[2] t list list+1 list+2
Programação em C/C++
Ponteiros, Vetores e Matrizes
short t, list[3]; /*2 bytes*/ list[0] = -4; /*=0xfffc*/ list[1] = 10; /*=0x000a*/ list[2] = 1200;/*=0x04b0*/ t = *list; *list = *(list+1); *(list+1) = *(list+2); *(list+2) = t; 0a 00 b0 04 b0 04 51 d4 02 7c fc ff list[0] list[1] list[2] t list list+1 list+2
Programação em C/C++
Ponteiros, Vetores e Matrizes
short t, list[3]; /*2 bytes*/ list[0] = -4; /*=0xfffc*/ list[1] = 10; /*=0x000a*/ list[2] = 1200;/*=0x04b0*/ t = *list; *list = *(list+1); *(list+1) = *(list+2); *(list+2) = t; 0a 00 b0 04 fc ff 51 d4 e5 02 7c fc ff list[0] list[1] list[2] t list list+1 list+2
Programação em C/C++
Ponteiros, Vetores e Matrizes
short t, list[3]; /*2 bytes*/ short *lptr; list[0] = -4; /*=0xfffc*/ list[1] = 10; /*=0x000a*/ list[2] = 1200;/*=0x04b0*/ t = *list; *list = *(list+1); *(list+1) = *(list+2); *(list+2) = t; 0a 00 b0 04 fc ff f7 24 02 7c fc ff list[0] list[1] list[2] t list list+1 list+2 0x006c24f5 lptr
Programação em C/C++
Ponteiros, Vetores e Matrizes
Vetores e matrizes podem ser alocados
dinamicamente usando ponteiros.
As funções em C que alocam memória para
vetores e matrizes são:
#include <stdlib.h>
void *calloc (unsigned n, unsigned bytes);
Programação em C/C++
Ponteiros, Vetores e Matrizes
Tanto o malloc quanto o calloc retornam o
endereço do primeiro byte da área de memória alocada.
Se não houver espaço de memória suficiente
para atender a alocação, ambas as funções
Programação em C/C++
Ponteiros, Vetores e Matrizes
Todo vetor e matriz alocado dinamicamente deve
ser desalocado (liberação da memória).
A função em C que libera a memória alocada
para vetores e matrizes dinâmicas é:
#include <stdlib.h>
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>void main(void) {
float irand_max = 1.0/RAND_MAX;
float *lista; /* ponteiro */ int i, j; /* contadores */
int dim; /* dimensao de lista */
srand(time(NULL));
for ( i=0; i<10; i++ ) {
printf ("Rodada %d\n",i);
/* 1<=dim<=100*/
printf("\tComprimento sorteado: %d\n",dim); lista = (float*)malloc(
dim*sizeof(float));
printf("\tEndereco de lista:%p\n", lista);
for ( j=0; j<dim; j++ ) {
lista[j] = rand()*irand_max; }
free(lista); }
Programação em C/C++
Ponteiros, Vetores e Matrizes
Uma matriz alocada dinamicamente segue a ideia
de vetor de vetores múltiplos.
Uma matriz bidimensional é um vetor de vetores,
um vetor de ponteiros.
Como o nome de um vetor é um ponteiro
também, um vetor de ponteiros é um ponteiro para ponteiros.
Programação em C/C++
Ponteiros, Vetores e Matrizes
Um ponteiro para ponteiro é declarado com dois
operadores ‘*’:
tipo **nome_matriz;
Exemplos:
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>void main(void) {
float irand_max = 1.0/RAND_MAX;
float **mat; /* ponteiro */ int i, j, k;/* contadores */
int l, c; /* dimensoes de mat */
srand(time(NULL));
for ( i=0; i<10; i++ ) {
printf ("Rodada %d\n",i);
/* 1<=dim<=100*/
printf("\tLinhas : %d\n",l);
printf("\tColunas: %d\n",c); mat = (float**)malloc(
l*sizeof(float*));
printf("\tEndereco de mat:%p\n", mat);
for ( j=0; j<l; j++ ) {
mat[j] = (float*)malloc(
c*sizeof(float)); for ( k=0; k<c; k++ ) { mat[j][k] = rand()*irand_max; } } for ( j=0; j<l; j++ ) free(mat[j]); free(mat);
Programação em C/C++
Funções
Na linguagem C, tudo é função.
Não existe uma declaração explicita para
subrotina.
O efeito de uma subrotina é criado pelo uso do
tipo void como retorno da função.
Programação em C/C++
Funções
Toda função declarada deve conter o comando
return, a menos que seja “subrotina”.
É boa prática de programação declarar os
protótipos das funções.
Um protótipo é a declaração de uma função
sem a codificação propriamente dita.
Não gera código e é usada exclusivamente
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h> /* prototipo da funcao sqr() */ float sqr(float n);void main(void) {
float a, b;
printf("Entre com um numero: "); scanf("%f",&a);
b = sqr(a);
printf("O quadrado deste numero eh"); printf(" %f\n",b);
/* implementacao da funcao sqr() */
float sqr(float n) {
return n*n; }
Programação em C/C++
Funções
A passagem de argumentos segue dois métodos
comuns para toda linguagem de programação:
passagem de parâmetro por valor
passagem de parâmetro por referência
Na passagem por valor, um dado externo à
função é copiado para dentro da função.
Neste caso, qualquer modificação no dado
Programação em C/C++
Funções
Na passagem por referência, não há cópia de
dado.
O dado externo é referenciado dentro da função
através de seu endereço, isto é, através de um
ponteiro.
Qualquer alteração no dado apontado pelo
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h>/* prototipos das funcoes */
float sqr(float n);
void sorteio(float *s);
void main(void) {
float a, b;
printf("Entre com um numero: "); scanf("%f",&a);
b = sqr(a);
printf("O quadrado deste numero eh "); printf("%f\n",b);
sorteio(&a);
/* implementacao da funcao sqr() */ /* passagem de argumento por valor */
float sqr(float n) {
n *= n; /* n = n*n; */
return n; }
/* implementacao da funcao sorteio() */ /* passagem de argumento por referencia*/
void sorteio(float *s) {
*s = rand()*1.0/RAND_MAX; }
Programação em C/C++
Entradas e Saídas Padrões
int printf(char *fmt, ...);
int sprintf(char *str, char *fmt, ...);
int scanf(char *fmt, ...);
Programação em C/C++
Arquivos
FILE *fopen(char *filename, char *mode);
int fprintf(FILE *stream, char *fmt, ...);
int fscanf(FILE *stream, char *fmt, ...);
int fread(void *ptr, int size, int cnt, FILE* stream);
int fwrite(void *ptr, int size, int cnt, FILE* stream);
int fclose(FILE *stream);
Programação em C/C++
Strings e Memória
void *memcpy(void *target, void *source, int size);
char *strcpy(char *target, char *source);
int memcmp(void *ptr1, void *ptr2, int size);
int strcmp(char *str1, char *str2);
Programação em C/C++
Diretivas de Compilação
As diretivas de compilação são destinadas ao
processo de compilação.
São reconhecidas somente pelo compilador.
Não geram código binário.
Auxiliam na estruturação do código fonte no que
diz respeito à portabilidade.
Programação em C/C++
Diretivas de Compilação: include
#include é usado para a inclusão de arquivos de
cabeçalho (header files).
Os arquivos de cabeçalho podem ser:
do sistema ( #include <arq.h> ) do usuário ( #include “arq.h” )
Os arquivos de cabeçalho do sistema estão num
Programação em C/C++
Diretivas de Compilação: include
Quando o arquivo de cabeçalho do usuário não
está no mesmo diretório do código fonte, deve-se incluir o caminho absoluto ou relativo na
declaração do #include.
Exemplo:
#include “c:\mingw\projetos\teste\meu_h.h” #include “/home/usuario/trabalho/outro_h.h” #include “../../source/header/mais_um_h.h”
Programação em C/C++
Diretivas de Compilação: define/undef
As diretivas #define são úteis para definir macros.
As macros funcionam como “estampas”,
“carimbos”.
Durante a compilação, as macros são
substituídas pelos códigos ou valores que representam.
Programação em C/C++
Diretivas de Compilação: define/undef
A diretiva #undef anula uma definição de macro.
Exemplos:
#define sqr(val) ((val)*(val)) #define Avogrado 6.02e23
#define TESTE #undef TESTE
Programação em C/C++
Diretivas de Compilação: if/else/elif/endif
A diretiva #if avalia o resultado de um teste lógico
e produz efeitos de compilação distintos dependendo do resultado.
As diretivas #else e #elif acompanham o #if
permitindo aternativas de compilação.
Programação em C/C++
Diretivas de Compilação: if/else/elif/endif
Exemplo:
#if defined(TESTE)
/* trecho de código se macro TESTE foi definida */ #else
/* trecho de código se macro TESTE não foi definida */
Programação em C/C++
Diretivas de Compilação: ifdef/ifndef/endif
As diretivas #ifdef e #ifndef são uma combinação
de #if defined (macro) e #if !defined (macro).
São muito úteis nos arquivos de cabeçalho para
evitar recompilação de código.
Exemplo:
#ifndef MEU_H_H #define MEU_H_H #include “meu_h.h”
Programação em C/C++
#ifndef TIPOS_H #define TIPOS_H typedef struct { double x, y, z; /* coords x, y, z */ } XYZ; typedef struct {double energia; /* energia em keV */
XYZ posicao; /* posicao do foton */
XYZ direcao; /* dir. de propagacao */
} foton;
typedef struct {
double energia, /* energia em keV*/
prob; /* probabilidade */
} espectro;
#include "tipos.h"
double Sortear_Valor(void);
double Sortear_Energia(espectro *lista,
int tam);
XYZ Sortear_Posicao(double foco);
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h> #include "tipos.h" #include "funcoes.h"double Sortear_Valor(void) {
return rand()/(double)RAND_MAX; }
double Sortear_Energia(espectro *lista,
int tam) {
double ene, /* energia sorteada */
eps; /* variavel auxiliar */
int i; /* contador */
for ( i=0; i<tam; i++ ) { if (lista[i].prob>=eps) { ene = lista[i].energia; break; } } return ene; }
XYZ Sortear_Posicao(double foco) { double raio, teta;
XYZ pos;
raio = 0.5*foco*Sortear_Valor(); teta = 2*M_PI*Sortear_Valor(); pos.x = raio*cos(teta);
Programação em C/C++
XYZ Sortear_Direcao(double abertura) { double teta, xsi;
XYZ dir;
teta = abertura*Sortear_Valor(); xsi = 2*M_PI*Sortear_Valor(); dir.x = sin(teta)*cos(xsi); dir.y = sin(teta)*sin(xsi); dir.z = cos(teta);
return dir; }
Programação em C/C++
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h> #include "funcoes.h"void main(int argc, char *argv[]) { int eventos = 10, tam;
int i;
double soma = 0, prob; foton hv; espectro *rx; FILE *fp,*fp1; if (argc > 1) { fp = fopen("espectro.txt","rt"); fscanf(fp,"%d",&tam); rx = (espectro *) malloc(tam*sizeof(espectro)); for ( i=0; i<tam; i++ ) {
fscanf(fp,"%lf",
&rx[i].energia); fscanf(fp,"%lf",&prob);
rx[i].prob = soma + prob; soma = rx[i].prob; #ifdef TESTE printf("Energia: %lf\t Prob. Acum: %lf\n", rx[i].energia,rx[i].prob); #endif } fclose(fp);
Programação em C/C++
#ifdef TESTE
fp = fopen("posicao.txt","wt"); fp1 = fopen("direcao.txt","wt"); #endif
for ( i=0; i<eventos; i++ ) {
hv.energia = Sortear_Energia(rx,tam); hv.posicao = Sortear_Posicao(1); hv.direcao = Sortear_Direcao(0.25*M_PI); #ifdef TESTE printf("Foton: energia= %7.3lf\n",hv.energia); printf(" posicao= (%7.3lf,%7.3lf,%7.3lf)\n", hv.posicao.x,hv.posicao.y, hv.posicao.z); printf(" direcao= (%7.3lf,%7.3lf,%7.3lf)\n", hv.direcao.x,hv.direcao.y, fprintf(fp,"%lf\t%lf\n", hv.posicao.x,hv.posicao.y); fprintf(fp1,"%lf\t%lf\t%lf\n", hv.direcao.x,hv.direcao.y, hv.direcao.z); #endif } #ifdef TESTE fclose(fp); fclose(fp1); #endif }
Programação em C/C++
Programação Orientada a Objeto
O que é esse paradigma?
Qual a grande diferença dos demais modelos?
O que muda na lógica de programação?
Programação em C/C++
Programação Orientada a Objeto
O paradigma (modelo) da programação orientada
a objeto está baseada na observação de que
algumas categorias de problemas podem ser
solucionadas através da adoção de elementos lógicos que englobam informações (dados) e
Programação em C/C++
Programação Orientada a Objeto
A solução propriamente dita é obtida através da
interação entre estes elementos lógicos.
O processo de interação entre os elementos
lógicos ocorre através de trocas de estímulos.
Computacionalmente, os elementos lógicos são
unidades de processamento de informação ou
unidades de execução e a troca de estímulos se
Programação em C/C++
Programação Orientada a Objeto
No jargão da programação orientada a objeto, a
unidade de execução é chamada de OBJETO.
Um programa orientado a objeto é uma coleção
de OBJETOS (unidades de execução) que colaboram entre si através de trocas de
MENSAGENS para que a solução computacional se concretize.
Programação em C/C++
Programação Orientada a Objeto
Todo OBJETO é uma materialização de um
modelo.
No jargão da programação orientada a objeto, um
modelo de objeto é chamado de CLASSE.
Um OBJETO é um INSTANCIAMENTO de uma
Programação em C/C++
Programação Orientada a Objeto
A capacidade de implementação de soluções
lógicas em programação orientada a objeto depende diretamente das propriedades das CLASSES e OBJETOS.
As CLASSES possuem três propriedades
básicas:
Encapsulamento Hereditariedade
Programação em C/C++
Programação Orientada a Objeto
A propriedade de encapsulamento é a mais
básica das três propriedades.
A programação orientada a objeto se baseia
naturalmente nesta propriedade.
Ela diz respeito a capacidade da unidade lógica
de programação de incluir na sua concepção o agrupamento de dados e ações numa única entidade.
Programação em C/C++
Programação Orientada a Objeto
Ou seja, uma classe encapsula atributos (dados)
e métodos (ações).
Sendo o objeto um instanciamento de uma
classe, ele transporta consigo os atributos e métodos encapsulados na classe.
Este encapsulamento pode organizar os atributos
e os métodos como públicos, protegidos e privados, chamados de visibilidade do
Programação em C/C++
Programação Orientada a Objeto
Os atributos e métodos públicos podem ser
acessados diretamente por outros objetos.
Os atributos e métodos protegidos e privados só
são acessados internamente.
Normalmente, os métodos de uma classe são
declarados como públicos e os atributos, como protegidos ou privados.
Programação em C/C++
Programação Orientada a Objeto
A propriedade de hereditariedade responde à
capacidade de uma classe de transmitir para classes descendentes o seu conteúdo
encapsulado, isto é, seus atributos e métodos públicos e protegidos.
Atributos e métodos privados só existem na
classe de objeto que as contêm.
Programação em C/C++
Programação Orientada a Objeto
A propriedade de herança também é um
mecanismo natural da programação orientada a objeto.
Esta propriedade permite que as classes se
organizem em diferentes níveis (categorias) de complexidade (especialização).
Uma classe pode tanto originar múltiplos
Programação em C/C++
Programação Orientada a Objeto
Os descendentes de uma classe podem
encapsular atributos e métodos próprios bem
como sobrescrever atributos e métodos herdados de seus ancestrais.
Exemplo:
Classe Radiação
Atributo Protegido Energia Método Público LerEnergia()
Programação em C/C++
Programação Orientada a Objeto
Exemplo:
Classe Radiação
Método Público LerEnergia(valor)
Energia ← valor
Fim
Método Público EscreverEnergia()
Programação em C/C++
Programação Orientada a Objeto
Exemplo:
Classe Partícula, descendente de Classe Radiação
Atributo Protegido Massa Método Público LerMassa()
Método Público EscreverMassa()
Classe Onda, descendente de Classe Radiação
Atributo Protegido Frequência Método Público LerFrequência()
Programação em C/C++
Programação Orientada a Objeto
Exemplo:
Objeto Elétron, instância de Classe Partícula Elétron.LerEnergia(E)
Elétron.LerMassa(m)
E ← Elétron.EscreverEnergia() m ← Elétron.EscreverMassa()
Programação em C/C++
Programação Orientada a Objeto
Exemplo:
Objeto Fóton, instância de Classe Onda Fóton.LerEnergia(E)
Fóton.LerFrequência(f)
E ← Fóton.EscreverEnergia() f ← Fóton.EscreverFrequência()
Programação em C/C++