1

私は Fortran 90 の課題に取り組んでおり、サブルーチンと関数の使用方法を学ぶのに多くの問題を抱えています。誰かが私を助けてくれることを願っています。明らかでない場合は、私は FORTRAN に非常に慣れていないため、C や Java などの言語に慣れています。

とにかく、ここで私がしなければならないことは次のとおりです。ユーザーは、実行したいことを選択します: 2 つの行列の加算、減算、乗算、または転置。これには選択ケースを使用していますが、これはうまく機能します。ただし、同じコードを複製して 2 つの行列を 4 回塗りつぶしたくないので、別の関数にしようとしています。理想的には、次のようなことをしたいと思います。

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
4

2 に答える 2

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.

于 2013-10-09T21:21:35.377 に答える
2

a を使用する場合は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

これは、 asubroutineと静的配列を使用して似ています(質問のように):

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てそこに割り当てることもできますが、それは別の話です...

于 2013-10-09T21:13:19.423 に答える