Fortran中的数组与动态数组

Fortran中的数组与动态数组

数组与动态数组示例

program array_exam
  implicit none

  integer, parameter :: n = 5
  integer :: i

  integer :: static_array(n) = [1,2,3,4,5]

  integer, allocatable :: dynamic_array(:)

  allocate(dynamic_array(n))

  dynamic_array = [(i * 2, i = 1, n)]

  print *, "Static Array:"
  do i = 1, n
    print *, static_array(i)
  end do
  
  print *, "Dynamic Array:"
  do i = 1, n
    print *, dynamic_array(i)
  end do
  
  deallocate(dynamic_array)
  
  write(*,*) "Program over!"
  read(*,*)

end program array_exam

动态数组的优势

处理不定长数据

  • 利用动态数组从不定长文件中读取数据
  • 事实上,在实际工作中,我们往往需要注意到一个问题
    • 你怎么可能不知道要处理的数据的长度呢?
      • 当然,傻瓜x方可能不懂规范
      • 也有可能有二傻子在文件中添加没有意义的注释啥的
    • 只需要将文件大小除一下字节长度即可
program data_storage
  implicit none

  integer :: n, i
  real, allocatable :: data(:)
  real, allocatable :: newdata(:)

  open(unit=10, file='data.txt', status='old', action='read')

  n = 1
  allocate(data(1))

  do
    read(10, *, iostat=i) data(n)
    if ((i /= 0) .and. (i /= -1)) then
      write(*,*)"here is:",n
      write(*,*)"fail because iostat is:",i
      exit
    end if 

    
    if (i /= -1) then
      n = n + 1      
      allocate(newdata(n),stat=i)
      newdata(1:n-1) = data(1:n-1)
      deallocate(data)
      allocate(data(n), stat=i)
      data(1:n-1) = newdata(1:n-1)
      deallocate(newdata)
    else 
      write(*,*)"read over!"
      n = n - 1
      allocate(newdata(n),stat=i)
      newdata(1:n) = data(1:n)
      deallocate(data)
      allocate(data(n), stat=i)
      data(1:n) = newdata(1:n)
      deallocate(newdata)      
      exit 
    end if 

  end do

  close(10)

  print *, "Array size:", n
  print *, "Array elements:"
  do i = 1, n
    print *, data(i)
  end do

  deallocate(data)
  write(*,*)"press any key to exit !"
  read(*,*)
end program data_storage
  • fortran90 中有一个小问题,他必须读了之后才能知道具体有没有达到文章的末尾,所以会有一串if i == -1 的问题

  •  数据文件结构:

数组与多维数组

  • 数组的声明
    • 类型说明符 数组名([维数下界(默认为1):]维数上界)
    • 类型说明符,维度([维数下界(默认为1):]维数上界):: 数组名
  • 数组的引用
    • 下标为6的元素:a(6)
    • 数组名(【起始下标】:【终止下标】【:步长】):a(1:10:3)
  • 数组的赋值语句
    • a(i) = i
    • a(5) = (/1,2,3,4,5/)
      • 限制 fortran90 以后
    • data 赋值方法

数组中元素的存储顺序与data赋值方法

  • [m,n]:n行m列
  • Fortran 中的存储顺序十分的甚至可以说九分的复杂,他是基于一种神秘的考虑逻辑的,简单的说
    • 我们在数字电路中学习过最小项的概念,
      • fortran的存储顺序是与最小项这一个概念类似的。
        • 如 A0 A1 A2 A3...
        • 对应的是 (A0,A1,A2,A3) 的数组

data 赋值方法

  • 普通赋值
    • 这里的 and 符号 表示分行写代码
program data_example

  implicit none
  real :: a(5)
  integer i 


  data a / 1.0,&
           2.0,&
           3.0,&
           4.0,&
           5.0 /
           
  write(*,*) "Array:"
  do i = 1, 5
    write(*,*) a(i)
  end do

  read(*,*)
end program data_example

  • 多维数组

