Главная страница

Курс лекций по дисциплине Программирование на языке Фортран


Скачать 0.98 Mb.
НазваниеКурс лекций по дисциплине Программирование на языке Фортран
Дата02.09.2019
Размер0.98 Mb.
Формат файлаdoc
Имя файлаFortran01.doc
ТипКурс лекций
#85698
страница3 из 15
1   2   3   4   5   6   7   8   9   ...   15

Операторы языка Fоrtran

  1. Порядок следования операторов

Язык Fоrtran требует определенного порядка следования операторов и строк, составляющих программную единицу. Процедура начинается с оператора либо SUBROUTINE, либо FUNCTION, либо BLOCK DATA и заканчивается оператором END. Основная программа начинается с оператора PROGRAM или любого другого оператора, отличного от операторов SUBROUTINE, FUNCTION или BLOCK DATA, и заканчивается оператором END. Процедура и основная программа являются программными единицами. Правила следования операторов:

1. Оператор PROGRAM, если он есть или оператор SUBROUTINE, FUNCTION, BLOCK DATA должны быть первым оператором программной единицы;

2. Оператор FORMAT может встретиться в любом месте после оператора SUBROUTINE, FUNCTION,BLOCK DATA или PROGRAM, если он есть;

3. Все операторы определения типов должны предшествовать операторам DATA, операторам-функциям и выполняемым операторам;

4. Все операторы DATA должны стоять после операторов определения типов. Операторы DATA могут быть перемешаны с операторами-функциями и выполняемыми операторами.

5. Обычно оператор PARAMETER предшествует всем другим операторам определения типов. Однако, когда некоторый оператор определяет тип константы, используемой в операторе PARAMETER, оператор PARAMETER должен следовать за этим оператором определения типа;

6. В операторах определения типа оператор IMPLICIT должен предшествовать всем другим операторам, за исключением оператора PARAMETER;

7. Все операторы-функции должны предшествовать всем выполняемым операторам;

8. Метакоманды $DO66, $DECMATH и $STORAGE должны предшествовать любым другим операторам.

метакоманды $DO66,$[NO]FLOATCALLS, $[NO]FREEFORM, $STORAGE

$[NO]DEBUG

$[NO]DECLARE

$DEFINE

$ELSE

$ELSEIF

$ENDIF

$IF

$INCLUDE

$LINESIZE

$[NO]LIST

$[NO]LOOPOPT

$MESSAGE

$PACK

$PAGE

$PAGESIZE

$[NOT]STRICT

$SUBTITLE

$TITLE

$[NO]TRUNCATE

операторы PROGRAM,FUNCTION, BLOCK DATА,SUBROUTINE

$[NOT]LARGE

без аргументов

оператор IMPLICIT

Операторы PARAMETER

Операторы FORMAT ENTRY,

ENTRY

COMMON, DIMENSION, EQUIVALENCE, EXTERNAL, INTRINSIC SAVE, операторы определения данных $[NOT]LARGE, с аргументом

функции-операторы

операторы

DATA

выполняемые

операторы

оператор END

    1. Общие сведения

Операторы представляют собой набор функций, таких как вычисления, запись результатов вычислений, изменение цепочек управления, чтение и запись файлов и определение информации для компилятора. Операторы Fоrtran разделяются на два основных класса: выполняемые и невыполняемые. Выполняемые операторы вызывают требуемые действия. Невыполняемые операторы никаких действий не вызывают. Вместо этого они определяют, описывают или классифицируют элементы программ, такие как входные точки, данные или программные единицы.

Функциональные категории операторов.

Категория

Описание

Присваивание

Выполняемый. Присваивает величину переменной или элементу массива.

Комментарий

Невыполняемый. Допускает комментарии внутри подпрограммы.

Управления

Выполняемый. Управляет порядком выполнения операторов.

DATA

Невыполняемый. Присваивает начальные значения переменным.

FORMAT

Невыполняемый. Обеспечивает информацию о редактировании данных.

Ввод/вывод

Выполняемый. Определяет тексты и адреса передачи данных и другие особенности ввода/вывода.

Описание

Невыполняемый. Определяет атрибуты переменных, массивов и имен функций программиста.

Функция-оператор

Невыполняемый. Определяет простую, локально используемую функцию.

Заголовок программной единицы

Невыполняемый. Определяет начало программной единицы и описывает ее формальные параметры.

    1. Операторы описания типов

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

Общий вид синтаксиса описания типа:

Тип имя_пер1 [,имя_пер2]...,

где тип - это один из следующих определителей типа данных: INTEGER, INTEGER*2, INTEGER*4, REAL, REAL*4, REAL*8, DOUBLE PRECISION, COMPLEX, COMPLEX*8, COMPLEX*16, LOGICAL, LOGICAL*2, LOGICAL*4, CHARACTER, CHARACTER*n.

имя_пер - символьное имя переменной, массива, или функции-оператора, или подпрограммы-функции, или оператора объявления массива.

n (в CHARACTER*n) это целое в диапазоне от 1 до 127.

Пример операторов определения типа:

INTEGER COUNT, MATRIX(4,4), SUM /22/ ! Объявление целых, в т.ч. массива 4х4. SUM=22

REAL MAN, IABS ! Объявление вещественных переменных

LOGICAL SWITCH /.TRUE./ ! Переменная логического типа, с начальным значением .TRUE.

INTEGER*2 Q, M12*4, IVEC(10)*4 ! Объявление целых переменных Q(2 байта), M12(4 байта), целого массива (каждый элемент 4 байта)

CHARACTER NAME*10, CITY*80, CH ! Объявление символьных переменных

Оператор определения типа может подтверждать или отвергать неявный тип имени. Оператор определения типа может также определить размер. Пользовательское имя переменной, массива, внешней функции или функции-оператора может упоминаться в операторе определения типа. В этом случае тип этого имени определен во всей программной единице. В программной единице оператор определения типа однозначно определяет тип имени. Оператор определения типа может также подтвердить тип встроенной функции, но это не обязательно. В операторе определения типа не может встретиться имя подпрограммы или основной программы. К оператору определения типа применимы следующие правила:

1. Оператор определения типа должен предшествовать всем выполняемым операторам.

2. Тип данных с символьным именем может быть точно описан только однажды.

