【问题标题】:Procedure with assumed-shape dummy argument must have an explicit interface [duplicate]具有假定形状的虚拟参数的过程必须具有显式接口
【发布时间】:2021-02-21 05:45:12
【问题描述】:

我对 Fortran 90 完全陌生,我正在尝试了解如何将数组传递给函数。我在网上看了看,找不到任何清晰简单的例子,所以我决定在这里发布。

我希望函数能够处理任意长度的数组(数组的长度不应该是函数的参数之一)。

我尝试编写一个简单的函数示例,该函数返回数组元素的总和:

function mysum(arr)
    implicit none
    real, dimension(:), intent(in) :: arr
    real :: mysum
    integer :: i,arrsize
    arrsize = size(arr)
    mysum=0.0
    do i=1,arrsize
        mysum=mysum+arr(i)
    enddo
end function mysum

program test
    implicit none
    real, dimension(4) :: a
    real :: mysum,a_sum
    call random_number(a)
    print *,a
    a_sum=mysum(a)
    print *,a_sum
end program

当我尝试编译时,我收到以下错误:

array_test.f90:17.14:

 real mysum,a_sum
           1
Error: Procedure 'mysum' at (1) with assumed-shape dummy argument 'arr' must have an explicit interface

我的程序有什么问题?

【问题讨论】:

  • 请使用标签fortran,Fortran 90 只是一个旧版本。我现在可以结束你的问题了......
  • 这里被处理了好几次。该过程必须在模块或内部,或者必须在调用站点提供接口块。模块是首选。
  • 如果你想写现代风格的 Fortran 所有程序都应该在一个模块内.
  • @VladimirF 好的,然后我将检查这些模块(和接口)。我阅读了您指出的可能重复的问题,但不幸的是,我目前的 Fortran 水平太低,无法理解如何准确地使用模块和接口的概念来解决我的问题。
  • 好的,让我们对这个确切的错误消息做一个更简单的答案。

标签: function fortran fortran90


【解决方案1】:

假定的形状虚拟参数(带有(:) 的参数)需要显式接口 才能在调用站点上使用该过程。这意味着调用代码必须知道子例程标题的确切外观。另见Module calling an external procedure with implicit interface

可以通过多种方式提供显式接口

1。 首选 - 一个模块过程

module procedures
  implicit none

contains

  function mysum(arr)

    real, dimension(:), intent(in) :: arr
    real :: mysum
    integer :: i,arrsize
    arrsize = size(arr)
    mysum=0.0
    do i=1,arrsize
        mysum=mysum+arr(i)
    enddo
  end function mysum
end module

program test
    use procedures

    implicit none
    !no mysum declared here, it comes from the module
    ...
end program

2。 内部过程 - 仅适用于简短的简单过程或如果该过程需要访问主机的变量。由于访问主机变量,它很容易出错。

program test
    implicit none
    !no a_sum declared here, it is visible below contains
    ...    
contains

  function mysum(arr)

    !implicit none inherited from the program

    real, dimension(:), intent(in) :: arr
    real :: mysum
    integer :: i,arrsize
    arrsize = size(arr)
    mysum=0.0
    do i=1,arrsize
        mysum=mysum+arr(i)
    enddo
  end function mysum
end program

3。 界面块 - 完全不推荐,你应该有一些特殊的理由来使用它

function mysum(arr)
  ! removed to save space
end function mysum

program test
    implicit none

     interface
       function mysum(arr)
         real, dimension(:), intent(in) :: arr
         real :: mysum
       end function
     end interface

     !no mysum declared there
     !it is declared in the interface block
     ...
end program

【讨论】:

  • 非常感谢,第一种方法(模块)完美地解决了我的问题,帮助我更好地理解了模块和接口的概念。更具体地说,如果有人想尝试这个例子,为了让它工作,我必须在“程序”中将“real :: mysum,a_sum”替换为“real :: a_sum”。
  • 是的,必须删除。还必须删除任何external。我忘了检查它(子程序不一定要在那里)。
猜你喜欢
  • 2021-05-04
  • 2020-04-20
  • 2017-12-26
  • 2020-02-25
  • 2019-03-14
  • 1970-01-01
  • 2021-02-02
  • 2021-09-16
相关资源
最近更新 更多