Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] динамический массив в функцию и вернуть


Автор: Mormishka 20.12.2010, 19:14
Не могу понять, вот так?


Код

function f(a,n) result b

integer :: a(:),b(:)
allocate a(n),b(n)
b=a

end function f


Автор: FCM 20.12.2010, 21:08
Сформулируй более четко, чего ты хочешь.

Если хочешь размещать в функции динмассив, то соотв. форм.параметр должен иметь атрибут ALLOCATABLE ( и соотв. аргумент должен быть ALLOCATABLE)
Если хочешь возвращать динмассив как рез-т функции, то функция должна быть объявлена как возвращающая  массив (:) и иметь атрибут ALLOCATABLE  (причем это надо указать в теле функции (до исполняемых инструкций)).

Автор: Mormishka 21.12.2010, 18:08
FCM, 
Я хочу чтобы функция принимала динамический массив a и целочисленную переменную n по значению. А возвращала массив a. Я не понимаю стоит ли писать в теле функции 
Код

allocate a(n) 
allocate f(n) 

или нет?


Я все правильно написал?
Код

function f(a,n)
integer allocatable :: a(:),f(:)
integer n
f=a
end function f

Автор: Mormishka 21.12.2010, 19:28
Попробовал написать функцию прогонки. Не могу использовать локальные  динамические массивы?
Код

    double precision function progon(cf, df, ef, bf, n)
        implicit none
1        double precision, allocatable::progon(:),cf(:),df(:),ef(:),bf(:)
        integer(4) :: n
        allocate (cf(n),df(n),ef(n),bf(n))
2        integer(4):: i
3        double precision, allocatable::al(:),be(:)
        allocate (al(n),be(n))
        al(2)=-ef(1)/df(1)
        be(2)=bf(1)/df(1)
        do i=1,n-1
            al(i + 1) = -ef(i) / (df(i) + cf(i) * al(i))
            be(i + 1) = (-cf(i) * be(i) + bf(i)) / (df(i) + cf(i) * al(i))
        end do
        progon(n) = (-cf(n) * be(n) + bf(n)) / (df(n) + cf(n) * al(n))
        do i=n-1,1,-1    
            progon(i) = al(i + 1) * progon(i + 1) + be(i + 1)
        end do
    end function progon


------ Построение начато: проект: PVFProject2, Конфигурация: Debug Win32 ------
Compiling Project  ...
ConsoleApp.f90
1 C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\ConsoleApp.f90(126) : warning W0119 : Redundant specification for progon
2 C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\ConsoleApp.f90(129) : error S0070 : Incorrect sequence of statements 
3 C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\ConsoleApp.f90(130) : error S0070 : Incorrect sequence of statements 
  0 inform,   1 warnings,   2 severes, 0 fatal for progon
ConsoleApp.f90
1 C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\ConsoleApp.f90(126) : warning W0119 : Redundant specification for progon
2 C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\ConsoleApp.f90(129) : error S0070 : Incorrect sequence of statements 
3 C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\ConsoleApp.f90(130) : error S0070 : Incorrect sequence of statements 
  0 inform,   1 warnings,   2 severes, 0 fatal for progon
PVFProject2 build failed.
Build log was saved at "file://C:\Users\Александр\Documents\Visual Studio 2008\Projects\PVFProject2\PVFProject2\Win32\Debug\BuildLog.htm"

========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

Автор: FCM 21.12.2010, 21:00
5-ая строка - исполняемая инструкция
6,7-ая - инструкции объявления
- неправильная последовательность инструкций: Incorrect sequence of statements

Локальные массивы   al, be   не обязательно делать ALLOCATABLE - естесТвеннее сделать их автоматическими
т.е. просто определить как
REAL(8) :: al(n), be(n)

Правда пока не совсем понимаю общий ход мысли.

Если массивы, передаваемые, через параметры cf, df, ef, bf, задаются в программной единице вызывающей progon, и размещаются в той же единице, то тогда не нужно, чтобы формальные параметры были allocatable - они могут быть обычными. Формальные прарметры процедуры делают allocatable, если массивы надо размещать именно в процедуре, а до вызова процедуры они неразмещенные.

Т.е. если массивы размещаются в вызывающей программной ед-це, то progon может принимать их как обычные статические массивы. Что касается рез-та функции, то поскольку ее размер известен в момент вызова процедуры, ее можно объявить просто как функцию, возвращающую массив размера n

Код

double precision function progon(cf, df, ef, bf, n)
        implicit none
        integer(4) :: n
        double precision:: progon(n)
        double precision:: cf(n),df(n),ef(n),bf(n)
        integer(4):: i
        double precision ::al(n),be(n)
        ...


PS/ В Фортране возможно передавать массив, не передавая его размер (размер можно получить с помощью функции SIZE)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)