درس سوم دستورالعمل‌هاي كنترلي و شرطي

 

در اين درس با دستورالعمل‌هاي كنترل و انتخاب در C# آشنا مي‌شويد. هدف اين درس عبارتست از :

  • يادگيري دستور if
  • يادگيري دستور switch
  • نحوه بكارگيري دستور break در دستور switch
  • درك صحيح از نحوه بكارگيري دستور goto

 

بررسي دستور if و انواع مختلف آن

در درسهاي گذشته، برنامه‌هايي كه مشاهده مي‌كرديد از چندين خط دستور تشكيل شده بودند كه يكي پس از ديگري اجرا مي‌شدند و سپس برنامه خاتمه مي‌يافت. در اين برنامه‌ها هيچ عمل تصميم‌گيري صورت نمي‌گرفت و تنها دستورات برنامه به ترتيب اجرا مي‌شدند. مطالب اين درس نحوه تصميم‌گيري در يك برنامه را به شما نشان مي‌دهد.

 

اولين دستور تصميم‌گيري كه ما آنرا بررسي مي‌نماييم، دستورالعمل if است. اين دستور داراي سه فرم كلي : تصميم‌گيري ساده، تصميم‌گيري دوگانه، تصميم‌گيري چندگانه مي‌باشد.

 

مثال 1-3 فرم‌هاي دستورالعمل if

using System;

 

class IfSelect

{

  public static void Main()

   {

    string myInput;

    int myInt;

    Console.Write("Please enter a number: ");

    myInput = Console.ReadLine();

    myInt = Int32.Parse(myInput);

    //تصميم‌گيري ساده و اجراي عمل داخل دو كروشه

    if (myInt > 0)

     {

      Console.WriteLine("Your number {0} is greater than zero.", myInt);

     }

    //تصميم‌گيري ساده و اجراي عمل بدون استفاده از دو كروشه

    if (myInt < 0)

      Console.WriteLine("Your number {0} is less than zero.", myInt);

    // تصميم‌گيري دوگانه

    if (myInt != 0)

     {

      Console.WriteLine("Your number {0} is not equal to zero.", myInt);

     }

    else

     {

      Console.WriteLine("Your number {0} is equal to zero.", myInt);

     }

    // تصميم‌گيري چندگانه

    if (myInt < 0 || myInt == 0)

     {

      Console.WriteLine("Your number {0} is less than or equal to zero.",  myInt);

     }

    else if (myInt > 0 && myInt <= 10)

    {

     Console.WriteLine("Your number {0} is between 1 and 10.", myInt);

    }

    else if (myInt > 10 && myInt <= 20)

    {

     Console.WriteLine("Your number {0} is between 11 and 20.", myInt);

    }

    else if (myInt > 20 && myInt <= 30)

    {

     Console.WriteLine("Your number {0} is between 21 and 30.", myInt);

    }

   else

   { 

    Console.WriteLine("Your number {0} is greater than 30.", myInt);

   }

  } //Main()پايان متد

} //IfSelectپايان كلاس 

 

برنامه 1-3 از يك متغير myInt براي دريافت ورودي از كاربر استفاده مي‌نمايد، سپس با استفاده از يك سري دستورات كنترلي، كه همان دستور if در اينجاست، عمليات خاصي را بسته به نوع ورودي انجام مي‌دهد. در ابتداي اين برنامه عبارت Please enter a umber: در خروجي چاپ مي‌شود. دستور Console.ReadLine() منتظر مي‌ماند تا كاربر ورودي وارد كرده و سپس كليد Enter را فشار دهد. همانطور كه در قبل نيز اشاره كرده‌ايم، دستور Console.ReadLine() عبارت ورودي را به فرم رشته دريافت مي‌نمايد پس مقدار ورودي كاربر در اينجا كه يك عدد است به فرم رشته‌اي در متغير myInput كه از نوع رشته‌اي تعريف شده است قرار مي‌گيرد. اما ميدانيم كه براي اجراي محاسبات و يا تصميم‌گيري بر روي اعداد نمي‌توان از آنها در فرم رشته‌اي استفاده كرد و بايد آنها را بصورت عددي مورد استفاده قرار داد. به همين منظور بايد متغير myInput را به نحوي به مقدار عددي تبديل نماييم. براي اين منظور از عبارت Int32.Parse() استفاده مي‌نماييم. اين دستور مقدار رشته‌اي متغير داخل پرانتزش را به مقدار عددي تبديل كرده و آنرا به متغير ديگري از نوع عددي تخصيص مي‌دهد. در اين مثال نيز همانطور كه ديده مي‌شود، myInput كه تز نوع رشته‌اي است در داخل پرانتز قرار گرفته و اين مقدار برابر با myInt كه از نوع int است قرار گرفته است. با اين كار مقدار عددي رشته ورودي كاربر به متغير myInt تخصيص داده مي‌شود. (توضيح كامل‌تري در مورد Int32 و ساير تبديلات مشابه به‌ آن در درسهاي آينده و در قسمت نوع‌هاي پيشرفته مورد بررسي قرار مي‌گيرند.)حال ما متغيري از نوع مورد نظر در دست داريم و مي‌توانيم با استفاده از دستور if بر روي آن پردازش انجام داده و تصميم‌گيري نماييم.

 

