دیرکن و ویژگیهای تابع
دیرکن کار پاکسازی را کنار کدی نگه میدارد که به آن نیاز دارد، تا با یک برگشت زودهنگام فراموش نشود. ویژگیهای تابع هم به مترجم میگویند تابع چه رفتاری دارد و مترجم بعضی از آنها را برایتان میسنجد.
دیرکن
دستوری که پس از دیرکن بیاید، همانجا اجرا نمیشود؛ وقتی بلوکِ دربرگیرندهاش تمام شود اجرا میشود. اگر چند دیرکن باشد، آخرین آنها زودتر اجرا میشود، درست مثل وقتی که کارها را به ترتیب وارونه برمیگردانید. رایجترین کاربردش آزادکردن چیزی درست کنار خطی است که آن را گرفته است.
تابع کار():
سرچاپ "آغاز کار"
دیرکن سرچاپ "پاکسازی نخست"
دیرکن سرچاپ "پاکسازی دوم"
سرچاپ "انجام کار"
پایان
تابع ریشه:
کار()
سرچاپ "پس از کار"
پایانهمهی راههای بیرون رفتن
دستور دیرکنشده از هر راهی که از بلوک بیرون بروید اجرا میشود: در پایان بلوک، با یک برگشت در میانه، یا با بشکن از یک حلقه. فایدهی اصلیاش همین است: تابعی که چند برگشت دارد یک دیرکن میخواهد، نه یک نسخه از پاکسازی پیش از هر برگشت.
تابع جستجو(فهرست: صحیح[]، خواسته: صحیح): صحیح:
دیرکن سرچاپ "جستجوی"، خواسته، "تمام شد"
هر ش، عضو در فهرست:
اگر عضو == خواسته:
برگشت ش
پایان
پایان
برگشت -۱
پایان
تابع ریشه:
کدها := [۴۰۴، ۲۰۰، ۵۰۰]
سرچاپ "جایگاه:"، جستجو(کدها، ۲۰۰)
سرچاپ "جایگاه:"، جستجو(کدها، ۳۰۱)
پایانخط دیرکنشده پس از آنکه نتیجه حساب شد و پیش از آنکه به دست فراخواننده برسد اجرا میشود؛ برای همین پیش از جایگاه: چاپ شده است. در ریشه هم همینطور است: برگشت ۱ باز هم دیرکنهای ریشه را اجرا میکند و به همین دلیل سیستم عامل.خروج آنجا مجاز نیست.
دیرکن مال بلوک خودش است
دیرکن در پایان بلوکی اجرا میشود که در آن نوشته شده، نه در پایان تابع. درون حلقه یعنی در پایان هر دور، و درون اگر یعنی در پایان همان شاخه.
تابع ریشه:
تکرار ۳ در روز:
دیرکن سرچاپ " بستن روز"، روز
سرچاپ "باز کردن روز"، روز
پایان
دیرکرد := ۲
اگر دیرکرد > ۰:
دیرکن سرچاپ " گزارش فرستاده شد"
سرچاپ "سفارشهای دیرکرده:"، دیرکرد
پایان
سرچاپ "تمام"
پایانپس چیزی که درون بدنهی حلقه گرفته و همانجا دیرکن شده، پیش از شروع دور بعد آزاد میشود و معمولاً همین را میخواهید.
مقدارها کی خوانده میشوند
دستور دیرکنشده متغیرهایش را هنگام اجرا میخواند، نه وقتی به خط دیرکن میرسیم. اگر متغیر در این فاصله عوض شود، دیرکن مقدار تازه را میبیند. برای نگهداشتن مقدارِ لحظهی دیرکن، اول آن را در متغیر دیگری کپی کنید.
تابع ریشه:
ناپایا مرحله := "آغاز"
دیرکن سرچاپ "دیرکن میبیند:"، مرحله
نگهداشته := مرحله
دیرکن سرچاپ "کپی نگهداشته:"، نگهداشته
مرحله = "پایان کار"
سرچاپ "مرحلهی کنونی:"، مرحله
پایانآزادکردن مجموعهها
وکتور و نگاشت حافظه میگیرند و با آزادکن() پس داده میشوند. درست در خط بعد از ساختنشان دیرکن نام.آزادکن() بنویسید تا همهی مسیرهای بیرون رفتن از تابع، از جمله برگشت ۰ زودهنگامِ این مثال، آن را آزاد کنند.
تابع میانگین خوانش(خام: صحیح[]): صحیح:
ناپایا معتبر := وکتور {} برگردان وکتور<صحیح>
دیرکن معتبر.آزادکن()
هر خ در خام:
اگر خ >= ۰:
معتبر.بیفزا(خ)
پایان
پایان
اگر معتبر.طول() == ۰:
برگشت ۰
پایان
ناپایا مجموع := ۰
هر م در معتبر:
مجموع += م
پایان
برگشت مجموع / معتبر.طول()
پایان
تابع ریشه:
سرچاپ میانگین خوانش([۲۱، -۱، ۲۳، ۲۵، -۱])
سرچاپ میانگین خوانش([-۱، -۱])
پایانوکتور و نگاشت در درس مجموعهها آمدهاند و درس حافظه توضیح میدهد چه چیزهایی باید آزاد شوند و چرا.
بستن پرونده
پروندهها هم با همین الگو بسته میشوند. بررسی کنید که باز کردن موفق بوده و بلافاصله بستن را دیرکن کنید؛ کدی که بعد میآید میتواند زود برگردد بیآنکه پرونده باز بماند. اینجا ریشه پاک کردن پروندهی موقت را هم دیرکن کرده تا پس از پایان برنامه اثری از آن نماند.
واردسازی سیستم عامل
تابع ذخیره گزارش(مسیر: رشته، جمع: صحیح): منطقی:
پ := سیستم عامل.بازکردن(مسیر، "w")
اگر پ == پوچ:
برگشت نادرست
پایان
دیرکن پ.ببند()
پ.نوشتن("جمع: " + جمع + "\n")
پ.نوشتن("وضعیت: پرداخت شده\n")
برگشت درست
پایان
تابع ریشه:
مسیر := سیستم عامل.پوشه موقت() + "/salam-report-fa.txt"
اگر وارونه ذخیره گزارش(مسیر، ۲۴۵):
نادرستسرچاپ "نوشتن ممکن نشد"، مسیر
برگشت ۱
پایان
دیرکن سیستم عامل.حذف(مسیر)
چاپ سیستم عامل.خواندن پرونده(مسیر)
پایاندیرکن میتواند تابعی را صدا بزند که مقداری برمیگرداند، مثل سیستم عامل.حذف؛ آن مقدار کنار گذاشته میشود. شکل بلوکی دیرکن: ... پایان وجود ندارد. اگر پاکسازی چند گام دارد، آنها را در یک تابع بگذارید و فراخوانی آن تابع را دیرکن کنید.
ویژگیهای تابع
این واژهها پیش از تابع میآیند و چیزی دربارهی تابع میگویند. بعضی قولهاییاند که مترجم میسنجد و بعضی فقط پیشنهادند:
| ویژگی | معنا | کاری که مترجم میکند |
|---|---|---|
ناب | بی اثر جانبی: نتیجه فقط به ورودیها بستگی دارد | چاپ کردن، نوشتن در متغیر سراسری یا صدا زدن تابع ناخالص را در آن نمیپذیرد |
درخط | بدنه در جای فراخوانی گذاشته شود | آن را پیشنهاد میگیرد؛ برای تابعهای کوچکی که بسیار صدا زده میشوند |
نادرخط | فراخوانی واقعی بماند | آن را پیشنهاد میگیرد؛ هنگام اندازهگیری کارایی یا اشکالزدایی به کار میآید |
نابرگشت | تابع هرگز برنمیگردد، مثلاً برنامه را تمام میکند | کد پس از فراخوانی آن را دسترسناپذیر میداند |
بیکاره | تابع کهنه شده است | در هر فراخوانی هشدار میدهد (W013) |
همگانی | بیرون از بسته هم دیده میشود | درس بستهها را ببینید |
ناب تابع بهای خالص(بها: صحیح، تخفیف: صحیح): صحیح:
برگشت بها - بها * تخفیف / ۱۰۰
پایان
درخط تابع مربع(ع: صحیح): صحیح:
برگشت ع * ع
پایان
نادرخط تابع خط رسید(نام: رشته، مبلغ: صحیح): رشته:
برگشت نام + ": " + مبلغ
پایان
تابع ریشه:
سرچاپ بهای خالص(۲۰۰، ۱۵)، مربع(۹)
سرچاپ خط رسید("چای"، بهای خالص(۹۰، ۱۰))
پایاناگر در بهای خالص یک سرچاپ بنویسید، ساخت متوقف میشود و مترجم میگوید تابع ناب نمیتواند چاپ را صدا بزند، چون اثر جانبی دارد. ارزش ناب در همین سنجش است: تابع ناب را میشود هر جا و هر چند بار که لازم است، بیخطر صدا زد.
واردسازی سیستم عامل
نابرگشت تابع شکست(پیام: رشته):
نادرستسرچاپ "خطا:"، پیام
سیستم عامل.خروج(۲)
پایان
بیکاره تابع جمع قدیمی(الف: صحیح، ب: صحیح): صحیح:
برگشت الف + ب
پایان
تابع بررسی سن(سن: صحیح): صحیح:
اگر سن < ۰ یا سن > ۱۵۰:
شکست("سن ناممکن " + سن)
پایان
برگشت سن
پایان
تابع ریشه:
سرچاپ بررسی سن(۳۴)
سرچاپ جمع قدیمی(۲، ۳)
پایاناگر بررسی سن با سن منفی ۳ صدا زده شود، «خطا: سن ناممکن -3» چاپ میشود و برنامه با کد ۲ بیرون میرود. چون شکست نابرگشت است، مترجم میداند این فراخوانی هرگز برنمیگردد و دستوری که درست پس از آن نوشته شود را دسترسناپذیر میداند و نمیپذیرد (E070). ولی خودِ بدنه را نمیسنجد: تابع نابرگشتی که برگردد برنامه را از کار میاندازد، پس مطمئن شوید همیشه با سیستم عامل.خروج یا فراخوانی دیگری که برنمیگردد تمام میشود. صدا زدن جمع قدیمی ساخته و اجرا میشود، فقط هشدار W013 میگیرد.
چند قاعدهی سرانگشتی
دیرکنرا درست در خط بعد از گرفتن چیزی بنویسید که آزادش میکند.- دیرکنها به ترتیب وارونه و در پایان بلوک خودشان اجرا میشوند.
- دستور دیرکنشده مقدار متغیرها را در لحظهی اجرا میبیند.
- تابعی را که ناب است
نابعلامت بزنید تا مترجم ناب نگهش دارد. نابرگشترا فقط برای تابعی بنویسید که واقعاً برنامه را تمام میکند.