Arrays

Arrays are stored in column-major order: a(1,1), a(2,1), a(3,1), a(1,2), ...

10.1 Declaring arrays

Arrays are stored in column-major order: a(1,1), a(2,1), a(3,1), a(1,2), ... — the first index varies fastest.

real :: v(10)                          ! 1-D, indices 1..10
real, dimension(10) :: w               ! equivalent
real :: a(3, 4)                        ! 2-D, 3 rows × 4 columns
real :: t(0:9)                         ! custom bounds 0..9
integer :: grid(-5:5, -5:5)
real :: cube(10, 10, 10)               ! up to 15 dimensions (Fortran 2008)
real, allocatable :: dyn(:), mat(:, :) ! deferred shape (allocated at run time)

10.2 Array constructors & initialization

integer :: p(5) = [2, 3, 5, 7, 11]           ! [ ] constructor (F2003); (/ ... /) in F90
real :: z(100) = 0.0                          ! scalar broadcast
integer :: sq(10) = [(i**2, i = 1, 10)]       ! implied-do (i must be declared)
real :: m(2, 3) = reshape([1, 2, 3, 4, 5, 6], [2, 3])   ! column-wise fill
character(len=5) :: names(3) = [character(len=5) :: "Ann", "Bob", "Carla"]
real, allocatable :: e(:)
e = [real ::]                                 ! empty array

10.3 Allocatable arrays

Allocatables are automatically deallocated when they go out of scope (no memory leaks) — prefer them over pointers.

real, allocatable :: x(:), A(:, :)
integer :: n, stat
character(len=200) :: msg

n = 1000
allocate(x(n), A(n, n), stat=stat, errmsg=msg)
if (stat /= 0) error stop trim(msg)

allocate(x, source=[1.0, 2.0, 3.0])           ! allocate with values
allocate(y, mold=x)                            ! same shape/type, uninitialized

if (allocated(x)) deallocate(x)

! Automatic (re)allocation on assignment (Fortran 2003)
x = [1.0, 2.0]                                 ! allocated with size 2
x = [x, 3.0]                                   ! grows to size 3 (append idiom)
call move_alloc(from=tmp, to=x)                ! efficient transfer without copy

10.4 Indexing & sections

real :: a(5, 5)
a(2, 3) = 1.0                ! single element
a(1, :)                      ! first row
a(:, 2)                      ! second column
a(2:4, 2:4)                  ! sub-matrix
a(1:5:2, :)                  ! rows 1, 3, 5 (stride)
a(5:1:-1, 1)                 ! reversed column
v([1, 3, 5])                 ! vector subscript (gather)
v(:)                         ! the whole array

10.5 Whole-array operations

real :: x(100), y(100), z(100)
x = 1.0                      ! assign scalar to all elements
y = 2.0 * x + 3.0            ! element-wise arithmetic
z = sqrt(x) + sin(y)         ! elemental intrinsics
z = x * y                    ! element-wise product (NOT matrix multiply)
x(2:100) = x(1:99)           ! overlapping sections handled correctly
where (y > 4.0) z = 0.0      ! masked assignment

10.6 Array attributes for procedures

real:: a(n, m) dummy size passed as argument real:: a(:,:) requires explicit interface (module) — preferred real:: a(*) legacy F77; size unknown real:: a(..) any rank (F2018), use select rank real, allocatable:: a(:) real:: work(size(a)) local array sized at run time (on the stack)