我正在查看一些代码,它是这样的:
BLOCK
...lines of code...
END BLOCK
BLOCK
的目的是什么?我尝试用Google搜索它,但发现的全部都是关于BLOCK DATA
和COMMON
块的内容。我不确定它们是否相关。
答案 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
针对x
和y
的可终结类型。
哦,让我们不要忘记如何将人们与隐式键入混淆。
答案 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
在块的本地重新定义,但在块外部无效。
由于无需查看整个子程序来了解本地定义的实体是什么,因此这些类型的块用于使代码更易读和易于理解。此外,编译器知道这些实体是本地定义的,因此它可能会做更多的优化。