通过引用传递给交换函数传递参数

时间:2011-11-03 11:49:40

标签: fortran runtime-error pass-by-reference swap

我在解决练习测试时遇到了这个问题

考虑以下用代码传递语言编写的代码 FORTRAN和关于代码的这些陈述

  subroutine swap(ix,iy)
    it = ix
    ix = iy    ! line L1
    iy = it    ! line L2
  end

  program main
    ia = 3
    ib = 8
    call swap (ia, ib+5)
    print *, ia, ib
  end program

说明:

  1. 编译器将生成用于分配临时无名单元的代码, 将其初始化为13,并传递单元格交换的地址
  2. 执行时,代码将在第L1行生成运行时错误
  3. 执行时,代码将在第L2行生成运行时错误
  4. 该程序将打印13和8
  5. 程序将打印13和-2
  6. 上述陈述中的哪一项是正确的。

    我认为S1和S4。有人可以确认吗? TIA

2 个答案:

答案 0 :(得分:3)

是的,S1和S4是正确的。

此外,

S0a:文件不可编译,因为L1:和L2:是语法错误。 :)

S0b:严格地说,将FORTRAN称为传递参考语言不正确:

答案 1 :(得分:2)

扩展@janneb的答案......以下是该程序的Fortran 95语法正确版本:

module my_subs

contains

subroutine swap(ix,iy)

integer :: ix, iy
integer :: it

it = ix
ix = iy
iy = it

end subroutine swap

end module my_subs

program test_swap

use my_subs

integer :: ia, ib

ia = 3
ib = 8

call swap (ia, ib+5)

print *, ia, ib

end program test_swap

由于这是非法的,因此无法保证输出。使用gfortran和lax编译器选项,我得到“S4”,即输出13和8。

现在将子例程中的参数声明更改为:

integer, intent (inout) :: ix, iy

并且gfortran拒绝编译它:

错误:变量定义上下文中的非变量表达式(INTENT = OUT / INOUT的实际参数)(1)

同样适用于英特尔ifort:

test_swap.f90(31):错误#6638:实际参数是表达式或常量;这是无效的,因为关联的伪参数具有显式的INTENT(OUT)或INTENT(INOUT)属性。 呼叫交换(ia,ib + 5) ----------------- ^ test_swap.f90(代码1)

的编译中止

因此,使用正确编写的代码,现代Fortran编译器不允许这样做。如果你是草率的话,你可以犯这个错误,而且在FORTRAN 77和更早的版本中它更容易。