2010-12-06 11 views
5

que tienen el siguiente programalímites de matriz teniendo en FORTRAN durante la llamada a subrutina

module test 
contains 
    subroutine foo() 
     integer, allocatable :: a(:) 
     allocate(a(-5:5)) 
     call bar(a) 
     print *, a 
    end subroutine 
    subroutine bar(a) 
     integer, intent(out) :: a(:) 
     a = 0 
     a(-4) = 3 ! here 
     a(2) = 3 
    end subroutine 
end module 

program x 
    use test 
    call foo() 
end program 

En la línea marcada con "aquí" que estoy haciendo algo mal. El hecho es que cuando recibo el arreglo a (en la persona que llama asignada de -5 a +5), el destinatario usa la numeración convencional (1 a n), lo que significa que asignando -4 estoy haciendo una asignación fuera del límite. ¿Cómo puedo indicar al compilador que, dentro de la rutina bar, la numeración de la matriz a debe ser la misma que en la persona que llama?

Respuesta

4

El tipo de argumento ficticio que está está utilizando en la subrutina, con la dimensión especificada con un colon, se llama "asume la forma". Este nombre es la clave: Fortran solo pasa la forma y no los límites inferior y superior. Se supone que el límite inferior es uno a menos que lo anule como se muestra en la respuesta de kemiisto. Si el límite inferior no es fijo, puede pasar un argumento para usar como límite inferior.

adición posterior: un ejemplo de código si la dimensión inferior no se conoce en tiempo de compilación:

subroutine example (low, array) 
    integer, intent (in) :: low 
    real, dimension (low:), intent (out) :: array 
2

¿Cómo puedo indicar al compilador que, dentro de la rutina de barras, la numeración de una matriz debe ser la misma que en la persona que llama?

No estoy seguro, pero de acuerdo con el estándar puede especificar el límite inferior para una matriz de forma asumida.

subroutine bar(a) 
     integer, intent(out) :: a(-5:) 
+0

¿Qué sucede si no conozco el índice inicial en el momento de la compilación? –

+0

@Stefano: ver M. S. B. respuesta. Necesita que el límite inferior sea el segundo argumento de su subrutina de barra. – Wildcat

+0

¿Entonces la declaración 'entero, intención (salida) :: a (lbound (a) :)' no es válida? (No lo he intentado, tal vez debería). No me gusta pasar detalles sobre mi matriz como argumento. –

3

Hay dos opciones comunes:

  • Como escribió kemisto, se pasa a un segundo argumento . Esto era común en el código de estilo F77. ¡No puedes usar el truco de LBOUND! Tiene que pasarse como un entero.
  • Declara que el argumento es un puntero, que incluye todo el descriptor de la matriz. Entonces los límites de la matriz en la subrutina son los mismos que en el alcance de la llamada. Por supuesto, puede perder en la optimización de esta manera.
Cuestiones relacionadas