در قسمت دوازدهم با دستور switch و کلماتکلیدی break و continue آشنا شدید. در این قسمت دستور goto و توضیحات تکمیلی دستور switch بیان میشود. همانطور که در قسمت قبل بیان شد، دستور switch یک متغیر را با چندین مورد مقایسه کرده و آن مورد را که با متغیر مطابقت دارد، انتخاب می کند.
به مثال زیر توجه کنید:
using System; class Example { static void Main() { int i; for (i = 0; i < 10; i++) switch (i) { case 0: Console.WriteLine("i is zero"); break; case 1: Console.WriteLine("i is one"); break; case 2: Console.WriteLine("i is two"); break; case 3: Console.WriteLine("i is three"); break; case 4: Console.WriteLine("i is four"); break; default: Console.WriteLine("i is five or more"); break; } } }
خروجی:
همانطور که میبینید، هربار از طریق حلقه مقدار i به ساختار switch داده شده و case مربوط به آن اجرا میشود. هنگامیکه مقدار i بیشتر از ۴ است دیگر در هر بار فقط default اجرا میشود زیرا case مربوط به آن موجود نیست. شما میتوانید هر interger type ای را توسط ساختار switch کنترل کنید، از جمله کاراکتر. به مثال زیر توجه کنید:
using System; class Example { static void Main() { char ch; for (ch = 'A'; ch <= 'E'; ch++) { switch (ch) { case 'A': Console.WriteLine("ch is A"); break; case 'B': Console.WriteLine("ch is B"); break; case 'C': Console.WriteLine("ch is C"); break; case 'D': Console.WriteLine("ch is D"); break; case 'E': Console.WriteLine("ch is E"); break; } } } }
خروجی:
ch is A
ch is B
ch is C
ch is D
ch is E
همانطور که میبینید در این مثال از default استفاده نشده چراکه این بخش از ساختار switch اختیاری است.
در سیشارپ قانونی به اسم no fall-through وجود دارد. طبق این قانون، کامپایلر بعد از statement sequence هر case به سراغ case بعدی نمیرود، چراکه این امر برای زبان سیشارپ یک خطا محسوب میشود و به همین دلیل است که در پایان هر case از break استفاده میکنیم تا کامپایلر بهکلی از ساختار switch خارج شود و به ادامهی برنامه و خطکدها بپردازد. قسمت default نیز نباید fall-through باشد و باید توسط break پایان یابد (از روشهای دیگر نیز میتوان قانون no fall-through را رعایت کرد مانند استفاده از goto بهجای break که در ادامهی این مقاله به شرح آن میپردازیم).
شما همچنین میتوانید چندین case داشته باشید که همگی یک statement sequence دارند:
// Empty cases can fall through. using System; class Example { static void Main() { int i; for (i = 1; i < 5; i++) switch (i) { case 1: case 2: case 3: Console.WriteLine("i is 1, 2 or 3"); break; case 4: Console.WriteLine("i is 4"); break; } } }
خروجی:
i is 1, 2 or 3
i is 1, 2 or 3
i is 1, 2 or 3
i is 4
در این مثال، اگر i شامل مقادیر ۱، ۲ و ۳ باشد اولین ()WriteLine اجرا شده و اگر i برابر با ۴ باشد آنگاه دومین ()WriteLine اجرا میشود.
The goto
goto یک jump statement غیر شرطی است. هنگامیکه برنامه به این کلمه میرسد، به مکان مشخصی از کد که توسط goto مشخص شده است، پرش میکند. goto سالها قبل از چشم برنامهنویسان افتاد چراکه موجب میشد کدنویسی شما مانند اسپاگتی شود! اگرچه هیچ موقعیت برنامهنویسی بهوجود نمیآید که به goto نیاز داشته باشید و در واقع سیشارپ برای اینکه یک زبان کامل باشد به goto نیاز ندارد اما هنوز هم بهندرت (و در برخی موارد بهصورت مفید) استفاده میشود. با این تفاصیر، اگر از goto بهصورت هوشمندانه استفاده شود میتواند سودمند باشد. نگرانی اصلی برنامهنویسان این است که استفاده زیاد از goto باعث شود برنامه ناخوانا و بههم ریخته شود اما در برخی از موارد برعکس است و بهجای بههم ریختگی باعث واضحتر شدن کد خواهد شد. در هرحال استفاده از این دستور پیشنهاد نمیشود مگر بهصورت هوشمندانه و بهجا. goto برای انجام عملیات نیاز به یک label دارد. label یکی از شناسههای سیشارپ است که بعد از آن علامت دونقطه (:) قرار میگیرد. label باید در همان بلاک و متدی باشد که goto قرار دارد (توضیح متد را در مقالات بعدی دنبال کنید). بهعنوان مثال، برنامه زیر یک حلقه است که اعداد ۱ تا ۲۰ را توسط goto و label نمایش میدهد:
using System; class Example { static void Main() { int x = 1; Loop1: // this is label if (x < 20) { Console.WriteLine(x); x++; goto Loop1; // it goes to the Loop1 label } Console.WriteLine("Done!"); } }
goto همچنین میتواند در یک ساختار switch به case و default دلخواه پرش کند. در این مورد، case و default نقش label را بازی میکنند بنابراین میتوانند هدف goto قرار گیرند. نکته اینجاست که goto باید درون switch مربوطه باشد و شما نمیتوانید از بیرون به درون یک switch پرش کنید.
به مثال زیر که از goto در ساختار switch استفاده میکند توجه کنید:
// Use goto with a switch. using System; class Example { static void Main() { for (int i = 1; i < 5; i++) { switch (i) { case 1: Console.WriteLine("In case 1"); goto case 3; case 2: Console.WriteLine("In case 2"); goto case 1; case 3: Console.WriteLine("In case 3"); goto default; default: Console.WriteLine("In default"); break; } Console.WriteLine(); } // goto case 1; // Error! Can't jump into a switch. } }
خروجی:
در این مثال ساختار switch درون یک حلقهی for قرار دارد و در هر دور حلقه، مقدار i به ساختار switch داده میشود. توجه کنید که در ساختار switch چگونه goto به case های مختلف و default پرش میکند. نکتهی دیگر اینجاست که case ها با break پایان نیافتهاند (بهجز default) چراکه استفاده از break در اینجا بیمورد و بیتاثیر است زیرا هر case توسط goto به case دیگری فرستاده شده و نهایتاً در قسمت default از ساختار switch خارج میشود. همانطور که گفته شد، نمیتوانید از بیرون به درون ساختار switch پرش کنید و اگر علامت کامنت را از ابتدای آخرین خطکد برنامه حذف کنید، برنامه کامپایل نمیشود. استفاده از goto در ساختار switch در برخی موارد خاص میتواند مفید باشد اما پیشنهاد نمیشود.
یکی از استفادههای مفید goto میتواند برای خارج شدن از حلقههای تودرتو با تو رفتگی زیاد باشد.
به این مثال دقت کنید:
// Demonstrate the goto. using System; class Example { static void Main() { int i = 0, j = 0, k = 0; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { for (k = 0; k < 10; k++) { Console.WriteLine("i, j, k: " + i + " " + j + " " + k); if (k == 3) goto stop; } } } stop: Console.WriteLine("Stopped! i, j, k: " + i + ", " + j + " " + k); } }
خروجی:
حذف goto در این مثال موجب میشود برای خاج شدن از سه حلقه که تودرتو هستند، از سه if و break استفاده کنید. در این مثال استفاده از goto کد را سادهتر میکند. هرچند که این یک مثال ساختگی است، اما میتوانید موقعیتهایی را بهوجود آورید که استفاده از goto مفید واقع شود. آخرین نکته این است که شما میتوانید توسط goto به خارج از یک بلاک پرش کنید اما نمیتوانید به درون یک بلاک پرش کنید.
شاید در فهم این مثال کمی با مشکل برخورده باشید ولی جای نگرانی نیست، چراکه توضیحات کافی در مورد حلقههای تودرتو خواهد داده شد و مثالها و تمرینات جالبی را انجام خواهیم داد.
salah kurdetani
۱۴ آبان ۱۳۹۱
سلام استاد . .
من هر سیزده زنگو دانلود کردم و میخوام آفلاین روشون کار کنم و خواستم بگم چرا تمرین خیلی کم دادید ؟؟
کاش میشد تمرینا زیاد باشن روشون کار کنیم .. و مشکلاتو باهاتون حل کنیم .
با تشکر
مسعود درویشیان
۱۵ آبان ۱۳۹۱
سلام. فعلاً مباحثی که مطرح شده بیشتر خوندنی هستن و نمیشه تمرین آنچنانی باهاشون انجام داد. جلوتر که بریم تمرینهای بیشتر، جالبتر و بهتری خواهیم داشت.
مرسی از همراهیتون
موفق باشید
salah kurdetani
۱۴ آبان ۱۳۹۱
راستی استاد پیشنهاد کنید تو وب تارگت سی پلاس پلاس هم بزارن ، خدایش خوب میشه !!
پیکسل
۱۵ آبان ۱۳۹۱
جالب بود اولین باره وب سایت شما رو میبینم ممنونم
داوود
۱۵ آبان ۱۳۹۱
سلام آقا مسعود؛ ممنون از ارائه آموزشهای خوبتون و بهتون خسته نباشید میگم.
واقعا کار سختی رو برعهده گرفتید.
انشاءالله موفق باشید.
مسعود درویشیان
۱۵ آبان ۱۳۹۱
سلام، قربان شما داوود جان…
خوانندههای عزیزی مثل شما سختی کار رو از تن آدم بیرون میبرن
amin
۱۷ آبان ۱۳۹۱
دنبال یه همچین سایتی بودم که بشه سی شارپ و تمرین کنم مرسی چون همه ۱۳ قسمتو دانلود کردمو میخام از امروز شروع کنم
مسعود درویشیان
۱۷ آبان ۱۳۹۱
Happy coding
فرشید
۱۷ آبان ۱۳۹۱
با سلام سوالی دارم که مربوط به dllاست معذرت میخوام که اینجا مطرح میکنم ولی اگر ممکنه خیلی فوری به جوابش احتیاج دارم فردا امتحان دارم
من یک پروژه class libraryایجاد کردم و متد ی نوشتم که ده براب عددی را برگردونه تا پایان ;return n*10 نوشتم وبعد f5 را زدم تا dll را تولید کنه و به رفرنس اضافه کنم ولی dllدر debug ایجاد نمیشه میدونید چرا ؟
مسعود درویشیان
۱۸ آبان ۱۳۹۱
F6 رو بزنید تا Build Solution انجام بشه
f1
۲۳ آبان ۱۳۹۱
سلام
ببخشید میشه در باره مراحل ابتداییش هم کمی مطلب قرار بدین
مانند
void
public
main()
class
ارث بری
کپسول سازی
چند ریختی
مثال عملی باشه ممنونم
مسعود درویشیان
۲۴ آبان ۱۳۹۱
سلام، در مورد همه اینها بحث خیلی خیلی مفصلی خواهیم داشت و کاملاً با شیگرایی آشنا میشید.
مثالها و تمرینهای زیادی هم انجام میدیم
خیلی عجله نکنید، میرسیم
f1
۲۴ آبان ۱۳۹۱
salam bebakhshi
darbareh tarahi algoritm ham age mish matalebi ro garar bedin mamnon misham
مهدی
۲۶ آبان ۱۳۹۱
الانه که هنگ کنم
دستتون درد نکنه علی بود
بهار
۱۷ بهمن ۱۳۹۱
سلام
من امروز سایتتون رو دیدم خیلی عالی بود ممنون از زحماتتون
ولی برای من چون یه خورده کار کردم ساده بود
اگه میشه درمورد مبحث linq صحبت کنید اگه امکانش هست به ایمیلم بفرستید من خودم فیلم آموزشی دارم به زبان اصلیه و زیاد سر در نیاوردم ممنون میشم اگه کمکم کنید
مسعود درویشیان
۱۷ بهمن ۱۳۹۱
سلام. در مورد LINQ توی مقالات آینده زنگ سیشارپ صحبت میکنیم.
Nima
۵ اسفند ۱۳۹۱
سلام استاد خیلی جذاب بود مطالب و آموزنده ممنون. . .یا علی !
edris
۲۲ فروردین ۱۳۹۲
با سلام و خسته نباشید،
استاد ما یکم دیر رسیدیم.میخواستم بپرسم که ادامه دارد یا درس ۱۳ آخرین درس بود،
با سپاس
مسعود درویشیان
۲۲ فروردین ۱۳۹۲
سلام، تا الان ۲۸ قسمت منتشر شده، فردا هم قسمت ۲۹ منتشر میشه!!!
ممنون میشم یه نگاه به صفحهی اصلی سایت بندازید :)
علیرضا اسکندرپور شوفری
۳۰ فروردین ۱۳۹۲
زیر تصویر دوم عبارت interger type غلط املایی داره. به integer type اصلاح کنید.
afsaneh
۸ اردیبهشت ۱۳۹۲
با سلام
و تشکر فراوان از آموزش #c .
لطفا ادامه بدهید
(*در مورد return توضیح دهید)
مسعود درویشیان
۸ اردیبهشت ۱۳۹۲
سلام. ممنون. توی قسمت متدها در مورد return هم توضیح داده شده
T.b
۴ مهر ۱۳۹۲
خیلی ممنون از اموزش جامعی که قرار دادید. اولین بار هست که این وب سایت رو می بینم و حتما مطالب اتی رو دنبال خواهم کرد.
رضا
۱۹ آذر ۱۳۹۲
جناب درویشان من یه تمرین در حد آموزشهای همین فصل خودم به خودم دادم که خوشحال می شم اگه شما بررسیش کنید.
برنامه رو با موفقیت نوشتم (البته به سختی).
اما دوست دارم بدونم از نظر شما روش فکر کردن من در رابطه با طرح کلی کار و در وهله ی دوم از نظر استفاده ی به جا یا نا به جا از مصالحی که در اختیار داریم چیه !
آیا بهتر بود طور دیگه ای می نوشتم ؟
هدف نوشتن برنامه ای بود که اعداد اول رو به ترتیب چاپ کنه.
پیشاپیش ممنونم.
using System;
class اعداداول
{
static void Main()
{
int x = 1;
loop_1:
if (x < 100) // بزرگترین عدد برای بررسی
{
for (int i = 2; i < x; i++)
{
if (x % i == 0)
{
++x; /* در اینجا چون حاصل تقسیم عدد مورد نظر بر یکی ازاعداد کوچکتر
* از خودش باقیمانده نداشته نتیجه میگیریم که این یک عدد اول نیست
بنابراین این عدد را رها کرده به سراغ عدد بعدی میرویم*/
goto loop_1;
}
continue; /*
اگر باقیمانده داشته باشیم یعنی ممکن است
ایکس عدد اول باشد بنابراین باید
آن را بر سایر اعداد کوچکتر از خودش هم تقسیم کنیم
در نتیجه ایکس را با همان مقدار مجددا به شرط حلقه میفرستیم */
}
Console.WriteLine("adade avval" + " " + x);/* فقط ایکسهایی به اینجا میرسند که به تمامی اعداد کوچکتر از خودشان
* تقسیم شده اند بدون آنکه هرگز باقیمانده ای داشته باشند
پس این ایکس ها اعداد اول هستند که پس از چاپ
یک واحد افزایش یافته و دوباره مورد بررسی قرارمی گیرند */
++x;
goto loop_1;
}
}
}
رضا
۱۹ آذر ۱۳۹۲
دوستان لطفا راهنمایی کنید چطوری کد رو بزارم که اینطور به هم نریزه
ممنون.
مسعود درویشیان
۱۹ آذر ۱۳۹۲
کدهاتون رو بین اینها قرار بدین:
مسعود درویشیان
۱۹ آذر ۱۳۹۲
خوبه ولی بهتر بود بهجای goto از حلقه استفاده میکردید.
رضا
۱۹ آذر ۱۳۹۲
خیلی ممنون از جوابتون
روش کار می کنم
علی
۲ خرداد ۱۳۹۳
ممنونم از آموزش های عالییییییتون
میشه همشو یه کتاب کنین و چاپش کنین…
راستی توی توضیح : The Go to
کلمه ی “تفاسیر” رو اشتباها نوشتید “تفاصیر”
بازم شرمنده
ممنونم
فاطمه
۲۳ مهر ۱۳۹۳
با سلامی د.واره و خسته نباشید به شما استاد گرامی
واقعا از زحماتتون نهایت تشکر رو دارم ممنون
محمدرضا
۱ اردیبهشت ۱۳۹۴
داداش دمت گرم آموزش دستور for بذار گیر کردم