0

我正在编写一个子程序来反转矩阵。输入是矩阵 A(n x n),输出是矩阵 invA。在子例程中,我想声明一个临时矩阵“temp”维度(n 乘 2n),但声明引起了奇怪的问题。在这一行之后(我在下面强调),我还声明了整数 i 和 j 并初始化它们 i = 0,j = 0。但是调试 i 和 j 的这些值,它显示 i = 1572472 !诡异的!!!!!如果我删除代码行“real, dimension (m, m * 2) :: temp”,那么一切都很好。任何人都可以为我解释为什么?

提前致谢。(我是 .Net 中的一名优秀程序员,现在正在学习 Fortran——但这让我发疯!)

program weird

implicit none

Real, Dimension (2,2)::B
Real, Dimension (2,2) ::B_inversed


B(1,1) = 0.6
B(1,2) = 0.8  
B(2,1) = -0.8
B(2,2) = 0.6

Call InverseMatrix(B,B_inversed)

contains

subroutine InverseMatrix(A, invA)
implicit none
real, intent(in), dimension (:,:) :: A  
real, intent(out), dimension (size(a,1),size(a,2)) :: invA 

real, dimension (size(a,1),2*size(a,2)) :: temp  <------THIS LINE CAUSES PROBLEMS


integer:: i,j
i = 0 !<------- 
j = 0 !<-------DEBUG line stops here, showing i = 3734648 !VERY WEIRD!!!!!

invA(1,1) =0.0
invA(1,2) =0.0
invA(2,1) =0.0
invA(2,2) =0.0

end subroutine

end program

这是一个非常直接的 FORTRAN 代码,但为什么我没有得到正确的 'i' 值?

4

2 回答 2

3

由于 Fortran 数组携带有关其自身大小的信息,因此更好的方法是让您开始您的子例程更像这样:

subroutine inversematrix(a, inva)
    ! ALWAYS include the next line within any scoping unit
    implicit none
    real, intent(in), dimension (:,:) :: a  ! no need to tell the compilers what the dims are
    real, intent(out), dimension (size(a,1),size(a,2)) :: inva 

    real, dimension (size(a,1),2*size(a,2)) :: temp  

要回答您的问题,我无法立即了解您的代码为什么不起作用以及为什么变量i不保留您分配给它的值。不知是否与子程序的接口相连。在现代 Fortran 中,当技术上可行时,确保编译器生成必要的例程接口总是一个好主意。实现这一点的一种方法是将所有例程放入模块中并使用关联它们,另一种方法是使用基本结构编写代码

program
! declarations
! executable statements
contains

subroutine ...
end subroutine

end program

而不是

subroutine ...
end subroutine

program
! declarations
! executable statements
end program

但我真的只是猜测。

使用implicit none并确保编译器生成例程接口;这些可能无法治愈您眼前的问题,但它们是很好的一般指导方针,将来会为您节省很多痛苦。

于 2013-02-15T11:41:06.623 回答
0

英特尔编译器在优化过程中会做一些可能会影响调试器输出的事情:

  1. 它重新排列语句的顺序,因此分配 j = 0 的行可能会在分配 i = 0 的行之前运行。

  2. 它“优化”变量,不仅通过删除未使用的变量,而且通过将变量与未同时使用的其他变量组合起来。

这两者似乎都不可预测(至少对我而言)。因此,如果您已修复程序以使其具有正确的行为,并且打印该值会产生正确的答案,那么调试器可能仍会显示错误的值。您可以尝试关闭/关闭优化,看看会发生什么。

于 2013-08-18T21:48:48.980 回答