]]> ]]>
Править | Обсудить | История

FORTRAN

Русское название:
Фортран
Дата создания:
1957
Повлиял на:
Парадигма:
Типизация:
Принятые расширения файлов:
.f, .f77, .f90, .f95, .f03
Диалекты:
Реализации и версии (свернуть все | развернуть все):
Язык программирования

Фортран (Fortran) — первый реализованный язык программирования высокого уровня (после Планкалкюля), правда, с одной небольшой оговоркой — для машин, построенных по классической схеме фон Неймана. Создан в период с 1954 по 1957 год группой программистов под руководством Джона Бэкуса (John Backus) в корпорации IBM. Через пару лет начались его коммерческие поставки. До этого программирование велось либо непосредственно в машинных кодах, либо на символических ассемблерах. Название Fortran является аббревиатурой от FORmula TRANslator, то есть, переводчик формул.

Фортран широко используется в первую очередь для научных и инженерных вычислений. Одно из преимуществ современного Фортрана — большое количество написанных на нём программ и библиотек подпрограмм. Среди учёных, например, ходит такая присказка, что любая математическая задача уже имеет решение на Фортране, и, действительно, можно найти среди тысяч фортрановских пакетов и пакет для перемножения матриц, и пакет для решения сложных интегральных уравнений и многие, многие другие. Ряд таких пакетов создавались на протяжении десятилетий и популярны по сей день (главным образом в научной среде).

Большинство таких библиотек является фактически достоянием человечества: они доступны в исходных кодах, хорошо документированы, отлажены и весьма эффективны. Поэтому изменять, а тем более переписывать их на других языках программирования накладно, несмотря на то, что регулярно производятся попытки автоматического конвертирования FORTRAN-кода на современные языки программирования.

Современный Фортран (Fortran 95 и Fortran 2003) приобрёл черты, необходимые для эффективного программирования для новых вычислительных архитектур; позволяет применять современные технологии программирования, в частности, ООП.

История

В конце 1953 Джон Бэкус предложил начать разработку эффективной альтернативы ассемблеру для программирования на ПК IBM 704. Уже к середине 1954 была закончена черновая спецификация языка Fortran. Первое руководство для Fortran появилось в октябре 1956 вместе с первым компилятором, поставленным в апреле 1957. Компилятор был оптимизирующим, потому что клиенты отказывались использовать язык программирования высокого уровня, который был не в состоянии генерировать код с производительностью ниже, чем у ассемблера.

В то время сообщество относилось скептически к новому способу программирования и не верили в то, что Fortran позволит программировать быстрее и эффективнее. По словам самого Джона Бэкуса большая часть его работы была направлена на то чтобы «быть ленивым». Ему жутко не нравилось писать программы под IBM 701 на ассемблере.

Язык был широко принят учеными для написания программ с интенсивными вычислениями. Включение комплексного типа данных сделало его особенно подходящим для технических приложений.

К 1960 году существовали версии Fortran для компьютеров IBM 709, 650, 1620, 7090. Его большая популярность побуждала конкурирующих изготовителей компьютеров создавать компиляторы Fortran для своих компьютеров. Таким образом, уже к 1963 существовало более 40 компиляторов для разных платформ. Именно по этому Fortran считают первым широко используемым языком программирования.

Поскольку FORTRAN оказался столь успешным языком, в Европе возникли опасения, что IBM будет доминировать в компьютерной отрасли. Немецкое общество прикладной математики (German society of applied mathematics — GAMM) создало комитет по разработке универсального языка. В то же время Association for Computing Machinery (ACM) организовала похожий комитет в США. Несмотря на то, что у европейцев было некоторое беспокойство по поводу господства американцев, оба этих комитета слились в один. Под руководством Питера Наура (Peter Naur) этот комитет разработал IAL (International Algorithmic Language). Предлагавшееся название ALGOL (ALGOrithmic Language) было вначале отвергнуто. Но поскольку оно стало общеупотребительным, официальное имя IAL пришлось впоследствии изменить на ALGOL 58. Новая версия появилась в 1960 г., и ALGOL 60 (с небольшими изменениями, сделанными в 1962 г.) с 60-х и до начала 70-х гг. прошлого века был стандартом академического языка программирования.

Фортран в СССР

Фортран в СССР появился позже, чем на Западе, поскольку поначалу у нас более перспективным языком считался Алгол. Во внедрении Фортрана большую роль сыграло общение советских физиков со своими коллегами из CERN, где в 1960-х годах почти все расчёты велись с использованием программ на Фортране.

