2

尽管我可以使用最新的编译器,但我必须使用一些旧版 Fortran。

该代码将大量数据存储在一维数组中。

例如,

PROGRAM horrible_coding
IMPLICIT EVERYTHING ! Sarcasm

REAL, DIMENSION(1000) :: data
INTEGER, DIMENSION(50)   :: info_location

! Somewhere, info is read in and stored temporarily as info_1, info_2, etc.

data(1:3) = info_1
data(4:9) = info_2
...
data(134:192) = info_n

DATA数组中的哪些元素与哪些元素之间的关联info存储在第二个数组中。就像是:

info_location(1) = 1
info_location(2) = 4
info_location(n) = 134

这是正确的。数组的每个元素的值是info_location指数据数组的第一个元素,您可以在其中找到相关信息。

因此,例如,如果要获取 info_7 的数据,则必须执行以下操作:

size_of_info_7 = info_location(8) - info_location(7)
ALLOCATE(data_for_info_7(size_of_info_7))
data_for_info_7 = data(info_location(7) : info_location(7) + size_of_info_7 - 1)

到现在为止,看到这种精神错乱可能会让你的眼睛开始喷血,所以我很抱歉。

我想创建对象实例并将每条信息的所有相关数据存储为实例数据。当我把事情带到 2003 年时,我会创建实例方法来获取和设置实例数据。

我不想重写代码,但想把这种现代化放在已经存在的东西之上。

我相信我可以通过使对象实例数据简单地指向data包含相关信息的数组的实际元素的指针来实现这一点。

这是合理的做法吗?

我可以在 Fortran 中创建实例数据主要是指针的对象吗?

如果没有先将这个想法扔给stackoverflow,我会犹豫是否要开始这项任务。

4

2 回答 2

3

我可以在 Fortran 中创建实例数据主要是指针的对象吗?

我不确定你的意思,但你绝对可以做一些事情:

type data_ptr
  real,dimension(:),pointer :: data
end type

您还可以制作以下类型的数组:

type(data_ptr),dimension(:),allocatable :: some_name

(也可以是指针或静态,如你所愿。)

然后,如果原始数据具有TARGET属性,则可以使用:

some_name(i)%data => data(lower:upper)

您还可以将指针重新映射到不同的下限,上面的过程将其设置为下限 1。

于 2012-06-04T07:29:06.183 回答
3

我发现您发布的“代码”有点令人困惑。我希望你知道这些线条

data(1:3) :: info_1
data(4:9) :: info_2
...
data(134:192) :: info_n

不是语法上有效的 Fortran(任何一代)。我认为我可以解释您试图告诉我们的内容,但宁愿不提供基于(错误)解释的建议。此外,您将诸如此类info_1, info_2的实体混入其中,而没有阐明它们的定义和声明。我不确定是否info_1info_location(1).

如果我了解您发布的内容,那么您有一个相当常见的(在旧的 Fortran 代码中)结构,其中一个固定大小的数据数组(在此处有用地称为data)用于存储项目集合。然后,您有一个索引数组(称为info_location),其中包含每个项目开头的数据索引。这个索引数组是 REAL 类型是非常奇特的,我希望它是 INTEGER 以便您可以编写如下语句:

data(info(3):info(4)-1))

这当然不会让我的眼球流血,也许我在 Fortran 中编程的时间太长了,但它看起来对我来说完全合理!您应该考虑的一种选择是以info_location某种方式转换为 INTEGER 并将其用作索引数组。或者,您可以在需要时进行这些转换,编写如下行:

data(int(info(3)):int(info(4))-1))

我个人会制作一个 INTEGER 索引数组,REAL 是数组索引的错误类型。

然后,你写

因此,例如,如果要获取 info_7 的数据,则必须执行以下操作:

size_of_info_7 = info_location(8) - info_location(7)
ALLOCATE(data_for_info_7(size_of_info_7))
data_for_info_7 = data(info_location(7) : info_location(7) + size_of_info_7 - 1)

由于您还没有确切地澄清什么,info_7或者data_for_info_7我对此感到有些困惑。如果您使用隐式类型,那么 size_of_info_7 将是 REAL 并且您的 ALLOCATE 语句将失败,需要一个 INTEGER 来表示分配对象的大小。

我想这data_for_info_7可能是一个可分配的 REAL 数组。如果info_location是 INTEGER 类型,您可以简单地编写:

ALLOCATE(data_for_info_7, source = data(info_location(7) : info_location(8) - 1))

Vladimir F 已经提供了关于使用指针清理代码的建议。另一种方法是使用 ASSOCIATE 构造。您可以在代码中的适当位置编写如下内容:

ASSOCIATE(data_for_info_7 => data(info_location(7) : info_location(8) - 1))

END ASSOCIATE将其与正确位置的语句相匹配。这有效地为 ASSOCIATE 构造中的数组部分定义了一个别名。

所以,总结一下:

  1. info_location数组类型错误。
  2. 撇开原始设计不谈,其中包含一个数据数组和另一个索引数组,是(当然是)完全合理的。
  3. 您有几个用于更新代码的选项,包括指针和关联。
于 2012-06-04T10:42:04.900 回答