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

hoa*_*ran 1 pointers specifications fortran90 bounds

我是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
Run Code Online (Sandbox Code Playgroud)

在编译期间我得到了错误:

 non_zeros(j) => a(i)
 1
 Error: Expected bounds specification for 'non_zeros' at (1)
Run Code Online (Sandbox Code Playgroud)

你能告诉我我做错了什么吗?先感谢您!

更新我的问题:根据高性能标记的解释,我定义了派生类型:

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
Run Code Online (Sandbox Code Playgroud)

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

Hig*_*ark 5

要将非零元素a转换为新数组,您可以简单地声明

integer, dimension(:), allocatable :: non_zeros
Run Code Online (Sandbox Code Playgroud)

然后用声明填充它

non_zeros = pack(a,a/=0)
Run Code Online (Sandbox Code Playgroud)

并避免完全摆弄指针.这依赖于2003标准中引入的功能,但它是由所有(我认为)目前市场上的Fortran编译器实现的.

你编写的代码对我来说就好像你想nz成为一个指针数组,每个元素都nz指向一个非零元素a.如果我是对的,你就误解了诸如此类的陈述

integer, pointer :: nz(:)
Run Code Online (Sandbox Code Playgroud)

声明.它没有声明一个指向整数的指针数组,它声明了一个指向整数数组的指针.当你写作

non_zeros(j) => a(i)
Run Code Online (Sandbox Code Playgroud)

你犯了一个错误,试图设置一个non_zeros指向元素的元素a.

错误消息在这里具有误导性,因为编译器将non_zeros(j)语法解释为语法错误的bounds-specbounds-remapping,但错误是语义错误,编译器无法理解您对Fortran的误解.