Fortran學習筆記目錄
書接上回:Fortran學習筆記:02 流控制語句
數組(Array)
定義數組
一維數組
program main
implicit none
integer :: i
integer :: a(10)
do i=1,10,1
a(i)=i*i;
end do
do i=1,10,1
write(*,*) "i=",i,"i*i=",a(i)
end do
end
數組申明格式:
Datatype name(size)
注意,size必須為常數,數組索引默認從1開始
多維數組
最多可以聲明7維數組,聲明格式
integer :: a(D1,D2,D3,...,Dn) !n維數組
其他數組聲明方式
沒有特別賦值的情況下,數組的默認索引是從1開始的,例如
integer :: a(3) !包含a(1),a(2),a(3)
自定義范圍聲明
integer :: a(0:2) !一維數組包含a(0),a(1),a(2)
integer :: b(2:3,-1:1) !二維數組b(2~3,-1~1)都可以使用
賦初值
直接賦初值
integer :: a(row,col)=0
program main
implicit none
integer ,parameter:: row=10
integer ,parameter:: col=10
integer :: a(row,col)=0
integer :: i,j
do i=1,row,1
do j=1,col,1
write(*,*) a(i,j)
end do
end do
end
對數組的操作
Fortran 95擁有強大的數組操作方法,簡化許多for循環操作
等號賦值
integer :: a(10),b(10)
!!數組賦值!!
a=10
!等效於
do i=1,10,1
a(i)=10
end do
!!數組復制!!
b=a
!等效於
do i=1,10,1
b(i)=a(i)
end do
矩陣基本運算
\(+,-,*,/\)基本四則運算與Matlab中點乘、點除方法相同,均為數組對應元素進行四則運算
數組操作 | 意義 |
---|---|
\(a=b+c\) | \(a(i,j)=b(i,j)+c(i,j)\)矩陣對應位置數值相加 |
\(a=b-c\) | \(a(i,j)=b(i,j)-c(i,j)\)矩陣對應位置數值相減 |
\(a=b*c\) | \(a(i,j)=b(i,j)*c(i,j)\)矩陣對應位置數值相乘 |
\(a=b/c\) | \(a(i,j)=b(i,j)/c(i,j)\)矩陣對應位置數值相除以 |
program main
implicit none
integer ,parameter:: row=10
integer ,parameter:: col=10
integer :: a(row,col)
real :: b(row,col),c(row,col)
integer :: i,j
a=10
b=.5
c=a*b
do i=1,row,1
do j=1,col,1
write(*,*) c(i,j)
end do
end do
end
矩陣切片運算
可以通過對矩陣中部分數據進行賦值操作,Matlab中矩陣切片方式繼承了Fortran語言這一形式。
a(3,5)=5 !a(3),a(4),a(5)數值設置為5
a(3:)=5 !a(3)之后的數值設置為5
a(3:5)=(/3,4,5/) !a(3),a(4),a(5)數值分別設為3,4,5
a(1:3)=b(4:6) !a,b賦值
a(1:5:2)=3 !a(1),a(3),a(5)賦值為3,1~5增量為2
a(1:10)=a(10:1:-1) !翻轉a
integer :: a(5),b(5,5)
a(:)=b(:,2) !b中第二列賦值給a
integer :: a(5,5),b(5,5,5)
a(:,:)=b(:,:,1)
注意在進行數組操作時,需要保證兩邊數組數目一致
WHERE 語句
where是Fortran95添加的功能,可以通過邏輯判斷,對數組部分元素進行操作。例如以下例子,可以將a中<3的數組元素賦值給b
program main
implicit none
integer :: i
integer :: a(5)=(/(i,i=1,5)/)
integer :: b(5)=0
where(a<3)
b=a
end where
write(*,*) "a=",a
write(*,*) "b=",b
stop
end
!輸出
a= 1 2 3 4 5
b= 1 2 0 0 0
where也可以作嵌套,elsewhere(邏輯判斷)
program main
implicit none
integer :: i
integer :: a(5)=(/(i,i=1,5)/)
integer :: b(5)=0
where(a<3)
b=1
elsewhere(a>4)
b=2
elsewhere
b=3
end where
write(*,*) "a=",a
write(*,*) "b=",b
end
!輸出
a= 1 2 3 4 5
b= 1 1 3 3 2
FORALL語句
forall是Fortran95中添加的功能
program main
implicit none
integer :: i
integer :: a(5)=0
forall(i=1:5:2) !1~5,增量為2
a(i)=5
end forall
write(*,*) "a=",a
forall(i=1:5)
a(i)=i
end forall
write(*,*) "a=",a
stop
end
!輸出
a= 5 0 5 0 5
a= 1 2 3 4 5
對於二維數組,有相同的操作
program main
implicit none
integer :: i,j
integer :: a(5,5)=0
forall(i=1:5:1,j=1:5:1)
a(i,j)=i+j
end forall
do i=1,5,1
write(*,*) a(:,i)
end do
stop
end
!輸出
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
還可以在forall中添加條件判斷,語法為
forall(索引1,索引2,邏輯判斷)
program main
implicit none
integer :: i,j
integer,parameter :: N = 5
integer :: a(N,N)=0
forall(i=1:N,j=1:N,i>j) a(i,j)=1 !上三角
forall(i=1:N,j=1:N,i==j) a(i,j)=2 !對角線
forall(i=1:N,j=1:N,i<j) a(i,j)=3 !下三角
write(*,"(5(5I5,/))") a
stop
end
!輸出
2 1 1 1 1
3 2 1 1 1
3 3 2 1 1
3 3 3 2 1
3 3 3 3 2
forall可以嵌套多層,forall中可以使用where,但是where中不能使用forall,例如
program main
implicit none
integer :: i,j
integer,parameter :: N = 5
integer :: a(N,N)=0
forall(i=1:N)
forall(j=1:N)
a(i,j)=i+j
end forall
end forall
write(*,"(5(5I5,/))") a
forall(i=1:N)
where(a(i,:)/=6)
a(i,:)=0
end where
end forall
write(*,"(5(5I5,/))") a
stop
end
!輸出
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
0 0 0 0 6
0 0 0 6 0
0 0 6 0 0
0 6 0 0 0
6 0 0 0 0
數組的存儲規則
可變大小的數組
利用allocate與deallocate分配與釋放內存
program main
implicit none
integer :: students
integer,allocatable :: a(:)
integer :: i
write(*,*) "How many students:"
read(*,*) students
allocate(a(students)) !分配內存
write(*,*) "size of array = ",size(a)
deallocate(a) !釋放內存
stop
end
測試程序(測試當前計算機所能分配的最大內存)
program main
implicit none
integer :: size_N=0,error=0
integer,parameter :: one_mb=1024*1024
character,allocatable :: a(:)
do while(.true.)
size_N=size_N+one_mb
allocate(a(size_N),stat=error) !分配內存
if(error/=0) then
exit
end if
write(*,"('Allocate ',I10,'bytes')") size_N
write(*,"(F10.2,'MB used')") real(size_N)/one_mb
deallocate(a) !釋放內存
end do
stop
end
數組應用實例
冒泡排序
program main
implicit none
integer :: a(5)=(/10,2,5,4,6/)
integer :: i,j,temp
write(*,"(5(I5))") a
do i=1,5
do j=i+1,5
if(a(i)>a(j)) then
temp=a(i)
a(i)=a(j)
a(j)=temp
end if
end do
end do
write(*,"(5(I5))") a
stop
end program
!輸出
10 2 5 4 6
2 4 5 6 10