Первый советский компилятор с Фортрана был создан в 1967 г. для машины «Минск-2», однако он не получил большой известности. Широкое внедрение Фортрана началось после создания в 1968 г. компилятора ФОРТРАН-ДУБНА для машины БЭСМ-6. Машины ЕС ЭВМ, появившиеся в 1972 г., уже изначально имели транслятор Фортрана («позаимствованный» с IBM/360 вместе с другим программным обеспечением).

Стандарты

Фортран — жёстко стандартизированный язык, именно поэтому он легко переносится на различные платформы. Существует несколько международных стандартов языка:

  • FORTRAN IV (позже положенный в основу FORTRAN 66 (1966);
  • FORTRAN 77 (1978)
    • множество улучшений: строковый тип данных и функции для его обработки, блочные операторы IF, ELSE IF, ELSE, END IF, оператор включения фрагмента программы INCLUDE и т. д.
  • Fortran 90 (1991)
    • значительно переработан стандарт языка. Введён свободный формат написания кода. Появились дополнительные описания IMPLICIT NONE, TYPE, ALLOCATABLE, POINTER, TARGET, NAMELIST; управляющие конструкции DO … END DO, DO WHILE, CYCLE, SELECT CASE, WHERE; работа с динамической памятью (ALLOCATE, DEALLOCATE, NULLIFY); программные компоненты MODULE, PRIVATE, PUBLIC, CONTAINS, INTERFACE, USE, INTENT. Появились новые встроенные функции, в первую очередь, для работы с массивами
    • в языке появились элементы ООП
  • Fortran 95 (1997) — коррекция предыдущего стандарта
  • Fortran 2003 (2004)
    • дальнейшее развитие поддержки ООП в языке. Взаимодействие с операционной системой

Компиляторы

До 1997 основным производителем компиляторов Fortran для IBM PC совместимых компьютеров была корпорация Microsoft. Впоследствии она отказалась от их разработки в связи с низкой прибыльностью. На данный момент компиляторы поставляет фирма DEC, вошедшая в 1998 г. в состав Compaq и вместе с последней в 2002 г. слившаяся с HP.

Компания DEC поставляет компилятор, интегрированный в среду разработки Digital Visual Fortran, основанную на Microsoft Visual Studio. Наиболее известными продуктами этой линейки являются FPS 4.0 (Microsoft Fortran Power Station), DVF 5.0 и 6.0. Каждый компилятор может поддерживать несколько стандартов Фортрана. Слияния компаний явились причиной того, что последующие продукты появлялась на рынке под торговыми марками Compaq и HP. В настоящее время HP продаёт среду разработки версии 6.6 для Intel/win32. Поддержка Fortran реализована также для всех высокопроизводительных платформ HP.

Другим крупным поставщиком систем разработки на Fortran является фирма Lahey, предлагающая интегрированные решения для Windows и Linux.

Долгое время лучшим компилятором Fortran считался компилятор фирмы Watcom, который был выделен в отдельный проект Open Watcom, развивающий компилятор на открытой основе.

Известен и развивается также компилятор фирмы Intel — Intel Fortran Compiler, который позволяет оптимизировать код под платформу Intel ia32 и ia64.

Среди бесплатных компиляторов Fortran следует выделить компилятор от Sun Microsystems, входящий в состав Sun Studio, который генерирует эффективный код под SPARC, x86 и x86_64 и доступен как для ОС Solaris, так и GNU/Linux.

Фонд свободного программного обеспечения GNU выпускает открытый компилятор FORTRAN 77 g77, доступный практически для любой платформы и полностью совместимый с GCC, но не поддерживающий всех языковых конструкций современных стандартов Fortran. Также существует проект g95 по созданию на основе GCC компилятора Fortran 95.

Возможности и структура программы

Fortran имеет достаточно большой набор встроенных математических функций, поддерживает работу с целыми, вещественными и комплексными числами высокой точности. Выразительные средства языка изначально были весьма бедны, поскольку Fortran был одним из первых языков высокого уровня. В дальнейшем были добавлены многие лексические конструкции, характерные для структурного, функционального и даже объектно-ориентированного программирования.

Структура программ изначально была ориентирована на ввод с перфокарт и имела ряд удобных именно для этого случая свойств. Так, 1-я колонка служила для маркировки текста как комментария (символом C), с 1-й по 5-ю располагалась область меток, а с 7-й по 72-ю располагался собственно текст оператора или комментария. Колонки с 73-й по 80-ю могли служить для нумерации карт (чтобы восстановить случайно рассыпавшуюся колоду) или для краткого комментария, транслятором они игнорировались. Если текст оператора не вписывался в отведённое пространство (с 7-й по 72-ю колонку), в 6-ой колонке следующей карты ставился признак продолжения, и затем оператор продолжался на ней. Расположить два или более оператора в одной строке (карте) было нельзя. Когда перфокарты ушли в историю, эти достоинства превратились в серьёзные неудобства.

Именно поэтому в стандарте, начиная с Fortran 90, в добавление к фиксированному формату исходного текста появился свободный формат, который не регламентирует позиции строки, а также позволяет записывать более одного оператора на строку. Введение свободного формата позволило создавать код, читабельность и ясность которого не уступает коду, созданному при помощи других современных языков программирования, таких как C или Java.

Своего рода «визитной карточкой» старого Fortran является огромное количество меток, которые использовались как в операторах безусловного перехода GOTO, так и в операторах циклов, и в операторах описания форматного ввода/вывода FORMAT. Большое количества меток и операторов GOTO часто делало программы на Фортране трудными для понимания.

Именно этот негативный опыт стал причиной, по которой в ряде современных языков программирования (например, Java) метки и связанные с ними операторы безусловного перехода вообще отсутствуют.

Однако современный Fortran избавлен от избытка меток за счет введения таких операторов, как DO … END DO, DO WHILE, SELECT CASE. Также к положительным чертам современного Fortran стоит отнести большое количество встроенных операций с массивами и гибкую поддержку массивов с необычной индексацией.

Взаимодействие с другими языками

Многие системы программирования позволяют компоновать полученные в результате трансляции программы на Fortran объектные файлы с объектными файлами, полученными от компиляторов с других языков, что позволяет создавать более гибкие и многофункциональные приложения. Для языка Фортран также доступно большое количество библиотек, содержащих как подпрограммы решения классических вычислительных задач (LAPACK, IMSL, BLAS), задач организации распределенных вычислений (MPI, pvm), так и задач построения графических интерфейсов (Quickwin, FORTRAN/TK) или доступа к СУБД (Oracle).

Наследие Fortran

Fortran использовался более пятидесяти лет и существует огромная часть принадлежащая ему и по сей день. Fortran — основной язык для некоторых задач требующих огромных вычислений, таких как моделирование погоды и климата, гидрогазодинамика, вычислительная химия, квантовая хромодинамика, моделирование динамики солнечной системы, вычисление орбит искусственных спутников и многие другие задачи.

Переносимость

Поначалу переносимость для Fortran была весьма насущной проблемой, потому что не существовало ни одного единого стандарта и даже справочной информации от IBM. И компьютерные фирмы соперничали между собой, обеспечивая несовместимость для разных компиляторов. Исправило дело появление стандартов. Стандарт 1966 года устанавливал синтаксис и семантику, но продавцы продолжали внедрять несовместимые расширения. Осмотрительные программисты понимали, что использование несовместимых расширений вызовет проблемы переносимости и зачастую использовали программы наподобие «The PFORT Verifier» для выявления несовместимых расширений.

Несовместимые расширения были не единственной проблемой. Существовал ряд проблем с численными вычислениями. Позже была развита и внедрена практически универсальная идея двоичной арифметики с плавающей запятой.

Доступ к исполняемой среде (например, к командной строке, переменным среды) был весьма затруднителен, пока на это не обратили на это внимание в стандарте 2003 года.

Сейчас относительно просто реализовать полностью переносимую программу на Fortran.

Элементы синтаксиса:

Комментарий до конца строки ! или * в первом символе строки
Регистрозависимость Нет
Регулярное выражение идентификатора переменной [a-zA-Z][_a-zA-Z0-9]{0-n}
Присваивание значения переменной =
Объявление переменной type :: variable
Объявление переменной с присваиванием значения type :: variable = value
Группировка выражений ()
Блок do ... end do
Равенство = или .EQ.
Неравенство /= или .NE.
Сравнение == < > <= >= <> или .LT. .GT. .LE. .GE.
Вызов функции CALL f(a,b...)
Вызов функции без параметров CALL f
Последовательность конец строки
Если - то if condition then ... end if
Если - то - иначе if condition then ... else ... endif
Цикл с постусловием DO ... WHILE (condition)
Цикл for - next для диапазона целых чисел с инкрементом на 1 do label i = 1, 10
Цикл for - next для диапазона целых чисел с декрементом на 1 do label i = 10, 1, -1

IDE/Редакторы:

Примеры:

Hello, World!:

Пример для версий Intel Visual Fortran 11.1, g95 0.93, gfortran 4.5.0

Этот пример написан в свободном формате, поддерживаемом Fortran 90 и последующими стандартами, а также диалектом F.

! Fortran 90-style comment
program HelloWorld
  print *, "Hello, World!"
end program HelloWorld

Факториал:

Пример для версий Intel Visual Fortran 11.1, g95 0.93, gfortran 4.5.0

Используется итеративное определение факториала и свободный формат программы. Спецификации формата I и A используются для вывода чисел в десятичном формате и строк, соответственно. При вычислении факториалов 13-16 возникает арифметическое переполнение, не вызывающее ошибку, поэтому выводятся неправильные значения:

13! = 1932053504
14! = 1278945280
15! = 2004310016
16! = 2004189184

program Factorial

  integer :: f,n
  f = 1
  n = 0
  do
    print "(I2, A, I10)", n, "! = ", f
    n = n + 1
    f = f * n
    if (n == 17) then
      exit
    end if
  end do

end program Factorial

Числа Фибоначчи:

Пример для версий Intel Visual Fortran 11.1, g95 0.93, gfortran 4.5.0

Используется итеративное определение чисел Фибоначчи. Самое сложное в этом примере — вывод вычисленных значений в нужном формате, в одну строку и без лишних пробелов. Спецификация формата (I3, A, $) означает, что вначале выводится целое число в десятичном формате, шириной ровно три символа, затем выводится строка, и наконец, $ подавляет перевод строки, используемый командой print по умолчанию, так что все выводится в одну строку. Отметим, что в диалекте F спецификатор формата $ не является стандартным; программа работает, но при компиляции выводит предупреждение об этом.

program Fibonacci

  integer :: f1,f2,f3,i
  i = 1
  f1 = 0
  f2 = 1
  do
    f3 = f2 + f1
    f1 = f2
    f2 = f3
    i = i + 1
    if (f1 < 10) then
      print "(I1, A, $)", f1, ", "
    elseif (f1 < 100) then
      print "(I2, A, $)", f1, ", "
    else
      print "(I3, A, $)", f1, ", "
    end if
    if (i == 17) then
      exit
    end if
  end do
  print *, "..."

end program Fibonacci

Квадратное уравнение:

Пример для версий g95 0.93, gfortran 4.5.0

В примере используется встроенный тип данных complex. // — оператор конкатенации строк. Число перед скобками в описании формата означает количество раз, которые повторяется формат в скобках (в данном случае дважды — для первого и второго корней).

program Quadratic
  integer :: a, b, c
  real :: d, p1, p2
  complex :: cp2

  read (*, *), a
  if (a == 0) then
    write (*, *) "Not a quadratic equation"
    stop
  end if
  read (*, *) b
  read (*, *) c
  d = b * b - 4 * a * c
  p1 = - b / 2.0 / a
  if (abs(d) < 1.0e-9) then
    write (*, "(A, F8.3)") "x = ", p1
  elseif (d > 0) then
    p2 = sqrt(d) / 2.0 / a
    write (*, "(2(A, F8.3))") "x1 = ", p1 + p2, char(13) // char(10) // "x2 = ", p1 - p2
  else
    cp2 = sqrt(cmplx(d)) / 2.0 / a
    write (*, "(2(A, F8.3, F8.3), A)") "x1 = (", p1 + cp2, ")" // char(13) // char(10) // "x2 = (", p1 - cp2, ")"
  end if
end

Hello, World!:

Пример для версий f2c 20090411, g95 0.93, gfortran 4.5.0

Этот пример написан в фиксированном формате (стиль FORTRAN 77); первые шесть символов каждой строки зарезервированы под служебную информацию — отметки о том, что строка является комментарием или продолжением предыдущей, метки и номера строк. Стандартный набор символов Fortran не содержит символов нижнего регистра, поэтому все программы пишутся в верхнем регистре. Исключением из этого правила являются символьные константы — они могут содержать любые символы, которые поддерживаются системой.

Первая строка дает этому фрагменту кода имя HELLO и указывает на то, что он является основной программой. Имя программы подчиняется тем же правилам, что и любые имена идентификаторов, т.е. должно начинаться с буквы и содержать не более 6 символов.

Команда WRITE реализует вывод на печать. В скобках передается список управляющих параметров, настраивающих вывод: UNIT выбирает файл вывода (по умолчанию — консоль), FMT — формат вывода. Звездочки означают параметры по умолчанию. Имена параметров передавать не обязательно, сокращенно эта же команда выглядела бы как WRITE (*, *) ....

В большинстве реализаций строковая константа может заключаться как в одинарные кавычки, так и в двойные.

! A simple Hello, World! program
      PROGRAM HELLO
        WRITE (UNIT=*, FMT=*) 'Hello, World!'
      END

Факториал:

Пример для версий f2c 20090411, g95 0.93, gfortran 4.5.0

Этот пример написан в фиксированном формате (стиль FORTRAN 77) и использует итеративное вычисление факториала.

Fortran позволяет пропускать объявления переменных; в таком случае он выводит их типы сам, но, в отличие от более поздних языков, не по контексту использования переменной, а по ее имени — если первая буква названия I..N, выбирается тип INTEGER, иначе — REAL. В данном случае обе переменные целые.

Цикл DO в данном случае соответствует циклу FOR более поздних языков: счетчик цикла N последовательно пробегает все значения от 0 до 16. Тело цикла заканчивается на строке с меткой 1, которая указана в заголовке цикла.

Команда PRINT использует формат вывода по умолчанию, который варьируется в зависимости от используемого компилятора.

      PROGRAM FACTOR
        NF = 1
        DO 1,N = 0,16
          PRINT *, N, "! =", NF
1         NF = NF * (N + 1)
      END

Числа Фибоначчи:

Пример для версий f2c 20090411, g95 0.93, gfortran 4.5.0

Этот пример демонстрирует использование массивов в Fortran. Индексация элементов начинается с 1.

      PROGRAM FIBONACCI
        INTEGER FIB(20)
        FIB(1) = 0
        FIB(2) = 1
        DO 1,N = 2,17
          PRINT "(I3, A, $)", FIB(N), ", "
1         FIB(N + 1) = FIB(N) + FIB(N - 1)
        PRINT *, "..."
      END

CamelCase:

Пример для версий f2c 20090411, g95 0.93, gfortran 4.5.0

Строки в Fortran имеют фиксированную длину, задаваемую при объявлении строки. Если длина фактического содержимого строки меньше, чем размер строки, ее остаток дополняется пробелами или “мусорными” символами. Кроме того, в Fortran нет символа “конца строки”, как в C. Из-за этого после посимвольного заполнения строки CC, содержащей результат, остаток строки приходится заполнять пробелами вручную.

Проверка того, что очередной символ исходной строки является буквой, слишком длинна, чтобы поместиться в одну строку (все символы строки программы, начиная с 73-ей позиции, игнорируются), поэтому ее приходится разбивать на две строки и отмечать вторую как продолжение первой (любым символом в 6 позиции).

Операторы сравнения в FORTRAN 77 записываются как .LE., .GE. и т.д. из-за того, что символы > и < не входят в набор символов языка; они были добавлены только в Fortran 90.

      PROGRAM CAMELC
        CHARACTER TEXT*30, CC*30
        LOGICAL LSPACE
        READ (*, '(A)') TEXT
        NCC = 0
        LSPACE = .TRUE.
        DO 1, I = 1,LEN(TEXT)
          NC = ICHAR(TEXT(I:I))
          IF (NC .GE. 65 .AND. NC .LE. 90 .OR.
     >        NC .GE. 97 .AND. NC .LE. 122) THEN
            IF (LSPACE) THEN
              IF (NC .GE. 97 .AND. NC .LE. 122) THEN
                NC = NC - 32
              END IF
            ELSE
              IF (NC .GE. 65 .AND. NC .LE. 90) THEN
                NC = NC + 32
              END IF
            END IF
            NCC = NCC + 1
            CC(NCC:NCC) = CHAR(NC)
            LSPACE = .FALSE.
          ELSE
            LSPACE = .TRUE.
          END IF
1       CONTINUE
        DO 2, I = NCC + 1,LEN(CC)
2         CC(I:I) = " "
        WRITE (*, *) CC
      END

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам