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

  • 1.10. Обработка программы

  • Замечание.

  • 2.2. Базовые структуры алгоритмов

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


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

    1. Элементы языка
    real :: x = 1.1, y = 2.2 real z print *, x, y
    ! Обязательно просматриваем результаты или: real x /1.1/, y /2.2/ real z print *, x, y
    ! Обязательно просматриваем результаты

    дадим теперь начальные значения переменным оператором DATA: real x, y, z data x / 1.1 /, y / 2.2 /
    ! или: data x, y / 1.1, 2.2 / print *, x, y

    поместим в список вывода выражение и опустим заголовок программы: real :: x = 1.1, y = 2.2 print *, x + y
    ! В списке вывода выражение end

    запишем несколько операторов на одной строчке: x = 1.1; y = 2.2; z = x + y
    ! или: z = x + y;

    внесем ошибку в программу и посмотрим реакцию компилятора: program p1 real :: x = 1.1, y = 2.2 print *, x + y end program p11
    ! Ошибка: имя p11 не совпадает с именем p1
    Составленные вами решения тестовых задач должны содержать достаточное число операторов вывода промежуточных результатов, которые позволят понять работу изучаемых элементов языка, убедиться в правильности вычислений или локализовать ошибку.
    Особенно внимательно следует наблюдать и проверять результаты выполняемого с клавиатуры и из файла ввода данных.
    Уже на начальном этапе освоения материала следует не пожалеть времени для приобретения навыков ввода данных из текстового файла.
    Данные в текстовой файл могут быть занесены с клавиатуры в DS так же, как и в другом текстовом редакторе. В DS для создания нового файла используйте приведенные в разд. 1.2.1 и 1.2.2 сведения. Далее введите с клавиатуры данные, разделяя числа одним или несколькими пробелами, например:
    1.2 -1.5 4.0 10 -3
    Сохранить данные можно в любой существующей папке, однако на первых порах лучше размещать файл в папке, из которой выполняется запуск ваших учебных программ. Это освободит вас от необходимости задавать в программе путь в имени файла. Для записи файла на диск
    21

    О. В. Бартеньев. Современный ФОРТРАН
    используйте File - Save - в поле "Имя файла" задать имя файла, например a.txt - сохранить.
    Теперь попробуем ввести данные из только что сформированного файла a.txt в одномерный массив ar из 10 элементов. Для этого мы должны открыть файл a.txt и поместить в список ввода оператора READ элементы массива, в которые выполняется ввод данных, например: integer, parameter :: n = 10
    ! Размер массива ar real :: ar(n)
    ! Объявляем вещественный массив ar character(50) :: fn = 'a.txt'
    ! Задаем имя файла ar = 0.0
    ! Теперь все элементы ar равны нулю open(1, file = fn)
    ! Подсоединяем файл к устройству 1
    ! Ввод первых пяти элементов из файла a.txt read(1, *) ar(1), ar(2), ar(3), ar(4), ar(5)
    ! Вывод первых пяти элементов массива ar на экран print *, ar(1), ar(2), ar(3), ar(4), ar(5) end
    В списке ввода размещено 5 элементов массива. Что будет, если добавить в него еще один элемент, например ar(6)? Если ответ на вопрос не очевиден, то добавьте, запустите программу и объясните природу ошибки.
    Использованные в примере списки В/В выглядят громоздко. Легко представить размер подобного списка при вводе, например, нескольких сотен элементов массива. В Фортране есть несколько способов задания компактных списков В/В. Например:
    ! Список ввода содержит все элементы массива ar read(1, *) ar
    ! Циклический список ввода, содержащий пяти первых элементов массива ar read(1, *) (ar(i), i = 1, 5)
    ! В списке ввода сечение массива ar из пяти первых его элементов read(1, *) ar(1:5)
    Таким же образом могут быть составлены и списки вывода.
    Наиболее компактно выглядит первый список ввода в операторе
    READ(1,*) ar,но в нашем случае он нам не подходит. Почему?
    В/В массива можно выполнить и в цикле do i = 1, 5 read(1, *) ar(i)
    ! В списке ввода один элемент массива ar end do
    Такой цикл эквивалентен последовательности 5 операторов ввода: read(1, *) ar(1)
    ! В списке ввода один элемент массива ar read(1, *) ar(2) read(1, *) ar(3)
    22

    1. Элементы языка
    read(1, *) ar(4) read(1, *) ar(5)
    Однако такая последовательность, хотя в ней присутствует только
    5 элементов массива, не может быть введена из созданного нами файла a.txt.
    Почему?
    Вывод массива ar при помощи цикла do i = 1, 5 write(1, *) ar(i)
    ! Вывод в файл a.txt write(*, *) ar(i)
    ! Вывод на экран end do будет выполнен успешно. При этом, однако, выводимые данные будут размещены в столбик. Почему? Кстати, где расположатся выводимые в файл a.txt записи?
    Добавим теперь в файлa.txt не менее пяти чисел. Если файл открыт в DS, то для перехода в окно с данными файла можно нажать Ctrl + F6 или выбрать окно с файлом, воспользовавшись пунктом меню Window. Пусть модифицированный файл выглядит так:
    1.2 -1.5 4.0 10 -3 34.2 -55 79.1 90 100.2 -0.4
    Теперь для ввода всех элементов массива можно применить оператор read(1, *) ar
    Кстати, почему можно размещать вводимые одним оператором READ данные на разных строчках файла?
    Напишите теперь программу вывода первых девяти элементов массива
    ar на трех строках экрана по 3 числа массива в каждой строке.
    Подобным образом следует анализировать и другие элементы Фортрана, сочетая чтение литературы, разбор приведенных в ней примеров с постановкой и решением учебных задач.
    1.10. Обработка программы
    Программист записывает программу в исходном коде (тексте).
    Программа может существовать в одном или нескольких файлах, называемых исходными файлами. Имена исходных файлов имеют расширения F90, FOR или F, напримерkoda.f90. По умолчанию Фортран считает, что файлы с расширением F90 написаны в свободной форме, а с расширениями FOR и F - в фиксированной.
    Далее выполняется компиляция программы, в результате которой исходный текст преобразовывается в объектный код. В процессе компиляции проверяется правильность составления программы и при
    23

    О. В. Бартеньев. Современный ФОРТРАН
    обнаружении синтаксических ошибок выдаются соответствующие сообщения. Объектный код - это запись программы в форме, которая может быть обработана аппаратными средствами. Такой код содержит точные инструкции о том, что компьютеру предстоит сделать. Отдельные компоненты программы могут быть откомпилированы раздельно. Часть компонентов может быть записана в библиотеку объектных файлов.
    Программа, преобразовывающая исходный код в объектный, называется
    компилятором или транслятором. Файлы с объектным кодом - объектные файлы - имеют расширение OBJ, напримерkoda.obj.
    На следующей стадии обработки выполняется сборка приложения. Часть объектных файлов может быть загружена из библиотек. При этом отдельные компоненты (главная программа, модули, подпрограммы, функции) связываются друг с другом, в результате чего образуется готовая к выполнению программа - исполняемый файл. Расширение таких файлов
    EXE. Программа, осуществляющая сборку, называется компоновщиком или построителем. На этапе генерации исполняемого кода также могут возникать ошибки, например вызов несуществующей подпрограммы.
    В CVF и FPS подготовка исходного, объектного и исполняемого кодов может быть выполнена в специальной среде - Microsoft Developer Studio.
    Причем из одного проекта можно генерировать несколько реализаций.
    Например, на этапе разработки программы можно работать с реализацией, в которой отсутствует оптимизация исполняемого кода по его размеру и скорости выполнения (заданы опция компилятора /Od и опция компоновщика /OPT:NOREF). Отсутствие подобной оптимизации повышает скорость компиляции и компоновки. После завершения отладки можно создать рабочий проект, оптимизированный по размеру и скорости выполнения исполняемого файла, задав, например, при компиляции опцию
    /Oxp, а для компоновки - /OPT:REF. Можно задать и другие опции компилятора. Так, опция /G5 позволяет сгенерировать код, оптимально работающий на процессоре Intel Pentium.
    По умолчанию при создании нового проекта в DS оказываются доступными две реализации: Debug и Release. В Debug активизирован отладочный режим. В Release исполняемый код оптимизируется по размеру и быстродействию. Ниже приведены задаваемые по умолчанию в FPS опции компилятора и компоновщика в реализациях Debug и Release при создании консоль-проекта.
    Реализация Debug
    Опции компилятора:
    /Zi /I "Debug/" /c /nologo /Fo"Debug/" /Fd"Debug/koda.pdb"
    Опции компоновщика:
    24

    1. Элементы языка
    kernel32.lib /nologo /subsystem:console /incremental:yes
    /pdb:"Debug/koda.pdb" /debug /machine:I386 /out:"Debug/koda.exe"
    Реализация Release
    Опции компилятора:
    /Ox /I "Release/" /c /nologo /Fo"Release/"
    Опции компоновщика: kernel32.lib /nologo /subsystem:console /incremental:no
    /pdb:"Release/koda.pdb" /machine:I386 /out:"Release/koda.exe"
    Замечание. Вопросы оптимального использования опций компилятора и построителя рассмотрены в [1].
    25

    2. Элементы программирования
    2.1. Алгоритм и программа
    Программа выполняет на ЭВМ некоторую последовательность действий, в результате чего должны получаться необходимые результаты.
    Для составления программы прежде необходимо уяснить суть задачи, а затем уже описать действия, после выполнения которых будут получены сформулированные в задаче цели. Иными словами, необходимо составить
    алгоритм решения задачи.
    Рассмотрим простой пример. Пусть надо составить таблицу значений функции y = x*sinx на отрезке [a, b] с шагом dx. Для решения задачи необходимо выполнить следующие действия:
    1°. Начало.
    2°. Ввести значения a и b границ отрезка и шаг dx.
    3°. Задать x - начальную точку вычислений, приняв x = a.
    4°. Пока x
    b, выполнять: вычислить значение функции y в точке x: y = x*sinx; вывести значения x и y; перейти к следующей точке отрезка: x = x + dx. конец цикла 4:
    5°. Конец.
    Четвертый пункт алгоритма предусматривает повторное выполнение вычислений y для разных значений аргумента x. Такое повторное выполнение однотипных действий называется циклом. Приведенный цикл завершится, когда значение x превысит b - правую границу отрезка.
    Для составления программы, выполняющей предусмотренные алгоритмом действия, надо перевести отдельные шаги алгоритма на язык программирования. Если буквально следовать приведенному алгоритму, то мы получим программу: read *, a, b, dx
    ! Выполняем 2-й шаг алгоритма x = a
    ! Выполняем 3-й шаг алгоритма do while(x <= b)
    ! Выполняем 4-й шаг алгоритма y = x*sin(x) print *, x, y
    ! Вывод x и y x = x + dx end do
    ! Конец цикла end !
    Завершаем программу
    Однако, хотя программа записана правильно, работать с ней практически невозможно. Предположим, что вы все же запустили программу для вычислений. Тогда перед вами окажется черный экран, глядя на который вам придется догадаться, что нужно ввести 3 числа.
    Предположим, что вы догадались и, угадав затем порядок ввода, набрали 0,
    26

    2. Элементы программирования
    1, 0.1. Тогда после нажатия на Enter перед вами появятся два столбика с цифрами и опять придется угадывать, что за числа в них расположены.
    Запустив эту программу через неделю, вы, конечно, уже ничего не вспомните.
    Поэтому нам следует придать программе некоторые иные, не предусмотренные первоначальным алгоритмом свойства. Так, нужно создать диалог для ввода данных, нужно пояснить, каким объектам принадлежат выводимые на экран значения. Иными словами, нужно создать некоторый интерфейс между пользователем и программой. Нужно также проверить правильность ввода данных: левая граница должна быть меньше правой, а шаг dx должен быть больше нуля (в противном случае мы можем получить бесконечный цикл, например если a < b и dx
    ≤ 0). Вводя подобные проверки, мы повышаем надежность программы. Можно предусмотреть и другие повышающие качество программы мероприятия.
    Помимо добавлений таких рабочих характеристик полезно увеличить и требования к оформлению программы: дать программе имя, объявить типы применяемых в вычислениях переменных, привести исчерпывающий комментарий. Можно выполнить запись операторов, имен встроенных процедур и других элементов Фортрана прописными буквами, а запись введенных пользователем имен - строчными. При записи фрагментов программы, например управляющей конструкции DO WHILE ... END DO, следует использовать правило рельефа, состоящее в том, что операторы DO
    WHILE и END DO начинаются с одной позиции, а расположенные внутри этой конструкции операторы смещаются на одну-две позиции вправо по отношению к начальной позиции записи DO WHILE и END DO. Еще одно полезное правило: после запятой или иного разделителя в тексте программы следует проставлять пробел, т. е. поступать так же, как и при записи текста на родном языке. После ряда дополнений мы можем получить программу: program txy
    ! Заголовок программы real a, b, dx, x, y
    ! Объявление имен и типов переменных real :: dxmin = 1.0e-4 print *, 'Ввод границ отрезка и шага вычислений' print *, 'Левая граница: '
    ! Выводим подсказку для пользователя read *, a
    ! Вводим с клавиатуры значение a и print *, 'Правая граница: '
    ! нажимаем на Enter. Так же вводятся read *, b
    ! другие данные print *, 'Шаг вычислений: ' read *, dx if(dx < dxmin) stop 'Ошибка при задании шага' x = a
    ! Выполняем 3-й шаг алгоритма do while(x <= b)
    ! Выполняем 4-й шаг алгоритма y = x*sin(x)
    ! При записи цикла используем правило рельефа print *, 'x = ', x, ' y = ', y
    27

    О. В. Бартеньев. Современный ФОРТРАН
    x = x + dx end do end program txy
    ! Завершаем программу txy
    Замечание. CVF и FPS обладают специальной библиотекой процедур
    DIALOGM, предназначенных для создания диалоговых окон В/В данных.
    Технология создания диалогов средствами DIALOGM рассмотрена в [1].
    Предположим, однако, что после ввода a = 0, b = 1 и dx = 0.1. Тогда для значений x, равных, например, 0.3, 0.4 и 0.5, будет выведен результат: x = 3.000000E-01 y = 8.865607E-02 x = 4.000000E-01 y = 1.557673E-01 x = 5.000000E-01 y = 2.397128E-01
    Каждая выводимая на экран строка является в нашем примере отдельной записью.
    Результат вывода понятен, но не очень нагляден. Форму его представления можно улучшить, применив форматный вывод, т. е. задав некоторые правила преобразования выводимых данных. Такие правила задаются дескрипторами преобразований (ДП). Для вывода заключенной в кавычки последовательности символов используем дескриптор A, а вывод значения x выполним на поле длиной в 5 позиций, располагая после десятичной точки две цифры. Для этого нам понадобится дескриптор F5.2.
    При выводе y используем дескриптор F6.4. Тогда оператор вывода x и y
    примет вид: print '(1x, a, f5.2, a, f6.4)', 'x = ', x, ' y = ', y
    Результат для тех же значений x будет выглядеть уже более наглядно: x = .30 y = .0887 x = .40 y = .1558 x = .50 y = .2397
    Заметим сразу, что список ДП открывает дескриптор 1X, который означает задание одного пробела, предваряющего выводимый текст. В FPS при форматном выводе это необходимо, поскольку первый символ каждой записи не печатается и рассматривается как символ управления кареткой.
    В CVF такой интерпретации первого символа не выполняется и дескриптор
    1X можно опустить.
    Можно также улучшить и фрагмент программы, предназначенный для ввода данных. Если вы запустите программу, то обнаружите, что после вывода каждой подсказки курсор смещается на начало новой строки.
    Иными словами, выполняется переход на начало следующей записи. Такого перехода можно избежать, если использовать при выводе подсказки форматный вывод и применить в нем для вывода строки дескриптор A, а вслед за ним дескриптор $ или \ или спецификатор ADVANCE = 'NO'.
    Правда, последняя опция применима лишь в операторе вывода WRITE.
    28

    2. Элементы программирования
    Выполняемый таким образом вывод называется выводом без продвижения.
    Например: print '(1x, a, $)', 'Левая граница: ' print '(1x, a, \)', 'Левая граница: ' write(*, '(1x, a)', advance = 'no') 'Левая граница: '
    Рассмотренный пример позволяет сделать, по крайней мере, 3 вывода.
    С одной стороны, разработанный алгоритм:

    позволяет понять, какие данные являются входными, какие - результатом (т. е. выделить входные и выходные данные);

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

    определяет порядок выполнения действий;

    устанавливает момент завершения вычислений.
    Основой для программной реализации алгоритма являются управляющие конструкции, одной из которых является только что использованная конструкция DO WHILE ... END DO.
    С другой стороны, очевидно, что для перевода алгоритма в программу необходимо обладать дополнительными, не связанными с алгоритмом знаниями. Например: как объявить типы данных, как создать приемлемый интерфейс между пользователем и программой, что такое запись, как выполнить форматный вывод, и что такое дескрипторы преобразований, и т. д.
    И наконец, последний вывод: программист должен одинаково хорошо владеть и техникой составления алгоритмов, и техникой программирования, для освоения которой в современном Фортране, надо признать, требуется проделать большую работу.
    2.2. Базовые структуры алгоритмов
    Запись программы на языке программирования следует выполнять после разработки алгоритма. Имея алгоритм, вы знаете, как решать задачу, и во многом уже определяете контуры будущей программы. Здесь мы говорим лишь о контурах программы, поскольку реализация алгоритма в виде исходного кода может быть выполнена несколькими способами.
    Для записи алгоритмов могут быть использованы линейные схемы, блок-
    схемы и псевдокод. Мы будем использовать линейные схемы, первый пример использования которой приведен в разд. 2.1. При их написании будем пользоваться правилом рельефа; необязательные элементы схем будем указывать в квадратных скобках, а знак вертикальной черты будем употреблять для обозначения "или".
    Любой алгоритм может быть записан при помощи трех базовых
    структур:

    блока операторов и конструкций;
    1   2   3   4   5   6   7   8   9   ...   49


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