الوحدة 6: العوامل (Operators) والحلقات (Loops) في Java

فهم كيفية تنفيذ العمليات وتكرار التعليمات بكفاءة

المدة: أسبوعان 6 ساعات نظرية 6 ساعات عملية

المقدمة والأهداف التعليمية

بعد أن اكتسبنا المهارات الأساسية في التعامل مع البيانات وإدخالها وإخراجها، حان الوقت لنتعلم كيف نجعل برامجنا أكثر ذكاءً وكفاءة. في هذه الوحدة، سنستكشف مفهومين أساسيين في البرمجة: **العوامل (Operators)** و**الحلقات (Loops)**. العوامل تمكننا من إجراء عمليات متنوعة على البيانات، بينما تسمح لنا الحلقات بتكرار تنفيذ أجزاء من الكود بكفاءة عالية.

فهم العوامل والحلقات ضروري لبناء أي برنامج معقد أو تفاعلي، حيث أنها تُعد اللبنات الأساسية للمنطق والتحكم في سير البرنامج.

الأهداف:

بنهاية هذه الوحدة، ستكون قادرًا على:

  • فهم مفهوم العوامل في Java وأنواعها المختلفة.
  • تطبيق العوامل الحسابية، عوامل المقارنة، والعوامل المنطقية في برامجك.
  • التعرف على عوامل البتات وعوامل الإسناد واستخداماتها.
  • فهم مفهوم الحلقات وأهميتها في تكرار الكود.
  • التعرف على الأنواع الرئيسية للحلقات في Java (`for`, `while`, `do-while`).
  • فهم واستخدام جمل التحكم `break` و `continue` مع الحلقات.
---

أولًا: العوامل (Operators) في جافا

1. مفهوم العوامل

**العوامل (Operators)** في Java هي رموز خاصة نستخدمها لتنفيذ عمليات معينة على القيم أو المتغيرات. تُستخدم هذه العوامل لمعالجة البيانات وإنشاء التعبيرات والتحكم في تدفق البرنامج.

مثلاً: + للجمع، - للطرح، * للضرب، وغيرها.

يمكن تقسيم العوامل في جافا إلى مجموعات رئيسية بناءً على نوع العملية التي تقوم بها:

  • العوامل الحسابية (Arithmetic Operators).
  • عوامل المقارنة (Comparison Operators).
  • العوامل المنطقية (Logical Operators).
  • عوامل التعامل مع البتات (Bitwise Operators).
  • عوامل الإسناد (Assignment Operators).

إضافة إلى ذلك، توجد عوامل أخرى مهمة سنتعرف عليها لاحقًا مثل العامل الشرطي ?: والعامل instanceof.

---

2. العوامل الحسابية (Arithmetic Operators)

تُستخدم هذه العوامل لتنفيذ العمليات الرياضية الأساسية.

فيما يلي أشهرها مع أمثلة:

اسم العامل الرمز مثال الشرح
الجمع `+` `a + b` يجمع قيمة `a` مع `b`.
الطرح `-` `a - b` يطرح `b` من `a`.
الضرب `*` `a * b` يضرب القيمتين.
القسمة `/` `a / b` يقسم `a` على `b`. (إذا كانا عددين صحيحين، فالناتج سيكون عددًا صحيحًا)
باقي القسمة `%` `a % b` يعطي الباقي عند قسمة `a` على `b`.
الزيادة (بعدية) `a++` `a++` يزيد قيمة `a` بمقدار 1 بعد استخدام قيمتها الحالية في التعبير.
الزيادة (قبلية) `++a` `++a` يزيد قيمة `a` بمقدار 1 قبل استخدام قيمتها في التعبير.
النقصان (بعدية) `a--` `a--` ينقص قيمة `a` بمقدار 1 بعد استخدام قيمتها الحالية في التعبير.
النقصان (قبلية) `--a` `--a` ينقص قيمة `a` بمقدار 1 قبل استخدام قيمتها في التعبير.
الجمع الأحادي `+a` `+a` لا يغيّر القيمة لكن يُظهر الإشارة الموجبة (نادراً ما يستخدم).
الطرح الأحادي `-a` `-a` يغيّر إشارة القيمة إلى سالبة.
مثال:
public class ArithmeticOperatorsExample {
    public static void main(String[] args) {
        int a = 10;
        int b = 3;

        System.out.println("a + b = " + (a + b)); // Output: 13
        System.out.println("a - b = " + (a - b)); // Output: 7
        System.out.println("a * b = " + (a * b)); // Output: 30
        System.out.println("a / b = " + (a / b)); // Output: 3 (integer division)
        System.out.println("a % b = " + (a % b)); // Output: 1

        int x = 5;
        System.out.println("x++ = " + (x++)); // Output: 5 (x becomes 6)
        System.out.println("x is now: " + x); // Output: 6
        
        int y = 5;
        System.out.println("++y = " + (++y)); // Output: 6 (y becomes 6)
        System.out.println("y is now: " + y); // Output: 6
    }
}
---

