سی شارپ #C

جلسه 22 - دستور goto در سی شارپ

 در جلسات قبل با شرط ها و حلقه آشنا شدیم . در این بخش می خوام استفاده از goto رو بهتون بگم . استفاده ی خیلی کمی داره ولی خیلی در موردش حرف زده میشه . 

goto

 

goto یک jump statement غیر شرطی است. هنگامی‌ که برنامه به این کلمه می‌ رسد، به مکان مشخصی از کد که توسط goto مشخص شده است، پرش می‌کند.

goto سال‌ها قبل از چشم برنامه‌ نویسان افتاد چراکه موجب می‌شد کد نویسی شما مانند اسپاگتی شود ! اگرچه هیچ موقعیت برنامه‌ نویسی به‌ وجود نمی‌آید که به goto نیاز داشته باشید و در واقع سی‌شارپ برای این‌که یک زبان کامل باشد به goto نیاز ندارد اما هنوز هم به‌ ندرت (و در برخی موارد به‌صورت مفید) استفاده می‌شود . با این تفاصیر ، اگر از goto به‌ صورت هوشمندانه استفاده شود می‌تواند سودمند باشد . نگرانی اصلی برنامه‌ نویسان این است که استفاده زیاد از goto باعث ‌شود برنامه ناخوانا و به‌هم ریخته شود اما در برخی از موارد برعکس است و به‌جای به‌ هم ریختگی باعث واضح‌ تر شدن کد خواهد ‌شد. در هرحال استفاده از این دستور پیشنهاد نمی‌شود مگر به‌صورت هوشمندانه و به‌جا . goto برای انجام عملیات نیاز به یک label دارد. label یکی از شناسه‌های سی‌شارپ است که بعد از آن علامت دونقطه (:) قرار می‌گیرد. label باید در همان بلاک و متدی باشد که goto قرار دارد (توضیح متد را در مقالات بعدی دنبال کنید). به‌عنوان مثال ، برنامه زیر یک حلقه است که اعداد ۱ تا ۲۰ را توسط goto و label نمایش می‌دهد :


 

        ; 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 استفاده می‌کند توجه کنید:


 

        (++for (int i = 1; i < 5; i  

        }

            (switch (i

            }

                :case 1


;(" کیس اول ")  MessageBox.Show


     
                    ; goto case 3

                : case 2

;(" کیس دوم ")  MessageBox.Show

                 
                   ; goto case 1

                : case 3

;(" کیس سوم ")  MessageBox.Show

             
                   ; goto default

                : default

;(" کیس پیش فرض ")  MessageBox.Show

                   
                   ; break

            {
        


        {

        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 می‌تواند برای خارج شدن از حلقه‌های تودرتو با تو رفتگی زیاد باشد.

 

به این مثال دقت کنید:

 


       ; 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          

                }          

 ;( MessageBox.Show("i , j , k: " + i + " " + j + " " + k           

                   ; if (k == 3) goto stop                

                {           

           {      

       {  

    :stop

 ;( MessageBox.Show("Stopped ! i , j , k: " + i + " " + j + " " + k

   


 خروجی:

i , j , k : 0  0  0

i , j , k : 0  0  1

i , j , k : 0  0  2

i , j , k : 0  0  3

Stopped ! i , j , k : 0 , 0 , 3

 

حذف goto در این مثال موجب می‌شود برای خاج شدن از سه حلقه که تودرتو هستند ، از سه if و break استفاده کنید . در این مثال استفاده از goto کد را ساده‌ تر می‌کند . هرچند که این یک مثال ساختگی است ، اما می‌توانید موقعیت‌ هایی را به‌ وجود آورید که استفاده از goto مفید واقع شود. آخرین نکته این است که شما می‌توانید توسط goto به خارج از یک بلاک پرش کنید اما نمی‌توانید به درون یک بلاک پرش کنید.

نکته : همانطور که در مثال می بینید 3 عدد for تو در تو وجود دارد . وقتی چند for تو در تو داشته باشیم ، کامپایلر از بیرونی ترین for شروع میکنه و به داخلی ترین for میره و مقادیر شمارنده ها و متغیر های داخل آنها رو ست می کنه . وقتی به داخلی ترین for رسید ، آنرا به تعداد تعریف شده در آن اجرا می کند تا زمانی که شرط بر قرار نشود وقتی اجرای for داخلی تمام شد for قبلی آن اجرا (در اینجا یک واحد بهش اضافه میشه) و دو مرتبه for داخب آن اجرا میشه . این کار انقدر تکرا میشه تا for دوم هم شرطش false شود . در این صورت نوبت به for اول می رسد (بیرونی ترین for) به آن نیز یک واحد اضافه میشود و دو مرتبه for های داخلی اجرا می شود تا نهایتا هر for بیرونی جواب شرطش false شود .

برای درک بهتر به فلوچارت زیر دقت کنید :

for 

اینم از goto بهتره برنامتون رو طوری بنویسید که نیاز به پرش کردن از یک نقطه به یک نقطه ی دیگه نداشته باشید ، اما در موارد نادر اشکالی نداره . 

 تا جلسه ی بعد خدانگهدار

 

اضافه کردن نظر