همانطور که میدانیم، در حدود 40 تا 50 سال پیش روال کاری مدارس بدین شکل بود که تکالیف نوروزی دانشآموزان را مثلاً نوشتن از روی کتاب فارسی به تعداد دفعات بسیار تعیین میکردند. در واقع، دانشآموزان موظف بودند تا چیزی تکراری را بارها و بارها بنویسند تا مثلاً تعداد 7 سری از تمامی دروس کتاب درسی مورد نظر نوشته شود که پس از 7 مرتبه رونویسی از روی کتاب، تکالیف دانشآموز به پایان رسیده و فرآیند بازنویسی متوقف میشد!
در دنیای برنامهنویسی چنین شرایطی با بهکارگیری مفهوم Loop یا «حلقه» قابل پیادهسازی میباشد. به عبارت دیگر، با استفاده از لوپ میتوانیم کاری ثابت را به تعداد دفعات مورد نیاز و حتی به تعداد بینهایت بار تکرار کنیم. به طور کلی، در زبان برنامهنویسی جاوا سه ساختار متفاوت برای پیادهسازی حلقهها داریم که عبارتند از do و while و همچنین حلقۀ for که هر یک از آنها کارکرد متفاوتی داشته و بسته به نیاز برنامۀ مورد نظر، در شرایط خاصی مورد استفاده قرار میگیرند. در این آموزش قصد داریم تا با ساختار حلقۀ for آشنا شده و در آموزشهای آتی با ساختار و همچنین نحوۀ پیادهسازی سایر حلقهها آشنا خواهیم شد.
نحوۀ بهکارگیری حلقۀ for در زبان برنامهنویسی جاوا
به عنوان یک مثال در دنیای واقعی، میتوان روال کاری آنتیویروس نصبشده روی سیستم را نام برد که در صورت دریافت ایمیلی جدید آنتیویروس مذکور فعال شده و ایمیل دریافتی را چک میکند تا ببیند که حاوی ویروس است یا خیر که انجام این کار توسط دستورات مرتبط با حلقهها پیادهسازی میشود. به عنوان مثالی دیگر هم میتوان Screen Saver را نام برد که در آن کاری تکراری بارها و بارها انجام میشود (به طور مثال یک توپ مکرراً از سمت چپ به سمت راست حرکت میکند و بالعکس) که انجام چنین کاری نیز توسط ساختار حلقهها پیادهسازی شده است.
حال برای درک مفهوم حلقۀ for به صورت عملی، پروژهای جدید تحت عنوان ForLoop ایجاد کرده و کلاسی تحت عنوان ForLoop در آن میسازیم که در ابتدا کدی به صورت زیر خواهیم داشت:
public class ForLoop {
public static void main(String[] args) {
}
}
برای پیادهسازی حلقۀ for ابتدا کیورد for با حروف کوچک را نوشته و مقابل آن دو علامت ( ) قرار میدهیم که داخل این علائم میباید سه پارامتر را درج نماییم که پارامتر اول نقطۀ آغازین حلقه بوده، پارامتر دوم نقطۀ انتهایی آن میباشد و در نهایت پارامتر سوم به منظور مشخص کردن مقدار افزایشی مرتبط با نقطۀ آغازین در هر بار تکرار حلقه مورد استفاده قرار میگیرد. به عبارت بهتر، پارامتر دوم در حلقۀ for به عنوان شرطی در نظر گرفته میشود که تا وقتی true باشد، اجرای دستورات مرتبط با حلقۀ مورد نظر ادامه مییابد و به محض false شدن شرط مربوط به پارامتر دوم، برنامه از حلقه خارج میشود. در نهایت، دو علامت { } قرار داده و دستوراتی را داخل علائم مذکور مینویسیم که قصد داریم تا به تعداد دفعات مورد نظر تکرار شوند.
برای مثال، در کد زیر حلقهای تعریف کردهايم كه از نقطۀ آغازین 1 شروع شده و پس از هر بار تكرار حلقه یک واحد به آن اضافه شده و در نهایت در نقطۀ پایانی 10 توقف مینماید:
public class ForLoop {
public static void main(String[] args) {
for (int number = 1; number <= 10; number++) {
System.out.println(number);
}
}
}
همانطور که در کد فوق میبینیم، با استفاده از دیتا تایپ int متغیری تحت عنوان number با مقدار اولیۀ 1 به عنوان نقطۀ آغازین تعریف کردهایم سپس یک علامت ; قرار میدهیم و بلافاصله نقطۀ پایانی را برای حلقۀ مورد نظر تعریف میکنیم که در آن گفتهایم تا زمانی حلقۀ for تکرار شود که مقدار اختصاصیافته به متغیر number کوچکتر از 10 یا مساوی آن باشد و در نهایت هم پارامتر سوم را داریم که نشانگر میزان افزایش مقدار منتسب به متغیر number در هر بار تکرار حلقه است که در این مثال یک واحد میباشد (علائم ++ نشانگر یک واحد افزایش هستند.)
در ادامه و داخل علائم { } دستور مورد نظر خود مبنی بر چاپ مقدار منتسب به متغیر number را مینویسیم بدین معنی که مقدار اختصاصیافته به متغیر مذکور در هر بار تکرار حلقه در کنسول چاپ شده و در نهایت یک واحد به مقدار قبلیِ منتسب به آن افزوده میشود و این کار تا زمانی ادامه مییابد که مقدار منتسب به متغیر number به عدد 10 برسد. حال کد فوق را اجرا کرده و در خروجی خواهیم داشت:
1
2
3
4
5
6
7
8
9
10نکتهای که در مورد کد فوق وجود دارد این است که میتوان متغیر number را خارج از حلقۀ for نیز تعریف کرد. به عبارت دیگر، کد فوق را به شکل زیر نیز میتوان بازنویسی نمود:
public class ForLoop {
public static void main(String[] args) {
int number;
for (number = 1; number <= 10; number++) {
System.out.println(number);
}
}
}
همانطور که مشاهده میکنیم، با بهکارگیری دیتا تایپ int متغیری تحت عنوان number خارج از حلقۀ for تعریف نمودهایم سپس داخل حلقه نیز مقدار اولیه، مقدار نهایی و همچنین مقدار افزایشیِ مورد نظر را به آن اختصاص دادهایم و با اجرای برنامۀ فوق نیز میبینیم که هر یک از اعداد 1 تا 10 در کنسول چاپ شده و این فرآیند با رسیدن به عدد 10 متوقف میشود:
1
2
3
4
5
6
7
8
9
10اکنون به منظور نهادینه کردن مفهوم حلقۀ for تغییراتی را در برنامهٔ فوق اِعمال میکنیم. برای مثال، حلقهای تعریف میکنیم تا اعدادی را با شروع از عدد 1 در کنسول چاپ کرده و هر بار سه واحد بدان اضافه کند و این فرآیند تا زمان رسیدن به عدد 22 تکرار شود. برای این منظور کد فوق را به شکل زیر بازنویسی میکنیم:
public class ForLoop {
public static void main(String[] args) {
for (int number = 1; number <= 22; number += 3) {
System.out.println(number);
}
}
}
برنامۀ فوق را اجرا کرده و در خروجی خواهیم داشت:
1
4
7
10
13
16
19
22همانطور که مشاهده میکنیم، اجرای دستورات داخلی حلقۀ for با چاپ عدد 1 در کنسول شروع شده و در هر بار تکرار حلقه سه واحد به عدد قبلیِ اختصاصیافته به متغیر number افزوده شده و اجرای دستورات مذکور تا زمان رسیدن مقدار منتسب به متغیر number به عدد 22 ادامه یافته است.
اکنون فرض کنیم که میخواهیم برنامۀ خود را به نوعی بازنویسی کنیم که چاپ اعداد در کنسول از عدد 1 شروع شده و تا بینهایت ادامه یابد. برای این منظور کد فوق را به شکل زیر بازنویسی خواهیم کرد:
public class ForLoop {
public static void main(String[] args) {
for (int number = 1; number > 0; number++) {
System.out.println(number);
}
}
}
در کد فوق، مقدار اولیۀ 1 را برای متغیر number در نظر گرفتهایم سپس شرط تکرار حلقه را بدین صورت تعریف کردهایم که در آن گفتهایم تا زمانی که مقدار اختصاصیافته به متغیر number بزرگتر از صفر باشد، حلقه تکرار شده و در هر بار تکرار نیز یک واحد به مقدار قبلیِ منتسب به متغیر number اضافه شود و از آنجایی که مقدار اولیۀ متغیر number برابر با 1 بوده و بزرگتر از صفر میباشد، بنابراین میتوان گفت که مقدار متغیر number همواره بزرگتر از صفر میباشد و بدین ترتیب شرط حلقه تا بینهایت برابر با true است و هیچ نقطۀ پایانی برای آن در نظر گرفته نمیشود! بنابراین خروجی از حاصل از اجرای کد فوق به صورت زیر میباشد:
125068
125069
125070
125071
125072
125073
125074
125075
125076
125077
125078
125079
125080
.
.
.در واقع، سه نقطۀ پایانی در خروجی فوق بدین معنی است که حلقۀ for تعریفشده تا بینهایت ادامه دارد و تنها در صورتی متوقف میشود که خود برنامهنویس به صورت دستی اقدام به انجام این کار نماید که چنین کاری در آیدیای اکلیپس با فشردن دکمۀ قرمز رنگ تحت عنوان Terminate در بخش کنسول امکانپذیر میباشد.
حال فرض کنیم که قصد داریم تا یک حلقۀ for پیادهسازی کنیم تا خروجی حاصل از آن با استرینگ مورد نظر Concate (الحاق) شده و در کنسول چاپ شود. برای این منظور کد فوق را به صورت زیر بازنویسی میکنیم:
public class ForLoop {
public static void main(String[] args) {
for (int number = 1; number <= 10; number++) {
System.out.println("My Number Is: " + number);
}
}
}
در کد فوق، استرینگ «:My Number Is» را به دستورات داخلی حلقۀ for اضافه کردهایم بدین صورت که مقدار منتسب به متغیر number با استفاده از یک عملگر + با استرینگ فوق کانکت شده و در قالب یک مقدار استرینگ در کنسول چاپ میشود که بدین ترتیب دستوری مبنی بر چاپ اعداد با شروع از عدد 1 به همراه استرینگ مذکور اجرا شده و تا رسیدن مقدار منتسب به متغیر number به عدد 10 ادامه مییابد و در هر بار تکرار حلقه نیز یک واحد بر مقدار قبلیِ اختصاصيافته به متغير number اضافه میشود به طوری که در خروجی داریم:
My Number Is: 1
My Number Is: 2
My Number Is: 3
My Number Is: 4
My Number Is: 5
My Number Is: 6
My Number Is: 7
My Number Is: 8
My Number Is: 9
My Number Is: 10اکنون مجدداً دستورات داخلی حلقۀ for را تغییر میدهیم بدین صورت که در هر بار تکرار حلقه و افزایش مقدار قبلیِ منتسب به متغیر number مقدار جدید در عدد 10 ضرب شده و به همراه استرینگ «:My Number Is» در کنسول چاپ شود که برای این منظور کد فوق را به شکل زیر بازنویسی میکنیم:
public class ForLoop {
public static void main(String[] args) {
for (int number = 1; number <= 10; number++) {
int multiply = number * 10;
System.out.println("My Number Is: " + multiply);
}
}
}
در کد فوق، با استفاده از دیتا تایپ int متغیر جدیدی تحت عنوان multiply تعریف کرده و نتیجۀ حاصل از ضرب مقدار اختصاصیافته به متغیر number در عدد 10 را بدان منتسب کردهایم. بنابراین حلقۀ for اجرا شده و عدد 1 به متغیر number اختصاص مییابد سپس شرط حلقه چک میشود که مقدار متغیر number کمتر از 10 بوده و از همین روی دستورات داخلی آن اجرا میگردند كه در نتيجه عدد 1 در عدد 10 ضرب شده و مقدار حاصل به متغير multiply اختصاص داده میشود و در سطر بعد مقدار منتسب به این متغیر به همراه استرینگ فوق در خروجی چاپ میگردد و در پایانِ اجرای دستورات داخلی نیز مقدار متغیر number یک واحد افزایش یافته و فرآیند فوقالذکر مجدداً تکرار میشود تا زمانی که مقدار متغیر number به عدد 11 رسیده و پارامتر دوم false شده و در نتیجه مفسر از حلقه خارج میگردد. بنابراین با اجرای برنامۀ فوق در خروجی داریم:
My Number Is: 10
My Number Is: 20
My Number Is: 30
My Number Is: 40
My Number Is: 50
My Number Is: 60
My Number Is: 70
My Number Is: 80
My Number Is: 90
My Number Is: 100
به عنوان مثال پایانی، چنانچه بخواهیم تا برنامۀ فوق را بدین شکل تغییر دهیم که مقدار متغیر number در هر بار تکرار حلقه در عددی همچون 0/12 ضرب شود، نیاز به استفاده از دیتا تایپ double داریم که بدین وسیله متغیری تعریف میکنیم تا در هر بار تکرار حلقه نتیجۀ حاصل از ضرب مقدار منتسب به متغیر number در عدد 0/12 را در آن ذخیره کرده و دستورات مد نظر را روی آن اجرا نماییم که برای این منظور کد فوق را به صورت زیر بازنویسی میکنیم:
public class ForLoop {
public static void main(String[] args) {
for (int number = 1; number <= 10; number++) {
double multiply = number * 0.12;
System.out.println("My Number Is: " + multiply);
}
}
}
مشابه آنچه که در مثال قبل توضیح دادیم، مقدار منتسب به متغیر number با شروع از عدد 1 در عدد 0/12 ضرب شده و مقدار حاصل به متغير multiply منتسب شده و به همراه استرینگ فوق در کنسول چاپ میشود که در هر بار تکرار حلقه یک واحد به مقدار قبلیِ منتسب به number افزوده شده و مجدداً در عدد 0/12 ضرب شده و مقدار حاصل به همراه استرینگ مذکور در کنسول چاپ میگردد که این فرآیند تا زمانی ادامه میيابد که مقدار اختصاصیافته به متغیر number کمتر از 10 یا مساوی با آن است. حال با اجرای برنامۀ فوق در خروجی داریم:
My Number Is: 0.12
My Number Is: 0.24
My Number Is: 0.36
My Number Is: 0.48
My Number Is: 0.6
My Number Is: 0.72
My Number Is: 0.84
My Number Is: 0.96
My Number Is: 1.08
My Number Is: 1.2همانطور که میبینیم، مقدار number با شروع از عدد 1 در عدد 0/12 ضرب شده و به همراه استرینگ «:My Number Is» در کنسول چاپ شده است. در واقع، تکرار حلقۀ فوق تا زمانی ادامه مییابد که شرط مربوط به پارامتر دوم true بوده و به محض اینکه شرط مذکور برقرار نباشد (یا به عبارتی مقدار منتسب به متغیر number بزرگتر از عدد 10 شود.) اجرای دستورات داخلی آن متوقف میشود.
