##個人理解,歡迎指正##
- 指針就是記錄數據的內存地址的變量。指針可以指向單個變量,也可以指向數組。
- 數組是一個概念,是若干個類型相同的元素的有序集合。
在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(1~5)=>b(1~5) 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 . . .