3. Оператор определения типа не должен иметь метки.

4. Оператор определения типа может описывать массив добавлением описателя размерности к имени массива.

За символьным именем может следовать определитель длины типа данных в виде *длина, где длина - одна из доступных типов длин для провозглашенного типа данных. Такое описание отменяет атрибут длины, который подразумевался оператором определения типа, и присваивает новую длину описываемому объекту. Если присутствуют как описатель длины типа, так и описатель массива, описатель длины типа должен быть последним.

      1. Оператор описания целого типа INTEGER

INTEGER { [*bytes] ¦ [{ C }] } vname [{attrs}] [*length] [(dim)] [ /values/ ] [,vname [{attrs}] [*length] [(dim)] [ /values/ ]]

*bytes - длина целой переменной в байтах. Целое 1,2 или 4.

C - определяет целое в формате языка Си.

vname - имя целой переменной может быть константой, переменной, именем массива, внешней или внутренней функцией, оператором-функцией. Параметр не может быть именем подпрограммы или именем головной программы.

attrs - атрибуты целой переменной, разделенные запятыми. Атрибут описывает vname. Допускается применение следующих атрибутов: ALLIAS, ALLOCATABLE, C, EXTERN, FAR, HUGE, NEAR, PASCAL, REFERENCE, VALUE. Атрибутами задается дополнительная информация о переменной, типа переменной, подпрограмме, или об аргументе подпрограммы. Они могут, использоваться в описании подпрограмм, после описания типа, и в операторах INTERFACE. Атрибуты пишутся после объекта, на который они ссылаются.

dim - размерность массива целых переменных.

length - длина левой целой переменной. Беззнаковая целая константа 1,2 или 4.

values - заданное значение целой переменной. Список констант или повторяющиеся константы (n*cоnst, где n - число повторений), разделенные запятыми.

Пример. INTEGER*2 a, b*4, c(11)/11*0/, d/-5/

      1. Оператор описания вещественного типа REAL

REAL [*bytes] vname [{attrs}] [*length] [(dim)] [ /values/ ] [,vname [{attrs}] [*length] [(dim)] [ /values/ ]] ...

*bytes - длина вещественной переменной в байтах. Целое 4 или 8.

vname - имя вещественной переменной может быть константой, переменной, именем массива, внешней или внутренней функцией, оператором-функцией. Параметр не может быть именем подпрограммы или именем головной программы.

attrs - атрибуты вещественной переменной, разделенные запятыми. Атрибут описывает vname. Допускается применение следующих атрибутов: ALLIAS, ALLOCATABLE, C, EXTERN, FAR, HUGE, NEAR, PASCAL, REFERENCE, VALUE.

dim - размерность массива целых переменных.

length - длина левой вещественной переменной.

Пример. REAL*4 a, b*8, c(11)/11*0./, d/-5.0/

      1. Оператор описания логического типа LOGICAL

LOGICAL [*bytes] vname[{attrs}][*length][(dim)][ /values/ ] [,vname[{attrs}][*length][(dim)][ /values/ ]] ...

*bytes - длина логической переменной в байтах. Целое 1,2 или 4.

vname - имя логической переменной (см. также INTEGER)

attrs - атрибуты логической переменной, разделенные запятыми. Атрибут описывает vname. Допускаемые атрибуты – см. INTEGER.

dim - размерность массива логических переменных.

length - длина левой логической переменной. Беззнаковая целая константа 1,2 или 4.

Пример. LOGICAL flag/.TRUE./, lоgmas(9)

      1. Оператор описания символьного типа CHARACTER

CHARACTER [*bytes] vname [{attrs}] [(dim)] [*length] [ /values/ ] [,vname [{attrs}] [(dim)] [*length] [ /values/ ] ...

*bytes - длина символьной переменной в байтах. Целое в диапазоне от 1 до 32767, или целое выражение, заключенное в скобки, или звездочка в скобках (*).

vname - имя символьной переменной может быть константой, переменной, именем массива, внешней или внутренней функцией, оператором-функцией. Параметр не может быть именем подпрограммы или именем головной программы.

attrs - атрибуты символьной переменной, разделенные запятыми. Атрибут описывает vname. Допускается применение следующих атрибутов: ALLIAS, ALLOCATABLE, C, EXTERN, FAR, HUGE, NEAR, PASCAL, REFERENCE, VALUE.

dim - размерность массива символьных переменных.

length - длина левой символьной переменной. Беззнаковая целая константа в диапазоне от 1 до 32767, целое выражение в скобках (не выходящее за диапазон), или звездочка (*).

values - заданное значение символьной переменной. Список констант или повторяющиеся константы (n*cоnst, где n - число повторений), разделенные запятыми.

Пример: CHARACTER*5 wоrd /'пример ввода текстовой переменной'/

    1. Система ввода-вывода

      1. Записи

Основной единицей в файлах MS_FORTRAN является запись. Запись - это набор знаков или значений. Допускаются записи трех видов: форматные записи, бесформатные записи и записи конца файла.

1. Форматные записи. Форматные записи - это набор знаков, заканчивающихся системным признаком конца строки. Форматные записи интерпретируют согласно с тем, как большинство операционных систем и файлов интерпретируют строку.

2. Бесформатные записи. Бесформатные записи - это набор значений, не преобразуемых системой. Бесформатные файлы хранятся в виде физических записей. Двоичные файлы содержат только значения во внутреннем представлении и исходя из этой информации нельзя, в общем случае, определить структуру записи.

3. Запись конца файла. После последней записи в файле MS_FORTRAN инициирует запись конца файла. Метод представления конца файла частично зависит от операционной системы.

      1. Файлы

Файл - это последовательность записей. Файлы бывают внешние и внутренние.

1. Внешний файл ‑ это либо файл на внешнем устройстве, либо само устройство или поименованная область во внешней памяти ЭВМ.

2. Внутренний файл ‑ знаковая переменная служащая источником или целью для какой-либо формальной операции ввода/вывода (или по другому – символьная строка (подстрока) или массив). B дальнейшем внутренние файлы MS_FORTRAN, а так же файлы, доступные для операционной системы, именуются просто "файлы". Оператор OPEN обеспечивает связь между двумя понятиями файла, в большинстве случаев неопределенность исчезает после открытия файла, когда оба понятия совпадают.

1) Характеристики файлов

