Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

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

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)

! Ось x

status2 = lineto(3_2*XE/4_2 + 10_2, YE/2_2)

call moveto(int2(XE/2), int2(YE/4 - 10), xy)

! Ось y

status2 = lineto(XE/2_2, 3_2*YE/4_2 + 10_2)

end subroutine axis

! График функции y = fx(x)

subroutine curve(fx, dx, color)

real(8) fx, dx, x, y

! fx - формальная функция

integer(2) color

! График функции цветом color

status2 = setcolor(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)

! Выход из функции fineg

if(fineg .lt. 0) return

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 имеет тот же смысл, что и в операторе FUNCTION. Имя результата не может совпадать с ename.

Вызов подпрограммы с использованием дополнительного входа: CALL ename [([список фактических параметров])]

Обращение к функции с использованием дополнительного входа: result = ename([список фактических параметров])

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

При таком вызове выполнение процедуры начинается с первого исполняемого оператора, следующего за оператором ENTRY.

Вподпрограмме оператор ENTRY определяет дополнительную подпрограмму с именем ename.

В функции оператор ENTRY определяет дополнительную функцию с результирующей переменной имя результата или ename, если предложение RESULT опущено. Описание результирующей переменной определяет характеристики возвращаемого функцией результата. Если характеристики результата функции, определяемой оператором ENTRY, такие же, как и у главного входа, то обе результирующие переменные (даже если они имеют разное имя) являются одной и той же переменной. В противном случае они ассоциируются в памяти и на них накладываются ограничения: все результирующие переменные должны иметь один вид памяти (текстовая или числовая), должны быть скалярами и не должны иметь атрибут POINTER. В случае текстового результата результирующие переменные должны быть одной длины.

При работе с оператором ENTRY следует соблюдать такие правила:

внутри подпрограммы имя входа не может совпадать с именем формального параметра в операторах FUNCTION, SUBROUTINE или EXTERNAL;

внутри функции имя входа не может появляться ни в одном из операторов функции, кроме оператора объявления типа, до тех пор, пока имя входа не будет определено в операторе ENTRY;

276

8. Программные единицы

если ENTRY определяет функцию символьного типа, то имена всех точек входа должны быть символьного типа и иметь одну длину;

формальный параметр оператора ENTRY не может появляться в выполняемом операторе, расположенном до оператора ENTRY. Однако это правило не распространяется на формальный параметр, если он также присутствует в операторах FUNCTION, SUBROUTINE или ранее размещенном операторе ENTRY;

оператор ENTRY может появляться только во внешней или модульной процедуре;

оператор ENTRY не может появляться внутри конструкций IF (между IF

иEND IF), SELECT CASE, WHERE, внутри DO- и DO WHILE-циклов

ив интерфейсном блоке;

нельзя определить точку входа с префиксом RECURSIVE. Задание RECURSIVE в главном входе (в операторах FUNCTION или SUBROUTINE) означает, что заданная точкой входа процедура может обращаться сама к себе.

Интерфейс к процедуре, определяемой точкой входа, если он необходим, задается в самостоятельном теле интерфейсного блока, в заголовке которого должны стоять операторы SUBROUTINE или FUNCTION (а не 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

! Точка входа negative

entry negative

write(*, *) '< 0'

 

return

 

end

 

Замечание. Так же как и в случае альтернативного возврата, применение дополнительных входов ухудшает структуру программы и поэтому не может быть рекомендовано для использования.

277