tahsis edilen diziyi alt yordamdan fortran'daki ana programa geçirmek; kullanım veya modül? arayüz?

Aug 16 2020

Bir alt yordama bir dizi ayırmak ve sonra bu diziyi ana programda kullanmak ve onu başka bir alt yordama geçirmek istiyorum. Geçmişte (F77?) Geçiş ortak bir blokta yapılabilirdi, ancak günümüzde tercih edilen prosedür bir modül kullanmak gibi görünüyor. Bunu denediğimde, kod örneğinde olduğu gibi, derleyici bana

Rank mismatch in argument ‘f’ at (1) (scalar and rank-1)

Görünüşe göre, ana program 'f'nin skaler olduğunu düşünüyor: ama bu kodu, onu hem alt programda hem de ana programda tek boyutlu bir dizi olarak ilan ettiğim anlamına gelecek şekilde okudum. Neyi kaçırıyorum?

Değişkenleri modülün bir parçası olarak bildirmek gibi varyasyonları denedim, ancak aklıma gelen hiçbir şey derlemeyi hatasız hale getirmedi (ve bazıları çok daha fazla hata üretti ;-() Herhangi bir anlayış çok takdir edilmektedir.

          module subs
        contains
        subroutine makef(f)
        end subroutine makef
      end module subs
c-----------------------------------------------------------------------
      program work

      use subs
      implicit none
        real, allocatable :: f(:)

      call makef(f)

      write (*,*) f
      stop
      end
c---------------------------------------------------------------------
      subroutine makef(f)
      implicit none

      real, allocatable, intent(out) :: f(:)
      integer :: i
      integer :: is

      is=10
      allocate(f(-is:is))

      do i=-is,is
        f(i)=i
      end do
      return
      end subroutine makef

Yanıtlar

2 francescalus Aug 16 2020 at 17:19

Fortran'daki modüller, yalnızca başka yerde tanımlanan şeyler hakkında bilgi sağlayan diğer dillerdeki başlık dosyalarına benzemez. "Ertelenmiş tanım" (alt modüller) kavramı vardır, ancak bu durumda modül, alt program hakkında her şeyi söylemeli, sadece varlığına işaret etmeye çalışmamalıdır.

Soru örneğinde, elimizde: ana program; Bir modül subsModül prosedüre makef; harici bir altyordam makef.

Ana program modülü subsve prosedürünü kullanır makef, bu nedenle ana programdaki referans makef, harici alt rutin değil, o modül prosedürüdür makef.

Modül alt yordamı makef, fbildirim ifadeleri içermeyen argümana sahiptir, bu da onu dolaylı olarak bildirilmiş bir skaler / harici işlev yapar. Bu derleyicinin mesajıdır. implicit noneModüllerde, tıpkı ana programda ve buradaki harici alt programda olduğu gibi kullanın .

Alt yordamın tüm tanımı modüle yerleştirilmelidir:

module subs
  implicit none
contains
  subroutine makef(f)
    real, allocatable, intent(out) :: f(:)
    integer :: i
    integer :: is

    is=10
    allocate(f(-is:is))

    do i=-is,is
      f(i)=i
    end do
  end subroutine makef
end module subs

Alternatif olarak, harici bir prosedürün sonraki uygulamasına atıfta bulunmak istenirse, bir arayüz bloğu, alt rutinin kendisini bildirmeden modülde yer alabilir. Bu durumda yine de tam arayüzü belirtmek gerekecektir:

module subs
  implicit none

! An interface block to give an explicit interface to the external subroutine makef
  interface
     subroutine makef(f)
       implicit none
       real, allocatable, intent(out) :: f(:)
     end subroutine makef
  end interface
end module subs

Bu durumda arayüz bloğunu tercih etmeyin.

VladimirF Aug 16 2020 at 13:07

Modüle sadece ilk ve son satırın kopyasını yerleştirdiniz. Bu işe yaramaz. Tüm alt programı modüle taşımalısınız.