Файлы Фортрана имеют следующие атрибуты:

1. Имя.

2. Положение.

3. Структуру (форматные, бесформатные или двоичные).

4. Метод доступа (последовательный или прямой).

1. Имя файла. Файл может иметь имя. Имя, если оно присутствует, - это последовательность знаков, используемая операционной системой для распознавания файлов. Правила именования определяются операционной системой.

2. Положение файла. Положение файла обычно устанавливается предшествующим положением ввода/вывода. Файл имеет: начальную точку, конечную точку, текущую запись, предыдущую запись и следующую запись. Возможно, что последующая запись идет за предыдущей, а текущей записи нет. При открытии файла устанавливается его начало. Если следующей операцией ввода/вывода являются WRITE (запись), все старые данные затираются. Положение файла после последовательного выполнения операций WRITE - конец файла, но не за пределом записи конца файла. Использование оператора ENDFILE (конец файла) помещает файл за записью конца файла, то же делает и оператор READ, выполняемый в конце файла. Вы можете определить конец файла, используя выражение END= в операторе READ (чтение).

3. Структура файлов. Внешние файлы могут быть открыты как форматные, бесформатные или двоичные файлы. Все внутренние файлы являются форматными.

(1) Форматные. Файлы, состоящие только из форматных записей (текстовые, ASCII).

Текстовый файл содержит символьное представление данных всех типов. При работе с текстовыми файлами используется форматный или управляемый списком ввод/вывод. При выводе данные из внутреннего представления преобразовываются во внешнее символьное представление. При вводе происходит обратное преобразование из символьного представления во внутреннее. При выводе в конце каждой записи Fortran проставляет два неотображаемых символа Char(13) – возврат каретки и Char(10) – новая строка. Записи последовательного текстового файла могут быть разной длины.

Если при форматном вводе не использован дескриптор \, то после завершения ввода файловый указатель перемещается на начало следующей записи (или позиционируется в конец файла), даже если были прочитаны не все поля текущей записи. Использование символа \ обеспечивает ввод без продвижения.

(2) Бесформатные. Файлы, состоящие только из бесформатных записей.

В неформатные файлы, так же как и в двоичные, данные передаются без преобразований. Однако в неформатном файле, в отличие от двоичного записью является не байт, а совокупность данных, выводимых в файл в результате выполнения оператора вывода Write. Каждый оператор вывода создает одну запись. Записи файла могут иметь разную длину. Каждая запись завершается символом конца записи.

В неформатных файлах при чтении записи ri нельзя ввести число байт, превышающее число байт в этой записи (это приведет к ошибке выполнения и прерыванию программы). Выполнение каждого оператора ввода, даже если число вводимых байт меньше числа байт записи, приведет к позиционированию файла вслед за прочитанной записью.

Пример управления файловым указателем в последовательном неформатном файле

Integer*2 ia, ib, d(4)/1,2,3,4/

Real*4 a

Character*3 ca

Open(1, file=’a.dat’, form=’unformatted’) ! Открытие неформатного файла

Write(1) 1.1, 2.2 ! Запись №1

Write(1) d ! Запись №2

Write(1) ‘aaa’, ‘bbb’, ‘ccc’ ! Запись №3

Rewind 1 ! Репозиционирование файлового указателя в начало файла

Read(1) a, a

Read(1) ia, ia, ia, ia ! Соблюдение соответствия между вводом и выводом

Read(1) ca, ca

backspace 1 ! Переход в начало 3-ей записи

backspace 1 ! Переход в начало 2-ой записи

read(1) ib, ib

print *, a, ia, ca, ib ! 2.200000 4bbb 2

rewind 1 ! Переход в начало файла

read(1) a ! Переход в начало 2-ой записи

write(1) ‘ghi’ ! Замена 2-й и 3-ей записей на ghi

rewind 1 ! В начало

read (1) a, a ! Первое значение затирается вторым

read (1) ca ! В файле осталось 2 записи: числа 1.1 и 2.2 и строка ghi

print *, a, ca ! 2.200000ghi

(3) Двоичные (бинарные). Последовательность байтов без внутренней структуры. При работе с двоичными файлами обмен данными выполняется без их преобразования. При записи в двоичный файл в него фактически копируется содержимое ячеек оперативной памяти. При чтении, наоборот, последовательность байтов двоичного файла передается в ячейки оперативной памяти, отведенные под элементы ввода. В Fortran число записей в двоичном файле равно числу переданных байт, поэтому выполнение оператора BACKSPACE приведет к перемещению на 1 байт назад. Между записями последовательного двоичного файла не проставляется символов (в отличие от неформатного, текстового или двоичного прямого доступа файлов). Ввод из двоичного файла значения переменной val, занимающей в оперативной памяти n байт, вызовет перемещение файлового указателя в двоичном файле на n записей (байт).

Пример управления файловым указателем в двоичном последовательном файле

Integer*2 ia, ib, d(5)/1,2,3,4,5/, i

Real*4 a

Character*3 ca

Open(1, file=’a.dat’, form=’binary’) ! Открытие двоичного файла

Write(1) 1.1, 2.2 ! Запись в файл 8 байт

Write(1) d ! Добавление в файл 10 байт

Write(1) ‘aaa’, ‘bbb’, ‘ccc’ ! Добавление еще 9 байт

Rewind 1 ! Репозиционирование файлового указателя в начало файла

Read(1) a, a, (ia, i=1, 5), ca, ca ! Чтение 24 байт из 27

Do 2 i=1, 10

2 backspace 1 ! Перемещение назад на 10 записей (байт)

read(1) ib ! Чтение с 15-го байта

write(*,*) a, ia, ca, ib ! Вывод: 2.200000 5bbb 4

rewind 1

read(1) a ! Файловый указатель переместился на 5-й байт

write(1)’ghi’ ! Замена 5, 6 и 7-го байта

rewind 1 ! Затирание всех последующих записей

read(1) a, ca

write(*,*) a, ca ! Вывод: 1.100000ghi (в файле 7 байт данных)

Любой внешний файл (неформатный, текстовый прямого и последовательного доступа) может быть открыт как двоичный, например, с целью копирования данных.

