一起学习Fortran:Fortran中的数组与字符串

我们之前使用了单个标量变量,在编程实践中,我们往往需要存储并操作一系列数字,这类数字序列通常被统称为数组。数组是一种多维变量,能够容纳多个值,并且我们可以通过一个或多个索引来访问这些值。在Fortran编程语言中,数组默认是基于1进行索引的;也就是说,在任何维度上,首个元素的索引均为1。

定义数组

静态声明

在Fortran中,我们能够声明任何类型的数组。声明数组变量时,通常采用两种常见的表示法:一种是使用维度属性(dimension),另一种则是在变量名后添加括号内的数组维度。

比如:

integer :: myArray
dimension myArray(5)  ! 声明一个包含5个整数元素的一维数组
integer :: myArray(5)  ! 同样是声明一个包含5个整数元素的一维数组

接下来举个栗子:

program test
  implicit none

  ! 1维整数数组
  integer, dimension(10) :: array1
  integer :: array2(10) ! 与array1等效表达的方式

  ! 2维浮点数组
  real, dimension(10, 2) :: array3

  ! 1维浮点数组
  real :: array4(0:9)
  real :: array5(-5:5)

  ! 给数组赋值
  array1 = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
  array2 = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
  array3 = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &
                      11, 12, 13, 14, 15, 16, 17, 18, 19, 20 /), (/ 10, 2 /))

  print *, array1
  print *, array2
  print *, array3
  print *, array4
  print *, array5

end program test

在这里插入图片描述

  • 这里:
    array1 和 array2 被初始化为1到10的整数序列。
    array3 使用reshape函数将一个1维数组转换为2维数组。reshape的第一个参数是要转换的1维数组,第二个参数是新数组的形状(在这里是10x2)。
    array4 和 array5 在此示例中未初始化,因此它们将包含默认值(通常是0或某种未定义的值,具体取决于编译器和运行时环境)。

我们如果想要为array4、array5赋值并打印后两位小数,我们可以:

program test
  implicit none

  ! 1维整数数组
  integer, dimension(10) :: array1
  integer :: array2(10) ! 等效表达方式

  ! 2维浮点数组
  real, dimension(10, 2) :: array3

  ! 1维浮点数组
  real :: array4(0:9)
  real :: array5(-5:5)

  integer :: i

  ! 初始化数组
  array1 = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
  array2 = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
  array3 = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &
                      11, 12, 13, 14, 15, 16, 17, 18, 19, 20 /), (/ 10, 2 /)) 
  array4 = (/ (i+0.1, i=0,9) /)
  array5 = (/ (i-5.0, i=0,10) /)
 
  ! 打印数组
  print *, 'array1: '
  print *, array1
 
  print *, 'array2: '
  print *, array2

  print *, 'array3: '
  do i = 1, size(array3, 1)
    print *, array3(i, :)
  end do

  print *, 'array4: '
  do i = lbound(array4, 1), ubound(array4, 1)
    print "(F8.2)", array4(i)
  end do
 
  print *, 'array5: '
  do i = lbound(array5, 1), ubound(array5, 1)
    print "(F8.2)", array5(i)
  end do
 
end program test

在这里插入图片描述

动态声明

Fortran语言的一个强大特性是它内置了对数组操作的支持;我们可以使用数组切片表示法对数组的全部或部分进行操作。
我们可以使用allocatable属性来声明动态数组。这意味着数组的大小在编译时是不确定的,而是在程序运行时根据需要分配。使用allocate语句为动态数组分配内存,当动态数组不再需要时,我们应该使用deallocate语句来释放它们占用的内存,可以避免内存泄漏。

program allocatable
    implicit none
  
    integer, allocatable :: array1(:)
    integer, allocatable :: array2(:,:)
    integer :: i 

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

    array1 = 0
    array2 = 0
  
    do i = 1, 10
      array1(i) = i
    end do
 
    do i = 1, 10
      array2(i,i) = i
    end do
  
    print *, "Array1: "
    do i = 1, 10
      print *, array1(i)
    end do
  
    print *, "Array2: "
    do i = 1, 10
      print *, array2(i,i)
    end do
  
    deallocate(array1)
    deallocate(array2)
  
  end program allocatable

在这里插入图片描述
运行结果如下:
在这里插入图片描述

数组切片

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

program array_slice
  implicit none

  integer :: i
  integer :: array1(10)  ! 1D integer array of 10 elements
  integer :: array2(10, 2)  ! 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
  array2 = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &
                      11, 12, 13, 14, 15, 16, 17, 18, 19, 20 /), (/ 10, 2 /)) 

  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

在这里插入图片描述
这里我们可以看一看使用python的方法,与Fortran的代码存在一定差别:

import numpy as np

array1 = np.zeros(10, dtype=int)
array1 = np.array([i for i in range(1, 11)])
array1[:] = 0
array1[0:5] = 1
array1[5:] = 1

array2 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
                    11, 12, 13, 14, 15, 16, 17, 18, 19, 20]).reshape(2, 10)

print(array1[0:10:2])
print(array2[0, :])
print(array1[9::-1])

在这里插入图片描述

字符串操作

静态字符串

在Fortran中,静态字符串的长度在声明时是固定的。使用character(len=n)来声明一个长度为n的字符串变量。可以直接将字符串字面量赋值给静态字符串变量,只要字面量的长度不超过变量声明的长度。使用//运算符可以拼接两个字符串。拼接时,需要确保结果字符串的长度不会超过目标变量的长度。

program string
    implicit none
  
    character(len=6) :: first_name
    character(len=4) :: last_name
    character(11) :: full_name
  
    first_name = 'GGBond'
    last_name = 'Dick'
  
    ! 拼接字符串
    full_name = first_name//' '//last_name
  
    print *, full_name
  
  end program string
可分配字符串

在Fortran里可以使用character(:), allocatable来声明一个可分配字符串。此时,字符串的长度在声明时是不确定的,需要在后续通过allocate语句或赋值时动态确定。而使用allocate(character(n) :: variable)可以显式分配字符串的长度

program allocatable_string
    implicit none
  
    character(:), allocatable :: first_name
    character(:), allocatable :: last_name
  
    ! Explicit allocation statement
    allocate(character(4) :: first_name)
    first_name = 'Dick'
  
    ! Allocation on assignment
    last_name = 'Big'
  
    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) :: "GGBond", "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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值