PDA

View Full Version : [Fortran]Subroutine che usa array creati nel main program


SoONicK
17-02-2012, 16:22
Salve a tutti.
Ho bisogno di un suggerimento riguardo una cosa semplice in Fortran.
Ho creato una subroutine che deve elaborare degli array creati nel main.
Come funziona la chiamata e la definizione delle variabili?
Grazie per qualsiasi suggerimento

vendettaaaaa
18-02-2012, 12:38
subroutine funzione(a1, a2, out)

parameter n1 = 100
parameter n2 = 100
double a1(n1)
double a2(n2)
double out

// conti, dove generi un valore di out in base ai valori contenuti in a1 e a2

return
end

program MyProgram

parameter n1 = 100
parameter n2 = 100
double array1(n1)
double array2(n2)
double output

// assegno dei valori ad array1, array2
call funzione(array1, array2, output)

write(*,*) output

end
In generale, una subroutine (o anche una function) ha una lista di parametri che non ha un tipo specificato; dopo la definizione della routine c'è una sezione di dichiarazione dove specifichi il tipo di ogni variabile e, con le parentesi tonde, se sono array.

Dopo il primo statement con un'espressione (tipo array1 = array2) non puoi più dichiarare niente.

Una subroutine non ritorna niente (è equivalente a void funzione() in C/C++), infatti necessita di un "return" prima di "end", quindi il risultato dei conti lo salvi dentro ad out.
Questo perchè nel FORTRAN tutte le variabili vengono sempre passate per pointer.
Una function invece ha un valore di ritorno.

Una subroutine non richiede che la/le variabile/i di output sia per forza l'ultima (o le ultime) nella lista di parametri, potevo anche scrivere
subroutine funzione(a2, out, a1) che non cambiava nulla.

Ovviamente nel main e nella subroutine la dichiarazione dei vettori deve concordare. Poichè passi gli array per pointer, la subroutine non può sapere la loro dimensione (FORTRAN è molto arcaico in questo). Quindi deve conoscere la loro dimensione (usando parameter, come nel primo esempio), o gliela devi passare come parametro:
subroutine funzione(a1, n1, a2, n2, out)

integer n1
double a1(n1)
integer n2
double a2(n2)
double out

// conti, dove generi un valore di out in base ai valori contenuti in a1 e a2

return
end
Questo è più o meno quanto.

vendettaaaaa
18-02-2012, 16:20
"double precision", non "double" e basta.

SoONicK
18-02-2012, 17:33
Quindi mi basterebbe fare una cosa del tipo

subroutine writebintable(coun,emin,emax,N)
parameter (N=1024)
integer N
integer k,coun(N)
real*4 emin(N),emax(N)
...


e poi nel main chiamare:

program main
integer N
real*4 emin(1024),emax(1024),Delta
parameter (N=1024)

...

call writebintable(coun(k),emin(k),emax(k),1024)
...


Purtroppo provando un migliaio di combinazioni continuo ad ottenere errori o risultati inconsistenti...
ad esempio se dopo la dichiarazione PARAMETER metto o non metto il valore della variabile fra parentesi ottengo diversi errori...

vendettaaaaa
18-02-2012, 18:12
Quindi mi basterebbe fare una cosa del tipo

subroutine writebintable(coun,emin,emax,N)
parameter (N=1024)
integer N
integer k,coun(N)
real*4 emin(N),emax(N)
...


e poi nel main chiamare:

program main
integer N
real*4 emin(1024),emax(1024),Delta
parameter (N=1024)

...

call writebintable(coun(k),emin(k),emax(k),1024)
...


Purtroppo provando un migliaio di combinazioni continuo ad ottenere errori o risultati inconsistenti...
ad esempio se dopo la dichiarazione PARAMETER metto o non metto il valore della variabile fra parentesi ottengo diversi errori...
Sì ho dimenticato le parentesi, i parametri vanno inizializzati tra parentesi.
Cmq nella funzione non puoi passare un parameter come argomento. Prova così:

subroutine writebintable(coun,emin,emax)
integer N
parameter (N=1024)
integer k,coun(N)
real*4 emin(N),emax(N)
...
return
end


e poi nel main chiamare:

program main
integer N
parameter (N=1024)
real*4 emin(N),emax(N),Delta
...

! call writebintable(coun(k),emin(k),emax(k),N) <-- no, devi passare solo il nome dell'array, senza parentesi
call writebintable(coun,emin,emax) <-- ok
...
end

SoONicK
18-02-2012, 18:22
Le sto provando tutte!
La libreria interna restituisce il seguente errore:
numerical overflow during implicit datatype conversion

vendettaaaaa
18-02-2012, 19:18
Mi manderesti il programma completo, se possibile, via pm? Provo a farlo girare sul mio pc e vediamo, m'hai incuriosito!