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 . . .

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM