Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 将可分配变量传递到具有不可分配参数的子例程中会产生什么效果?_Fortran - Fatal编程技术网

Fortran 将可分配变量传递到具有不可分配参数的子例程中会产生什么效果?

Fortran 将可分配变量传递到具有不可分配参数的子例程中会产生什么效果?,fortran,Fortran,假设我们有这个变量定义 Real*8, Dimension(:), Allocatable :: dblA Allocate (dblA(1000)) 现在我调用这个子程序: Call MySub(dblA) 其中: Subroutine MySub(dblA) Real*8, INTENT(Out), DIMENSION(1000) :: dblA End 这种做法的副作用是什么? 我应该避免这种情况吗?如果数组在传递给子例程之前已分配,那么子例程对可分配性没有影响,效果与数组是静态

假设我们有这个变量定义

Real*8, Dimension(:), Allocatable :: dblA
Allocate  (dblA(1000))
现在我调用这个子程序:

Call MySub(dblA)
其中:

Subroutine MySub(dblA)
Real*8,  INTENT(Out), DIMENSION(1000) :: dblA
End
这种做法的副作用是什么?
我应该避免这种情况吗?

如果数组在传递给子例程之前已分配,那么子例程对可分配性没有影响,效果与数组是静态的一样。在您展示给我们的片段中,没有什么可以反对,也没有什么实践可以避免。然而,这些片段实际上做的很少,很容易想到扩展它们的方法来使这个建议无效

现在帮你自己一个忙,改变一下

Real*8,  INTENT(Out), DIMENSION(1000) :: dblA

因此,无论传递的数组大小如何,子例程都能正常工作。使用
dblA
作为伪参数和实际参数的名称可能也是一个坏主意,您只会混淆自己

而且
real*8
不是,也从来不是一种符合标准的声明8字节real的方法。关于这一点,请参见此处的大量问题和答案。

说明了我想要的一切。不过,为了强调,我将重复一个方面

在调用子例程时,非常需要分配子例程中的可分配数组。[就问题而言,应具有足够的规模。]

为了让这个答案不仅仅是一个评论,我将回答更一般的问题标题。在这之前,我将看看“可分配或不可分配的伪参数”思想中可能出现的问题

  • 因为伪参数(子例程中的参数)具有
    intent(out)
    属性,所以它和实际参数变得未定义。如果伪参数是可分配的,则它也会在条目上解除分配。在本例中,实际参数保持分配状态,并保持其原始大小

  • 如果不可分配,则虚拟参数(和实际参数)不能查询或更改分配状态;伪参数不能进一步传递给期望可分配参数的过程,即使实际参数可以是

  • 如果伪参数是可分配的,而不是(静态)显式形状数组,则实际参数也必须是可分配数组

  • 对于可分配的伪参数,当引用子例程时,需要显式接口。[有些人会说,即使在隐式接口很好的情况下,这也是一个好主意。]

关于更一般的事情,我将给出一个示例,其中对可分配的实际/不可分配的虚拟对象有限制(F2008,12.5.2.4):

如果实际参数是多态的共索引对象,则伪参数不应是多态的

但对大多数人来说,这并不值得担心


哦,还有一件事我要从另一个答案中扣除:
Real*8
应该避免。

是的,这就是我一直在想的东西,但是太无聊了,写不出来……:-(@Francescalus,你是说意图应该是INOUT吗?一点也不,@Holmz。意图应该是适合使用伪参数(或其他设计考虑因素)的任何东西。对于可分配的伪参数,
INTENT(out)
INTENT(INOUT)
之间的区别要大得多(前者意味着进入时取消分配)比显式形状数组的情况要好。如果你告诉我答案中的哪一点导致了你的问题,我将了解如何澄清。这甚至可以帮助原始询问者。@francescalus在ifort上,数组的尺寸在aubroutine内部是未知的,没有意图(INOUT),这就是问题所在。我的愿望是使用OUT,但我发现INOUT经常是需要的。@Holmz,当有一个显式的shape数组伪参数(如在原始问题中)或一个假定的shape数组时,不必使用
intent(INOUT)
来定义伪参数的边界(即有效)参数可用。对于可分配(指针)伪参数,有效参数在进入子例程时被解除分配(相应地,变为未定义的关联状态)-丢失形状细节。看不到您的代码(可能有问题,但可能脱离主题)我不能再多说了。请注意,
real*8
不是有效的Fortran,也从来不是任何ISO Fortran/Fortran标准的一部分。请使用内部模块
ISO\u Fortran\u env
selected\u real\u kind
中的命名常量,以便以可移植的方式控制精度。
Real*8,  INTENT(Out), DIMENSION(:) :: dblA