3

我不知道这个自由格式的 Fortran 程序有什么问题。它没有正确处理其命令行参数。

如果我对命令行参数使用静态数组而不是数组,它会起作用allocatable

另外,这是一个很好的第一个 Fortran 程序吗?这是 Fortran 有用的问题类型吗?我已经知道 C、C++ 和一点点 D。

module fibonacci
  use ISO_FORTRAN_ENV
  implicit none
contains
  subroutine output_fibonacci(ordinal)
    ! Declare variables
    integer, parameter :: LongInt = selected_int_kind (38)
    integer, intent(in) :: ordinal
    integer :: count
    ! integer (kind=LongInt) :: count, compare=2
    integer (kind=LongInt), dimension(2,2) :: matrix, initial
    matrix=reshape((/ 1, 1, 1, 0 /), shape(matrix))
    initial=reshape((/ 1, 0, 0, 1 /), shape(initial))
    count = ordinal
     ! Do actual computations
    do while (count > 0)
       ! If the exponent is odd, then the output matrix
       ! should be multiplied by the current base
       if (mod(count,2) == 1) then
          initial = matmul(matrix, initial)
       end if
       ! This is the squaring step
       matrix = matmul(matrix, matrix)
       count = count/2
    end do
    write (*,*) initial(1,2)
  end subroutine output_fibonacci
end module fibonacci
program main
  use, intrinsic :: ISO_FORTRAN_ENV
  use fibonacci
  implicit none
  ! The maximum allowed input to the program
  integer :: max=200, i, size=20
  character, allocatable :: argumen(:)
  integer :: error, length, input
  allocate(argumen(size))

  ! write(*,*) argcount
  do i=1, command_argument_count()
     call get_command_argument(i, argumen, length, error)
     read(argumen,*,iostat=error) input
     !    write(*,*) argument
     !    write (*,*) input
     if (error .ne. 0) then
        write(ERROR_UNIT,'(I36.1,A)') input, "is not an integer"
        stop (1)
     else if (input > max) then
        write(ERROR_UNIT,'(A,I36.1,A)') "Input ", input, " is too large"
        stop (1)
     end if
     call output_fibonacci(input)
  end do
end program
4

1 回答 1

8

这条线

character, allocatable :: argumen(:)

声明一个可分配的字符数组。所以声明

allocate(argumen(size))

创建argumen一个包含 20 个单字符元素的数组。这不是在 Fortran 中处理字符串的常用方法,并且argumen不匹配(在类型或等级上)调用get_command_argument.

相反,你应该写

character(len=:), allocatable :: argumen

声明argumen为可分配长度的字符变量。在某些情况下,您可以简单地分配给这样的变量,例如

argumen = 'this is the argument'

无需事先明确分配它。

使用 Intel Fortran v14 时,调用get_command_argument编译时不会发出警告,但在执行时,参数argumen不会自动分配,它保持未分配状态。老实说,我不确定这种行为是否符合标准。一种方法是对 进行两次调用get_command_argument,首先获取参数的大小,然后获取参数;像这样

 do i=1, command_argument_count()
     call get_command_argument(i, length=length, status=error)
     allocate(character(length)::argumen)
     call get_command_argument(i, argumen, status=error)
    ! do stuff with argument
    deallocate(argumen)
  end do

使用length变量的名称来分配由调用的可选参数返回的值length是合法的,但有点令人困惑。该deallocate语句确保argumen可以为下一个参数再次分配。

我将留给您声明和使用可分配长度字符的可分配数组的练习。

免责声明:接下来的两段包含一些可能会觉得主观的材料。我不会就这个答案的这些部分进行任何讨论。

这是一个很好的第一个 Fortran 程序吗? 这比我在 SO 上看到的很多内容要好。就我个人而言,我更喜欢始终如一地使用现代/=to .ne.<to .lt( etcstop ),如果我可以避免它,我不会使用它(我通常可以),我相信我可以找到其他的 nits 来选择。

这是 Fortran 有用的问题类型吗? Fortran 对所有类型的问题都很有用,尽管我承认使用它来编写 Web 服务器可能非常具有挑战性。

于 2013-11-21T05:56:00.733 回答