Fortran BLOCK结构
Fortran 2008标准提出了BLOCK
语法结构,其作用是创建一个独立的命名空间,在里面可以定义一个可以包含声明的可执行代码块。
BLOCK语法如下:
[block_name:] BLOCK
! declartion
! executable statements
END BLOCK [block_name]
其中block_name可选,对block结构起一个名字可以让代码更加清晰。
BLOCK结构中声明对象包括变量、type定义、外部过程等,这些声明的对象作用域(生命周期)只限于该BLCOK结构,不会影响到BLOCK外的变量,这意味着你可以在BLOCK内声明一个与外部相同的变量名,在BLOCK内声明的变量如与外部变量名相同,外部变量会暂时被”抑制“。
program main
implicit none
integer :: x = 10
block
integer :: x
x = 4
print*, "Inside a block, x=",x
end block
print*, "Outside a block, x=",x
end
编译运行结果:
Inside a block, x= 4
Outside a block, x= 10
BLCOK内部声明外部过程和type派生类型示例:
integer function add(a,b)
integer :: a,b
add = a + b
end function
program main
implicit none
integer :: x = 10
block
integer :: x,y
integer,external :: add ! external funciton add
x = 4; y = 10
print*, "Inside a block, add(x,y)=",add(x,y)
end block
block
type mytype
integer :: value
end type mytype
type(mytype) :: v
v = mytype(10)
print*,"v%value=",v%value
end block
end
BLOCK结构内可以使用EXIT
和GOTO
语句提前终止BLOCK代码的执行。
BLOCK结构可以嵌套使用。
示例:
PROGRAM foo
IMPLICIT NONE
INTEGER :: a
a = 10
add1 : BLOCK
INTEGER :: res1
res1 = a + 1
print*, "res1=",res1
! The BLOCK statement has no BLOCK_construct_name
BLOCK
INTEGER :: res2
res2 = res1 + 1
print*, "res2=",res2
END BLOCK
! The END BLOCK statement must have the same BLOCK construct name 'add1'
END BLOCK add1
!print*,"outside block res1=",res1
END PROGRAM foo
编译运行结果:
res1= 11
res2= 12
如果将最后注释的print语句打开,重新编译会报错,说明res1变量作用域只在BLOCK块中。
block_1.f90:19:35:
print*,"outside block res1=",res1
1
Error: Symbol ‘res1’ at (1) has no IMPLICIT type
实例
代码实例来自stackflow,代码目的是获取C字符串的Fortran指针。 在Fortran与C混编时,C字符串是char *
类型,相当于一个deferred length pointer
,在用C_F_POINTER
函数转换C指针为Fortran指针时需要指定长度(c字符串等价于Fortran char类型的数组),通过以下技巧实现获得C字符串的Fortran指针。
program blox3
use ISO_C_BINDING
implicit none
character(len=:,kind=C_CHAR), allocatable, target :: x
type(C_PTR) c_hello ! C pointer
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)) ! get x's c address
address = transfer(c_hello,address) ! casting type into another
i = 0
do
! convert c pointer of every character into fortran pointer
call C_F_POINTER(transfer(address+i,C_NULL_PTR),nul_address)
! if fortran pointer point to '\0', exit loop
if(nul_address == C_NULL_CHAR) exit
i = i+1
end do
BLOCK
! declare pointer of character of length i
character(len=i,kind=C_CHAR), pointer :: temp
call C_F_POINTER(c_hello,temp) ! c pointer => fortran pointer
f_hello => temp
END BLOCK
write(*,'(i0,1x,a)') len(f_hello), f_hello
end program blox3
参考资料
https://www.ibm.com/docs/en/xffbg/121.141?topic=control-block-construct-fortran-2008
https://stackoverflow.com/questions/51475773/what-is-the-point-of-block-in-fortran

