جاوا از دو دستور انتخاب پشتيباني مي كنند : ifو switchو . با اين دستورات شما اجراي برنامه را براساس شرايطي كه فقط حين اجراي برنامه اتفاق مي افتند كنترل مي كنيد. اگر سابقه برنامه نويسي با C++/C را نداريد، از قدرت و انعطاف پذيري موجود در اين دو دستور متعجب و شگفت زده خواهيد شد .
if
دستور if دستور انشعاب شرطي در جاوا است . از اين دستور مي توان استفاده نمود و اجراي برنامه را طي دو مسير متفاوت به جريان انداخت . شكل كلي اين دستور بصورت زير است :
if( condition )statement 1;
else statement 2;
دراينجا هر statement ممكن است يك دستور منفرد يا يك دستور مركب قرار گرفته
در ابروها ( يعني يك بلوك ) باشد . condition ( شرط ) هر عبارتي است كه يك
مقدار boolean را برمي گرداند . جمله else اختياري است . if
بصورت زير كار مي كند : اگر شرايط محقق باشد ، آنگاه statement 1 اجرا
مي شود . در غير اينصورت statement 2 ( در صورت وجود ) اجرا خواهد شد .
تحت هيچ شرايطي هر دو دستور با هم اجرا نخواهند شد . بعنوان مثال ، در نظر
بگيريد :
+ int a/ b;
+ //...
+ if(a 0 ){
+ ProcessData)(;
+ bytesAvailable- = n;
+ } else
+ waitForMoreData)(;
در اينجا ، هر دو دستور داخل بلوك if اجرا خواهند شد اگر bytes Available
بزرگتر از صفر باشد .
برخي از برنامه نويسان راحت ترند تا هنگام استفاده از if ، از ابروهاي باز
و بسته استفاده نمايند، حتي زمانيكه فقط يك دستور در هر جمله وجود داشته باشد.
اين امر سبب مي شود تا بعدا" بتوان براحتي دستور ديگري را اضافه نمود و نگراني
از فراموش كردن ابروها نخواهيد داشت . در حقيقت ، فراموش كردن تعريف يك بلوك
هنگامي كه نياز است ، يكي از دلايل رايج بروز خطاها مي باشد . بعنوان مثال قطعه
زير از يك كد را در نظر بگيريد :
+ int bytesAvailable;
+ //...
+ if( bytesAvailable > 0 ){
+ ProcessData)(;
+ bytesAvailable- = n;
+ } else
+ waitForMoreData)(;
+ bytesAvailable = n;
بنظر خيلي روشن است كه دستور bytes Available=n طوري طراحي شده تا داخل جمله else اجرا گردد ، و اين بخاطر سطح طراحي آن است . اما حتما" بياد داريد كه فضاي خالي براي جاوا اهميتي ندارد و راهي وجود ندارد كه كامپايلر بفهمد چه مقصودي وجود دارد . اين كد بدون مشكل كامپايل خواهد شد ، اما هنگام اجرا بطور ناصحيح اجرا خواهد شد . مثال بعدي داخل كدي كه مشاهده مي كنيد تثبيت شده است :
+ int bytesAvailable;
+ //...
+ if( bytesAvailable > 0 ){
+ ProcessData)(;
+ bytesAvailable- = n;
+ } else {
+ waitForMoreData)(;
+ bytesAvailable = n;
+ }
if
Nested ifs هاي تودرتو شده
يك nested if يك دستور if است كه هدف ifيا elseا ديگري باشد. if هاي تودرتو
در برنامه نويسي بسيار رايج هستند. هنگاميكه if ها را تودرتو مي كنيد، مهمترين
چيزي كه بايد بخاطر بسپاريد اين است كه يك دستورelse هميشه به نزديكترين دستور if
خود كه داخل همان بلوك else است و قبلا" با يك else همراه نشده ، مراجعه
خواهد نمود . مثالي را مشاهده نماييد :
+ if(i == 10 ){
+ if(j 100 )c = d; // this if is
+ else a = c; // associated with this else
+ }
+ else a = d; // this else refers to if(i == 10)
همانگونه كه توضيحات نشان مي دهند ، else نهايي با (20
چون داخل همان بلوك قرار ندارد ( اگر چه نزديكترين if بدون else است ) . بجاي
آن ، else نهايي با (i==10)if همراه مي شود . else داخلي به (100>k)if ارجاع
مي كند ، زيرا نزديكترين if در داخل همان بلوك است .
نردبان if-else-if
يك ساختار برنامه نويسي رايج براساس يك ترتيب از ifهاي تودرتو شده يا نردبان if-else-if
است . اين ساختار بصورت زير است :
if(condition)
statement;
else if(condition)
statement;
else if(condition)
statement;
.
.
.
else
statement;
دستورات if از بالا به پايين اجرا مي شوند . ماداميكه يكي از شرايط كنترل
كننده if صحيح باشد (true)، دستور همراه با آن if اجرا مي شود ، و بقيه نردبان
رد خواهد شد . اگر هيچكدام از شرايط صحيح نباشند، آنگاه دستور else نهايي اجرا
خواهد شد . else نهايي بعنوان شرط پيش فرض عمل مي كند ، يعني اگر كليه شرايط
ديگر صحيح نباشند ، آنگاه آخرين دستور else انجام خواهد شد . اگر else نهايي
وجود نداشته باشد و ساير شرايط ناصحيح باشند ، آنگاه هيچ عملي انجام نخواهد
گرفت .
در زير ، برنامه اي را مشاهده مي كنيد كه از نردبان if-else-if استفاده كرده
تا تعيين كند كه يك ماه مشخص در كدام فصل واقع شده است .
+ // Demonstrate if-else-if statement.
+ class IfElse {
+ public static void main(String args[] ){
+ int month = 4; // April
+ String season;
+
+ if(month == 12 || month == 1 || month == 2)
+ season = "Winter";
+ else if(month == 3 || month == 4 || month == 5)
+ season = "Spring";
+ else if(month == 6 || month == 7 || month == 8)
+ season = "Summer";
+ else if(month == 9 || month == 10 || month == 11)
+ season = "Autumn";
+ else
+ season = "Bogus Month";
+
+ System.out.println("April is in the" + season + ".");
+ }
+ }
خروجي اين برنامه بقرار زير مي باشد :
April is in the Spring.
ممكن است بخواهيد اين برنامه را تجربه نماييد . خواهيد ديد كه هيچ فرقي
ندارد كه چه مقداري به month بدهيد ، يك و فقط يك دستور انتساب داخل نردبان
اجرا خواهد شد .
switch
دستور switch ، دستور انشعاب چند راهه در جاوا است . اين دستور راه ساده اي
است براي تغيير مسير اجراي بخشهاي مختلف يك كد براساس مقدار يك عبارت . اين
روش يك جايگزين مناسب تر براي مجموعه هاي بزرگتر از دستورات if-else-if است .
شكل كلي دستور switch بقرار زير مي باشد :
switch(expression){
case value1:
// statement sequence
break;
case value2:
// statement sequence
break;
.
.
.
case valueN:
// statement sequence
break;
default:
// default statement sequence
}
expression
مي تواند هر نوع ساده اي را برگرداند ، هر يك از مقادير (values)
در دستورات case بايد از نوع سازگار با عبارت باشند . هر يك از مقادير case
بايد يك مقدار لفظي منحصر بفرد باشد ( يعني بايد يك ثابت ، نه متغير ، باشد ).
دو برابر سازي مقادير case مجاز نيست .
دستور switch بشرح فوق عمل مي كند : مقدار عبارت با هر يك از مقادير لفظي
در دستورات case مقايسه مي شوند. اگر تطابق پيدا شود ، كد سلسله اي تعقيب كننده
آن دستور case اجرا خواهد شد . اگر هيچيك از ثابت ها با مقدار عبارت تطابق
نيابند ، آنگاه دستور پيش فرض (default) اجرا خواهد شد ، اما دستور default
اختياري است . اگر هيچيك از case ها تطابق نيابد و default وجود نداشته باشد
آنگاه عمل اضافي ديگري انجام نخواهد شد .
از دستور break داخل دستور switch استفاده شده تا سلسله يك دستور را پايان
دهد . هنگاميكه با يك دستور break مواجه مي شويم ، اجرا به خط اول برنامه كه
بعد از كل دستور switch قرار گرفته ، منشعب خواهد شد . اين حالت تاثير پريدن switch
است .
در زير مثال ساده اي را مشاهده مي كنيد كه از دستور switch استفاده نموده
است :
+ // A simple example of the switch.
+ class SampleSwitch {
+ public static void main(String args[] ){
+ for(int i=0; in) عمل كاهش n و آزمايش براي صفر را در يك عبارت
گنجانده است . عملكرد آن بقرار بعدي است . ابتدا دستور n اجرا مي شود و n
را كاهش داده و مقدار جديد را به n برمي گرداند . اين مقدار سپس با صفر مقايسه
مي شود . اگر بزرگتر از صفر باشد ، حلقه ادامه مي يابد . در غير اينصورت حلقه
پايان مي گيرد .
حلقه do-while بويژه هنگام پردازش انتخاب منو بسيار سودمند است ، زيرا
معمولا" مايليد تا بدنه يك حلقه منو حداقل يكبار اجرا شود . برنامه بعدي را كه
يك سيستم Help ساده را براي دستورات تكرار و انتخاب در جاوا پياده سازي مي كند
در نظر بگيريد :
+ // Using a do-while to process a menu selection -- a simple help system.
+ class Menu {
+ public static void main(String args[])
+ throws java.io.IOException {
+ char choice;
+
+ do {
+ System.out.prinln("Help on:");
+ System.out.prinln(" 1 .if");
+ System.out.prinln(" 2 .switch");
+ System.out.prinln(" 3 .while");
+ System.out.prinln(" 4 .do-while");
+ System.out.prinln(" 5 .for\n");
+ System.out.prinln("Choose one:");
+ choice =( char )System.in.read)(;
+ } while(choice '5');
+
+ System.out.println("\n");
+ switch(choice ){
+ case '1':
+ System.out.println("The if:\n");
+ System.out.println("if(condition )statement;");
+ System.out.println("else statement;");
+ break;
+ case '2':
+
+ System.out.println("The switch:\n");
+ System.out.println("switch(expression ){");
+ System.out.println(" case constant:");
+ System.out.println(" statement sequence");
+ System.out.println(" break;");
+ System.out.println(" //... ");
+ System.out.println("}");
+ break;
+ case '3':
+ System.out.println("The switch:\n");
+ System.out.println(while(condition )statement;");
+ break;
+ case '4':
+ System.out.println("The do-while:\n");
+ System.out.println("do {");
+ System.out.println(" statement;");
+ System.out.println("} while( condition);");
+ break;
+ case '5':
+ System.out.println("The for:\n");
+ System.out.print("for(init; condition; iteration)");
+ System.out.println(" statement;");
+ break;
+ }
+ }
+ }
اكنون يك اجراي نمونه توليد شده توسط اين برنامه را مشاهده مي كنيد :
Help on:
1 .if
2 .switch
3 .while
4 .do-while
5 .for
Choos one:
4
The do-while:
do {
statement;
} while( condition);
در برنامه ، از حلقه do-while براي تصديق اينكه كاربر يك گزينه معتبر را
وارد كرده باشد ، استفاده مي شود . در غير اينصورت ، به كاربر مجددا" اعلان
خواهد شد . از آنجاييكه منو بايد حداقل يكبار بنمايش درآيد ، do-while حلقه
كاملي براي انجام اين مقصود است .
چند نكته ديگر درباره اين مثال : دقت كنيد كه كاراكترهااز صفحه كليد بوسيله
فراخواني ()system.in.read خوانده مي شوند . اين يكي از توابع ورودي كنسول در
جاوا است .
اگر چه بررسي تفصيلي روشهاي l/o جاوا به بحثهاي بعدي موكول شده ، اما از
()system.in.read در اينجا براي بدست آوردن گزينه كاربر استفاده شده است . اين
تابع كاراكترها را از ورودي استاندارد مي خواند ( كه بعنوان عدد صحيح برگردان
شد ، اين دليلي است كه چرا مقدار برگردان از طريق تبديل (cast) به char تبديل
شده است ). بصورت پيش فرض ، ورودي استاندارد، بافر شده خطي است (line buffered)
بنابراين قبل از اينكه كاراكترهايي را كه تايپ كرده ايد به برنامه اتان ارسال
كنيد ، بايد كليد ENTER را فشار دهيد . ( اين حالت مشابه C++/C است و احتمالا"
از قبل با آن آشنايي داريد ) .
ورودي كنسول در جاوا كاملا" محدود شده و كار با آن بسيار مشكل است . بعلاوه
اكثر برنامه و ريز برنامه هاي واقعي نوشته شده با جاوا گرافيكي و پنجره اي
هستند. از سوي ديگر : چون از ()system.in.read استفاده شده ، برنامه بايد جمله throwsjava.io.loException
را كاملا" توصيف نمايد . اين خط براي مديريت خطاهاي
ورودي ضروري است . اين بخشي از جنبه هاي مختلف اداره استثنائ در جاوا است كه
بعدا" بررسي خواهد شد .
for
خواهيد ديد كه حلقه for يك ساختار قدرتمند و بسيار روان است .شكل كلي دستور for
بصورت زير است :
for(initialization; condition; iteration; ){
// body
}
اگر فقط يك دستور بايد تكرار شود ، نيازي به ابروها نيست .
عملكرد حلقه for بشرح بعدي است . وقتي كه حلقه براي اولين بار شروع مي شود
بخض مقدار دهي اوليه در حلقه اجرا مي شود . معمولا" ، اين بخش يك عبارت است كه
مقدار متغير كنترل حلقه را تعيين مي كند ، كه بعنوان يك شمارشگر ، كنترل حلقه
را انجام خواهد داد . مهم است بدانيم كه عبارت مقدار دهي اوليه فقط يكبار اجرا
مي شود . سپس شرط مورد ارزيابي قرار مي گيرد . اين شرط بايد يك عبارت بولي
باشد . اين بخش معمولا" مقدار متغير كنترل حلقه را با مقدار هدف مقايسه مي كند.
اگر عبارت صحيح (true) باشد، آنگاه بدنه حلقه اجرا خواهد شد . اگر ناصحيح باشد
حلقه پايان مي گيرد . بعد، بخش تكرار (iteration) حلقه اجرا مي شود . اين بخش
معمولا" عبارتي است كه مقدار متغير كنترل را افزايش يا كاهش مي دهد. آنگاه حلقه
تكرار خواهد شد ، ابتدا عبارت شرطي را ارزيابي مي كند ، سپس بدنه حلقه را اجرا
مي كند و سرانجام عبارت تكرار را در هر گذر (pass) اجرا ميكند. اين روال آنقدر
دادمه مي يابد تا عبارت شرطي ناصحيح (false) گردد .
در زير روايت جديدي از برنامه "tick" را مي بينيد كه از يك حلقه for استفاده
كرده است :
+ // Demonstrate the for loop.
+ class ForTick {
+ public static void main(String args[] ){
+ int n;
+ for(n=10; n>0; n)--
+ System.out.println("tick" + n);
+ }
+ }
اعلان متغيرهاي كنترل حلقه داخل حلقه for
غالبا" متغيري كه يك حلقه for را كنترل مي كند ، فقط براي همان حلقه مورد
نياز بوده و كاربري ديگري ندارد . در چنين حالتي ، مي توان آن متغير را داخل
بخش مقدار دهي اوليه حلقه for اعلان نمود . بعنوان مثال در اينجا همان برنامه
قبلي را مشاهده مي كنيد كه متغير كنترل حلقه يعني n بعنوان يك int در داخل
حلقه for اعلان شده است .
+ // Declare a loop control variable inside the for.
+ class ForTick {
+ public static void main(String args[] ){
+
+ // here/ n is declared inside of the for loop
+ for(int n=10; n>0; n)--
+ System.out.println("tick" + n);
+ }
+ }
هنگاميكه يك متغير را داخل يك حلقه for اعلان مي كنيد ، يك نكته مهم را بايد
بياد داشته باشيد : قلمرو آن متغير هنگاميكه دستور for انجام مي شود ، پايان
مي يابد . ( يعني قلمرو متغير محدود به حلقه for است . ) خارج از حلقه for
حيات آن متغير متوقف مي شود . اگر بخواهيد از اين متغير كنترل حلقه در جاي
ديگري از برنامه اتان استفاده كنيد ، نبايد آن متغير را داخل حلقه for اعلان
نماييد .
درشرايطي كه متغير كنترل حلقه جاي ديگري موردنياز نباشد، اكثر برنامه نويسان
جاوا آن متغير را داخل for اعلان مي كنند . بعنوان مثال ، در اينجا يك برنامه
ساده را مشاهده مي كنيد كه بدنبال اعداد اول مي گردد. دقت كنيد كه متغير كنترل
حلقه ، چون جاي ديگري مورد نياز نيست ، داخل for اعلان شده است .
+ // Test for primes.
+ class FindPrime {
+ public static void main(String args[] ){
+ int num;
+ boolean isPrime = true;
+
+ num = 14;
+ for(int i=2; i < num/2; i++ ){
+ if((num % i )== 0 ){
+ isPrime = false;
+ break;
+ }
+ }
+ if(isPrime )System.out.println("Prime");
+ else System.out.println("Not Prime");
+ }
+ }
استفاده از كاما Comma
شرايطي پيش مي آيد كه مايليد بيش از يك دستور در بخش مقدار دهي اوليه
(initalization) و تكرار (iteration) بگنجانيد . بعنوان مثال ، حلقه موجود در
برنامه بعدي را در نظر بگيريد :
+ class Sample {
+ public static void main(String args[] ){
+ int a/ b;
+
+ b = 4;
+ for(a=1; a
+ System.out.println("a = " + a);
+ System.out.println("b = " + b);
+ b--;
+ }
+ }
+ }
همانطوريكه مي بينيد ، حلقه توسط ارتباط متقابل دو متغير كنترل مي شود . از
آنجاييكه حلقه توسط دو متغير اداره مي شود ، بجاي اينكه b را بصورت دستي اداره
كنيم ، بهتر است تا هر دو را در دستور for بگنجانيم . خوشبختانه جاوا راهي
براي اينكار دارد . براي اينكه دو يا چند متغير بتوانند يك حلقه for را كنترل
كنند ، جاوا به شما امكان مي دهد تا چندين دستور را در بخشهاي مقدار دهي اوليه
و تكرار حلقه for قرار دهيد . هر دستور را بوسيله يك كاما از دستور بعدي جدا
مي كنيم .
حلقه for قبلي را با استفاده از كاما ، خيلي كاراتر از قبل مي توان بصورت
زير كد بندي نمود :
+ // Using the comma.
+ class Comma {
+ public static void main(String args[] ){
+ int a/ b;
+
+ for(a=1/ b=4; a
+ System.out.println("a = " + a);
+ System.out.println("b = " + b);
+ }
+ }
+ }
در اين مثال ، بخش مقدار دهي اوليه ، مقادير aو bو را تعيين مي كند . هربار
كه حلقه تكرار مي شود ، دو دستور جدا شده توسط كاما در بخش تكرار (itration)
اجرا خواهند شد . خروجي اين برنامه بقرار زير مي باشد :
a=1
b=4
a=2
b=3
نكته : اگر با C++/C آشنايي داريد ، حتما" مي دانيد كه در اين زبانها ، علامت
كاما يك عملگر است كه در هر عبارت معتبري قابل استفاده است . اما در
جاوا اينطور نيست . در جاوا ، علامت كاما يك جدا كننده است كه فقط در
حلقه for قابل اعمال مي باشد .
برخي گوناگونيهاي حلقه for
حلقه for از تعدادي گوناگونيها پشتيباني مي كند كه قدرت و كاربري آن را
افزايش مي دهند . دليل انعطاف پذيري آن است كه لزومي ندارد كه سه بخش مقداردهي
اوليه ، آزمون شرط و تكرار ، فقط براي همان اهداف مورد استفاده قرار گيرند .
در حقيقت ، سه بخش حلقه for براي هر هدف مورد نظر شما قابل استفاده هستند . به
چند مثال توجه فرمائيد .
يكي از رايجترين گوناگونيها مربوط به عبارت شرطي است . بطور مشخص ، لزومي
ندارد اين عبارت ، متغير كنترل حلقه را با برخي مقادير هدف آزمايش نمايد . در
حقيقت ، شرط كنترل كننده حلقه for ممكن است هر نوع عبارت بولي باشد . بعنوان
مثال ، قطعه زير را در نظر بگيريد :
+ boolean done = false;
+
+ for(int i=1; !done; i++ ){
+ //...
+ if(intettupted ))(done = true;
+ }
در اين مثال ، حلقه for تا زمانيكه متغير بولي done معادل true بشود ، اجرا
را ادامه خواهد داد . اين مثال مقدار i را بررسي نمي كند .
اكنون يكي ديگر از گوناگونيهاي جالب حلقه for را مشاهده مي كنيد. ممكن است
يكي يا هر دو عبارت مقدار دهي اوليه و تكرار غايت باشند ، نظير برنامه بعدي :
+ // Parts of the for loop can be empty.
+ class ForVar {
+ public static void main(String args[] ){
+ int i;
+ boolean done = false;
+
+ i = 0;
+ for (; !done; ) {
+ System.out.println("i is" + i);
+ if(i == 10 )done = true;
+ i++;
+ }
+ }
+ }
در اينجا عبارتهاي مقدار دهي اوليه و تكرار به خارج ازfor انتقال يافته اند.
برخي از بخشهاي حلقه for تهي هستند . اگر چه در اين مثال ساده چنين حالتي هيچ
ارزشي ندارد ، اما در حقيقت شرايطي وجود دارد كه اين روش بسيار كارا و سودمند
خواهد بود. بعنوان مثال ، اگر شرط اوليه بصورت يك عبارت پيچيده و در جاي ديگري
از برنامه قرار گرفته باشد و يا تغييرات متغير كنترل حلقه بصورت غير ترتيبي و
توسط اعمال اتفاق افتاده در داخل بدنه حلقه تعيين شود ، پس بهتر است كه اين
بخشها را در حلقه for تهي بگذاريم .
اكنون يكي ديگر از گوناگونيهاي حلقه for را مشاهده مي كنيد. اگر هر سه بخش
حلقه for را تهي بگذاريد ، آنگاه بعمد يك حلقه نامحدود ( حلقه اي كه هرگز پايان
نمي گيرد ) ايجاد كرده ايد . بعنوان مثال :
+ for (; ; ) {
+ //...
+ }
اين حلقه تا ابد ادامه خواهد يافت ، زيرا هيچ شرطي براي پايان گرفتن آن
تعبيه نشده است . اگر چه برخي برنامه ها نظير پردازشهاي فرمان سيستم عامل
مستلزم يك حلقه نامحدود هستند ، اما اكثر حلقه هاي نامحدود در واقع حلقه هايي
هستند كه ملزومات پايان گيري ويژه اي دارند . بزودي خواهيد ديد ، راهي براي
پايان دادن به يك حلقه حتي يك حلقه نامحدود نظير مثال قبلي وجود دارد كه
از عبارت شرطي معمولي حلقه استفاده نمي كند .
حلقه هاي تودرتو
نظير كليه زبانهاي برنامه نويسي ، جاوا نيز امكان تودرتو كردن حلقه ها را
دارد . يعني يك حلقه داخل حلقه ديگري قرار خواهد گرفت . بعنوان مثال ، در
برنامه بعدي حلقه هاي for تودرتو نشده اند :
+ // Loops may be nested.
+ class Nested {
+ public static void main(String args[] ){
+ int i/ j;
+
+ for(i=0; i<10; i++ ){
+ for(j=i; j<10; j++)
+ System.out.print(".");
+ System.out.println)(;
+ }
+ }
+ }
بازدیدها: 294