Fortran 中的指针数组

2024-06-26

我已经编写一个用于热力学计算的大型 Fortran 程序近 10 年了,当我开始时,我对新的 Fortran 标准还很陌生(我很熟悉 F77,而且太老了,无法学习其他东西)。我发现新的 TYPE 构造非常好并且经常使用它们,但我没有意识到一些限制,例如不允许创建指针数组,我后来发现了这一点。

现在我正在纠正一些旧代码,我惊讶地发现在记录声明中: TYPE gtp_phase_add

声明:TYPE(tpfun_expression)、dimension(:)、指针 :: explink

其中 explink 用于指向另一个包含数学表达式的结构。这并没有产生任何编译错误(我通常使用 gfortran,但我也使用 intel fortran 编译了这个程序)。当我看到这段旧代码(大约 10 年前写的)时,我以为缺少一个“可分配”,但添加后却出现了编译错误。

我制作了一个最小的完整程序来模仿它的使用方式:

MODULE test1
  implicit none
  
  TYPE tpfun_expression
     integer nc
     double precision, allocatable, dimension(:) :: coeffs
     integer, allocatable, dimension(:) :: powers
  END type tpfun_expression

  TYPE gtp_phase_add
!**************************************************************************
! My question is if it is correct Fortran to have an array of pointers here
     TYPE(tpfun_expression), dimension(:), pointer :: explink
!**************************************************************************
     TYPE(gtp_phase_add), pointer :: nextadd
  END TYPE gtp_phase_add

contains

  subroutine create_tpfun(n,coeffs,powers,exp)
    integer n,i,powers(*)
    double precision coeffs(*)
    type(tpfun_expression), pointer :: exp
    allocate(exp%coeffs(n))
    allocate(exp%powers(n))
    exp%nc=n
    do i=1,n
       exp%coeffs(i)=coeffs(i)
       exp%powers(i)=powers(i)
    enddo
    return
  end subroutine create_tpfun

  subroutine create_addrec(typ,this)
    integer typ,n,m
    TYPE(tpfun_expression), target :: exp1
    TYPE(tpfun_expression), pointer :: exp2
    TYPE(gtp_phase_add), pointer :: this
    integer ipow(4)
    double precision coeffs(4)
!
!**************************************************************************
! here I allocate a pointer array
    allocate(this%explink(typ))
!**************************************************************************
    if(typ.eq.1) then
       do m=1,4
          ipow(m)=m-1
          coeffs(m)=2.0D0*m
       enddo
       exp2=>this%explink(1)
       call create_tpfun(4,coeffs,ipow,exp2)
    else
       do m=1,4
          ipow(m)=m-1
          coeffs(m)=3.0D0
       enddo
       exp2=>this%explink(1)
       call create_tpfun(4,coeffs,ipow,exp2)
       do m=1,3
          ipow(m)=1-m
          coeffs(m)=5.0D0
       enddo
       exp2=>this%explink(2)
       call create_tpfun(3,coeffs,ipow,exp2)
    endif
    return
  end subroutine create_addrec

end MODULE test1

program main
  use test1
  integer n,m,j,k,q
  TYPE(gtp_phase_add), target :: addrec
  TYPE(gtp_phase_add), pointer :: next,first
  TYPE(tpfun_expression) :: exp
  
  first=>addrec
  next=>addrec
  write(*,*)'Creating addrec 1'
  call create_addrec(1,next)
  allocate(next%nextadd)
  write(*,*)'Creating addrec 2'
  next=>next%nextadd
  call create_addrec(2,next)
! just a check that the functions are correct
  write(*,*)'Listing functions in all addrecs'
  next=>first
  q=0
  do while(associated(next))
     q=q+1
     write(*,*)'Addition record ',q
     n=size(next%explink)
     do m=1,n
        k=next%explink(m)%nc
        write(*,10)(next%explink(m)%coeffs(j),next%explink(m)%powers(j),j=1,k)
     enddo
10   format(10(F6.3,1x,i3))
     next=>next%nextadd
  enddo
end program main

这正如我所期望的那样,我只是惊讶于我允许声明一个指针数组,所以我想知道这是否是正确的 Fortran。 如果我无法理解如何更优雅地编辑它,我很抱歉。


是的,您可以拥有一个带有指针属性的数组。考虑简单的代码

program foo
  integer, target :: i(10)
  integer, pointer :: j(:)
  i = [(n,n=1,10)]
  j => i
  print '(10(I3))', j
end program foo

使用 gfortran 编译时,没有警告/错误(正确的程序不应该有),并且输出为 1 2 3 4 5 6 7 8 9 10。上面的一个稍微复杂的版本是

program foo
  integer, pointer :: j(:)
  allocate(j(10))
  j = [(n,n=1,10)]
  print '(10(I3))', j
end program foo

