أتمتة المهام المتكررة بكفاءة وفعالية
تُعد **الحلقات (Loops)** ركنًا أساسيًا في عالم البرمجة، فهي تمنحنا القدرة على تكرار تنفيذ مجموعة من الأوامر عددًا من المرات دون الحاجة لكتابة نفس الكود مرارًا وتكرارًا. هذه الوحدة ستأخذك في رحلة عميقة لاستكشاف الأنواع المختلفة للحلقات في لغة الجافا، وكيفية استخدامها بفاعلية لجعل برامجك أكثر كفاءة وقوة.
بعد إتقانك لجمل التحكم الشرطية في الوحدة السابقة، ستجد أن الحلقات تكمل هذا المفهوم بتمكين برامجك من أداء مهام متكررة بذكاء وديناميكية. سنتعلم متى نختار النوع المناسب من الحلقات (for، while، do-while) وكيف نتحكم في تدفقها باستخدام أدوات قوية مثل break و continue.
بنهاية هذه الوحدة، ستكون قادرًا على:
for، while، و do-while.for لتكرار الكود لعدد معروف مسبقًا من المرات.while لتكرار الكود طالما أن شرط معين صحيح.do-while التي تضمن تنفيذ الكود مرة واحدة على الأقل.break و continue.تخيل أن لديك مهمة تتطلب تكرار نفس العملية عدة مرات، مثلاً: طباعة الأعداد من 1 إلى 100، أو جمع درجات 50 طالبًا، أو معالجة كل ملف في مجلد معين. بدون الحلقات، ستضطر إلى كتابة سطر كود لكل عملية، مما سيجعل الكود طويلًا، صعب القراءة، وأكثر عرضة للأخطاء. هنا تكمن قوة **الحلقات (Loops)**.
**الحلقات (Loops)** هي هياكل تحكم في البرمجة تسمح بتكرار تنفيذ مجموعة معينة من التعليمات البرمجية طالما أن شرطًا معينًا يظل صحيحًا، أو لعدد محدد من المرات. إنها تُعد من اللبنات الأساسية في بناء برامج فعالة، ديناميكية، ومختصرة.
توفر لغة الجافا ثلاثة أنواع رئيسية من الحلقات، كل نوع له بنيته واستخداماته المفضلة:
حلقة for هي الخيار الأمثل عندما يكون **عدد مرات التكرار معروفًا مسبقًا**. على سبيل المثال، إذا كنت تريد طباعة قائمة بأسماء الطلاب، أو حساب مجموع 10 أرقام، فإن for هي الأنسب. تتميز حلقة `for` بأنها تجمع جميع عناصر التحكم في التكرار (التهيئة، الشرط، والتحديث) في سطر واحد، مما يجعلها أنيقة ومنظمة.
بنيتها الأساسية:
for (initialization; condition; update) {
// مجموعة الأوامر التي سيتم تكرار تنفيذها
}
true، تستمر الحلقة في التنفيذ. إذا أصبحت false، تتوقف الحلقة وينتقل التحكم إلى الجملة التي تليها مباشرة.public class ForLoopNumbers {
public static void main(String[] args) {
System.out.println("طباعة الأعداد باستخدام for:");
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
}
}
الشرح:
int i = 1;: يبدأ العداد i من القيمة 1 (تهيئة).i <= 5;: الشرط هو أن يستمر التكرار طالما أن i أقل من أو يساوي 5.i++: بعد كل دورة، تزداد قيمة i بمقدار 1 (تحديث).الناتج المتوقع:
طباعة الأعداد باستخدام for:
1
2
3
4
5
حلقة while هي الأكثر مرونة، وتُستخدم عندما **لا نعرف عدد مرات التكرار مسبقًا**، ولكن لدينا شرط معين يجب أن يتحقق لكي تستمر الحلقة. طالما أن الشرط صحيح، تستمر الحلقة في العمل. غالبًا ما تُستخدم في سيناريوهات مثل قراءة البيانات حتى تصل إلى نهاية ملف، أو الاستمرار في طلب إدخال من المستخدم حتى يُدخل قيمة صحيحة.
بنيتها الأساسية:
while (condition) {
// مجموعة الأوامر التي سيتم تكرار تنفيذها
// يجب أن يكون هناك كود داخل الكتلة يؤثر على الشرط ليصبح false في النهاية،
// وإلا ستكون حلقة لا نهائية (infinite loop)
}
public class WhileLoopNumbers {
public static void main(String[] args) {
System.out.println("طباعة الأعداد باستخدام while:");
int i = 1; // تهيئة المتغير خارج الحلقة
while (i <= 5) { // الشرط
System.out.println(i);
i++; // تحديث المتغير داخل الحلقة
}
}
}
الشرح: يتم تهيئة `i` قبل الحلقة. يتم فحص الشرط (`i <= 5`) في بداية كل دورة. إذا كان صحيحًا، تُنفذ الأوامر ثم يتم تحديث `i`. هذا الترتيب يعني أن الكود داخل الحلقة قد لا يُنفذ أبدًا إذا كان الشرط خاطئًا من البداية.
الناتج المتوقع:
طباعة الأعداد باستخدام while:
1
2
3
4
5
حلقة do-while هي نوع خاص من حلقات `while`. الفرق الأساسي يكمن في ترتيب فحص الشرط. في do-while، يتم تنفيذ مجموعة الأوامر **مرة واحدة على الأقل** قبل أن يتم تقييم الشرط. هذا يعني أن كتلة do ستُنفذ دائمًا، حتى لو كان الشرط خاطئًا من البداية. تُستخدم هذه الحلقة عادةً عندما تحتاج إلى التأكد من تنفيذ عملية معينة مرة واحدة على الأقل، مثل طلب إدخال من المستخدم ثم التحقق من صحته.
بنيتها الأساسية:
do {
// مجموعة الأوامر التي سيتم تكرار تنفيذها
// تُنفذ هذه الأوامر مرة واحدة على الأقل
} while (condition); // يتم تقييم الشرط في نهاية الدورة
import java.util.Scanner;
public class DoWhilePositiveNumber {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int number;
System.out.println("سنطلب منك إدخال رقم موجب.");
do {
System.out.print("أدخل رقمًا موجبًا: ");
number = input.nextInt();
if (number <= 0) {
System.out.println("الرقم الذي أدخلته غير موجب، يرجى المحاولة مرة أخرى.");
}
} while (number <= 0); // ستستمر الحلقة طالما أن الرقم ليس موجباً
System.out.println("شكرًا لك! لقد أدخلت الرقم الموجب: " + number);
input.close();
}
}
الشرح: في هذا المثال، سيتم طلب الرقم من المستخدم مرة واحدة على الأقل. إذا أدخل المستخدم رقمًا غير موجب، سيتم طباعة رسالة الخطأ وستستمر الحلقة في التكرار حتى يتم إدخال رقم موجب.
اختيار الحلقة الصحيحة يعتمد على السيناريو الذي تعمل عليه. فهم الفروقات الرئيسية سيساعدك على اتخاذ القرار الأمثل:
| نوع الحلقة | متى تُستخدم (الحالات الشائعة) | السمات الرئيسية والمميزات |
|---|---|---|
for |
|
|
while |
|
|
do-while |
|
|
تذكر أن اختيار الحلقة المناسبة يؤثر على كفاءة الكود وقابليته للقراءة والصيانة. حاول دائمًا أن تختار النوع الذي يعبر بوضوح عن نيتك البرمجية.
إلى جانب الشروط التي تحدد متى تبدأ الحلقة ومتى تتوقف، توفر لنا جافا جملتي تحكم إضافيتين لمنحنا سيطرة أدق على سلوك الحلقات:
break، يتوقف تنفيذ الحلقة فورًا، وينتقل التحكم إلى أول جملة كود تلي الحلقة مباشرةً. إنها مفيدة لإنهاء الحلقة مبكرًا عند استيفاء شرط معين لا يتطلب استكمال جميع التكرارات.break التي تنهي الحلقة، جملة continue تُستخدم لتجاوز الدورة **الحالية** من الحلقة والانتقال مباشرةً إلى الدورة التالية. يتم تجاهل أي تعليمات برمجية موجودة بعد continue في الدورة الحالية، وتنتقل الحلقة مباشرةً إلى تحديث متغير التحكم (في حالة for) أو فحص الشرط (في حالة while و do-while) لبدء الدورة الجديدة.public class ContinueExample {
public static void main(String[] args) {
System.out.println("طباعة الأعداد الفردية فقط من 1 إلى 10:");
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) { // إذا كان العدد زوجيًا (باقي القسمة على 2 يساوي 0)
continue; // تجاوز هذه الدورة وانتقل للدورة التالية مباشرة
}
System.out.println(i); // هذا السطر لن يُنفذ إذا كان i زوجيًا
}
}
}
الناتج المتوقع:
طباعة الأعداد الفردية فقط من 1 إلى 10:
1
3
5
7
9
public class BreakExample {
public static void main(String[] args) {
System.out.println("البحث عن أول رقم يقبل القسمة على 7 من 1 إلى 20:");
for (int i = 1; i <= 20; i++) {
if (i % 7 == 0) { // إذا كان العدد يقبل القسمة على 7
System.out.println("تم العثور على أول رقم يقبل القسمة على 7: " + i);
break; // اخرج تمامًا من الحلقة فوراً
}
}
System.out.println("انتهى البحث.");
}
}
الناتج المتوقع:
البحث عن أول رقم يقبل القسمة على 7 من 1 إلى 20:
تم العثور على أول رقم يقبل القسمة على 7: 7
انتهى البحث.
لنُطبق ما تعلمناه في أمثلة برمجية متنوعة تعكس استخدامات الحلقات في سيناريوهات واقعية.
اكتب برنامجًا يطلب من المستخدم إدخال عدد صحيح موجب (N)، ثم يحسب ويطبع مجموع الأعداد من 1 إلى N.
import java.util.Scanner;
public class SumOfNNumbers {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n;
long sum = 0; // استخدم long لتجنب تجاوز سعة int للأعداد الكبيرة
System.out.print("أدخل عددًا صحيحًا موجبًا (N) لحساب مجموع الأعداد من 1 إلى N: ");
n = scanner.nextInt();
if (n < 1) {
System.out.println("الرجاء إدخال عدد موجب.");
} else {
for (int i = 1; i <= n; i++) {
sum += i; // اختصار لـ sum = sum + i;
}
System.out.println("مجموع الأعداد من 1 إلى " + n + " هو: " + sum);
}
scanner.close();
}
}
مثال على الإدخال والناتج:
أدخل عددًا صحيحًا موجبًا (N) لحساب مجموع الأعداد من 1 إلى N: 10
مجموع الأعداد من 1 إلى 10 هو: 55
اكتب برنامجًا يطلب من المستخدم إدخال كلمة مرور. يجب أن تكون كلمة المرور "secret123" فقط. استمر في طلب كلمة المرور حتى يُدخلها المستخدم بشكل صحيح.
import java.util.Scanner;
public class PasswordValidator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String password;
String correctPassword = "secret123";
System.out.println("برنامج التحقق من كلمة المرور.");
do {
System.out.print("الرجاء إدخال كلمة المرور: ");
password = scanner.nextLine();
if (!password.equals(correctPassword)) {
System.out.println("كلمة المرور خاطئة. يرجى المحاولة مرة أخرى.");
}
} while (!password.equals(correctPassword)); // الشرط: استمر طالما كلمة المرور غير صحيحة
System.out.println("تهانينا! لقد أدخلت كلمة المرور الصحيحة. مرحباً بك!");
scanner.close();
}
}
مثال على الإدخال والناتج:
برنامج التحقق من كلمة المرور.
الرجاء إدخال كلمة المرور: wrong
كلمة المرور خاطئة. يرجى المحاولة مرة أخرى.
الرجاء إدخال كلمة المرور: password
كلمة المرور خاطئة. يرجى المحاولة مرة أخرى.
الرجاء إدخال كلمة المرور: secret123
تهانينا! لقد أدخلت كلمة المرور الصحيحة. مرحباً بك!
اكتب برنامجًا يعرض قائمة من الخيارات للمستخدم (مثل 1: عرض، 2: إضافة، 3: حذف، 4: خروج) ويستمر في عرض القائمة وتلقي المدخلات حتى يختار المستخدم الخيار "4" (الخروج).
import java.util.Scanner;
public class MenuDrivenProgram {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int choice = 0; // تهيئة بـ 0 لضمان دخول الحلقة لأول مرة
while (choice != 4) { // استمر طالما أن المستخدم لم يختر الخروج
System.out.println("\n--- قائمة الخيارات ---");
System.out.println("1. عرض البيانات");
System.out.println("2. إضافة سجل جديد");
System.out.println("3. حذف سجل");
System.out.println("4. الخروج من البرنامج");
System.out.print("الرجاء اختيار رقم: ");
choice = scanner.nextInt(); // قراءة اختيار المستخدم
switch (choice) {
case 1:
System.out.println(">>> يتم عرض البيانات...");
break;
case 2:
System.out.println(">>> يتم إضافة سجل جديد...");
break;
case 3:
System.out.println(">>> يتم حذف سجل...");
break;
case 4:
System.out.println(">>> شكرًا لاستخدامك البرنامج. إلى اللقاء!");
break;
default:
System.out.println(">>> خيار غير صالح. يرجى اختيار رقم من 1 إلى 4.");
}
}
scanner.close();
}
}
مثال على الإدخال والناتج:
--- قائمة الخيارات ---
1. عرض البيانات
2. إضافة سجل جديد
3. حذف سجل
4. الخروج من البرنامج
الرجاء اختيار رقم: 1
>>> يتم عرض البيانات...
--- قائمة الخيارات ---
1. عرض البيانات
2. إضافة سجل جديد
3. حذف سجل
4. الخروج من البرنامج
الرجاء اختيار رقم: 5
>>> خيار غير صالح. يرجى اختيار رقم من 1 إلى 4.
--- قائمة الخيارات ---
1. عرض البيانات
2. إضافة سجل جديد
3. حذف سجل
4. الخروج من البرنامج
الرجاء اختيار رقم: 4
>>> شكرًا لاستخدامك البرنامج. إلى اللقاء!
اختبر فهمك لهذه الوحدة من خلال حل التمارين التالية:
اكتب برنامج جافا يطلب من المستخدم إدخال عدد صحيح موجب. قم بحساب العدد العاملي (Factorial) لهذا العدد واطبعه. العدد العاملي للعدد $N$ (يُرمز له بـ $N!$) هو حاصل ضرب جميع الأعداد الصحيحة الموجبة الأقل من أو تساوي $N$. على سبيل المثال، $5! = 5 \times 4 \times 3 \times 2 \times 1 = 120$.
import java.util.Scanner;
public class FactorialCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// اكتب الكود هنا لحساب العدد العاملي
scanner.close();
}
}
اكتب برنامجًا يطلب من المستخدم إدخال عدد الصفوف (مثل 5). ثم اطبع هرمًا من النجوم على الكونسول بهذا العدد من الصفوف.
مثال لهرم بـ 5 صفوف:
*
**
***
****
*****
import java.util.Scanner;
public class StarPyramid {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// اكتب الكود هنا لطباعة هرم من النجوم
scanner.close();
}
}
اكتب برنامجًا يحدد رقمًا سريًا ثابتًا (مثلاً 42). اطلب من المستخدم تخمين الرقم. استمر في طلب التخمين حتى يقوم المستخدم بتخمين الرقم الصحيح.
import java.util.Scanner;
import java.util.Random; // لتوليد رقم عشوائي إذا أردت الرقم السري متغيرًا
public class GuessTheNumber {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// int secretNumber = new Random().nextInt(100) + 1; // رقم سري عشوائي بين 1 و 100
int secretNumber = 42; // رقم سري ثابت
int guess;
int attempts = 0;
System.out.println("مرحباً بك في لعبة تخمين الرقم السري!");
System.out.println("أنا أفكر في رقم بين 1 و 100.");
// اكتب الكود هنا للعبة التخمين باستخدام حلقة while
scanner.close();
}
}
لقد اكتشفت في هذه الوحدة الحاسمة قوة ومرونة **الحلقات (Loops)** في Java، وهي أدوات لا غنى عنها لأي مبرمج يسعى لكتابة برامج فعالة ومختصرة.
for: مثالية عندما يكون عدد التكرارات معروفًا مسبقًا.while: تُستخدم عندما يكون الشرط معروفًا ولكن عدد التكرارات غير محدد مسبقًا.do-while: تضمن تنفيذ الكود مرة واحدة على الأقل قبل التحقق من الشرط، وهي مفيدة لسيناريوهات التحقق من المدخلات.break و continue التي تمنحنا مرونة أكبر للتحكم في تدفق الحلقة، سواء بالخروج منها تمامًا أو بتخطي الدورة الحالية.إن إتقان الحلقات هو خطوة أساسية نحو كتابة برامج أكثر كفاءة وتعقيدًا. تذكر أن التدريب العملي على أمثلة متنوعة هو أفضل وسيلة لإتقان استخدام الحلقات بشكل فعال. في الوحدة القادمة، سنتعمق في الدوال (Methods) وكيفية تنظيم الكود الخاص بك في كتل قابلة لإعادة الاستخدام.