Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [General] Зачем нужны интерфейсы? 
V
    Опции темы
valvliv
Дата 25.1.2006, 02:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 25.1.2006

Репутация: нет
Всего: 1



Добрый день.

Зарегистрировалась и ищу фортранистов, ау.

Хочу поприставать с ламерскими вопросами, поскольку осваиваю 90/95 фортран после многолетнего перерыва со слабыми воспоминиями о 77-м.

Вот для чего модули, это понятно. Объясните, народ, для чего интерфейсы?? Читаю доки и не въезжаю, в чем суть?

Заранее спасибо.

Лера

PM MAIL   Вверх
Cr@$h
Дата 25.1.2006, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: 1
Всего: 41



Ау smile Я, например, фортранист. На Винграде есть всё. smile

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

1. Перегрузка процедур.
Можо под одним именем (родовым) определить несколько процедур. Более того, объединяемые процедуры могут содержать разное число параметров. Под одним именем могут быть перегружены одновременно и подпрограммы, и функции, с разным числом параметров.

Пример 1.1
Код

program Interfaces

    implicit none

    ! Объединяем под одним родовым именем функции и подпрограмму.
    interface Maximum
        ! Заголовки процедур с их специфическими именами.

        function IntegerMax( int1, int2 )
            integer IntegerMax, int1, int2
        end

        function RealMax( real1, real2 )
            real RealMax, real1, real2
        end

        subroutine CharacterMax( char1, char2, char3 )
            character(*) char1, char2, char3
        end
    end interface Maximum

    integer :: i1 = 3, i2 = 4
    real :: r1 = 4, r2 = 5
    character(*), parameter :: char1 = "Welcome"
    character(*), parameter :: char2 = "Vingrad,"
    character(*), parameter :: char3 = "Lera!"

    ! Используя родовое имя, вызываем каждый раз свою процедуру.
    print *, Maximum( i1, i2 ), Maximum( r1, r2 )
    call Maximum( char1, char2, char3 )

    read *

end program Interfaces

! Используемые процедуры определены вне программы.
function IntegerMax( int1, int2 )
    integer IntegerMax, int1, int2

    IntegerMax = Max( int1, int2 )
end function IntegerMax

function RealMax( real1, real2 )
    real RealMax, real1, real2

    RealMax = Max( real1, real2 )
end function RealMax

subroutine CharacterMax( char1, char2, char3 )
    character(*) char1, char2, char3

    print *, Max( Len(char1), Len(char2) )
end subroutine CharacterMax


Результат выполнения
Код

           4   5.000000
           8


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

Пример 1.2
Код

program Interfaces

    implicit none

    ! Объединяем под одним родовым именем функции и подпрограмму.
    interface Maximum
        ! Заголовки процедур с их специфическими именами. Указаны только имена
        ! процедур, т.к. они определены в этом же модуле (а данном случае -- в
        ! программе).
        module procedure IntegerMax, RealMax, CharacterMax
    end interface Maximum

    integer :: i1 = 3, i2 = 4
    real :: r1 = 4, r2 = 5
    character(*), parameter :: char1 = "Welcome"
    character(*), parameter :: char2 = "Vingrad,"
    character(*), parameter :: char3 = "Lera!"

    ! Используя родовое имя, вызываем каждый раз свою процедуру.
    print *, Maximum( i1, i2 ), Maximum( r1, r2 )
    call Maximum( char1, char2, char3 )

    read *

! Используемые процедуры определены внутри программы.
contains
    
    function IntegerMax( int1, int2 )
        integer IntegerMax, int1, int2

        IntegerMax = Max( int1, int2 )
    end function IntegerMax

    function RealMax( real1, real2 )
        real RealMax, real1, real2

        RealMax = Max( real1, real2 )
    end function RealMax

    subroutine CharacterMax( char1, char2, char3 )
        character(*) char1, char2, char3

        print *, Max( Len(char1), Len(char2) )
    end subroutine CharacterMax
end program Interfaces


Процедуры вместе с интерфейсом можно определить внутри модуля, тем самым облегчив текст программы.
Пример 1.3
Код