3. عوامل المقارنة (Comparison Operators)

تُستخدم هذه العوامل للمقارنة بين القيم، ويكون ناتجها دائمًا قيمة منطقية (true أو false). تُستخدم بشكل شائع في الجمل الشرطية والحلقات.

اسم العامل الرمز مثال الشرح
يساوي `==` `(a == b)` صحيح إذا كانت القيمتان متساويتين.
لا يساوي `!=` `(a != b)` صحيح إذا كانت القيمتان مختلفتين.
أكبر من `>` `(a > b)` صحيح إذا كانت `a` أكبر من `b`.
أصغر من `<` `(a < b)` صحيح إذا كانت `a` أصغر من `b`.
أكبر أو يساوي `>=` `(a >= b)` صحيح إذا كانت `a` أكبر أو تساوي `b`.
أصغر أو يساوي `<=` `(a <= b)` صحيح إذا كانت `a` أصغر أو تساوي `b`.
مثال:
public class ComparisonOperatorsExample {
    public static void main(String[] args) {
        int x = 10;
        int y = 5;

        System.out.println("x == y: " + (x == y)); // Output: false
        System.out.println("x != y: " + (x != y)); // Output: true
        System.out.println("x > y: " + (x > y));   // Output: true
        System.out.println("x < y: " + (x < y));   // Output: false
        System.out.println("x >= y: " + (x >= y)); // Output: true
        System.out.println("x <= y: " + (x <= y)); // Output: false
    }
}
---

4. العوامل المنطقية (Logical Operators)

تُستخدم هذه العوامل لدمج أكثر من شرط منطقي أو لعكس قيمة شرط. ناتجها دائمًا قيمة منطقية (true أو false).

اسم العامل الرمز مثال الشرح
AND (منطقي) `&&` `(a && b)` صحيح فقط إذا كان الشرطان (أو التعبيران المنطقيان) صحيحين معًا.
OR (منطقي) `||` `(a || b)` صحيح إذا كان أحد الشرطين (أو كلاهما) صحيحًا. خاطئ فقط إذا كان كلاهما خاطئًا.
NOT (منطقي) `!` `!a` يعكس القيمة المنطقية (إذا كانت `true` تصبح `false` والعكس).
مثال:
public class LogicalOperatorsExample {
    public static void main(String[] args) {
        boolean isStudent = true;
        boolean hasGoodGrades = false;
        int age = 20;

        // AND (&&)
        System.out.println("isStudent && hasGoodGrades: " + (isStudent && hasGoodGrades)); // Output: false
        
        // OR (||)
        System.out.println("isStudent || hasGoodGrades: " + (isStudent || hasGoodGrades)); // Output: true
        
        // NOT (!)
        System.out.println("!isStudent: " + (!isStudent)); // Output: false

        // دمج الشروط
        System.out.println("(age > 18 && isStudent): " + (age > 18 && isStudent)); // Output: true
    }
}
---

5. العوامل على البتات (Bitwise Operators)

تتعامل هذه العوامل مع الأعداد على شكل بتات ثنائية (0 و 1)، وتُستخدم عادة في البرمجة المنخفضة المستوى، عند التعامل مع الذاكرة، أو في تشفير البيانات. تتطلب فهماً جيداً لكيفية تمثيل الأرقام في النظام الثنائي.

