2013-07-09 2 views
1

Я хочу рассчитать производный тип данных в подпрограмме (или функции). Как я могу ссылаться на переменную в аргументах подпрограммы?Фортран: как передать переменные типа в подпрограмму

До сих пор я мог достичь своей цели, ссылаясь на весь объект, а затем ссылаясь на переменную внутри подпрограммы. Есть ли способ ссылаться только на переменную myObj% var в аргументах подпрограммы?

PROGRAM test 

    TYPE obj 
     INTEGER :: var 
    END TYPE obj 

    TYPE (obj) :: myObj 
    CALL set(myObj) 
    PRINT*, myObj%var 

     CONTAINS 

    SUBROUTINE set(myObj) 
     TYPE (obj) :: myObj 
     myObj%var = 5 
    END SUBROUTINE set 

END PROGRAM test 

ответ

2

Вы могли бы просто написать

SUBROUTINE set(an_int) 
    integer, intent(inout) :: an_int 
    an_int = 5 
END SUBROUTINE set 

, а затем вызвать функцию так:

CALL set(myObj%var) 

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

MODULE mytype 

    IMPLICIT NONE 

    TYPE obj 
    INTEGER, PRIVATE :: var 
    CONTAINS 
    PROCEDURE, PASS :: get_var 
    PROCEDURE, PASS :: set_var 
    END TYPE obj 

CONTAINS 

    SUBROUTINE set_var(this,an_int) 
    CLASS(obj), INTENT(inout) :: this 
    INTEGER, INTENT(in) :: an_int 
    this%var = an_int 
    END SUBROUTINE set_var 

    INTEGER FUNCTION get_var(this) 
    CLASS(obj), INTENT(inout) :: this 
    get_var = this%var 
    END FUNCTION get_var 

END MODULE mytype 


PROGRAM test 

    USE mytype 
    IMPLICIT NONE 

    TYPE (obj) :: myObj 
    CALL myobj%set_var(12) 
    PRINT*, myObj%get_var() 

END PROGRAM test 
+0

Я согласен, что я бы не сделал объект, чтобы инициализировать его переменные функцией. Я пробовал тестовую версию. В конечном счете, я буду производить вычисления с использованием разных переменных из разных объектов. – astromonerd

1

Если у вас есть только компилятор F95 без всех битов 2003/2008, вот как это можно сделать.

MODULE ObjMod 
    IMPLICIT NONE 

    TYPE ObjType 
    INTEGER, PRIVATE :: var 
    END TYPE ObjType 

CONTAINS 

    SUBROUTINE ObjCreate(this) 
    TYPE(ObjType), POINTER :: this 
    allocate(this) 
    END SUBROUTINE ObjCreate 

    SUBROUTINE ObjDelete(this) 
    TYPE(ObjType), POINTER :: this 
    deallocate (this) 
    END SUBROUTINE ObjDelete 

    SUBROUTINE ObjSet(this, value) 
    TYPE(ObjType), INTENT(inout) :: this 
    INTEGER, INTENT(in) :: value 
    this%var = value 
    END SUBROUTINE ObjSet 

INTEGER FUNCTION ObjGet(this) 
    TYPE(ObjType), INTENT(inout) :: this 
    ObjGet = this%var 
END FUNCTION ObjGet 

END MODULE ObjMod 


PROGRAM test 

USE ObjMod 
IMPLICIT NONE 

TYPE (ObjType), POINTER :: testObj 

CALL ObjCreate(testObj) 
CALL ObjSet(testObj, 12) 
PRINT*, ObjGet(testObj) 
CALL ObjDelete(testObj) 
STOP 
END PROGRAM test 

Я также используется для кодирования как и в C в начале 80-х годов, прежде чем приличная C++ компилятор вышел. Что вы найдете, так это то, что многие системы, написанные в 70-х годах до начала 90-х годов, используют эту технику. Он будет работать на любом языке, который поддерживает структуры и динамическое распределение памяти.

Смежные вопросы