在Fortran中显示intent(out)和intent(inout)之间差异的有效程序
这是我在SO上发现的一篇文章的后续内容: 链接的问题询问了Fortran中在Fortran中显示intent(out)和intent(inout)之间差异的有效程序,fortran,Fortran,这是我在SO上发现的一篇文章的后续内容: 链接的问题询问了Fortran中intent(out)和intent(inout)之间的区别,方法是询问一个 任何人都可以通过将intent(inout)更改为intent(out),或者反之亦然,想出一个简单有效的程序来给出不同的结果吗?给你 program intent_test implicit none integer, allocatable :: a(:) a = [1,2,3,4,5] call intent_inout (a) ca
intent(out)
和intent(inout)
之间的区别,方法是询问一个
任何人都可以通过将intent(inout)
更改为intent(out)
,或者反之亦然,想出一个简单有效的程序来给出不同的结果吗?给你
program intent_test
implicit none
integer, allocatable :: a(:)
a = [1,2,3,4,5]
call intent_inout (a)
call intent_out (a)
contains
subroutine intent_inout (a)
integer, allocatable, intent(inout) :: a(:)
if (allocated(a)) then
print *, a
else
print *, "Unallocated"
end if
end subroutine intent_inout
subroutine intent_out (a)
integer, allocatable, intent(out) :: a(:)
if (allocated(a)) then
print *, a
else
print *, "Unallocated"
end if
end subroutine intent_out
end program intent_test
12345
未分配的
正如史蒂夫·莱昂内尔(Steve Lionel)所说,以及我原始答案中可能引发这种兴趣的评论,意图(out)
对伪参数(和实际参数)初始状态的影响是回答这个问题的一种方式
intent(inout)
让伪参数在进入过程时反映实际参数的值intent(out)
“重置”伪参数。在链接问题的情况下,这种“未定义”是程序无效性质的原因
更准确地说,关于intent(out)
伪参数,我们可以说以下几点:
- 可分配的实际参数被解除分配李>
- 指针实际参数的指针关联变得未定义李>
- 对于非指针伪参数,任何未默认初始化的组件都将变为未定义李>
implicit none
type t
integer :: x=1
end type t
type(t) :: x=t(0)
call s1(x)
call s2(x)
contains
subroutine s1(x)
type(t), intent(inout) :: x
print*, x%x
end subroutine s1
subroutine s2(x)
type(t), intent(out) :: x
print*, x%x
end subroutine s2
end
重要的是,组件的默认初始化意味着即使在进入s2
之前,x%x
也不是未定义的,但它在进入过程之前接受了一个可能与实际参数组件不同的值
使用指针参数编写一个合适的程序是很棘手的:在重新定义指针关联状态之前,无法引用/查询具有未定义指针关联状态的指针
这让我们看到了可分配组件。与指针不同,指针关联状态未定义时无法查询,我们可以询问分配状态。取消分配与意图(out)
伪对象对应的实际参数;使用intent(inout)
分配状态不变:
implicit none
integer, allocatable :: i
allocate (i)
call s1(i); print*, allocated(i)
call s2(i); print*, allocated(i)
contains
subroutine s1(i)
integer, allocatable, intent(inout) :: i
end subroutine s1
subroutine s2(i)
integer, allocatable, intent(out) :: i
end subroutine s2
end
(这是史蒂夫·莱昂内尔例子的简单版本。)
这一切都表明,存在差异是可能的。不正确地使用
intent
可能导致程序无效或意义发生重大变化。理解什么是intent(in)
,intent(inout)
,intent(out)
,以及没有指定的意图是Fortran程序员的关键部分。+1。谢谢你的快速回复,史蒂夫!本例中使用了一个数组,@francescalus使用type
执行“技巧”。这让我想知道,如果只使用只执行简单算术的integer
变量和子例程,或者只使用print
函数,那么out
和inout
是否可能总是给出相同的结果。(这当然是另一个问题。)我怀疑这不太可能。但是,通过一些示例,我没有发现任何差异。重要的是ALLOCATABLE
属性-变量可以是任何类型。根据标准,INTENT(OUT)
意味着伪参数的定义状态在进入过程时为“未定义”,但在其他情况下很难检测到。关于@francescalus对“disassociates”的使用——这让我感到不安,指针被解除关联INTENT(OUT)
导致指针未定义,而不是解除关联,因此您不能假设甚至测试指针已解除关联。是的,我使用“disassociate”作为“成为未定义关联状态”的(懒惰)速记(有关更精确的状态,请参见我的答案)。请注意,“指针变为未定义”同样不精确:它未定义(这很好),但它的关联状态也未定义(这很好)。谢谢!在我看来,intent(inout)
和intent(out)之间的区别
非常微妙,虽然底层机制不同,但它们给出相同的结果可能并不罕见。需要记住的重要一点是,INTENT
实际上是对程序员的一种帮助,它为编译器提供了额外的信息,可以用来提醒您可能出现的错误。例如,传递INTENT(INOUT)
参数的常量是错误的,因为INTENT(INOUT)
要求实际参数是可定义的。这不同于省略INTENT
(我游说支持INTENT(NONE)
与省略INTENT
)和INTENT(in)的含义相同
如果实际值未定义,编译器可能会警告您。我仍然有点困惑,在这两种情况下(inout或out)正确吗我仍然需要在主程序中声明变量?如果不在子例程中声明变量,子例程中的变量可能与主程序中的等效变量有不同的维度,或者没有?@Hermantouthrot,我不确定我是否理解你的问题。但是,让我们看看这是否有帮助:使用intent(inout)
和intent(out)
引用过程的地方(比如主程序)必须有一个对应的(可定义对象/)变量。有了这些意图,就不可能使用表达式作为参数。数组维度是否匹配与任何指定意图无关。(请注意,我这里的示例中没有数组。)