اسم العامل الرمز مثال الشرح
Bitwise AND `&` `a & b` يُرجع `1` إذا كان كلا البتين المقابلين `1`، وإلا `0`.
Bitwise OR `|` `a | b` يُرجع `1` إذا كان أي من البتين المقابلين `1`، وإلا `0`.
Bitwise XOR `^` `a ^ b` يُرجع `1` إذا كان البتان المقابلان مختلفين، وإلا `0`.
Bitwise NOT (Complement) `~` `~a` يقلب جميع البتات (0 تصبح 1 و 1 تصبح 0).
إزاحة لليسار (Signed Left Shift) `<<` `a << 2` يُزح البتات لليسار بمقدار معين (هنا 2)، ويضيف أصفارًا من اليمين. يعادل الضرب في قوة 2.
إزاحة لليمين (Signed Right Shift) `>>` `a >> 2` يُزح البتات لليمين بمقدار معين (هنا 2)، ويحتفظ بإشارة الرقم (يملأ من اليسار بإشارة البت الأخير). يعادل القسمة على قوة 2.
إزاحة لليمين مع ملء بالأصفار (Unsigned Right Shift) `>>>` `a >>> 2` يُزح البتات لليمين ويملأ الفراغ من اليسار بأصفار، بغض النظر عن إشارة الرقم.
مثال:
public class BitwiseOperatorsExample {
    public static void main(String[] args) {
        int a = 5;  // Binary: 0101
        int b = 3;  // Binary: 0011

        System.out.println("a & b = " + (a & b));   // Output: 1 (Binary: 0001)
        System.out.println("a | b = " + (a | b));   // Output: 7 (Binary: 0111)
        System.out.println("a ^ b = " + (a ^ b));   // Output: 6 (Binary: 0110)
        System.out.println("~a = " + (~a));         // Output: -6 (Binary: 1010, two's complement)
        System.out.println("a << 1 = " + (a << 1)); // Output: 10 (Binary: 1010)
        System.out.println("a >> 1 = " + (a >> 1)); // Output: 2 (Binary: 0010)

        int negativeNum = -10; // Binary (example): 1111...11110110 (using two's complement)
        System.out.println("negativeNum >> 1 = " + (negativeNum >> 1));  // Output: -5 (sign preserved)
        System.out.println("negativeNum >>> 1 = " + (negativeNum >>> 1)); // Output: 2147483643 (fills with zero, changes sign for negative numbers)
    }
}
---

6. عوامل الإسناد (Assignment Operators)

تُستخدم لإعطاء قيم للمتغيرات. بعضها يجمع بين عملية حسابية والإسناد، مما يجعل الكود أكثر اختصاراً ووضوحاً.

اسم العامل الرمز مثال الشرح
إسناد أساسي `=` `a = b` يعين قيمة `b` إلى `a`.
جمع مع إسناد `+=` `a += b` يكافئ `a = a + b`. يضيف `b` إلى `a` ثم يخزن الناتج في `a`.
طرح مع إسناد `-=` `a -= b` يكافئ `a = a - b`. يطرح `b` من `a` ويخزن الناتج.
ضرب مع إسناد `*=` `a *= b` يكافئ `a = a * b`. يضرب القيمتين ويخزن الناتج.
قسمة مع إسناد `/=` `a /= b` يكافئ `a = a / b`. يقسم `a` على `b` ويخزن الناتج.
باقي القسمة مع إسناد `%=` `a %= b` يكافئ `a = a % b`. يخزن باقي القسمة في `a`.
إزاحة يسار مع إسناد `<<=` `a <<= 2` يكافئ `a = a << 2`. يزح البتات لليسار ويخزن الناتج.
إزاحة يمين مع إسناد `>>=` `a >>= 2` يكافئ `a = a >> 2`. يزح البتات لليمين ويخزن الناتج.
AND مع إسناد `&=` `a &= b` يكافئ `a = a & b`. يحسب Bitwise AND ويخزن الناتج.
XOR مع إسناد `^=` `a ^= b` يكافئ `a = a ^ b`. يحسب Bitwise XOR ويخزن الناتج.
OR مع إسناد `|=` `a |= b` يكافئ `a = a | b`. يحسب Bitwise OR ويخزن الناتج.
مثال:
public class AssignmentOperatorsExample {
    public static void main(String[] args) {
        int x = 10;
        int y = 5;

        x += y; // x = x + y;  x becomes 15
        System.out.println("x after +=: " + x); // Output: 15

        x -= y; // x = x - y;  x becomes 10
        System.out.println("x after -=: " + x); // Output: 10

        x *= y; // x = x * y;  x becomes 50
        System.out.println("x after *=: " + x); // Output: 50

        x /= y; // x = x / y;  x becomes 10
        System.out.println("x after /=: " + x); // Output: 10
    }
}
---

7. عوامل أخرى مهمة

العامل الشرطي (Ternary Operator `?:`)

يُستخدم كبديل مختصر لجملة `if-else` لتعيين قيمة لمتغير بناءً على شرط واحد.

الصيغة:

