Fortran 基本函数 - 这种行为正常吗?
Fortran elemental function - is this behavior normal?
考虑以下函数
ELEMENTAL FUNCTION int2str(i) RESULT(s)
INTEGER, INTENT(IN) :: i
CHARACTER(LEN = 50) :: appo
CHARACTER(LEN = :), ALLOCATABLE :: s
WRITE(appo, '(I0)') i
ALLOCATE(s, source = TRIM(appo))
END FUNCTION int2str
作为元素的函数是一个标量函数(在我的例子中它接受一个标量整数并返回一个标量字符,即使在长度上是可分配的)应用于数组。
为什么输出
print *, '>>>'//int2str([1, 3, 5, 7])//'<<<'
是(出乎我的意料)
>>>1<<<>>>3<<<>>>5<<<>>>7<<<
而
的输出
print *, '>>>', int2str([1, 3, 5, 7]), '<<<'
是(预计)
>>>1357<<<
?
我的意思是该函数应该应用于组成数组的四个标量整数中的每一个,从而返回一个长度为 4 的数组,每个元素都是一个字符串,但在我看来它的元素- ness 适用于三个字符串的整个连接,就好像 //
运算符优先于函数的结果。
我意外的遇到了我没想到的结果(>>>1<<<>>>3<<<>>>5<<<>>>7<<<
),即使我手动实现了函数的ELEMENTAL
性,也确实是一样的,即
print *, '>>>'//[num2str(1), num2str(3), num2str(5), num2str(7)]//'<<<'
所以我可能误解了自己的话因此RETURN
创建了一个长度为 4 的数组,每个元素都是一个字符串。该函数确实返回一个字符串数组,并且连接适用于数组的每个元素(数组的元素粘在一起,中间没有 space 只是因为它们是字符串)。
对于字符连接,表达式
'>>>'//['1','3','5','7']
取决于标量 '>>>'
和数组 ['1','3','5','7']
。与其他操作数是标量和秩为 1 的数组的内部二元运算一样,表达式是秩为 1 的数组。
在确定表达式的值时,标量操作数被视为数组,如
['>>>','>>>','>>>','>>>']
表达式等同于
['>>>','>>>','>>>','>>>'] // ['1','3','5','7']
最后,表达式具有值,其中元素是成对的操作数:
['>>>1','>>>3','>>>5','>>>7']
你可以看到与表达式
的相似之处
9+[1,3,5,7] ! [9,9,9,9]+[1,3,5,7] --> [10,12,14,16]
当有两个集中操作进行时,明显的值就是结果。
请注意,我没有用基本函数的结果来表达这一点。这部分是因为数组来自函数这一事实并不重要。此外,您的基本函数实际上是不允许的:基本函数结果可能无法分配。
关于无效函数,Vladimir F 已提交 a bug report 涵盖 gfortran 未检测到对 Fortran 2008 编号约束 C1290 的违反。在该报告中您可以看到,如果删除 result(s)
和将 int2str
声明为具有可分配属性,该函数被拒绝。其他一些编译器确实已经检测到违规。
考虑以下函数
ELEMENTAL FUNCTION int2str(i) RESULT(s)
INTEGER, INTENT(IN) :: i
CHARACTER(LEN = 50) :: appo
CHARACTER(LEN = :), ALLOCATABLE :: s
WRITE(appo, '(I0)') i
ALLOCATE(s, source = TRIM(appo))
END FUNCTION int2str
作为元素的函数是一个标量函数(在我的例子中它接受一个标量整数并返回一个标量字符,即使在长度上是可分配的)应用于数组。
为什么输出
print *, '>>>'//int2str([1, 3, 5, 7])//'<<<'
是(出乎我的意料)
>>>1<<<>>>3<<<>>>5<<<>>>7<<<
而
的输出print *, '>>>', int2str([1, 3, 5, 7]), '<<<'
是(预计)
>>>1357<<<
?
我的意思是该函数应该应用于组成数组的四个标量整数中的每一个,从而返回一个长度为 4 的数组,每个元素都是一个字符串,但在我看来它的元素- ness 适用于三个字符串的整个连接,就好像 //
运算符优先于函数的结果。
我意外的遇到了我没想到的结果(>>>1<<<>>>3<<<>>>5<<<>>>7<<<
),即使我手动实现了函数的ELEMENTAL
性,也确实是一样的,即
print *, '>>>'//[num2str(1), num2str(3), num2str(5), num2str(7)]//'<<<'
所以我可能误解了自己的话因此RETURN
创建了一个长度为 4 的数组,每个元素都是一个字符串。该函数确实返回一个字符串数组,并且连接适用于数组的每个元素(数组的元素粘在一起,中间没有 space 只是因为它们是字符串)。
对于字符连接,表达式
'>>>'//['1','3','5','7']
取决于标量 '>>>'
和数组 ['1','3','5','7']
。与其他操作数是标量和秩为 1 的数组的内部二元运算一样,表达式是秩为 1 的数组。
在确定表达式的值时,标量操作数被视为数组,如
['>>>','>>>','>>>','>>>']
表达式等同于
['>>>','>>>','>>>','>>>'] // ['1','3','5','7']
最后,表达式具有值,其中元素是成对的操作数:
['>>>1','>>>3','>>>5','>>>7']
你可以看到与表达式
的相似之处9+[1,3,5,7] ! [9,9,9,9]+[1,3,5,7] --> [10,12,14,16]
当有两个集中操作进行时,明显的值就是结果。
请注意,我没有用基本函数的结果来表达这一点。这部分是因为数组来自函数这一事实并不重要。此外,您的基本函数实际上是不允许的:基本函数结果可能无法分配。
关于无效函数,Vladimir F 已提交 a bug report 涵盖 gfortran 未检测到对 Fortran 2008 编号约束 C1290 的违反。在该报告中您可以看到,如果删除 result(s)
和将 int2str
声明为具有可分配属性,该函数被拒绝。其他一些编译器确实已经检测到违规。