수색…


암시 적 변수 유형

Fortran이 원래 개발되었을 때 메모리는 프리미엄되었습니다. 변수 및 프로 시저 이름은 최대 6 자까지 가능하며 변수는 종종 암시 적으로 입력 됩니다. 즉, 변수 이름의 첫 문자가 유형을 결정합니다.

  • i, j, ..., n으로 시작하는 변수는 integer
  • 그 밖의 모든 것은 (a, b, ..., h, o, p, ..., z) real

허용되는 Fortran은 다음과 같은 프로그램입니다.

program badbadnotgood
  j = 4
  key = 5 ! only the first letter determines the type
  x = 3.142
  print*, "j = ", j, "key = ", key, "x = ", x
end program badbadnotgood

implicit 성명을 사용하여 implicit 적 규칙을 정의 할 수도 있습니다.

! all variables are real by default 
implicit real (a-z)

또는

! variables starting with x, y, z are complex
! variables starting with c, s are character with length of 4 bytes
! and all other letters have their default implicit type
implicit complex (x,y,z), character*4 (c,s) 

암시 적 타이핑은 더 이상 모범 사례로 간주되지 않습니다. 오타가 눈에 띄지 않을 수 있으므로 암시 적 타이핑을 사용하여 실수를하는 것은 매우 쉽습니다.

program oops
  real :: somelongandcomplicatedname

  ...

  call expensive_subroutine(somelongandcomplEcatedname)
end program oops

이 프로그램은 즐겁게 달리고 잘못된 일을 할 것입니다.


암시 적 타이핑을 끄려면 implicit none 문을 사용할 수 있습니다.

program much_better
  implicit none
  integer :: j = 4
  real :: x = 3.142
  print*, "j = ", j, "x = ", x
end program much_better

우리가 사용되지 않았다면 implicit none 프로그램에 oops 위, 컴파일러는 즉시 발견하고, 오류가 발생했을 것입니다.

산술 if 문

산술 if 문을 사용하면 산술 표현식의 결과에 따라 세 가지 분기를 사용할 수 있습니다.

if (arith_expr) label1, label2, label3

if 문은 제어 흐름을 코드의 레이블 중 하나로 전달합니다. arith_expr 의 결과가 음수 인 경우 label1 이 관련되고 결과가 0이면 label2 가 사용되며 결과가 양수이면 마지막 label3 이 적용됩니다. 산술 if 세 가지 레이블을 필요로하지만, 따라서이 문장은 두 가지로 단순화 할 수있는 라벨의 재사용을 허용 if .

예 :

if (N * N - N / 2) 130, 140, 130

if (X) 100, 110, 120

이제이 기능은 if 구문과 if-else 구문이 제공하는 동일한 기능으로 폐기되었습니다. 예를 들어, 조각

    if (X) 100, 110, 120
100 print*, "Negative"
    goto 200
110 print*, "Zero"
    goto 200
120 print*, "Positive"
200 continue

if-else 구문으로 쓸 수 있습니다.

if (X<0) then
  print*, "Negative"
else if (X==0) then
  print*, "Zero"
else
  print*, "Positive"
end if

if 문 대체

    if (X) 100, 100, 200
100 print *, "Negative or zero"
200 continue

아마도

if (X<=0) print*, "Negative or zero"

비 블록 DO 구성

non-block do 구조는 다음과 같습니다.

    integer i
    do 100, i=1, 5
100 print *, i

즉, 레이블이 지정된 종료 문이 continue 문이 아닌 경우입니다. 종료 문으로 사용될 수있는 문에는 여러 가지 제한이 있으며 일반적으로 모든 것이 매우 혼란 스럽습니다.

이러한 비 블록 구조는 다음과 같이 블록 형식으로 재 작성 될 수 있습니다.

    integer i
    do 100 i=1,5
      print *, i
100 continue

또는 더 나은, end do 종료 문을 사용하여,

integer i
do i=1,5
  print *, i
end do

대체 수익

대체 리턴은 서브 루틴의 리턴시 실행 플로우를 제어하는 ​​기능입니다. 이것은 종종 오류 처리의 한 형태로 사용됩니다 :

real x

call sub(x, 1, *100, *200)
print*, "Success:", x
stop

100 print*, "Negative input value"
stop

200 print*, "Input value too large"
stop

end

subroutine sub(x, i, *, *)
  real, intent(out) :: x
  integer, intent(in) :: i
  if (i<0) return 1
  if (i>10) return 2
  x = i
