Определение типа переменной в Фортране - PullRequest
15 голосов
/ 01 апреля 2010

В Фортране есть способ определить тип переменной?

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

Ответы [ 2 ]

8 голосов
/ 01 апреля 2010

Что ж, вы можете делать то, что хотите, если возитесь с внутренними и указателями 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 сопоставит вызов с верной версией функции. Конечно, вы должны написать обе версии функции, но на самом деле это Фортран 95 способ сделать это. Это может быть довольно утомительно, я склонен писать общую версию и запускать скрипт sed, чтобы специализировать его. Это немного круто, но это работает.

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

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

4 голосов
/ 01 апреля 2010

Да, есть два пути.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...