정보

    • 업무명     : 포트란을 활용한 기초 2 : 상수,키워드, 기본 제어 입출력, 연산자 (논리, 관계, IF, CASE, DO, CYCLE)

    • 작성자     : 이상호

    • 작성일     : 2020-11-10

    • 설   명      :

    • 수정이력 :

     

     내용

    [개요]

    • 안녕하세요? 웹 개발 및 연구 개발을 담당하고 있는 해솔입니다.

    • Fortran (포트란)은 수식 (Formular) 변환기 (Translator)의 약자로 과학 계산용으로 주고 사용되는 언어입니다.

    • 복잡한 계산 수행 성능이 뛰어나 공학과 자연과학 등 특정분야에 주로 사용되며 기상 데이터 처리를 위해 널리 사용되고 있습니다.

    • 오늘 포스팅은 포트란을 활용한 기초 2를 소개합니다.

     

     

    [특징]

    • 기상 데이터 처리를 위해서 포트란 (Fortran)기술이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 기술서

     

    [기능]

    • 상수, 키워드

    • 기본 제어 입출력

    • 연산자 (논리, 관계, IF, CASE, DO, CYCLE)

     

    [활용 자료]

    • 없음

     

    [자료 처리 방안 및 활용 분석 기법]

    • 없음

     

    [사용법]

    • 없음

     

    [사용 OS]

    • Linux (CentOS v7.8)

     

    [사용 언어]

    • gfortran v4.8.5

     

     세부 내용

    상수, 키워드
    • 이름상수 (Named Constant) 와 키워드 PARAMETER

      • C언어에서 #define 으로, 상수에 이름을 붙여서 사용하는 것과 비슷한 방식으로 포트란에서도 상수에 이름을 붙여서 사용할 수 있습니다.

      • 이는 프로그램의 수정 및 이식에 있어서 상당히 요긴하게 쓰이게 됩니다.

      • C언어의 #define 이 컴파일 전에 코드를 치환하는 역할만 하지만 포트란에서는 키워드 PARAMETER를 이용하여, 데이터타입을 지정해 줄 수도 있어 더욱 용이 하게 쓸 수 있습니다.

      • datatype, PARAMETER :: var_name = value , ...

    PROGRAM const_name
      INTEGER, PARAMETER :: AAAA = 4, DDDD = 8
      REAL, PARAMETER :: PI = 3.141592
      REAL (KIND=AAAA) :: x
      REAL (KIND=BBBB) :: y
      x = PI ** 2
      y = PI ** 2
      WRITE (*,*) x,y
    END PROGRAM

     

    결과
    9.869600 9.86960029602051

     

    기본 제어 입출력
    • READ , WRITE

      • READ 와 WRITE 는 제어부와 입출력리스트로 구성됩니다.

      • 입력 READ ( io unit , format ) input list

      • 출력 WRITE ( io unit , format ) output list

      • input list 와 output list 는 comma(,) 에 의해 구분됩니다.

      • READ 에서, 실제 입력데이터는 콤마, 빈칸, 줄에 의해 구분됩니다.

      • 입력값은 각 데이터형 상수 방식으로 입력합니다.

      • 가령 복소수를 입력 할 때는 ( a,b ) 와 같이 입력 합니다.

      • 괄호 없이 숫자만 입력하면, 실수로 처리되어 실수로 입력되고, 허수부는 0 이 됩니다.

      • 논리형이라면 .TRUE. 와 .FALSE. 로 입력하면 되는데, 이것이 상당히 번거로우므로, 간단히 T 와 F 로
        입력 하는 것을 추천합니다.

    PROGRAM ioi
      READ (*,*) I,j
      WRITE (*,*) 'i*j= ', i*j
    END PROGRAM

     

    • ( ) 는 제어부로, 첫 번째 부분은 입출력 unit에 대한 부분이고, 두 번째 부분은 입출력 포맷에 관한 부분입니다.

    • io unit 는 어디서 데이터를 읽어올 것인가를 나타내며, (*,*)에서 *는 standard input device 를 나타내며, 보통 키보드 입력을 말합니다.

    • format 은 입출력 형식에 관한 것입니다.

    • * 는 list-directed (free format) 으로, input list 의 변수 자료형이 입력 받을 자료의 포맷을 결정한다는 의미입니다.

    • 위의 예제를 실행하여 두 숫자를 입력 한 결과는 다음과 같습니다.

    결과
    4 6
    I*j= 24

     

    연산자 (논리, 관계, IF, CASE, DO, CYCLE)
    • 논리연산

      • 논리 연산에 사용되는 것은 다음과 같습니다.

    이름

    연산자

    비고

    논리곱

    .AND.

    둘 다 참 일 때만 참, 나머진 거짓

    논리합

    .OR.

    둘 다 거짓 일 때만 거짓, 나머진 참

    부정

    .NOT.

    논리값을 반대로 바꿈

    동치

    .EQV.

    논리값이 같으면 참, 아니면 거짓

    비동치

    .NEQV.

    논리값이 다르면 참, 아니면 거짓

     

    • 관계연산

      • 대소비교에 의한 평가값은 논리값을 갖습니다.

    연산자(기호)

    연산자(문자)

    비고

    ==

    .EQ.

    같다

    /=

    .NE.

    다르다

    .GT.

    크다

    .LT.

    작다

    >=

    .GE.

    크거나 같다

    <=

    .LE.

    작거나 같다

     

    PROGRAM logic_cal
      LOGICAL :: T=.TRUE. , F=.FALSE.
      WRITE (*,*) .TRUE..AND..TRUE. , .TRUE..AND..FALSE. , T.OR.T , T.OR.F , F.OR.F
      WRITE (*,*) 1<2. 1==2 1>2, .NOT.((1>2).OR.(1<2))
    END PROGRAM

     

    결과
    T F T T F
    T F F F

     

    • IF 문

      • 조건 분기문 IF의 기본 구조는 다음과 같습니다

    IF (logical expression) THEN
      statements
    END IF

     

    • IF 와 END IF 사이의 내용은 logical expression 의 논리값이 참일 경우에만 실행되게 됩니다.

    • IF 문에 의해서 실행되는 문장이, 하나밖에 없을 때에는 THEN 과 END IF 를 생략하고, 바로 다음과 같은 형식으로 쓸 수 있습니다.

    IF (logical expression) statement

     

    • IF 를 사용한 다중분기는 ELSE 와 ELSE IF 를 이용하게 됩니다.

    IF (logical expr1) THEN
      statements
    ELSE IF (logical expr2) THEN
      statements
    ELSE
      statements
    END IF

     

    • 포트란의 IF 문은 nested IF 문의 경우에 어떤 ELSE IF 가 어디서 시작되었는지, 어떤 END IF 가 어떤 IF에 해당하는지 표시 할 때 유용하다.

    • 레이블(name)링을 이용한 구문은 다음과 같습니다

    name: IF ( ... ) THEN
      ...
    ELSE IF ( ... ) THEN [name]
      ...
    ELSE [name]
      ...
    END IF name.

     

    • SELECT CASE 문

      • 포트란의 다중분기의 기본 구조는 다음과 같습니다

    SELECT CASE ( case expression )
    CASE ( case selector 1 )
      ...
    CASE ( case selector 2 )
      ...
    CASE DEFAULT
      ...
    END SELECT

     

    • case expression 부분에 들어가는 내용의 분기 값은 정수형, 문자형(문자열포함), 논리형 을 사용할 수 있습니다.

    • case selector 는 case expression 의 분기 값이 포함될 범위나 특정 값을 나타냅니다.

    • case selector는 case expression 의 분기 값을 동시에 만족하는 조건이 있으면 안됩니다.

    • case selector 가 특정 값 일 때는, 괄호 안에 그 값을 그냥 넣어 주면 됩니다.

    • 특정 값들이 여러 개 일 경우에는 콤마(,) 를 이용하여 나열하여 넣어 줍니다.

    • 범위 일 때는 콜론 (:) 을 이용하게 됩니다.. a : b 는 ' a 이상 b 이하 ' 를 의미합니다.

    • 또한, : b 는 'b 이하' 를 나타내고, a : 는 'a 이상' 을 의미합니다.

    • SELECT CASE 도 IF 와 마찬가지로 네이밍이 가능합니다.

     

    • 루프 DO , 탈출 EXIT , 스킵핑 CYCLE (1/2)

      • DO 는 루프문이라 하여 조건에 따라 반복 수행하는 구문으로 기본 구조는 다음과 같습니다.

    DO [ index_variable = index_start, index_end [,index_increment ]]
      ...
    END DO

     

    • 카운팅 루프를 위한 [ ] 부분은 옵션이다. [ ] 부분을 생략할 경우, DO ~ END DO 는 기본적으로 무한루프로 계속 동작하게 됩니다.

    • 이 경우, 반드시 루프 탈출을 위한 문장(EXIT)이 루프내부에서 실행되어야 합니다.

    • 루프 탈출을 위한 EXIT는 IF 로 탈출조건을 제시하는 것이 기본 사용법입니다.

    IF ( exit condition )
      EXIT
    END IF

     

    • 카운팅 루프를 위한 부분을 살펴보면, index_variable 항은 루프변수의 시작값, index_end은 종료값, index_increment 값은 증가치 입니다.

    • index_start, index_end [,index_increment ] 부분은 상수일수도 있고, 변수일수도 있고, 수식일수도 있습니다.

    • 실행순서를 서술해 보면 다음과 같습니다.

    • 일단 루프 시작 시 카운팅 제어 부분에 대한 평가가 실행되고 루프변수의 시작 값을 배정하는 부분이 실행된 후 루프변수와 종료 값과의 비교하여 루프내용(바디)을 실행하거나 건너뜁니다.

    • 바디실행 후, 증가치에 따라 루프 변수 값을 변화 ( 값이 음수이면 감소) 시키고, 다시 비교하여 바디를 실행하거나 건너뛰게 됩니다.

    • 예를 들어

    DO 1 , 5 , 1
      ... body
    END DO

     

    • 일 경우 1의 값이 1씩 증가하면서 5가 될 때까지 바디를 5번 수행하게 됩니다.

     

    • 루프 DO , 탈출 EXIT , 스킵핑 CYCLE (2/2)

      • 루프변수와 종료값의 비교에 의한 바디 실행조건은, 증분값이 양수이냐 음수이냐에 따라 기본적으로 다음과 같이 생각할 수 있습니다.

      • 양수인 경우, 루프변수는 증가하고, 따라서 루프변수가 종료변수 이하 일 때 바디가 실행됩니다.

      • 음수인 경우, 루프변수는 감소하고, 따라서 루프변수가 종료변수 이상 일 때 바디가 실행됩니다.

      • index_increment (증가분 부분)는 생략되는 경우, 1로 간주하게 됩니다.

      • 루프변수도 역시 변수인 관계로, 루프 내부에서 조작 및 참조가 가능합니다.

      • EXIT 가 루프자체를 완전히 탈출시킨다면, CYCLE 은 컨트롤을 index_increment (증가분 부분)으로이동시키는 역할을 합니다.

    IF ( cycle condition )
      CYCLE
    END IF

     

    • cycle 조건이 되면 index_increment 에 따라 루프변수 값을 변화 시킵니다.(쉽게 말하면 조건에 따라 한번 스킵) EXIT 와 CYCLE 은 C언어의 break , continue 와 같다고 할 수 있겠습니다.

    • 루프문 DO 에도 네이밍이 가능합니다.

    • 이는 앞의 IF 나 SELECT CASE 믄에서 처럼 네스티드 구조일때 상당한 효용성을 제공하게 됩니다.

    • DO 에 네이밍했으면 END DO 도 매치되는 네이밍을 요구하게 됩니다.

    • CYCLE 과 EXIT 에 대해서는 네이밍은 옵션이지만 네이밍 할 경우, 대응되는 루프의 네임과 매치되어야만 합니다.

    name : DO
      …
      … CYCLE [name]
      … EXIT [name]
      …
    END DO name

     

     참고 문헌

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기