tahsis edilen diziyi alt yordamdan fortran'daki ana programa geçirmek; kullanım veya modül? arayüz?
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
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 subs
Modül prosedüre makef
; harici bir altyordam makef
.
Ana program modülü subs
ve 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
, f
bildirim 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.
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.