النتيجة = (الشرط) ? القيمة_إذا_صح : القيمة_إذا_خطأ;
مثال:
public class TernaryOperatorExample {
    public static void main(String[] args) {
        int score = 75;
        String result = (score >= 60) ? "ناجح" : "راسب";
        System.out.println("النتيجة: " + result); // Output: ناجح

        int num = 10;
        String type = (num % 2 == 0) ? "زوجي" : "فردي";
        System.out.println("الرقم " + num + " هو: " + type); // Output: الرقم 10 هو: زوجي
    }
}

العامل `instanceof`

يُستخدم للتحقق مما إذا كان الكائن (Object) ينتمي إلى كلاس معين أو واجهة (interface) أم لا. يُرجع true إذا كان الكائن من النوع المحدد، و false بخلاف ذلك.

مثال:
public class InstanceofExample {
    public static void main(String[] args) {
        String myString = "Hello Java";
        Integer myInteger = 123;

        System.out.println("myString instanceof String: " + (myString instanceof String)); // Output: true
        System.out.println("myInteger instanceof Integer: " + (myInteger instanceof Integer)); // Output: true
        System.out.println("myInteger instanceof Object: " + (myInteger instanceof Object)); // Output: true (Integer هو كائن من Object)
        System.out.println("myString instanceof Integer: " + (myString instanceof Integer)); // Output: false
    }
}
---

ثانيًا: الحلقات (Loops) في Java

مفهوم الحلقات

بعد فهم العوامل التي تساعدنا على كتابة الشروط والتعبيرات المنطقية، ننتقل إلى **الحلقات (Loops)**، وهي آلية أساسية في البرمجة تُستخدم لتكرار تنفيذ مجموعة من التعليمات البرمجية أكثر من مرة.

أهمية الحلقات تكمن في أنها تغنيك عن كتابة نفس الكود مرارًا وتكرارًا، مما يجعل الكود أقصر، أكثر قابلية للصيانة، وأقل عرضة للأخطاء. على سبيل المثال: إذا أردت طباعة الأرقام من 1 إلى 100، يمكنك استخدام حلقة بدلًا من كتابة 100 سطر كود منفصل.

طريقة تنفيذ الأوامر والحلقات في الذاكرة:

الأوامر في العادة تتنفذ بتسلسل وراء بعضها. ولكن الحلقات تجعل سهم تنفيذ الأوامر يقف عندها، فيقوم بتنفيذ الأوامر التي بداخلها عدة مرات، و بعد أن يخرج من الحلقة يعود و يكمل تنفيذ باقي الأوامر الموجودة بعدها.

عندما تتنفذ الحلقة، فإن الأوامر الموضوعة فيها تنفذ بشكل منفصل عن باقي الأوامر الموجودة في البرنامج. أي يمكنك اعتبار أن جميع أوامر الحلقة توضع في مكان خاص في الذاكرة، هذا المكان يسمى **`scope` (نطاق)**. بعد أن تتنفذ جميع أوامر الحلقة في هذا الـ `scope`، يتم مسح الـ `scope` كلياً من الذاكرة، و هذه العملية تسمى **`Destroy` (إتلاف)**.

---

أنواع الحلقات في Java

توفر Java ثلاثة أنواع رئيسية من الحلقات، كل منها مناسب لحالات استخدام معينة:

اسم الحلقة دواعي الإستخدام
For Loop تستخدم الحلقة for في حال كان **عدد المرات التي سيعاد فيها تنفيذ الكود معروفاً** مسبقاً (مثلاً: كرر 10 مرات، اطبع الأرقام من 1 إلى 50).
While Loop يفضل استخدام الحلقة while في حال كان **عدد المرات التي سيعاد فيها تنفيذ الكود غير معروف** مسبقاً، وتعتمد على تحقق شرط معين للاستمرار في التكرار (مثلاً: كرر طالما المستخدم لم يضغط على "خروج").
Do-While Loop تُشبه حلقة while، حيث يفضل استخدامها في حال كان عدد المرات التي سيعاد فيها تنفيذ الكود غير معروف، ولكنها تضمن أن يتم **تنفيذ الكود داخل الحلقة مرة واحدة على الأقل** قبل التحقق من الشرط.
---

جمل التحكم مع الحلقات (Control Statements)

نستخدم جمل التحكم Control Statements للتحكم في سير تنفيذ الحلقات، وتُستخدم أيضًا مع جملة الشرط switch (التي سنتعرف عليها لاحقًا).

