创建包装器对象来解卷可怕的Fortran代码?

时间:2012-06-04 05:08:40

标签: oop object pointers fortran legacy-code

我必须使用一些传统的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之前,我对开始这项任务犹豫不决。

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:3)

我发现你发布的'代码'有点令人困惑。我希望你知道这些行

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

在语法上不是有效的Fortran(任何一代)。我认为我可以解释你想要告诉我们的内容,但宁愿不提供基于(错误)解释的建议。此外,您将诸如info_1, info_2之类的实体放入混合中,而不会明确其定义和声明。我不确定info_1是否与info_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索引数组,REALs是数组索引的错误类型。

然后,你写了

  

因此,例如,如果您想获取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_7data_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. 您可以通过多种方式更新代码,包括指针和关联。