program data_example

  implicit none
  real :: b(2,3)
  integer i,j

  data b /1.0, 2.0, 3.0 ,4.0, 5.0, 6.0 /
  
  write(*,*) "Array :"

  do i = 1,2
    do j = 1,3
      write(*,*) b(i,j)
    end do
  end do

  read(*,*)
end program data_example

数组函数

maxval() and minval()

program function_example
  implicit none
  integer i

  real :: f(3, 4)
  real :: max_value = 0
  real :: min_value = 0 

  f = reshape([(i, i=1, size(f))], [3,4])  
  write(*,*)"array f:"
  write(*,*)f 

  max_value = maxval(f(:,2))  
  print *, "Max value of array f:", max_value

  min_value = minval(f(3,:))  
  print *, "Min value of array f:", min_value
  
  write(*,*)"press any key to exit"
  read(*,*)
end program function_example

maxloc() and minloc()

  • 注意,这两个函数返回的是一个只包含一个元素的一维数组
program array
implicit none

   real,dimension(1:6) :: a = (/ 21.0, 12.0,33.0, 24.0,15.0, 16.0/)
   real,dimension(2,3) :: b
   integer max_a(1)
   integer min_a(1)

   b = reshape(a,[2,3])
   write(*,*) "max of a"
   max_a = maxloc(a)
   write(*,*) max_a
   write(*,*) "min of a"
   min_a = minloc(a)
   write(*,*) min_a    
   read(*,*)
end program array

sum() and product()

  • 求和和求乘积
program sum_function_example
  implicit none

  integer :: h(4)
  real :: total_sum
  real :: total_pro

  h = [3, 6, 9, 12]  
  total_sum = sum(h)  
  total_pro = product(h)
  write(*,*)"Total sum of array h:", total_sum
  write(*,*)"Total pro of array h:", total_pro

  write(*,*) "press any key to exit"
  read(*,*)
end program sum_function_example

count()

program count_function_example
  implicit none

  integer :: k(6)
  integer :: num
  k = [1, 10, 1, -10, 1, 1]  
  num = count(k==1)  
  print *, "Number of 1 in array:", num
  num = count(k.gt.1)  
  print *, "Number bigger than 1 in array:", num  
    num = count(k.le.1)  
  print *, "Number smaller than or equal 1 in array:", num
  read(*,*)
end program count_function_example

all() and any()

program all_function_example
  implicit none

  logical :: l(3)
  logical :: resultl
  logical :: m(4)
  logical :: resultm

  l = [.true., .false., .true.] 
  resultl = all(l) 
  write(*,*) "All elements in array are true:", resultl

  m = [.false., .true., .false., .false.] 
  resultm = any(m) 
  write(*,*) "At least one element in array is true:", resultm

  read(*,*)
end program all_function_example

transpose(array)

  • 矩阵转置
program function_example
  implicit none

  integer i,j
  integer :: n(2,3)
  integer :: transposed(3,2)

  n = reshape([1,2,3,4,5,6],[2,3])  
  transposed = transpose(n)  

  print *, "Original matrix:"
  do i = 1,size(n(:,1))
    do j = 1,size(n(1,:))
      print *, n(i,j)
    end do
  end do

  print *, "Transposed matrix:"
  do i = 1,size(transposed(:,1))
    do j = 1,size(transposed(1,:))
      print *, transposed(i,j)
    end do
  end do

  read(*,*)
end program function_example

shape(array)

program function_example

  implicit none

  integer :: a(3,4,5)
  integer :: dimension(3)
  dimension = shape(a)

  write(*,*) "Array dimension:", dimension
  read(*,*)

end program function_example

size()

  • 所有维度上的元素总数
program function_example

  implicit none
  real :: b(1,2,3)
  integer :: total_size,second_dimension_size

  total_size = size(b)  
  second_dimension_size = size(b, dim=2) 

  write(*,*) "Total size of array b:", total_size
  write(*,*) "Size of second dimension:", second_dimension_size
  read(*,*)

