1.数组
1.1声明数组
数组的声明方法:Datatype name(size),其中,Datatype代表数组的类型,除4种基本类型(integer、real、complex、logical),还有type自定义的类型;name代表数组变量的名字,size代表数组的大小,必须用整型。
!声明数组
!法一
integer a1(10)
!法二
integer,dimension(10)::a2
!法三
integer a3
dimension a3(10)
!法四
Type::person
real::height,weight
End type
Type(person)::a4(10) !用personl这个新类型来声明数组
a4(1)%height=180.0 !在变量后边加上“%”来使用person类型中的元素
a4(1)%weight=70
implicit none
integer,parameter::students=5
integer::student(students)
integer i
Type::person
real::height,weight
end Type
Type(person)::a(1) !声明数组
a(1)%height=180.0 !在变量后面加上"%"来使用person类型中的元素
a(1)%weight=70
write(*,"('person:',f5.1,f5.1)") a(1)%weight,a(1)%height
do i=1,students
write(*,"('Number:',I2)")i
read(*,*)student(i)
end do
do while(.true.)
write(*,*)"Query:"
read(*,*)i
if(i<=0 .or. i>students) exit
write(*,*)student(i)
end do
pause
1.2 二维数组
使用二维数组时,要给两个坐标索引值。
implicit none
integer,parameter::classes=5
integer,parameter::students=5
integer::student(students,classes)
integer s !用来赋值学生号码
integer c !用来赋值班级号码
do c=1,classes
do s=1,students
write(*,"('Number',I2,' of class',I2)")s,c
read(*,*)student(s,c) !第c班的第s位学生
end do
end do
do while(.true.)
write(*,*)"class:"
read(*,*)c
if(c<=0 .or. c>classes) exit
write(*,*)"student:"
read(*,*)s
if(s<=0 .or. s>students) exit
write(*,"('score:',I3)") student(s,c)
end do
pause
将二维数组作为矩阵使用。
implicit none
!二维数组作为矩阵使用
!让用户输入两个2*2矩阵的值,再把这两个矩阵相加
integer,parameter::row=2
integer,parameter::col=2
integer::matrixA(row,col)
integer::matrixB(row,col)
integer::matrixC(row,col)
integer r !用来赋值row
integer c !用来赋值col
!读取矩阵A的内容
write(*,*)"Matrix A"
do r=1,row
do c=1,col
write(*,"('A(',I1,',',I1,')=')")r,c
read(*,*)matrixA(r,c)
end do
end do
!读取矩阵B的内容
write(*,*)"Matrix B"
do r=1,row
do c=1,col
write(*,"('B(',I1,',',I1,')=')")r,c
read(*,*)matrixB(r,c)
end do
end do
!把矩阵A,B相加并输出结果
write(*,*)"Matrix A+B="
do r=1,row
do c=1,col
matrixC(r,c)=matrixB(r,c)+matrixA(r,c)
write(*,"('(',I1,',',I1,')=',I3)")r,c,matrixC(r,c)
end do
end do
1.3多维数组
Fortran最多可以声明7维数组。
!与上述代码作用一致,只是再循环上多了一层,改进了一点算法。
implicit none
!三维数组
integer,parameter::row=2
integer,parameter::col=2
integer::matrix(row,col,3)
integer m !用来赋值第几个矩阵
integer r !用来赋值row
integer c !用来赋值col
!读取矩阵的内容
do m=1,2
write(*,"('Matrix',I1)")m
do r=1,row
do c=1,col
write(*,"('(',I1,',',I1,')=')")r,c
read(*,*)matrix(r,c,m)
end do
end do
end do
!把第1,2个矩阵相加
write(*,*)"Matrix1+Matrix2="
do r=1,row
do c=1,col
matrix(r,c,3)=matrix(r,c,1)+matrix(r,c,2)
write(*,"('(',I1,',',I1,')=',I3)")r,c,matrix(r,c,3)
end do
end do
1.5另类数组的声明
通常情况下数组的索引值从1开始:
例如:integer a(5) !a(1),a(2),a(3),a(4),a(5)这5个元素
通过声明改变这个默认的规则:①integer a(0:5) !a(0),a(1),a(2),a(3),a(4),a(5)这6个元素
②integer a(-3,3) !a(-3),a(-2),a(-1),a(0),a(1),a(2),a(3)这7个元素
③integer a(5,0:5) !a(1~ 5 ,0~5)
④integer a(2:3,-1:3) !b(2~ 3,-1~3)
2.数组内容的设置
2.1 赋初值
integer A2(5)
DATA A2 /1,2,3,4,5/ !A(1)=1,A(2)=2,...,A(5)=5
!DATA的数据区中还可以使用星号*来表示数据重复
integer B(5)
DATA B /5*3/ !这里5*3指有5个3,而不是计算5*3
!B(1)=3,B(2)=3,...,B(5)=3
!隐含式循环功能用来设置数组的初值
integer A1(5)
integer I1
DATA(A1(I1),I1=2,4)/2,3,4/ !I从2增加到4,依据顺序取后边的值,这里A(2)=2,A(3)=3,A(4)=4;A(1),A(5)没有赋值
!在最后多加一个数字,同样可以改变计数器的累加数值,默认值为1
!(A(I),I=2,10,2),循环执行5次,I分别为2、4、6、8、10
!隐含式循环可以多层嵌套,可以应用于多维数组上:
integer A(2,2)
integer I,J
DATA((A(I,J),I=1,2),J=1,2)/1,2,3,4/ !括号里面的循环会先执行
!结果:A(1,1)=1,A(2,1)=2,A(1,2)=3,A(2,2)=4
!Fortran90中,可以省略DATA描述,直接设置初值
integer::aa(5)=(/1,2,3,4,5/) !注意括号与除号之间不能有空格
!这里aa(1)=1,aa(2)=2,aa(3)=3,...
!省略DATA时,不能像使用DATA时一样,每个元素都必须给定初值
!Integer::a(5)=(/(2,I=2,4))/,这里a(1),a(5)没有给定,会出现错误
!integer::a(5)=(/1,(2,I=2,4),5/),这里a(1)=1,a(2)=a(3)=a(4)=2,a(5)=5
!integer::I
!integer::a(5)=(/I,I=1,5/) ,a(1)=1,a(2)=2,...,a(5)=5
实例:查询学生成绩
implicit none
integer,parameter::students=5
integer::student(students)=(/80,90,85,75,95/)
integer i
do while(.true.)
write(*,*)"Query:"
read(*,*)i
if(i<=0 .or. i>students)exit
write(*,*)student(i)
end do
integer,parameter::row=2
integer,parameter::col=2
integer::m(row,col)
integer r !用来赋值row
integer c !用来赋值col
data((m(r,c),r=1,2),c=1,2)/1,2,3,4/ !m(1,1)=1,m(2,1)=2,m(1,2)=3,m(2,2)=4
write(*,"(I3,I3,/,I3,I3)")((m(r,c),c=1,2),r=1,2) !按顺序输出m(1,1)=1,m(1,2)=3,m(2,1)=3,m(2,2)=4
2.2 对整个数组操作
integer,parameter::row=2
integer,parameter::col=2
integer::ma(row,col)=(/1,2,3,4/)
integer::mb(row,col)=(/2,3,4,5/)
integer::mc(row,col)
integer::i,j
mc=ma+mb
write(*,"(I3,I3,/,I3,I3)")((mc(i,j),i=1,2),j=1,2)
2.3 对部分数组操作
①a(3:)=5, a(3)=a(4)=a(5)=5;
②a(1:3)=b(4:6), a(1)=b(4),a(2)=b(5),a(3)=b(6)
③a(1:5:2)=3, a(1)=a(3)=a(5)=3
④a(1:10)=a(10:1:-1), 将a中元素倒序
⑤a(:)=b(:,2), 将二维数组b的第二列元素按顺序给一维数组a
⑥a(:,:)=b(:,:,1), 将三维数组b的一部分给二维数组a
要求:
(1)等号两边所使用的数组元素数目一样多;
(2)同时使用多个隐含式循环时,较低维的循环可以想象为内层的循环。
eg:integer::a(2,2),b(2,2)
b=a(2:1:-1,2:1:-1)
b(1,1)=a(2,2),b(2,1)=a(1,2),b(1,2)=a(2,1),b(2,2)=a(1,1)
integer,parameter::row=2
integer,parameter::col=2
integer::a(2,2)=(/1,2,3,4/)
!a(1,1)=1,a(2,1)=2,a(1,2)=3,a(2,2)=4
integer::b(4)=(/5,6,7,8/)
integer::c(2)
write(*,*)a
write(*,*)a(:,1)
c=a(:,1)
write(*,*)c
write(*,*)c(2:1:-1)
c=b(1:4:2)
write(*,*)c
2.4 WHERE
用来取出部分数组内容进行设置。
integer::i
integer::a(5)=(/(i,i=1,5)/)
!a(1)=1,a(2)=2,...a(5)=5
integer::b(5)=0
!把a(1-5)中<3的元素值设置给b
where(a<3)
b=a
end where
!where处理问题时两者间的长度必须一致
!把a(1-5)中<3的元素值设置给b
where(a<3)
b=1
elsewhere !配合使用elsewhere
b=2
end where
where(a<2) b=1
elsewhere(a>5) b=2
elsewhere b=3
end where
write(*,"(5(I3,1X))")b !5个数字的设置均为一个整数占3格,一个空格
例子:假设年所得3万以下所得税率为10%,3万到5万之间为12%,5万以上为15%。使用WHERE命令来计算,并记录10个人的所得税金额。
implicit none
integer::i
real::income(10)=(/25000,30000,50000,40000,35000,&
60000,27000,45000,20000,70000/)
real::tax(10)=0
where(income<30000.0)
tax=income*0.10
elsewhere(income<50000.0)
tax=income*0.12
elsewhere
tax=income*0.15
end where
write(*,"(10(F8.1,1X))") tax
2.5 FORALL
语法:
forall(triplet1[,triple2[,triplet3…]],mask)
…
end forall
tripletn用来赋值数组坐标范围的值,mask用作条件判断且只作用于数组中符合条件的元素。
例子:声明一个二维数组作为二维矩阵使用,使用forall命令把矩阵的上半部设置为1,对角线部分设置为2,下半部设置为3。
implicit none
integer I,J
integer,parameter::size=5
integer::a(size,size)
forall(I=1:size,J=1:size,I>J) a(I,J)=1
forall(I=1:size,J=1:size,I==J) a(I,J)=2
forall(I=1:size,J=1:size,I<J) a(I,J)=3
write(*,"(5(5I5,/))")a
2.6 可变大小的数组
某些情况下,要等到程序执行之后,才会知道所需要使用的数组大小。
allocate(a( )) !配置内存空间;
deallocate !逆向运行,把allocate命令所得到的内存空间释放掉。
allocate(a(100),stat=erro) !error是事先声明的整型变量,做allocate这个动作时会经由stat这个叙述传给error一个数值,如果error=0则表示allocate数组成功,而如果error不等于0,则表示allocate数组失败。
2.7 数组的应用
例1:选择排序法
swap命令可以用来交换两个变量的内容,在main函数中使用。
implicit none
integer,parameter::size=10
integer::a(size)=(/5,3,6,4,8,7,1,9,2,10/)
integer::i,j
integer::t
do i=1,size-1
do j=i+1,size
if(a(i)>a(j)) then
t=a(i)
a(i)=a(j)
a(j)=t
end if
end do
end do
write(*,"(10I4)")a
例2:
implicit none
integer,parameter::L=3,M=4,N=2
real::A(L,M)=(/1,2,3,4,5,6,7,8,9,10,11,12/)
real::B(M,N)=(/1,2,3,4,5,6,7,8/)
real::C(L,N)
integer::i,j,k
do i=1,L
do j=1,N
C(i,j)=0.0
do k=1,M
C(i,j)=C(i,j)+A(i,k)*B(k,j)
end do
end do
end do
do i=1,L
write(*,*)C(i,:)
end do
3.课后习题
implicit none
!1
integer,parameter::size=10
integer::i
integer::a(size)=(/(i*2,i=1,10)/)
write(*,"('a(i),i=1:10的均值为:',f5.2)")real(sum(a))/real(10)
!2
!integer a(5,5) 5*5=25个
!integer b(2,3,4) 2*3*4=24个
!integer c(3,4,5,6) 3*4*5*6=360个
!integer d(-5:5) 11个
!integer e(-3:3,-3:3) 7*7=49个
!3
integer::i
integer,parameter::size=10
integer::f(size)
f(1)=0
f(2)=1
do i=3,10
f(i)=f(i-1)+f(i-2)
end do
write(*,"(10I4)")f
!4
integer,parameter::size=10
integer::a(size)=(/5,3,6,4,8,7,1,9,2,10/)
integer::i,j,t
do i=1,size-1
do j=i+1,size
if(a(i)<a(j)) then
t=a(i)
a(i)=a(j)
a(j)=t
end if
end do
end do
write(*,"(10I4)")a
!5
integer,parameter::size=5
integer::a(size,size)
integer::i,j=0
integer::count=0
integer::rank1,rank2=0
do i=1,size
do j=1,size
count=count+1
if(i==2 .and. j==2) then
rank1=count
end if
if(i==3 .and. j==3) then
rank2=count
exit
end if
end do
end do
write(*,"('a(2,2)的所在位置:',I2,',a(3,3)的所在位置:',I2)")rank1,rank2