end subroutine

대체 리턴은 서브 루틴 임시 인수 목록의 인수 * 로 표시됩니다.

*100*200 위의 call 명령문에서 각각 100200 레이블이 붙은 명령문을 참조하십시오.

서브 루틴 자체에서 대체 return에 해당하는 return 문에는 숫자가 있습니다. 이 숫자는 반환 값이 아니며 반환 할 때 실행이 전달되는 제공된 레이블을 나타냅니다. 이 경우 return 1100 이라고 표시된 문으로 실행을 전달하고 return 2200 이라는 문으로 실행을 전달합니다. 캐스팅하지 return 없이 문, 또는 서브 루틴의 실행이 완료 return 문, passess 실행에 즉시 호출 문 후.

대체 리턴 구문은 다른 형식의 인수 연관과 매우 다르며이 기능은 현대적인 취향과 반대되는 흐름 제어를 도입합니다. 더 나은 흐름 제어는 정수 "상태"코드를 반환하여 관리 할 수 ​​있습니다.

real x
integer status

call sub(x, 1, status)
select case (status)
case (0)
  print*, "Success:", x
case (1)
  print*, "Negative input value"
case (2)
  print*, "Input value too large"
end select

end

subroutine sub(x, i, status)
  real, intent(out) :: x
  integer, intent(in) :: i
  integer, intent(out) :: status

  status = 0

  if (i<0) then
    status = 1
  else if (i>10)
    status = 2
  else
    x = i
  end if

end subroutine

고정 소스 양식

Fortran은 원래 80 열 펀치 카드를 기반으로 고정 된 형식 으로 설계되었습니다.

여기에 이미지 설명을 입력하십시오.

예 : 작성자 자신의 코드 줄입니다.

이것은 다음과 같이 카드 펀치 기계에서 생성되었습니다.

여기에 이미지 설명을 입력하십시오.

이미지는 저자가 직접 찍은 사진입니다.

그림 샘플 카드에 표시된 것처럼 서식에는 처음 5 개의 열이 문 서 레이블에 예약되어 있습니다. 첫 번째 열은 문자 C로 주석을 나타 내기 위해 사용되었습니다. 여섯 번째 열은 명령문 연속을 나타내는 데 사용됩니다 ( '0'이외의 문자를 삽입하여). 마지막 8 개의 열은 카드 식별 및 시퀀싱에 사용되었으며, 바닥에 카드 덱을 떨어 뜨린 경우 매우 유용했습니다. 천공 카드에 대한 문자 코드는 제한된 문자 집합을 가지고 있었으며 대문자 만 사용되었습니다. 결과적으로 Fortran 프로그램은 다음과 같이 보입니다.

       DIMENSION A(10)                                                    00000001
C THIS IS A COMMENT STATEMENT TO EXPLAIN THIS EXAMPLE PROGRAM             00000002
       WRITE (6,100)                                                      00000003
 100   FORMAT(169HTHIS IS A RATHER LONG STRING BEING OUTPUT WHICH GOES OVE00000004
      1R MORE THAN ONE LINE, AND USES THE STATEMENT CONTINUATION MARKER IN00000005
      2COLUMN 6, AND ALSO USES HOLLERITH STRING FORMAT)                   00000006
       STOP                                                               00000007
       END                                                                00000008

공백 문자는 Hollerith 문자 상수를 제외하고는 모든 곳에서 무시되었습니다 (위 그림 참조). 이것은 공간이 예약어와 상수 안에서 발생할 수 있거나 완전히 빠져 있음을 의미합니다. 이것은 다음과 같은 약간 오해의 소지가있는 진술의 부작용을 가지고있다 :

       DO 1 I = 1.0

변수 DO1I 대한 할당은 다음과 같습니다.

       DO1I = 1,0 

실제로는 변수 IDO 루프입니다.


Modern Fortran은 고정 된 형태의 입력을 필요로하지 않으며 모든 컬럼을 사용하여 자유 형식을 허용합니다. 코멘트는 이제 ! 표시됩니다 ! 이는 명령문 행에 추가 될 수도 있습니다. 공백은 이제 어디서든 허용되지 않으며 대부분의 다른 언어에서와 마찬가지로 구분 기호로 사용해야합니다. 위의 프로그램은 현대 Fortran에서 다음과 같이 작성 될 수 있습니다.

