下面的fortran代码遇到分段错误。然而,当我修改print*,pow(10_8,i)
到print*,pow(j,i)
,它的工作原理没有呕吐分段错误。为什么?这很奇怪。
module mdl
implicit none
integer(kind=8)::n,m=1000000007
integer(kind=8)::p(1000),k(1000),div(10000000)
contains
integer(kind=8) function pow(a,pwr)
implicit none
integer(kind=8)::a,pwr
integer(kind=8)::cur
cur=pwr
pow=1
do while(cur>0)
if(mod(cur,2)==1)pow=mod(pow*a,m)
a=MOD(a*a,m)
cur=cur/2
end do
end function
end module
program main
use mdl
implicit none
integer(kind=8)::i,j,l,r,x,y
i=2
j=10
print*,pow(10_8,i)
print*,i
end program
这里的问题在于a
函数的参数pow
。在函数中,该参数a
(可能)在行上被修改
a=MOD(a*a,m)
10_8
引用该函数时,实际参数是文字常量,不能修改。这是您的程序失败时。当使用时print*,pow(j,i)
,j
变量可以被修改,并且程序不会失败。
这里发生了很多复杂的事情,在这个答案中我不会完全解释(您可以搜索其他问题)。一个主题是参数关联,它说明了为什么要尝试修改常量10_8
。但是,我会说一些关于虚拟参数意图的事情。
dummy参数a
未指定意图。当您打算在a
输入函数时使用的值,并且希望(可能)对其进行修改时,应该使用适当的意图intent(inout)
。如果应用此方法,则应该发现编译器抱怨该分配行。
毫无疑问(例如在问题中)是可以接受的。这具有一定的意义。即,是否a
可以修改取决于引用该函数时的实际参数是否可以。当实际的论据10_8
不是时;当它是j
它的可能。
至关重要的是,检查程序是否在此做某事不是您的责任,而是您的责任。
现在,j
即使允许,您可能也不想修改实际参数。您有两种选择:
a
为intent(in)
),可以安全地对其进行修改;value
属性为输入数据制作匿名可修改的副本。您首先要使用cur=pwr
。作为第二个示例:
integer(kind=bigint) function pow(a,pwr)
implicit none
integer(kind=bigint), value :: a, pwr
pow=1
do while(cur>0)
if(mod(pwr,2)==1)pow=mod(pow*a,m)
a=MOD(a*a,m)
pwr=pwr/2
end do
end function
您现在甚至可以将其标记pow
为纯函数。
最后,如果使用该value
属性,则在引用该函数时要求显式接口可用。使用此功能的模块时,这里就是这种情况,但是在更一般的情况下需要考虑这一点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句