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

  • 8.14. Область видимости имен

  • 8.15. Область видимости меток

  • 8.16. Ассоциирование памяти

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


    Скачать 2.24 Mb.
    НазваниеО. В. Бартеньев Современный Фортран
    Анкорсовременный фортран , Бортеньев.pdf
    Дата28.05.2018
    Размер2.24 Mb.
    Формат файлаpdf
    Имя файласовременный фортран , Бортеньев.pdf
    ТипДокументы
    #19729
    страница28 из 49
    1   ...   24   25   26   27   28   29   30   31   ...   49
    8.13. Ассоциирование имен
    Большинство объектов Фортран-программы являются локальными.
    К ним относятся имена переменных, констант, производных типов данных, внутренних и модульных процедур, операторных функций. Глобальными
    253

    О. В. Бартеньев. Современный ФОРТРАН
    являются имена главной программы, встроенных и внешних процедур, модулей, common-блоков, BLOCK DATA. Однако локальный объект программной единицы можно сделать доступным в другой программной единице, используя ассоциирование имен: ассоциирование параметров процедуры, use-ассоциирование и ассоциирование через носитель.
    В момент вызова процедуры между формальными и фактическими параметрами устанавливается связь, или, иными словами, формальные параметры процедуры ассоциируются с фактическими. Благодаря такой связи:

    осуществляется обмен данными между программными единицами;

    реализуется альтернативный возврат из подпрограммы (разд. 8.19);

    передается в процедуру имя внешней или встроенной функции.
    Более подробно о правилах соответствия формальных и фактических параметров см. в разд. 8.11.1.
    Объекты модуля становятся доступны в программной единице, если в ней есть оператор USE, содержащий имя модуля. Использование этого оператора равнозначно повторному описанию всех не имеющих атрибута
    PRIVATE объектов модуля внутри программной единицы с сохранением всех имен (если нет переименований) и свойств. (Доступ к объектам модуля может быть ограничен за счет использования в операторе USE опции
    ONLY.) В этом случае говорится, что объекты модуля доступны за счет use-
    ассоциирования. Благодаря use-ассоциированию может быть обеспечен доступ к следующим объектам модуля:

    именованным объектам данных;

    определениям производных типов;

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

    модульным процедурам;

    родовым интерфейсам;

    namelist-группам.
    Use-ассоциирование передает как данные, так и статус объектов, например статус размещаемого массива (разд. 4.8.2).
    При подключении к программной единице модулей нельзя допускать дублирования передаваемых через use-ассоциирование имен и локальных имен самой программной единицы. Однако доступные через use-
    ассоциирование имена могут совпадать, если:

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

    продублированное имя является родовым (разд. 8.12).
    Избежать конфликтов имен можно за счет переименования, использования опции ONLY и за счет придания атрибута PRIVATE тем объектам модуля, которые предназначены только для внутреннего использования в модуле.
    254

    8. Программные единицы
    В модульных и внутренних процедурах доступны все объекты носителя этих процедур, в том числе и объекты, доступные носителю через use-
    ассоциирование. Такой механизм доступа к объектам носителя называется
    ассоциированием через носитель. Общее правило таково: имя объекта носителя считается повторно описанным с теми же свойствами в модульной или внутренней процедуре при условии, что в процедуре нет другого объекта с таким же именем, объявленного локально, или доступного путем
    use-ассоциирования, или являющегося локальным формальным параметром или результирующей переменной.
    Пример: real :: x = 1.0, w = 1.0, z = 1.0 call decar(x) print '(3f5.2)', x, w, z
    ! 5.0 1.0 5.0 contains subroutine decar(x) real x, w
    ! Локальная переменная w подпрограммы decar x = 5; w = 5; z = 5
    ! закрывает локальную переменную w носителя end subroutine end
    8.14. Область видимости имен
    Областью видимости именованного объекта называется часть программы, в которой можно ссылаться на этот объект.
    Например, на объявленный во внешней процедуре объект можно ссылаться в этой процедуре. Кроме того, этот объект за счет ассоциирования через носитель доступен в любой ее внутренней процедуре.
    При этом в самой процедуре могут существовать фрагменты, в которых ссылка на эту переменную невозможна. Такими фрагментами могут быть определения типов и интерфейсные блоки. Приведем фрагмент процедуры для описанной ситуации. subroutine reg( ) integer, parameter :: m = 40, n = 20
    ! Область 1 real a(m, n), b(3, 4, 5)
    ! Область 1 type win integer n
    ! Область 2 real a(n)
    ! Область 2 end type interface subroutine ones(a, m)
    ! Область 3 integer m
    ! Область 3 real a(:, :, :)
    ! Область 3 end subroutine ones
    ! Область 3 end interface type(win) tin(n)
    ! Область 1
    255

    О. В. Бартеньев. Современный ФОРТРАН
    a = real(n)
    ! Область 1 tin(n).a = real(m)
    ! Область 1 print *, a(m, n), tin(n).a(1)
    ! Область 1 call ones(b, n)
    ! Область 1 call two( ) contains subroutine two( )
    ! Внутренняя подпрограмма не является областью integer m
    ! видимости объектов носителя, но объекты носителя m = n
    ! n, a, b, win, tin и интерфейс к подпрограмме a = real(m)
    ! ones достижимы в two благодаря ассоциированию call ones(b, m)
    ! через носитель. Переменная m подпрограммы end subroutine two
    ! two закрывает константу m носителя end subroutine reg program t2
    ! Драйвер подпрограммы reg call reg( ) end program t2 subroutine ones(a, m) integer m real a(:, :, :) a = real(m) end subroutine ones
    В этом фрагменте область 1 является областью видимости констант
    m и n. Впрочем, эти же константы видны и в области 2 определения производного типа: в объявлении REAL a(n) используется константа n из области 1. В то же время в области 2 можно объявить компонент с именем
    n. В области 3 интерфейсного блока константы m и n, так же как и массив
    a(1:m, 1:n), не видны. Иными словами, использованные в областях 1, 2 и 3 имена m, n и a относятся к разным объектам данных. Таким образом, область видимости констант m и n состоит из трех блоков видимости, разделенных областью 3. Областью видимости массива a(1:m, 1:n) и трехмерного массива b являются два блока, разделенные уже двумя областями с номерами 2 и 3.
    Область видимости именованного объекта зависит от вида его имени.
    Имена объектов разделяются на глобальные, локальные и операторные.
    Глобальными являются имена главной программы, модулей, встроенных и внешних процедур и common-блоков. Эти имена известны в любой программной единице, и не может быть двух глобальных объектов с одним именем. Так, не может быть common-блока с именем sqrt, поскольку это имя принадлежит встроенной функции.
    Если же в каком-либо блоке видимости определена локальная переменная sqrt, то глобальное имя встроенной функции SQRT в этом блоке видимости становится недоступным.
    256

    8. Программные единицы
    Если же глобальное имя встроенной процедуры определено в блоке видимости с атрибутом EXTERNAL, то встроенная процедура также становится недоступной в этом блоке видимости, но введенное имя трактуется как глобальное имя внешней процедуры.
    Пример: real :: sqrt, x = 4.0, y real, external :: sin
    ! Должна быть определена внешняя функция sin sqrt = 5.0
    ! Локальное имя закрывает глобальное имя y = sqrt(x)
    ! Ошибка - встроенная функция SQRT недоступна
    К локальным именам относятся имена переменных, формальных параметров, именованных констант, производных типов, операторных функций, внутренних, модульных и формальных процедур, родовых описаний, namelist-групп. Блоками видимости локальных имен являются:

    определение производного типа;

    тело интерфейса, за исключением содержащихся в нем определений производных типов и тел интерфейсных блоков;

    программная единица, за исключением содержащихся в ней определений производных типов, интерфейсных блоков и внутренних процедур.
    Локальные имена в случае объявления их в блоке видимости закрывают имена глобальных объектов, и последние становятся недоступными в этом блоке видимости. Исключение составляют применяемые при вызове процедур ключевые слова, родовые описания и имена common-блоков.
    Выше было показано, как локальное имя sqrt закрыло глобальное имя встроенной функции SQRT. Такой же эффект вызовет и использование внутренней функции, например, с именем tan, которое закроет в блоке видимости имя встроенной функции TAN, например: subroutine dehi y = tan(x)
    ! Будет вызвана внутренняя функция tan contains function tan(x) end function tan end subroutine dehi
    Областью видимости операторного имени является один оператор.
    Операторные имена могут появляться при задании операторной функции, а также в неявных циклах операторов DATA и конструкторов массивов.
    Областью видимости формальных параметров операторной функции является оператор задания этой функции. Областью видимости переменной неявного цикла, которая должна быть целого типа, является этот цикл.
    257

    О. В. Бартеньев. Современный ФОРТРАН
    Параметры неявных циклов операторов В/В не являются операторными, а относятся к локальным и могут быть вещественного типа. Например: real c(100) z(x, y) = sin(x) * exp(-y)
    ! Определяем операторную функцию z b = 55.0
    ! Переменная b будет использована в качестве параметра цикла оператора WRITE write(*, '(5f7.4)') ((z(a, b), a = 0.0, 1.0, 0.2), b = 0.0, 1.0, 0.2) k = 55
    ! k - локальная переменная c = (/ (float(k), k = 1, 100) /)
    ! k - пример операторного имени print *, b
    ! 1.20000 print *, k
    ! 55 end
    Замечание. Использовать нецелые параметры в неявном цикле, так же как и в DO-цикле с параметром, не рекомендуется (см. П.-2.2.4).
    Имя локального объекта не закрывает имени common-блока, поэтому эти имена могут быть одновременно использованы в блоке видимости.
    Имя common-блока, если оно используется в операторе SAVE, должно обрамляться слешами.
    Например: common /vab/ a, b real vab
    ! Имена переменной vab и common-блока совпадают save :: /vab/, vab
    ! Атрибут SAVE имеют и переменная и common-блок
    Имена локальных объектов в блоке видимости могут совпадать с используемыми при вызовах процедур ключевыми словами. Область видимости ключевых слов определяется областью видимости интерфейсного блока к процедуре, в которой эти ключевые слова описаны. Область действия интерфейсного блока может быть распространена на другую программную единицу в результате use-ассоциирования или ассоциирования через носитель.
    8.15. Область видимости меток
    Метки являются локальными объектами. Главная программа и каждая процедура имеют свой независимый набор меток. Оператор END носителя может иметь метку. Если в таком носителе есть внутренние процедуры, то они разбивают область видимости этой метки на два блока: до оператора
    CONTAINS и оператор END носителя.
    8.16. Ассоциирование памяти
    Фортран предоставляет пользователю еще один способ обмена данными - это ассоциирование памяти. Применив оператор COMMON, в программе можно создать общую область памяти, на которую можно ссылаться изо всех программных единиц, содержащих этот оператор.
    Например:
    258

    8. Программные единицы program gocom integer(4) a, b, c common /vab/ a, b, c
    ! Создаем общую область числовой памяти a = -1
    ! В этой области существует 3 единицы call chaco( )
    ! памяти по 4 байта каждая print *, a, b, c
    ! 1 2 3 end program gocom subroutine chaco( ) integer(4) ia, ib, ic common /vab/ ia, ib, ic print *, ia
    ! -1 ia = 1; ib = 2; ic = 3 end subroutine
    В приведенном примере переменные a, b и c главной программы и переменные ia, ib и ic подпрограммы chaco используют одну и ту же область памяти. Более того, переменные a и ia адресуют одну и ту же единицу памяти.
    Это означает, что после выхода из подпрограммы переменная a получит значение переменной ia. То же справедливо и для пар переменных b и ib, c и ic.
    Одинаковые по порядку имена в расположенном в разных программных единицах common-блоке могут совпадать. Они также могут и различаться
    (это видно из примера). Более того, они могут различаться рангом и формой. Так, мы получим тот же результат, создав, например, подпрограмму: subroutine chaco( ) integer(4) abc, k common /vab/ abc(3)
    ! Массив abc вместо переменных a, b и c print *, abc(1)
    ! -1 abc = (/ (k, k = 1, 3) /) end subroutine
    В этом случае уже a и abc(1) адресуют одну и ту же единицу памяти.
    То же справедливо и для пар b и abc(2), c и abc(3).
    Иной пример ассоциирования памяти - применение оператора EQUIVA-
    LENCE, который явно указывает, что два или более объекта занимают одну область памяти. integer :: a(5) = 3, b(5) equivalence(a, b) print *, a
    ! 3 3 3 3 3 print *, b
    ! 3 3 3 3 3
    Рассмотренный на примерах механизм доступа к памяти называется
    ассоциированием памяти. Такой механизм используется для обмена данными. Правда, в прежние времена при недостатке вычислительных ресурсов он часто использовался и для экономии памяти. Последнее выполнялось за счет применения оператора EQUIVALENCE. Однако такая
    259

    О. В. Бартеньев. Современный ФОРТРАН
    практика является причиной многих ошибок и не может быть рекомендована для применения (прил. 2).
    Для дальнейшего рассмотрения вопроса нам понадобятся некоторые дополнительные сведения.
    8.16.1. Типы ассоциируемой памяти
    Под единицей памяти понимают область памяти компьютера, выделяемую под определенные данные. Размер такой единицы зависит от типа и параметра разновидности типа. Так, единица памяти под скаляр типа
    REAL(4) равна 4 байтам, а скаляр типа COMPLEX(8) занимает две единицы памяти по 8 байт каждая.
    Единица памяти может быть:

    числовой;

    текстовой;

    неспецифицированной.
    Числовая единица памяти выделяется под нессылочный скаляр (т. е. скаляр без атрибута POINTER) стандартного вещественного, целого или логического типа.
    Текстовую единицу памяти занимает нессылочный скаляр стандартного символьного типа единичной длины.
    К объектам производного типа ассоциирование памяти применимо лишь при наличии у них атрибута SEQUENCE. Если в определении типа использованы другие производные типы, то они тоже должны иметь атрибут SEQUENCE. В таком случае объекты производного типа могут быть использованы в операторах COMMON, EQUIVALENCE и в качестве параметров процедур.
    С производным типом, имеющим атрибут SEQUENCE и не имеющим ссылочных компонентов на любом уровне, ассоциируется:

    числовая память, если конечные компоненты типа относятся к стандартному целому, вещественному, вещественному двойной точности, комплексному или логическому типу;

    текстовая память, если конечные компоненты типа относятся к стандартному символьному типу.
    Неспецифицированная единица памяти присуща любым другим производным типам с атрибутом SEQUENCE, а также объектам с атрибутом POINTER. Размер неспецифицированной единицы памяти таких объектов уникален для каждого типа, параметра типа и ранга.
    Нессылочный массив встроенного типа или производного типа с атрибутом
    SEQUENCE занимает ряд последовательных отрезков памяти,по одному на каждый элемент массива в порядке их следования в массиве. Нессылочный скаляр производного типа с атрибутом SEQUENCE, имеющий n конечных
    260

    8. Программные единицы компонентов, занимает n отрезков памяти, по одному на каждый конечный компонент в порядке их объявления в производном типе.
    Последовательность отрезков и единиц памяти образует объединенный
    отрезок памяти.
    Для правильного обмена данными следует ассоциировать объекты с единицами памяти одного и того же типа.
    8.16.2. Оператор COMMON
    Оператор COMMON создает общую область памяти - глобальный отрезок памяти, доступный в различных программных единицах.
    COMMON [/[cname]/] список имен [[,] /[cname]/ список имен] ...
    cname - имя общего блока (common-блока), которому принадлежат объекты соответствующего списка имен. Имя может быть опущено. Такой
    common-блок называется неименованным. Если первый задаваемый в операторе COMMON общий блок является неименованным, то слеши могут быть опущены, например: common a, r, g(40)
    Имя common-блока является глобальным и должно отличаться от любого другого глобального имени (программной единицы, другого com-
    mon-блока), но может совпадать с именем локального объекта, кроме именованной константы.
    список имен - список входящих в именованную или неименованную общую область имен простых переменных, строк, записей, массивов и объявлений массивов. При объявлении в common-блоке массива размеры его границ задаются в виде целочисленных констант или константных выражений. Объекты common-блока могут иметь атрибуты POINTER и
    TARGET. Имена в списке разделяются запятыми. Каждое имя в программной единице может появляться в списке имен только один раз и не может появляться в другом списке имен этой программной единицы.
    В списке имен не могут появляться имена формальных параметров, процедур, точек входа, результирующей переменной функции, размещаемых массивов и автоматических объектов, именованных констант
    (объектов с атрибутом PARAMETER). Объекты производного типа могут быть помещены в common-блок при наличии у них атрибута SEQUENCE.
    Оператор COMMONразмещается в разделе объявлений программной единицы. В программной единице можно объявить несколько общих областей, задаваемых одним или несколькими операторами COMMON.
    Имя любого common-блока (включая и пустое имя) может появляться в разделе описаний программного модуля более одного раза. При этом список элементов конкретного common-блока рассматривается как продолжение списка элементов предшествующего common-блока с тем же именем.
    1   ...   24   25   26   27   28   29   30   31   ...   49


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