फोरट्रान से फोरट्रान में मुख्य कार्यक्रम के लिए आवंटित सरणी पारित करना; उपयोग या मॉड्यूल? इंटरफेस?

Aug 16 2020

मैं एक सबरूटीन में एक सरणी आवंटित करना चाहता हूं, और फिर मुख्य कार्यक्रम में इस सरणी का उपयोग कर सकता हूं और इसे किसी अन्य सबऑउटआउट में पास कर सकता हूं। अतीत में (F77?) पासिंग को एक सामान्य ब्लॉक में किया जा सकता था, लेकिन आजकल एक मॉड्यूल का उपयोग करने के लिए इष्ट प्रक्रिया लगती है। जब मैं यह कोशिश करता हूं, जैसा कि कोड उदाहरण में, संकलक मुझे बताता है

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

जाहिरा तौर पर, मुख्य कार्यक्रम सोचता है कि 'एफ' एक अदिश राशि है: लेकिन, मैंने इस कोड को इस अर्थ में पढ़ा है कि मैंने इसे एक आयामी आयामी के रूप में घोषित किया है, जो कि सबरूटीन के अंदर और मुख्य कार्यक्रम दोनों में है। मैं क्या खो रहा हूँ?

मैंने विभिन्नताओं की कोशिश की है, जैसे कि मॉड्यूल के हिस्से के रूप में चर घोषित करना, लेकिन कुछ भी मैं संकलन त्रुटि-मुक्त नहीं सोच सकता था (और कुछ ने कई और त्रुटियों का उत्पादन किया; --()। किसी भी अंतर्दृष्टि को सबसे अधिक सराहना की जाती है।

          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

जवाब

2 francescalus Aug 16 2020 at 17:19

फोरट्रान में मॉड्यूल अन्य भाषाओं में हेडर फ़ाइलों की तरह नहीं हैं, जो केवल कहीं और परिभाषित चीजों के बारे में जानकारी प्रदान करते हैं। "आस्थगित परिभाषा" (सबमॉड्यूल्स) की अवधारणा है, लेकिन इस मामले में मॉड्यूल को सबरूटीन के बारे में सब कुछ कहना चाहिए, न कि केवल इसके अस्तित्व को इंगित करने का प्रयास।

प्रश्न के उदाहरण में, हमारे पास है: मुख्य कार्यक्रम; subsमॉड्यूल प्रक्रिया के साथ एक मॉड्यूल makef; एक बाहरी सबरूटीन makef

मुख्य कार्यक्रम मॉड्यूल subs, और इसकी प्रक्रिया का उपयोग करता है makef, इसलिए मुख्य कार्यक्रम में संदर्भ makefउस मॉड्यूल प्रक्रिया के लिए है जो बाहरी सबरूटीन नहीं है makef

मॉड्यूल सबरूटीन makefका तर्क है fजिसमें कोई घोषणा बयान नहीं है, जिससे यह स्पष्ट रूप से घोषित स्केलर / बाहरी फ़ंक्शन है। यह संकलक का संदेश है। implicit noneमॉड्यूल में उपयोग करें , जैसे कि यह मुख्य कार्यक्रम और बाहरी सबरूटीन में है।

सबरूटीन की पूरी परिभाषा को मॉड्यूल में रखा जाना चाहिए:

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

वैकल्पिक रूप से, यदि कोई बाहरी प्रक्रिया के बाद के कार्यान्वयन को संदर्भित करना चाहता है, तो एक इंटरफ़ेस ब्लॉक मॉड्यूल में सबरूटीन को स्वयं घोषित किए बिना सुविधा दे सकता है। इस मामले में पूर्ण इंटरफ़ेस निर्दिष्ट करना अभी भी आवश्यक होगा:

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

इस मामले में, इंटरफ़ेस ब्लॉक को प्राथमिकता न दें।

VladimirF Aug 16 2020 at 13:07

आपने केवल पहली और अंतिम पंक्ति की प्रति मॉड्यूल में रखी थी। वह काम नहीं कर सकता। आपको मॉड्यूल में पूरे सबरूटीन को स्थानांतरित करना होगा।