آموزش برنامه نویسی جاوا: مفاهیم پایه در زبان جاوا (قسمت ۴)

چهارشنبه ۲۸ بهمن ۱۳۹۴ - ۱۵:۵۰
مطالعه 10 دقیقه
کامپیوتر‌ها برای ساده‌تر کردن زندگی ما انسان‌ها ساخته شده‌اند. یعنی بجای اینکه ما کاری را بار‌ها و بار‌ها انجام دهیم، فقط یک‌بار روش حل مسئله را می‌نویسیم و آن را در اختیار کامپیوتر قرار می‌دهیم و کامپیوتر آن را بدون اشتباه با هر تعداد دفعاتی که ما مشخص کنیم و با سرعت بسیار بالایی انجام می‌دهد. یکی از ساختار‌هایی که در برنامه نویسی کاربرد زیادی دارد، حلقه‌ی تکرار یا به اصطلاح Loop است.
تبلیغات

 در ادامه‌ی جلسه‌ی قبل که با ساختار کنترلی if آشنا شدیم، در این جلسه با یکی دیگر از ساختار‌های کنترلی تحت عنوان switch آشنا می‌شویم. ساختار switch مشابه‌ if else چندگانه است. ولی این ساختار تنها برای ارزیابی مساوی بودن یک عبارت با مقادیر گوناگون به کار می‌رود. به کد زیر با تمام دقت نگاه کنید:

switch

سلسله مطالب آمورش جاوا

برای نوشتن ساختار سوییچ، ابتدا باید از کلمه‌ی کلیدی switch استفاده کنیم. سپس در مقابل آن یک جفت پرانتز باز و بسته می‌نویسم. بعد از این کار ما باید بدنه‌ی switch را مشخص کنیم. برای این کار از آکولاد‌های باز و بسته استفاده می‌کنیم. (در آموزش‌های قبلی در مورد بدنه‌ی متد‌ها و کلاس‌ها توضیح داده‌ایم). حالا باید case‌هایی را داخل بدنه‌ی switch بنویسیم. اگر بخواهیم case را در فارسی معنی کنیم، بهترین معنی واژه‌ی گزینه است. یعنی ما باید در داخل بدنه‌ی switch گزینه‌هایی را برای مقایسه با کلید اصلی بنویسیم. همانطور که در تصویر مشخص شده است، کلید ما مقداری است که در داخل پرانتز مقابل switch نوشته می‌شود. case‌های ما که به هر تعدادی می‌تواند باشد، از ابتدا یکی یکی با کلید اصلی مقایسه می‌شود و هرکدام از گزینه‌ها (case‌ها) که برابر با کلید اصلی بود، اجرا می‌شود. در کد از کلمه‌ی کلیدی دیگری با نام break استفاده شده است. کاربرد break به این صورت است که هرگاه مقدار یک case با کلید اصلی برابر شد و آن case اجرا شد، بعد از پایان کد‌های نوشته شده مربوط به گزینه‌ی مورد نظر، برنامه از ساختار switch خارج می‌شود و دیگر کد‌های مربوط به case‌های اجرا نمی‌شود. توجه داشته باشید که ما می‌خواهیم از بین چند گزینه فقط گزینه‌ای که با کلید اصلی برابر است را پیدا کنیم. بنابراین بعد از پیدا کردن گزینه‌ی مورد نظر و اجرای دستورات آن، دیگر نیازی نیست که سایر case‌ها اجرا شوند و باید از ساختار switch خارج شویم. اگر break را ننویسیم، تمام case‌ها یکی پس از دیگری اجرا می‌شود و خروجی برنامه‌ی ما یک چیز نامعلوم می‌شود. در آخر از یک کلمه‌ی کلیدی دیگری به نام default استفاده شده است. کاربرد default برای این است که فرض کنید تمام مقادیر case‌های ما با مقدار کلید اصلی برابر نباشند، در این صورت اگر default نباشد برنامه‌ی ما هیچ خروجی‌ای ندارد. ما می‌توانیم در default پیغامی را بنویسیم تا اگر مقادیر case‌های ما با کلید اصلی برابر نبودند، به کاربر نمایش دهد و برنامه‌ی ما بدون خروجی باقی نماند.

حالا می‌خواهیم با یک مثال بسیار ساده کاربرد ساختار سوییچ را آموزش دهیم. در این مثال ما مقدار 10 را برای کلید اصلی در نظر می‌گیریم. به کد زیر دقت کنید:

switch

همانطور که در کد مشخص است ما یک متغیر با نام num از نوع Integer (عدد صحیح) تعریف کرده‌ایم و مقدار آن را صفر در نظر گرفته‌ایم. سپس ساختار switch را نوشته‌ایم. متغیر num را برای کلید اصلی در نظر گرفته‌ایم. یعنی قرار است که ما case‌های داخل بدنه‌ی سوییچ را با متغیر num مقایسه کنیم و اگر هرکدام از case‌ها که مقدار آن با مقدار متغیر num برابر بود، کد مربوط به آن case اجرا می‌شود و سپس برنامه از ساختار switch خارج می‌شود.

برای مقدار دهی case‌ ها ابتدا کلمه‌ی کلیدی case را می‌نویسیم و سپس یک فاصله (space) می‌دهیم و بعد مقدار مورد نظرمان را در جلوی آن می‌نویسیم. مثلا اولین case ما مقدار صفر دارد. دومی مقدار یک و سومی مقدار دو دارد. توجه داشته باشید که 0, 1, 2 مقادیر case‌های ما هستند و به اشتباه فکر نکنید که case‌ها دارای شماره هستند. بعد از اینکه ما مقدار یک case را مشخص کردیم، در مقابل آن یک دو نقطه قرار می‌دهیم و سپس در مقابل آن یا در خط پایین آن دستورات مربوط به case را می‌نویسیم.

در این برنامه اولین case ما مقدار صفر دارد. مقدار این case با کلید اصلی مقایسه می‌شود. آیا مقدار آن با کلید اصلی یکسان است؟ بله. بنابراین کد مربوط به این case اجرا می‌شود. یعنی پیغام: Good Luck در خروجی استاندارد چاپ می‌شود و سپس از ساختار switch خارج می‌شود و دیگر case‌های بعدی اجرا نمی‌شوند. حالا می‌توانید به عنوان تمرین مقدار متغیر num را تغییر دهید تا خروجی‌های متفاوت آن را ببینید.

ساختار تکرار for

حلقه‌ی for پرکاربردترین حلقه در جاوا است. شاید بتوان برنامه‌هایی را که با ساختار for پیاده‌سازی می‌کنیم را با سایر حلقه‌های دیگر بنویسیم. اما هرکدام برای کار خاصی طراحی شده‌اند و بهتر است با توجه به شرایطی که در برنامه به وجود می‌آید، ساختار مناسب را انتخاب کنیم. شرط انتخاب حلقه‌ی for این است که ما تعداد دفعات تکرار حلقه را از قبل بدانیم. فرض کنید می‌خواهیم یک عملیات را ۱۰ مرتبه اجرا کنیم. بنابراین بهتر است که از ساختار for استفاده کنیم. ساختار کلی for به صورت زیر است. با دقت به کد نگاه کنید:

for-loop

همانطور که در کد فوق مشاهده می‌کنید ساختار بسیار ساده‌ای دارد. ابتدا کلمه‌ی کلیدی for را می‌نویسیم و بعد یک جفت پرانتز باز و بسته قرار می‌دهیم. چنانچه می‌بینید در داخل پرانتز ما سه قسمت جداگانه وجود دارد که هر قسمت با یک سمی‌کالن (;) از هم جدا می‌شوند. همانطور که قرار است حلقه‌ی ما به تعداد 10 بار اجرا شود، پس نیاز به یک شمارنده دارد که با هر بار اجرای حلقه مقداری به شمارنده‌ی ما اضافه یا کم شود. (مقداری که باید اضافه یا کم شود توسط برنامه نویس مشخص می‌شود). مثلا در برنامه‌ی ما مقدار شمارنده در هر بار اجرای حلقه یک واحد اضافه می‌شود. (در مورد ++i در ادامه‌ی همین آموزش توضیح می‌دهیم). قسمت دوم شرط حلقه است. شرط حلقه‌ی ما این است که تا زمانی که مقدار متغیر i به 9 نرسیده است، این حلقه ادامه داشته باشید و زمانی که به 9 رسید دیگر حلقه ادامه پیدا نکند و از ساختار for خارج شود. قسمت سوم هم گام حرکت شمارنده است. یعنی شمارنده‌ی ما چگونه تغییر کند. مثلا در برنامه‌ی ما در هر بار اجرای حلقه یک واحد به شمارنده اضافه می‌شود تا به عدد 9 برسد. ممکن است در یک برنامه‌ی دیگر بجای یک واحد، دو واحد و یا سه واحد به شمارنده اضافه شود یا ممکن است که از مقدار شمارنده کم شود. بنابراین تغییر شمارنده بستگی به برنامه‌ای است که در حال نوشتن آن هستیم.

عملگر ++

در مورد گام حرکت شمارنده نکته‌ای است که باید بسیار به آن دقت کنید. ما می‌توانیم یک متغیر را به صورت ++i یا i++ بنویسیم. یعنی علامت ++ (plus plus) یکبار در سمت راست متغیر قرار دارد و بار دیگر در سمت چپ آن. این عملگر باعث افزایش یک واحد در متغیر می‌شود. در بعضی از مواقع سمت راست یا چپ نوشتن عملگر ++ تغییری در برنامه ایجاد نمی‌کند. اما مفهوم آن را باید بدانید.

