Fortran 简明教程

Fortran - Procedures

procedure 是一组语句,可以执行明确定义的任务,并可以从程序中调用。信息(或数据)作为参数传递给调用程序和过程。

有两种类型的过程 −

  1. Functions

  2. Subroutines

Function

函数是返回单个数量的过程。函数不应修改其参数。

返回的数量称为 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

请注意 −

  1. 您必须在主程序和过程中指定 implicit none

  2. 被调用函数中的参数 r 称为 dummy argument

The result Option

如果您希望将返回的值存储在函数名以外的其他名称中,可以使用 result 选项。

您可以将返回值变量名指定为 −

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

Subroutine

子例程不返回值,但可以修改其参数。

Syntax

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

Calling a Subroutine

您需要使用 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

Specifying the Intent of the Arguments

intent 属性允许您指定在过程中使用参数的目的。下表提供了 intent 属性的值 −

Value

Used as

Explanation

in

intent(in)

用作输入值,不改变此函数

out

intent(out)

用作输出值,会覆盖它们

inout

intent(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 Procedures

当编程语言允许您在同一函数内调用函数时,就会发生递归。它称为函数的递归调用。

当过程直接或间接调用自身时,称为递归过程。您应该在声明前添加 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

Internal Procedures

当一个过程包含在程序中时,它被称为程序的内部过程。包含内部过程的语法如下 −

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