Fortran:过程procedures

声明:本博文翻译自:https://www.tutorialspoint.com/fortran/fortran_procedures.htm

过程是一组语句,它们执行定义的语句,可以从程序中调用。信息(或数据)作为参数传递给调用程序,传递给过程。
这里主要介绍两种procedures
(1) Fucntions
(2) Subroutines

1. functions
函数是返回单个数量的过程。函数不应该修改它的参数。当然了,函数现在也能返回数组了
function的基本语法如下:
function name(arg1, arg2, ....)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]
这里给出一个示例代码:
Program calling_func
  implicit none
  real :: a, area_of_circle
  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)  
  implicit none            
  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.56637
这里注意以下几点:
(1) 由于函数area_of_circle没有写在模块或是内部过程中(模块下节讲解,内部过程下面讲),所以在主程序中要对函数area_of_circle进行声明。
(2) 在函数area_of_circle中,声明area_of_circle的修饰词写可以写在function前面,如下所示:
real function area_of_circle (r)  
  implicit none            

  ! local variables 
  real :: r     
  real :: pi

  pi = 4 * atan (1.0)     
  area_of_circle = pi * r**2  

end function area_of_circle
注意两种写法的区别。

注意一下:
(1) 在主程序与procedures中最好都写implicit none
(2) 函数中的参数r被称为虚参dummy argument

2. result选项
基本语法如下:
function name(arg1, arg2, ....) result (return_var_name)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]
使用result不外乎下面这种情况。
有时候为了增加代码的可读性,所以函数的名字可能会很长。所以对函数内部,使用result将函数名转化为一个简短的函数名。对函数外依旧引用原函数名(较长的函数名,方便代码阅读)
示例代码如下:
Program calling_func
  implicit none
  real :: a, area_of_circle
  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) result (s)
  implicit none            
  real :: s  

  ! local variables 
  real :: r     
  real :: pi

  pi = 4 * atan (1.0)     
  s = pi * r**2  

end function area_of_circle
执行结果如下:
The area of a circle with radius 2.0 is
12.56637

3. subroutine
子程序可以理解为没有返回值的函数。
语法如下:
subroutine name(arg1, arg2, ....)    
   [declarations, including those for the arguments]    
   [executable statements]  
end subroutine [name]

调用子程序
使用keyword call调用子程序
下面的示例演示了子程序对变量的交换和使用,它改变了其参数的值。
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.000000
 b =    3.000000
 After calling swap
 a =    3.000000
 b =    2.000000

4. 指定参数的属性
        Value                   Used as                             Explanation
         in                    intent(in)        Used as input values, not changed in the function
        out                    intent(out)           Used as output value, they are overwritten
       inout                  intent(inout)           Arguments are both used and overwritten
示例代码如下:
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.00000

5. 递归过程
当编程语言允许在同一个函数中调用自身时,就会发生递归。它被称为函数的递归调用。
当过程直接或间接地调用自身时,称为递归过程。应该使用recursive声明这种类型的过程。
当递归地使用函数时,必须使用result选项。
示例代码如下:
program calling_func
  implicit none
  integer :: i, f, myfactorial

  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
执行结果如下:
The value of factorial 15 is
2004310016

6. 内部过程
当一个过程**包含**在一个程序中时,它被称为程序的内部过程。
基本语法如下:
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)     
    implicit none
    real :: x, y, temp      
    temp = x 
    x = y  
    y = temp   
  end subroutine swap 

End program mainprog 
执行结果如下:
 Before calling swap
 a =    2.000000
 b =    3.000000
 After calling swap
 a =    3.000000
 b =    2.000000
这里顺便提及一下,写在内部过程中的function,可不在主程序里面声明。
而且内部子程序可以直接使用主程序中的变量,而不需要再次声明
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()

  Print *, "After calling swap"
  Print *, "a = ", a
  Print *, "b = ", b

contains   
  subroutine swap()     
    implicit none
    real :: temp      
    temp = a
    a = b  
    b = temp   
  end subroutine swap 

End program mainprog 
**注意体会**。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值