Domanda

In C si può facilmente inizializzare un array utilizzando la sintassi parentesi graffe, se non ricordo male:

int* a = new int[] { 1, 2, 3, 4 };

Come si può fare lo stesso in Fortran per array bidimensionali quando si desidera inizializzare una matrice con valori di test specifici per scopi matematici? (Senza dover doppiamente indice ogni elemento di dichiarazioni separate)

La matrice può essere definito sia da

real, dimension(3, 3) :: a

o

real, dimension(:), allocatable :: a
È stato utile?

Soluzione

È possibile farlo utilizzando rimodellare e intrinseche forma . Qualcosa di simile:

INTEGER, DIMENSION(3, 3) :: array
array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))

Ma ricordate l'ordine delle colonne-major. La matrice sarà

1   4   7
2   5   8
3   6   9

dopo rimodellare.

Quindi, per ottenere:

1   2   3
4   5   6
7   8   9

trasporre intrinseca:

array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))

Per esempio più generale (array allocatable 2D con dimensioni diverse), uno esigenze dimensioni intrinseca:

PROGRAM main

  IMPLICIT NONE

  INTEGER, DIMENSION(:, :), ALLOCATABLE :: array

  ALLOCATE (array(2, 3))

  array = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /),                            &
    (/ size(array, 2), size(array, 1) /)))

  DEALLOCATE (array)

END PROGRAM main

Altri suggerimenti

Per rango (> 1) array multidimensionali, il modo per Fortran differisce inizializzazione della soluzione C perché in C array multidimensionali sono solo array di array di etc.

In FORTRAN, ognuno corrisponde ad un rango diverso attributo del tipo di dati modificati. Ma c'è solo un costruttore di array per rango-1 array. Da queste due ragioni, inizializzazione attraverso costruttore matrice richiede la funzione intrinseci RESHAPE.

In aggiunta a quanto già risposto, c'è un modo più diretto inserendo il valore di una matrice per righe invece come per colonna: rimodellazione ha un ORDER argomento opzionale che può essere usata per modificare l'ordine di riempimento dell'elemento della matrice multidimensionale con le voci del costruttore matrice.

Ad esempio, nel caso dell'esempio nella prima risposta, si potrebbe scrivere:

INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, &
                                              4, 5, 6, &
                                              7, 8, 9 /), &
                                           shape(array), order=(/2,1/) )

ottenere il riempimento della matrice esattamente nell'ordine indicato dalle linee di codice.

Le forze matrice (/2, 1/) l'indice di colonna (2) avere la precedenza sulla (1) indice di riga, dando l'effetto desiderato.

inizializzazione array può essere realizzata in comunicazione dichiarazione matrice stessa, come illustrato di seguito:

program test
 real:: x(3) = (/1,2,3/)
 real:: y(3,3) = reshape((/1,2,3,4,5,6,7,8,9/), (/3,3/))
 integer:: i(3,2,2) = reshape((/1,2,3,4,5,6,7,8,9,10,11,12/), (/3,2,2/))

end program test

Mi sorprende che

 real:: y(3,3) = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)

non accettato dal compilatore (G95 provato, gfortran). Si scopre che la shape di (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) è 9 e non 3 3!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top