fortran 90在指针赋值期间预期的边界规范

时间:2014-03-05 12:23:49

标签: pointers fortran90 bounds specifications

我是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

现在程序可以运行并提供所需的结果。但是,在这种情况下我没有使用指针函数,因为我的函数返回一个可分配的指针数组,而不是指向数组的指针。有没有办法在这里使用指针功能?谢谢

1 个答案:

答案 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的误解。