16. 공통 블록 (Common blocks)

Fortran 77에는 global 변수 즉 여러 rogram units (subroutines)에서 공통으로 사용하는 변수가 없다. 지금까지 보아온 것처럼 subroutine 사이에서 정보를 전달하는 유일한 방법은 subroutine parameter 목록을 사용하는 것이다. 여러 subroutines에서 많은 parameters를 공유해야할 경우 등에는 이런 제한은 불편한다. 그러한 경우 공통 블록 common block을 사용할 수 있다. 이는 어떤 subroutine 사이에사 어떤 변수를 공유하는가를 정하는 방법이다. 그러나 일반적으로 common blocks 사용은 최소로 하여야 한다.

Example

여러 subroutines에서 필요한 두 변수 alpah와 beta가 있다. 다음은 common block을 사용하여 어떻게 할 수 있는가를 보여주는 예이다.
      program main
      some declarations
      real alpha, beta
      common /coeff/ alpha, beta

      statements
      stop
      end

      subroutine sub1 (some arguments)
      declarations of arguments
      real alpha, beta
      common /coeff/ alpha, beta

      statements
      return
      end

      subroutine sub2 (some arguments)
      declarations of arguments
      real alpha, beta
      common /coeff/ alpha, beta

      statements
      return
      end
여기서 coeff이라는 이름의 common block을 정의한다. common block의 내용은 alpha와 beta 두 변수이다. common block에는 여러 개의 변수를 사용할 수 있다. 모두가 같은 형태일 필요는 없다. common block 안의 변수 중 어느 것을 필요로 하는 모든 subroutine 에서 전체 block을 정의하여야 한다. declare the whole block.

이 예에서는 alpah와 beta를 parameter(argument)로 넘겨줌으로써 common block을 사용하지 않을 수도 있다. 좋은 방법은 가능한 common block을 사용하지 않는 것이다. 그러나 다른 방법이 없는 경우가 간혹 있다.

Syntax

      common / name / list-of-variables
다음을 알아야 한다. 이를 이해하기 위하여 다음 예를 살펴 본다.
      subroutine sub3 (some arguments)
      declarations of arguments
      real a, b
      common /coeff/ a, b

      statements
      return
      end
이 선언은 alpha와 beta를 사용한 앞의 예와 같다. 혼동을 피하기 위하여 같은 common block에서는 변수 이름을 같게 할 것을 권한다. 다음은 아주 나쁜 경우의 예이다.
      subroutine sub4 (some arguments)
      declarations of arguments
      real alpha, beta
      common /coeff/ beta, alpha

      statements
      return
      end
여기서 alpha는 main program의 beta이고 beta는 main program의 alpha이다. 이러한 것을 본다면 이는 아마 실수일 것이다. 그런 잘못은 찾기 힘들다.

공통 블록 안의 배열 (Arrays in common blocks)

common block에는 배열도 사용할 수 있다. 그러나 권하지는 않는다. 주된 이유는 융통성때문이다. 아래는 왜 나쁜가를 보여주는 예이다. main program에서 다음과 같이 선언하였다고 하자.
      program main
      integer nmax
      parameter (nmax=20)
      integer n
      real A(nmax, nmax)
      common /matrix/ A, n, nmax
common block에는 우선 A의 모든 원소, 그리고 정수 n과 nmax이 포함되어 있다. 이제 matrix A를 어떤 subroutine에서 사용하고자 할 경우 모든 subroutines에 같은 선언을 넣어야 한다. 즉,
      subroutine sub1 (...)
      integer nmax
      parameter (nmax=20)
      integer n
      real A(nmax, nmax)
      common /matrix/ A, n, nmax
common block에 가변 차원 배열은 사용할 수 없다. 따라서 nmax의 값은 main program에서와 정확하게 일치하여야 한다. matrix의 크기는 compile할 때 알려주어야 하기에 nmax는 parameter 문장에서 정의하여야만 한다. nmax는 common block에 있기에 subroutine에서 parameter 문을 사용하지 않고 싶을 테지만 이는 규칙에 어긋나는 일이다.

다음은 보통 common block에 배열을 넣어도 얻는 것이 없다는 것을 보여 주는 예이다. 따라서 Fortran 77에서 바람직한 방법은 배열을 argument로 (leading 차원과 함께)subroutine에 넘겨 주는 것이다.


Exercises

Exercise A
common block을 사용하지 않도록 다음 프로그램과 부 프로그램을 다시 작성하라. 전체 구조는 유지하도록 한다.
      program main
      real origo(3), x(3)
      real d, dist
      common /silly/ origo
      
      read(*,*) origo(1), origo(2), origo(3)
  10  continue
         read(*,*) x(1), x(2), x(3)
         d = dist(x)
         write(*,*) 'The distance is ', d
      if (x(1).ge.0.) goto 10

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

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

      return
      end


[Fortran Tutorial]
충남대학교 물리학과 오 병성