• Fortran的数组与指针


    ##个人理解,欢迎指正##

    • 指针就是记录数据的内存地址的变量。指针可以指向单个变量,也可以指向数组。
    • 数组是一个概念,是若干个类型相同的元素的有序集合。

    在Fortran中,数组中存放的元素可以是整数,实数,复数,甚至结构体(又称“自定义数据类型”),但不能是指针 即,不存在这样一个数组,该数组的每一个元素都是一个指针,分别指向不同的数组。

    那么怎样才能实现这样一个数组,其中的每一个元素都能指向其他的数组呢?

    实现一个数组,其中的元素指向不同的数组

    因为数组中存放的元素可以是结构体,那么可以通过定义一个结构体,在结构体中定义一个指针变量来解决。

    type container
      class(object), pointer :: obj
    end type container
    
    type(container), allocatable, dimension(:) :: objects
    allocate (objects(0:num_objects))
    objects(0)%obj => s1

    其中,objects(0:num_objects)就是定义的结构体数组,数组中的第0个元素的obj分量(objects(0)%obj)指向一个变量s1,s1是类型为object的变量。

    上式objects数组中的每一个元素都是指向单个变量的,那么如果需要结构体数组中的每一个元素都指向一个数组,则定义结构体中的指针变量需要定义为是指向数组的(下面第10行):

     1 program ex1
     2 implicit none
     3 integer :: i,j
     4 
     5 !//声明目标数组work
     6 real(RK),allocatable,target :: work(:,:)
     7 
     8 !//定义结构体类型qcontainer,该类型中的分量obj可以指向一个一维的数组
     9 type qcontainer
    10         real(RK),pointer :: obj(:)
    11 end type qcontainer    
    12 
    13 !//声明一个一维的的数组qtwork
    14 type(qcontainer),allocatable :: qtwork(:) 
    15 
    16 !//定义数组work并赋初值
    17 allocate(work(2,3))
    18 do i=1,2
    19     do j=1,3
    20         work(i,j)=i*j**2*7
    21     end do
    22 end do
    23 
    24 !//定义数组qtwork
    25 allocate(qtwork(3))
    26 
    27 !//qtwork中第j个元素的object分量指向数组work的第j列
    28 qtwork(j)%obj => work(:,j)
    29 
    30 
    31 end program ex1

     

    关于彭书中的“”指针数组“

    彭国伦《Fortran95程序设计》书中275页上说,“指针也可以声明成数组”,并给了以下示例代码

     1 program ex1004
     2   implicit none
     3   integer, pointer :: a(:)
     4   integer, target  :: b(5)=(/ 1,2,3,4,5 /)
     5   ! 把指针数组a指向数组b
     6   a=>b  
     7   ! a(15)=>b(15)
     8   write(*,*) a
     9   a=>b(1:3)
    10   ! a(1)=>b(1), a(2)=>b(2), a(3)=>b(3)
    11   write(*,*) a 
    12   a=>b(1:5:2)
    13   ! a(1)=>b(1), a(2)=>b(3), a(3)=>b(5)
    14   write(*,*) a 
    15   a=>b(5:1:-1)
    16   ! a(1)=>b(5), a(2)=>b(4), a(3)=>b(3), a(4)=>b(2), a(5)=>b(1)
    17   write(*,*) a 
    18   stop
    19 end

    这里用指针a表示了数组b。这告诉我们,指针不仅可以指向单个变量的内存地址,还可以指向数组。

    但是需要注意的是,指针a(:)中的每一个变量a(i)都确定的表示某一个单独的变量,而不是表示变量的集合(数组)即指针a(:)只能表示一个数组,不能同时表示多个数组的集合。

    另外,需要注意,声明指针a的时候,可以说明a的形状,但不能指定a的数组大小。换句话说,声明指针a的时候,可以告诉编译器,a指向的是几维的数组,但是不能告诉编译器,a指向的数组是大小是100×100的。

    所以,如果第3行换成以下语句是非法的

    !//非法的代码
     integer, pointer :: a(5)

    编译器错误提示是“ ALLOCATABLE or POINTER attribute dictates a deferred-shape-array.” 即声明变量时,allocatable或pointer的属性表明数组为假定形状数组。如果此时声明上述语句(即给了数组的大小),那显然矛盾。

     

    总结

    • 在Fortran中,指针可以指向一个数组或者一个数组中的一部分,但指针不能同时表示多个数组。
    • 数组是若干相同类型元素的集合,但数组的元素不能是指针。
    • 如果想实现一个数组,且数组的元素具有指针的功能,可以定义一个结构体类型的数组。

     

    附录代码:

     

     1 program test
     2     implicit none
     3     integer i,j,k
     4     real,allocatable,target :: work(:,:)
     5 
     6     type qcontainer
     7         real,pointer :: obj(:)
     8     end type qcontainer
     9 
    10     type(qcontainer),allocatable :: qtwork(:) ,qtemp
    11 
    12 
    13     allocate(work(2,3))
    14     allocate(qtwork(3))
    15 
    16     !//初始化
    17     do j=1,3
    18         do i=1,2
    19             work(i,j)=i*j**2*7
    20         end do
    21     end do
    22 
    23     !//指针变量赋值
    24     do j=1,3
    25         qtwork(j)%obj => work(:,j)
    26     end do
    27 
    28     !//打印输入数组
    29     print*,"input array: "
    30     do j=1,3
    31         print*,work(:,j)
    32     end do
    33 
    34     !//打印指向的数组
    35     print*,"point array: "
    36     do j=1,3
    37         print*,qtwork(j)%obj
    38     end do
    39 
    40     !//置换
    41     print*,"swap"
    42     qtemp = qtwork(1)
    43     do j=1,2
    44         qtwork(j) = qtwork(j+1)
    45     end do
    46     qtwork(3)=qtemp
    47 
    48     !//输出置换结果
    49     do j=1,3
    50         print*,qtwork(j)%obj
    51     end do
    52 
    53     deallocate(work)
    54 
    55 
    56     end program

     

    输出结果:

     

     input array:
       7.000000       14.00000
       28.00000       56.00000
       63.00000       126.0000
     point array:
       7.000000       14.00000
       28.00000       56.00000
       63.00000       126.0000
     swap
       28.00000       56.00000
       63.00000       126.0000
       7.000000       14.00000
    Press any key to continue . . .

     

  • 相关阅读:
    1217 实验四 递归下降语法分析程序设计
    1118实验三有限自动机的构造与识别
    11.12评论
    C语言文法
    25-陈庆祥-词法分析
    0909我的看法
    文法定义评价
    1029 语言文法
    1022 词法分析程序
    0909 随说
  • 原文地址:https://www.cnblogs.com/jiangleads/p/10511877.html
Copyright © 2020-2023  润新知