Skip to content

fortran2008数组-3-切片和索引

Fortran 数组索引和切片方式

Fortran 提供了多种灵活的数组索引和切片操作方式,以下是全面的总结:

1. 基本索引方式

1.1 单元素访问

real :: A(10)
A(5) = 3.14  ! 访问第5个元素

1.2 多维数组访问

real :: B(3,3)
B(2,3) = 2.0  ! 访问第2行第3列元素

2. 数组切片方式

2.1 连续范围切片

integer :: arr(10) = [(i, i=1,10)]
print *, arr(3:7)  ! 输出 [3,4,5,6,7]
print *, arr(:5)   ! 输出前5个元素 [1,2,3,4,5]
print *, arr(6:)   ! 输出第6个及之后元素 [6,7,8,9,10]

2.2 带步长的切片

print *, arr(1:10:2)  ! 输出 [1,3,5,7,9]
print *, arr(10:1:-1) ! 逆序输出 [10,9,8,7,6,5,4,3,2,1]

2.3 多维数组切片

real :: matrix(5,5)
matrix(2:4, 3) = 1.0  ! 第3列的第2-4行
matrix(:, 1) = 0.0     ! 第1列全部元素
matrix(5, 2:4) = 2.0   ! 第5行的2-4列

3. 高级索引方式

3.1 向量下标索引

integer :: idx(3) = [2,5,7]
print *, arr(idx)  ! 输出 [arr(2), arr(5), arr(7)]

3.2 逻辑掩码索引

logical :: mask(10)
mask = arr > 5      ! 创建逻辑掩码
print *, arr(mask)  ! 输出大于5的元素

4. 特殊切片技术

4.1 隐式循环 (implied do)

print *, (arr(i), i=2,8,2)  ! 输出 [arr(2), arr(4), arr(6), arr(8)]

4.2 数组构造器切片

real :: new_arr(3) = [arr(3), arr(5), arr(7)]

4.3 指针关联切片

real, pointer :: p(:)
p => arr(3:7)  ! p指向arr的子数组
p(1) = 99.0    ! 会修改原数组arr(3)的值

5. 数组切片赋值

5.1 标量赋值给切片

arr(3:7) = 0.0  ! 将第3-7个元素设为0

5.2 数组对数组赋值

real :: source(5) = [1.0,2.0,3.0,4.0,5.0]
arr(1:5) = source  ! 将source复制到arr的前5个位置

5.3 自动填充

arr(1:10:2) = 1.0  ! 奇数位置设为1.0
arr(2:10:2) = 2.0  ! 偶数位置设为2.0

6. 数组切片在函数中的应用

6.1 作为函数参数

call process_subarray(arr(3:7))  ! 传递子数组

subroutine process_subarray(sub)
    real :: sub(:)
    ! ...处理子数组...
end subroutine

6.2 返回数组切片

function get_even_elements(a) result(even)
    real, intent(in) :: a(:)
    real :: even(size(a)/2)
    even = a(::2)  ! 返回偶数索引元素
end function

7. 性能注意事项

  1. 连续访问:Fortran是列优先存储,matrix(:,j)matrix(i,:)效率更高
  2. 临时数组:复杂切片可能产生临时数组,影响性能
  3. 向量化:简单连续切片更易被编译器优化
  4. 边界检查:使用-fno-bounds-check关闭边界检查可提高性能(调试时不建议)

8. 特殊数组切片案例

8.1 对角元素提取

real :: diag(3) = [matrix(i,i), i=1,3]  ! 提取3x3矩阵对角线

8.2 块操作

matrix(2:3, 2:3) = 0.0  ! 将中心2x2子矩阵置零
sub_arr=matrix([1,3],[1,3]) ! 返回一个2*2的矩阵

8.3 条件切片

print *, pack(arr, arr > 5.0)  ! 输出大于5的元素

Fortran的数组切片功能非常强大,合理使用可以写出既简洁又高效的代码。对于性能关键代码,建议结合具体编译器优化特性进行调优。