زیر برنامه ها: رویه ها و عملکردها - 1


یک زیربرنامه قسمت جداگانه ای از برنامه است که نام دارد و وظیفه جداگانه خود را حل می کند. زیربرنامه در ابتدای برنامه اصلی قرار دارد و می توان آن را از برنامه اصلی با مشخص کردن نام راه اندازی کرد ( فراخوانی کرد)

استفاده از زیر روال ها به شما این امکان را می دهد که در صورت نیاز به نوشتن کد مشابه در مکان های مختلف برنامه، از تکرار کد جلوگیری کنید. 
کتابخانه‌هایی که به یک برنامه وارد می‌شوند (مثلاً ریاضی کتابخانه ریاضی) از زیر روال‌هایی تشکیل شده‌اند که قبلاً توسط شخصی کامپایل شده‌اند. برنامه نویسان نیازی ندارند به الگوریتم هایی که پیاده سازی می کنند فکر کنند، بلکه به سادگی آنها را اعمال می کنند و فقط به این فکر می کنند که دقیقاً چه کاری انجام می دهند. این یک صرفه جویی بزرگ در زمان است. نیازی به نوشتن الگوریتمی نیست که قبلا توسط شخص دیگری نوشته شده باشد.

هر روتین فقط باید یک کار انجام دهد:  یا فقط چیزی را محاسبه کنید، یا مقداری داده را خروجی بگیرید، یا کار دیگری انجام دهید. 

دو نوع زیر روال وجود دارد - روش هاو عملکرد

زیربرنامه‌ها برخی از اقدامات را انجام می‌دهند، مانند چاپ نتیجه روی صفحه به شکلی خاص (یک مثال ساده، عبارت writeln() یک زیربرنامه استاندارد است که به اطلاعات صفحه نمایش)

زیرروال های تابع نتیجه ای را برمی گرداند (عدد، رشته کاراکتر و غیره) که می توانیم در برنامه اصلی استفاده کنیم.

بیایید سعی کنیم یک روش ساده بنویسیم:
فرض کنید باید رشته "Error" را روی صفحه نمایش دهیم هر بار که ممکن است به دلیل خطای کاربر خطایی در کد رخ دهد (مثلاً وقتی داده های نادرست وارد می کند)
این را می توان با نوشتن بیانیه انجام داد <پیش> writeln('Error'); و حالا تصور کنید که چنین خطی باید در بسیاری از جاهای برنامه درج شود. البته، شما فقط می توانید آن را در همه جا بنویسید. اما این راه حل دو اشکال دارد.
1) این رشته بارها در حافظه ذخیره می شود
2) اگر بخواهیم خروجی خطا را تغییر دهیم، باید این خط را در طول برنامه تغییر دهیم، که نسبتاً ناخوشایند است

برای چنین مواردی، مراحل لازم است.
یک برنامه با رویه ممکن است به شکل زیر باشد: <پیش> ... با استفاده از namespace std. رویه printError(); // شرح روش شروع writeln('خطا'); // body body - دستوراتی که رویه اجرا خواهد کرد پایان؛ // برنامه اصلی شروع؛ ... چاپگر(); // روند اجرا را شروع کنید. ما فقط نام رویه ای را که می خواهیم اجرا کنیم را مشخص می کنیم. ... چاپگر(); ... پایان. رویه با کلمه procedure شروع می شود. بعد از نام رویه، پرانتزهایی نوشته می شود که نشان دهنده متغیرها و انواع آنهاست که اجرای رویه به آنها بستگی دارد. به عنوان مثال:

var a, b, answer: integer;
روش Sum(a, b: integer);
شروع
    پاسخ := a + b;
پایان؛

تمام دستوراتی که در یک رویه اجرا می شوند تورفتگی دارند. 

رویه ها قبل از برنامه اصلی نوشته می شوند

برای اجرای یک رویه، در برنامه اصلی باید آن را با نام صدا بزنید و به یاد داشته باشید که پرانتز بنویسید!
شما می توانید یک رویه را در یک برنامه هر چند بار فراخوانی کنید.

حالا بیایید تصور کنیم که بسته به نوع اشتباه کاربر، باید پیام های مختلفی را در پاسخ به خطای کاربر نمایش دهیم.
در این صورت، می توانید رویه خود را برای هر خطا بنویسید:   <پیش> رویه printErrorZero(); شروع writeln('خطا. تقسیم بر صفر!'); پایان؛ <پیش> رویه printErrorInput(); شروع writeln('خطا در ورودی!'); پایان؛ اگر خطاهای احتمالی بسیار بیشتری وجود داشته باشد چه؟ این راه حل برای ما مناسب نیست!
ما باید یاد بگیریم که چگونه رویه را با گفتن اینکه چه پیام خطایی نمایش دهد، کنترل کنیم.
برای این کار به پارامترهایی نیاز داریم که بعد از نام رویه در پرانتز می نویسیم <پیش> فرآیند printError(s: string); شروع نوشتن (ها)؛ پایان; در این روش، s یک پارامتر است - یک متغیر ویژه که به شما امکان می دهد رویه را کنترل کنید.
پارامتر متغیری است که نحوه عملکرد زیربرنامه را تعیین می کند. نام پارامترها با نقطه ویرگول در سربرگ زیربرنامه از هم جدا شده اند. بعد از پارامتر، یک کولون با نوع آن دنبال می شود.

