العمليات الحسابية الأساسية
جافا فيها آلة حاسبة كاملة: الجمع والطرح والضرب والقسمة — بأربع علامات بسيطة.
تخيّل أن المتغيرات أرقام في ذهنك والعمليات هي العلامات الحسابية التي تعرفها من المدرسة: + للجمع، و- للطرح، و* للضرب — نعم، النجمة وليس علامة الضرب المعتادة، لأن لوحة المفاتيح لا تملك × — و/ للقسمة.
نكتب العملية ونضع ناتجها في متغير أو نطبعه مباشرة، وجافا تحسبها فورًا أثناء التنفيذ.
public class Calculate { public static void main(String[] args) { int a = 17; int b = 5; System.out.println("Sum: " + (a + b)); System.out.println("Subtraction: " + (a - b)); System.out.println("Multiplication: " + (a * b)); System.out.println("Division: " + (a / b)); double x = 17.0; System.out.println("Decimal division: " + (x / b)); System.out.println("No parentheses: " + (2 + 3 * 4)); System.out.println("With parentheses: " + ((2 + 3) * 4)); }}
انتبه لهذه الفخاخ الثلاثة
- الضرب يستخدم النجمة * والقسمة الشرطة المائلة / — لا يوجد × أو ÷ على لوحة المفاتيح.
- الأولوية كما في الرياضيات: الضرب والقسمة قبل الجمع والطرح — لذلك 2 + 3 * 4 تعطي 14 وليس 20.
- الأقواس ( ) لها أعلى أولوية وتغيّر النتيجة تمامًا كما في الرياضيات.
مثال واقعي: متوسط الدرجات
ثلاث درجات في المتغيرات — لاحظ أن كل العمليات هنا على أعداد صحيحة، فماذا يحدث للمتوسط؟
public class GradesAverage { public static void main(String[] args) { int sum = 20 + 15 + 18; int count = 3; int average = sum / count; System.out.println("Sum: " + sum); System.out.println("Average: " + average); }}
int a = 17; double x = 17.0; System.out.println(a / 5); System.out.println(x / 5);
باقي القسمة %
رمز صغير غير مألوف في الرياضيات، لكنه من أقوى أدوات المبرمج — اسأل أي طالب وزّع 23 طالبًا على مجموعات.
تخيّل أن عندك 23 طالبًا وتريد تكوين مجموعات من 5: تكوّن 4 مجموعات كاملة، ويتبقى 3 طلاب. العملية % تعطيك الباقي فقط: 23 % 5 النتيجة 3. ويقابلها / التي تعطي عدد المجموعات الكاملة: 23 / 5 النتيجة 4.
اقرأ السطرين معًا: «القسمة تقول كم مجموعة كاملة تكوّن، والباقي يقول كم يتبقى خارجها».
اكشف الإجابة
17 % 5 تساوي 2، و17 / 5 تساوي 3: تتكوّن 3 مجموعات كاملة (3 × 5 = 15) ويبقى نقطتان (17 - 15 = 2).public class Remainder { public static void main(String[] args) { System.out.println("10 % 3 = " + (10 % 3)); System.out.println("17 % 5 = " + (17 % 5)); System.out.println("20 % 10 = " + (20 % 10)); int students = 23; int groupSize = 5; System.out.println("Complete groups: " + (students / groupSize)); System.out.println("Students left: " + (students % groupSize)); System.out.println("8 % 2 = " + (8 % 2) + " (even)"); System.out.println("7 % 2 = " + (7 % 2) + " (odd)"); }}
أين نستخدم % في البرمجة؟
- الفردي والزوجي: أي عدد n % 2 ناتجه 0 فهو زوجي وإن كان 1 فهو فردي.
- التوزيع على مجموعات: معرفة المتبقي بعد توزيع العناصر كما في المثال.
- استخراج آخر رقم: n % 10 تعطيك الآحاد من أي عدد.
- الأمر الدوري: اختيار كل ثالث عنصر مثلًا — عندما يكون n % 3 يساوي 0.
جدول أولوية العمليات — من يُنفَّذ أولًا؟
عندما تجتمع أكثر من عملية في سطر واحد، جافا لا تنفّذها عشوائيًا — بل تتبع جدول أولويات ثابت تحفظه الرياضيات:
| الأولوية | العملية | المعنى |
|---|---|---|
| ١ — الأعلى | ( ) | ما بداخل الأقواس يُحسب دائمًا أولًا، مهما كان حوله |
| ٢ | * / % | الضرب والقسمة وباقي القسمة — متساوية فيما بينها، تُنفَّذ من اليسار إلى اليمين |
| ٣ | + - | الجمع والطرح — تأتي بعد الضرب والقسمة |
| ٤ — الأخيرة | = | التخزين في المتغير يحدث بعد حساب الطرف الأيمن كاملًا |
لاحظ الفرق بين السطرين في هذا البرنامج — نفس الأرقام ونفس العمليات، لكن الأقواس غيّرت كل شيء:
public class Precedence { public static void main(String[] args) { int a = 2 + 3 * 4; // 14: multiplication first int b = (2 + 3) * 4; // 20: parentheses first System.out.println(a); System.out.println(b); }}
معاملا الزيادة والنقصان ++ و --
أسطر مثل count = count + 1 تتكرر كثيرًا في البرامج — فاختصرتها جافا إلى رمزين فقط.
في الألعاب، كلما جمعت نقطة تُحسب هكذا: score = score + 1;. بما أن هذا السطر شائع جدًا، وفّرت جافا اختصارًا: score++; وتعني حرفيًا «أضف 1 على score». ويقابلها score--; لتنقيص 1.
للمعاملين صورتان: بعد المتغير x++ وقبله ++x — والفرق بينهما يظهر فقط عند وضعهما داخل تعبير أكبر (إسناد أو println…)، كما سنرى في المثال.
توقّع: في y = x++ هل تأخذ y القيمة قبل الزيادة أم بعدها؟
public class Counter { public static void main(String[] args) { int score = 10; score++; // same as: score = score + 1; System.out.println("After increment: " + score); score++; System.out.println("After second increment: " + score); score--; System.out.println("After decrement: " + score); int level = 1; ++level; System.out.println("New level: " + level); int box = 7; int taken = box++; System.out.println("We took the old value: " + taken); System.out.println("The box is now: " + box); }}
اقرأ المثال سطرًا سطرًا
- score++ تضيف 1 كل مرة — لاحظ القيمة تتغير 10 ثم 11 ثم 12.
- score-- تُنقص 1 فترجع 12 إلى 11.
- الصورتان ++x وx++ متطابقتان عندما تكونان أمرًا مستقلًا بذاته.
- الفرق يظهر فقط داخل تعبير (إسناد أو println…): taken = box++; تضع القيمة القديمة 7 في taken ثم ترفع box إلى 8.
public class PostfixTrap { public static void main(String[] args) { int x = 5; x = x++; // trap: the increment is lost! System.out.println("After x = x++ : " + x); int y = 5; y++; // this is the correct form System.out.println("After y++ : " + y); }}
int x = 5; x++; x++; x--; System.out.println(x);
تحدي: أين الخطأ؟
ثلاثة برامج عن العمليات الحسابية — البرنامج يعمل لكن ناتجه خاطئ أو يرفض التشغيل. اقرأ الكود بتمعّن وتتبّع الناتج سطرًا سطرًا، ثم اضغط على السطر المخالف.
المقطع ١: المتغير double لكن البرنامج يطبع 2.0 بدل 2.5. أين الخطأ؟
تتبّع القسمة نفسها قبل التخزين: ما نوع الطرفين اللذين تقسم بينهما؟ وراجع فخ «القسمة الصحيحة» في الدرس 2·1.
المقطع ٢: نريد متوسط عددين لكن الناتج خاطئ. أين الخطأ؟
احسب ماذا ينفذ أولًا وفق جدول الأولويات، ثم قارن بما نريد فعلًا. الأقواس تملي الترتيب.
المقطع ٣: نريد عدد الطلاب المتبقين خارج المجموعات لكن الناتج 4. أين الخطأ؟
«كم مجموعة كاملة نكوّن؟» و«كم يتبقى خارجها؟» — كل سؤال له عملية مختلفة في الدرس 2·2.
تمارين الوحدة ٢
تمارين على العمليات الحسابية (الجمع والطرح والضرب والقسمة، باقي القسمة، والزيادة والنقصان). كل تمرين أمامه كود ناقص: اضغط «✎ تعديل»، اكتب الكود المطلوب مكان التعليقات، اضغط «✔ حفظ» ثم «▶ تشغيل» — وقارن نتيجتك بالهدف المكتوب أسفل كل تمرين.
سعر القطعة الواحدة 7 ريالات، والكمية المطلوبة 6 قطع. أكمل البرنامج بسطر واحد: عرّف متغير total يحسب الإجمالي (السعر مضروبًا في الكمية).
public class Invoice { public static void main(String[] args) { int price = 7; int quantity = 6; // define total = price * quantity System.out.println("Total: " + total + " SAR"); }}
Total: 42 SAR
درجات الطالب أربع: 90 و85 و78 و92. أكمل البرنامج: عرّف متغير avg من نوع double يحسب معدل الدرجات الأربع — واحذر فخ القسمة الصحيحة الذي تعلمته في الدرس 2·1!
public class Average { public static void main(String[] args) { int math = 90; int science = 85; int english = 78; int arabic = 92; // define avg = sum of grades / count (as a double) System.out.println("GPA: " + avg); }}
GPA: 86.25
عندك 23 طالبًا تريد تقسيمهم إلى مجموعات متساوية كل مجموعة فيها 5 طلاب. أكمل المتغيرين الناقصين: groups يخزن عدد المجموعات الكاملة، وleftover يخزن عدد الطلاب المتبقين.
public class Groups { public static void main(String[] args) { int students = 23; int groupSize = 5; // full groups count in variable groups // leftover students in variable leftover System.out.println("Groups: " + groups + " leftover: " + leftover); }}
Groups: 4 leftover: 3
لعبة بدأت بنقاط 10. في الجزء الأول استخدم ++ مرتين ثم -- مرة (ثلاثة أسطر) على المتغير score. في الجزء الثاني اطبع score مرة، ثم اطبع score++ داخل println مباشرة، ثم اطبع score مرة أخيرة — راقب كيف تُطبع القيمة القديمة قبل الزيادة!
public class ScoreBoard { public static void main(String[] args) { int score = 10; // 1) ++ twice then -- once (three lines) // 2) print score, then print score++, then print score }}
11 11 12