[15. Arreglos en subprogramas ]  [Tutorial de Fortran]  [17. Datos y bloques de datos ]

16. Bloques Comunes

Fortran 77 no tiene variables tipo global, es decir, variables que se compartan en varias unidades del programa (subrutinas). La única forma para pasar información entre subrutinas ya se ha visto previamente, y es usando una lista de parámetros en la subrutina. Algunas veces es inconveniente, por ejemplo cuando muchas subrutinas comparten un conjunto grandes de parámetros. En tales casos se puede usar un bloque común (common block). Esta es una forma para indicar que ciertas variables podrían compartirse en ciertas subrutinas. Se recomienda en lo general, minimizar el uso de bloques comunes en los programas.

Ejemplo

Supongamos que se tienen dos parámetros alpha y beta, los cuales son usados por varias subrutinas. El siguiente ejemplo muestra como puede hacerse usando bloques comunes.
      program main
         algunas declaraciones
         real alpha, beta
         common /coeff/ alpha, beta

         sentencias
         stop
      end

      subroutine sub1 (algunos argumentos)
         declaraciones de argumentos
         real alpha, beta
         common /coeff/ alpha, beta

         sentencias
         return
      end

      subroutine sub2 (algunos argumentos)
         declaraciones de argumentos
         real alpha, beta
         common /coeff/ alpha, beta

         sentencias
         return
      end
En el código anterior se ha definido un bloque común con el nombre coeff. El contenido del bloque común son las dos variables alpha y beta. Un bloque común puede contener todas la variables que se deseen, no se necesita que todas sean del mismo tipo. Cada subrutina que quiere usar algunas de las variables del bloque común, tiene que declarar todo el bloque.

Se observa que en este ejemplo se pudo haber evitado fácilmente los bloques comunes, pasando alpha y beta como argumentos. Una buena regla es tratar de evitar los bloques comunes si es posible. Hay pocos casos donde no es posible hacerlo.

Sintaxis

      common / nombre / lista_de_variables
Se debe tener presente que Para mostrar lo anterior, se puede ver el siguiente ejemplo:
      subroutine sub3 (algunos argumentos)
         declaraciones de argumentos
         real a, b
         common /coeff/ a, b

         sentencias
         return
      end
Esta declaración es equivalente a la de la versión previa donde fue usada alpha y beta. Se recomienda que siempre se use el mismo nombre de la variable que aparece en el bloque común, para evitar confusión. Se muestra un ejemplo de algo que no debe hacerse:
      subroutine sub4 (algunos argumentos)
         declaraciones de argumentos
         real alpha, beta
         common /coeff/ beta, alpha

         sentencias
         return
      end
Ahora alpha es la beta del programa principal y viceversa. Si se ve algo como lo anterior, es probable que se tenga un error de lógica. Tales errores son muy difíciles de encontrar.

Arreglos en Bloques Comunes

Los bloques comunes pueden incluir arreglos también, pero nuevamente no es recomendado, la razón principal es por flexibilidad. Un ejemplo que muestra porque es una mala idea. Suponiendo que se tienen las siguientes declaraciones en el programa main:
      program main
         integer nmax
         parameter (nmax=20)
         integer n
         real A(nmax, nmax)
         common /matriz/ A, n, nmax
Este bloque común contiene todos los elementos de A, y los enteros n y nmax. Supongamos que se quiere usar la matriz A en algunas subrutinas. Entonces se tiene que incluir la misma declaración en todas las subrutinas, por ejemplo:
      subroutine sub1 (...)
         integer nmax
         parameter (nmax=20)
         integer n
         real A(nmax, nmax)
         common /matriz/ A, n, nmax
Los arreglos con dimensiones variables no pueden aparecer en bloques comunes, por lo tanto el valor de nmax tiene que ser exactamente el mismo que el del programa principal. Recordar que el tamaño de la matriz tiene que ser conocido en tiempo de compilación, por eso nmax pertenece al bloque común, pero esto sera ilegal.

El ejemplo muestra que no hay ganancia poniendo arreglos en bloques comunes. Por lo que el método preferido en Fortran 77 es pasar arreglos como argumentos a las subrutinas ( junto con las dimensiones principales).


Ejercicios

Ejercicio A
Reescribir el siguiente programa y subprograma de tal forma que no se usen bloques comunes. Conservar la estructura global.
      program main
         real origo(3), x(3)
         real d, dist
         common /inutil/ origo
      
         read(*,*) origo(1), origo(2), origo(3)
  10  continue
         read(*,*) x(1), x(2), x(3)
         d = dist(x)
         write(*,*) 'La distancia es ', d
      if (x(1) .ge. 0.0) goto 10

         stop
      end
      
      real function dist (x)
         real x(3)
         real x0, y0, z0
         common /inutil/ x0, y0, z0

         dist = sqrt((x(1)-x0)**2 + (x(2)-y0)**2 + (x(3)-z0)**2)

         return
      end


 [15. Arreglos en subprogramas ]  [Tutorial de Fortran]  [17. Datos y bloques de datos ]