Me todos Computacionais em Fı sica Sandra Amato Instituto de Fı sica Universidade Federal do Rio de Janeiro Segundo Semestre de 2017
Estrutura de um Programa Estrutura dos programas feitos ate agora Entrada de Dados Soluc a o do Problema Impressa o do Resultado Algoritmo de Leitura Algoritmo p/ o Problema Algoritmo de Saı da
Estrutura de um Programa Estrutura dos programas feitos ate agora Entrada de Dados Soluc a o do Problema Impressa o do Resultado Algoritmo de Leitura Algoritmos p/ o Problema Algoritmo de Saı da Quando os programas se tornam mais complexos e necessa rio dividir o algoritmo em partes, que sera o tratadas separadamente. Estrutura modular
do Programa Como modularizar? 1- Dividir um problema complexo em va rios problemas simples, dividindo o programa em partes que realizem tarefas especı ficas e razoavelmente independentes. 2- Identificar e usar soluc o es ja existentes. 3- Identificar tarefas especı ficas que sera o usadas frequentemente ao longo do programa e desenvolver uma soluc a o gene rica (func o es ou macros) para executa -la. 4- lembrando que o co digo deve ser: 8 legı vel identado, documentado comenta rios, identificadores 8 sucinto Simples, sem ca lculos desnecessa rios 8 eficiente
do Programa Como modularizar? 1- Dividir um problema complexo em va rios problemas simples, dividindo o programa em partes que realizem tarefas especı ficas e razoavelmente independentes. 2- Identificar e usar soluc o es ja existentes. 3- Identificar tarefas especı ficas que sera o usadas frequentemente ao longo do programa e desenvolver uma soluc a o gene rica (func o es ou macros) para executa -la. 4- lembrando que o co digo deve ser: 8 legı vel identado, documentado comenta rios, identificadores 8 sucinto Simples, sem ca lculos desnecessa rios 8 eficiente 8 correto!
do Programa Como modularizar? 1- Dividir um problema complexo em va rios problemas simples, dividindo o programa em partes que realizem tarefas especı ficas e razoavelmente independentes. 2- Identificar e usar soluc o es ja existentes. 3- Identificar tarefas especı ficas que sera o usadas frequentemente ao longo do programa e desenvolver uma soluc a o gene rica (func o es ou macros) para executa -la. 4- lembrando que o co digo deve ser, em ordem de releva ncia: 8 8 8 8 correto! legı vel sucinto eficiente
Vantagens desse procedimento 8 simplifica a elaborac a o e manutenc a o do co digo (erros) 8 permite escrever func o es gene ricas (uso diversificado) 8 facilita o trabalho em equipe, com diferentes grupos trabalhando em cada mo dulo independentemente. 8 Os erros sa o mais facilmente detetados
Vantagens desse procedimento 8 simplifica a elaborac a o e manutenc a o do co digo (erros) 8 permite escrever func o es gene ricas (uso diversificado) 8 facilita o trabalho em equipe, com diferentes grupos trabalhando em cada mo dulo independentemente. 8 Os erros sa o mais facilmente detetados em c:
Vantagens desse procedimento 8 simplifica a elaborac a o e manutenc a o do co digo (erros) 8 permite escrever func o es gene ricas (uso diversificado) 8 facilita o trabalho em equipe, com diferentes grupos trabalhando em cada mo dulo independentemente. 8 Os erros sa o mais facilmente detetados em c:
em C Ü Ja utilizamos va rias func o es da biblioteca padra o de entrada e saı da ou matema tica: scanf, printf, cos, sqrt...
em C Ü Ja utilizamos va rias func o es da biblioteca padra o de entrada e saı da ou matema tica: scanf, printf, cos, sqrt... Ü Tambe m construı mos uma func a o: main
em C Ü Ja utilizamos va rias func o es da biblioteca padra o de entrada e saı da ou matema tica: scanf, printf, cos, sqrt... Ü Tambe m construı mos uma func a o: main Ü Podemos criar outras func o es. A Sintaxe e :
em C Ü Ja utilizamos va rias func o es da biblioteca padra o de entrada e saı da ou matema tica: scanf, printf, cos, sqrt... Ü Tambe m construı mos uma func a o: main Ü Podemos criar outras func o es. A Sintaxe e : tipo nome (tipo1 arg1, tipo2 arg2,...){ linhas de co digo return valor; } Exemplo: double energiacinetica ( double m, double v ) { double resultado = 1./2 * m * v * v ; return resultado; }
em C Ü Ja utilizamos va rias func o es da biblioteca padra o de entrada e saı da ou matema tica: scanf, printf, cos, sqrt... Ü Tambe m construı mos uma func a o: main Ü Podemos criar outras func o es. A Sintaxe e : tipo nome (tipo1 arg1, tipo2 arg2,...){ linhas de co digo return valor; } Exemplo: double energiacinetica ( double m, double v ) { double resultado = 1./2 * m * v * v ; return resultado; } Ü Abra o programa fat.c
Usando - Exemplo #include <stdio.h> double fatorial(int n); /*prototipo da funcao */ int main() { double nfatorial; int n; n=5; nfatorial = fatorial(n); printf("%d! = %6.2f\n",n,nfatorial); return 0; } double fatorial(int n){ int i; double fat; if (n==0 n==1) return 1.0; fat = n; for (i = 2; i < n; i++) fat = fat * i; return fat; }
Proto tipo de uma Func a o Ü Uma func a o, como qualquer identificador, so pode ser utilizada depois de ser declarada.
Proto tipo de uma Func a o Ü Uma func a o, como qualquer identificador, so pode ser utilizada depois de ser declarada. Ü A declarac a o e feita atrave s da apresentac a o do proto tipo da func a o: tipo nome (tipo1 var1, tipo2 var2,...);
Proto tipo de uma Func a o Ü Uma func a o, como qualquer identificador, so pode ser utilizada depois de ser declarada. Ü A declarac a o e feita atrave s da apresentac a o do proto tipo da func a o: tipo nome (tipo1 var1, tipo2 var2,...); Ü Normalmente as declarac o es ficam no comec o do arquivo, antes de main().
Proto tipo de uma Func a o Ü Uma func a o, como qualquer identificador, so pode ser utilizada depois de ser declarada. Ü A declarac a o e feita atrave s da apresentac a o do proto tipo da func a o: tipo nome (tipo1 var1, tipo2 var2,...); Ü Normalmente as declarac o es ficam no comec o do arquivo, antes de main(). Ü Como para as demais declarac o es, os proto tipos sa o necessa rios para o compilador conferir se o uso da func a o esta correto. Ex: double sin( double x ); // prototipo double x, y; y = sin(x); Ü A implementac a o pode ser feita em outra parte do programa ou em outro arquivo
Usando - Como funciona 8 Ao chegar na chamada da func a o, a execuc a o da func a o atual, por ex., main, e interrompida.
Usando - Como funciona 8 Ao chegar na chamada da func a o, a execuc a o da func a o atual, por ex., main, e interrompida. 8 O valor do argumento, quando este existe, e passado para a func a o, que executa suas linhas de comando ate encontrar um return.
Usando - Como funciona 8 Ao chegar na chamada da func a o, a execuc a o da func a o atual, por ex., main, e interrompida. 8 O valor do argumento, quando este existe, e passado para a func a o, que executa suas linhas de comando ate encontrar um return. 8 A execuc a o da func a o e terminada e o valor calculado, quando for o caso, e retornado ao programa que chamou a func a o.
Usando - Como funciona 8 Ao chegar na chamada da func a o, a execuc a o da func a o atual, por ex., main, e interrompida. 8 O valor do argumento, quando este existe, e passado para a func a o, que executa suas linhas de comando ate encontrar um return. 8 A execuc a o da func a o e terminada e o valor calculado, quando for o caso, e retornado ao programa que chamou a func a o. 8 Observe que pode haver mais de um return.
Usando - Como funciona 8 Ao chegar na chamada da func a o, a execuc a o da func a o atual, por ex., main, e interrompida. 8 O valor do argumento, quando este existe, e passado para a func a o, que executa suas linhas de comando ate encontrar um return. 8 A execuc a o da func a o e terminada e o valor calculado, quando for o caso, e retornado ao programa que chamou a func a o. 8 Observe que pode haver mais de um return. 8 A implementac a o da func a o pode aparecer em qualquer ordem dentro de um arquivo, mesmo antes de main, ou em arquivo separado, mas na o pode ser definida dentro de outra func a o.
Tipos de Ü em C podem retornar qualquer tipo de varia vel (int, float, double), menos arrays ou func o es.
Tipos de Ü em C podem retornar qualquer tipo de varia vel (int, float, double), menos arrays ou func o es. Ü A expressa o apo s o return deve ser do tipo da func a o.
Tipos de Ü em C podem retornar qualquer tipo de varia vel (int, float, double), menos arrays ou func o es. Ü A expressa o apo s o return deve ser do tipo da func a o. Ü Podem na o retornar nada. Neste caso o tipo e void void saudacao(int codigo){ if(codigo==10)printf( Bom dia! ); if(codigo==20)printf( Boa noite! ); return; }
Argumentos de 8 Os nomes das varia veis na definic a o (proto tipo) e na implementac a o da func a o sa o so refere ncias. proto tipo: double energiacinetica ( double massa, double velocidade ); ou simplesmente double energiacinetica ( double, double ); implementac a o: double energiacinetica ( double m, double v ) {... } 8 Ao usarmos a func a o, colocamos os argumentos definidos no programa que chama a func a o double K = energiacinetica(m1,v1); chamada da func a o 8 E necessa rio respeitar a ordem dos argumentos nos 3 (proto tipo, chamada, implementac a o). Veja o programa energia.c
Passagem por Valor Em C na o e a varia vel que e passada a func a o, mas sim o seu valor #include <stdio.h> double fatorial (int n); int main(){ double nfatorial; int n=5; nfatorial = fatorial(n); printf ("O fatorial de %d eh %lf\n",n, nfatorial) return 0; } double fatorial (int n){ double fat = 1.0; for ( ; n > 1; n--) fat = fat * n; return fat; } O valor de n foi alterado na func a o fatorial, mas na o em main.
Exercı cio Escreva um programa que calcule a me dia aritme tica entre dois nu meros reais lido do teclado. O ca lculo da me dia deve ser feito atrave s de uma func a o.
Passagem de Array Para um array, o que e passado e o enderec o do inı cio do vetor.
Passagem de Array Para um array, o que e passado e o enderec o do inı cio do vetor. Neste caso, ao alterar o array na func a o, o valor em main tambe m e alterado. void inicializa (double a[], int m); int main() { const int n=10; double r[n];... inicializa(r, n);... } void inicializa (double v[], int d){ int i; for (i = 0; i < d; i++) v[i] = i; }
Passagem de Array Para um array, o que e passado e o enderec o do inı cio do vetor. Neste caso, ao alterar o array na func a o, o valor em main tambe m e alterado. void inicializa (double a[], int m); int main() { const int n=10; double r[n];... inicializa(r, n);... } void inicializa (double v[], int d){ int i; for (i = 0; i < d; i++) v[i] = i; } Analise o programa farray.c
Exercı cio Modifique o seu programa que calcula o produto escalar entre dois vetores para usar func a o. O produto escalar e o mo dulo de um vetor devem ser calculados em duas func o es separadamente.
Func a o como Argumento Ü Uma func a o pode ter como argumento uma outra func a o.
Func a o como Argumento Ü Uma func a o pode ter como argumento uma outra func a o. Ü Exemplo de proto tipo void tabela( double xi, double xf, double dx, double (*f)( double x ) );
Func a o como Argumento Ü Uma func a o pode ter como argumento uma outra func a o. Ü Exemplo de proto tipo void tabela( double xi, double xf, double dx, double (*f)( double x ) ); Ü o asterisco indica que estamos fornecendo o enderec o (ponteiro) da func a o. Ü na o se esquec a dos pare nteses
Func a o como Argumento Ü Uma func a o pode ter como argumento uma outra func a o. Ü Exemplo de proto tipo void tabela( double xi, double xf, double dx, double (*f)( double x ) ); Ü o asterisco indica que estamos fornecendo o enderec o (ponteiro) da func a o. Ü na o se esquec a dos pare nteses Ü no programa, f pode ser substituı do por qualquer func a o double, de bibliotecas ou definida pelo usua rio, que tenha um argumento do tipo double.
Func a o como Argumento Ü Uma func a o pode ter como argumento uma outra func a o. Ü Exemplo de proto tipo void tabela( double xi, double xf, double dx, double (*f)( double x ) ); Ü o asterisco indica que estamos fornecendo o enderec o (ponteiro) da func a o. Ü na o se esquec a dos pare nteses Ü no programa, f pode ser substituı do por qualquer func a o double, de bibliotecas ou definida pelo usua rio, que tenha um argumento do tipo double. tabela(1.0,16.0,1.0,sqrt);
Func a o como Argumento Ü Uma func a o pode ter como argumento uma outra func a o. Ü Exemplo de proto tipo void tabela( double xi, double xf, double dx, double (*f)( double x ) ); Ü o asterisco indica que estamos fornecendo o enderec o (ponteiro) da func a o. Ü na o se esquec a dos pare nteses Ü no programa, f pode ser substituı do por qualquer func a o double, de bibliotecas ou definida pelo usua rio, que tenha um argumento do tipo double. tabela(1.0,16.0,1.0,sqrt); tabela(1.0,16.0,1.0,minhafuncao);
Func a o como Argumento - um Exemplo void tabela( double xi, double xf, double dx, double (*f)( double x ) ); main {... tabela(1.0,16.0,1.0,sqrt);... } void tabela( double xi, double xf, double dx, double (*f)(double x )){ double x; for(x=xi; x<=xf; x = x + dx) printf("%.5f %.5f\n",x,f(x)); return; } Analise o programa tabela.c
e durac a o de Varia veis de uma varia vel: a regia o do co digo em que uma varia vel e acessı vel 8 Varia veis locais - criadas dentro de uma func a o e so sa o vistas dentro dela. 8 Varia veis globais - criadas fora das func o es e sa o vistas em qualquer ponto do programa a partir de sua declarac a o.
de Varia veis Locais Quando uma varia vel e criada dentro de uma func a o ela so e vista em seu interior, e uma varia vel local. Existem dois tipos de varia veis locais: 8 automa ticas: elas deixam de existir quando a execuc a o da func a o e terminada. 8 esta ticas: o seu valor e preservado, mas tambe m so sa o acessı veis a func a o onde foram definidas. Sintaxe: static int n = 0; Veja o programa contar.c 8 A criac a o de varia veis esta ticas e feita em tempo de compilac a o e deve-se inicializa -la na hora da declarac a o
de Varia veis Globais E possı vel definir varia veis que sejam acessı veis por va rias func o es, as varia veis globais 7 Sa o definidas fora (antes ou entre) das func o es 7 Sa o varia veis esta ticas permanecem na memo ria durante toda a execuc a o do programa. 7 Sa o acessı veis do ponto da declarac a o ate o fim do arquivo. Sa o vistas por todas as func o es definidas fisicamente abaixo delas. 7 E uma maneira pra tica de fazer com que func o es diferentes compartilhem a mesma varia vel. 7 Sa o inimigas da modularizac a o! 7 Cuidado com o uso! Uma func a o pode alterar o valor de uma varia vel global por engano. 7 Ao definir uma varia vel como global, pergunte-se por que isto e necessa rio!
Analise o programa var global.c: #include <stdio.h> int soma (int n); int j = 5; main(){ int i = 1; printf ("j = %d\n", j); printf ("k = %d\n", k); // Erro: k ainda nao declarada printf ("l = %d\n", l); // Erro: l e local em soma() printf ("i+j+k+l = %d\n", soma(i)); } int k = 10; int soma(int n){ int l = 4; return n+j+k+l; }
Pre-processador 8 O primeiro passo antes da compilac a o propriamente dita pre-processamento Compilac a o Linkagem 8 Arquivos de cabec alho sa o incluı dos. #include <xxx.h> 8 simbo licas e macros sa o substituı das. #define ZZZ (veja a seguir) 8 A saı da ainda e um arquivo texto, passado ao compilador. Em geral na o estamos interessados neste arquivo...
Simbo licas 8 Frequentemente usamos o mesmo valor em diversas partes do programa. E conveniente usarmos as constantes simbo licas Ex.: #define VSOM 340.0
Simbo licas 8 Frequentemente usamos o mesmo valor em diversas partes do programa. E conveniente usarmos as constantes simbo licas Ex.: #define VSOM 340.0 8 Sempre que VSOM for encontrado, ele sera substituı do por 340.0 pelo pre -processador
Simbo licas 8 Frequentemente usamos o mesmo valor em diversas partes do programa. E conveniente usarmos as constantes simbo licas Ex.: #define VSOM 340.0 8 Sempre que VSOM for encontrado, ele sera substituı do por 340.0 pelo pre -processador 8 Exemplo... #define NDIM 3 int main(){ double r[ndim];... for(i=0, i<ndim,i++) r[i]=i*i;...
Se a func a o puder ser escrita em uma so linha podemos usar MACROS do pre -processador #define F(x) (5*(cos((x)*(x)-1.)-1./2)) Sempre que um F(y) for encontrado, ele sera substituı do por (5*(cos((y)*(y)-1.)-1./2)) pelo pre -processador y pode ser um nu mero, uma varia vel ou uma expressa o mais complexa. E mais eficiente e simples do que usar uma func a o propriamente dita!
Se a func a o puder ser escrita em uma so linha podemos usar MACROS do pre -processador #define F(x) (5*(cos((x)*(x)-1.)-1./2)) Sempre que um F(y) for encontrado, ele sera substituı do por (5*(cos((y)*(y)-1.)-1./2)) pelo pre -processador y pode ser um nu mero, uma varia vel ou uma expressa o mais complexa. E mais eficiente e simples do que usar uma func a o propriamente dita! Mas cuidado com a definic a o de macros!
Exemplos de #include <stdio.h> #define SQR(x) ((x)*(x)) #define CUBE(a) ((a)*(a)*(a)) #define SOMA(x,y) x+y // Definicao errada #define MAXIMO(x,y) (((x) > (y))? #define MINIMO(x,y) (((x) < (y))? (x) : (x) : (y)) (y)) (Veja o programa macros.c. Defina SOMA(x,y) corretamente)
Exemplos de #include <stdio.h> #define SQR(x) ((x)*(x)) #define CUBE(a) ((a)*(a)*(a)) #define SOMA(x,y) x+y // Definicao errada #define MAXIMO(x,y) (((x) > (y))? #define MINIMO(x,y) (((x) < (y))? (x) : (x) : (y)) (y)) int main(){ double a = -5.0, b = 10.0; printf("sqr(a) = %f\n", SQR(a)); printf("cube(-3) = %d\n", CUBE(-3)); printf("maximo(a,b) = %f\n", MAXIMO(a,b)); printf("minimo(a,b) = %f\n", MINIMO(a,b)); printf("dobro de a+b = %f\n", 2*SOMA(a,b));//Errado return 0; } (Veja o programa macros.c. Defina SOMA(x,y) corretamente)
Exemplos de #include <stdio.h> #define SQR(x) ((x)*(x)) #define CUBE(a) ((a)*(a)*(a)) #define SOMA(x,y) x+y // Definicao errada #define MAXIMO(x,y) (((x) > (y))? #define MINIMO(x,y) (((x) < (y))? (x) : (x) : (y)) (y)) int main(){ double a = -5.0, b = 10.0; printf("sqr(a) = %f\n", SQR(a)); printf("cube(-3) = %d\n", CUBE(-3)); printf("maximo(a,b) = %f\n", MAXIMO(a,b)); printf("minimo(a,b) = %f\n", MINIMO(a,b)); printf("dobro de a+b = %f\n", 2*SOMA(a,b));//Errado return 0; } SQR(a) = 25.0 CUBE(3) = -27 MAXIMO(a,b) = 10.0 MINIMO(a,b) = -5.0 2*SOMA(a,b) = 0.0 (e na o 10.0!) (Veja o programa macros.c. Defina SOMA(x,y) corretamente)
Exercı cio 8 Refac a o programa que calcula a raiz de uma func a o pelo me todo de Newton-Raphson de forma a usar func o es. 8 Veja os detalhes no arquivo Tarefa8.pdf
raiz.c #include <stdio.h> #include <math.h> double f1( double x ); double df1( double x ); double NewtonRaphson( double xini, double (*f)(double), double (*df)(double), double precisao, int maxloop); int npassos=0; int main() { double x_min; /* aproximacao inicial da raiz */ double raizn,precisao=1e-7; int maxloop = 100; /* numero maximo de tentativas */ int npn; printf ("----> eˆ(-x) - sin(pi*x/2) \n"); printf ("Entre com o valor inicial para o calculo da raiz:\n "); scanf ("%lf", &x_min); // Metodo de Newton-Raphson raizn = NewtonRaphson ( x_min, f1, df1, precisao, maxloop ); npn = npassos; printf (" A raiz encontrada pelo metodo de NR foi: %10.8f\n", raizn ); printf (" com %d tentativas \n",npn); return; } double NewtonRaphson (double x_ini, double (*f)(double), double (*derf)(double), double precisao, int maxloop) {.. } double f1 (double x) {... } double df1 (double x) {... }