دستور if

اولين دستور بصورت if (boolean expression) {statements} آورده شده است. دستور if با استفاده از كلمه كليدي if آغاز مي‌شود. سپس يك عبارت منطقي درون يك زوج پرانتز قرار مي‌گيرد . پس از بررسي اين عبارات منطقي دستورالعمل/دستورالعمل‌هاي داخل كروشه اجرا مي‌شوند. همانطور كه مشاهده مي‌نماييد، دستور if يك عبارت منطقي را بررسي مي‌كند. در صورتيكه مقدار اين عبارات true باشد دستورهاي داخل بلوك خود را اجرا مي‌نمايد(قبلا توضيح داده شد كه دستورهايي كه داخل يك زوج كروشه {} قرار مي‌گيرند در اصطلاح يك بلوك ناميده مي‌شوند.) و در صورتيكه مقدار آن برابر با false باشد اجراي برنامه به بعد از بلوك if منتقل مي‌شود. در اين مثال همانطور كه ملاحظه مي‌نماييد، عبارت منطقي دستور if بشكل if(myInt > 0) است. در صورتيكه مقدار myInt بزرگتر از عدد صفر باشد، دستور داخل بلوك if اجرا مي‌شود و در غير اينصورت اجراي برنامه به بعد از بلوك if منتقل مي‌گردد.

 

دومين دستور if دراين برنامه بسيار شبيه به دستور اول است، با اين تفاوت كه در اين دستور، دستور اجرايي if درون يك بلوك قرار نگرفته است. در صورتيكه بخواهيم با استفاده از دستور if تنها يك دستورالعمل اجرا شود، نيازي به استفاده از بلوك براي آن دستورالعمل نمي‌باشد. استفاده از بلوك تنها زماني ضروري است كه بخواهيم از چندين دستور استفاده نماييم.

 

دستور if-else

در بيشتر موارد از تصميم‌گيري‌هاي دوگانه يا چندگانه استفاده مي‌شود. در اين نوع تصميم‌گيري‌ها، دو يا چند شرط مختلف بررسي مي‌شوند و در صورت true بودن يكي از آنها عمل مربوط به آن اجرا مي‌گردد. سومين دستور if در اين برنامه نشان دهنده يك تصميم‌گيري دوگانه است. در اين حالت درصورتيكه عبارت منطقي دستور if برابر با true باشد دستور بعد از if اجرا مي‌شود و در غير اينصورت دستور بعد از else به اجرا در مي‌آيد. در حقيقت در اين حالت مي‌گوئيم " اگر شرط if صحيح است دستورات مربوط به if را انجام بده و درغير اينصورت دستورات else را اجرا كن".

فرم كلي دستور if-else بصورت زير است :

if (boolean expression)

   {statements}

else

   {statements}

كه در آن boolean expression عبارت منطقي است كه صحت آن مورد بررسي قرار مي‌گيرد و statements دستور يا دستوراتي است كه اجرا مي‌گردند.

 

دستور if-else if … else يا if تودرتو

در صورتيكه نياز باشد تا چندين حالت منطقي مورد بررسي قرار گيرد و دستورات مربوط به يكي از آنها اجرا شود، از فرم تصميم‌گيري چندگانه استفاده مي‌نماييم. اين نوع استفاده از دستور if در اصطلاح به if تودرتو (Nested If) معروف است چراكه در آن از چندين دستور if مرتبط به يكديگر استفاده شده است. چهارمين دستور if در مثال 1-3 استفاده از if تودرتو  را نشان مي‌دهد. در اين حالت نيز دستور با كلمه كليدي if آغاز مي‌گردد. شرطي بررسي شده و در صورت true بودن دستورات مربوط به آن اجرا مي‌گردد. اما اگر مقدار اين عبارت منطقي false بود آنگاه شرطهاي فرعي ديگري بررسي مي‌شوند.اين شرطهاي فرعي با استفاده از else if مورد بررسي قرار مي‌گيرند. هر يك از اين شرطها داراي عبارات منطقي مربوط به خود هستند كه در صورت true بودن عبارت منطقي دستورات مربوط به آنها اجرا مي‌گردد و در غير اينصورت شرط بعدي مورد بررسي قرار مي‌گيرد. بايد توجه كنيد كه در ساختار if تودرتو تنها يكي از حالتها اتفاق مي‌افتد و تنها يكي از شرطها مقدار true را بازمي‌گرداند.

فرم كلي if تودرتو بشكل زير است :

if (boolean expression)

   {statements}

else if (boolean expression)

   {statements}

else

   {statements}

عملگرهاي OR و AND  (|| و &&)

نكته ديگري كه بايد در اينجا بدان اشاره كرد، نوع شرطي است كه در عبارت منطقي دستور if آخر مورد استفاده قرار گرفته است. در اين عبارت منطقي از عملگر || استفاده شده است كه بيانگر OR منطقي است. عملگر OR زماني مقدار true بازمي‌گرداند كه حداقل يكي از عملوندهاي آن داراي مقدار true باشد. بعنوان مثال در عبارت (myInt < 0 || myInt == 0)، در صورتيكه مقدار متغير myInt كوچكتر يا مساوي با صفر باشد، مقدار عبارت برابر با true است. نكته قابل توجه آنست كه در زبان ‍C#، همانطور كه در درس دوم به آن اشاره شد، دو نوع عملگر OR وجود دارد. يكي OR منطقي كه با || نمايش داده مي‌شود و ديگري OR معمولي كه با | نشان داده مي‌شود. تفاوت بين اين دو نوع OR در آنست كه OR معمولي هر دو عملگر خود را بررسي مي‌نمايد اما OR منطقي تنها در صورتيكه عملگر اول آن مقدار false داشته باشد به بررسي عملگر دوم خود مي‌پردازد.

 

عبارت منطقي (myInt > 0 && myInt <= 10) حاوي عملگر AND شرطي (&&) مي‌باشد. اين عبارت در صورتي مقدار true بازمي‌گرداند كه هر دو عملوند AND داراي مقدار true باشند. يعني در صورتيكه myInt هم بزرگتر از صفر باشد و هم كوچگتر از 10، مقدار عبارت برابر با true مي‌گردد. در مورد AND نيز همانند OR دو نوع عملگر وجود دارد. يكي AND معمولي (&) و ديگري AND شرطي (&&). تفاوت اين دو نيز در آنست كه AND معمولي (&) هميشه هر دو عملوند خود را بررسي مي‌نمايد ولي AND شرطي (&&) تنها هنگامي به بررسي عملوند دوم خود مي‌پردازد كه مقدار اولين عملوندش برابر با true باشد. عملگرهاي منطقي  (|| و &&) را در اصطلاح عملگرهاي ميانبر (short-circuit) مي‌نامند چراكه تنها در صورت لزوم عملوند دوم خود را بررسي مي‌نمايند و از اينرو سريعتر اجرا مي‌شوند.

 

بررسي دستور switch

همانند دستور if، دستور switch نيز امكان تصميم‌گيري را در يك برنامه فراهم مي‌نمايد.

مثال 2-3 دستورالعمل switch

using System;

 

class SwitchSelect

 {

   public static void Main()

   {

    string myInput;

    int myInt;

    begin:

    Console.Write("Please enter a number between 1 and 3: ");

    myInput = Console.ReadLine();

    myInt = Int32.Parse(myInput);

    // بهمراه متغيري از نوع صحيح switch دستور

    switch (myInt)

    {

     case 1:

        Console.WriteLine("Your number is {0}.", myInt);

        break;

     case 2:

        Console.WriteLine("Your number is {0}.", myInt);

        break;

     case 3:

        Console.WriteLine("Your number is {0}.", myInt);

        break;

     default:

        Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);

        break;

    } //switchپايان بلوك

   decide:

   Console.Write("Type \"continue\" to go on or \"quit\" to stop: ");

   myInput = Console.ReadLine();

   // بهمراه متغيري از نوع رشته‌اي switch دستور

   switch (myInput)

   {

    case "continue":

       goto begin;

    case "quit":

       Console.WriteLine("Bye.");

       break;

    default:

       Console.WriteLine("Your input {0} is incorrect.", myInput);

       goto decide;

   } //switchپايان بلوك

  } //Main()پايان متد

} //SwitchSelectپايان كلاس

 

مثال 2-3 دو مورد استفاده از دستور switch را نشان مي‌دهد. دستور switch بوسيله كلمه كليدي switch آغاز شده و به دنبال آن عبارت دستور switch قرار مي‌گيرد. عبارت دستور switch مي‌تواند يكي از انواع زير باشد : sbyte, byte, short, ushort, int, uint, long, ulong, char, string, enum .(نوع enum در مبحث جداگانه‌اي مورد بررسي قرار خواهد گرفت.) در اولين دستور switch در مثال 2-3، عبارت دستور switch از نوع عددي صحيح (int) مي‌باشد.

 

به دنبال دستور و عبارت switch، بلوك switch قرار مي‌گيرد كه در آن گزينه‌هايي قرار دارند كه جهت منطبق بودن با مقدار عبارت switch مورد بررسي قرار مي‌گيرند. هر يك از اين گزينه‌ها با استفاده از كلمه كليدي case مشخص مي‌شوند. پس از كلمه كليدي case خود گزينه قرار مي‌گيرد و به دنبال آن ":" و سپس دستوري كه بايد اجرا شود. بعنوان مثال به اولين دستور switch در اين برنامه توجه نماييد. در اينجا عبارت دستور switch از نوع int است. هدف از استفاده از دستور switch آنست كه از بين گزينه‌هاي موجود در بلوك switch، گزينه‌اي را كه مقدارش با مقدار عبارت switch برابر است پيدا شده و عمل مرتبط با آن گزينه اجرا شود. در اين مثال مقدار متغير myInt بررسي مي‌شود. سپس اگر اين مقدار با يكي از مقادير گزينه‌هاي داخل بلوك switch برابر بود، دستور يا عمل مربوط به آن گزينه اجرا مي‌گردد. توجه نماييد كه در اين مثال منظور ما از گزينه همان عدد پس از case است و منظور از دستور عبارتي است كه پس از ":" قرار گرفته است. بعنوان مثال، در دستور زير :

 

case 1:

     Console.WriteLine("Your number is {0}.", myInt);

عدد 1، گزينه مورد نظر ما و دستور Console.WriteLine(…)، عمل مورد نظر است. در صورتيكه مقدار myInt برابر با عدد 1 باشد آنگاه دستور مربوط به case 1 اجرا مي‌شود كه همان Console.WriteLine("Your number is {0}.", myInt); است. پس از منطبق شدن مقدار عبارت switch با يكي از case ها، بلوك switch بايد خاتمه يابد كه اين عمل بوسيله استفاده از كلمه كليدي break، اجراي برنامه را به اولين خط بعد از بلوك switch منتقل مي‌نمايد.

 

همانطور كه در ساختار دستور switch مشاهده مي‌نماييد، علاوه بر case و break، دستور ديگري نيز در داخل بلوك وجود دارد. اين دستور يعني default، براي زماني مورد استفاده قرار مي‌گيرد كه هيچ يك از گزينه‌هاي بلوك switch با عبارت دستور switch منطبق نباشند. به عبارت ديگر درصورتيكه مقدار عبارت switch با هيچ يك از گزينه‌هاي case برابر نباشد، دستور مربوط به default اجرا مي‌گردد. استفاده از اين دستور در ساختار بلوك switch اختياري است. همچنين قرار دادن دستور break پس از دستور default نيز اختياري مي‌باشد.

 

همانطور كه قبلاً نيز گفته شد پس از هر دستور case، به منظور خاتمه دادن اجراي بلوك switch بايد از يك break استفاده نمود. دو استثنا براي اين موضوع وجود دارد. اول اينكه دو دستور case بدون وجود كد و دستورالعملي در بين آنها، پشت سر هم قرار گيرند و ديگري در زمانيكه از دستور goto استفاده شده باشد.

 

در صورتيكه دو دستور case بدون وجود كدي در بين آنها، پشت سر يكديگر قرار گيرند، بدين معناست كه براي هر دو case مورد نظر يك عمل خاص در نظر گرفته شده است. به مثال زير توجه نماييد.

switch (myInt)

 {

   case 1:

   case 2:

   case 3:

      Console.WriteLine("Your number is {0}.", myInt);

      break;

   default:

     Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);

     break;

 }

در اين مثال، همانطور كه مشاهده مي‌كنيد، سه دستور case بدون وجود كدي در بين آنها پشت سر يكديگر قرار گرفته‌اند. اين عمل بدين معناست كه براي تمامي گزينه‌هاي 1، 2 و 3 دستور  ;(Console.WriteLine("Your number is {0}.", myInt اجرا خواهد شد. يعني اگر مقدار myInt برابر با هر يك از مقادير 1، 2 و 3 باشد، يك دستور براي آن اجرا مي‌شود.

 

نكته قابل توجه ديگر در مورد بلوك switch آنست كه، دستورات case حتماً نبايد يك دستور باشد بلكه مي‌توان از يك بلوك دستور براي case استفاده نمود.

 

دومين استفاده از دستور switch در مثال 2-3، داراي عبارتي از نوع رشته‌ايست. در اين بلوك switch چگونگي استفاده از دستور goto نيز نشان داده شده است. دستور goto اجراي برنامه را به برچسبي (label) كه معين شده هدايت مي‌نمايد. در حين اجراي اين برنامه، اگر كاربر رشته continue وارد نمايد، اين رشته با يكي از گزينه‌هاي دومين switch منطبق مي‌شود. چون دستور case مربوط به اين گزينه داراي دستور goto است، اجراي برنامه به برچسبي كه اين دستور مشخص كرده فرستاده مي‌شود، بدين معني كه اجراي برنامه به ابتداي جايي مي‌رود كه عبارت begin: در آنجا قرار دارد (در اوايل متد Main()). بدين صورت اجراي برنامه از بلوك switch خارج شده و به ابتداي برنامه و در جائيكه برچسب begin: قرار گرفته ارسال مي‌شود. در اين برنامه، استفاده از چنين حالتي استفاده از goto باعث ايجاد يك حلقه شده است كه با وارد كردن عبارت quit اجراي آن به پايان مي‌رسد.

 

در صورتيكه هيچ يك از عبارات continue و يا quit وارد نشوند، اجراي switch به گزينه default مي‌رود و در اين گزينه ابتدا پيغام خطايي بر كنسول چاپ شده و سپس با استفاده از دستور goto پرشي به برچسب decide صورت مي‌گيرد. پس از پرش به برچسب decide، از كاربر پرسيده مي‌شود كه آيا مي‌خواهد اجراي برنامه را ادامه دهد يا خير.( با وارد كردن گزينه‌هاي continue يا quit) همانطور كه مي‌بينيد در اينجا نيز حلقه‌اي توليد شده است.

 

استفاده از دستور goto در بلوك switch مي‌تواند موثر باشد اما بايد توجه نماييد كه استفاده‌هاي بي مورد از دستور goto باعث ناخوانا شدن برنامه شده و عيب‌يابي (Debug) برنامه را بسيار دشوار مي‌نمايد. در برنامه‌نويسي‌هاي امروزي استفاده از دستور goto بغير از موارد بسيار لازم و ضروري منسوخ شده و به هيچ عنوان توصيه نمي‌شود. براي توليد و ساخت حلقه نيز دستورات مفيد و سودمندي در زبان تعبيه شده‌اند كه استفاده از goto را به حداقل مي‌رسانند. دستورات حلقه در مبحث آينده مورد بررسي قرار خواهند گرفت.

 

نكته پاياني اين مبحث آنست كه توجه نماييد كه به جاي استفاده از دستور switch مي‌توانيد از چندين دستور if-else استفاده نمايد. دو قطعه برنامه زير معادل يكديگر مي‌باشند.

switch(myChar)

  {

    case 'A' :

          Console.WriteLine("Add operation\n");

          break;

    case 'M' :

          Console.WriteLine("Multiple operation\n");

          break;

    case 'S' :

          Console.WriteLine("Subtraction operation\n");

          break;

    default :

          Console.WriteLine("Error, Unknown operation\n");

          break;

  }

معادل بلوك switch با استفاده از if-else

if (myChar == 'A')

   Console.WriteLine("Add operation\n");

else if (myChar == 'M')

   Console.WriteLine("Multiple operation\n");

else if (myChar == 'S')

   Console.WriteLine("Subtraction operation\n");

else

   Console.WriteLine("Error, Unknown operation\n");

 

همانطور كه ملاحظه مي‌كنيد استفاده از بلوك دستور switch بسيار ساده‌تر از استفاده از if-else هاي تودرتو است.

 

در اين درس با نحوه تصميم‌گيري در برنامه بوسيله دستور if و switch آشنا شديد. با نحوه عملكرد و استفاده دستور goto نيز آشنايي پيدا كرديد. در پايان مجدداً يادآوري مي‌كنم كه در استفاده از دستور goto با احتياط عمل نماييد و به جز در موارد ضروري از آن استفاده نكنيد.

 

 

درس چهارم دستورالعمل‌هاي كنترلي، حلقه‌ها

 

در اين درس نحوه استفاده از دستورالعمل‌هاي كنترل حلقه در زبان 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\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

{ } while ();

 

دستورالعملهاي مورد استفاده در بلوك اين دستور، هر دستورالعمل معتبر زبان 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 = {"Meysam", "Ghazvini", "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 تغيير مي‌نمايد.