! This is a comment statement to explain this example program
Print *,"THIS IS A RATHER LONG STRING BEING OUTPUT WHICH no longer GOES OVER MORE THAN ONE LINE, AND does not need to USE THE STATEMENT CONTINUATION MARKER IN COLUMN 6, or the HOLLERITH STRING FORMAT"

이전 스타일의 연속성은 더 이상 사용되지 않지만 위의 예에서는 매우 긴 명령문이 계속 발생 함을 보여줍니다. 현대 Fortran은 연속의 끝과 처음에 & 기호를 사용합니다. 예를 들어 위의 내용을보다 읽기 쉬운 형식으로 작성할 수 있습니다.

! This is a comment statement to explain this example program
Print *,"THIS IS A RATHER LONG STRING BEING OUTPUT WHICH still &
         &GOES OVER MORE THAN ONE LINE, AND does need to USE THE STATEMENT &
         &CONTINUATION notation"

공통 블록

초기 양식의 Fortran에서 서브 루틴 및 함수에서 볼 수있는 전역 변수 저장소를 만드는 유일한 메커니즘은 COMMON 블록 메커니즘을 사용하는 것입니다. 이것은 일련의 변수가 이름이되고 공통으로 공유되도록 허용했습니다.

명명 된 공통 블록 외에도 공백 (이름이없는) 공통 블록이있을 수 있습니다.

빈 공통 블록은 다음과 같이 선언 될 수 있습니다.

common i, j

명명 된 블록 variables 는 다음과 같이 선언 될 수 있습니다.

common /variables/ i, j

완전한 예제로서 값을 추가하고 제거 할 수있는 루틴에 의해 사용되는 힙 저장소를 상상할 수 있습니다.

       PROGRAM STACKING
       COMMON /HEAP/ ICOUNT, ISTACK(1023)
       ICOUNT = 0
       READ *, IVAL
       CALL PUSH(IVAL)
       CALL POP(IVAL)
       END

       SUBROUTINE PUSH(IVAL)
       COMMON /HEAP/ ICOUNT, ISTACK(1023)
       ICOUNT = ICOUNT + 1
       ISTACK(ICOUNT) = IVAL
       RETURN
       END

       SUBROUTINE POP(IVAL)
       COMMON /HEAP/ ICOUNT, ISTACK(1023)
       IVAL = ISTACK(ICOUNT)
       ICOUNT = ICOUNT - 1
       RETURN
       END

변수의 유형을 내재적으로 선언하고 dimension 속성을 지정하기 위해 공통 명령문을 사용할 수 있습니다. 이러한 행동만으로는 혼란의 원인이 될 수 있습니다. 또한, 묵시적 저장 연관과 프로그램 단위에 반복적 인 정의가 필요한 이유는 공통 블록을 사용하여 오류가 발생하기 쉽습니다.

마지막으로 공통 블록은 포함 된 객체에서 매우 제한적입니다. 예를 들어, 공통 블록의 배열은 명시적인 크기 여야합니다. 할당 가능한 객체가 발생하지 않을 수 있습니다. 파생 형식은 기본 초기화가 없어야합니다.

현대 Fortran에서이 변수 공유는 모듈을 사용하여 처리 할 수 ​​있습니다. 위의 예는 다음과 같이 작성할 수 있습니다.

module heap
  implicit none
  ! In Fortran 2008 all module variables are implicitly saved
  integer, save :: count = 0
  integer, save :: stack(1023)
end module heap

program stacking
  implicit none
  integer val
  read *, val
  call push(val)
  call pop(val)

contains
  subroutine push(val)
    use heap, only : count, stack
    integer val
    count = count + 1
    stack(count) = val
  end subroutine push

  subroutine pop(val)
    use heap, only : count, stack
    integer val
    val = stack(count)
    count = count - 1
  end subroutine pop
end program stacking

명명 된 빈 블록과 빈 일반 블록은 약간 다른 동작을합니다. 주의 사항 :

  • 명명 된 공통 블록의 객체가 처음에 정의 될 수 있습니다. 빈 공동의 물건은
  • 빈 공통 블록의 객체는 공통 블록에 save 속성이있는 것처럼 동작합니다. 블록이 활성 프로그램 단위의 범위에 있지 않으면 save 속성없이 명명 된 공통 블록의 객체가 정의되지 않을 수 있습니다

이 후자의 점은 현대 코드의 모듈 변수의 동작과 대조 될 수 있습니다. Fortran 2008의 모든 모듈 변수는 암시 적으로 저장되며 모듈이 범위를 벗어날 때 정의되지 않습니다. 명명 된 공통 블록의 변수와 마찬가지로 Fortran 2008 모듈 변수가 나오기 전에 모듈이 범위를 벗어 났을 때 정의되지 않은 상태가됩니다.

