2

有一个非常简单的函数来获取月份的名称,“Jan”、“Feb”等并转换为月份的数字:

function month_num(month_str)

  character*(*) :: month_str
  character*3 :: month_names(12)
  integer :: ipos(1),location(12)

  data month_names/'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug', &
                   'Sep','Oct','Nov','Dec'/

  where (month_names==month_str) location=1

  ipos = maxloc(location)
  month_num = ipos(1)

end function

好的,是的,我知道在使用它之前不定义“位置”是很危险的。

问题:在函数执行期间,如果输入正常,“位置”的某个值将设置为 1。令我惊讶的是,当再次调用该函数时,该值仍然等于 1。当然,这真的把事情搞砸了。所以我想我会用一条新线来修复它

data location/12*0/

我也遇到了同样的问题

最后,我输入

location = 0

就在“where”语句之前,这解决了所有问题。

所以,我认为 FORTRAN 子程序不会保存数据,除非变量是用“SAVE”属性声明的。此外,对于许多编译器,您可以调用某种“静态”选项来保存所有内容。我在这里都没有做这些,但是“位置”数组被保存了。有人可以告诉我 FORTRAN 何时保存数据以及何时不保存数据的规则吗?谢谢。

4

1 回答 1

3

过程局部变量的值通过SAVE以下两种方式之一保存(即,它是 d):

  1. 程序员SAVE在声明变量时指定属性,例如:

    REAL, SAVE :: var1

  2. 程序员在声明时初始化变量,例如

    REAL :: var1 = 3.1415

这第二种隐含行为是 Fortran 的一个特性,它似乎旨在吸引程序员,而不仅仅是初学者。请注意,在第二个示例中,变量在重新调用时的值不是,3.1415,而是在最后一次调用退出时它具有的任何值。

SAVE当程序员没有使用这些选项中的任何一个时,编译器的行为就好像一个变量是 d 是很常见的,也许在下一次调用之前不会覆盖一次调用过程使用的内存位置。但这种行为是不可靠的。

对于在模块中声明的变量,情况略有不同。再次SAVE保存具有该属性的任何变量,但任何其他变量仅在模块与已开始执行但未完成的程序单元使用关联时保留其值。同样,尽管模块超出范围,但某些编译器和某些程序的某些执行可能表现得好像模块变量的值被保留,但这是非标准行为,不应依赖。

SAVE当模块中定义的变量将隐式获取属性时,此行为计划在 Fortran 2008 中更改。

就个人而言,我喜欢显式SAVE变量,即使我确信它们会隐式地获取属性,它使代码在下一次更容易理解。

于 2013-08-12T20:51:08.370 回答