如何访问Fortran中contains内的子程序以重置save变量
Fortran中如何访问contains内的内部子程序?
Fortran语法规定,contains块内的内部子程序是封装在宿主子程序作用域内的,没办法直接从外部绕过限制调用。不过针对你的重置需求,有几种改动量极小的替代方案:
方案1:给宿主子程序加控制参数
直接给count子程序加一个可选开关参数,用来触发内部的重置逻辑,不需要修改原有调用代码,新增重置调用只需要传参数即可:
program main implicit none call count ! 1 call count ! 2 call count ! 3 call count(reset=.true.) ! 触发重置操作 call count ! 1 end program main subroutine count(reset) logical, intent(in), optional :: reset integer, save :: numcalled = 0 ! 优先处理重置请求 if (present(reset)) then if (reset) then numcalled = 0 return end if end if numcalled = numcalled + 1 print *, numcalled return contains ! 原reset子程序可保留作为内部实现,也可以直接把逻辑写到上面的判断里 subroutine reset_internal numcalled = 0 end subroutine reset_internal end subroutine count
方案2:封装到模块中(适合多场景复用)
如果后续有更多类似的重置需求,把需要保存的变量和操作逻辑移到模块里,模块内的子程序可以互相访问,外部也能直接调用重置子程序,更符合Fortran模块化设计:
module count_mod implicit none integer, save :: numcalled = 0 contains subroutine count() numcalled = numcalled + 1 print *, numcalled end subroutine count subroutine reset() numcalled = 0 end subroutine reset end module count_mod program main use count_mod implicit none call count ! 1 call count ! 2 call count ! 3 call reset ! 直接调用重置 call count ! 1 end program main
为什么无法直接调用contains内的子程序?
Fortran的内部子程序依赖宿主关联,作用域严格限定在宿主子程序内部,这是语言本身的封装机制。interface和external关键字也无法突破这个限制——因为内部子程序没有在宿主外的作用域中声明,外部代码根本无法识别它的存在。
内容的提问来源于stack exchange,提问作者Marty Farce
相关产品推荐
相关产品推荐