지정된 GOTO

지정된 GOTO는 ASSIGN 문을 사용하여 명령문 레이블이 지정된 정수 변수를 사용합니다.

100 CONTINUE

...

ASSIGN 100 TO ILABEL

...


GOTO ILABEL

지정된 GOTO는 Fortran 90에서는 폐기되었으며 Fortran 95 이상에서는 삭제되었습니다. 프로 시저, 내부 프로 시저, 프로 시저 포인터 및 기타 기능을 사용하여 현대 코드에서 피할 수 있습니다.

계산 된 GOTO

계산 된 GOTO는 정수 표현식의 값에 따라 프로그램 분기를 허용합니다.

GOTO (label_1, label_2,... label_n) scalar-integer-expression

scalar-integer-expression 이 1이면 프로그램은 명령문 레이블 label_1 에서 계속 진행하고 2와 label_2 로 이동합니다. 1 보다 작거나 n 보다 크면 다음 줄에 프로그램이 계속됩니다.

예:

ivar = 2

...

GOTO (10, 20, 30, 40) ivar

명령문 레이블 20으로 점프합니다.

이 형태의 goto 는 Fortran 95 이상에서 폐기되었으며, select case 구문으로 대체되었습니다.

지정된 형식 지정자

Fortran 95 이전에는 입력 또는 출력을 위해 지정된 형식을 사용할 수있었습니다. 중히 여기다

integer i, fmt
read *, i

assign 100 to fmt
if (i<100000) assign 200 to fmt

print fmt, i

100 format ("This is a big number", I10)
200 format ("This is a small number", I6)

end

assign 문은 명령문 레이블을 정수 변수에 지정합니다. 이 정수 변수는 나중에 print 문에서 형식 지정자로 사용됩니다.

이러한 형식 지정자 할당은 Fortran 95에서 삭제되었습니다. 대신 최신 코드는 다른 형태의 실행 흐름 제어를 사용할 수 있습니다

integer i
read *, i

if (i<100000) then
  print 100, i
else
  print 200, i
end if

100 format ("This is a big number", I10)
200 format ("This is a small number", I6)

end

또는 문자 변수가 형식 지정자로 사용될 수 있습니다

character(29), target :: big_fmt='("This is a big number", I10)'
character(30), target :: small_fmt='("This is a small number", I6)'
character(:), pointer :: fmt

integer i
read *, i

fmt=>big_fmt
if (i<100000) fmt=>small_fmt

print fmt, i

end

명령문 함수

프로그램을 고려해보십시오.

implicit none
integer f, i
f(i)=i

print *, f(1)
end

여기서 f 는 명령문 기능입니다. 그것은 하나의 정수 더미 인수를 취하는 정수 결과 유형을가집니다. 1

이러한 명령문 기능은 정의 된 범위 내에 존재합니다. 특히, 해당 범위에서 액세스 할 수있는 변수 및 명명 된 상수에 액세스 할 수 있습니다.

그러나 명령문 함수는 많은 제한을받으며 잠재적으로 혼란 스럽습니다 (배열 요소 할당 문과 같은 일시적인 것을 보았을 때). 중요한 제한 사항은 다음과 같습니다.

  • 함수 결과와 더미 인수는 스칼라 여야합니다.
  • 가짜 인수는 함수와 동일한 범위에 있습니다.
  • 명령문 함수에는 지역 변수가 없습니다.
  • 명령문 함수는 실제 인수로 전달 될 수 없습니다.

명령문 함수의 주요 이점은 내부 함수에 의해 반복됩니다.

implicit none

print *, f(1)

contains

  integer function f(i)
    integer i
    f = i
  end function

end

내부 함수는 내부 서브 프로그램이 더 이상 내부 서브 프로그램을 포함하지 않을 수 있지만 (명령문 함수를 포함 할 수 있음) 유의할만한 가치가 있지만, 위에서 언급 한 제한 사항의 적용을받지 않습니다.

내부 기능에는 자체 범위가 있지만 사용 가능한 호스트 연결도 있습니다.


1 실제 예전의 코드 예제에서는 결과에 명시 적 형식이 있더라도 암시 적으로 형식화 된 문 함수의 가짜 인수를 보는 것이 일반적이지는 않습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow