Fortran - Procedimentos

UMA procedureé um grupo de instruções que executam uma tarefa bem definida e podem ser chamadas de seu programa. Informações (ou dados) são passados ​​para o programa de chamada, para o procedimento como argumentos.

Existem dois tipos de procedimentos -

  • Functions
  • Subroutines

Função

Uma função é um procedimento que retorna uma única quantidade. Uma função não deve modificar seus argumentos.

A quantidade devolvida é conhecida como function value, e é denotado pelo nome da função.

Syntax

A sintaxe para uma função é a seguinte -

function name(arg1, arg2, ....)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

O exemplo a seguir demonstra uma função chamada area_of_circle. Ele calcula a área de um círculo com raio r.

program calling_func

   real :: a
   a = area_of_circle(2.0) 
   
   Print *, "The area of a circle with radius 2.0 is"
   Print *, a
   
end program calling_func


! this function computes the area of a circle with radius r  
function area_of_circle (r)  

! function result     
implicit none      

   ! dummy arguments        
   real :: area_of_circle   
   
   ! local variables 
   real :: r     
   real :: pi
   
   pi = 4 * atan (1.0)     
   area_of_circle = pi * r**2  
   
end function area_of_circle

Quando você compila e executa o programa acima, ele produz o seguinte resultado -

The area of a circle with radius 2.0 is
   12.5663710

Observe que -

  • Você deve especificar implicit none tanto no programa principal quanto no procedimento.

  • O argumento r na função chamada é chamado dummy argument.

O resultado Opção

Se você quiser que o valor retornado seja armazenado em algum outro nome que não o nome da função, você pode usar o result opção.

Você pode especificar o nome da variável de retorno como -

function name(arg1, arg2, ....) result (return_var_name)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

Subrotina

Uma sub-rotina não retorna um valor, mas pode modificar seus argumentos.

Syntax

subroutine name(arg1, arg2, ....)    
   [declarations, including those for the arguments]    
   [executable statements]  
end subroutine [name]

Chamando uma subrotina

Você precisa invocar uma sub-rotina usando o call declaração.

O exemplo a seguir demonstra a definição e o uso de uma troca de sub-rotina, que altera os valores de seus argumentos.

program calling_func
implicit none

   real :: a, b
   a = 2.0
   b = 3.0
   
   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
   call swap(a, b)
   
   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
end program calling_func


subroutine swap(x, y) 
implicit none

   real :: x, y, temp   
   
   temp = x  
   x = y 
   y = temp  
   
end subroutine swap

Quando você compila e executa o programa acima, ele produz o seguinte resultado -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000

Especificando a intenção dos argumentos

O atributo intent permite que você especifique a intenção com a qual os argumentos são usados ​​no procedimento. A tabela a seguir fornece os valores do atributo intent -

Valor Usado como Explicação
dentro intenção (em) Usado como valores de entrada, não alterado na função
Fora intenção (fora) Usado como valor de saída, eles são substituídos
entrada intenção (inout) Os argumentos são usados ​​e substituídos

O exemplo a seguir demonstra o conceito -

program calling_func
implicit none

   real :: x, y, z, disc
   
   x = 1.0
   y = 5.0
   z = 2.0
   
   call intent_example(x, y, z, disc)
   
   Print *, "The value of the discriminant is"
   Print *, disc
   
end program calling_func


subroutine intent_example (a, b, c, d)     
implicit none     

   ! dummy arguments      
   real, intent (in) :: a     
   real, intent (in) :: b      
   real, intent (in) :: c    
   real, intent (out) :: d   
   
   d = b * b - 4.0 * a * c 
   
end subroutine intent_example

Quando você compila e executa o programa acima, ele produz o seguinte resultado -

The value of the discriminant is
   17.0000000

Procedimentos Recursivos

A recursão ocorre quando uma linguagem de programação permite chamar uma função dentro da mesma função. É chamado de chamada recursiva da função.

Quando um procedimento chama a si mesmo, direta ou indiretamente, é chamado de procedimento recursivo. Você deve declarar este tipo de procedimento precedendo a palavrarecursive antes de sua declaração.

Quando uma função é usada recursivamente, o result opção deve ser usada.

A seguir está um exemplo, que calcula o fatorial para um determinado número usando um procedimento recursivo -

program calling_func
implicit none

   integer :: i, f
   i = 15
   
   Print *, "The value of factorial 15 is"
   f = myfactorial(15)
   Print *, f
   
end program calling_func

! computes the factorial of n (n!)      
recursive function myfactorial (n) result (fac)  
! function result     
implicit none     

   ! dummy arguments     
   integer :: fac     
   integer, intent (in) :: n     
   
   select case (n)         
      case (0:1)         
         fac = 1         
      case default    
         fac = n * myfactorial (n-1)  
   end select 
   
end function myfactorial

Procedimentos Internos

Quando um procedimento está contido em um programa, é chamado de procedimento interno do programa. A sintaxe para conter um procedimento interno é a seguinte -

program program_name     
   implicit none         
   ! type declaration statements         
   ! executable statements    
   . . .     
   contains         
   ! internal procedures      
   . . .  
end program program_name

O exemplo a seguir demonstra o conceito -

program mainprog  
implicit none 

   real :: a, b 
   a = 2.0
   b = 3.0
   
   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
   call swap(a, b)
   
   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
 
contains   
   subroutine swap(x, y)     
      real :: x, y, temp      
      temp = x 
      x = y  
      y = temp   
   end subroutine swap 
   
end program mainprog

Quando você compila e executa o programa acima, ele produz o seguinte resultado -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000