4. Методы доступа. Внешние файлы открываются как файлы последовательного либо прямого доступа.

(1) Последовательный доступ. Файлы, содержащие записи, порядок следования которых определен порядком, в котором они были записаны (нормальный последовательный порядок). Эти файлы не могут быть прочитаны или записаны с помощью выражения REC= (определяет позицию прямого доступа). В последовательном файле возможно лишь чтение и добавление записей. Модифицировать существующую запись непосредственно в последовательном файле нельзя. Для изменения записи возможен такой путь: прочитать все записи файла в массив, изменить в нем нужную запись, перейти на начало файла и записать массив в файл.

(2) Прямой доступ. Файл, записи которого могут быть записаны или прочитаны в любом порядке (файл с произвольным доступом). Записи последовательно нумеруются, первая запись имеет номер 1. Записи имеют одинаковую длину, определяемую при открытии файла, каждая запись имеет собственный номер, определяемый при записывании записи. B файлах прямого доступа возможно занесение записей в произвольном порядке (например, 9,5 и 11) без занесения записей между ними. Невозможно удаление записанной записи; однако запись можно переписать, новым значением.

Чтение записей из файлов прямого доступа не имеющих записей приводит к ошибке. Файлы прямого доступа находятся на диске. Операционная система пытается расширить файл прямого доступа, если предыдущая запись выходит за установленные ранее границы, удача этой операции определяется наличием физического пространства на носителе.

В Fortran можно создать двоичные, неформатные и форматные (текстовые) файлы прямого доступа. При этом в случае неформатного и текстового файлов число считываемых из файла байт и добавляемых в файл байт одним оператором ввода/вывода не должно превышать длины записи. В случае вывода недостающие байты записи будут содержать null-символы (Char(0)). В файле прямого доступа можно перейти в начало любой записи ri, выполнив оператор Read, в котором задан параметр Rec=ri-1. Чтобы удалить ненужные хвостовые записи файла прямого доступа, следует переместиться в начало первой удаляемой записи файла (обычно с помощью Read), а затем применить оператор EndFile.

Двоичный и неформатный файлы прямого доступа имеют структуру, совпадающую со структурой двоичного последовательного файла. Однако в двоичном файле прямого доступа длина записи определяется параметром recl, и не равна 1 байту, как в последовательном двоичном файле. После каждой записи двоичного и неформатного файлов прямого доступа проставляются разделители – два null-символа. Файлы прямого доступа могут быть открыты как двоичные последовательные файлы.

Отличия между неформатными и двоичными файлами прямого доступа.

В двоичный файл прямого доступа можно записывать любое число байт, не обращая внимания на значение параметра recl (при этом длина записи все же определяется параметром recl); из двоичного файла одним оператором ввода можно считать больше байт, чем задано параметром recl.

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

2) Особенности внутренних и внешних файлов

Внутренний файл ‑ символьная переменная или элемент символьного массива. Файл содержит только одну запись, совпадающую по длине с символьной переменной или элементом массива. Если внутренний файл – символьный массив, то число его записей равно числу элементов.

Внутренние файлы являются открытыми по умолчанию. Если записывается не вся запись, оставшееся место заполняется пробелами. Положение файла всегда в начале файла, до выполнения операторов ввода/вывода. Внутренние файлы позволяют только форматный, последовательный ввод/вывод; внутренний файл могут определять только операторы ввода/вывода READ и WRITE. Внутренние файлы обеспечивают механизм для использования форматных возможностей системы ввода/вывода для преобразования значений "в" и "из" представления внешних символов во внутренние структуры памяти MS_Фортрана. Так чтение символьных переменных преобразует символьные значения в числовые, логические или символьные значения, а запись символьных переменных позволяет преобразовать числовые значения в их (внешнее) символьное представление.

Редакционная спецификация обратный слеш (\) не может быть использована во внутренних файлах.

Пример преобразования типов данных с использованием внутреннего файла.

Character*12 val ! Объявление символьной переменной

...

write(val,’(f12.2,1x)’) (a-b)/2 ! Запись значения выражения во внутренний файл (символьную переменную), тем самым производится ее преобразование из числового типа в символьное.

Пример преобразования типов

Real a/234.55/

Integer kb

Character*20 st

Write(st,*) a ! Преобразование число - строка

Print*, st ! 234.550000

Read(st,’(i2)’) kb ! Преобразование строка - число

Print*, kb ! 23

Внешний файл – поименованная область во внешней памяти ЭВМ. Внешние файлы могут быть открыты как для монопольного доступа, так и для разделенного (сетевого) доступа. Можно создать временный (scratch) внешний файл, который будет удален с устройства либо после закрытия файла, либо при нормальном завершении программы. При разделенном доступе внешний файл можно полностью или частично заблокировать (сделать недоступным для использования другим процессом).

3) Устройства

Устройство является средством обращения к файлам. Устройство определяется в операторе ввода/вывода как внешнее или внутреннее. К устройствам ввода/вывода могут быть подсоединены внешние и внутренние файлы, а также физические устройства, например, клавиатура, экран, принтер, параллельный порт.

Внешний файл подсоединяется к устройству ввода/вывода в результате выполнения оператора OPEN. Номером устройства является целочисленное выражение, значение которого должно находиться в интервале от 0 до 32767. После подсоединения и устройство, и файл считаются открытыми. Доступ к файлу после его открытия выполняется по номеру устройства, к которому он подсоединен: все программные компоненты, ссылающиеся на один и тот же номер устройства, ссылаются на один и тот же файл. Устройство не может быть одновременно подсоединено более чем к одному файлу, так же и файл не может быть одновременно подсоединен более чем к одному устройству.

1. Определение внешнего устройства. Спецификацией внешнего устройства является целое выражение или символ * (определяет экран для вывода и клавиатуру для ввода). B большинстве случаев, спецификация внешнего устройства связана с физическим устройством (или файлом, имеющимся на устройстве) с помощью имени при использовании оператора OPEN. При такой связи устройства с системным именем файла операторам ввода/вывода MS_FORTRAN достаточно номера устройства для обращения к соответствующему внешнему устройству. Если файл открыт, значение, определяющее внешнее устройство, будет связано с конкретным внешним устройством до тех пор, пока не используют операцию CLOSE, или пока не окончится программа. Единственным исключением из этих правил является то, что нулевое устройство связывается с клавиатурой для чтения и экраном для записи, и не требуется явного оператора OPEN. Система файлов MS_Фортрана интерпретирует символ *, как нулевое устройство.

