Отладка циклов DO / IF в программе на Фортране 90 (начальный уровень)

Я был бы благодарен, если бы кто-то мог помочь мне здесь. Я только начинаю учиться программировать, поэтому есть большая вероятность, что я упускаю что-то очень очевидное. Я пытаюсь написать программу на Фортране 90, которая решает вопрос 4 i) на странице 45 этого PDF-файла. Мне наконец-то удалось заставить мой код что-то скомпилировать, но теперь, когда что-то является чепухой, данные, которые он генерирует, сумасшедшие (с увеличением времени я получаю уменьшение расстояния после того, что я ввел в момент времени t0). Может кто-то заметить мою ошибку? Я понимаю, что это довольно много кода для просмотра, я прошу прощения за то, что так много вас спрашиваю. Заранее спасибо за просмотр!


   PROGRAM PARACHUTIST
   ! Tabulation of parachutist's descent z and and speed zdot
   ! as functions of time t

     !Assign the program's associated constants

    IMPLICIT NONE
      REAL z, zdot, g, U1, U2, z0, u0, t0, q0, t, x,c,s
    INTEGER I


g=9.8
U1=54
U2=5

!Break z0 down a little with q0

q0=COSH(g*t0/U1)
z0=U1**2/g*LOG(q0)
u0=U1*TANH(g*t0/U1)

      !Prompt for and read in the free-fall time

      Print*, 'Input free-fall time in seconds:'
      Read*, t0

      !Print the table headings
      WRITE(*,1000)

1000 FORMAT (6X, 'TIME', 6X, 'DISTANCE', 6X, 'VELOCITY',            /6X, '(SEC)', 7X, '(M)', 10X, '(M/SEC)',&
        /6X, '0.0', 10X, '0.0', 10X, '0.0' )

      !Loop covering the specified times
      t=0 

    DO I=0,20

  ! Calculate the distance above ground
200         IF(t<=t0) THEN
            x=g*t/U1
            z=U1**2/g*LOG(COSH(x))
            zdot=U1*TANH(x)

    Elseif(t>t0) THEN
            x=g*(t-t0)/U2  
    !store re-used expressions

            c=cosh(x)
            s=sinh(x)
            z= z0 + (U2**2/g)*LOG(c+ (u0/U2)*s)
            zdot=U2*(U2*s+u0*c)/(U2*c+u0*s) 

        Endif

         !Print a line of table using T formats
         WRITE(*,100) t, z, zdot
100      Format(4X, F5.2, 6X, F7.2, 6X, F7.2)

!Stop with message if landed

         If(z.GE.500) THEN
        PRINT*, 'LANDED'
        STOP
         !If we haven't yet landed then increment t as in 
        !   problem specs
         Elseif(t<15) then
            t=t+1
         Elseif(t.GE.15) then
            t=t+10

        ENDIF

     !End of the t-loop
      END DO

  END PROGRAM PARACHUTIST

1 ответ

Решение

Я написал это как два комментария, но это было действительно слишком долго. Иди и удали все это, если ты планировал это сделать. Я только что просмотрел документ, сравнивающий Fortran77 и "современный" Fortran90. (Я кодировал в Fortran77, когда я только начинал школу, некоторое время назад...). Вот некоторые предложения:

Будьте осторожны при использовании "ELSEIF". ELSE и IF обычно не используют пробел, но это не так в противном случае с кодом в свободном формате (я думаю, что единственными другими экземплярами space-option являются DOUBLE PRECISION, ELSE IF, GO TO, END DO и КОНЕЦ ЕСЛИ).

Преимущество использования Fortran90 состоит в том, что вам даже не нужны ELSE IF (или вычисленные GOTO!), Поскольку есть SELECT CASE.

Вам также не нужен FORMAT, так как он может быть напрямую включен в строку формата непосредственно в операторе READ или WRITE.

Да, вы можете использовать либо старые операторы Fortran 77 .GE..GT..EQ..NE..LE..LT. или новые >= > == /= <= <, Однако я не уверен, стоит ли вам смешивать их, что я заметил в вашем коде.

РЕДАКТИРОВАТЬ: Вторая ссылка выше, о структурах управления, описывает, как вы можете использовать циклы DO вместо IF в Fortran90, разделы 3.2 - 3.5. Вы можете использовать именованные DO, неопределенные циклы DO, DO WHILE, все виды вещей! Есть примеры тоже. (Название всего документа - Fortran90 для программистов на Fortran77.)

Другие вопросы по тегам