【问题标题】:FORTRAN: Use character as changeable array nameFORTRAN:使用字符作为可变数组名称
【发布时间】:2015-02-16 10:33:09
【问题描述】:

我正在尝试编写一个子程序以某种方式访问​​数组。 子例程的一个输入参数是一个字符,其中包含需要访问的数组的名称。这是一个相当简化的代码示例,说明我通常认为它是如何工作的:

PROGAM prog
real, dimension(3,3) :: array1(3,3)
real, dimension(3,3) :: array2(3,3)
real value1
real value2
... fill 'array1' and 'array2'...
call sub(array1,2,2,value1)
call sub(array2,2,2,value2)
... do something with 'value1' and 'value2'...
END

SUBROUTINE sub(name,x,y,out)
character(len=*), intent(in) :: name
integer, intent(in) :: x
integer, intent(in) :: y
real, intent(out) :: out
out = name(x,y)
RETURN
END

我想要的是按照参数中的要求访问array1(2,2) 并将这个值返回给value1 的子例程。然后访问array2(2,2)并将这个值返回给value2。上面的代码 sn-p 不起作用 - 难怪。如何将name(x,y) 分别替换为array1(x,y) array2(x,y)

非常感谢和最好的问候!

【问题讨论】:

    标签: arrays fortran character


    【解决方案1】:

    如果数组是在调用者中声明的,则不必使用数组的名称来获取其内容。然后使用普通的参数关联。

    你可以把你的子程序写成

    subroutine sub(a,x,y,out)
      integer, intent(in) :: x, y
      real, intent(out) :: out
      real, dimension(:,:), intent(in) :: a
      out = a(x,y)
    end subroutine sub
    

    在主程序中会更简单

    value1 = array1(2,2)
    value2 = array2(2,2)
    

    我会推荐一本关于 Fortran 的教科书,甚至可以看看 http://en.wikipedia.org/wiki/Fortran_95_language_features

    编辑:

    您也可以使用 SELECT CASE 语句,如下所示:

      subroutine bar(c, i, j, out)
        character(len=*), intent(in) :: c
        integer, intent(in) :: i,j
        real, intent(out) :: out
    
        select case (trim(c))
          case ("array1")
             out = array1(i,j)
          case ("array2")
             out = array2(i,j)
          case default
             stop "Argument is bletchful"
          end case
      end subroutine bar
    

    与直接使用数组相比,我完全不知道这样做有什么好处。

    【讨论】:

    • 感谢您的回答。但子例程的重点是能够通过参数中给出的名称访问任何数组。调用者中的声明是不可能的,主程序中的标准访问也是不可能的。代码 sn-p 非常简化,应该只说明一般问题。
    • 那么,有问题的数组在哪里声明?
    • 它在模块中声明为可分配的,而不是在其他子程序中分配。我只需要一种方法来转换字符串,以便我可以使用它来寻址与字符串内容同名的数组。
    • 你能编辑你的例子,让它显示你真正想做的事情,包括模块结构吗?
    • 声明数组的方式和位置并没有真正的区别。它仅与子例程有关,它应该获取一个字符作为输入并使用该字符来访问与字符内容具有相同名称的(已经声明和填充的)数组。根据输入的字符,可以访问不同的数组。如果代码 sn-p 没有说明这一点,我很抱歉。
    【解决方案2】:

    这是你想要的吗?

    select case (array_name)
       case ("array_dog")
          array_ptr => array_dog
       case ("array_cat")
          array_ptr => array_cat
    end select 
    

    其中array_name 是字符变量,array_dogarray_cat 是模块中声明的数组(需要target 属性),array_ptr 是另一个具有pointer 属性的数组。

    【讨论】:

    • 感谢您的回答。我不认为这是我正在寻找的。想象一下有几个数组。在运行时,我通过输入字符变量来决定要访问的数组。此字符变量用于访问与字符变量的内容同名的数组。我不想使用预编码的案例说明或类似的东西。如何告诉 Fortran 使用字符串的内容作为数组的名称?
    • 我认为 Fortran 不可能将字符串的内容转换为变量的名称。
    • tkoenig 在另一个答案中写道。我想那时会使用 case 指令并改变程序的概念,因为没有其他选择。非常感谢您的回答和您的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2023-03-27
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多