Подтвердить что ты не робот

Определение типа переменной в Fortran

В Fortran существует ли способ определить тип переменной?

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

4b9b3361

Ответ 1

Хорошо, что вы можете делать то, что хотите, если вы возитесь с внутренними и POINTER-ключами KIND, но если вас интересует только подпись функций и подпрограмм, оставьте это в Fortran. Если вы определяете

function calc8(arg1)
    real(8), intent(in) :: arg1
    ...

и

function calc4(arg1)
    real(4), intent(in) :: arg1
    ...

в модуле и объявить интерфейс, подобный этому

interface calc
    module procedure calc8
    module procedure calc4
end interface

(Предупреждение, я не проверял синтаксис в деталях, что ваша ответственность.)

то Fortran будет соответствовать вызову в правильную версию функции. Конечно, вам нужно написать обе версии функции, но это действительно способ Fortran 95 сделать это. Это может быть довольно утомительным, я обычно пишу общую версию и запускаю sed script, чтобы специализироваться на ней. Это немного клочья, но он работает.

Если код функции идентичен, кроме типа аргументов, я иногда пишу функцию для real (8) (или что-то еще) и записываю версию для real (4), которая вызывает завершенную версию (8) в типах.

В Fortran 2003 есть улучшенные способы определения полиморфных и универсальных функций, но я пока еще не обнял их.

Ответ 2

Да, есть два способа.

Первый способ требует, чтобы вы записывали отдельные функции или подпрограммы для каждого типа переменной, но вам не нужно вызывать разные функции. Это может быть или не быть достаточно близко к тому, что вы хотите. Вы пишете отдельные процедуры, а затем создаете интерфейс для создания общей функции или подпрограммы, обертывающей эти конкретные подпрограммы. Вам не нужно передавать тип переменной или делать что-либо особенное в своем вызове - все это делается через объявление и автоматически компилятором из самой переменной, если переменные достаточно различны, чтобы компилятор мог различать их (есть правила о том, что требуется). Это похоже на то, как работают внутренние функции - вы можете называть грех реальным аргументом, реальным аргументом двойной точности или сложным аргументом, а компилятор вызывает правильную фактическую функцию и возвращает результат сопоставления. High Performance Mark набросал решение в этом направлении. По другому вопросу я опубликовал рабочий пример, в котором отличительной особенностью переменных был ранг массива: как написать оболочку для 'allocate'. Преимущество этого метода заключается в том, что он широко поддерживается компиляторами Fortran.

В Fortran 2003/2008 существуют обширные объектно-ориентированные функции. Цитирование "Fortran 95/2003" объясняется Metcalf, Reid и Cohen: "Для выполнения альтернативного кода в зависимости от динамического типа полиморфного объекта и получения доступа к динамическим частям предоставляется конструкция типа выбора". Оператор select type немного похож на оператор case case. Это поддержка меньшим количеством компиляторов. Опять же, вам не нужно передавать тип, поскольку компилятор может определить его из самой переменной. Но он должен быть полиморфным типом... Оба типа Intel ifort и gfortran выбирают тип и полиморфные типы данных, которые поддерживаются - позже с некоторыми экспериментальными аспектами в gfortran (http://gcc.gnu.org/wiki/Fortran2003). Это недавние дополнения к этим компиляторам.