درس چهارم – دستورالعملهای کنترلی، حلقهها
در این درس نحوه استفاده از دستورالعملهای کنترل حلقه در زبان C# را فرا خواهید گرفت. هدف این درس فهم و درک موارد زیر میباشد :
ü حلقه while
ü حلقه do-while
ü حلقه for
ü حلقه foreach
ü مطالب تکمیلی درباره دستورالعمل break
ü فراگیری نحوه بکارگیری دستورالعمل continue
در درس قبل، نحوه ایجاد یک حلقه بسیار ساده را با استفاده از دستور goto را فرا گرفتید. در همان مطلب نیز اشاره کردیم که این روش، روش مناسبی جهت ایجاد حلقه نیست. در این درس با نحوه صحیح ایجاد حلقهها در زبان C# آشنا خواهید شد. اولین دستوری که با آن آشنا میشوید نیز دستور while است.
حلقه while
ابتدا به مثال زیر توجه نمایید.
using System;
class WhileLoop
{
public static void Main()
{
int myInt = 0;
while (myInt < 10)
{
Console.Write("{0} ", myInt);
myInt++;
}
Console.WriteLine();
}
}
مثال 1-4 که در بالا ملاحظه میکنید، یک حلقه while ساده را نشان میدهد. این حلقه با کلمه کلیدی while آغاز شده و سپس به دنبال آن یک عبارت منطقی قرار میگیرد و مورد بررسی قرار میگیرد. تمامی دستورالعملهای کنترلی از یک عبارت منطقی بهره میگیرند و این بدین معناست که ابتدا این عبارت باید بررسی شود تا مشخص شود مقدار این عبارت true است یا false. در این مثال مقدار متغیر myInt مورد بررسی قرار میگیرد تا چک شود آیا مقدارش از 10 کوچکتر هست یا خیر. چون در ابتدای برنامه به این متغیر مقدار صفر تخصیص داده شده است، عبارت منطقی مقدار true را باز میگرداند و سپس بلوک قرار گرفته بعد از عبارت منطقی مورد اجرا قرار میگیرد.
درون بلوک while ابتدا مقدار متغیر myInt در کنسول نمایش داده میشود و سپس یک واحد به مقدار این متغیر افزوده میگردد. پس از اتمام بلوک while، عبارت منطقی مجددا کنترل میشود و در صورتیکه این عبارت مقدار true بازگرداند، حلقه while مجدداً اجرا میشود. زمانیکه عبارت منطقی مقدار false برگرداند، اجرا برنامه به اولین دستور بعد از بلوک while منتقل میشود. در این مثال اعداد صفر تا 9 بر روی صفحه نمایش داده میشوند و سپس یک خط خالی چاپ شده و اجرای برنامه خاتمه مییابد.
حلقه بعدی که بسیار شبیه به حلقه while میباشد، حلقه do-while است.
حلقه do-while
ابتدا به مثال 2-4 توجه نمایید.
using System;
class DoLoop
{
public static void Main()
{
string myChoice;
do
{
// منویی نمایش داده میشود
Console.WriteLine("My Address Book ");
Console.WriteLine("A - Add New Address");
Console.WriteLine("D - Delete Address");
Console.WriteLine("M - Modify Address");
Console.WriteLine("V - View Addresses");
Console.WriteLine("Q - Quit ");
Console.WriteLine("Choice (A,D,M,V,or Q): ");
// ورودی کاربر بررسی میشود
myChoice = Console.ReadLine();
// تصمیمی بر اساس ورودی کاربر گرفته میشود
switch(myChoice)
{
case "A":
case "a":
Console.WriteLine("You wish to add an address.");
break;
case "D":
case "d":
Console.WriteLine("You wish to delete an address.");
break;
case "M":
case "m":
Console.WriteLine("You wish to modify an address.");
break;
case "V":
case "v":
Console.WriteLine("You wish to view the address list.");
break;
case "Q":
case "q":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("{0} is not a valid choice", myChoice);
break;
}
Console.Write("Press Enter key to continue...");
Console.ReadLine();
Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q");
}
}
مثال 2-4 نحوه استفاده از حلقه do-while را نشان میدهد. ساختار نوشتاری این دستور بصورت زیر است :
do
{
دستورالعملهای مورد استفاده در بلوک این دستور، هر دستورالعمل معتبر زبان C# میتواند باشد. عبارت منطقی نیز همانند نمونههائیست که تا کنون با آنها آشنا شدیم و یکی از دو مقدار true یا false را بر میگرداند.
یکی از مصارف عمده حلقه do به جای حلقه while، مواردی است که میخواهیم یکسری دستورالعمل خاص، که آنها را درون بلوک do قرار میدهیم، حداقل یکبار اجرا شوند. در این مثال ابتدا یک منو برای کاربر نمایش داده میشود و سپس ورودی از وی دریافت میگردد. چون حلقه while عبارت منطقی خود در ابتدای اجرای حلقه بررسی مینماید، از اینرو تضمینی برای اجرای دستورات درون بلوک وجود نخواهد داشت، مگر شما بطور صریح برنامه را طوری طراحی نمایید که این عمل اتفاق بیفتد.
یک نگاه کلی به مثال 2-4 بیندازیم. در متد Main() متغیر myChoice را از نوع رشتهای تعریف نمودهایم. سپس یکسری دستورات را بر روی کنسول چاپ نمودهایم. این دستورات منوهای انتخاب برای کاربر هستند. ما باید ورودی از کاربر دریافت کنیم که چون این عمل از طریق Console.ReadLine() صورت گرفته، باید در متغیری از نوع رشتهای قرار گیرد و از اینرو این ورودی را در myChoice قرار دادهایم. ما باید ورودی را از کاربر دریافت کنیم و بر روی آن پردازش انجام دهیم. یک روش کارآمد برای این منظور استفاده از دستورالعمل switch است. همانطور که در دستور switch ملاحظه میکنید، بری default نیز دستوری در نظر گرفته شده است که نشان میدهد مقدار ورودی معتبر نیست.
حلقه for
به مثال 3-4 توجه کنید.
using System;
class ForLoop
{
public static void Main()
{
for (int i=0; i < 20; i++)
{
if (i == 10)
break;
if (i % 2 == 0)
continue;
Console.Write("{0} ", i);
}
Console.WriteLine();
}
}
مثال 3-4 یک حلقه for را نشان میدهد. استفاده از حلقه for برای زمانی مناسب است که دقیقاً بدانید که حلقه چندبار باید تکرا شود. محتویات درون پرانتزهای حلقه for از سه قسمت تشکیل شده است :
(
initializer list لیستی از عبارات است که بوسیله کاما از یکدیگر جدا میشوند. این عبارات تنها یکبار در طول دوره کاری حلقه for پردازش میشوند. همانطور که در مثال 3-4 نیز ملاحظه میکنید، این قسمت معمولا برای تعیین متغیری عددی جهت آغاز عمل شمارش مورد استفاده قرار میگیرد.
پس از اینکه عبارتهای دورن initializer list پردازش شد، حلقه for به سراغ قسمت بعدی، یعنی عبارات منطقی(boolean expression) میرود. در این قسمت تنها یک عبارت منطقی میتوان قرار داد ولی هر اندازه که بخواهید میتوانید این عبارت منطقی را پیچیده نمایید، فقط توجه نمایید که این عبارت باید بگونهای شود که مقدار true یا false برگرداند. از این عبارت منطقی معمولا جهت کنترل متغیر شمارشی استفاده میشود.
هنگامیکه عبارت منطقی مقدار true بازگرداند، دستورالعملهای بلوک for اجرا میشوند. در مثال 3-4 ما از دو دستور if درون حلقه for نیز استفاده کردهایم. اولین دستور if بررسی میکند که آیا مقدار متغیر i برابر با 10 هست یا نه. در اینجا یک نمونه دیگر از استفاده دستور break را ملاحظه میکنید. عملکرد دستور break در اینجا نیز همانند مورد استفاده آن در دستور switch است. در صورت اجرای دستور break اجرای حلقه for خاتمه یافته و اجرای برنامه به اولین دستور بعد از حلقه for منتقل میشود.
دومین دستور if با اسقتاده از عملگر باقیمانده (%) بررسی میکند که آیا متغیر i بر 2 بخش پذیر هست یا نه. در صورتیکه متغیر i بر 2 بخش پذیر باشد، دستور continue اجرا میشود. پس از اجرای دستور continue از سایر دستورات حلقه for که بعد از continue قرار گرفتهاند صرفهنظر میشود و اجرای برنامه به اول حلقه for باز میگردد.
قسمت سوم در حلقه for، قسمت postloopaction list است. پس از اینکه تمامی دستورات درون حلقه for اجرا شد، اجرای حلقه به این قسمت باز میگردد. این قسمت لیستی از عملیاتی است که میخواهید پس از اجرای دستورات درون بلوک حلقه for انجام شوند. در مثال 3-4 این عمل، اضافه کردن یک واحد به متغیر شمارشی است. پس از افزوده شدن یک واحد به متغیر شمارشی، عبارت منطقی مجدداً مورد بررسی قرار میگیرد و در صورتیکه مقدار این عبارت برابر با true باشد، حلقه for مجدداً اجرا میگردد. حلقه for تا زمانیکه عبارت منطقی برابر با true باشد اجرا میشود.
حلقه foreach
به مثال 4-4 توجه کنید.
using System;
class ForEachLoop
{
public static void Main()
{
string[] names = {"Hadi", "Salehy", "C#", "Persian"};
foreach (string person in names)
{
Console.WriteLine("{0} ", person);
}
}
}
حلقه foreach برای پیمایش مجموعهها بسیار مناسب است. یک نمونه از مجموعهها در C#، آرایهها هستند که در مثال 4-4 نیز مورد استفاده قرار گرفته است. اولین کاری که در متد Main() صورت گرفته، اعلان آرایه names از نوع رشتهای و مقدار دهی آن است.
درون پرانتزهای foreach عبارتی متشکل از دو المان قرار دارد که این المانها بوسیله کلمه کلیدی in از یکدیگر جدا شدهاند. المان سمت راست، مجموعهایست که میخواهید اعضای آنرا مورد پیمایش قرار دهید. المان سمت چپ، متغیری از نوع مجموعه مورد نظر است که مقادیر پیمایش شده را بر میگرداند.
در هربار پیمایش، عنصری جدیدی از مجموعه درخواست میشود. این درخواستها از طریق متغیر فقط خواندنی تعریف شده درون پرانتزهای foreach بازگردانده میشوند. تا زمانیکه عنصری در مجموعه وجود داشته باشد که مورد پیمایش قرار نگرفته است، حلقه foreach به کار خود ادامه خواهد داد زیرا عبارت منطقی حلقه foreach مقدار true را باز میگرداند. به محض اینکه تمامی عناصر مجموعه پیمایش شد، عبارت منطقی برابر با false شده و اجرای حلقه foreach خاتمه مییابد. در این حالت اجرای برنامه به اولین دستور بعد از حلقه foreach منتقل میگردد.
در مثال 4-4، متغیری از نوع رشته با نام person برای نگهداری عناصری که از آرایه names خوانده میشود، تعریف کردهایم. تا زمانیکه اسمی در آرایه names وجود داشته باشد، در متغیر person قرار میگیرد و درون حلقه foreach بوسیله دستور Console.WriteLine() در خروجی نمایش داده میشود.
نکته : یکی از مهمترین ویژگیهای حلقه foreach در آنست که فقط میتواند عناصر یک مجموعه را بخواند و نمیتواند تغییری در آنها ایجاد نماید. مزیت دیگر آن، پیمایش تمامی عناصر مجموعه بدون اطلاع از تعداد عناصر موجود در آن است.
خلاصه
در این درس با نحوه کار با دستورالعملهای for، while، do-while و foreach آشنا شدید. حلقه while تا زمانیکه شرطش صحیح باشد انجام میشود بدین معنی که تا زمانیکه عبارت منطقی آن دارای مقدار true باشد، دستورات درون بلوک آن اجرا میشوند. حلقه do، دستورات بلوک خود را حداقل یکبار اجرا میکند و سپس شرط مورد نظر را بررسی مینماید و در صورتیکه عبارت منطقی آن مقدار true بازگرداند، دستورات بلوک خود را تکرار مینماید. حلقه for دستورات بلوک خود را به تعداد دفعات مشخص اجرا مینماید و حلقه foreach عناصر یک مجموعه را مورد پیمایش قرار میدهد. در نهایت نیز اشاره میشود که روند اجرای حلقهها با استفاده از دستورات break و continue تغییر مینماید.