حلقه بی نهایت (Infinite Loop) یا حلقه بی پایان (Endless Loop) به گونهای از حلقه ها گفته میشود که در آن مجموعهای از دستورات به صورت نامتناهی تکرار میشوند. به عبارت بهتر دستوراتی که در بدنه این نوع حلقه قرار میگیرد تا زمانی که برنامه در حال اجراست تکرار میشود.
نحوه شکل گیری حلقه های بی نهایت
یک حلقه بدون پایان میتواند در اثر عوامل مختلفی نظیر وجود شرطی که هرگز حلقه را به پایان نمیرساند و یا وجود دستوراتی که مانع از به پایان رسیدن حلقه میشوند شکل بگیرد. در واقع حلقه های بی نهایت الزاما نوعی حلقه مجزا با یک کلمه کلیدی از پیش رزرو شده متمایز در زبانهای برنامه نویسی نیست؛ بلکه هر حلقه یا ساختار جریان کنترلی که منجربه تکرار دستورات به تعداد نامتناهی شود یک حلقه بی نهایت را تشکیل میدهد. این ساختار میتواند شامل هرچیزی اعم از یک حلقه معمولی و یا استفاده از دستور GOTO برای ایجاد یک حلقه بیپایان باشد.
حلقه های بی نهایت ممکن است به صورت عمدی یا غیرعمدی (ناخواسته) به وجود بیایند. به عنوان مثالی از کاربرد عمدی این نوع حلقه ها میتوان به استفاده از آنها در سیستمهای تعاملی به منظور بررسی مدوام ورودی ها (مانند کلیدهای فشرده شده توسط کاربر) اشاره نمود. در طرف مقابل ممکن است به دلیل اشتباه برنامه نویس، حلقه های بی پایان غیرعمدی در برنامه شکل بگیرند که این اتفاق معمولا در مورد برنامه نویسان تازه کار و کم تجربه رخ میدهد.
جالب است بدانید حلقه های بی نهایت ممکن است باعث هنگ کردن و فریز سیستم شوند. اما در صورتی که سیستم همچنان به واکنشهای کاربر پاسخگو باشد معمولا میتوان حلقه های بدون پایان ناخواسته را با روشی مثل استفاده از Task Manager و پایان دادن به فرایند مربوطه متوقف نمود.
به عنوان نمونه هایی از حلقه های بدون پایان از نوع While میتوان به دو قطعه کد ساده زیر که به زبان برنامه نویسی جاوا نوشته شدهاند اشاره کرد. نتیجه ارزیابی شرط در این حلقه ها همواره صحیح (true) باقی میماند و دستورات بدنه تا زمانی که اجرای برنامه متوقف نشود تکرار میشوند. در مثال سمت چپ، متغیر y همواره برابر با عدد 1 باقی میماند و در نتیجه شرط y < 20 همواره صحیح خواهد بود. در مثال سمت راست (که یکی از رایجترین روشهای ایجاد حلقه بی پایان میباشد) حاصل ارزیابی متغیر b همواره صحیح (true) بوده و تنها دستور بدنه حلقه به طور مداوم تکرار میشود.
دو نمونه حلقه بی نهایت از نوع While. در این دو مثال متغیر y و b هیچگاه تغییری نمیکنند و شرط همواره برقرار میماند.
حلقه (Loop) در زبان های برنامه نویسی برای اجرای دنبالهای از دستورات به صورت تکراری مورد استفاده قرار میگیرد. بدنه حلقه (Loop Body) شامل دستوراتی است که قرار است تکرار شوند؛ این دستورات تنها یک بار نوشته میشوند اما ممکن است چندین بار به صورت پشت سرهم اجرا شوند. بخش دیگری از Loop که به آن هدر (header) نیز گفته میشود نوع Loop و ویژگیهای آن را مشخص میکند.
انواع رایج حلقه ها
گونههای مختلفی از حلقهها توسط اغلب زبان های برنامه نویسی امروزی پشتیبانی میشود. تعداد دفعاتی که دستورات موجود در یک لوپ اجرا میشود ممکن است به صورت مستقیم مشخص شود و یا به یک شرط یا تعداد عناصری که در یک مجموعه وجود دارد وابسته باشد. حتی ممکن است دستورات برای همیشه اجرا شوند و هیچ پایانی برای آنها درنظر گرفته نشده باشد.
1- For Loop
حلقههای For از جمله رایجترین حلقههایی هستند که معمولا تعداد اجرای دستورات در آنها به صورت مستقیم مشخص میشود. البته توجه داشته باشید این مفهوم بدان معنا نیست که تعداد دفعات اجرای دستورات میبایست به صورت ثابت هنگام برنامه نویسی مشخص شود بلکه به عنوان مثال تعداد تکرارها میتواند وابسته به مقدار یک متغیر باشد که هنگام اجرا از کاربر گرفته شده است و یا حاصل ارزیابی یک عبارت حسابی باشد.
در تصویر زیر میتوانید دو نمونه For Loop را به زبان های جاوا (سمت چپ) و ویژوال بیسیک (سمت راست) مشاهده کنید. دستورات موجود در هر دو مثال 5 بار تکرار میشوند. متغیرهای index در این حلقهها را متغیرهای شمارنده حلقه (Loop Counter) مینامند. در تکرار اول مقدار این متغیرها برابر با 1 میباشد (مقدار آغازین) و در هر تکرار یک واحد به آنها افزوده میشود (گام شمارش در هر دو مثال برابر 1 است که در تصویر سمت چپ با i++ و در تصویر سمت راست به دلیل آنکه گام شمارش در زبان ویژوال بیسیک به صورت پیشفرض برابر با 1 است حذف شده است). در هر تکرار، مقدار کنونی متغیر شمارنده در خروجی نوشته میشود. زمانی که مقدار این متغیرها به 5 میرسد دستورات بدنه Loop برای آخرین بار اجرا میشوند. همانطور که مشاهده میکنید پایان لوپ در مثال سمت چپ با کمک شرط index <= 5 و در مثال سمت راست براساس مقداری که پس از کلمه To آمده است مشخص شده است. خروجی نهایی این دو مثال، اعداد 1 تا 5 خواهند بود.
نمونههایی از حلقههای For به زبانهای جاوا (سمت چپ) و ویژوال بیسیک (سمت راست)
2- While Loop
در حلقههایی که توسط یک شرط کنترل میشوند معمولا دستورات تا زمانی که شرط صحیح باشد اجرا میشوند. بسته به نوع این حلقهها، ممکن است شرط در ابتدا یا در انتهای حلقه بررسی شود؛ چنانکه شرط صحیح باشد برای بار دیگر دستورات حلقه تکرار میشوند. توجه داشته باشید در صورتی که این تست در انتهای ساختار Loop انجام شود حتی اگر شرط از همان ابتدا صحیح نباشد دستورات حداقل یک بار اجرا میشوند اما اگر شرط در همان ابتدای حلقه مورد بررسی قرار گیرد ممکن است دستورات بدنه هیچگاه اجرا نشوند.
حلقههای While (در اغلب زبان ها) و Do While و Do Until نمونههایی از این نوع لوپها به شمار میروند با این تفاوت که در حلقههای While، شرط را تنها میتوان در ابتدای حلقه بررسی نمود اما در حلقههای Do While و Do Until میتوان شرط را در ابتدا یا انتهای حلقه بررسی کرد. به علاوه در حلقههای While و Do While تنها در صورتی که شرط صحیح باشد دستورات اجرا میشوند اما Do Until تا زمانی دستورات بدنه خود را اجرا میکند که شرط نادرست باشد و به محض صحیح بودن نتیجه تست شرط، حلقه متوقف میشود.
در تصویر زیر، از یک حلقه While برای ایجاد همان خروجی که در مثال قبل با استفاده از حلقه For به دست آمد استفاده شده است. در این نمونه شرط x <= 5 به عنوان شرط لوپ به کار رفته است و در بدنه هر تکرار یک واحد به متغیر x افزوده میشود (این درحالیست که در ساختار For این متغیر در هدر حلقه تغییر میکرد نه در بدنه آن).
نمونهای از حلقه While به زبان جاوا
3- For each Loop
در بسیاری از زبانهای برنامه نویسی افزون بر این حلقهها از ساختارهای تکرارشونده ویژهای برای مجموعه (Collection) ها پشتیبانی میشود. در این نوع حلقهها که معمولا به حلقههای For each موسوم هستند دستورات برای هر عنصر از مجموعه مورد نظر تکرار میشود. در تصویر زیر نمونه حلقه For each را به زبان جاوا برای ایجاد خروجی مشابه با مثالهای قبل مشاهده میکنید.
نمونهای از حلقه For each به زبان جاوا
4- Infinite Loop
حلقه های بی نهایت یا بی پایان (Infinite Loop) به حلقههایی گفته میشود که دستورات بدنه آنها تا زمان اجرای برنامه تکرار میشوند. این نوع از loop ها ممکن است به خاطر استفاده از شرایطی که هیچ پایانی برای تکرارها رقم نمیزنند به وجود بیاید (برای مثال یک While Loop که شرط آن true باشد). نمونهای از کاربرد عمدی این نوع حلقهها را میتوان در مواردی دانست که لازم است برنامه به صورت مدوام وقوع رخدادی را چک کند.
ادامه حلقه و خروج زودهنگام از آن
در برخی موارد ترجیح داده میشود مابقی دستورات برای تکرار کنونی Loop نادیده گرفته شود و دنباله دستورات برای تکرار بعدی اجرا شوند. دستوراتی مانند continue (در اغلب زبانها) و next (در زبان Perl) به همین منظور استفاده میشوند.
در برخی موارد نیز ممکن است موقعیتی پیش بیاید که لازم شود پیش از آنکه Loop به صورت طبیعی اتمام شود اجرای تکرارهای بعدی نادیده گرفته شود و حلقه به صورت پیش از موعد پایان یابد. به عنوان مثال هنگام جستجو در میان مجموعهای از عناصر به محض اینکه عنصر موردنظر پیدا میشود اساسا نیازی به تکمیل فرایند جستجو در میان عناصر باقیمانده وجود ندارد. دستوراتی مانند break (در اغلب زبانها)، last (در زبان Perl) و Exit (در زبان ویژوال بیسیک) به این منظور استفاده میشوند.