современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
11 О. В. Бартеньев. Современный ФОРТРАН character(30) :: fn = 'c:\dig.bin' ! fn - символьная переменная real, parameter :: pi = 3.141593 ! pi - вещественная константа В программе составной объект может быть использован целиком, можно также использовать и часть составного объекта, которая называется подобъектом. Так, в случае массива его подобъектом является отдельный элемент массива, а также и любая часть массива, которая называется сечением массива. Например: real a(5) ! Объявляем вещественный массив a из пяти элементов a = 1.2 ! Присвоим значение 1.2 всем элементам массива a a(2) = -4.0 ! Присвоим значение -4.0 второму элементу массива print *, a(1:3) ! Вывод сечения массива a - первых трех его элементов print *, a(1), a(2), a(3) ! Этот вывод эквивалентен предыдущему 1.5. Имена Переменные, константы, программные компоненты имеют имена. Имя - это последовательность латинских букв, цифр, символа $ или подчеркивания, начинающаяся с буквы или символа $. Имя не должно содержать более 31 символа. Регистр букв не является значащим. Так, имена st, St, sT, ST есть одно и то же. Следует придумывать имена, отображающие смысл применяемых переменных, констант и других объектов программы. Примеры имен: Cat1 F_Name $var stlen Имена разделяются на глобальные, например имя главной программы или встроенной процедуры, и локальные, например имя переменной или константы. Разрешается создавать локальные имена, совпадающие с глобальными именами встроенных процедур. Но если в программной единице имя, например sum, использовано для имени локальной переменной, встроенная функция SUM в этой программной единице будет недоступна. Поэтому для создаваемых объектов следует придумывать имена, которые отличаются от имен встроенных процедур. Не стоит также давать создаваемым объектам имена, совпадающие с именами операторов и других объектов Фортрана. Замечание. Широко используется при формировании имен так называемая Венгерская нотация. В соответствии с ней имя объекта снабжается префиксом из строчных букв, указывающих его тип (если объект обладает типом). Последующая часть имени раскрывает его смысл. Причем каждая часть имени, отражающая отдельный смысловой компонент, начинается с прописной буквы. Например, имя iVectorSize может быть дано именованной константе, хранящей размер вектора, а имя SetInitValues может иметь подпрограмма, выполняющая инициализацию переменных. В 12 1. Элементы языка примерах пособия Венгерская нотация (за редкими исключениями) не употребляется. 1.6. Выражения и операции Выражение - это формула, по которой вычисляется значение, например 2.0*cos(x/4.5). Выражение состоит из операндов и нуля или более операций. Используемые в выражениях операции разделяются на двуместные и одноместные (унарные + и -). В двуместной операции участвуют два операнда, в одноместной - один. Например: b + c ! Простое выражение с двуместной операцией -b ! Простое выражение с одноместной операцией c ! Выражение без операций Операндами выражения могут быть константы, переменные и вызовы функций. Выражение может присутствовать в правой части оператора присваивания, в операторах вывода, в вызовах процедур и других операторах языка. Общий вид выражения, в котором присутствуют двуместные операции: операнд операция операнд операция операнд ... Значение каждого операнда выражения должно быть определено, а результат должен иметь математический смысл. Например, не должно быть деления на нуль. Замечание. Подобъект составного объекта также является переменной и, следовательно, может быть операндом выражения. Например: real a(10) = 3.0, b(7) ! Массив является составной переменной a = 2.0 * a ! Массив как элемент выражения ! Элементом выражения является сечение подобъект массива - его сечение a(2:8) b = a(2:8) / 2.5 В зависимости от типа возвращаемого результата выражения подразделяются на арифметические, логические, символьные и производного типа. Для выражений первых трех типов в Фортране определены встроенные операции. В выражениях производного типа операции должны быть заданы программистом. Встроенные арифметические операции приведены в табл. 1.1. Таблица 1.1. Встроенные арифметические операции Действия Обозначения Примеры Запись на Фортране Возведение в степень ** 3 2 2**(1.0 / 3.0) Умножение, деление *, / a × b; a : b a * b; a / b 13 О. В. Бартеньев. Современный ФОРТРАН Сложение, вычитание +, - a + b; a - b a + b; a - b Унарные + и - +2; -5.5 +2; -5.5 Пример арифметического выражения: real :: a = -1.2 a = a * a + 2.2**2 ! Возвращает 6.28 Возведение в степень имеет ограниченную область действия. Так, запрещается возводить отрицательное число в нецелочисленную степень, например ошибочно выражение (-2)**3.1. Также нельзя возводить нуль в отрицательную или нулевую степень. Операции различаются старшинством, или приоритетом. Среди арифметических операций наибольшим приоритетом обладает операция возведения в степень, далее с одинаковым приоритетом следуют умножение и деление, одинаковый и наименьший приоритет имеют сложение, вычитание и унарные + и -. Например, -3**2 возвращает -9, а не 9. Выражения без скобок вычисляются слева направо последовательно для операций с одинаковым приоритетом, за исключением операций возведения в степень, которые выполняются справа налево. Если требуется изменить эту последовательность, то часть выражения, которую нужно вычислить в первую очередь, выделяется скобками. Иногда скобки используются и для улучшения читаемости выражения. Между элементом выражения и знаком операции для улучшения читаемости выражения можно проставить один пробел. Пример: real :: a, c, d = 1.1 real :: s1 = -1.0, s2 = -2.2, s3 = 3.3 d = (d + 5.17) / 46.2 ! Прежде вычисляется выражение в скобках a = d - (s1 + s2 + s3) ! или a = d - s1 - s2 - s3 c = 2.0**2.0**(1.0/3.0) ! Отобразим порядок вычислений, c = 2.0**( 2.0**(1.0/3.0) ) ! расставив скобки Знак одноместной операции не должен следовать непосредственно за другим знаком операции. Чтобы этого избежать, подвыражение с одноместной операцией заключается в скобки. Например: a = 4 / -2 ! Ошибка a = 4 / (-2) ! Правильно Всегда надо учитывать эффект целочисленного деления, при котором отбрасывается получаемая в результате арифметического деления дробная часть, например: -5 / 2 Возвращает -2 5 / 2 Возвращает 2 14 1. Элементы языка Результатом арифметического выражения может быть целое, вещественное или комплексное число. Результатом логического выражения является либо .TRUE. - истина, либо .FALSE. - ложь. Результатом символьного выражения является последовательность символов, которая называется символьной строкой. Примеры логического и символьного выражений: real :: a = 4.3, d = -5.0 logical :: fl = .false. ! Объявление логической переменной character(10) :: st, st2*3 = 'C6' ! Объявление символьных переменных st и st2 fl = .not. fl .and. a > d ! .TRUE. st = st2 // '- 97' ! C6 - 97 Выражение является константным, если оно образуется из констант. Такого рода выражения могут быть использованы, например, при объявлении массивов или символьных данных: integer, parameter :: n = 20, m = 3 * n real a(n), d(2*n), c(m) character(len = n / 2) st Операндами арифметических, логических и символьных выражений могут быть согласованные массивы или их сечения. Одномерные массивы согласованы, если они имеют одинаковое число элементов. Всегда согласованы массив и скаляр, т. е. объект данных, не являющийся массивом. Например: integer :: a(0:4) = 3, b(-1:3) = 7, d(5) d = (a + b) / 2 ! Элементы массива d: 5, 5, 5, 5, 5 В приведенном примере поэлементно выполняется сложение соответствующих элементов массивов a и b, затем скаляр 2 расширяется до одномерного массива из пяти элементов, каждый элемент которого равен двум и на который поэлементно делится полученный ранее массив сумм, т. е. оператор d = (a + b)/2 эквивалентен оператору d = (a + b) / (/ 2, 2, 2, 2, 2 /) Фортран позволяет использовать в выражениях не только встроенные, но и задаваемые программистом операции. Такие операции применяются, например, при работе с производными типами данных, для которых не определено ни одной встроенной операции. Могут быть заданы как двуместные, так и одноместные операции. 1.7. Присваивание Оператор присваивания обозначается знаком равенства (=) и записывается в виде 15 О. В. Бартеньев. Современный ФОРТРАН varname = выражение В результате присваивания переменная varname получает новое значение, которое возвращается в результате вычисления выражения. Знак равенства оператора присваивания трактуется иначе, чем знак равенства в математике. Так, в математике запись k = 2 * k + 1 означает запись уравнения, решением которого является k = -1, а уравнение k = k + 1 вообще не имеет решения. В то же время в программе integer :: k = 4 k = k + 1 ! После присваивания k равно пяти k = 2 * k + 1 ! После присваивания k равно 11 встроенный оператор присваивания определен для числовых, логического и символьного типов данных. Использовать varname для переменной производного типа можно, если выражение имеет тот же тип, что и varname. Если тип переменной varname отличается от типа выражения, то результат выражения преобразовывается в тип varname. Поскольку в результате преобразований возможна потеря точности, то необходимо следить, чтобы эта потеря не привела к серьезному искажению результата, например: integer n real x, y n = 9.0 / 2 ! После присваивания n равно четырем x = 9.0 / 2 ! После присваивания x равно 4.5 y = n * 5 ! Возвращает 20 - потеря точности y = x * 5 ! Возвращает 22.5 - вычисления без потери точности 1.8. Простой ввод/вывод При вводе с клавиатуры данные из текстового представления преобразовываются во внутреннее. При выводе на экран данные из внутреннего представления преобразовываются во внешнее (текстовое). Преобразования ввода/вывода (В/В) можно задать дескрипторами преобразований. Можно также использовать В/В, в котором преобразования выполняются в соответствии с установленными по умолчанию правилами. Такого рода преобразования обеспечиваются управляемым списком В/В, который мы и будем преимущественно использовать в поясняющих примерах. Управляемые списком операторы ввода с клавиатуры и вывода на экран выглядят так: READ(*, *) список ввода ! Ввод с клавиатуры READ *, список ввода ! Ввод с клавиатуры WRITE(*, *) список вывода ! Вывод на экран 16 1. Элементы языка PRINT *, список вывода ! Вывод на экран Список ввода - часть оператора ввода, устанавливающая величины, которые надо ввести. Список вывода устанавливает величины, которые надо вывести. Список вывода может содержать произвольные выражения; список ввода - только переменные. Последняя или единственная звездочка приведенных операторов означает, что В/В управляется списком. В операторах, содержащих две заключенные в скобки и разделенные запятой звездочки, первая - задает устройство В/В (клавиатуру и экран). Пример: integer n real a(500) print *, 'Введите n ' ! На экране появится сообщение: Введите n read *, n ! Используем для В/В циклический список read *, (a(i), i = 1, n) ! Потребуется ввести с клавиатуры n значений print *, (a(i), i = 1, n) ! Контрольный вывод на экран Выполним ввод: 3 (После ввода значения для n нажимаем Enter) 1 2 3 (Отдельные значения разделяются пробелом) Результат вывода: 1.00000 2.000000 3.000000 Замечания: 1. В качестве разделителя задаваемых при вводе значений можно использовать и запятые или запятые вместе с пробелами, например: 1, 2, 3 2. В вышеприведенном операторе PRINT указан русский текст. Однако если не принять специальных мер, то в DOS-окне, в которое этот текст направляется при работе с консоль-проектами, будут выведены совсем другие символы: -тхфшЄх n Чтобы избежать таких искажений, необходимо в программе, выводящей русский текст в DOS-окно, выполнить ссылку use TextTransfer обеспечить доступ к модулю TextTransfer и выполнить перекодировку текста, применив, имеющуюся в модуле TextTransfer функцию RuDosWin, записав вместо print *, 'Введите n ' 17 О. В. Бартеньев. Современный ФОРТРАН оператор print *, trim(RuDosWin('Введите n ', .false.)) Текст модуля TextTransfer и правила его употребления приведены в прил. 1. В дальнейшем, однако, при использовании русского текста в операторе вывода обращение к RuDosWin явно выполняться не будет, но всегда будет подразумеваться. 1.8.1. Некоторые правила ввода Для рассмотрения правил ввода введем ряд понятий. Запись текстового последовательного файла - строка символов, завершаемая символом новой строки. Поле записи файла - часть записи, содержащая данные, которые могут быть использованы оператором ввода. Файл состоит из записей и завершается специальной записью "конец файла". При вводе с клавиатуры при необходимости можно проставить запись "конец файла", нажав Сtrl + Z, например: integer ios real x do ! Цикл продолжается до нажатия Сtrl + Z print '(1x, a, $)', 'Enter x ' ! Вывод подсказки; выполняется без продвижения read(*, *, iostat = ios) x ! После Сtrl + Z будет введена запись "конец файла", if(ios == -1) exit ! ios примет значение -1 и произойдет выход из цикла print *, 'x = ', x end do Ввод под управлением списка выполняется по правилам: • поля записи могут разделяться пробелами и запятой; • если между полями записи присутствует слеш (/), то ввод прекращается; • каждый оператор ввода (если не задан спецификатор ADVANCE = 'NO') выполняет ввод с начала новой записи. Например, при вводе read *, x, y, z можно обойтись одной записью, например: 1.1 2.2 3.3 тогда как при вводе read *, x read *, y read *, z уже потребуется 3 записи, например: 18 1. Элементы языка 1.1 2.2 3.3 Причем если создать, например, в первой строке больше полей ввода: 1.1 4.4 5.5 2.2 3.3 то поля с символами 4.4 и 5.5 будут в последней версии ввода проигнорированы и по-прежнему после ввода: x = 1.1, y = 2.2, z = 3.3; • если число элементов списка ввода больше числа полей записи, то для ввода недостающих значений оператор ввода перейдет к следующей записи; • для ввода значения логической переменной достаточно набрать T или F. Ошибки ввода возникают: • если число элементов списка ввода больше числа доступных для чтения полей записи (т. е. если выполняется попытка чтения записи "конец файла" и за пределами файла); • если размещенные на читаемом поле символы не могут быть приведены к типу соответствующего элемента списка ввода. Пример: read *, k Ошибка ввода последует, если, например, ввести k = 2 Правильный ввод: 2 1.8.2. Ввод из текстового файла Ввод с клавиатуры даже сравнительно небольшого объема данных - достаточно утомительное занятие. Если, например, на этапе отладки вы многократно запускаете программу, то работа пойдет гораздо быстрее при вводе данных из файла. Пусть надо определить вещественные переменные x, y и z, задав им при вводе значения 1.1, 2.2 и 3.3. Создадим файл a.txtв том же месте, откуда выполняется запуск программы, и занесем в него строку 1.1 2.2 3.3 Программа ввода из файла: real x, y, z open(2, file = 'a.txt') ! 2 - номер устройства В/В 19 О. В. Бартеньев. Современный ФОРТРАН read(2, *) x, y, z ! Ввод из файла a.txt print *, x, y, z ! Вывод на экран end Оператор OPEN создает в программе устройство В/В и соединяет его с файлом a.txt. Далее в операторе READ вместо первой звездочки используется номер устройства, что обеспечивает ввод данных их файла, который с этим устройством связан. Правила ввода из текстового файла и с клавиатуры совпадают, поскольку клавиатура по своей сути является стандартным текстовым файлом. 1.8.3. Вывод на принтер Принтер, как и клавиатуру, можно рассматривать как файл, который может быть подсоединен к созданному оператором OPEN устройству. Тогда программа вывода на принтер может выглядеть так: real :: x = 1.1, y = 2.2, z = 3.3 open(3, file = 'prn') ! Подсоединяем принтер к устройству 3 write(3, *) x, y, z ! Вывод на принтер write(*, *) x, y, z ! Вывод на экран end 1.9. Рекомендации по изучению Фортрана Изучение языка программирования помимо чтения и разбора приведенного в книгах и пособиях материала включает и выполнение многочисленных, часто не связанных с практической деятельностью задач. Преимущественно такие задачи должны быть придуманы вами самостоятельно, поскольку постановка задачи помогает пониманию материала столь же эффективно, как и процесс ее анализа и решения. К составлению и выполнению тестовых задач следует приступить начиная с первого дня изучения материала. Предположим, что прочитано несколько страниц 1-й главы. В соответствии с материалом вами набрана и запущена программа program p1 real x, y, z x = 1.1 y = 2.2 z = x + y print *, 'z = ', z end Какие дополнительные шаги в рамках изучения языка могут быть предприняты? Возможно, следующие: • выполним инициализацию переменных в операторе объявления: |