3

我正在尝试我在 Fortran 中的第一个程序,试图求解一个二次方程。我对我的代码进行了两次和三次检查,没有发现任何问题。我不断在不同位置收到“(1) 处的名称中的无效字符”和“(1) 处的不可分类声明”。代码有什么问题?

! This program solves quadratic equations
! of the form ax^2 + bx + c = 0.
! Record:
! Name:             Date:     Notes:
! Damon Robles      4/3/10    Original Code

PROGRAM quad_solv
IMPLICIT NONE

! Variables
REAL :: a, b, c
REAL :: discrim, root1, root2,    
COMPLEX :: comp1, comp2
CHARACTER(len=1) :: correct 

! Prompt user for coefficients.
WRITE(*,*) "This program solves quadratic equations "
WRITE(*,*) "of the form ax^2 + bx + c = 0. "
WRITE(*,*) "Please enter the coefficients a, b, and "
WRITE(*,*) "c, separated by commas:"
READ(*,*) a, b, c
WRITE(*,*) "Is this correct: a = ", a, " b = ", b
WRITE(*,*) " c = ", c, " [Y/N]? "
READ(*,*) correct
IF correct = N STOP
IF correct = Y THEN

! Definition
discrim = b**2 - 4*a*c

! Calculations
IF discrim > 0 THEN
root1 = (-b + sqrt(discrim))/(2*a)
root2 = (-b - sqrt(discrim))/(2*a)
WRITE(*,*) "This equation has two real roots. "
WRITE(*,*) "x1 = ", root1
WRITE(*,*) "x2 = ", root2
IF discrim = 0 THEN
root1 = -b/(2*a)
WRITE(*,*) "This equation has a double root. "
WRITE(*,*) "x1 = ", root1
IF discrim < 0 THEN
comp1 = (-b + sqrt(discrim))/(2*a)
comp2 = (-b - sqrt(discrim))/(2*a)
WRITE(*,*) "x1 = ", comp1
WRITE(*,*) "x2 = ", comp2

PROGRAM END quad_solv
4

4 回答 4

2

关于如何循环回重做输入的附加问题——一个演示 Fortran >= 90 循环特性的示例程序。循环显然是无限的——由 IF 语句控制的退出退出循环并使循环有限。还显示了循环控制,如果遇到无效输入则使用它,否则会导致程序崩溃。(例如,键入“A”作为第一次读取的输入,而不是数字。)在这种情况下,iostat 变量获取非零值,IF 语句激活循环,​​DO 循环的其余部分是跳过,以便循环重新循环。

program test_readdata

real :: a, b, c
integer :: ReturnCode
character (len=1) :: correct

ReadData: do

   write (*, '( "This program solves quadratic equations of the form ax^2 + bx + c = 0. " )' ) 
   write (*, '( "Please enter the coefficients a, b, and c, separated by commas: " )', advance='no' )
   read (*,*, iostat=ReturnCode) a, b, c
   if ( ReturnCode /= 0 ) cycle ReadData
   write (*,*) "Is this correct: a = ", a, " b = ", b, " c = ", c
   write (*, '( "Enter Y or N: " )', advance='no' )
   read (*,*, iostat=ReturnCode) correct
   if ( ReturnCode /= 0 ) cycle ReadData
   if ( correct == 'Y'  .or.  correct == 'y' )  exit ReadData

end do ReadData

stop

end program test_readdata

我的书推荐:由 Metcalf、Reid 和 Cohen解释的 Fortran 95/2003 。

于 2010-04-08T00:02:34.567 回答
1

我注意到您的代码的第一件事是程序末尾的语法错误。

END

应该在词程序之前

您的编辑器没有突出显示您的语法错误吗?

你可以很便宜地获得 ELF 90 的学生版,这是一个很好的起点。然后,我将使用 Visual Studio 和算法流程图生成器升级到 Lahey ELF 95,该生成器对值的传递路径进行颜色编码。

于 2010-04-14T22:49:06.103 回答
0

这么多错误...看来您不了解 Fortran 基础知识...

用最少的修正

! This program solves quadratic equations
! of the form ax^2 + bx + c = 0.
! Record:
! Name:             Date:     Notes:
! Damon Robles      4/3/10    Original Code

PROGRAM quad_solv

  IMPLICIT NONE

  ! Variables
  REAL :: a, b, c
  REAL :: discrim, root1, root2    
  COMPLEX :: comp1, comp2
  CHARACTER(len=1) :: correct 

  ! Prompt user for coefficients.
  WRITE(*,*) "This program solves quadratic equations "
  WRITE(*,*) "of the form ax^2 + bx + c = 0. "
  WRITE(*,*) "Please enter the coefficients a, b, and "
  WRITE(*,*) "c, separated by commas:"
  READ(*,*) a, b, c
  WRITE(*,*) "Is this correct: a = ", a, " b = ", b
  WRITE(*,*) " c = ", c, " [Y/N]? "
  READ(*,*) correct

  IF (correct == 'N') STOP

  IF (correct == 'Y') THEN

    ! Definition
    discrim = b**2 - 4*a*c

    ! Calculations
    IF (discrim > 0) THEN
      root1 = (-b + sqrt(discrim))/(2*a)
      root2 = (-b - sqrt(discrim))/(2*a)
      WRITE(*,*) "This equation has two real roots. "
      WRITE(*,*) "x1 = ", root1
      WRITE(*,*) "x2 = ", root2
    ELSEIF (discrim == 0) THEN
      root1 = -b/(2*a)
      WRITE(*,*) "This equation has a double root. "
      WRITE(*,*) "x1 = ", root1
    ELSE
      comp1 = (-b + sqrt(discrim))/(2*a)
      comp2 = (-b - sqrt(discrim))/(2*a)
      WRITE(*,*) "x1 = ", comp1
      WRITE(*,*) "x2 = ", comp2
    END IF

  END IF  

END PROGRAM quad_solv

PS我没有检查正确性。PPS 始终缩进您的代码以使其可读,并且不要使用 STOP 语句。每个程序(或子程序)应该有一个入口和一个出口。STOP 的唯一正确位置恰好在 END PROGRAM 语句之前,它是冗余的。所以根本不要使用 STOP 。

于 2010-04-06T20:59:32.207 回答
0

一些变化:正确的 IF 语法;常量是实数而不是整数,在适当的时候:

IF (CORRECT == "N" ) stop
if ( discrim > 0.0 ) then

在其他位置申请,您应该非常接近。祝你好运。

测试浮点数是否具有精确值可能是一种糟糕的算法。如果舍入误差使 disrim 的值为 1.0E-30,而完美的算术将给出值为零并表示双根,该怎么办?

于 2010-04-06T20:59:36.157 回答