Física Computacional
2011-2
I N T R O D U Ç Ã O À L Ó G I C A D E P R O G R A M A Ç Ã O
P R O F . L U Í S F E R N A N D O D E O L I V E I R A
UNIVERSIDADE DO ESTADO DO RIO DE JANEIRO INSTITUTO DE FÍSICA ARMANDO DIAS TAVARES
Funções e Subrotinas
A última característica da lógica de programação que falta ser apresentada é a estruturação.
A estruturação significa organizar a lógica da
programação em pequenos módulos que compartimentam ações a serem realizadas.
Não é raro que um determinado grupo de instruções tenha que ser repetido inúmeras vezes dentro de um mesmo algoritmo ou um mesmo procedimento em diferentes algoritmos.
Funções e Subrotinas
Um grupo de instruções que se repetem ao longo da lógica pode ser organizado em uma unidade própria de execução chamada procedimento.
Quando um procedimento retorna um resultado, ele é chamado de função.
Quando um procedimento não retorna resultado algum, ele é chamado de subrotina.
Funções e subrotinas podem estar organizadas em “bibliotecas” chamadas de módulos.
Funções e Subrotinas
Resumindo:
Um módulo é um conjunto de funções e subrotinas disponíveis
para serem utilizadas na lógica de programação.
Uma função é um conjunto de instruções que manipulam
dados, produzindo um resultado (informação) que deve
ser utilizado pelo algoritmo.
Uma subrotina é um conjunto de instruções que manipulam
dados, mas não geram um resultado específico para o algoritmo.
Funções e Subrotinas
Como identificar uma situação onde se aplica a criação de uma função ou subrotina?
Começamos olhando o algoritmo e verificando que conjunto de instruções se repetem com frequência. No exemplo do cálculo das médias dos alunos,
percebemos que o cálculo em si das médias sempre se repete:
média das provas média dos testes
média das atividades
Funções e Subrotinas
As médias são procedimentos similares.
Mudam os dados, mas a lógica é sempre a mesma. Média é média.
Então, o cálculo da média poderia ser um candidato a se transformar em função ou subrotina.
Agora, função ou subrotina?
A resposta depende do tipo de informação que é gerado.
No caso do cálculo da média, a média é a informação gerada.
Funções e Subrotinas
Então, este conjunto de instruções se enquadra na categoria de função.
Toda função, assim com subrotina, deve ter um nome que a identifique.
A escrita de uma função e de uma subrotina no algoritmo segue um padrão:
função <nome da função>(argumentos) fim função <nome da função>
subrotina <nome da subrotina>(argumentos) fim subrotina <nome da subrotina>
Funções e Subrotinas
No caso do cálculo da média, Média parece ser um bom nome, pois identifica corretamente o seu
propósito.
função Média(argumentos) {bloco de instruções} fim função Média
Funções e Subrotinas
Os argumentos funcionam como uma porta de entrada e saída de dados.
Eles fazem a comunicação entre o mundo exterior e interior da função e subrotina.
Entende-se como mundo exterior o algoritmo como um todo.
E aqui é importante falarmos dos tipos de passagem de argumento, isto é, mecanismos de comunicação. Primeiro, os argumentos de uma função ou subrotina
não são mais que variáveis locais.
Funções e Subrotinas
Estas variáveis são ditas locais, pois são declaradas dentro da função e subrotina e só existem dentro delas.
Elas desempenham um papel importantíssimo na comunicação do mundo exterior com o interior da função e subrotina.
Elas funcionam como se fossem uma janela espelhada pelo lado de fora.
E como toda boa janela, pode estar aberta ou fechada.
Funções e Subrotinas
Desta forma, a comunicação do interior da função e subrotina com o mundo exterior pode ser feita de duas formas (usando analogia):
ou a janela está fechada e o máximo que dá para fazer é ler o que está fora e copiar para dentro da função e subrotina e o que está fora não acessa o que esta dentro,
ou a janela está aberta e o que está fora é acessado diretamente de dentro da função e subrotina e vice-versa.
Os efeitos são distintos em cada um dos casos.
Funções e Subrotinas
Se a janela é espelhada por fora e está fechada, quem está dentro da função e subrotina vê o que está fora, mas não pode tocá-la.
Quem está dentro pode apenas copiar a informação que passar pela janela pelo lado de fora.
As informações que entram são nossos argumentos. Como as informações dentro da função e subrotina
são cópias neste caso, podemos modificá-las que nada mudará do lado de fora, no mundo exterior.
Funções e Subrotinas
Isto é o que se chama de passagem de parâmetros (ou passagem de argumentos) por cópia de valor. Os dados são apenas copiados para a função e
subrotina.
O que for feito com estas cópias não afetará os dados originais fora da função e da subrotina.
Funções e Subrotinas
A outra situação é a da janela aberta.
Neste caso, as informações que forem apresentadas diante da janela poderão ser acessadas diretamente. Isto significa que se uma determinada informação
for modificada dentro da função ou subrotina, esta modificação será percebida fora, no mundo exterior. Este tipo de comunicação, de passagem de
argumentos, se chama passagem de parâmetros (ou argumentos) por referência.
Funções e Subrotinas
Quem faz o papel da janela são as variáveis locais
declaradas como argumentos da função e subrotina. Como as variáveis devem ter uma natureza, isto
implica que somente dados dos mesmos tipos das variáveis podem passar como argumentos.
Seguindo o padrão de escrita das funções e
subrotinas, as variáveis no papel de argumentos devem ser declaradas no interior da função e
subrotina.
Funções e Subrotinas
Exemplo: função Minha_Função(a, b, c) declare a numérico declare b literal declare c lógico{variáveis locais que não sejam argumentos} {bloco de instruções}
fim função Minha_Função
Repare que as variáveis que comprem o papel de argumento são declaradas dentro da função.
Funções e Subrotinas
Exemplo: subrotina Minha_Subrotina(x, y, z) declare x numérico declare y numérico declare z numérico{variáveis locais que não sejam argumentos} {bloco de instruções}
fim subrotina Minha_Subrotina
Novamente, as variáveis que são argumentos são declaradas dentro da subrotina.
Funções e Subrotinas
As funções e subrotinas podem declarar um número ilimitado de variáveis como argumento.
Podem também não declarar nenhuma. Exemplo:
subrotina Desligar( )
{variáveis locais que não sejam argumentos} {bloco de instruções}
fim subrotina Desligar
Esta subrotina não faria nada além de desligar um equipamento.
Funções e Subrotinas
A diferença entre função e subrotina é o retorno de um resultado.
Por isso, a função deve apresentar em algum lugar do seu bloco de instruções o comando “retorne alguma coisa”.
Exemplo:
função Func1(p)
declare p numérico retorne 2*p
fim função Func1
Funções e Subrotinas
O comando retorne devolve ao mundo exterior o resultado da expressão que o acompanha.
A informação retornada pela função deve ser
atribuída a alguma variável ou deve fazer parte de uma expressão.
Exemplo:
Considere o último exemplo (função Func1). O argumento é uma variável numérica.
A invocação desta função poderia ser implementada da seguinte forma:
a Func1(10)
Funções e Subrotinas
A constante numérica 10 ocupa o lugar do argumento p. Logo, o valor da constante será copiada para a variável p.
A função Func1 retorna um resultado que é a multiplicação do conteúdo de p pela constante numérica 2.
O valor retornado por Func1(10) é então atribuído à variável a.
Como uma subrotina não retorna valor algum, não se usa o comando retorne.
Por outro lado, subrotina (e função também) pode receber/retornar valores através da passagem de parâmetros por referência.
Funções e Subrotinas
Para indicar quando uma variável de argumento é usada no modo cópia ou referência, é necessário adotar um padrão de indicação:
se o argumento for usado no modo cópia de valor, adotaremos o padrão: declare <variável> <tipo> por valor;
se o argumento for usado no modo referência, adotaremos o padrão: declare <variável> <tipo> por referência.
Exemplo:
função Func1(p)
declare p numérico por valor retorne 2*p
fim função Func1
Funções e Subrotinas
Exemplo usando subrotina
subrotina Subrot1(a)
declare a literal por referência a „x‟
fim subrotina Subrot1
Neste exemplo, modificar o conteúdo do argumento
a significa modificar o conteúdo da variável externa.
Exemplo:
c „s‟
Subrot1(c) {sobrescreve o conteúdo de c com „x‟} escreva “o conteúdo de c é ”, c {imprimirá „x‟}
Funções e Subrotinas
A variável c foi inicializada com o valor „s‟.
Na execução da subrotina Subrot1, o conteúdo de c foi alterado, sobrescrevendo-se „s‟ com „x‟.
Isso acontece porque o argumento a referencia a variável externa c no momento de sua execução.
Os argumentos das funções e subrotinas podem ser de qualquer um dos tipos de dados apresentados até agora: numéricos, literais, lógicos, estruturas
homogêneas (listas e matrizes) e heterogêneas (registros).
Funções e Subrotinas
No caso de listas (vetores) e matrizes, é importante que os tamanhos sejam passados.
Para que não haja erro de lógica na leitura do
algoritmo, é importante que as dimensões das listas e matrizes declaradas como argumentos por cópia de valor sejam do mesmo tamanho ou maiores que os dados originais (versões externas).
Para o caso de argumentos passados por referência, as dimensões não precisam ser declaradas,
deixando-se somente os colchetes vazios.
Mas a quantidade de dados ainda é necessário.
Funções e Subrotinas
função Média(tam,vet)declare tam numérico por valor
declare vet[100] numérico por valor declare i, sum numérico
sum 0
para i de 1 até tam, faça sum sum+vet[i] fim para
sum sum/tam retorne sum
fim função Média
Funções e Subrotinas
subrotina Ordenação(l,a)declare l numérico por valor declare a[] literal por referência declare i, j numérico
declare tmp literal para i de 1 até l-1, faça para j de i+1 até l, faça se (a[j]<a[i]), então tmp a[i] a[i] a[j] a[j] tmp fim se {continua} fim para fim para
fim subrotina Ordenação
Funções e Subrotinas
Lembrando, qualquer tipo de informação pode ser passado para uma função ou subrotina.
Além disso, estas informações podem ser passadas como cópia ou por referência.
A decisão pelo mecanismo de passagem de
argumentos depende do objetivo da função ou subrotina.
Se a informação que está sendo passado para a função ou subrotina tiver que ser processada e o
processamento tiver que refletir no código externo, então, a passagem de argumentos é por referência.
Funções e Subrotinas
A passagem de parâmetros por referência é muito comum nas subrotinas e é raramente usada nas funções.
As funções podem retornar qualquer tipo de
informação, mas somente uma unidade de dado.
Isto significa que uma função não pode retornar dois ou mais dados separadamente.
Se este for o caso, é mais interessante criar-se um registro que agrupe os diferentes tipos de dados e retornar-se o registro em si.
Funções e Subrotinas
Exemplo
Imagine que um programador tenha que mudar a
representação de coordenadas espaciais de um determinado dado de cartesiano para polar.
A coordenada cartesiana é representada pela combinação de dois parâmetros: x e y.
A coordenada polar também é representada por um par de ordenadas: comprimento e ângulo, r e teta.
As coordenadas são unidades de informação compostas por dois parâmetros cada.
Uma função não pode retornar dois dados, mas pode retornar um registro que combine ambas.
Funções e Subrotinas
Então, uma solução seria criar-se um registro chamado
coordenada_cartesiana e outro chamado coordenada_polar. defina coordenada_cartesiana registro (x, y numéricos)
defina coordenada_polar registro (r, teta numéricos)
Depois declarar-se duas variáveis de cada tipo de registro. declare cdado registro coordenada_cartesiana
declare pdado registro coordenada_polar
Agora, podemos pensar na estrutura da função que converte uma representação em outra.
r raiz(x*x + y*y) teta arcotangente(y/x)
admitindo que a função arcotangente retorne um ângulo em graus.
Funções e Subrotinas
Só que temos um problema, a função trigonométrica
arcotangente só retorna a informação correta do ângulo para ângulos no 1º e no 4º quadrantes.
Ângulos no 2º e no 3º quadrantes precisam ser calculados corretamente. 32 y x y x teta teta
Funções e Subrotinas
Para produzirmos a conversão correta, devemos identificar o quadrante: se for o 2º quadrante, o resultado da função
arcotangente deve ser acrescido de 180 (se o resultado está em graus); se for o 3º quadrante, o resultado deve ser subtraído de 180.
Estes procedimentos simples corrigirão os resultados da transformação de coordenadas:
se (y>0 e x<0), então
teta arcotangente(y/x) + 180 senão se (y<0 e x<0), então
teta arcotangente(y/x) - 180 fim se
Funções e Subrotinas
Agora, vamos escrever o algoritmo da função. A função pode se chamar Conversão_para_Polar. O argumento é um registro coordenada_cartesiana. A função retorna um registro coordenada_polar. A passagem de argumento é por cópia de valor. Vejamos uma possível solução:
Funções e Subrotinas
função Conversão_para_Polar(cart)declare cart registro coordenada_cartesiana por valor declare polar registro coordenada_polar
polar.r raiz(cart.x**2 + cart.y**2)
polar.teta arcotangente(cart.y/cart.x)
se (cart.y>0 e cart.x<0), então
polar.teta polar.teta + 180
senão se (cart.y<0 e cart.x<0), então
polar.teta polar.teta - 180
fim se
retorne polar
fim função Conversão_para_Polar
Funções e Subrotinas
Vejamos também, um exemplo onde a funçãoConversão_para_Polar seja usada:
algoritmo
defina coordenada_cartesiana registro (x, y numéricos) defina coordenda_polar registro (r, teta numéricos) declare c registro coordenada_cartesiana
declare p registro coordenada_polar
c.x 1
c.y 1
p Conversão_para_Polar(c)
escreva “Ponto ”,c.x, “,”, c.y, “ convertido vale ”,p.r, “,”, p.teta
fim algoritmo