Array: sezioni

Dato un array, è possibile esprimere un suo sottoinsieme (selezionato in maniera lineare) con la notazione delle sezioni: a([start]:[stop][:incr],...) dove start stop e incr, se omessi, valgono rispettivamente (qui i=1):
  • start=LBOUND(a,i)
  • stop=UBOUND(a,i)
  • incr=1
È consentito anche definire sezioni nulle di array, ad es. se start > stop, in genere le funzioni intrinseche si comportano correttamente anche nel caso di sezioni nulle, per cui, se la logica del programma lo consente, è possibile evitare tali controlli.

Array e/o loro sezioni, assieme a scalari, possono essere usati nelle espressioni purché abbiano la stessa shape (e lo stesso tipo numerico, a meno di conversioni automatiche) per ottenere un risultato con la stessa shape che è uguale al risultato della corrispondente espressione scalare effettuata elemento per elemento. Tutte le funzioni numeriche intrinseche del F90 sono in grado di lavorare in maniera trasparente anche su array.

Gli array possono essere ovviamente anche di tipo logico; tutti gli operatori .AND., .OR. e .NOT. funzionano in maniera trasparente elemento per elemento, ma qui non è consentito mescolare scalari ed array in un'espressione (ha poco senso). Posso comunque assegnare uno scalare logico ad un array logico, con lo stesso significato che ciò ha per un'assegnazione numerica.

Il costrutto WHERE permette di effettuare operazioni su array sotto il controllo di una condizione logica che abbia la stessa shape.

PROGRAM vettori

REAL :: a(12,18), b(12,18), c(12,36)
LOGICAL :: la(12,18), lb(12,18)
REAL :: f
REAL, PARAMETER :: rmiss = -1.0E15
INTEGER :: na, nb

a = b + c(:,::2)*f
a = b + c(:,1:18)*f
a(:,:) = b(:,:) + c(:,1:18)*f

a = SQRT(b*f) + LOG(c(:,1:18))

la = (a /= rmiss)
lb = (b /= rmiss)

WHERE(la .AND. lb)
  c(:,1:18) = a + b
ELSE WHERE
  c(:,1:18) = rmiss
END WHERE

END PROGRAM vettori
È possibile anche esprimere sezioni non lineari di array utilizzando come indice a sua volta un array unidimensionale intero (array subscript), che indica gli elementi dell'array originale da prelevare per formare la sezione desiderata; questa è una notazione molto potente ma poco efficiente e il cui uso non è universale.
PROGRAM vettori

REAL :: a(10) = (/2.,4.,6.,8.,10.,12.,14.,16.,18.,20./)
INTEGER :: b(6)

b = (/1,4,8,2,4,5/)

PRINT*,a(b)

END PROGRAM vettori