اگر عملگر ++ را در سمت راست متغیر بنویسید: یعنی ++i، مقدار متغیر i ابتدا در برنامه استفاده می‌شود و بعد یک واحد به مقدار متغیر اضافه می‌شود. اما اگر عملگر ++ را در سمت چپ متغیر بنویسید: یعنی i++، ابتدا به متغیر یک واحد اضافه می‌شود و بعد در برنامه استفاده می‌شود. برای روشن شدن این مسئله به مثال زیر دقت کنید:

++

خروجی برنامه‌ی بالا در زیر آمده است. با دقت نگاه کنید:

++

همانطور که در کد مشاهده می‌کنید ما ابتدا دو متغیر با نام‌های a و b ایجاد کرده‌ایم و مقدار آن‌ها را صفر در نظر گرفته‌ایم و بعد مقادیر آن دو متغیر را چاپ کرده ایم. همانطور که در خروجی مشاهده می‌کنید، مقادیر متغیر‌ها همانطور که خودمان مشخص کردیم، قبل از تغییر صفر است. اما بعد از تغییر مقدار متغیر a از صفر به یک تغییر کرده است اما متغیر b تغییر نکرده است. در حالی که ما در برنامه مقدار متغیر b را برابر با ++a در نظر گرفتیم. همانطور که گفتیم عملگر ++ باعث افزایش یک واحد در متغیر می‌شود، بنابراین باید متغیر b هم به یک تغییر می‌کرد. اما چرا تغییر نکرد!؟ دلیلش این است که ابتدا متغیر a در برنامه استفاده شد و بعد به مقدار آن یک واحد اضافه شد. یعنی ابتدا مقدار متغیر a که صفر بود به متغیر b داده شد و بعد به مقدار متغیر a یک واحد اضافه شد.

حالا بر می‌گردیم به حلقه‌ی for. ما می‌خواهیم هنگامی که برنامه اجرا شد، اعداد 0 تا 9 در خروجی استاندارد چاپ شود. برای این‌کار کد خود را به صورت زیر تغییر می‌دهیم:

شمارنده‌ی ما (متغیر i) مقدار صفر دارد و در هر بار اجرای حلقه یک واحد به آن اضافه می‌شود. ما همان متغیر را در خروجی استاندارد چاپ کرده‌ایم. بنابراین خروجی برنامه‌ی ما چاپ اعدا 0 تا 9 است.

نکته‌ی دیگری که در مورد حلقه‌ها وجود دارد این است که اگر الگوریتمی که برای طراحی حلقه پیاده‌سازی می‌کنیم اشتباه باشد، با نتایج متفاوتی رو به رو می‌شویم. مثلا ممکن است که حلقه‌ی ما پایان نداشته باشد و تا بی‌نهایت ادامه داشته باشد. یک حلقه‌ی بی‌نهایت ساده در زیر مشاهده می‌کنید:

for-loop

در کد بالا شرط حلقه هیچ وقت برقرار نمی‌شود. یعنی همیشه متغیر i یک واحد کم می‌آورد. برای همین این حلقه تا بی‌نهایت ادامه دارد. (بعد از اجرای برنامه، برای نگه داری برنامه بر روی دکمه‌ی قرمز رنگ در کنسول اکلیپس با نام Terminate کلیک کنید).

حلقه‌های تو در تو

اگر در داخل بدنه‌ی یک حلقه از یک حلقه‌ی دیگری استفاده شود، می‌گوییم که حلقه‌های تو در تو ایجاد شده‌اند. نکته‌ای که باید در مورد حلقه‌های تو در تو یا (Nested Loops) توجه کنیم این است که به ازای هر بار تغییر شمارنده‌ی حلقه‌ی بیرونی، حلقه‌ی درونی یک‌بار به طور کامل اجرا می‌شود. به عنوان مثال فرض کنید شمارنده‌ی حلقه‌ی بیرونی و داخلی 0 است. وقتی شمارنده‌ی حلقه‌ی بیرونی از صفر به یک تبدیل می‌شود، حلقه‌ی داخلی یک‌بار به طور کامل (به عنوان مثال اگر شرط حلقه 10 است) یعنی 10 بار اجرا می‌شود و بعد از ده بار اجرای حلقه‌ی داخلی، حلقه‌ی بیرونی یک‌بار دیگر تغییر می‌کند.

به عنوان تمرین برنامه‌ای بنویسید که جدول ضرب را از 0 تا 100 به صورت مرتب چاپ کند. (برای حل این مسئله در مورد کارکتر‌های کنترلی تحقیق کنید. به عنوان مثال کارکتر کنترلی t\). خروجی جدول ضرب به صورت زیر است:

nested-loops

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

در جلسه‌ی آینده در مورد ساختار‌های حلقه‌های تکرار دیگر در جاوا صحبت می‌کنیم.

تبلیغات
داغ‌ترین مطالب روز

نظرات

تبلیغات