سؤال

في Fortran ، يوجد اختلاف واضح بين الوظيفة والروتين الفرعي: تُرجع الوظائف قيمة واحدة ، لا تُرجع الروتين الفرعي أي قيمة. هذا يقدم سلسلة من الاختلافات بين الاثنين. أحد الأمثلة على ذلك هو الدلالات الدلالية: يمكنك استدعاء وظيفة كما هو الحال في اللغات الأخرى ، ولكن من أجل استدعاء روتين فرعي يجب عليك إصدار أ call بيان أولا.

مع إضافة المؤشرات وأنواع البيانات في Fortran95 ، يبدو أنه لا يوجد قيود فنية في جعل أي برنامج فرعي وظيفة ، والحفاظ على الروتين الفرعي فقط للإرث. يمكن أن تُرجع الوظائف صفرًا (يمكنك فقط إرجاع عدد صحيح وهمية) أو قيم واحدة أو متعددة (على سبيل المثال ، يمكنك إرجاع مؤشر إلى مثيل مخصص من النوع ، مثل زوج C ++ STL).

هل أنا مخطئ؟ هل ما زلنا بحاجة إلى روتين فرعي في برمجة Fortran نظرًا لبعض الميزات التي لديها الروتين الفرعي والوظائف لا؟

هل كانت مفيدة؟

المحلول

إذا بحثت عن محفوظات Comp.lang.fortran ، فستجد مناقشات حول دلالات الوظائف. اتضح أنه لم يتم تحديده بوضوح في المعيار وما هو غير مسموح بالوظائف التي لها آثار جانبية.

على سبيل المثال ، هل يمكن للمترجم تحسين

x = foo (args) + foo (args)

داخل

x = 2 * foo (args)

أو مثال آخر ، فكر

x = y + foo (y)

ماذا لو قام Foo () بتغيير قيمة Y؟ تذكر أن Fortran ليس لديه مفهوم C لنقاط التسلسل.

بشكل عام ، تتمثل التوصية التي قدمها العديد من الخبراء في استخدام الوظائف فقط إذا كانت نقية ، وإلا استخدم الروتين الفرعي. وهذه نصيحة أن أتابع نفسي أيضًا.

نصائح أخرى

لا أعتقد أن الروتين الفرعي يذهبون إلى أي مكان. تسمح معظم اللغات الأخرى بالأساليب التي لا تُرجع القيم. لا أستطيع أن أرى أي سبب لسبب هذا شيء سيء. لا ينبغي نقل أي شخص لتغيير شيء ما.

يقول Legacy وحده أن الروتين الفرعي ستستمر طالما يفعل فورتران. وطالما كان فورتران موجودًا ، فلن يكون هناك شيء خاطئ في كتابة طريقة لا تنفذ أي شيء ولا تعيد شيئًا.

تحديث:

لماذا تقول "متاعب"؟ ما هي الصفقة الكبيرة؟ لا أتفق مع فكرة أن الروتين الفرعي هي "متاعب" عند استخدامها في موقف مناسب.

حافظت Fortran على تمييز بين الوظائف والتوصيل الفرعي منذ الإصدار 77 وربما في وقت سابق. لغات العائلة C الأخرى تفعل ذلك أيضًا. لماذا هذا فجأة مثل هذه المتاعب؟ حتى اللغات التي لديها مؤشرات وأشياء لفترة طويلة لها طرق تعود باطلة.

أنت تحاول برمجة C في Fortran مرة أخرى ، أليس كذلك؟ ؛-)

في رأيي ، نعم - نحن نفعل. لأنه إذا كان من الأسهل فهمها لسبب واحد فقط ، فهي تستخدم على نطاق أوسع من الوظائف.

أيضا ، -1 ، لأنني أعتقد أن هذا ليس سؤال بناء. إذا كنت لا تحبهم ، فلا تستخدمهم.

إذا فهمت بشكل صحيح ، فإن ستيفانو ليس ضد فكرة الروتين الفرعي. الرأي ضدهم هراء. انه ضد استخدام أنماط مختلفة للروتين الفرعي/الوظائف.

فورتران هي لغة البرمجة الضرورية. بتعبير أدق هي لغة برمجة إجرائية (وحتى أدق أن تكون لغة برمجة منظمة).

في البرمجة الضرورية لدينا دولة وبيانات لتغييرها. في البرمجة الإجرائية أدواتنا لإجراء التغييرات هي إجراءات (نقوم بتطبيق التغييرات داخل الإجراءات). قد يعيد الإجراء أو لا يعيد بعض القيمة. ولا أعتقد أن هذه الحقيقة (إما قيمة إرجاع الإجراء أم لا) هي سبب مهم للغاية لوجود كيانين مختلفين في لغة البرمجة. يمكن أن يكون لدينا وظائف فقط (كما هو الحال في C) وإرجاع شيء مميز عندما لا نحتاج فعليًا إلى إعادة شيء ما (باطل). أو يمكن أن يكون لدينا فقط الإجراءات وبناء الجملة الخاص الذي يسمح بإرجاع القيم كما في Modula-2 ، Oberon ، ...

ربما يجب أن يكون لدى اللغة نمط واحد فقط لإعلان الإجراءات. وأنا أتفق معك يا ستيفانو.

حقيقة أنني يجب أن أجيب على هذا السؤال مجنونة ، ولكن هذا هو ما هو عليه.

ينبع الفرق من حقيقة أنه لا يمكنك "استدعاء وظائف مثل اللغات الأخرى" في فورتران. بينما في C يمكنك استدعاء وظيفة عدد صحيح دون تعيين القيمة ، مثال

int foo() {
    return 5;
}
int main() {
    foo(); // this works
}

في فورتران ، عليك دائمًا ربط متغير استلام. مثال

module test
   implicit none

contains
   integer function foo()
      print *, "hello"
      foo = 0
   end function

end module

program hello
   use test
   integer :: x

   x = foo() ! this works
   foo() ! this does not compile

end program hello

وهذا يعني أن "محاكاة" وظيفة الفراغ عن طريق إعادة عدد صحيح وهمية لا يزال لا يسمح لك بالاتصال دون وجود متغير مستقبل.

في فورتران ، void نوع العودة غير موجود. من الناحية الفنية ، يمكنك هيكلة البرنامج الخاص بك بجميع الوظائف ، واستبدال كل حدوث call بيان مع x = كما هو موضح أعلاه ، ولكن هذا لن يجعل بناء الجملة الخاص بك مماثلًا لـ C أو اللغات الأخرى على أي حال ، حيث لا يوجد تمييز بين وظائف إعادة الفراغ والوظائف العائدة غير المودعة. الروتين الفرعيون هي الكيانات الوحيدة التي تسمح "بإعادة باطل" ، لكن الدلالي لإجراء المكالمة تختلف ببساطة. بصرف النظر عن ذلك ، لا يوجد فرق بين الاثنين.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top