جلسه سوم Module 4 Module 4: Statements and Exceptions
نکته :یک بلک پدر و فرزند نمی توانند حاوی تعریف یک متغییر همنام باشند
{ ;int i ... { ;int i ... } }
بلوکهای خواهر و برادر :
{ ;int i ... } ... { ;int i ... }
: تو در توIF if (percent >= 0 && percent <= 100) if (percent > 50) Console.WriteLine("Pass"); else Console.WriteLine("Error: out of range");
کد صفحه قبل معادل کد زیر می باشد if (percent >= 0 && percent <= 100) { if (percent > 50) Console.WriteLine("Pass"); else Console.WriteLine("Error: out of range"); }
کد صحیح به فرم زیر می :باشد if (percent >= 0 && percent <= 100) { if (percent > 50) Console.WriteLine("Pass"); } else { Console.WriteLine("Error: out of range"); }
while ( Boolean-expression ) { embedded-statement update }
مثال : برنامه ای بنویسید که میانگین امتیازات یک کلس را محاسبه کرده و در خروجی نمایش دهد؟ تذکر :برنامه زمانی به پذیرفتن نمرات پایان می دهد که عدد -1به عنوان نمره وارد شود
Using system; Class average { static void Main(string[] args) { int total,gradecounter,gradevalue; double average; total=0; gradecounter = 0; console.writeline(“Enter Integer,-1 to quit”); gradevalue = Int32.Parse(Console.ReadLine()); while (gradevalue != -1) {
total=total+gradevalue; gradecounter++; console.writeline(“Enter Integer,-1 to quit”); gradevalue = Int32.Parse(Console.ReadLine()); } if (gradecounter!=0)
{ average=(double) total/gradecounter; console.writeline(“class average is {0},average”);}
else {console.writeline(“no grade entered”);} }}
: For حلقه for ( initializer ; condition ; update ) { embedded-statement }
: مثال For (int i=0;i<10;i++) { Console.writeline(i); }
مشکل کد زیر چیست ؟ For (int i=0;i<10;i++) Console.writeline(i); Console.writeline(i); //I is no longer in scope
حلقه بی پایان : Condition ،Updateو initializeنواحی اختیاری م ی باشن د ک د زی ر ی ک حلقه بی پایان را پیاده سازی می کند: );;(For { }//infinite loop
ایراد کد زیر چیست ؟ { …. Int I; For (int i=0;i<10;i++) //compiler error … }
فلوچارت معادل دستور :Switch
:Switch گزاره Switch (controlling expression){ Case constantexpression: Statements; Break; Case constantexpression: Statements; Break; …. Default : Statements; Break; }
نکاتی در مورد :Switch (1در یک بلوک Switchمی توان متغییر تعریف نمود که حوزه این متغییر از نقطه تعریف تا انتهای بلوک سوئیچ می باشد. (2عبارت Switchمی تواند یکی از انواع char، ،integer type ،enumو یا یک stringباشد. (3دستور Switchاز چندین بلوک Caseتشکیل شده ک ه ب ه ه ر کدام از آنه ا ی ک ثابت را مشخ ص م ی کن د و نم ی توان گروهی از ثابتها را در یک Caseگروه بندی کرد.
: نحوه گروه کردن چند ثابت enum MonthName { January, February, ..., December }; MonthName current; int monthDays; ... switch (current) { case MonthName.February : monthDays = 28; break; case MonthName.April : case MonthName.September : case MonthName.November : monthDays = 30; break; default : monthDays = 31; break;}
: fall through
بر خلف آنچ ه در ++Cداری م دس تور Switchبای د به گون ه ای نوشت ه شود ک ه اجراء برنام ه از یک case وارد caseبعدی نشود .در ص ورتی ک ه ی ک چنین وضعیتی داشته باشیم یک خطای fall throughداریم.
: مثال switch (days % 10) { case 1 : if (days / 10 != 1) { suffix = "st"; break;}// Error: fall through here case 2 : if (days / 10 != 1) { suffix = "nd"; break;}// Error: fall through here case 3 : if (days / 10 != 1) { suffix = "rd"; break;}// Error: fall through here default : suffix = "th";// Error: fall through here}
:اصلح مثال قبل switch (days % 10) { case 1 : suffix = (days / 10 == 1) ? "th" : "st"; break; case 2 : suffix = (days / 10 == 1) ? "th" : "nd"; break; case 3 : suffix = (days / 10 == 1) ? "th" : "rd"; break; default : suffix = "th"; break; }
مثال :برنام ه ای بنویس ید که ده gradeرا از ورودی گرفته و در پایان تعداد هر کدام از gradeها را چاپ کند ؟
فلوچارت معادل حلقه : Do While
:do while ساختار Do { Expressions; } While (booleanexpression);
:error – handling روش سنتی If (somefunc() == ERROR_RETURN_VALUE) //handle error or call error handler function Else //proceed normally If (anotherfunc() == NULL) //handle error or call error handler function Else //proceed normally If (thirdfunc() == 0) //handle error or call error handler function Else //proceed normally
مثال روش سنتی مدیریت خطا :
چرا ب ه مکانیس م حالت های استثنائی احتیاج داریم؟ مشکل ی ک ه در روش س نتی وجود دارد آن اس ت ک ه ه ر احضار منفرد چنی ن تابع ی باید توس ط برنام ه مورد بررس ی قرار گیرد با قرار دادن احضار هر تابع بین یک دستور … if .. elseو نوشتن دستورهایی که به حل مساله خط ا کم ک م ی کن د ص ورت برنامه پیچیده و خواندن آن را نیز با مشکل مواجه می کند. هنگامی که برنامه از کلس ها استفاده می کن د مشک ل پیچیده ت ر م ی شود زیرا خطاها ممکن است در خارج از یک تابع اتفاق بیافتد که به صورت صریح احظار شده اند.
ک د های س نتی مدیری ت خط ا فاقد اطلعات لزم درباره خطا می باشند. در net.برای رف ع ای ن مشکل تعدادی کلس Exceptionاز پیش تعریف شده در سیستم وجود دارد. ساختار این کلسها در اسلید بعد ارائه شده اند.
: اشیاءException
استفاده از این کلسها دارای مزیت های زیر می باشد: خطاهای اتفاق افتاده با یک کد نمایش داده نمی شوند .و در عوض از exception نظیر ی classهای تفاده OutOfMemoryExceptionاس می کنیم. پیامهای با معنی به راحتی تولید می شوند.
Catch :Try
: مثال class Program { int days; static int Main(string[] args) { try { int t=1; t=Int32.Parse(Console.ReadLine()); t = t / t; Console.WriteLine(t); } catch (System.DivideByZeroException e) { Console.WriteLine(e.ToString()); }; Console.ReadKey(); return 0; } }
در یک بلوک tryچندین خط برنامه وجود دارند که هر کدام از آنها می توانن د نوع خاص ی exceptionتولید کنند .بنابرای ن م ا م ی توانی م چندین بلوک catchداشت ه باشی م ک ه هر کدام نوع خاصی از exceptionرا ت مدیری می کنند.
زمانی که یک exceptionاتفاق می افتد اجراء برنامه متوقف شده و بر اساس نوع exceptionاتفاق افتاده یک بلوک catchمناسب جستجو می شود.
:Catch چند بلوک 1. try { 2. File source = new File("code.cs"); 3. int length = (int)source.Length; 4. char[ ] contents = new char[length]; 5. ... 6. } 7. catch (SecurityException caught) { ... } 8. catch (IOException caught) { ... } 9. catch (OutOfMemoryException caught) { ... } 10. ...
نکت ه :اگ ر جریان کنترل برنامه موف ق ب ه یافت ن یک بلوک Catch مناس ب نشود ب ه س راغ تابع جاری ع تاب فراخواننده می رود و در آن تابع بلوک catch مناسب جستجو می شود .این روند تا تابع mainادامه پیدا می کند و در نهایت تابع mainخاتمه پیدا می کند.
: عمومیcatch بلوک : روش اول catch { ... } : روش دوم catch (System.Exception ) { ... }
نکته :هر بلوک tryتنها می تواند دارای یک بلوک عمومی catchباشد. { try ... } } catch { ... catch { ... } // Error
اگر از یک بلوک عمومی catchاستفاده می کنیم حتما باید آخرین بلوک catchبلوک عمومی باشد. { try } catch { ... } // Error catch (OutOfMemoryException caught) { ... }
نباید دو بلوکexception برای یک کلس : نوشتcatch catch (OutOfMemoryException caught) { ... } catch (OutOfMemoryException caught) { ... } // Error
یک کلس نبای د قبل ازcatch بلوک کلس های مشتق شدهcatch بلوک :بیاید catch (Exception caught) { ... } catch (OutOfMemoryException caught) { ... }//error
: حذف حالت استثنائی برای حذف حالت استثنائی می :توان از روش زیر استفاده نمود if (minute < 1 || minute >= 60) { string fault = minute + "is not a valid minute"; throw new InvalidTimeException(fault); // !!Not reached!! }
Throwing Objects در جلوی دستور Throwتنها از کلس هایی م ی توان استفاده کرد که به صورت مستقیما و یا غی ر مستقیم از کلس System.Exceptionمشتق شده باشند.
شئی استثناء را می توان دوباره در بلوک Catchبه کار گرفت. { )catch (Exception caught ... ;throw caught }
می توان یک شیئی جدید استثناء را . به کار گرفتcatch در بلوک catch (FileIOException caught) { ... throw new FileNotFoundException(filename); } Caution
throw می توان از عبارتcatch در بلوک .بدون هیچ شیئی استفاده نمود دو قطعه کد زیر معادل یکدیگر می: مثال .باشند catch (OutOfMemoryException caught) { throw caught; } ... catch (OutOfMemoryException) { throw ; }
عبارت : finally در صورتی که اجراء برنامه از یک بلوک tryخارج شود عبارات داخل بلوک finallyدر هر صورت اجراء می شوند. ای ن موضوع در مورد خروج عادی )به پایان رسیدن بلوک (tryو یا خروج غیر عادی )خروج بر اث ر اجراء دستورات break ،goto ،continueیا رخ داد یک حالت استثنائی(صدق می کند.
عبارت finallyدر دو ص ورت استفاده می شوند: (1جلوگیری از تکرار دستورات (2آزاد کردن منابع
جلوگیری از تکرار دستورات : در کد سمت چپ تکرار دستورات داریم که در کد سمت راس ت توس ط دستور finallyحذف شده است: { try try {... ... statement } } { catch catch ... } {... { finally statement statement } }
:آزد کردن منابع StreamReader reader = null; try { File source = new File(filename); reader = source.OpenText( ); ... } finally { if (reader != null) { reader.Close( ); } }
تذک ر :در ص ورتی ک ه در داخل بلوک finallyاز دستور goto ، ،Continueو breakاستفاده می کنیم هدف پرش باید داخل بلوک finallyباش د در غیر اینصورت errorخواهیم داشت و استفاده از دستور returnدر داخ ل بلوک finallyدر هر
If an exception is thrown during the execution of a finally block, it is propagated to the next enclosing try block, as shown: try { try { ... } catch { // ExampleException is not caught here } finally { throw new ExampleException("who will catch me?"); } } catch { // ExampleException is caught here } If an exception is thrown during the execution of a finally block, and another exception was in the process of being propagated, then the original exception is lost, as shown: try { throw ExampleException("Will be lost"); } finally { throw ExampleException("Might be found and caught"); }
به صورت پیش فرض در محاسبات به. چک نم ی شودOverflow ریاض ی عنوان مثال در زی ر بدون اعلم پیام خطا // example.cs : داریمOverflow class Example { static void Main( ) { int number = int.MaxValue( ); Console.WriteLine(++number); }}
عبارت checkedو :unchecked با بکار بردن عبارت ، checked سرریز ریاض ی چک شده و در صورت رخ دادن سر ریز یک استثناء نوع System.OverflowException اتفاق م ی افتد .و در صورت استفاده از عبارت unchecked سر ریز ریاضی چک نمی شود.
برایunchecked وchecked می توان از به صورت زیر،کنترل عبارات داخل بلوکها .استفاده کرد checked { statement-list } unchecked { statement-list }
unchecked وcheckedمی توان از .برای کنترل عبارات استفاده کرد
کد زیر یک استثناء نوع: مثال System.OverflowException // example.cs .تولید می کند class Example { static void Main( ) { int number = int.MaxValue( ); Console.WriteLine(checked(++number)); } }