前面几天,学完函数之后,老是心心念念的递归,今天终于可以了!
其实之前我有一个误区,就是老是觉得Fortran会像c++和其他语言一样,函数可以直接调用自己来进行递归,实际上我错了,Fortran太老了,当初创建他的时候,估计那帮老学究想着一定要声明好,所以才给函数给了命令,让有这个命令的函数才能调用自己形成递归。
先回顾以下递归的三个条件:
- 一个问题的解是否能分解为几个子问题的解
- 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
- 存在递归终止条件
好了,回顾完成之后,我们就开始学习递归吧:
Fortran的递归函数,在声明的时候就要用recursive来声明,只有这样子,这个function才能进行递归。
recursive integer function func(input) result(output)
result可以用来在程序代码中使用另一个名字来设置函数的传回值,这里的output用来代替原先的func
简单的跟着书上的例子敲一个计算阶乘:
recursive integer function func(input) result(output)
implicit none
integer,INTENT(IN)::input
if(input<0)then
output=-1
RETURN
else if ( input<=1 )then
output=1
RETURN
end if
output=input*func(input-1)
RETURN
end
program main
implicit none
integer::num
integer,external::func
write(*,*)"input a number"
read(*,*)num
write(*,"(I3,'!=',I5)")num,func(num)
stop "over"
end program main

ok,这下试试我心心念念的递归求斐波那契数列:
recursive integer function fib(input) result(output)
implicit none
integer,INTENT(IN)::input
if((input==1).or.(input==0))then
output=1
RETURN
else
output=fib(input-1)+fib(input-2)
end if
RETURN
end function
program main
implicit none
integer::num
integer,external::func
integer,external::fib
integer i
do i=0,10
write(*,"(I3)")fib(i)
end do
stop "over"
end program main

完全实现,没得一点问题,虽然书上说,有的编译器可以接受不改名的递归函数(result(output)中的output可以直接写成input),但我觉得,就Fortran而言,还是改了比较好。
ok 递归函数搞完了,这下来学习内部函数:也就是定义时规定,某些函数只能够在某些特定的函数里被调用:
program main or subroutine sub_name or function function_name
......
......
contains
subroutine localsub
......
end subroutine
function function_name
......
end function
end program/subroutine/function
我写的时候感觉这就是内部函数的声明方法,其实内部函数的作用还是体现在封装上,整个函数的内部是不可以被看到的。
简单的来吧上面的斐波那契数列给改编一下:
program main
implicit none
integer::num
integer,external::func
! integer,external::fib
integer i
do i=0,10
write(*,"(I3)")fib(i)
end do
stop "over"
contains
recursive integer function fib(input) result(output)
implicit none
integer,INTENT(IN)::input
if((input==1).or.(input==0))then
output=1
RETURN
else
output=fib(input-1)+fib(input-2)
end if
RETURN
end function fib
! stop "over"这会就不能在这写这句了,得在上面写,否则会报错,说你contains中不应该包含这句话
end program main
结果直接看上面的图就好,再没啥好说的,就是在内部的时候,就不用再去声明函数了。
pure函数:
一般情况不会用到,这个是用来搞并行运算的。
(1)PURE 函数的参数必须都是只读 INTENT(IN)。
(2)PURE 子程序的每个参数都要赋值属性。
(3)PURE 函数中不能使用 SAVE。
(4)PURE 函数中所包含的内部函数也都必须是 PURE 类型函数。
(5) PURE 函数中不能使用 STOP、PRINT 及跟输出入相关的命令如 READ、WRITE
OPEN、CLOSE、BACKSPACE、ENDFILE、REWIND、INQUTRE 等等。
(6)PURE 函数中只能够读取,不能改变全局变量的值。
elemental函数:
和pure一样,也可以用来做并行计算,但是其参数不能是数组
使用elemental函数的时候,必须先声明他的使用接口,主程序才hi正确做出设置数组的调用。
跟着书上的写一个,但我感觉这个用处不会很大,而且我按书上讲的写了,出错。。。
program main
implicit none
interface
elemental real function func(num)
implicit none
real, INTENT(IN) :: num
end function
end interface
real i
real::a(10)=(/i,i=1.0,10/)
real::b(10)
write(*,"(10F6.2)")a
a=func(a)
write(*,"(10F6.2)")a
end
elemental real function func(num)
implicit none
real,INTENT(IN)::num
func=sin(num)+cos(num)
RETURN
end
并行运算我感觉就是多线程,了解一下就好,实际应用,一、碰不到,二、即使是碰到了,你也不会用。
百思不得其解,如果有人有兴趣的话,可以看一看,留言大家交流一下,谢谢

4566

被折叠的 条评论
为什么被折叠?