end program function_example

lbound() and ubound()

  • 返回给定数组在指定维度上的最低(高)索引
program function_example

  implicit none

  real :: c(-4:5,10)
  integer :: starting_index, ending_index


  starting_index = lbound(c,dim=1)  
  ending_index = ubound(c, dim=2)  

  print *, "Starting index of first dimension:", starting_index
  print *, "Ending index of second dimension:", ending_index

  read(*,*)

end program function_example

reshape(source_array, shape)

  • 一定要记得提前分配内存,任何时候都要记得这件事情

    • 具体操作参见上面的操作代码,有相关reshape函数的使用

流传很广的一些计算机笑话

  • Why programmers always mix up Halloween and Christmas?
    • Because Oct 31 == Dec 25!
  • There are 10 types of people in the world: Those who understand binary, those who don't

Good Luck!

                To my best friend for my rest life.

### Fortran数组之间的赋值方法 在 Fortran 编程语言中,数组间的赋值可以通过多种方式完成。以下是几种常见的方法及其特点: #### 方法一:直接赋值 最简单的方式是通过直接赋值语句将一个数组的内容复制到另一个数组中。这种方式适用于两个数组具有相同形状的情况。 ```fortran program direct_assignment implicit none integer, dimension(3) :: array1 = [1, 2, 3], array2 array2 = array1 ! 将array1的值赋给array2 print *, 'Array2:', array2 end program direct_assignment ``` 这种方法的优点在于简洁明了,但在执行前需确保目标数组已正确定义并分配足够的存储空间[^1]。 --- #### 方法二:使用 `DO` 循环逐一赋值 如果需要更灵活的操作或处理复杂逻辑,则可以借助循环结构逐个元素进行赋值。 ```fortran program loop_assignment implicit none integer, dimension(5) :: source_array = [10, 20, 30, 40, 50] integer, dimension(5) :: target_array integer :: i do i = 1, size(source_array) target_array(i) = source_array(i) end do print *, 'Target Array:', target_array end program loop_assignment ``` 此方法适合用于涉及条件判断或其他额外操作的情形下[^2]。 --- #### 方法三:利用内置函数 `RESHAPE` 当源数据并非严格意义上的同维数或多维度转换需求时,可通过调用 `RESHAPE` 函数重新排列原始数据形成新数组。 ```fortran program reshape_example implicit none real, parameter :: c = 10.d0, b = 30.d0 real, dimension(2,3) :: reshaped_array reshaped_array = reshape([c,b,4,5,2,3], shape=[2,3]) print *, 'Reshaped Array:' print '(f6.1)', reshaped_array end program reshape_example ``` 这里展示了如何创建一个二维浮点型数组并通过指定初始列表以及期望尺寸参数来初始化它[^2]。 --- #### 方法四:动态分配释放内存 对于运行期间未知大小的数组,先对其进行动态分配再实施赋值过程尤为重要。 ```fortran program dynamic_allocation implicit none integer, allocatable :: dyn_arr(:), copy_dyn_arr(:) integer :: n, i read(*,*) n ! 输入长度n allocate(dyn_arr(n)) allocate(copy_dyn_arr(n)) do i = 1,n dyn_arr(i)=i**2 ! 初始化dyn_arr enddo copy_dyn_arr=dyn_arr ! 复制整个数组内容至copy_dyn_arr print*, 'Copied Dynamic Array:', copy_dyn_arr deallocate(dyn_arr,copy_dyn_arr) end program dynamic_allocation ``` 上述代码片段说明了如何读取用户输入决定数组规模,并安全地管理资源以防止泄漏问题发生[^5]。 --- ### 总结 综上所述,在Fortran里实现不同场景下的数组间赋值有诸多途径可供选择,具体取决于实际应用场景和个人偏好等因素影响最终决策方向。无论是简单的全量拷贝还是复杂的结构调整均能找到合适的解决方案满足开发人员的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

River Chandler

谢谢,我会更努力学习工作的!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值