Главная страница
Навигация по странице:

  • 2.4. Этапы проектирования программ

  • 2.5. Правила записи исходного кода

  • 3.1. Типы данных

  • современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран


    Скачать 2.24 Mb.
    НазваниеО. В. Бартеньев Современный Фортран
    Анкорсовременный фортран , Бортеньев.pdf
    Дата28.05.2018
    Размер2.24 Mb.
    Формат файлаpdf
    Имя файласовременный фортран , Бортеньев.pdf
    ТипДокументы
    #19729
    страница5 из 49
    1   2   3   4   5   6   7   8   9   ...   49
    39

    О. В. Бартеньев. Современный ФОРТРАН
    integer md
    ! внешняя, то необходимо объявить ее тип
    <Ввод массивов a, b, и c> ma = md(a, na)
    ! Передача входных данных (массива и числа mb = md(b, nb)
    ! его элементов) в функцию md выполняется mc = md(c, nc)
    ! через ее параметры if(ma + mb + mc == 0) then print *, 'В массивах a, b и c нет отрицательных элементов' else m3 = min(ma, mb, mc) if(ma == m3) print *, 'В массиве a' if(mb == m3) print *, 'В массиве b' if(mc == m3) print *, 'В массиве c' end if end program nera function md(d, n)
    ! Заголовок функции integer md
    ! Результирующая переменная integer n, d(n), i
    ! Функция возвращает первый отрицательный элемент i = 1
    ! массива d или 0 при отсутствии таковых md = d(i) do while(md >= 0 .and. i < n) i = i + 1 md = d(i) end do if(md > 0) md = 0
    ! или: md = min(md, 0) end function md
    2.3.2. Использование подпрограмм
    Если фрагмент алгоритма возвращает более одного скаляра и/или массива, то такой фрагмент, как правило, оформляется в виде подпрограммы. Передача входных данных в подпрограмму и возвращаемых из нее величин выполняется через ее параметры.
    Выполним подсчет числа положительных (pos), отрицательных (neg) и равных нулю (ze) элементов массива a из примера разд. 2.2.4 в подпрограмме vapeg. В нее мы должны передать массив a, и затем получить из нее искомые значения: pos, neg и ze: program pns
    <Объявление данных> !
    См. текст программы pn разд. 2.2.4 call vapeg(a, n, pos, neg, ze)
    ! Вызов внешней подпрограммы vapeg if(ze > k) stop 'Число нулевых элементов больше нормы' write(*, *) 'pos = ', pos, ' neg = ', neg end program pns subroutine vapeg(a, n, pos, neg, ze) integer :: n, a(n), pos, neg, ze, i, va pos = 0; neg = 0; ze = 0
    ! Подготовка к вычислениям
    40

    2. Элементы программирования
    <Вычисление pos, neg и ze> !
    См. разд. 2.2.4 end subroutine vapeg
    2.3.3. Использование модулей
    Модули могут объединять в себе данные и процедуры, которые выполняют обработку объявленных в модуле данных. Программная единица, в которой присутствует оператор USE имя-модуля, получает доступ к не имеющим атрибута PRIVATE данным и процедурам модуля.
    Рассмотрим пример использования модуля для записи фрагмента алгоритма. Вернемся для этого к задаче разд. 2.1. В ней можно выделить два фрагмента:
    1°. Начало.
    2°. Ввести и проверить введенные значения границ отрезка a, b и шага dx.
    3°. Если введенные данные не содержат ошибок, то
    Выполнить начиная с точки x = a до точки b с шагом dx вычисление y и вывод значений x и y. конец если 3°.
    4°. Конец.
    Записи линейных схем фрагментов 2° и 3° легко выполнить по приведенному в разд. 2.1 алгоритму.
    Фрагмент 2° хорошо вписывается в концепцию модуля: он содержит данные и некоторый код, выполняющий обработку данных, часть из которых затем будет использована во втором фрагменте. Реализацию третьего фрагмента, как и ранее, выполним в главной программе. module ched
    ! Модуль ввода и обработки данных real a, b, dx
    ! Объявление данных модуля real, private :: dxmin = 1.0e-4 contains !
    Далее следует модульная функция function moched( )
    ! ввода и обработки данных logical moched
    ! Тип модульной функции print *, 'Ввод границ отрезка и шага вычислений' print '(1x, a, $)', 'Левая граница: ' read *, a print '(1x, a, $)', 'Правая граница: ' read *, b print '(1x, a, $)', 'Шаг вычислений: ' read *, dx moched = .false.
    ! Результирующая переменная moched равна if(dx < dxmin) then
    ! .FALSE., если есть ошибки в данных print *, 'Ошибка при задании шага' else if(a >= b) then print *, 'Ошибка при задании границ отрезка' else moched = .true.
    ! Если нет ошибок в данных
    41

    О. В. Бартеньев. Современный ФОРТРАН
    end if end function end module program txy
    ! Заголовок главной программы use ched
    ! Ссылка на модуль CHED real x, y
    ! Объявление данных главной программы if(moched( )) then
    ! Вызов модульной функции x = a
    ! Выполняем вычисления, если введенные do while(x <= b)
    ! данные не содержат ошибок y = x * sin(x) print '(1x, a, f5.2, a, f6.4)', 'x = ', x, ' y = ', y x = x + dx end do end if end program txy
    2.4. Этапы проектирования программ
    Рассмотренный выше порядок создания программы включает этапы составления общей схемы решения задачи, выделения фрагментов и их интерфейсов (входных и выходных данных), разработки алгоритмов для фрагментов и последующего их кодирования. Если теперь их дополнить этапом тестирования и отладки, то получится схема, вполне пригодная для решения простых задач. Однако жизненный цикл крупных программ несколько шире и состоит из этапов:
    1.
    Разработка спецификации.
    2.
    Проектирование программы.
    3.
    Запись программы на языке программирования (кодирование).
    4.
    Отладка и тестирование программы.
    5.
    Доработка программы.
    6.
    Производство окончательного программного продукта.
    7.
    Документирование.
    8.
    Поддержка программы в процессе эксплуатации.
    Спецификация содержит постановку задачи, анализ этой задачи и подробное описание действий, которые должна выполнять программа.
    В спецификации отражаются:

    состав входных, выходных и промежуточных данных;

    какие входные данные являются корректными и какие ошибочными;

    кто является пользователем программы и каким должен быть интерфейс;

    какие ошибки должны выявляться и какие сообщения должны выдаваться пользователю;

    какие ограничения имеет программа (например, программа размещения элементов печатной платы может иметь ограничение по числу размещаемых элементов);
    42

    2. Элементы программирования

    все особые ситуации, которые требуют специального рассмотрения;

    какая документация должна быть подготовлена;

    перспективы развития программы.
    На этапе проектирования создается структура программы и для каждого фрагмента выбираются известные или разрабатываются новые
    алгоритмы. Последние должны быть подвергнуты тщательным исследованиям на предмет их результативности, т. е. способности алгоритма получать требуемые результаты, и эффективности - способности алгоритма получать нужные результаты за приемлемое время.
    Параллельно с разработкой алгоритмов решаются вопросы организации
    данных, т. е. выделяются данные стандартных типов и способы их представления (скаляр или массив), а также разрабатываются новые структуры данных и определяется круг используемых с этими структурами операций. Подходы к решению этих задач во многом зависят от используемого языка программирования, который может быть, например, объектно-ориентированным или модульным. Современный Фортран поддерживает концепции как процедурного, так и модульного программирования (разд. 8.1).
    Для каждого фрагмента на этом этапе также создаются полные
    спецификации по приведенной выше схеме.
    Кодирование после разработки проекта программы и необходимых спецификаций является достаточно простой задачей. Когда же первые два этапа в явном виде не присутствуют, то неявно они выносятся на этап кодирования, со всеми вытекающими отсюда последствиями. Впрочем, для сложных задач игнорирование обозначенных выше этапов разработки программы недопустимо.
    Тестирование - это запуск программы или отдельного фрагмента с целью выявления в них ошибок. Отладка - процесс локализации и исправления ошибок. В результате тестирования устанавливается, соответствуют или нет разработанные фрагменты и состоящая из них программа сформулированным в спецификациях требованиям. Методы тестирования и отладки рассмотрены, например, в [10].
    Для тестирования фрагмента (программы) создаются специальные
    тестовые наборы входных данных, для которых до запуска фрагмента
    (программы) вычисляются ожидаемые результаты. Запуск фрагмента выполняется из специально созданной вспомогательной программы, называемой драйвером. Если фрагмент, в свою очередь, вызывает другие фрагменты, работоспособность которых пока еще не проверена, то эти фрагменты заменяются специальными простыми программами, которые имеют тот же интерфейс, что и заменяемые фрагменты, и имитируют их деятельность. Такие программы называются заглушками.
    43

    О. В. Бартеньев. Современный ФОРТРАН
    Тестирование может начинаться с фрагментов низшего уровня. Тогда нам понадобятся только драйверы, поскольку фрагменты более высокого уровня будут вызывать уже проверенные фрагменты. Такая стратегия тестирования называется восходящей. При нисходящей стратегии тестирование начинается с фрагментов высшего уровня. В этом случае понадобятся только заглушки. Обычно при тестировании восходящая и нисходящая стратегии используются совместно.
    Проделанная на предшествующих этапах работа, как правило, предоставляет разработчикам достаточный материал, позволяющий сделать выводы о рабочих характеристиках программы и сформулировать предложения по улучшению программы и ее отдельных показателей.
    Однако не всегда все эти предложения сразу же реализуются и программа с определенными изъянами выходит в свет в качестве программного
    продукта. Впрочем, если некоторые характеристики серьезно ухудшают качество программы, то придется выполнить ее доработку.
    Поддержка программы в процессе эксплуатации имеет целью устранение выявленных пользователями ошибок и адаптацию программного продукта к условиям его эксплуатации. Помимо этого, накапливается материал, необходимый для последующего развития и создания новой версии программы.
    2.5. Правила записи исходного кода
    Программисты, как правило, со временем вырабатывают свой стиль записи исходного кода, позволяющий им при повторном обращении к программе быстро вспоминать, что она делает и как работает, и при необходимости быстро вносить изменения в программу. Иными словами, программист умеет писать хорошо читаемый и легко изменяемый код.
    В ряде случаев необходимо, чтобы этот код легко могли бы прочесть и изменить другие программисты, например сопровождающие программу.
    Итак, за счет каких приемов удается записать хорошо читаемый и легко изменяемый код? Вот некоторые из них:

    программная единица должна содержать достаточный комментарий, позволяющий определить ее назначение, состав входных и выходных данных и выполняемые ей действия. Комментарий, однако, не должен мешать чтению операторов Фортрана;

    комментарий должен пояснять смысл используемых объектов данных;

    все используемые в программной единице данные должны быть явно объявлены. Это правило будет легче выполнить, если ввести в программную единицу оператор IMPLICIT NONE;

    операторы объявления следует группировать по типам;

    используемые для объектов данных и процедур имена должны напоминать их смысл и указывать на используемый тип. Например, имя
    44

    2. Элементы программирования
    g может быть использовано для обозначения ускорения свободного падения, имя iVectorSize подойдет для указания длины вектора. Понятен смысл и имени pi;

    атрибуты объектов данных следует объявлять в операторах объявления типа, например так: integer, parameter :: n = 20, m = 10
    ! Размерности матрицы a а не так: integer n, m
    ! Этот способ хуже parameter (n = 20, m = 10)

    задание размерностей статических массивов лучше выполнять в виде именованных констант. В случае изменения размерности потребуется изменить лишь значение соответствующей константы: integer, parameter :: m = 10, n = 20 real a(m, n)

    длину символьной именованной константы лучше задавать в виде звездочки, например: character(*), parameter :: date = '01.01.2000'

    при записи управляющих конструкций следует использовать правило
    рельефа, состоящее в том, что расположенные внутри конструкции операторы записываются правее образующих эту конструкцию операторов, например операторов IF-THEN-ELSE. Это же правило распространяется на запись определений производных типов и процедур;

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

    при создании вложенных конструкций им следует давать имена;

    операторы FORMAT группируются в одном месте, как правило вверху или внизу программной единицы;

    размещенные в одном файле программные единицы должны разделяться пустыми строками;

    программные единицы следует располагать в файле в алфавитном порядке их имен;

    однократно используемые в программе процедуры лучше оформлять как внутренние, следующие после оператора CONTAINS;

    внутренняя функция лучше операторной;

    формальный параметр - массив следует оформлять как массив, перенимающий форму, или как массив заданной формы;
    45

    О. В. Бартеньев. Современный ФОРТРАН

    внутренние массивы и строки процедур следует оформлять как автоматические объекты;

    не использовать оператор GOTO;

    не применять ассоциирования памяти;

    отказаться от использования нерекомендуемых и устаревших средств
    Фортрана (прил. 2).
    Большинство из приведенных правил рассмотрены в пособии и проиллюстрированы примерами.
    46

    3. Организация данных
    Для каждого применяемого внутри программной единицы объекта данных должны быть определены тип, диапазон изменения (в случае числового типа), а также форма представления: скаляр или массив. Данные также должны быть разделены на изменяемые - переменные - и не подлежащие изменению - константы.
    Помимо переменных и констант к объектам данных можно отнести и функции, поскольку они так же, как и переменные и константы, обладают типом и используются в качестве операндов выражений.
    Термины переменная и константа распространяются на скаляры, массивы и их подобъекты, например элементы массивов, компоненты структур, сечения массивов, подстроки.
    Цель настоящей главы - рассмотрение типов данных Фортрана, их свойств, способов объявления объектов данных разных типов, способов задания начальных значений переменных и других, связанных с организацией данных вопросов. Диапазон рассмотрения ограничен скалярами. Массивы, как более сложные, играющие исключительно важную роль в Фортране объекты данных, рассмотрены отдельно.
    Замечание. При описании операторов Фортрана их необязательные элементы заключаются в квадратные скобки. Символ вертикальной черты
    (|) используется в описании оператора для обозначения "или".
    3.1. Типы данных
    Типы данных разделяются на встроенные и производные, создаваемые пользователем (разд. 3.9).
    Встроенные типы данных:
    Целый - INTEGER, BYTE, INTEGER(1), INTEGER(2), INTEGER(4).
    Вещественный - REAL, REAL(4), REAL(8), DOUBLE PRECISION.
    Комплексный - COMPLEX, COMPLEX(4), COMPLEX(8), DOUBLE COM-
    PLEX.
    Логический - LOGICAL, LOGICAL(1), LOGICAL(2), LOGICAL(4). Объект данных логического типа может принимать значения .TRUE. (истина) или .FALSE. (ложь).
    Символьный - CHARACTER(n), где n - длина символьной строки
    (1
    n ≤ 32767).
    В Фортране каждый встроенный тип данных характеризуется параметром разновидности (KIND). Для числовых типов данных этот параметр описывает точность и диапазон изменения. В настоящее время для символьного типа данных существует только одна разновидность
    (KIND = 1).
    47

    О. В. Бартеньев. Современный ФОРТРАН
    Каждый встроенный тип данных имеет стандартную, задаваемую по умолчанию разновидность. Встроенный тип с задаваемой по умолчанию разновидностью называется стандартным типом данных.
    Стандартные типы данных:
    Целый - INTEGER.
    Вещественный - REAL.
    Комплексный - COMPLEX.
    Логический - LOGICAL.
    Символьный - CHARACTER.
    В табл. 3.1 приведены разновидности встроенных типов данных. В графе "Число байт" указано количество байт, отводимых под объект заданного типа. При обозначении типа данных использован введенный в стандарте
    Фортран 90 синтаксис.
    Таблица 3.1. Разновидности встроенных типов данных
    Типы
    Разновидность Число
    байт
    Примечание
    Целый тип
    BYTE 1 1
    То же, что и INTEGER(1)
    INTEGER(1) 1 1
    INTEGER(2) 2 2
    INTEGER(4) 4 4
    INTEGER 4 4
    То же, что и INTEGER(4)
    Вещественный тип
    REAL(4) 4 4
    REAL 4 4
    То же, что и REAL(4)
    REAL(8) 8 8
    DOUBLE
    PRECISION
    8 8
    То же, что и REAL(8)
    Комплексный тип
    COMPLEX(4) 4 8
    4 байта под действительную и столько же под мнимую часть
    COMPLEX 4 8
    То же, что и COMPLEX(4)
    COMPLEX(8) 8 16 8 байт под действительную и столько же под мнимую часть
    DOUBLE
    COMPLEX
    8 16
    То же, что и COMPLEX(8)
    48
    риложение3. Организация данных
    Логический тип
    LOGICAL(1) 1 1
    Байт, содержащий либо 0 -
    .FALSE., либо 1 - .TRUE.
    LOGICAL(2) 2 2
    Первый (старший) байт содержит значение LOGICAL(1), второй - null
    LOGICAL(4) 4 4
    Первый байт содержит значение
    LOGICAL(1), остальные - null
    LOGICAL 4 4
    То же, что и LOGICAL(4)
    Символьный тип
    CHARACTER или
    CHARACTER(1)
    1 1
    Единичный символ
    CHARACTER(n) 1 n
    n - длина строки в байтах
    Замечания:
    1. Каждый числовой тип данных содержит 0, который не имеет знака.
    2. Все приведенные в табл. 3.1 типы данных были доступны и в
    Фортране 77. Правда, синтаксис определения типа был иным, например:
    Фортран 90
    Фортран 77
    INTEGER(1) INTEGER*1
    INTEGER INTEGER
    COMPLEX(4) COMPLEX*8
    COMPLEX(8) COMPLEX*16
    В Фортране 90 после описания встроенного типа данных в скобках указывается значение параметра разновидности, а в Фортране 77 после звездочки следует число отводимых под тип байт. С целью преемственности можно использовать при задании типов данных синтаксис
    Фортрана 77.
    Помимо встроенных типов можно задать и производные типы данных
    (структуры), которые создаются комбинаций данных, встроенных и ранее введенных производных типов. Такие типы данных вводятся оператором
    TYPE ... END TYPE.
    Фортран включает большое число встроенных числовых справочных и преобразовывающих функций (разд. 6.11-6.13), позволяющих получать информацию о свойствах данных различных типов. Так, наибольшее положительное число для целого и вещественного типов определяется функцией HUGE, а наименьшее положительное число вещественного типа - функцией TINY.
    1   2   3   4   5   6   7   8   9   ...   49


    написать администратору сайта