Функция Fortran не возвращает значение основной программе

#fortran

#fortran

Вопрос:

Я вызвал функцию integ из другой функции rter3 . Я напечатал integ значения из integ функции, и она печатает допустимые значения. Но когда я печатаю integ значения в rter3 функции, она печатает 0.00 . Я перепробовал все, что мог, чтобы понять, почему она это делает, но не смог выяснить. Пожалуйста, помогите мне здесь. Спасибо.

 function rter3(z,c1,nx1,xarray,xlocation,angl3r,gamr,probr,aaa,da1)
    use data
    integer:: z,o,nx1,lc
    double precision:: c1(nx1),w1,w2,rter3,angl3r,gamr,probr(100),aaa,da1,rati2,xarray(nx1),xlocation,div1
    double precision:: variable
    dx=0.1
    rati2=20.0
    !write(*,*) z,o,nx1,xlocation,angl3,gam
    w1=div1(c1(z-1),c1(z),dx)
    w2=div1(c1(z),c1(z 1),dx)
    variable=integ(nx1,c1,xarray,xlocation,dx,angl3r,gamr,probr,aaa,da1,w1,w2)
    rter3=rati2*variable
    write(*,*) "rter3=", rter3, variable, rati2, xlocation, gam, angl3, da1
end function rter3

function integ(nxx,hfield,xfield,loc1,diff,angl3,gam,prob,afield,dprob,ab2,af2)
    implicit none
    integer :: l,nxx,dui,kk,indx,indt
    double precision:: du(101),prob(100),am1,a,ap1,angl3,gam,diff,dprob,integ,function12,afield(100),xfield(nxx)
    double precision:: loc1,loc2,hfield(nxx),am2,ap2,ab2,af2
    !write(*,*) 'test loop', loc1, diff, angl3, gam, dprob

    do kk=1,100
        do l=1,nxx
            if (0.95*xfield(l)>=loc1-afield(kk).and. 1.05*xfield(l)<loc1-afield(kk)) then
                dui=l
                !call exit()
            endif
        enddo
        !dui= loc1-kk
        !write(*,*) "Entered integ", dui
        !write(*,*) dui
        if (dui<=3) then
            dui=3
        endif
        if (dui>= nxx-2) then
            dui=nxx-2
        endif
        am1=hfield(dui-1)
        am2=hfield(dui-2)
        a=hfield(dui)
        ap2=hfield(dui 2)
        ap1=hfield(dui 1)
        du(kk)=abs(prob(kk)*(function12(am2,am1,ap1,ap2,diff,angl3,gam,ab2,af2))*dprob)
    enddo

    integ=sum(du)
    write(*,*) "integration value=", integ, nxx, loc1, diff, angl3, gam, dprob
end function integ
  

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

Ответ №1:

Как функция rter3 «знает» интерфейс функции integ? Оба находятся в одном модуле? Если нет, возможно, rter3 не знает интерфейс и использует неявный ввод. Поскольку вы не использовали «неявное none» в rter3, это может произойти, и в этом случае биты integ будут интерпретироваться как целое число, в то время как предполагается, что они интерпретируются как двойная точность — значение будет отображаться неправильно. Мои предложения: всегда размещайте свои процедуры в модуле. Тогда у вас все в порядке с процедурами в том же модуле… компилятор может проверить согласованность аргументов. Если вы вызываете подпрограмму или функцию из основной программы или другого модуля, «используйте» модуль для получения проверки аргумента. Используйте «неявное нет». В случае, если вы забыли включить неявное none в свой исходный код, дополнительно используйте опцию компилятора, которая делает то же самое (например, -fimplicit-none для gfortran).

Комментарии:

1. Привет. Спасибо за ваш ответ. Да, вы правы, и я изначально поместил все процедуры (rter3 и integ, обе с двойной точностью) в модуль под названием «данные», который использовался в функции rter3. Я также использовал неявное none в исходном коде. Можете ли вы предложить мне что-нибудь еще, что я могу сделать? Еще раз спасибо.

2. Привет. Вместо этого я определил ‘double precision:: integ’ в rter3, и это сработало!. Каким-то образом модуль не сработал. Большое спасибо за эту идею.

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