如何使用fortran子程序(或函数)填充矩阵并将矩阵传递回主程序?

时间:2013-10-09 20:29:56

标签: function matrix fortran subroutine

我正在进行Fortran 90任务,我在学习如何使用子程序和函数方面遇到很多问题,我希望有人可以帮助我。如果不是很明显,我对FORTRAN非常陌生,对C语言和Java等语言更加满意。

无论如何,这就是我要做的事情:用户选择他们想做的事情:添加,减去,乘法或转置两个矩阵。我正在使用一个精选案例,这很好用。但是,我显然不想复制相同的代码以在四个不同的时间填充两个矩阵,所以我试图使它成为一个单独的函数。理想情况下,我想做这样的事情:

integer matrix1(11,11), matrix2(11,11)
integer rows1,cols1,rows2,cols2,i,j
case (1)  
    matrix1 = fillmatrix(rows1,cols1)
    matrix2 = fillmatrix(rows2,cols2)
.
.
.


function fillmatrix(rows,columns)
  integer input
  read *,rows,columns
  do i = 1, rows
    do j = 1, columns
       fillmatrix(i,j) = read *,input
    end do
  end do
end

有没有办法做这样的事情?我是否清楚自己,因为有时我很难说出我的意思。

或者这可能吗?

matrix1 = fillmatrix(rows1)cols1)


function fillmatrix(rows,columns)
   integer input,matrix(11,11)
       //fill matrix
   return matrix
end

2 个答案:

答案 0 :(得分:2)

如果要使用function,则需要在调用之前知道矩阵的大小。这是一个小例子:

module readMatrix
  implicit none
contains
  function fillmatrix(cols,rows)
    implicit none
    ! Argument/return value
    integer,intent(in)  :: rows,cols
    integer             :: fillmatrix(rows,cols)
    ! Loop counters
    integer             :: i,j

    do j = 1, rows
      do i = 1, cols
        write(*,*) 'Enter matrix element ',i,j
        read *,fillmatrix(i,j)
      enddo ! j
    enddo ! i
  end function
end module

program test
  use readMatrix
  implicit none
  integer,allocatable :: matrix(:,:)
  integer             :: row,col, stat

  write(*,*) 'Enter number of rows'
  read *,row
  write(*,*) 'Enter number of cols'
  read *,col
  allocate( matrix(col,row), stat=stat )
  if (stat/=0) stop 'Cannot allocate memory'

  matrix = fillmatrix(col,row)

  write(*,*) matrix
  deallocate(matrix)
end program

这类似,使用subroutine和静态数组(如问题中所示):

module readMatrix
  implicit none
contains
  subroutine fillmatrix(cols,rows,matrix)
    implicit none
    ! Argument/return value
    integer,intent(out) :: rows,cols
    integer,intent(out) :: matrix(:,:)
    ! Loop counters
    integer             :: i,j

    write(*,*) 'Enter number of rows, up to a maximum of ',size(matrix,2)
    read *,rows
    write(*,*) 'Enter number of cols, up to a maximum of ',size(matrix,1)
    read *,cols

    if ( rows > size(matrix,2) .or. cols > size(matrix,1) ) &
      stop 'Invalid dimension specified'

    do j = 1, rows
      do i = 1, cols
        write(*,*) 'Enter matrix element ',i,j
        read *,matrix(i,j)
      enddo ! j
    enddo ! i
  end subroutine
end module

program test
  use readMatrix
  implicit none
  integer,parameter   :: maxCol=10,maxRow=10
  integer             :: matrix(maxCol,maxRow)
  integer             :: row,col

  call fillmatrix(col,row,matrix)

  write(*,*) matrix(1:col,1:row)

end program

你甚至可以将allocatable数组传递给子程序并在那里分配,但这是一个不同的故事......

答案 1 :(得分:2)

在C或Java中,您只有函数,但Fortran同时具有函数和子例程。在这种情况下,将其编写为subroutine而不是function可能更容易,因此您的调用看起来像

integer matrix1(11,11), matrix2(11,11)
integer rows1,cols1,rows2,cols2,i,j
...
case (1)  
    call fillmatrix(matrix1)
    call fillmatrix(matrix2)
...

子程序看起来像

subroutine fillmatrix(m)
    implicit none
    integer, intent(out) :: m(:,:)

    integer :: i, j
    do j = 1,size(m,2)
        do i = 1,size(m,1)
            read *, m(i,j)
        end do
    end do
end subroutine fillmatrix

请注意,我没有直接指定数组边界 - 而是我在子程序中计算它们。这意味着此子例程需要一个显式接口 - 最简单的方法是将其放在contains块或module中。