Fortran中BLOCK的意义是什么?

时间:2018-07-23 09:41:52

标签: fortran

我正在查看一些代码,它是这样的:

BLOCK

...lines of code...

END BLOCK

BLOCK的目的是什么?我尝试用Google搜索它,但发现的全部都是关于BLOCK DATACOMMON块的内容。我不确定它们是否相关。

3 个答案:

答案 0 :(得分:8)

根据Fortran 2008标准:

  

BLOCK构造是一个可执行的构造,可能包含声明。

它与通用块或块数据程序单元无关。

因此,主要用途是此“包含声明”。

作为范围划分单位,我们有类似的东西

integer i
block
  integer j ! A local integer
  integer i ! Another i
  save i    ! ... which can even be SAVEd
end block

提供声明的位置:

! ... lots of code
block
  integer something
  read *, something
end block
! ... lots more code

这些作用域块允许automatic objects

integer i
i = 5
block
  real x(i)
end block

作为可执行结构,它们还具有有用的flow control

this_block: block
  if (something) exit this_block
  ! ... lots of code
end block

它们还具有最终确定控制权:

type(t) x
block
  type(t) y
end block ! y is finalized
end  ! x is not finalized

针对xy的可终结类型。

哦,让我们不要忘记如何将人们与隐式键入混淆。

答案 1 :(得分:5)

我还撰写了一些有趣的示例。如果要在子程序的同一实例中调用具有不同assumed length function的{​​{1}}怎么办?您需要一个lengths来告诉编译器您想要的长度,因此specification statement构造可以为您完成此操作

BLOCK

输出为function F(x) implicit none character(*) F character x(:) integer i do i = 1, len(F) F(i:i) = x(1) end do end function F program blox1 implicit none integer i character c do i = 1, 7 c = achar(65+modulo(i**4+6*i**2+1,26)) block character(2*i+1), external :: F call blox1a(F) end block end do contains subroutine blox1a(F) interface function F(x) import implicit none character(2*i+1) F character x(:) end function F end interface write(*,'(a)') F([c]) end subroutine blox1a end program blox1

gfortran

或者什么时候需要III PPPPP GGGGGGG PPPPPPPPP WWWWWWWWWWW FFFFFFFFFFFFF SSSSSSSSSSSSSSS 来使用合适的KIND?这需要REAL literal,并且named constant可以在另一个KIND的{​​{1}}中给出,甚至可以作为specification statements给出。在这种情况下,您可以尝试使用该MODULE的值定义一个expression,但是如果做出了不幸的选择,则该名称可能会覆盖另一个named constant的名称。 expression构造可以使一切正常:

host associated

输出为BLOCK

module mytypes
   use ISO_FORTRAN_ENV
   implicit none
   type T(KIND)
      integer, kind :: KIND
      real(KIND) x
   end type T
   interface assignment(=)
      module procedure assign8, assign4
   end interface assignment(=)
   contains
      subroutine assign8(x,y)
         real(REAL64), intent(in) :: y
         type(T(kind(y))), intent(out) :: x
         x%x = y
      end subroutine assign8
      subroutine assign4(x,y)
         real(REAL32), intent(in) :: y
         type(T(kind(y))), intent(out) :: x
         x%x = y
      end subroutine assign4
end module mytypes

program blox2
   use mytypes
   implicit none
   type(T(REAL32)) x
BLOCK
!   integer, parameter :: rk = x%KIND ! Not allowed
   integer, parameter :: rk = kind(x%x)
   x = 0.0072973525664_rk
   write(*,'(g0)') x%x
END BLOCK    -1 is too small
12! = 479001600
13 is too big
BLOCK
   type(T(REAL64)) x
BLOCK
!   integer, parameter :: rk = x%KIND ! Not allowed
   integer, parameter :: rk = kind(x%x)
   x = 0.0072973525664_rk
   write(*,'(g0)') x%x
END BLOCK
END BLOCK
end program blox2

gfortran赋予0.729735242E-02 0.72973525663999998E-002 可能很棘手,因为没有语法可以告诉Fortran pointer的{​​{1}}中C string的{​​{1}} C_F_POINTER应该是。 length进行救援!

target

输出为deferred length pointer

BLOCK

更不用说program blox3 use ISO_C_BINDING implicit none character(len=:,kind=C_CHAR), allocatable, target :: x type(C_PTR) c_hello integer(C_INTPTR_T) address character(kind=C_CHAR), pointer :: nul_address character(len=:,kind=C_CHAR), pointer :: f_hello integer i x = 'Hello, world'//achar(0) c_hello = C_LOC(x(1:1)) address = transfer(c_hello,address) i = 0 do call C_F_POINTER(transfer(address+i,C_NULL_PTR),nul_address) if(nul_address == C_NULL_CHAR) exit i = i+1 end do BLOCK character(len=i,kind=C_CHAR), pointer :: temp call C_F_POINTER(c_hello,temp) f_hello => temp END BLOCK write(*,'(i0,1x,a)') len(f_hello), f_hello end program blox3 赋予我们gfortran来将12 Hello, world 挂在:

named BLOCK construct

输出为label

spaghetti code

答案 2 :(得分:4)

block构造允许您声明实体,例如变量,类型,外部过程等,这些实体对于块是本地已知的,但对块外的任何变量均无效。

示例1:

IF (swapxy) THEN
  BLOCK
    REAL (KIND (x)) tmp
    tmp = x
    x = y
    y = tmp
  END BLOCK
END IF

此处,变量tmp在本地定义,以帮助交换两个变量。在块外部,变量tmp是未知的,或者如果它在块外部定义,则返回其原始形式(请参见下一个示例)。

示例2:

F = 254E-2
BLOCK
  REAL F
  F = 39.37
END BLOCK
! F is still equal to 254E-2.

变量F在块的本地重新定义,但在块外部无效。

由于无需查看整个子程序来了解本地定义的实体是什么,因此这些类型的块用于使代码更易读和易于理解。此外,编译器知道这些实体是本地定义的,因此它可能会做更多的优化。