【问题标题】:Passing arguments by pass-by-reference to a swap function通过传递引用传递参数到交换函数
【发布时间】:2011-11-03 11:49:39
【问题描述】:

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

考虑以下使用传递引用语言编写的代码,例如 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

以上陈述中哪些是正确的。

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

【问题讨论】:

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


    【解决方案1】:

    是的,S1 和 S4 是正确的。

    还有,

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

    S0b:严格来说,将 FORTRAN 称为传递引用语言是不正确的:

    【讨论】:

    【解决方案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 及更早版本中更容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      • 2010-10-07
      • 2011-08-21
      • 2019-02-12
      • 2014-05-05
      • 2016-10-26
      • 2017-09-25
      相关资源
      最近更新 更多