program Interfaces

    use Procedures
    
    implicit none
    
    integer :: i1 = 3, i2 = 4
    real :: r1 = 4, r2 = 5
    character(*), parameter :: char1 = "Welcome"
    character(*), parameter :: char2 = "Vingrad,"
    character(*), parameter :: char3 = "Lera!"

    ! Используя родовое имя, вызываем каждый раз свою процедуру,.
    print *, Maximum( i1, i2 ), Maximum( r1, r2 )
    call Maximum( char1, char2, char3 )

    read *
end program Interfaces

Код

module Procedures

    implicit none

    ! Объединяем под одним родовым именем функции и подпрограмму.
    interface Maximum
        ! Заголовки процедур с их специфическими именами. Указаны только имена
        ! процедур, т.к. они определены в этом же модуле (а данном случае -- в
        ! модуле).
        module procedure IntegerMax, RealMax, CharacterMax
    end interface Maximum

! Используемые процедуры определены внутри модуля.
contains
    
    function IntegerMax( int1, int2 )
        integer IntegerMax, int1, int2

        IntegerMax = Max( int1, int2 )
    end function IntegerMax

    function RealMax( real1, real2 )
        real RealMax, real1, real2

        RealMax = Max( real1, real2 )
    end function RealMax

    subroutine CharacterMax( char1, char2, char3 )
        character(*) char1, char2, char3

        print *, Max( Len(char1), Len(char2) )
    end subroutine CharacterMax
end module Procedures


Более того, саму перегрузку можно делать в программе. В модуле процедуры будут только описаны, но не объединены под одним именем.
Пример 1.4
Код

program Interfaces

    use Procedures
    
    implicit none
    
    ! Объединяем под одним родовым именем функции и подпрограмму.
    interface Maximum
        ! Заголовки процедур с их специфическими именами. Указаны только имена
        ! процедур, т.к. они определены в этом же модуле (а данном случае -- в
        ! модуле).
        module procedure IntegerMax, RealMax, CharacterMax
    end interface Maximum
    
    integer :: i1 = 3, i2 = 4
    real :: r1 = 4, r2 = 5
    character(*), parameter :: char1 = "Welcome"
    character(*), parameter :: char2 = "Vingrad,"
    character(*), parameter :: char3 = "Lera!"

    ! Используя родовое имя, вызываем каждый раз свою процедуру,.
    print *, Maximum( i1, i2 ), Maximum( r1, r2 )
    call Maximum( char1, char2, char3 )

    read *
end program Interfaces

Код

module Procedures

    implicit none

! Используемые процедуры определены внутри модуля.
contains
    
    function IntegerMax( int1, int2 )
        integer IntegerMax, int1, int2

        IntegerMax = Max( int1, int2 )
    end function IntegerMax

    function RealMax( real1, real2 )
        real RealMax, real1, real2

        RealMax = Max( real1, real2 )
    end function RealMax

    subroutine CharacterMax( char1, char2, char3 )
        character(*) char1, char2, char3

        print *, Max( Len(char1), Len(char2) )
    end subroutine CharacterMax
end module Procedures



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

interface operator(op)

op -- существующий или придуманный оператор. Последнее поддерживают немногие языки. Процедуры, которые задают операции должны обязательно быть функциями, которые содержат один параметр в случае определения унарной операции и два параметра в случае определения бинарной рперации. Оба параметра должны иметь вид связи in: intent(in).
Процедуры могут быть модульными и нет. Весь предыдущий раздел по виду подробности описания распространяется и на этот случай.
При перегрузке присваивания интерфейс имеет вид:
Код

interface assignment(=)

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

Пример 2.1
Код

program Interfaces

    use PointType
    
    implicit none
    
    type(Point) point1, point2
    
    ! Используем операцию присваивания точке комплексного числа.
    point1 = (3.7, 8.2)
    point2 = (6.3, 1.8)
    
    ! Используем операцию сложения.
    point1 = point1 + point2
    
    print *, point1

    read *
end program Interfaces

Код

