الروتين الفرعي: الإجراءات والوظائف - 1


الإجراء الفرعي هو جزء منفصل من البرنامج له اسم ويقوم بحل المهمة المنفصلة الخاصة به. يقع الروتين الفرعي في بداية البرنامج الرئيسي ويمكن إطلاقه (يسمى) من البرنامج الرئيسي عن طريق تحديد الاسم
يتيح لك استخدام الإجراءات الفرعية تجنب تكرار الكود ، في حال احتجت إلى كتابة نفس الرمز في أماكن مختلفة من البرنامج. & nbsp؛
تتكون المكتبات التي يتم استيرادها إلى أحد البرامج (على سبيل المثال ، مكتبة الرياضيات الرياضية) من إجراءات فرعية قام شخص ما بتجميعها بالفعل. لا يحتاج المبرمجون إلى التفكير في الخوارزميات التي ينفذونها ، لكنهم ببساطة يطبقونها ، ويفكرون فقط في ما يفعلونه بالضبط. هذا هو توفير كبير للوقت. ليست هناك حاجة لكتابة خوارزمية سبق أن كتبها شخص آخر.

يجب أن يقوم كل إجراء على & nbsp؛ بعمل شيء واحد فقط: & nbsp؛ إما حساب شيء ما ، أو إخراج بعض البيانات ، أو القيام بشيء آخر. & nbsp؛

هناك نوعان من الإجراءات الفرعية - الإجراءات و الوظائف

تنفذ الإجراءات الفرعية بعض الإجراءات ، مثل طباعة النتيجة على الشاشة في نموذج معين (مثال بسيط ، العبارة writeln () هي إجراء فرعي قياسي يطبع إلى معلومات الشاشة)

الإجراءات الفرعية للوظيفة تُرجع نتيجة (رقم ، سلسلة أحرف ، إلخ.) يمكننا استخدامها في البرنامج الرئيسي.

دعنا نحاول كتابة إجراء بسيط:
لنفترض أننا بحاجة إلى عرض السلسلة "خطأ" على الشاشة في كل مرة يمكن أن يحدث خطأ في الكود بسبب خطأ المستخدم (على سبيل المثال ، عندما يقوم بإدخال بيانات غير صحيحة)
يمكن القيام بذلك عن طريق كتابة البيان <قبل> writeln (& # 39 ؛ Error & # 39 ؛) ؛ والآن تخيل أن مثل هذا الخط يحتاج إلى إدخاله في العديد من الأماكن في البرنامج. بالطبع ، يمكنك كتابتها في كل مكان. لكن هذا الحل له عيبان.
1) سيتم تخزين هذه السلسلة في الذاكرة عدة مرات
2) إذا أردنا تغيير الناتج عند الخطأ ، فسيتعين علينا تغيير هذا الخط في جميع أنحاء البرنامج ، وهو أمر غير مريح إلى حد ما

لمثل هذه الحالات ، هناك حاجة إلى إجراءات.
قد يبدو البرنامج الذي يحتوي على إجراء كما يلي: <قبل> ... استخدام اسم للمحطة؛ إجراء printError () ؛ // وصف الإجراء يبدأ writeln (& # 39 ؛ خطأ & # 39 ؛) ؛ // جسم الإجراء - الأوامر التي سينفذها الإجراء نهاية؛ // البرنامج الرئيسي يبدأ؛ ... printerror () ؛ // ابدأ إجراءات التنفيذ. نحن نحدد فقط اسم الإجراء الذي نريد تنفيذه. ... printerror () ؛ ... نهاية. يبدأ الإجراء بكلمة إجراء . & nbsp ؛ بعد اسم الإجراء ، تتم كتابة الأقواس ، والتي تشير إلى المتغيرات وأنواعها التي يعتمد عليها تنفيذ الإجراء. على سبيل المثال:

فار أ ، ب ، إجابة: عدد صحيح ؛
مجموع الإجراء (أ ، ب: عدد صحيح) ؛
تبدأ
نبسب ؛ نبسب ؛ الجواب: = أ + ب ؛
النهاية ؛