جملة التحكم تعريفها
Break Statement تُستخدم في الحلقات وفي الجملة switch. بمجرد أن تُنفذ الجملة break، فإنها توقف الـ `scope` (النطاق) بأكمله وتخرج منه وتمسحه من الذاكرة، ثم ينتقل تنفيذ البرنامج إلى الكود الذي يلي الحلقة أو جملة `switch`.
Continue Statement تُستخدم مع الحلقات فقط. نستخدمها لتجاوز تنفيذ جزء معين من الكود داخل التكرار الحالي للحلقة والانتقال مباشرة إلى التكرار التالي. إذاً، نستخدمها لتجاوز جزء من كود الـ `scope` الحالي فقط، دون الخروج من الحلقة كليًا.
ملاحظة:

سنشرح الجملة break بالتفصيل مع الجملة switch في الوحدة القادمة، وسنقدم أمثلة عملية لكل من `break` و `continue` عند شرح الحلقات بأنواعها.

---

تمارين وتحديات

هذه التمارين ستساعدك على تطبيق المفاهيم التي تعلمتها في هذه الوحدة:

1. تمرين: استخدام العوامل الحسابية

اكتب برنامج جافا يطلب من المستخدم إدخال طول وعرض مستطيل (أعداد عشرية). قم بحساب مساحة ومحيط المستطيل باستخدام العوامل الحسابية المناسبة، ثم اطبع النتائج على الكونسول. تأكد من استخدام `Scanner` ومعالجة الأخطاء المحتملة.

import java.util.Scanner;
import java.util.InputMismatchException;

public class RectangleCalculator {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // اكتب الكود هنا
        input.close();
    }
}

2. تمرين: تطبيق عوامل المقارنة والمنطقية

اكتب برنامج يطلب من المستخدم إدخال عمره ودرجة حرارته. بناءً على هذه المدخلات، اطبع رسالة على الكونسول:

  • "شخص بالغ وفي حالة جيدة" إذا كان العمر أكبر من أو يساوي 18 ودرجة الحرارة بين 36 و 37.5 (شاملة).
  • "طفل أو شاب" إذا كان العمر أقل من 18.
  • "تحقق من درجة الحرارة!" في أي حالة أخرى.
استخدم عوامل المقارنة والعوامل المنطقية (`&&`، `||`).

import java.util.Scanner;
import java.util.InputMismatchException;

public class HealthCheck {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // اكتب الكود هنا
        input.close();
    }
}

3. تمرين تحدي: استخدام العامل الشرطي

اكتب برنامج يطلب من المستخدم إدخال رقم. استخدم العامل الشرطي (`?:`) لتحديد ما إذا كان الرقم زوجياً أم فردياً، ثم اطبع النتيجة. (تلميح: استخدم عامل باقي القسمة `%`).

import java.util.Scanner;
import java.util.InputMismatchException;

public class EvenOddChecker {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // اكتب الكود هنا
        input.close();
    }
}
---

المراجع

  • موقع Oracle Java Documentation.
  • "Java: A Beginner's Guide" – Herbert Schildt.
  • "Head First Java" – Kathy Sierra, Bert Bates.
---

ملخص الوحدة

في هذه الوحدة، استكشفنا عالم **العوامل (Operators)** في Java، حيث تعلمنا كيفية استخدامها لإجراء عمليات حسابية ومنطقية ومعالجة البتات وإسناد القيم. كما تعرفنا على العوامل الشرطية و instanceof التي تزيد من مرونة الكود.

بعد ذلك، انتقلنا إلى فهم **الحلقات (Loops)**، وهي أدوات قوية لتكرار التعليمات البرمجية بكفاءة، مما يوفر الجهد ويحسن من قراءة الكود وصيانته. تعرفنا على الأنواع الرئيسية للحلقات: `for`، `while`، و `do-while`، بالإضافة إلى جمل التحكم `break` و `continue` التي تمنحنا تحكماً دقيقاً في سير التكرار.

هذه المفاهيم تُعد أساساً جوهرياً لأي مبرمج، فهي تمكنك من بناء منطق برنامجك والتحكم في تدفقه. في الوحدة القادمة، سنتعمق في **جمل التحكم الشرطية (If-Else, Switch)**، والتي ستسمح لبرامجك باتخاذ قرارات معقدة بناءً على الشروط، مما يزيد من ذكاء برامجك وقدرتها على الاستجابة لسيناريوهات مختلفة.