module PointType
    implicit none
    
    type Point
        real x
        real y
    end type Point
    
    ! Задаем операцию присваивания точке комплексного числа.
    interface assignment(=)
        module procedure AssignIntegerToPoint
    end interface assignment(=)
    
    ! Задаем операцию сложения точек.
    interface operator(+)
        module procedure SumPoints
    end interface operator(+)
    
contains

    subroutine AssignIntegerToPoint( dot, compl )
        type(Point), intent(inout) :: dot
        complex, intent(in) :: compl
        
        ! Используем конструктор.
        dot = Point( Real(compl), Imag(compl) )
        ! Это равносильно:
        !dot%x = Real(compl)
        !dot%y = Imag(compl)
    end subroutine AssignIntegerToPoint
    
    function SumPoints( point1, point2 )
        type(Point) SumPoints
        type(Point), intent(in) :: point1, point2
        
        ! Используем конструктор.
        SumPoints = Point( point1%x + point2%x, point1%y + point2%y )
        ! Это равносильно:
        !SumPoints%x = point1%x + point2%x
        !SumPoints%y = point1%y + point2%y
    end function SumPoints
end module PointType


Результат выполнения
Код

   10.00000       10.00000

Вместо оператора + можно было бы написать .plus.. Тогда код выглядел бы так:

Пример 2.2
Код

program Interfaces
    ...    

    ! Используем операцию сложения.
    point1 = point1 .plus. point2
    
    ...
end program Interfaces

Код

module PointType
    ...
    
    ! Задаем операцию сложения точек .
    interface operator(.plus.)
        module procedure SumPoints
    end interface operator(.plus.)

    ...
end module PointType


Указывать родовое имя, присваивание или перегружаемый оператор в
операторе end interface необязательно.

3. Определение внешних процедур
Тут следует посмотреть на Пример 1.1. Процедуры определены вне какого-то модуля, на который можно было бы ссылаться. Тем не менеее процедуры содержаться в исходных файлах проекта. В данном случае они описаны в том же файле, что и основная программа. Чтобы иметь возможность обращаться к ним, их заголовки и были описаны в интерфейсе. При этом не обязательно давать им родовое имя, оно может отсутсвовать, если нам достаточно будет обращения через их фактические внешние имена.
Процедуры после определения в интерфейсном блоке приобретают атрибут external. Имена процедур с атрибутом external могут быть использованы в качестве параметров других процедур. Этот атрибут применяется также для замены встроенной процедуры на пользовательскую.
В интерфейсе можно указать директивы компилятора, чтобы, например, обратиться к процедуре, содержащейся в DLL. Если не пользуетесь DLL, то не стоит забивать себе голову.

Пример 3.
Код

interface
    function FMin( ax, bx, F, tol )
        !DEC$ ATTRIBUTES DLLIMPORT, STDCALL, DECORATE, ALIAS : "_FMin" :: FMin

        interface
            function F( x )
                !DEC$ ATTRIBUTES STDCALL :: F

                real F
                real, intent(in) :: x
            end function F
        end interface

        real FMinS
        real, intent(in) :: ax, bx, tol
    end function FMin
end interface


Это сообщение отредактировал(а) Cr@$h - 25.1.2006, 14:05
PM MAIL ICQ   Вверх
valvliv
Дата 25.1.2006, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 25.1.2006

Репутация: нет
Всего: 1



Большое спасибочки! Буду изучать, потом еще попристаю! smile

Л.

PM MAIL   Вверх
Cr@$h
Дата 25.1.2006, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: 1
Всего: 41



Цитата(valvliv @ 25.1.2006, 23:59 Найти цитируемый пост)

Большое спасибочки! Буду изучать, потом еще попристаю!

Договорились. smile Только не забывайте, по правилам форума в одной теме не должно быть разных вопросов.
PM MAIL ICQ   Вверх
valvliv
Дата 25.1.2006, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 25.1.2006

Репутация: нет
Всего: 1



Учту smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Fortran | Следующая тема »


 




[ Время генерации скрипта: 0.1206 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.