يتم وضع مسافة بادئة لجميع العبارات التي يتم تنفيذها في إجراء. & nbsp؛

الإجراءات مكتوبة قبل البرنامج الرئيسي

لتنفيذ إجراء ، في البرنامج الرئيسي تحتاج إلى تسميته بالاسم وتذكر كتابة الأقواس !
يمكنك استدعاء إجراء في برنامج أي عدد من المرات.

الآن دعنا نتخيل أننا بحاجة إلى عرض رسائل مختلفة ردًا على خطأ المستخدم ، اعتمادًا على نوع الخطأ الذي ارتكبه.
في هذه الحالة ، يمكنك كتابة الإجراء الخاص بك لكل خطأ: & nbsp؛ <قبل> إجراء printErrorZero () ؛ يبدأ writeln (& # 39 ؛ خطأ. القسمة على الصفر! & # 39 ؛) ؛ نهاية؛ <قبل> إجراء printErrorInput () ؛ يبدأ writeln (& # 39 ؛ خطأ في الإدخال! & # 39 ؛) ؛ نهاية؛ ماذا لو كان هناك العديد من الأخطاء المحتملة؟ هذا الحل لن يناسبنا!
نحتاج إلى معرفة كيفية التحكم في الإجراء من خلال إخباره برسالة الخطأ التي سيتم عرضها.
للقيام بذلك ، نحتاج إلى معلمات نكتبها بين قوسين بعد اسم الإجراء <قبل> إجراء printError (s: string) ؛ يبدأ writeln (ق) ؛ النهاية ؛ في هذا الإجراء ، تعتبر s معلمة - متغير خاص يسمح لك بالتحكم في الإجراء.
المعلمة هي متغير يحدد كيفية عمل الإجراء الفرعي. يتم سرد أسماء المعلمات مفصولة بفواصل منقوطة في رأس البرنامج الفرعي. بعد المعلمة ، النقطتان & nbsp؛ متبوعة بنوعها.
الآن ، عند استدعاء الإجراء ، تحتاج إلى الإشارة بين قوسين إلى القيمة الفعلية التي سيتم تعيينها للمعامل (المتغيرات) داخل الإجراء الخاص بنا <قبل> printError (& # 39 ؛ خطأ! القسمة على الصفر! & # 39 ؛) ؛ هذه القيمة تسمى وسيطة.
الوسيطة هي قيمة المعلمة التي يتم تمريرها إلى الروتين الفرعي عندما يتم استدعاؤها. لا يمكن أن تكون الوسيطة قيمة ثابتة فحسب ، بل يمكن أن تكون أيضًا متغيرًا أو تعبيرًا حسابيًا.

غالبًا ما يكون من الضروري استخدام متغيرات إضافية سيتم استخدامها فقط في الروتين الفرعي. تسمى هذه المتغيرات محلية (أو محلية) ولا يمكن معالجتها إلا ضمن الروتين الفرعي الذي تم إنشاؤها فيه.
نبسب ؛
نطاق المتغير المحلي هو الوظيفة أو الإجراء الذي يتم من خلاله الإعلان عن & nbsp؛

وبالتالي ، من الممكن قصر نطاق (نطاق) المتغير فقط على الروتين الفرعي حيث يكون مطلوبًا بالفعل. في البرمجة ، تسمى هذه التقنية encapsulation & nbsp؛ - إخفاء متغير من التغيير من الخارج.

إذا كان من الضروري الإعلان عن متغير يمكن رؤيته في أي مكان في البرنامج (في أي روتين فرعي) ، فسيتم الإعلان عن هذه المتغيرات خارج جميع الإجراءات الفرعية (انظر البرنامج 3 من الجدول أدناه)
تسمى هذه المتغيرات عمومية .

حلل ثلاثة برامج: <الجسم> على الشاشة
1) في هذا البرنامج ، المتغير i محلي. يتم التصريح عن متغير محلي داخل روتين فرعي 2) هنا ، حتى لو كان هناك متغير i في البرنامج الرئيسي (بقيمة 7) ، سيتم إنشاء متغير محلي جديد i بقيمة 5. & nbsp؛
عند تشغيل هذا البرنامج ، ستعرض الشاشة القيمة 75
3) يحتوي هذا البرنامج على متغير شامل i. يمكن تغيير قيمته داخل روتين فرعي وداخل البرنامج الرئيسي
سيعمل الإجراء مع المتغير العام i وسيتم تعيين قيمة جديدة له تساوي 2. يتم عرض القيمة 2
اختبار الإجراء () ؛
var i: عدد صحيح ؛
تبدأ
نبسب ؛ نبسب ؛ أنا: = 5 ؛
نبسب ؛ نبسب ؛ writeln (i) ؛
النهاية ؛
var i: عدد صحيح ؛