2. Определение внутреннего устройства. Спецификацией внутреннего устройства является символьная переменная или символьный массив непосредственно определяющий внутренний файл.

4) Наиболее широко используемые структуры файлов

B MS_Фортране возможно множество комбинаций структур файла. Однако, для большинства применений достаточно двух:

1. * файлы.

2. Именованные, внешние, последовательные, форматные файлы.

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

Внешние файлы могут быть связаны с системным именем одним из следующих методов:

1. Если файл явно открыт, имя может быть приведено в операторе OPEN.

2. Если файл явно открыт и имя определено пробелами, имя читается из управляющей строки (если имеется). Если командная строка отсутствует или не содержит имени, пользователь получит запрос об имени.

3. Если файл открыт неявно (операторами REAL и WRITE) имя определяется согласно методу пункта 2, описанного в предыдущем параграфе.

4. Если файл явно открыт и имя отсутствует в операторе OPEN, этот файл считается временным или вспомогательным файлом, принимающим имя, заложенное в компиляторе.

Ниже приведен пример программы, использующей для чтения и записи * файлы, а так же именованные, внешние, последовательные форматные файлы. Операторы ввода/вывода пишутся в этой части заглавными буквами.

Пример копирования файла с тремя колонками целых переменных (каждая колонка по 7 позиций) из файла,
имя которого введено пользователем, в файл с именем OUT.TXT с перестановкой первой и второй колонок.

PROGRAM COLSWP

CHARACTER*64 FNAME

WRITE (*, 900) ! Вывод сообщения на экран

900 FORMAT ('Введите имя входного файла'\)

READ(*, 910) FNAME ! Считывание вводимого имени файла с клавиатуры по формату 910

910 FORMAT(A) ! А - дескриптор символьного типа

OPEN (3, FILE=FNAME) ! Открытие устройства 3 (номер любой, кроме 0), связанного с файлом

OPEN (4,FILE='OUT.TXT', STATUS='NEW') ! Открытие устройства 3 (номер любой, кроме 0 и 3), связанного с файлом OUT.TXT

100 READ (3,920,END=200)I,J,K ! Считывание до конца файла по формату 920 (3 целых числа по 7 позиций)

WRITE (4,920) J, I, K ! Запись в файл, связанный с устройством 4

920 FORMAT (3I7) ! 3 целых числа по 7 позиций, I – дескриптор целого типа.

GO TO 100 ! Цикл до достижения конца файла

200 WRITE (*,910)' Копирование выполнено '

END

Пример демонстрации открытия файлов

Integer k/2/, m/4/ ! Номер устройства – целочисленное выражение

Open(k*m,file=’d:\a.txt’) ! Файл d:\a.txt подсоединен к устройству 8

Open(k,file=’d:\b.txt’) ! Файл d:\b.txt подсоединен к устройству 2

Write(8,’(I8)’) k ! Запись в файл d:\a.txt

Write(m-k,’(I2)’) m ! Запись в файл d:\b.txt

Close 8 ! Закрытие устройства 8 и файла d:\a.txt

Close (k) ! Закрытие устройства 2 и файла d:\b.txt

Выбор типа файла. Двоичные и неформатные файлы имеют очевидные преимущества перед текстовыми. 1) передача данных выполняется быстрее, поскольку нет потерь на преобразование данных. 2) в текстовых файлах из-за округления могут возникнуть потери точности. 3) программирование двоичного и неформатного ввода/вывода проще, чем форматного. 4) двоичные и неформатные файлы, как правило, имеют меньший размер, чем текстовые файлы с теми же данными. Однако, текстовые файлы содержат данные в пригодной для чтения форме и также используются для обмена данными между программами, в том числе работающими в различных операционных системах (например, DXF файл программы AutoCAD).

5) Старые и новые файлы

Открытый файл Ms Fortran является либо OLD (старым), либо NEW (новым), но "открытые для чтения" не отличаются от "открытых для записи". Следовательно, можно открывать старые (уже существующие) файлы и записывать в них заново. Можно так же попеременно записывать и считывать данные одного и того же файла (но не за пределами конца файла, и не считывать незаписанные записи в файле прямого доступа). Запись в последовательный файл уничтожает любые записи после вновь записываемых.

Когда устройство, подобное клавиатуре или печати, открыто, как файл, то обычно не имеет значения, является ли этот файл OLD или NEW. Но для файлов на диске, однако, открытие файла NEW, создает новый файл:

1. Если у предыдущего файла было такое же имя, то он стирается.

2. Если новый файл закрыт с помощью STATUS='KEEP', или если программа заканчивается без выполнения над файлом операции CLOSE, то создается постоянный файл с именем, данным, при открытии.

6) Ограничения в использовании системы ввода-вывода

1. Связь файлов прямого доступа с устройствами прямого доступа. Существует два вида устройств: последовательные и прямые. Файлы, связанные с последовательными устройствами, представляют собой последовательность символов; никакого явного действия, кроме чтения и записи, не допускается. K последовательным устройствам относится клавиатура, экран, печать.

Прямые устройства, такие как диски, имеют дополнительную задачу поиска адреса. Доступ к прямым устройствам может быть как последовательным, так и произвольным, это соответствует файлам прямого доступа. Система ввода/вывода MS_FORTRAN не допускает файлов прямого доступа на последовательных устройствах.

2. Связь BACKSPACE/BINARI (операция возврата/двоичный последовательный файл). B двоичном последовательном файле не указываются границы записи, следовательно, операция BACKSPACE в таком файле означает возврат одного байта. Файл прямого доступа содержат записи постоянной, определенной длины, следовательно, возможно возвращаться к записям бесформатных файлов прямого доступа.

3. Частичное считывание двоичного файла. Длина данных, считываемых из двоичного файла, должна соответствовать длине записываемых данных бесформатных последовательных файлов. Bнутреняя структура позволяет считывать часть записи или вообще не считывать ее (несчитанная запись пропускается).

