современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
270 8. Программные единицы Остаток по модулю p MOD(a, p) MOD AMOD DMOD Integer Real Real(8) Integer(4) Real(4) Real(8) Мнимая часть AIMAG(z) AIMAG IMAG DIMAG Cmp Cmp(4) Cmp(8) Real(4) Real(4) Real(8) Комплексное сопряжение CONJG(z) CONJG DCONJG Cmp(4) Cmp(8) Cmp(4) Cmp(8) Квадратный корень SQRT(x) SQRT DSQRT CSQRT CDSQRT Real Real(8) Cmp(4) Cmp(8) Real(4) Real(8) Cmp(4) Cmp(8) Экспонента EXP(x) EXP DEXP CEXP CDEXP Real Real(8) Cmp(4) Cmp(8) Real(4) Real(8) Cmp(4) Cmp(8) Натуральный логарифм LOG(x) ALOG DLOG CLOG CDLOG Real Real(8) Cmp(4) Cmp(8) Real(4) Real(8) Cmp(4) Cmp(8) Десятичный логарифм LOG10(x) ALOG10 DLOG10 Real Real(8) Real(4) Real(8) Синус SIN(x) SIN DSIN CSIN Real Real(8) Cmp(4) Real(4) Real(8) Cmp(4) Синус (аргумент в град.) SIND(x) SIND DSIND Real, Cmp Real(8) Real(4) Real(8) Косинус COS(x) COS DCOS CCOS CDCOS Real Real(8) Cmp(4) Cmp(8) Real(4) Real(8) Cmp(4) Cmp(8) Косинус (аргумент в град.) COSD(x) COSD DCOSD Real, Cmp Real(8) Real(4) Real(8) Тангенс TAN(x) TAN DTAN Real Real(8) Real(4) Real(8) Тангенс (аргумент в град.) TAND(x) TAND DTAND Real Real(8) Real(4) Real(8) Котангенс COTAN(x) COTAN DCOTAN Real Real(8) Real(4) Real(8) Арксинус ASIN(x) ASIN DASIN Real Real(8) Real(4) Real(8) 271 О. В. Бартеньев. Современный ФОРТРАН Арксинус (результат в град.) ASIND(x) ASIND DASIND Real Real(8) Real(4) Real(8) Арккосинус ACOS(x) ACOS DACOS Real Real(8) Real(4) Real(8) Арккосинус (результат в град.) ACOSD(x) ACOSD DACOSD Real Real(8) Real(4) Real(8) Арктангенс ATAN(x) ATAN DATAN Real Real(8) Real(4) Real(8) Арктангенс (результат в град.) ATAND(x) ATAND DATAND Real Real(8) Real(4) Real(8) Арктангенс (y/x) ATAN2(y, x) ATAN2 DATAN2 Real Real(8) Real(4) Real(8) Арктангенс (y/x) (результат в град.) ATAN2D(y, x) ATAN2D DATAN2D Real Real(8) Real(4) Real(8) Гиперболический синус SINH(x) SINH DSINH Real Real(8) Real(4) Real(8) Гиперболический косинус COSH(x) COSH DCOSH Real Real(8) Real(4) Real(8) Гиперболический тангенс TANH(x) TANH DTANH Real Real(8) Real(4) Real(8) Текстовая длина LEN(string) LEN Character Integer(4) Начальная позиция INDEX(s, sub) INDEX " " В качестве параметров, даже после их объявления с атрибутом INTRIN- SIC, не могут быть использованы родовые имена встроенных процедур, а также специфические имена приведенных в табл. 8.4 встроенных процедур. Таблица 8.4. Специфические имена, не допускаемые в качестве фактических параметров Описание функции Форма вызова с родовым именем Специфичес кие имена Типы аргуметов Типы функций Преобразование в целый тип INT(a) INT IFIX IDINT Real, Cmp Real(4) Real(8) Integer Integer(4) Integer Преобразование в вещественный тип REAL(a) REAL FLOAT SNGL DREAL Integer Integer Real(8) Cmp(8) Real Real Real Real(8) Мнимая часть AIMAG(z) IMAG Cmp(4) Real(4) MAX(a1, a2, ...) MAX(a1, a2, ...) MAX0 Integer Integer 272 8. Программные единицы AMAX1 DMAX1 AMAX0 MAX1 Real Real(8) Integer Real Real Real(8) Real Integer MIN(a1, a2, ...) MIN(a1, a2, ...) MIN0 AMIN1 DMIN1 AMIN0 MIN1 Integer Real Real(8) Integer Real Integer Real Real(8) Real Integer Пример. Построить графики функций sinx и cosx на отрезке [- π, π]. Для работы в графическом режиме необходимо создать проект как приложение QuickWin или Standard Graphics. Для доступа к процедурам графической библиотеки выполняется ссылка на модуль MSFLIB. В графическом режиме физическая система координат видового окна начинается в его верхнем левом углу. Для построения графика используем оконную систему координат, расположив начало системы координат в центре окна. Оконная система координат позволяет выполнять графические построения, оперируя реальными координатами. Размеры окна вывода по осям x и y установим равными половине соответствующих размеров видеоокна. Для определения последних воспользуемся функцией GET- WINDOWCONFIG. Назначение использованных графических процедур можно понять из размещенного в тексте программы комментария. Их подробное описание дано в [1]. use msflib intrinsic dsin, dcos ! Используем специфические logical res ! имена встроенных функций integer(2) status2, XE, YE ! XE,YE - размеры экрана в пикселях real(8) dx ! Используем двойную точность logical(2) finv /.true./ ! Ось y направлена снизу вверх real(8), parameter :: pi = 3.14159265 type(windowconfig) wc ! Автоматическая настройка конфигурации окна data wc.numxpixels, wc.numypixels, wc.numtextcols, & wc.numtextrows, wc.numcolors, wc.fontsize / 6*-1 / wc.title = "Встроенные функции как параметры процедуры"C res = setwindowconfig(wc) res = getwindowconfig(wc) ! Читаем параметры видеоокна XE = wc.numxpixels ! numxpixels - число пикселей по оси x YE = wc.numypixels ! numypixels - число пикселей по оси y call axis( ) ! Рисуем оси координат ! Задание видового порта размером XE/2 * YE/2 в центре видеоокна call setviewport(XE/4_2, YE/4_2, 3_2*XE/4_2, 3_2*YE/4_2) ! Оконная система координат (ОСК) status2 = setwindow(finv, -pi, -1.0_8, pi, 1.0_8) 273 О. В. Бартеньев. Современный ФОРТРАН dx = pi / dble(XE/2) ! Шаг по оси x call curve(dsin, dx, 10_2) ! Рисуем sinx светло-зеленым цветом call curve(dcos, dx, 14_2) ! Рисуем cosx желтым цветом contains subroutine axis( ) ! Рисуем оси координат type(xycoord) xy status2 = setcolor(15_2) ! Оси координат - белым цветом call moveto(int2(XE/4 - 10), int2(YE/2), xy) status2 = lineto(3_2*XE/4_2 + 10_2, YE/2_2) ! Ось x call moveto(int2(XE/2), int2(YE/4 - 10), xy) status2 = lineto(XE/2_2, 3_2*YE/4_2 + 10_2) ! Ось y end subroutine axis subroutine curve(fx, dx, color) ! График функции y = fx(x) real(8) fx, dx, x, y ! fx - формальная функция integer(2) color status2 = setcolor(color) ! График функции цветом color do x = -pi, pi, dx ! Изменение x в ОСК y = fx(x) ! Значение y в ОСК status2 = setpixel_w(x, y) ! Вывод точки графика end do end subroutine curve end ! Результат приведен на рис. 8.2 Рис. 8.2. Графики функций sinx и cosx 8.19. Оператор RETURN выхода из процедуры Выход из процедуры осуществляется в результате выполнения оператора END или оператора RETURN. Пример. Составить функцию поиска первого отрицательного числа в массиве. real b(20) /1.1, 1.2, -1.3, 1.4, 16*0.0/, bneg, fineg bneg = fineg(b, 20) ! Функция fineg возвращает 0, если if(bneg .eq. 0 ) then ! в массиве нет отрицательных чисел write(*, *) ' В массиве нет отрицательных чисел' else write(*, *) ' Первое отрицательное число', bneg end if end 274 8. Программные единицы function fineg (b, n) integer i, n real fineg, b(n) fineg = 0 ! Вернем 0, если нет отрицательных чисел do i = 1, n fineg = b(i) if(fineg .lt. 0) return ! Выход из функции fineg end do end В подпрограммах оператор RETURN может также иметь вид: RETURN номер метки номер метки - номер звездочки в списке формальных параметров подпрограммы. Такой возврат из подпрограммы называется альтернативным и обеспечивает в вызывающей программной единице передачу управления на оператор, метка которого является фактическим параметром и соответствует формальному параметру - звездочке, номер которой указан в операторе RETURN. Пример альтернативного возврата: integer a(5) /-1, 2, 3, 4, 5/, n /5/ call alre(a, n, *10, *20) ! Перед меткой обязательна * write(*, *) ' = 0' ! На данном наборе данных go to 40 ! будет выполнен переход на метку 20 10 write(*, *) ' < 0' go to 40 20 write(*, *) ' > 0' 40 end subroutine alre(a, n, *, *) integer a(n), sv sv = sum(a) if(sv .eq. 0) return ! Нормальный возврат if(sv .lt. 0) return 1 ! Передача управления на метку 10 return 2 ! sv > 0; передача управления на метку 20 end Замечание. Программы с альтернативным возвратом обладают плохой структурой. Отказаться от альтернативного возврата позволяют конструкции IF и SELECT CASE. 8.20. Оператор ENTRY дополнительного входа в процедуру Оператор RETURN позволяет организовать несколько точек выхода из процедуры. Наряду с этим в Фортране можно организовать и 275 О. В. Бартеньев. Современный ФОРТРАН дополнительные точки входа во внешнюю или модульную процедуру. Для этого используется оператор ENTRY. ENTRY ename [([список формальных параметров])] & [RESULT (имя результата)] Каждая точка входа задает отдельную процедуру со своим именем ename, называемым именем входа. Формальные параметры процедуры определяются списком формальных параметров оператора ENTRY. Имя точки входа является глобальным и не должно совпадать с другим глобальным именем. Оно также не должно совпадать с локальными именами процедуры, в которой эта точка входа существует. Предложение RESULT имеет тот же смысл, что и в операторе FUNC- TION. Имя результата не может совпадать с ename. Вызов подпрограммы с использованием дополнительного входа: CALL ename [([список фактических параметров])] Обращение к функции с использованием дополнительного входа: result = ename([список фактических параметров]) В случае функции использование круглых скобок даже при отсутствии фактических параметров обязательно. При таком вызове выполнение процедуры начинается с первого исполняемого оператора, следующего за оператором ENTRY. В подпрограмме оператор ENTRY определяет дополнительную подпрограмму с именем ename. В функции оператор ENTRY определяет дополнительную функцию с результирующей переменной имя результата или ename, если предложение RESULT опущено. Описание результирующей переменной определяет характеристики возвращаемого функцией результата. Если характеристики результата функции, определяемой оператором ENTRY, такие же, как и у главного входа, то обе результирующие переменные (даже если они имеют разное имя) являются одной и той же переменной. В противном случае они ассоциируются в памяти и на них накладываются ограничения: все результирующие переменные должны иметь один вид памяти (текстовая или числовая), должны быть скалярами и не должны иметь атрибут POINTER. В случае текстового результата результирующие переменные должны быть одной длины. При работе с оператором ENTRY следует соблюдать такие правила: • внутри подпрограммы имя входа не может совпадать с именем формального параметра в операторах FUNCTION, SUBROUTINE или EX- TERNAL; • внутри функции имя входа не может появляться ни в одном из операторов функции, кроме оператора объявления типа, до тех пор, пока имя входа не будет определено в операторе ENTRY; 276 8. Программные единицы • если ENTRY определяет функцию символьного типа, то имена всех точек входа должны быть символьного типа и иметь одну длину; • формальный параметр оператора ENTRY не может появляться в выполняемом операторе, расположенном до оператора ENTRY. Однако это правило не распространяется на формальный параметр, если он также присутствует в операторах FUNCTION, SUBROUTINE или ранее размещенном оператореENTRY; • оператор ENTRY может появляться только во внешней или модульной процедуре; • оператор ENTRY не может появляться внутри конструкций IF (между IF и END IF), SELECT CASE, WHERE, внутри DO- и DO WHILE-циклов и в интерфейсном блоке; • нельзя определить точку входа с префиксом RECURSIVE. Задание RE- CURSIVE в главном входе (в операторах FUNCTION или SUBROUTINE) означает, что заданная точкой входа процедура может обращаться сама к себе. Интерфейс к процедуре, определяемой точкой входа, если он необходим, задается в самостоятельном теле интерфейсного блока, в заголовке которого должны стоять операторы SUBROUTINE или FUNC- TION (а не ENTRY). Число дополнительных входов в процедуру не ограничено. Пример. Подпрограмма vsign выведет сообщение '>= 0', если num ≥ 0, и сообщение '< 0', если num < 0. write(*,'(1x, a \)') 'Enter num (INTEGER): ! Вывод без продвижения read(*, *) num if(num .ge. 0) then call vsign else call negative end if end subroutine vsign ! Главный вход write(*, *) '>= 0' return entry negative ! Точка входа negative write(*, *) '< 0' return end Замечание. Так же как и в случае альтернативного возврата, применение дополнительных входов ухудшает структуру программы и поэтому не может быть рекомендовано для использования. 277 О. В. Бартеньев. Современный ФОРТРАН 8.21. Атрибут AUTOMATIC В CVF и FPS по умолчанию переменные являются в большинстве случаев статическими, т. е. под них всегда выделена память и они размещены в памяти статически (адрес размещения статической переменной не меняется в процессе выполнения программы). Переменная называется автоматической, если память под эту переменную выделяется по необходимости. Размещение автоматических переменных выполняется в стеке. Примерами автоматических объектов являются объявляемые в процедуре автоматические массивы и строки. Однако в процедуре и модуле можно сделать переменную автоматической, присвоив ей атрибут AUTO- MATIC. Атрибут AUTOMATIC является расширением над стандартом Фортрана и может быть задан в отдельном операторе и при объявлении типа: АUTOMATIC [список имен переменных] type-spec, АUTOMATIC [, атрибуты] :: список имен переменных Автоматические переменные прекращают существование после выполнения операторов RETURN или END. Таким образом, их значения при следующем вызове процедуры могут отличаться от тех, которые они получили ранее. Если оператор AUTOMATIC задан без списка имен, то все переменные внутри блока видимости, которые могут иметь атрибут AUTOMATIC, будут неявно объявлены автоматическими. В операторе AUTOMATICне могут появляться: • имена и объекты common-блоков; • переменные, имеющие атрибут SAVE; • переменные с атрибутами ALLOCATABLEилиEXTERNAL; • формальные параметры и имена процедур. Переменная, которой явно присвоен атрибут AUTOMATIC, не может быть инициализирована в операторе DATA или в операторе объявления типа. Переменные, неявно ставшие автоматическими и появившиеся в операторе DATA или инициализированные в операторе объявления типа, получат атрибут SAVE и будут помещены в статическую память. Переменная не может появляться в операторе AUTOMATIC более одного раза. Пример: call atav(2, 3) call atav(4, 5) end subroutine atav (m, n) automatic ! Переменные объявляются автоматическими неявно 278 8. Программные единицы integer :: m, n, a, b = 2 print *, 'b = ', b ! Переменная b является статической, a = m ! поэтому сохраняет полученное значение b = n ! при повторном вызове end ! Переменная a является автоматической Результат: b = 2 b = 3 8.22. Атрибут SAVE Существующая в процедуре или модуле переменная будет сохранять свое значение, статус определенности, статус ассоциирования (для ссылок) и статус размещения (в случае размещаемых массивов) после выполнения оператора RETURN или END, если она имеет атрибут SAVE. В CVF и FPS все переменные (кроме объектов с атрибутом ALLOCATABLE или POINTER и автоматических объектов) по умолчанию имеют такой атрибут. Поэтому объявление переменной с атрибутом SAVE выполняется для создания программ, переносимых на другие платформы или в том случае, если переменные процедуры или модуля неявно получили атрибут AUTOMATIC. Атрибут SAVE задается отдельным оператором или при объявлении типа: SAVE [[::] список объектов] type-spec, SAVE [, атрибуты] :: список объектов Список объектов может включать имена переменных и common-блоков. Последние при задании обрамляются слешами. Один и тот же объект не может дважды появляться в операторе SAVE. Если оператор SAVE задан без списка объектов, то все объекты программной единицы, которые могут иметь атрибут SAVE, получают этот атрибут. Задание атрибута SAVE в главной программе не имеет никакого действия. Если common-блок задан в главной программе, то он и, следовательно, все его переменные имеют атрибут SAVE. Если же common- блок задан только в процедурах, то он должен быть сохранен в каждой использующей его процедуре. Атрибут SAVE не может быть задан: • переменным, помещенным в common-блок; • формальным параметрам процедур; • именам процедур и результирующей переменной функции; • автоматическим массивам и строкам (разд. 4.8.3); • объектам, явно получившим атрибут AUTOMATIC. Пример: |