The allocate语句将分配一个包含 10 个元素的匿名目标(由于缺乏更好的名称)。j指向那个匿名目标。与第一个程序相比,这里的区别在于j = [(n,n=1,10]是一个内在的分配,而在前者j => i是指针赋值。

PS:如果不需要的话pointer,这是(IMO)使用的好习惯allocatable.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Fortran 中的指针数组 的相关文章

随机推荐

  • 当执行 Tomcat 的 proxy_pass 时,Nginx 如何添加子域作为参数

    我想要实现的目标Web 应用程序应该能够支持多个子域 而无需在每次使用新子域时对 nginx 或 tomcat 进行任何更改 我已经对 DNS 进行了必要的更改以支持通配符子域 Nginx 监听端口 80 它在端口 8080 上对 tomc
  • CanExecute 何时被调用?

    在演示中 我有一个按钮可以切换布尔字段isAsking 我创建了一个命令 该命令仅在以下情况下执行isAsking true 一旦我按下切换按钮 okButton IsEnable立即更改 这表明该命令发现了更改isAsking 我感到很困
  • MVC 4 文本框未在回发时更新

    我有一个使用 modelview 对象的表单 该对象在提交表单的回发时不会更新文本框值 提交表单时 我编辑绑定到文本框的对象的属性 当表单返回时 对象属性仍然更改 但文本框值不会更改 这就像文本框值被缓存并且不会改变 我该如何解决 文本框默
  • 使关闭图像出现在 DIV 的右上角

    我想知道如何使一个小十字 闭合 图像出现在 div 的右上角 使用 CSS 和 XHTML 谢谢 你可以这样做 jsfiddle net 7JEAZ 1317 http jsfiddle net 7JEAZ 1317 代码片段 panel
  • Java 中的“实现 Runnable”与“扩展线程”

    从我什么时候开始使用线程Java 我找到了这两种编写线程的方法 With 实施Runnable public class MyRunnable implements Runnable public void run Code Started
  • UIView 的变换看起来很糟糕

    我有一个简单的视图和简单的背景 我需要旋转视图及其内容 代码在这里 CGAffineTransform r CGAffineTransformMakeRotation 5 M PI 180 0f backView transform r 我
  • 任意旋转中两条抛物线相交的代码或公式

    我正在研究一个几何问题 需要找到任何旋转中两个抛物线弧的交点 我能够通过旋转平面使弧与轴对齐来相交直线和抛物线弧 但两条抛物线不能同时与轴对齐 我正在努力推导公 式 但我想知道是否有可用的资源 我首先定义没有旋转的二维抛物线弧的方程 x t
  • Django 嵌套查询集

    我有一个像这样的 Django 数据模型 省略数据字段 class Atom Model pass class State Model atom ForeignKey Atom class Transition Model atom For
  • Safari 不会通过 http/2 加载某些资源

    服务器上启用了 Http 2 昨天我注意到在 Iphone IOS 10 2 上未加载某些资源并出现错误 failed to load resource connecting to server is not possible 当我将 Ip
  • Firebase 无法使用类检索数据[重复]

    这个问题在这里已经有答案了 我有一些功能齐全的代码行检索每个数据 但未能使用类检索它们 例如 这些线路运行良好 double value double ds child player1score getValue long value lo
  • 如何模拟 FileReader 的失败

    我有一个函数可以创建一个FileReader 在该函数中我还设置了load and error事件处理程序 handleFileSelect files ArrayLike
  • 如何阻止 Xcode 11 将 CFBundleVersion 和 CFBundleShortVersionString 更改为 $(CURRENT_PROJECT_VERSION) 和 $(MARKETING_VERSION)?

    从版本 11 开始 Xcode 设置了我的CFBundleVersion价值 CURRENT PROJECT VERSION and my CFBundleShortVersionString重视 MARKETING VERSION 每当我
  • 我无法在项目中使用节点波本威士忌

    我尝试对 scss 文件使用 npm 模块 波本威士忌 我收到以下错误 with function var paths Array prototype slice call arguments return concat apply bou
  • 我应该如何从非 root Debian Linux 守护进程登录?

    我正在编写一个新的守护进程 它将托管在 Debian Linux 上 我发现 var log 具有仅 root 写入权限 因此我的守护进程无法在那里写入日志文件 但是 如果它写入那里 它似乎将获得自动日志轮转 并且也按照用户期望的方式工作
  • 如何逐步完成 Python 表达式求值过程?

    我想构建一个可视化调试器 它可以帮助编程学生查看表达式求值是如何发生的 子表达式如何求值并被其值 替换 类似于 Excel 中的表达式求值可视化工具 看起来您无法使用 Python 的 pdb 逐步完成此过程 因为其最精细的步骤粒度是代码行
  • C# 属性实际上是方法吗?

    到现在为止 我的印象是Properties Methods在 C 中是两个不同的东西 但后来我做了如下的事情 这对我来说是 大开眼界 我本来期待一处房产stringProp和一种方法stringProp但我得到了这个 为什么会发生这样的事
  • PHP 难以检查数组中的元素是否为整数类型

    我正在尝试检测一个或多个变量是否包含数字 我尝试了几种不同的方法 但并没有完全成功 这是我尝试过的
  • 尝试将无根 Podman + docker-compose + Traefik 与 podman.sock 一起使用时权限被拒绝

    TL DR 尝试通过 podman 套接字将无根 Podman 与 docker compose 一起使用 并使用 Traefik 容器 与 podman 套接字通信 将流量代理到其他容器 与https stackoverflow com
  • React-Router 在路由更改时重新安装组件

    我有一个连接 到 redux 存储 的组件 我有多个路由都在渲染道具中使用此组件 每次路线改变时 整个组件似乎都被重新安装 有什么办法可以防止这种情况发生吗 我的第一个想法是 我可能每次都会重新实例化组件 因为 render prop 是一
  • Fortran 中的指针数组

    我已经编写一个用于热力学计算的大型 Fortran 程序近 10 年了 当我开始时 我对新的 Fortran 标准还很陌生 我很熟悉 F77 而且太老了 无法学习其他东西 我发现新的 TYPE 构造非常好并且经常使用它们 但我没有意识到一些