4. Побочные влияния вызванных функций на операторы ввода/вывода. При выполнении какого-либо оператора ввода/вывода вычисление выражения может привести к вызову функции. Такой вызов функции не должен приводить к выполнению оператора ввода/вывода.

    1. Операторы ввода-вывода

Различные операторы ввода/вывода имеют параметры и аргументы, определяющие источники и цели передачи данных, а так же другие особенности операции ввода/вывода. Элементы ввода-вывода:

1. Спецификация устройства.

2. Спецификация формата.

3. Список ввода/вывода.

1. Спецификация устройства в операторе ввода/вывода может принимать одну из следующих форм:

1) *спецификация

WRITE (*,*) 'Начало вывода' ! Первая * относится к клавиатуре или к экрану и определяет устройство.

2) целое выражение.

WRITE (10,*) 'файл 10:'

Целое число относится к внешнему файлу, который связан с номером устройства 10 (* означает устройство номер ноль). Допустимы спецификации устройства в диапазоне от -32767 до 32767.

3) Имя знаковой переменной или элемента знакового массива.

CHARACTER*10 STRING

WRITE (STRING,'(I10)')IVAL ! Значение Ival присваивается переменной String. Ival имеет целый тип, происходит преобразование значения в символьный тип.

Знаковая переменная STRING относится к внутреннему файлу. Ранее в данной части описывались различия между спецификациями внешних и внутренних устройств. Значение переменной IVAL присваивается переменной STRING с преобразованием в символьный тип.

2. спецификация формата в операторе ввода/вывода может принимать одну из следующих форм:

1) Метка оператора.

WRITE (*,990) I,J,K

990 FORMAT (1X,2I5,I3) ! Метка оператора 990 отсылает к оператору FORMAT с меткой 990.

2) Имя целой переменной.

ASSIGN 990 TO IFMT

990 FORMAT (1X,2I5,I3)

WRITE (*,IFMT) I,J,K ! B операторе WRITE целая переменная IFMT отсылает к метке 990 оператора FORMAT, которая была ей присвоена непосредственно перед оператором FORMAT.

3) Символьное выражение.

WRITE (*,'(1X, 2I5,I3)') I, J, K

значением символьного выражения является спецификация формата.

4) Символьная переменная.

CHARACTER * 11 FMTCH

FMTCH = ' (1X, 2I5,I3)'

WRITE (*, FMTCH) I, J, K ! Оператор WRITE использует содержание символьной переменной FMTCH в качестве спецификации формата.

Пример создания строки формата, необходимой для вывода наперед неизвестного количества чисел.

Character*1 val

...

write(5,*) ‘Введите количество n<9 чисел’

read(5,*) n

write(5,1) ‘Введите’,n,’чисел’

1 format(a,1x,i1,1x,a) ! 1x – отступ одного пробела от последней позиции

Read (5,*) (a(i),i=1,n)

Write(val,’(i1)’)n ! Перевод числа n в символьный тип

Frm=val//’i2,2x’ ! Создание строки формата

Write(5,Frm) (a(i),i=1,n) ! Вывод n чисел в строку через 2 пробела

5) * спецификация.

WRITE (*,*) I,J,K ! Выражение * указывает на передачу данных при вводе/выводе списком.

3. список ввода/вывода определяет данные, значения которых передаются операторами RЕAD и WRITE. Список ввода/вывода может быть и пустым, но обычно состоит из входных/выходных данных и включает в себя списки неявного DO, разделенные запятыми. Входные данные могут быть определены в списке ввода/вывода оператора READ, а выходные - в списке оператора WRITE.

Входные данные представляют собой переменное имя, имя элемента массива или имя массива. Имя массива определяет все элементы массива, последовательно расположенные в памяти.

Выходные данные могут иметь такой же вид, как перечисленные входные данные, но могут принимать вид выражений, не начинающихся знаком открытой скобки "(". (Левая открытая скобка служит для отличия списков DO от выражений).

Чтобы отличить выражение от неявного списка DO, выражение (A+B)*(C+D) можно записать так:

+(A+B)*(C+D)

Неявные списки DO можно определить, как данные в списке ввода/вывода операторов READ и WRITE. Они имеют следующий формат:

список_ввода/вывода, переменная=выраж1,выраж2[,выраж3])

Пример: write(5,*) (a(x), x=xStart, xEnd, xStep)

список_ввода/вывода определен так же, как и элементы оператора ввода/вывода (включая списки внутреннего неявного DO).

переменная, выраж1, выраж2 и выраж3 определены так же, как и для оператора DO. Переменная является целой переменной, а выраж1, выраж2 и выраж3 - целыми выражениями.

Пример: write(5,*)(q(i), i=1,10,3) ! Вывод q(1), q(4), q(7), q(10)

write(5,*)(b(j), c(j), j=1,3) ! Вывод b(1), c(1), b(2), c(2), b(3), c(3)

write(5,*)((q(i, j), j=1,4), i=1,6) ! Вывод матрицы q по строкам (в памяти матрицы хранятся по столбцам).

B операторе READ переменная DO (или соответствующее данное) не должно появляться в качестве данного списка во внутреннем списке ввода/вывода, но его можно считывать тем же оператором READ перед списком неявного DO. Встроенный список ввода/вывода повторяется для каждой итерации переменной с соответствующей заменой значений переменной DO.

B случае вложенных неявных циклов DO, наиболее глубокий внутренний цикл всегда выполняется первым.

Оператор печати PRINT

Оператор PRINT осуществляет вывод по стандартному направлению.

PRINT {*,¦fоrmаtsрес¦nаmеlist} [,iоlist] fоrmаtsрес - спецификация формата;

nаmеlist - спецификация группового списка имен; iоlist - список ввода/вывода;

Замечание: спецификация формата * обозначает вывод в формате по умолчанию.

Если используется групповой список имен nаmеlist, то не допускается применение списка данных для вывода iоlist. Оператор PRINT выводит данные только на устройство * (по умолчанию). Список данных не может содержать структурные данные, но может иметь структурные элементы.

В списке данных могут использоваться функции, за исключением функций ввода/вывода и встроенной функции EOF.

Пример. PRINT *, ‘Введите n’

Здесь на экране появится сообщение «Введите n».

Оператор печати WRITE

