简体   繁体   English

将可分配数组传递给子例程

[英]Passing allocatable array into a subroutine

I am working on a f90 code that I didn't write.我正在编写我没有编写的 f90 代码。 I am not a very experienced fortran user.我不是一个非常有经验的 fortran 用户。

There is a part that bothers me a bit and I am not sure if it is a normal practice.有一部分让我有点困扰,我不确定这是否是正常做法。 Can someone help me to clarify a bit please ?有人可以帮我澄清一下吗?

  • I have a structure with an allocatable array defined in a module.我有一个在模块中定义的可分配数组的结构。
  • This variable is passed un-allocated to a subroutine.此变量未分配地传递给子例程。
  • The subroutine then allocates its corresponding local variable.然后子例程分配其对应的局部变量。
  • In the main, the output of the passed structure variable is allocated.主要分配传递的结构变量的输出。

What I am not sure I understand is how the main program is handling the size of the return variable as it is not defined before.我不确定我理解的是主程序如何处理返回变量的大小,因为它之前没有定义。 Is it a common practice?这是一种常见的做法吗?

Personally, I would have think that a variable with a defined size should have been passed to the subroutine.就个人而言,我认为应该将具有定义大小的变量传递给子例程。

If I resume coarsly the code:如果我粗略地恢复代码:

modulus_mod.f90 :模数模数.f90

module modulus_mod
public :: mod

type mod
real,allocatable,dimension(:,:)    :: rec
end type mod

end module modulus_mod

subtoto.f90 : subtoto.f90

subroutine subtoto(recloc)

implicit none

real,allocatable,dimension(:,:)    :: recloc

WRITE(*,*) 'in'
ALLOCATE( recloc(10,10) )
WRITE(*,*) 'inout'
recloc(:,:)=1.
WRITE(*,*) 'out'

endsubroutine subtoto

toto.f90 : toto.f90

program toto
use modulus_mod

implicit none
type(mod)  :: model

!>>> Here not allocated if tested
if(allocated(model%rec)) WRITE(*,*) 'allocated bf'
if(.NOT.allocated(model%rec)) WRITE(*,*) 'NOT allocated bf'

CALL subtoto(model%rec)

WRITE(*,*) 'out sub'
!>>>Here it should be allocated correctly if tested
if(allocated(model%rec)) WRITE(*,*) 'allocated af'
if(.NOT.allocated(model%rec)) WRITE(*,*) 'NOT allocated af'

end program toto

Trying to make a hands-on summary here:尝试在这里做一个动手总结:

  1. Variable is an allocatable dummy argument in a subroutine, for example:变量是子例程中allocatable的虚拟参数,例如:
subroutine sub(variable)
   real, allocatable, [intent(...)] :: variable(:)

here, status is controlled by the intent keyword:在这里,状态由intent关键字控制:

  • intent(out) : initially not allocated, when the subroutine is called intent(out) :最初分配,当子程序被调用时
  • intent(in) , intent(inout) or [no intent declared]: initial allocation status depends on what the variable was like outside of this routine intent(in)intent(inout)或 [未声明意图]:初始分配状态取决于变量在此例程之外的情况

At any times, you can check both the status and the size of this variable by allocated(variable) and size(variable) .在任何时候,您都可以通过allocated(variable)size(variable)检查该变量的状态和大小。

Note that size is undefined if the variable is not allocated , so you may want to use something like:请注意,如果未分配变量,则 size 未定义,因此您可能需要使用以下内容:

safe_size = merge(size(variable),-1,allocated(variable))

to prevent the undefined behavior.以防止未定义的行为。

  1. Variable is in a module: it is save d.变量在一个模块中:它是save d。 Its status is not allocated at the beginning of the program;它的状态not allocated的; both status and contents can change during runtime (for example being changed by a subroutine or function, with the rules of 1.), but nothing is modified between these calls.状态和内容都可以在运行时改变(例如被子程序或函数改变,规则为 1.),但在这些调用之间没有任何修改。

In your case, if you want your variable to always be allocated by the routine, you should specify an intent(out) , like:在您的情况下,如果您希望您的变量始终由例程分配,您应该指定一个intent(out) ,例如:

subroutine subtoto(recloc)
   implicit none
   real,allocatable,dimension(:,:), intent(out) :: recloc
   [...]
end subroutine subtoto

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用名称列表以派生类型编写可分配数组? - How to write an allocatable array in a derived type using namelists? 带有子例程的输入数组文件(.dat)的最小值和最大值 - min and max of input array file (.dat) with subroutine 使用 Fortran 将 txt 文件读入可分配数组时出现错误结果 90 - Wrong results when reading a txt file into an allocatable array using Fortran 90 使用带有名称列表的allocatable / assume-size数组读写 - Using allocatable/assumed-size arrays with namelist read write 用于将 stdout 和 stderr 管道传输到文件的子例程 - Subroutine for piping stdout and stderr into file 传递到数组时使用文本文件的Scanner I / O问题 - Problems with Scanner i/o using a text file when passing to an array 如何将文件名传递给perl中的子程序? - How to pass file names to a subroutine in perl? 从多个线程调用带有OPEN语句的子例程 - Subroutine with OPEN statement called from multiple threads 有没有一种方法可以使用名称列表I / O功能读取具有可分配组件的派生类型? - Is there a way to use the namelist I/O feature to read in a derived type with allocatable components? 如何在 Perl 中为简单的 I/O 子程序创建单元测试 - How to create a unit test for a simple I/O subroutine in Perl
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM