
آموزش گام به گام #C(جلسه سوم: عبارات کنترلی – گزینشی)
برای تعاملی کردن برنامه و اعمال فرآیند تصمیمگیری در کدها باید کاملا به موضوع عبارات کنترلی - گزینشی تسلط داشته باشیم. در این جلسه، عبارات کنترلی اصلی و پایهای زبان برنامهنویسی #C را مفصل توضیح خواهیم داد. با ما همراه باشید.
جلسه اول: آغاز کار با #C | جلسه ششم: namespaceها | جلسه یازدهم: اندیس گذار یا indexerها | جلسه شانزدهم: استفاده از اتریبیوتها | جلسه بیست و یکم: متدهای بینام یا anonymous |
جلسه دوم: عملگرها، نوعها و متغیرها | جلسه هفتم: مقدمهای بر کلاسهای #C | جلسه دوازدهم: ساختار یا structها | جلسه هفدهم: enumها | جلسه بیست و دوم: موضوعاتی در مورد نوع در #C |
جلسه سوم: عبارات کنترلی - گزینشی | جلسه هشتم: وراثت کلاس در #C | جلسه سیزدهم: واسط یا interfaceها | جلسه هجدهم: عملگرهای overloading | جلسه بیست و سوم: کار با نوعهای nullable |
جلسه چهارم: عبارات کنترلی - حلقهها | جلسه نهم: چند ریختی | جلسه چهاردهم: مقدمهای بر delegateها و رویدادها | جلسه نوزدهم: کپسولهسازی | |
جلسه پنجم: متدها | جلسه دهم: ویژگی یا propertyها | جلسه پانزدهم: مقدمهای بر کنترل خطا یا exception | جلسه بیستم: مقدمهای بر generic collectionها |
در دو جلسه پیش، هر برنامهای که مشاهده کردید شامل چند مرحله ترتیبی بود و بعد از انجام آنها برنامه متوقف میشد. در مورد ورودی هیچ تصمیمی نمیتوانستید اتخاذ کنید و تنها قانون و مانع اعمال شده در برنامه این بود که باید برنامه را مستقیم از ابتدا تا انتها طی میکردید.
اطلاعات موجود در این جلسه به شما کمک میکنند تا بر اساس تصمیماتی که اتخاذ میکنید برنامه را به چندین شاخه از توالیهای منطقی تبدیل کنید. اهداف این جلسه به شرح زیر هستند:
- آموزش عبارات if.
- آموزش عبارت switch.
- آموزش عملکرد break در عبارات Switch.
- درک کامل طرز استفاده مناسب از عبارت goto.
عبارت if
عبارت if به شما اجازه میدهد که با توجه به شرایط مشخص شده، مسیرهای منطقی مختلف را در پیش بگیرید. وقتی شرایط صدق کنند یا true باشند، یک بلوک کد برای آن شرایط اجرا خواهد شد.
میتوانید از عبارت if تکی، عبارتهای if تو در تو یا چندتایی و در صورت نیاز از عبارت Else استفاده کنید. لیست۱-۳ نشان میدهد که هر کدام از این انواع عبارات if چگونه عمل میکنند.
لیست ۱-۳ اشکال مختلف عبارت if: IfSelection.cs
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);
// Either/Or تصمیم
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 in the range from 1 to 10.", myInt);
}
else if (myInt > 10 && myInt <= 20)
{
Console.WriteLine("Your number {0} is in the range from 11 to 20.", myInt);
}
else if (myInt > 20 && myInt <= 30)
{
Console.WriteLine("Your number {0} is in the range from 21 to 30.", myInt);
}
else
{
Console.WriteLine("Your number {0} is greater than 30.", myInt);
}
}
}
عبارات درون لیست ۱-۳ از یک متغیر ورودی یکسان به نام myInt به عنوان بخشی از ارزیابیهایشان استفاده میکنند. این نیز یک روش دیگر برای گرفتن ورودی از کاربر به سبک تعاملی است. کد زیر، کد مربوط به بخش تعاملی برنامه است:
Console.Write("Please enter a number: ");
myInput = Console.ReadLine();
myInt = Int32.Parse(myInput);
ابتدا جمله “:Please enter a number” را در کنسول نمایش میدهیم. عبارت ()Console.ReadLine باعث میشود برنامه صبر کند تا کاربر ورودی خود را وارد کند، کاربر یک عدد تایپ میکند و کلید ENTER را میزند.
این عدد به شکل یک رشته به متغیر myInput (که نوع این متغیر String است) اختصاص داده میشود. چون ما باید ورودی کاربر را به فرم یک Int ارزیابی کنیم، پس myInput باید تبدیل شود. این امر با دستور (Int32.Parse(myInput انجام شده است. (Int32 و انواع مشابه آن در جلسه دیگری به طور مفصل توضیح داده خواهند شد).
نتیجه درون متغیر myInt (که نوع آن int) است قرار میگیرد.
حالا که یک متغیر با همان نوعی که مد نظرمان بود داریم، آن را با عبارات if ارزیابی میکنیم. اولین عبارت به شکل زیر است:
(معادله یا عبارت بولین)If
}
کدهایی که در صورت true بودن کد داخل پرانتز اجرا میشوند.
{
که طرز استفاده از آن را در کدهای زیر مشاهده میکنید:
// یک تصمیم داخل پرانتز و یک عمل درون آکولاد
if (myInt > 0)
{
Console.WriteLine("Your number {0} is greater than zero.", myInt);
}
ابتدا باید کلید واژه if را بنویسید. سپس نوبت به معادله یا عبارت boolean انتزها میرسد. این معادله یا عبارت بولین باید با مقادیر true یا false سنجیده شود. در این مثال، ما ورودی کاربر را بررسی میکنیم تا متوجه شویم که بزرگتر از صفر هست یا نه.
اگر مقدار این معادله boolean با true باشد، کدهای داخل آکولادها اجرا میشوند. (ساختار درون آکولادها را یک بلوک کد مینامیم) درون بلوک، یک یا چند کد وجود خواهند داشت. اگر مقدار معادله یا عبارت بولین برابر با false باشد، عبارات درون بلوک نادیده گرفته شده و برنامه به اجرای کدهای بعد از بلوک خواهد پرداخت.
نکته: در زبانهای دیگر(مانند C و ++C) میتوان شرایط را به صورت عددی ارزیابی کرد یعنی به این شکل که اگر مثلا نتیجه صفر شد شرایط false و اگر هر عدد دیگری بود شرایط true باشند.
در #C، شرایط باید به شکل ع مقادیر true یا false سنجیده شوند. اگر زمانی مجبور شدید یک شرط عددی را با #C شبیهسازی کنید، میتوانید این کار را با نوشتن کد به این شکل: myInt !=0 انجام دهید، این کد یعنی اینکه اگر myInt صفر نباشد، شرایط true خواهند بود.
دومین عبارت if از همه لحاظ شبیه به اولین عبارت است، به جز یک مورد: این عبارت بلوک کد ندارد. که زیر آن را مشاهده میکنید:
// یک تصمیم داخل پرانتز و یک عمل بدون آکولاد
if (myInt < 0)
Console.WriteLine("Your number {0} is less than zero.", myInt);
اگر نتیجه ارزیابی معادله بولین درون پرانتز true باشد، اولین عبارت کد بعد از معادله بولین اجرا خواهد شد. اما اگر نتیجه ارزیابی معادله بولین False باشد، اولین عبارت پس از معادله بولین نادیده گرفته شده و برنامه به اجرای کدهای بعد از عبارت نادیده گرفته شده خواهد پرداخت.
این شکل از عبارت if زمانی مناسب است که شما فقط یک خط کد برای اجرا شدن داشته باشید. اگر میخواهید دو یا تعداد بیشتری خط کد اجرا کنید، پس باید کدهای خود را درون آکولاد قرار دهید.
اکثر مواقع، لازم است تصمیمهای Either/or(یا این یا اون) استفاده کنید. همچنین به آنها تصمیمات if/else نیز گفته میشود. سومین عبارت if در لیست ۱-۳ این ایده را نمایش میدهد که در زیر مشاهده میکنید:
// Either/Or تصمیم
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);
}
وقتی نتیجه ارزیابی معادله بولین برابر با true باشد، کد یا کدهای درون بلوکی که بلافاصله پس از عبارت if قرار دارند اجرا میشوند. اما اگر نتیجه ارزیابی معادله False باشد، کدهای درون بلوکی که پس از کلید واژه else قرار دارد اجرا میشوند.
وقتی چند معادله برای سنجش و ارزیابی داشته باشید، میتوانید از شکل if/else if/else استفاده کنید. ما این شکل را چهارمین نوع عبارت if از لیست ۱-۳ نشان دادیم و در زیر نیز آن را مشاهده میکنید:
// حالت چند تصمیمی
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 in the range from 1 to 10.", myInt);
}
else if (myInt > 10 && myInt <= 20)
{
Console.WriteLine("Your number {0} is in the range from 11 to 20.", myInt);
}
else if (myInt > 20 && myInt <= 30)
{
Console.WriteLine("Your number {0} is in the range from 21 to 30.", myInt);
}
else
{
Console.WriteLine("Your number {0} is greater than 30.", myInt);
}
این مثال با کلید واژه if آغاز میشود و همانند عبارات قبلی، اگر نتیجه معادله بولین درون پرانتزها True باشد، کدهای درون بلوک بعد از if اجرا میشوند. ولی این دفعه، با بهرهگیری از کلید واژه ترکیبی else if، چندین شرط را بعد از شرط اولیه بررسی کنید.
عبارت Else if نیز دارای عبارت یا معادله بولین است، درست مانند عبارت if. وقتی نتیجه معادله بولین برای عبارت if else هم True باشد، همان قوانین همیشگی و یکسان اجرا خواهند شد. یعنی بلوکی که بلافاصله پس از معادله بولین قرار دارد اجرا میشود.
وقتی هیچکدام از شرایط معادلات بولین عبارات if و else if صدق نکنند یا true نباشند، آنگاه بلوکی که پس از کلیدواژه else قرار دارد اجرا خواهد شد. در هر حال، فقط یکی از بخشهای کل عبارت if/else if/else اجرا خواهد شد.
یکی از تفاوتهای آخرین عبارت با بقیه عبارات در معادلههای بولین آن است. معادله بولین (myInt<0 || myInt ==0) دارای عملگر OR(||) شرطی است. هم در عملگر OR معمولی(|) و هم OR شرطی(||)، معادله بولین اگر یکی از شرایط دو طرف عملگر True باشند، کل عبارت True خواهد شد.
تفاوت اصلی بین دو شکل متفاوت OR این است که، عملگر OR معمولی در همه حال شرایط دو طرف عملگر را بررسی میکند، اما OR شرطی فقط در صورت عبارت سمت راست عملگر را بررسی میکند که عبارت سمت چپ True نباشد.
معادله بولین (myInt > 0 && myInt <=10)، دارای عملگر AND شرطی است. هم AND معمولی(&) و هم AND شرطی(&&) فقط زمانی مقدار True را بازمیگردانند که شرایط هر دو طرف عملگر true باشند.
تفاوت بین این دو عملگر این است که، عملگر AND معمولی همیشه هر دو شرط موجود در دو طرف عملگر را بررسی میکند، اما عملگر AND شرطی فقط در صورت شرط سمت راست عملگر را بررسی میکند که شرط اول یا سمت چپ عملگر حتما True باشد.
عملگرهای شرطی (&& و ||) را معمولا عملگرهای اتصال کوتاه یا میانبر مینامند، چون آنها همیشه کل عبارت یا معادلهها را بررسی نمیکنند. بنابراین، از آنها برای تولید کدهای مختصر و مفید استفاده میشود چون این عملگرها به صورت خودکار، منطقهای غیر ضروری را نادیده میگیرند.
عبارت switch
نوع دیگری از عبارات گزینشی، عبارت switch است، که بسته به مقدار یک پارامتر مشخص شده، مجموعهای از کدهای منطقی را اجرا میکند. انواع مقادیری که یک عبارت switch میتواند با آنها کار کند عبارتاند از بولینها، enumها، انواع integral و رشتهها.
در جلسه دوم در مورد نوع bool، انواع Integralها و رشتهها صحبت کردیم و در جلسه هفدهم نیز نوع enum را آموزش خواهیم داد. لیست ۲-۳ نشان میدهد که چگونه میتوانید از نوعهای int و string در عبارت Switch استفاده کنید.
لیست ۲-۳: عبارات switch: SwitchSelection.cs
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);
// integer با نوع 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;
}
decide:
Console.Write("Type \"continue\" to go on or \"quit\" to stop: ");
myInput = Console.ReadLine();
// با نوع رشته
switch (myInput)
{
case "continue":
goto begin;
case "quit":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("Your input {0} is incorrect.", myInput);
goto decide;
}
}
}
نکته: در لیست ۲-۳ اگر هر مقداری غیر از یک int وارد کنید، برنامه به شما یک Exception میدهد. برای مثال اگر حرف a را وارد کنید، برنامه ارور میدهد.
لیست ۲-۳ چند عبارت switch را نمایش میدهد. عبارت switch با کلیدواژه switch آغاز میشود و بعد از آن، معادله Switch نوشته میشود. در اولین عبارت switch در لیست ۲-۳، معادله Switch یک نوع int را ارزیابی میکند، که در زیر مشاهده میکنید:
//integer با نوع 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 بعد از معادله Switchقرار دارد، که در آن یک یا چند انتخاب ارزیابی و سنجیده میشوند تا بالاخره انتخاب یا case منطبق با معادله Switch یافت شود. هر انتخاب با کلیدواژه case مشخص شده است، بعد از case یک نمونه(هم نوع با معادله Switch) قرار گرفته و بعد از آن هم عملگر دو نقطه( : ) قرار دارد.
در این مثال case ها به این صورت هستند:
:Case 1:، case 2:، case 3 و الی آخر.
وقتی نتیجه معادله Switch با یکی از این انتخابها تطابق یابد، کدهای درون آن انتخاب یا case اجرا خواهند شد. در انتهای این کدها یک عبارت انشعابی وجود دارد که میتواند یکی از عبارات زیر باشد:
Break، continue، goto، return یا throw.
جدل ۱-۳ عبارات انشعابی را به طور خلاصه نشان میدهد.
جدول ۱-۳: عبارات انشعابی در #C
همچنین میتوانید یک انتخاب Default نیز در انتهای همه caseها قرار دهید. در این صورت، اگر هیچکدام از انتخابها صدق نکنند، آنگاه انتخاب Default برگزیده میشود و کدهای آن اجرا خواهند شد.
اگرچه استفاده از انتخاب default اجباری نیست، اما به شدت توصیه میشود که همیشه آن را در انتهای Switch قرار دهید.
این کار باعث میشود از بروز موقعیتها و خطاهای غیر منتظره جلوگیری شده و برنامه شما قابلاعتمادتر باشد.
هر case باید با یک عبارت انشعابی پایان یابد(که در جدول ۱-۳ معرفی شدند). معمولا از عبارت break استفاده میشود. عبارت break باعث میشود برنامه از حلقه Switch خارج شده و شروع به اجرای کدهایی که بعد از بلوک switch قرار دارند، میکند.
دو استثنا برای این حالت وجود دارند:
وجود عبارات case پشت سر هم بدون اینکه بین آنها کد دیگری وجود داشته باشد یا استفاده از یک عبارت goto. در زیر مثالی مشاهده میکنید که نشان میدهد چگونه میتوان عبارات 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 پشت سر هم، بدون اینکه کدی بین آنها باشد، در واقع یک case برای چندین مقدار ایجاد کردهاید. یک Case بدون کد به صورت خودکار نادیده گرفته شده و برنامه به سراغ case بعدی میرود.
مثال بالا نشان میدهد گه چگونه سه Case برای متغیر myInt برابر با مقادیر ۱، ۲ یا ۳ میشوند.
در این مثال، caseهای ۱ و۲ نادیده گرفته میشوند و برنامه به سراغ اجرای کد Case 3 میرود.
برای اینکه کدهای درون یک عبارت Case اجرا شوند، باید مقدار رو به روی Case دقیقا با مقدار متغیر اصلی مطابقت داشته باشد، نمیتوانید برای اجرای Case ها از شرطهای منطقی استفاده کنید. اگر لازم بود از شروط منطقی استفاده کنید، میتواند از عبارت if/else if/else استفاده کنید.
روش دیگر برای کنترل جریان منطق برنامه در یک عبارت Switch این است که از عبارت goto استفاده کنید. با استفاده از عبارت gotoیا میتوانید به یک عبارت Case دیگر جهش کنید یا میتوانید کلا از switch خارج شوید.
دومین عبارت Switch در لیست ۲-۳، طرز استفاده از عبارت goto را نمایش میدهد که در زیر مشاهده میکنید:
//با نوع رشته switch
switch (myInput)
{
case "continue":
goto begin;
case "quit":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("Your input {0} is incorrect.", myInput);
goto decide;
}
نکته: در این مثال، “continue”، یک Case از عبارت Switch است – نه یک کلید واژه.
عبارت goto باعث میشود برنامه به بخشی از برنامه جهش کند که آن بخش هم نام با عبارت نوشته شده در رو به روی کلید واژه goto میباشد.
در طول اجرا، اگر کاربر تایپ کند “continue”، آنگاه عبارت Switch ورودی کاربر یعنی continue را(که از نوع رشته هم هست) را با Case continue مطابقت داده و در نتیجه برنامه دستور goto begin را اجرا میکند.
حالا برنامه از کل عبارت Switch خارج شده و شروع به اجرای کدهای اولین بخشی از برنامه که دارای نام begin باشد، میکند. این کار عملا یک حلقه ایجاد میکند. حلقهای که به شما اجازه میدهد یک کد یکسان را چندین بار اجرا کنید.
حلقه زمانی خاتمه مییابد که کاربر رشته “quit” را تایپ کند. آنگاه عبارت Switch این ورودی کاربر را با case quit مطابقت داده و کلمه “Bye” در کنسول نمایش داده میشود، برنامه از عبارت Switch خارج میشود یا اصطلاحا break میشود و برنامه خاتمه مییابد.
هشدار: هیچوقت نباید چنین حلقههایی ایجاد کنید. این یک سبک برنامهنویسی بد است. تنها دلیلی که این مثال را زدیم این است که من میخواستم به شما نحوه نوشتن و نحو عبارت goto را نشان دهم. در عوض، از یکی از عبارات حلقهای ساختارمند برای ایجاد حلقه استفاده کنید.
وقتی هیچکدام از رشتههای “continue” و “quit” توسط کاربر وارد نشوند، آنگاه برنامه انتخاب Default را برگزیده و کدهای آن را اجرا میکند. دستورات درون Default یک پیغام ارور در کنسول نمایش میدهند و دستور goto decide اجرا خواهد شد.
این دستور باعث میشود برنامه به اولین عبارت دارای واژه decide جهش کند که کدهای این بخش، از کاربر سوال میپرسند که آیا کاربر میخواهد ادامه دهد یا از برنامه خارج شود؟ این نیز یک حلقه دیگر است.
مشخص است که عبارت goto بسیار قدرتمند است و میتواند تحت شرایط کنترل شده، مفید هم باشد. به هر حال، باید قویا به شما هشدار دهم که در استفاده از آن با احتیاط و هوشیارانه عمل کنید. عبارت goto پتانسیل زیادی برای استفاده نامناسب دارد.
معمولا برنامههایی که از goto استفاده میکنند بسیار سخت بوده و رفع اشکال و اصلاح و مراقبت از آنها نیز بسیار مشکل است. سبک کد نویسی اسپاگتی را در نظر بگیرید که در آن به صورت تصادفی از عبارات goto در قسمتهای مختلف کد استفاده شده باشد، مثل یک کابوس است.
در جلسه بعدی، روش بهتری برای ایجاد حلقهها در برنامه به شما معرفی خواهم کرد.
خلاصه
عبارت if را میتوان به چندین روش نوشت تا بتوان چندین انشعاب منطقی مختلف ایجاد کرد.
عبارت Switch برای مجموعهای از انواع bool، enum، integral یا String چندین انتخاب فراهم میکند. از عبارات break، continue، goto، return یا throw برای خارج شدن از یک عبارت case استفاده میشود.
حتما از به کار بردن عبارت Goto در کدتان خودداری کندی، مگر اینکه دلیل خیلی خیلی خوبی برای استفاده از آن داشته باشید.
در کنار شروط انشعابی، همچنین استفاده از یک بلوک کد به دفعات متعدد نیز میتواند مفید باشد. اما یک عبارت goto برای چنین منطقی نه کافی است و نه حتی مناسب و به صرفه. در نتیجه، توصیه میکنم از عبارات مخصوص ایجاد حلقه استفاده کنید که در جلسه آینده به توضیح مفصل آنها خواهیم پرداخت.
جلسه بعد جلسه قبل
منبع: C# - Station
آخرین مطالب

دستور UPDATE در SQL Server برای تغییر دادههای موجود در یک جدول، از دستور UPDATE به شکل زیر استفاده ...

دستور DROP TABLE در SQL Server گاهی، لازم است یک جدول که دیگر استفادهای ندارد را حذف کنید. برای ...

بخش اول از آخرین مبحث دوره جامع آموزش SQL Server در جلسه قبلی بررسی شد. این مبحث که ...
دیدگاه خود را درباره این پست بنویسید