(C ++) الروتينات الفرعية: الإجراءات والوظائف - 1


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

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

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

تؤدي الإجراءات الفرعية بعض الإجراءات ، على سبيل المثال ، عرض النتيجة على الشاشة في شكل معين (مثال بسيط ، عامل التشغيل printf () & nbsp؛ هو إجراء فرعي قياسي يطبع المعلومات على الشاشة)

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

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

لمثل هذه الحالات ، هناك حاجة إلى إجراءات.
قد يبدو البرنامج الذي يحتوي على إجراء كما يلي: # include & lt؛ iostream & gt؛ استخدام اسم للمحطة؛ printError () باطلة // وصف الإجراء { كوت & lt؛ & lt؛ "خطأ"؛ // جسم الإجراء - الأوامر التي سينفذها الإجراء } رئيسي() { ... printError () // ابدأ إجراء التنفيذ. نحن نحدد فقط اسم الإجراء الذي نريد تنفيذه. ... خطأ طباعة () ... } يبدأ الإجراء بكلمة void . & nbsp؛ توجد أقواس فارغة بعد اسم الإجراء.
يتم وضع مسافة بادئة لجميع العبارات التي يتم تنفيذها في إجراء. & nbsp؛

تتم كتابة الإجراءات قبل الوظيفة الرئيسية main ()

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

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

المتغيرات المحلية والعالمية غالبًا ما يكون من الضروري استخدام متغيرات إضافية سيتم استخدامها فقط في الروتين الفرعي. تسمى هذه المتغيرات محلية (أو محلية) ولا يمكن معالجتها إلا ضمن الروتين الفرعي الذي تم إنشاؤها فيه.
نبسب ؛
نطاق المتغير المحلي هو الكتلة المتعرجة بين قوسين حيث يتم الإعلان عنها
البرنامج الرئيسي في C ++ هو أيضًا روتين فرعي ، لذا فإن جميع المتغيرات المعلنة داخل main () هي متغيرات محلية.
لا تعرف الإجراءات الفرعية الأخرى أي شيء عن المتغيرات المحلية للروتينات الفرعية الأخرى.

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

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

في C ++ ، عند بدء تشغيل البرنامج ، يتم تعيين جميع المتغيرات العامة تلقائيًا على صفر ( تأخذ المتغيرات المنطقية القيمة false ).


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

مهمة اكتب إجراء يتبادل قيم متغيرين.

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

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