Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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
Pointers Fortran调用:通过指针传递与通过引用传递的优势_Pointers_Fortran - Fatal编程技术网

Pointers Fortran调用:通过指针传递与通过引用传递的优势

Pointers Fortran调用:通过指针传递与通过引用传递的优势,pointers,fortran,Pointers,Fortran,据我所知,在Fortran中,数组是通过引用传递的。因此,与传递数组本身相比,将指针传递到大型数组(传递到子例程)是否有优势 您能否在递归函数的上下文中阐明这一点。我见过使用指针的实现是为了“提高效率”,但如果一切都是通过引用传递的,那么指针的好处是什么呢 这里有一个例子。我有一个数组X(实际上,让我们假设它是一个非常大的数组) 我可以定义一个接受此数组的子例程,如下所示: SUBROUTINE FOO(X) INTEGER, INTENT(IN) :: X(:) INTEGE

据我所知,在Fortran中,数组是通过引用传递的。因此,与传递数组本身相比,将指针传递到大型数组(传递到子例程)是否有优势

您能否在递归函数的上下文中阐明这一点。我见过使用指针的实现是为了“提高效率”,但如果一切都是通过引用传递的,那么指针的好处是什么呢

这里有一个例子。我有一个数组X(实际上,让我们假设它是一个非常大的数组)

我可以定义一个接受此数组的子例程,如下所示:

SUBROUTINE FOO(X)
    INTEGER, INTENT(IN) :: X(:)

    INTEGER :: I

    DO I = 1, 4
        WRITE(*,*) X(I)
   ENDDO
END SUBROUTINE FOO
PROGRAM TEST
IMPLICIT NONE

INTEGER, TARGET :: X(5)
INTEGER, POINTER :: Y(:)

X = (/1,2,3,4,5/)
Y => X

CALL FOO2(Y)
END PROGRAM TEST
当我调用上面的子例程时,当fortran传递对它的引用时,数组X不会被复制。现在让我们假设我有一个修改版本的子程序:

SUBROUTINE FOO2(X)
    INTEGER, POINTER, INTENT(IN) :: X(:)
    INTEGER :: I

    DO I = 1, 4
        WRITE(*,*) X(I)
   ENDDO
END SUBROUTINE FOO2
我可以通过以下程序调用
FOO2

SUBROUTINE FOO(X)
    INTEGER, INTENT(IN) :: X(:)

    INTEGER :: I

    DO I = 1, 4
        WRITE(*,*) X(I)
   ENDDO
END SUBROUTINE FOO
PROGRAM TEST
IMPLICIT NONE

INTEGER, TARGET :: X(5)
INTEGER, POINTER :: Y(:)

X = (/1,2,3,4,5/)
Y => X

CALL FOO2(Y)
END PROGRAM TEST

然后我的问题是:两个版本的foo之间有性能差异吗?是否有任何有用的场景表明FOO2的声明可能比FOO更可取?

在这个简单的例子中,不应该有任何真正的区别。注意:该程序是非法的,您没有到
FOO
FOO2
的显式接口,但我假设您只是为了简单起见才使用它,并且它们位于模块或内部

这两个数组原则上可以是非连续的,所以这里没有区别。如果这会减慢代码的速度,那么
continuous
属性可能会有所帮助。或假定大小或显式大小数组

您的子例程太简单了,因此也没有出现别名的危险。这是指针性能下降的常见原因。如果具有
target
属性,则主机或使用关联访问的其他参数或其他变量可能存在别名

指针参数的用途实际上是允许解除关联(
null()
)参数,或允许更改子例程中的关联状态。您的示例没有使用这两个属性,因此指针属性是多余的


还有最后一点小差别。标准中未规定指针变量在机器代码级别实际传递给子程序的内容。如果它只是一个地址(可能是标量),那么它与非指针相同,只是别名规则和允许的用法不同。否则会传递一些描述符,但任何开销都可以忽略不计,假定的形状数组也使用描述符。

您似乎很困惑。你指的是Fortran指针变量还是地址?通过引用传递和通过指针传递在机器代码级别或C语言级别(几乎)是相同的。向我们展示你的两种方法的例子,你的描述肯定是不够的。现在投票结束。指针,什么是指针?我是一名Fortran程序员。与传递数组本身相反,您指的是什么?现在我倾向于同意@VladimirF(我通常是这么认为的),不知道你的问题,按照措辞,是如何得出好的答案的。@VladimirF我并不困惑,但我可以说得更清楚。我指的是指针变量(我不知道在fortran的上下文中指针还能指什么,所以我看不出任何混淆的根源)。我只是想了解,从效率的角度来看,将数组X传递给子例程和将指向目标X的指针传递给该子例程之间是否有区别。我还应该补充一点,你不应该因为不理解被问到的问题就否决投票问题。只要求澄清。编辑你的问题并插入一个例子。顺便说一句,我没有投你的反对票,只是投了结束票,但规则不同,你可以投你认为在这里没有用的任何东西的反对票。这也涉及到非常难以理解的问题。不要忘记指定是指标量还是数组。无论是一个论点还是更多的论点。非指针数组参数是假定形状还是假定大小/显式大小。无论您是使用主机中的任何其他变量,还是使用具有
target
属性的关联。这可能意味着很多。