정보
-
업무명 : 포트란을 활용한 기초 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
참고 문헌
[논문]
- 없음
[보고서]
- 없음
[URL]
- Fortran을 활용한 분석, 날씨마루 (기상기후 빅데이터 분석 플랫폼), bd.kma.go.kr/kma2020/dta/edu/KBP57200_Fortran.do?pageNum=5&menuCd=F040304000.
문의사항
[기상학/프로그래밍 언어]
- sangho.lee.1990@gmail.com
[해양학/천문학/빅데이터]
- saimang0804@gmail.com
'프로그래밍 언어 > Fortran' 카테고리의 다른 글
[Fortran] 포트란 기초 및 활용 문서 (4) | 2020.11.17 |
---|---|
[Fortran] 포트란을 활용한 에러 : 개요, NaN and Inf3, 예외 처리 (Exception), 에러 종류와 예시 (0) | 2020.11.11 |
[Fortran] 포트란을 활용한 기초 1 : 개요, 포트란 기초, 기본 자료형, 형변환 (0) | 2020.11.09 |
[Fortran] 포트란 Random 함수를 이용한 정규 분포 가시화 (0) | 2020.01.29 |
[Fortran] 포트란 유닉스 시간 (Unix Time)을 날짜로 변환 (0) | 2020.01.28 |
최근댓글