اختبار الإجراء () ؛
var i: عدد صحيح ؛
تبدأ
نبسب ؛ نبسب ؛ أنا: = 5 ؛
نبسب ؛ نبسب ؛ writeln (i) ؛
النهاية ؛

تبدأ
نبسب ؛ نبسب ؛ أنا: = 7 ؛
نبسب ؛ نبسب ؛ اكتب (ط) ؛
نبسب ؛ نبسب ؛ اختبار () ؛
النهاية.
var i: عدد صحيح ؛

اختبار الإجراء () ؛
تبدأ
نبسب ؛ نبسب ؛ أنا: = 2 ؛
النهاية ؛

تبدأ
نبسب ؛ نبسب ؛ اختبار () ؛
نبسب ؛ نبسب ؛ writeln (i) ؛
النهاية.

المشكلة: اكتب إجراءً يبادل قيم متغيرين.
خصوصيات هذه المهمة هي أننا بحاجة إلى التغييرات التي تم إجراؤها في الإجراء حتى تصبح معروفة للبرنامج المتصل.

دعنا نحاول كتابة الإجراء مثل هذا:

var x ، y: عدد صحيح ؛ <قبل> إجراء مبادلة (أ ، ب: عدد صحيح) ؛ // مع هذا الوصف لمعلمات الإجراء ، فار ج: عدد صحيح ؛ start // سوف تنسخ قيم الوسيطات (x و y) // المتغيرات a و b هي متغيرات مستقلة لا علاقة لها بـ x و y ج: = أ ؛ أ: = ب ؛ ب: = ج ؛ نهاية؛ يبدأ س: = 1 ؛ نبسب ؛ ص: = 2 ؛ المبادلة (س ، ص) ؛ // قيم المتغيرات x و y (الوسائط) يتم نسخها إلى المعلمات a و b writeln (& # 39 ؛ x = & # 39 ؛، x ، & # 39 ؛، y = & # 39 ؛، y) ؛ // س = 1 ، ص = 2 نهاية. إذا قمت بتشغيل هذا البرنامج ، يمكنك أن ترى أن قيم المتغيرين x و y لم تتغير. لكي تغير المعلمات قيم الوسيطات ، يجب عليك استخدام تمرير البيانات حسب المرجع. & nbsp؛ للقيام بذلك ، بعد اسم نوع البيانات في رأس الروتين الفرعي ، يجب عليك وضع الكلمة & nbsp؛ var & nbsp؛ <قبل> إجراء مبادلة ( var a، b: عدد صحيح) ؛ نبسب ؛ // الآن يحصل المتغيران a و b على عناوين المتغيرين x و y في الذاكرة فار ج: عدد صحيح ؛ نبسب ؛ يبدأ ج: = أ ؛ أ: = ب ؛ ب: = ج ؛ نهاية؛ الاستخدام: إذا قمت بتمرير وسيطة من خلال المرجع ، فيمكن أن يكون اسم المتغير فقط ( ليس رقمًا وليس تعبيرًا حسابيًا ) في هذا المكان عند استدعاء الإجراء! < ر />
لا تطلب إجراءً مثل هذا: <قبل> المبادلة (x، 4 ) ؛ Swap ( 5 + x ، y) ؛