Оператор WRITE осуществляет запись данных в поток вывода (передает данные из объектов списка_ввода/вывода в файл, связанный с указанным устройством).

WRITE ( [UNIT=]определитель_устройства [,{ [FMT = определитель_формата] ¦ [NML = ] nmlsрес }

[,IOSTAT = состояние] [,ERR = метка] [,REC = номер_записи] ) список_ввода/вывода

Где определитель_устройства - это определитель заданного устройства, он должен быть первым параметром.

Определитель_формата требуется, как второй параметр, для форматного WRITE. Не должен появляться для неформатного WRITE. Остальные параметры, если они есть, могут появляться в любом порядке.

Состояние ‑ это целая переменная или элемент целого массива, который присваивается:

а) нуль, если не встретились ошибка или конец файла.

b) машинно-зависимая положительная целая величина, если встретилась ошибка.

с) машинно-зависимая отрицательная величина, если встретится конец файла и не было ошибки.

Пример использования IOSTAT

Write(1,*,IOSTAT=st) (a(x), x=1,n,0.1*(n-1)) ! Запись в файл

If (st.Gt.0) then

Write(5,*) ‘Ошибка при записи’

Else if (st.Lt.0) then

Write(5,*) ‘Запись успешна’

End if

Метка ‑ это необязательная метка оператора. Если ее нет, ошибка ввода/вывода порождает ошибку счета. Если она есть, ошибка ввода/вывода передает управление на заданный выполняемый оператор.

Номер_записи определен только для файлов прямого доступа (в противном случае вызывает ошибку). Это положительное целое выражение, определяющее с какого номера записи в файле производить запись. Первая запись в файле имеет номер 1. Если для файлов прямого доступа номер записи отсутствует, запись продолжается с текущей позиции в файле.

Список_ввода/вывода определяет объекты, чьи величины должны быть переданы оператором WRITE. Список ввода/вывода может быть пустым, но обычно он содержит объекты вывода и неявные циклы, разделенные запятыми.

Особенности. Если запись внутренняя, то адресатом вывода является символьная переменная или массив символьных элементов, определенные как устройство; в противном случае, адресат – это внешнее устройство.

Если файл не был открыт оператором OPEN, подразумевается, что выполняется неявная операция открытия. Эта операция эквивалентна следующему оператору:

