درس چهارم – دستورالعملهاي كنترلي، حلقهها
در درس قبل، نحوه ايجاد يك حلقه بسيار ساده را با استفاده از دستور goto را فرا گرفتيد. در همان مطلب نيز اشاره كرديم كه اين روش، روش مناسبي جهت ايجاد حلقه نيست. در اين درس با نحوه صحيح ايجاد حلقهها در زبان C# آشنا خواهيد شد. اولين دستوري كه با آن آشنا ميشويد نيز دستور while است.
حلقه while
ابتدا به مثال زير توجه نماييد.
کد:
usingSystem;
classWhileLoop
{
public static voidMain()
{
intmyInt = 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 توجه نماييد.
کد:
usingSystem;
classDoLoop
{
public static voidMain()
{
stringmyChoice;
do
{
// منويي نمايش داده ميشود
Console.WriteLine("My Address Book\n");
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\n");
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
{ <statements> } while (<boolean expression>);
دستورالعملهاي مورد استفاده در بلوك اين دستور، هر دستورالعمل معتبر زبان C# ميتواند باشد. عبارت منطقي نيز همانند نمونههائيست كه تا كنون با آنها آشنا شديم و يكي از دو مقدار true يا false را بر ميگرداند.
يكي از مصارف عمده حلقه do به جاي حلقه while، مواردي است كه ميخواهيم يكسري دستورالعمل خاص، كه آنها را درون بلوك do قرار ميدهيم، حداقل يكبار اجرا شوند. در اين مثال ابتدا يك منو براي كاربر نمايش داده ميشود و سپس ورودي از وي دريافت ميگردد. چون حلقه while عبارت منطقي خود در ابتداي اجراي حلقه بررسي مينمايد، از اينرو تضميني براي اجراي دستورات درون بلوك وجود نخواهد داشت، مگر شما بطور صريح برنامه را طوري طراحي نماييد كه اين عمل اتفاق بيفتد.
يك نگاه كلي به مثال 2-4 بيندازيم. در متد Main() متغير myChoice را از نوع رشتهاي تعريف نمودهايم. سپس يكسري دستورات را بر روي كنسول چاپ نمودهايم. اين دستورات منوهاي انتخاب براي كاربر هستند. ما بايد ورودي از كاربر دريافت كنيم كه چون اين عمل از طريق Console.ReadLine() صورت گرفته، بايد در متغيري از نوع رشتهاي قرار گيرد و از اينرو اين ورودي را در myChoice قرار دادهايم. ما بايد ورودي را از كاربر دريافت كنيم و بر روي آن پردازش انجام دهيم. يك روش كارآمد براي اين منظور استفاده از دستورالعمل switch است. همانطور كه در دستور switch ملاحظه ميكنيد، بري default نيز دستوري در نظر گرفته شده است كه نشان ميدهد مقدار ورودي معتبر نيست.
حلقه for
به مثال 3-4 توجه كنيد.
کد:
usingSystem;
classForLoop
{
public static void Main()
{
for(inti=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>; <boolean expression>; <postloopaction list>)
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 توجه كنيد.
کد:
usingSystem;
classForEachLoop
{
public static voidMain()
{
string[] names = {"Meysam", "Ghazvini", "C#", "Persian"};
foreach(stringperson innames)
{
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 تغيير مينمايد.