Фортран - Процедуры

А procedureэто группа операторов, которые выполняют четко определенную задачу и могут быть вызваны из вашей программы. Информация (или данные) передаются вызывающей программе в процедуру в качестве аргументов.

Есть два типа процедур -

  • Functions
  • Subroutines

Функция

Функция - это процедура, которая возвращает одно количество. Функция не должна изменять свои аргументы.

Возвращенное количество известно как function value, и обозначается именем функции.

Syntax

Синтаксис функции следующий -

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

В следующем примере демонстрируется функция с именем area_of_circle. Он вычисляет площадь круга радиусом 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

Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:

The area of a circle with radius 2.0 is
   12.5663710

Обратите внимание, что -

  • Вы должны указать implicit none как в основной программе, так и в самой процедуре.

  • Аргумент r в вызываемой функции называется dummy argument.

Вариант результата

Если вы хотите, чтобы возвращаемое значение сохранялось под другим именем, чем имя функции, вы можете использовать result вариант.

Вы можете указать имя возвращаемой переменной как -

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

Подпрограмма

Подпрограмма не возвращает значения, но может изменять свои аргументы.

Syntax

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

Вызов подпрограммы

Вам нужно вызвать подпрограмму, используя call заявление.

В следующем примере демонстрируется определение и использование подпрограммы swap, которая изменяет значения своих аргументов.

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

Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:

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

Определение цели аргументов

Атрибут intent позволяет указать намерение, с которым аргументы используются в процедуре. В следующей таблице представлены значения атрибута намерения -

Значение Используется в качестве Объяснение
в намерение (в) Используется как входные значения, не изменяется в функции
из намерение (выход) Используемые как выходные значения, они перезаписываются
inout намерение (inout) Аргументы используются и перезаписываются

Следующий пример демонстрирует концепцию -

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

Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:

The value of the discriminant is
   17.0000000

Рекурсивные процедуры

Рекурсия возникает, когда языки программирования позволяют вызывать функцию внутри той же функции. Это называется рекурсивным вызовом функции.

Когда процедура вызывает себя прямо или косвенно, это называется рекурсивной процедурой. Вы должны объявить этот тип процедур, поставив перед словомrecursive перед его объявлением.

Когда функция используется рекурсивно, result должна использоваться опция.

Ниже приведен пример, который вычисляет факториал для данного числа с помощью рекурсивной процедуры.

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

Внутренние процедуры

Когда процедура содержится в программе, она называется внутренней процедурой программы. Синтаксис для содержания внутренней процедуры следующий:

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

Следующий пример демонстрирует концепцию -

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

Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:

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