我正在使用Silverfrost FTN95,因为我不是专家,我需要你的帮助来创建一个函数,它接受一个逻辑变量数组并返回一个整数变量数组,0表示false,1表示true。 我写这个简单的代码只是为了简化我试图实现它的方式:
program main
logical, dimension(2,1) :: a
integer, dimension(2,1) :: b
integer, dimension(2,1) :: toInt
a(:,1)=.false.
b=toInt(a)
write(*,*)b
end program
function toInt(log) result(val)
logical, dimension(2,1), intent(in) :: log
integer, dimension(2,1) :: val
do i=1,2
if (log(i,1)) then
val(i,1) = 1
else
val(i,1) = 0
end if
end do
end function
这段代码给了我这个错误:在数组边界下标中预期的INTEGER表达式,变量' A'没有INTEGER类型(在行#34; b = toInt(a)"),我无法找到错误。 任何解决我的问题的建议或其他方法都会非常有帮助。 感谢
答案 0 :(得分:1)
出现错误消息是因为在程序main
中您已将toint
声明为数组,因此语句toint(a)
被解释为尝试索引该数组使用逻辑a
。您可能认为您已将toint
声明为返回整数数组的外部函数,但您没有给编译器足够的信息来与函数定义建立连接。
您可以通过从程序中删除toint
的误导性声明,将行end program
移动到源文件的末尾,并将行contains
插入其中来解决此问题。您目前有end program
。这些步骤将使toint
内部,编译器将负责匹配您对函数本身的调用。
但我认为有三种,可能更多,更好的方式,而不是你现在的方式。
一个是按照
的方式写一些东西integer, dimension(x,y) :: a,b,r
logical, dimension(x,y) :: m
! set the elements of m as you wish
a = 1
b = 0
r = merge(a,b,m)
将r
a
m
.true.
b
和m
.false.
x
y
merge
where
和r = 0 ! all elements are set to 0
where(m) r = 1 ! where m is true, r is set to 1
是什么并不重要,只是a
的数组参数是一致的。将其转换为重复使用的功能应该相对容易。
其次,您可以使用b
语句,也许就像这样
elemental
此方法省略了{{1}}和{{1}}。
第三,您可以研究编写一个{{1}}函数,该函数对标量和任何等级的数组进行操作。我将这个作为练习。它需要对您已有的函数进行一些修改,以便它在标量而不是固定大小的数组上运行。第三种方法可能是最好的 - 最简单,最灵活,最容易编程。
答案 1 :(得分:0)
除了Mark的3种可能性之外,第4种是合并内在函数 - 实际上这基本上是他的第3个建议,只是它已经在语言中了。这是一个例子:
ian@ian-pc:~/test/stack$ cat merge.f90
Program m
Implicit None
Logical, Dimension( 1:3, 1:2 ) :: log
Integer, Dimension( 1:3, 1:2 ) :: val
log = .False.
log( 2, 1 ) = .True.
val = Merge( 1, 0, log )
Write( *, * ) val
End Program m
ian@ian-pc:~/test/stack$ nagfor -C=all -C=undefined merge.f90
NAG Fortran Compiler Release 5.3.1(907)
[NAG Fortran Compiler normal termination]
ian@ian-pc:~/test/stack$ ./a.out
0 1 0 0 0 0