Fortran学习:chapter7数组

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指有53,而不是计算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/ !I2增加到4,依据顺序取后边的值,这里A(2)=2,A(3)=3,A(4)=4;A(1),A(5)没有赋值

    !在最后多加一个数字,同样可以改变计数器的累加数值,默认值为1
    !(A(I),I=2,10,2),循环执行5次,I分别为246810
    
    !隐含式循环可以多层嵌套,可以应用于多维数组上:
    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(12)=3,m(21)=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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值