我是Fortran的新手。我正在Fortran 90中编写一个程序来获取数组的非零元素,并使用指针函数将它们放入一个新的数组中:
program prog
implicit none
integer, target :: a(5)
integer :: i
integer, pointer :: nz(:)
a(1) = 1
a(2) = 0
a(3) = 0
a(4) = 2
a(5) = 3
nz => non_zeros(a)
do i=1, size(nz)
write(*,*) nz(i)
end do
contains
function non_zeros(a)
integer, target :: a(:)
integer, pointer:: non_zeros(:)
integer :: n, i, j
n = count(a .ne. 0)
allocate(non_zeros(n))
j = 0
do i=1, m
if (a(i) .ne. 0) then
j = j + 1
non_zeros(j) => a(i)
end if
end do
end function non_zeros
end program prog
在编译期间我收到错误:
non_zeros(j) => a(i)
1
Error: Expected bounds specification for 'non_zeros' at (1)
你能告诉我我做错了什么吗?提前谢谢!
更新我的问题:根据高性能标记的解释,我定义了派生类型:
program prog
implicit none
integer, target :: a(5)
type dt
integer, pointer :: x
end type
type(dt), allocatable :: nz(:)
a(1) = 1
a(2) = 0
a(3) = 0
a(4) = 2
a(5) = 3
nz = non_zeros(a)
contains
function non_zeros(a)
integer, target :: a(:)
type(dt), allocatable :: non_zeros(:)
integer :: n, i, j
n = count(a .ne. 0)
allocate(non_zeros(n))
j = 0
do i=1, m
if (a(i) .ne. 0) then
j = j + 1
non_zeros(j)%x => a(i)
end if
end do
end function non_zeros
end program prog
现在程序可以运行并提供所需的结果。但是,在这种情况下我没有使用指针函数,因为我的函数返回一个可分配的指针数组,而不是指向数组的指针。有没有办法在这里使用指针功能?谢谢
答案 0 :(得分:5)
要将a
的非零元素放入新数组,您只需声明
integer, dimension(:), allocatable :: non_zeros
然后使用语句
填充它non_zeros = pack(a,a/=0)
并避免完全摆弄指针。这依赖于2003标准中引入的功能,但它是由所有(我认为)当前市场上的Fortran编译器实现的。
您编写的代码对我来说就像您希望nz
是一个指针数组一样,nz
中的每个元素都指向a
的非零元素。如果我是对的,你就误解了诸如
integer, pointer :: nz(:)
声明。它没有声明一个指向整数的指针数组,它声明了一个指向整数数组的指针。当你写
non_zeros(j) => a(i)
你错误地试图将non_zeros
的元素设置为指向a
的元素。
错误消息在这里会产生误导,因为编译器会将non_zeros(j)
解释为语法错误的 bounds-spec 或 bounds-remapping ,但错误是语义错误,编译器不理解你对Fortran的误解。