OPEN (определитель_устройства,FILE=",STATUS=NEW',ACCESS='SEQUENTIAL',FORM=формат).

Формат - это FORMATTED для форматной записи и UNFORMATTED для неформатного оператора OPEN для понимания действия FILE=параметр.

Пример вывода сообщения "Onе=1, Twо=2, Thrее=3" на экран, не самым простым образом

WRITE (* ,980)'Onе= ',1,1+1,'ее= ',+(1+1+1)

  1. FORMAT (A,I2,Twо= ',1X,I1,Thr',A,I2)

Оператор чтения READ

Осуществляет чтение данных из входного потока или передает данные из файла, связанного с определителем устройства, в объекты списка_ввода/вывода, при условии, что нет конца файла или ошибки.

READ (определитель устройства [,определитель формата] [,IOSTAT=состояние] [,REC=номер записи]

[,END=метка1] [,ERR=метка2]) список_ввода/вывода

Где определитель_устройства - это определитель требуемого устройства, который должен быть первым параметром.

определитель_формата - требуется для формального чтения как второй параметр. Не должен появляться для неформатного чтения. Остальные параметры если они есть, могут появляться в любом порядке.

Состояние – см. WRITE.

номер записи - определен только для файлов прямого доступа если номер записи определен для файла не типа прямого доступа возникнет ошибка. Номер_записи - это положительное целое выражение определяющее положение записи (первая запись в файле имеет номер равный 1) перед началом передачи данных. Если для файла прямого доступа этого параметра нет, чтение продолжится последовательно от позиции в файле.

метка 1 - это необязательная метка оператора в той же самой программной единице, что и оператор READ. Если этот параметр отсутствует, чтение дошедшее до конца файла порождает ошибку счета. Если он есть, встретившееся условие конца файла передает управление на указанный выполняемый оператор.

метка 2 - необязательная метка оператора в той же самой программной единице, что и оператор READ. Если этот параметр отсутствует, ошибка ввода/вывода порождает ошибку счета. Если он есть, ошибка ввода/вывода передает управление на указанный выполняемый оператор.

Список_ввода/вывода ‑ определяет объекты, в которые передаются величины из файла. Он может быть пустым, но обычно содержит объекты для ввода и неявные циклы, разделенные запятыми.

Особенности. Если чтение внутреннее, источником ввода служит символьная переменная или массив символьных элементов; если чтение не внутреннее, источником ввода является внешнее устройство.

Если файл не был открыт оператором OPEN, выполняется операция OPEN по умолчанию. Эта операция эквивалентна выполнению следующего оператора: см. WRITE.

Пример

DIMENSION IA(10,20) ! Описание двухмерного массива

С Чтение в границы массива. Эти границы не превышают 10 и 20 соответственно. Затем чтение в массив
C неявным циклом DO с вводным форматом 8 колонок по 5 цифр.

READ (3,990) IL, JL, ((IA(I,J), J=1, JL), I=1, IL)

990 FORMAT (2I5/,(8I5))

Пример с использованием нескольких операторов:

INTEGER n

REAL а(500)

PRINT *, ‘Введите n ’ ! Вывод сообщения «Введите n » на экран

READ *, n ! Ввод с клавиатуры значения n

READ *, (а(i), i=1,n) ! Ввод с клавиатуры n значений с помощью неявного цикла

PRINT *, (а(i), i=1,n) ! Контрольный вывод введенных значений на экран

В качестве разделителя вводимых с клавиатуры или задаваемых в файле значений можно использовать запятые и/или пробелы. Например, после запуска предыдущей программы и ввода:
3
1 2, 3
получим результат 1.00000 2.00000 3.00000.

Отметим, что при наличии в программе оператора ввода
READ *, х, y, z
три значения можно ввести или в столбик или в строку (через запятую и/или пробел): 1.1, 2.2, 3.3. При наличии же 3-х операторов ввода:
READ *, х
READ *, y
READ *, z
значения необходимо вводить в столбик, т.к. с одной строки считывается только одно значение, а остальные игнорируются.
2.5.5 Оператор цикла с условием DO WHILE

Цикл с условием используется при заранее неизвестном количестве повторений.

Синтаксис:

DO WHILE (logic_expr)

Тело цикла

END DO

logic_expr – логическое тестовое выражение. Тело цикла – набор операторов, выполняемых до тех пор, пока тестовое выражение истинно.

При выполнении оператора DO WHILE выполняется следующая последовательность шагов:

  1. Вычисление логического выражения logic_expr.

  2. Если logic_expr=.FALSE., то тело цикла не выполняется и управление передается на следующий за END DO оператор.

  3. Если logic_expr=.TRUE., то выполняется тело цикла.

  4. По достижении конца тела цикла логическое выражение вычисляется заново и выполнение цикла продолжается.

Пример вычисления суммы знакочередующегося степенного ряда (с точностью  = 10–6):

S(x) =  .

Т.к. погрешность суммы членов {bk } знакочередующегося ряда не превосходят модуля первого отброшенного члена, то условие достижения заданной точности bk < .

Значение последующего члена ряда удобно определять используя предыдущий, а именно его умножением на их отношение:

 =   =   = 
Пропущено
Для определения функции прогибов балки (см. рис.) воспользуемся вариационным методом Ритца–Тимошенко. Сущность данного метода – отыскание функций, удовлетворяющих граничным условиям задачи и минимизирующих потенциальную энергию П системы. Решение представляется в форме ряда, удовлетворяющего граничные условия и содержащего неопределенные параметры, определяемые из системы уравнений.

Функция прогибов в виде сходящегося ряда:



Функция вычисления суммы ряда.

! x - рассматриваемое сечение, n - число учитываемых членов ряда

function Ritc01(x,n)

implicit none

real q ! Распределенная нагрузка

real P ! Продольное усилие

real k ! Коэффициент k*k=P/EI

real EI ! Изгибная жесткость стержня

real L ! Длина стержня

real Ritc01

real pi/3.14159265/

real c1,c2 ! Константы

real x,s/0.0/

integer n,i
L=6; q=4; EI=4635 ! Исходные данные
c1=4.0*q*L**4/(EI*pi**5)

c2=pi*x/L

do i=1,2*n-1,2

s=s+sin(i*c2)/i**5

end do

Ritc01=c1*s

end function

! Тест: однопролетная шарнирно-опертая балка длиной 6м с равномерно-распределенной нагрузкой. q=4кН/м. Сечение прямоугольное 10х30см. Модуль упругости стали E=2.06*10^11Па (EI=4635). Прогиб посередине: f=1.45631072344650см (f=5qL^4/(384EI))

Пример.

Дано уравнение f(x) = 0. Известно, что хотя бы один его корень лежит в интервале [a, b]. Необходимо найти корень x методом бисекции с погрешностью .

! Дано уравнение f(x) = 0. Известно, что хотя бы один его корень лежит в интервале [a, b].

! Необходимо найти корень x методом бисекции с погрешностью eps.

program fx

call fx1

end
subroutine fx1

implicit none

Real a,b,c,f,eps,fa,fc

Write(*,*)'Vvedite granici intervala a,b'

Read(*,*) a,b

if(f(a)*f(b).gt.0) stop 'F ne menyaet znak'

eps=1.0E-5

C=0.5*(a+b)

Do while(abs(b-a).gt.eps) ! Длина интервала больше погрешности

fa=f(a); fc=f(c)

If(fa*fc.le.0)then

B=c

Else

A=c

End if

C=0.5*(a+b)

End do

C=0.5*(a+b)

Write(*,*)'Koren x=',c

end

function f(x)

real f,x

!f=x**3-0.4*x*x+0.9

f=0.2*x**3-0.8*x*x+0.9 ! x1=3.664981; x2=-0.9531585; x3=1.288177

end
Пример решения уравнения f(x) = 0 с использованием многоточечной однопараметрической функции с памятью Многоточечная однопараметрическая ИФ полученная аппроксимацией производной, p = 2. ИД: x0, f(x). (x) = x – ,  0.

Integer itmax/100/

Real y0,bet/-1.0/,p0,f

Write(*,*)’Введите начальное приближение’

Read(*,*)p0

y0=f(p0) ! Начальное значение функции

do while (k.le.itmax)

dp=bet*y0*y0/(f(p0+bet*y0)-y0)

p1=p0-dp ! Последующее приближение

y1=f(p1) ! Последующее значение функции

relerr=abs(dp)/(abs(p1)+small)

if ((relerr.lt.delta).and.(abs(y1).lt.epsilon)) cond=2

p0=p1; y0=y1 ! Предыдущее-->последующее

end do

Write(*,*)’Корень x=’,p1
Многоточечная однопараметрическая ИФ с памятью, p = 1 +  = 2.41. Не использует производные. На каждой итерации параметр уточняется на основе информации с предыдущей итерации, что приводит к "самоускоряющемуся" методу. ИД: x0, f(x).
(xi+1) = xi – f(xi) / Гi , Гi = , i = –1/ Гi . Начальное приближение:
0 = .

2.6 Операторы объявления программных компонентов

2.6.1 Основные сведения

При разработке алгоритма исходная задача разбивается на отдельные подзадачи, которые затем реализуются в виде отдельных программных компонентов: головной программы и процедуры (подпрограмма, функция или блок данных).

Программные компоненты (единицы):

  • физически отделены друг от друга;

  • начинаются оператором-заголовком, содержащим одно из слов: SUBROUTINE, FUNCTION, BLOCK DATA;

  • заканчиваются оператором END;

  • обрабатываются компилятором отдельно от остальных.

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

2.6.2 Оператор PROGRAM

Оператор PROGRAM объявляет головную программу и задает ей имя.

[PROGRAM [name_of_prog]]

name_of_prog – имя головной программы. Оператор PROGRAM является необязательным. Имя программы является глобальным именем, поэтому оно не может совпадать с именем другой процедуры.

PROGRAM Describe_Of_Type

2.6.3 Операторы SUBROUTINE и CALL

Оператор SUBROUTINE – идентифицирует программный компонент как п/п, задает ей имя, определяет формальные параметры процедуры.

SUBROUTINE sname [
1   2   3   4   5   6   7   8   9   ...   15


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