Fortran:在函数中调用其他函数

Fortran: Calling other functions in a function

我在 Code::Blocks 上的两个单独文件中编写了 GNU Fortran 代码:main.f95、example.f95。 main.f95内容:

program testing

   use example

   implicit none
   integer :: a, b

   write(*,"(a)", advance="no") "Enter first number: "
   read(*,*) a

   write(*,"(a)", advance="no") "Enter second number: "
   read(*,*) b

   write(*,*) factorial(a)
   write(*,*) permutation(a, b)
   write(*,*) combination(a, b)

end program testing

example.f95内容:

module example


contains


  integer function factorial(x)

     implicit none
     integer, intent(in) :: x
     integer :: product_ = 1, i

     if (x < 1) then

        factorial = -1

     else if (x == 0 .or. x == 1) then

        factorial = 1

     else

        do i = 2, x
           product_ = product_ * i
        end do

        factorial = product_

     end if

  end function factorial


  real function permutation(x, y)

     implicit none
     integer, intent(in) :: x, y
     permutation = factorial(x) / factorial(x - y)

  end function permutation


  real function combination(x, y)

     implicit none
     integer, intent(in) :: x, y

     combination = permutation(x, y) / factorial(y)

  end function combination


end module example

当我运行这段代码时,输​​出是:

Enter first number: 5
Enter second number: 3
     120
   0.00000000    
   0.00000000    

排列组合函数不能正常工作。感谢您的回答。

我认为您遇到了 Fort运行 的一个众所周知的陷阱(对于了解它的人来说)。但在透露之前我必须问你做了多少测试?我 运行 你的代码,得到了奇怪的结果并思考了一分钟......

然后我测试了 factorial 函数的一些小值 x 产生了

 factorial            1  =            1
 factorial            2  =            2
 factorial            3  =           12
 factorial            4  =          288
 factorial            5  =        34560
 factorial            6  =     24883200
 factorial            7  =    857276416
 factorial            8  =   -511705088
 factorial            9  =   1073741824
 factorial           10  =            0

这显然是错误的。因此,在寻求帮助之前,您似乎没有正确测试您的代码(如果有的话)。 (我没有测试你的 combinationpermutation 函数。)

O tempora, o mores

您已经在行

中初始化了变量product_
 integer :: product_ = 1, i

这自动意味着 product_ 获取属性 save 因此它的值在调用之间存储(明白了!)。在每次调用开始时(第一个除外)product_ 具有上一次调用结束时的值。

补救方法很简单,不要初始化product_。更改

 integer :: product_ = 1, i

 integer :: product_ , i
 ...
 product_ = 1

更简单的方法是不编写自己的阶乘函数,而是使用内部 product 函数,但这是另一回事了。