اکنون، هنگام فراخوانی رویه، باید مقدار واقعی را که به پارامتر (متغیر s) در داخل رویه ما تخصیص داده می شود، در براکت ها نشان دهید. <پیش> printError('خطا! تقسیم بر صفر!'); این مقدار آرگومان نامیده می شود.
Argumentمقدار پارامتری است که هنگام فراخوانی به زیربرنامه ارسال می شود.
یک آرگومان نه تنها می تواند یک مقدار ثابت باشد، بلکه می تواند یک متغیر یا یک عبارت حسابی نیز باشد.

اغلب لازم است از متغیرهای اضافی استفاده شود که فقط در زیربرنامه استفاده می شوند. چنین متغیرهایی local (یا محلی) نامیده می شوند و فقط می توانند در زیر برنامه ای که در آن ایجاد شده اند دستکاری شوند.
 
محدوده متغیر محلی تابع یا رویه‌ای است که در آن اعلام می‌شود
بنابراین، می توان دامنه (حوزه) یک متغیر را فقط به زیربرنامه ای که واقعاً مورد نیاز است محدود کرد. در برنامه نویسی به این تکنیکencapsulation  - پنهان کردن یک متغیر از تغییر از خارج.

اگر لازم است متغیری را تعریف کنید که در هر نقطه از برنامه قابل مشاهده باشد (در هر زیربرنامه)، آنگاه چنین متغیرهایی خارج از همه زیربرنامه ها اعلام می شوند (برنامه 3 را از جدول زیر ببینید)
چنین متغیرهایی جهانی نامیده می شوند.

تجزیه و تحلیل سه برنامه: <بدن> اعلان می شود نمایش داده می شود روی صفحه نمایش داده می شود.
1) در این برنامه متغیر i محلی است. یک متغیر محلی در یک زیربرنامه2) در اینجا، حتی اگر یک متغیر i در برنامه اصلی (با مقدار 7) وجود داشته باشد، یک متغیر محلی جدید i با مقدار 5 ایجاد می شود. 
وقتی این برنامه را اجرا می کنید، روی صفحه مقدار 75
3) این برنامه دارای یک متغیر جهانی i است. مقدار آن را می توان در یک زیر روال و در داخل برنامه اصلی تغییر داد
رویه با متغیر سراسری i کار می کند و مقدار جدیدی برابر با 2 به آن اختصاص داده می شود. مقدار 2
تست رویه();
var i: عدد صحیح؛
شروع
    i := 5;
    writeln(i);
پایان؛
var i: عدد صحیح؛

روش تست();
var i: عدد صحیح؛
شروع
    i := 5;
    writeln(i);
پایان؛

شروع
    i := 7;
    نوشتن (i)؛
    test();
پایان.
var i: عدد صحیح؛

روش تست();
شروع
    i := 2;
پایان؛

شروع
    test();
    writeln(i);
پایان.

مشکل: روشی بنویسید که مقادیر دو متغیر را تعویض کند.
ویژگی های این کار این است که ما به تغییرات ایجاد شده در رویه نیاز داریم تا به برنامه فراخوانی شناخته شود.

بیایید سعی کنیم روال را به این صورت بنویسیم:

var x, y: عدد صحیح; <پیش> Procedure Swap(a, b: integer); // با چنین توصیفی از پارامترهای رویه، var c: عدد صحیح; شروع // مقادیر آرگومان ها را کپی می کند (x و y) // متغیرهای a و b متغیرهای مستقلی هستند که به x و y مرتبط نیستند ج := a; a := b; b := c; پایان؛ شروع x := 1;   y := 2; مبادله (x, y); //مقادیر متغیرهای x و y (آگومان ها) در پارامترهای a و b کپی می شوند. writeln('x = '، x، '، y = '، y); // x=1، y=2 پایان. اگر این برنامه را اجرا کنید، می بینید که مقادیر متغیرهای x و y تغییر نکرده است. برای اینکه پارامترها مقادیر آرگومان‌ها را تغییر دهند، باید از عبور داده‌ها با مرجع استفاده کنید. برای انجام این کار، پس از نام نوع داده در سربرگ زیربرنامه باید کلمه var  را قرار دهید. <پیش> Procedure Swap(var a, b: integer);   // اکنون متغیرهای a و b آدرس متغیرهای x و y را در حافظه دریافت می کنند var c: عدد صحیح;  شروع ج := a; a := b; b := c; پایان؛ استفاده: اگر یک آرگومان را با مرجع ارسال می‌کنید، آنگاه فقط نام متغیر (نه یک عدد و نه یک عبارت حسابی) می‌تواند در این مکان هنگام فراخوانی رویه باشد!< br />
روشی را مانند این فراخوانی نکنید: <پیش> مبادله (x، 4)؛ تعویض (5+x، y);