数组和字符串#

通常情况下,我们需要存储和操作一长串数字,而不是迄今为止我们一直使用的单个标量变量;在计算机编程中,此类列表称为 arrays

数组是 多维 变量,包含多个值,其中每个值都使用一个或多个索引访问。

Fortran 中的数组默认是 one-based ;这意味着沿任何维度的第一个元素位于索引 1 处。

数组声明#

我们可以声明任何类型的数组。声明数组变量有两种常见的表示法:使用 dimension 属性或通过将括号中的数组维度附加到变量名称。

示例: 静态数组声明

program arrays
  implicit none

  ! 1D integer array
  integer, dimension(10) :: array1

  ! An equivalent array declaration
  integer :: array2(10)

  ! 2D real array
  real, dimension(10, 10) :: array3

  ! Custom lower and upper index bounds
  real :: array4(0:9)
  real :: array5(-5:5)

end program arrays

数组切片#

Fortran 语言的一个强大特性是它对数组操作的内置支持。我们可以使用数组 切片 表示法对数组的全部或部分执行操作:

示例: 数组切片

program array_slice
  implicit none

  integer :: i
  integer :: array1(10)  ! 1D integer array of 10 elements
  integer :: array2(10, 10)  ! 2D integer array of 100 elements

  array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  ! Array constructor
  array1 = [(i, i = 1, 10)]  ! Implied do loop constructor
  array1(:) = 0  ! Set all elements to zero
  array1(1:5) = 1  ! Set first five elements to one
  array1(6:) = 1  ! Set all elements after five to one

  print *, array1(1:10:2)  ! Print out elements at odd indices
  print *, array2(:,1)  ! Print out the first column in a 2D array
  print *, array1(10:1:-1)  ! Print an array in reverse

end program array_slice

Fortran 数组以 column-major 顺序存储;第一个指数变化最快。

可分配(动态)数组#

到目前为止,我们已经在程序代码中指定了数组的大小 —— 这种类型的数组被称为 静态 数组,因为它的大小在我们编译程序时是固定的。

很多时候,在我们运行程序之前,我们并不知道数组需要多大,例如,如果我们正在从一个未知大小的文件中读取数据。

对于这个问题,我们需要 allocatable 数组。一旦我们知道数组需要多大,这些数组在程序运行时 被分配内存空间

示例: 可分配数组

program allocatable
  implicit none

  integer, allocatable :: array1(:)
  integer, allocatable :: array2(:,:)

  allocate(array1(10))
  allocate(array2(10,10))

  ! ...

  deallocate(array1)
  deallocate(array2)

end program allocatable

可分配的局部数组超出作用域时会自动释放。

字符串#

示例: 静态字符串

program string
  implicit none

  character(len=4) :: first_name
  character(len=5) :: last_name
  character(10) :: full_name

  first_name = 'John'
  last_name = 'Smith'

  ! String concatenation
  full_name = first_name//' '//last_name

  print *, full_name

end program string

示例: 可分配的字符串

program allocatable_string
  implicit none

  character(:), allocatable :: first_name
  character(:), allocatable :: last_name

  ! Explicit allocation statement
  allocate(character(4) :: first_name)
  first_name = 'John'

  ! Allocation on assignment
  last_name = 'Smith'

  print *, first_name//' '//last_name

end program allocatable_string

字符串数组#

字符串数组可以在 Fortran 中表示为 character 变量数组。 character 数组中的所有元素都具有相等的长度。但是,可以将不同长度的字符串作为输入提供给数组构造函数,如下例所示。如果它们分别比“字符”数组的声明长度长或短,它们将被截断或用空格右填充。最后,在将值打印到标准输出时,我们使用内部函数 trim 删除任何多余的空格。

示例: 字符串数组

program string_array
  implicit none
  character(len=10), dimension(2) :: keys, vals

  keys = [character(len=10) :: "user", "dbname"]
  vals = [character(len=10) :: "ben", "motivation"]

  call show(keys, vals)

  contains

  subroutine show(akeys, avals)
    character(len=*), intent(in) :: akeys(:), avals(:)
    integer                      :: i

    do i = 1, size(akeys)
      print *, trim(akeys(i)), ": ", trim(avals(i))
    end do

  end subroutine show

end program string_array