كيف تجعل برامجك تتخذ القرارات وتستجيب بذكاء
بعد أن تعلمنا في الوحدات السابقة كيفية التعامل مع البيانات والمتغيرات، وكيفية استخدام العوامل لإجراء العمليات الحسابية والمنطقية، حان الوقت لننتقل إلى مستوى متقدم يجعل برامجنا أكثر تفاعلاً وذكاءً. في هذه الوحدة، سنكتشف **جمل التحكم الشرطية (Conditional Control Statements)**، وهي اللبنة الأساسية لجعل برامجك تتخذ القرارات وتغير سلوكها بناءً على شروط معينة.
سنركز على فهم عميق لجملتي `if-else` بجميع أشكالها، وكيفية استخدام جملة `switch` كبديل أنيق في بعض السيناريوهات. هذه الأدوات ضرورية لبناء أي منطق معقد في تطبيقاتك.
بنهاية هذه الوحدة، ستكون قادرًا على:
if الأساسية لتنفيذ كود مشروط.if-else لتوفير مسار بديل عند عدم تحقق الشرط.else-if للتعامل مع شروط متعددة ومتتالية.&&، ||، !).switch كبديل فعال لـ if-else if المتعددة في حالات معينة.break في جملة switch.if-else ومتى تستخدم switch.تُعد **الشروط (Conditions)** هي الأساس الذي يجعل البرامج "ذكية" وقادرة على اتخاذ القرارات. بدون الشروط، سيكون البرنامج مجرد سلسلة أوامر ثابتة تُنفذ دون أي اعتبار لمدخلات المستخدم أو التغيرات التي تحدث أثناء تشغيل البرنامج. الشروط تسمح للبرنامج بأن يسلك مسارًا مختلفًا أو ينفذ مجموعة معينة من التعليمات بناءً على صحة تعبير منطقي.
على سبيل المثال: تخيل أنك تصمم برنامجًا يحدد ما إذا كان الطالب ناجحًا أو راسبًا. هنا تحتاج إلى شرط:
بهذا الأسلوب، تسمح الشروط للبرنامج أن يتفرع إلى مسارات تنفيذ مختلفة حسب القيم والمتغيرات، مما يمنح البرامج مرونة وقدرة على الاستجابة لسيناريوهات متعددة.
جمل `if` و `else` هي الأكثر استخدامًا للتحكم في تدفق البرنامج بناءً على الشروط.
الجملة `if` هي أبسط أشكال الجمل الشرطية. تنفذ مجموعة من التعليمات إذا كان الشرط صحيحًا (`true`).
الصيغة العامة:
if (condition) {
// الكود الذي سينفذ إذا كان الشرط صحيحًا (true)
}
public class SimpleIfExample {
public static void main(String[] args) {
int age = 20;
if (age >= 18) {
System.out.println("يمكنك الدخول إلى الموقع.");
}
System.out.println("انتهى البرنامج.");
}
}
الشرح: هنا، إذا كانت قيمة `age` أكبر من أو تساوي 18، سيتم طباعة رسالة "يمكنك الدخول إلى الموقع.". إذا كانت `age` أقل من 18 (مثلاً 16)، فلن يتم طباعة هذه الرسالة وسينتقل البرنامج مباشرة إلى "انتهى البرنامج.".
تُستخدم جملة `if-else` عندما نريد توفير مسار بديل لتنفيذ الكود في حالة عدم تحقق الشرط الأساسي. فإذا كان الشرط في `if` صحيحًا، يُنفذ الكود داخل `if`، وإلا (أي إذا كان الشرط خاطئًا)، يُنفذ الكود داخل `else`.
الصيغة العامة:
if (condition) {
// الكود الذي سينفذ إذا كان الشرط صحيحًا (true)
} else {
// الكود الذي سينفذ إذا كان الشرط خاطئًا (false)
}
public class IfElseExample {
public static void main(String[] args) {
int grade = 45;
if (grade >= 50) {
System.out.println("ناجح");
} else {
System.out.println("راسب");
}
}
}
الشرح: في هذا المثال، بما أن `grade` (45) ليست أكبر من أو تساوي 50، فالشرط خاطئ، وبالتالي سيتم تنفيذ الكود داخل كتلة `else` وستظهر رسالة "راسب".
عندما نحتاج إلى التحقق من أكثر من شرط واحد بطريقة متسلسلة، يمكننا استخدام جمل `else-if`. يتم فحص الشروط بالترتيب، وبمجرد أن يصبح أحد الشروط صحيحًا، يتم تنفيذ كوده وتتجاهل بقية الشروط الأخرى.
الصيغة العامة:
if (condition1) {
// الكود إذا كان الشرط الأول صحيحًا
} else if (condition2) {
// الكود إذا كان الشرط الثاني صحيحًا (فقط إذا كان الأول خاطئًا)
} else if (condition3) {
// الكود إذا كان الشرط الثالث صحيحًا (فقط إذا كان الأول والثاني خاطئين)
} else {
// الكود إذا لم يتحقق أي من الشروط السابقة
}
public class ElseIfExample {
public static void main(String[] args) {
int score = 85;
if (score >= 90) {
System.out.println("ممتاز");
} else if (score >= 75) {
System.out.println("جيد جدًا");
} else if (score >= 50) {
System.out.println("ناجح");
} else {
System.out.println("راسب");
}
}
}
الشرح: في هذا المثال، `score` هي 85. الشرط الأول (`score >= 90`) خاطئ. الشرط الثاني (`score >= 75`) صحيح، لذا سيتم طباعة "جيد جدًا" وسيتوقف فحص باقي الشروط.
يمكننا دمج عدة شروط بسيطة لإنشاء شروط أكثر تعقيدًا باستخدام **العوامل المنطقية (Logical Operators)** التي تعرفنا عليها في الوحدة السادسة.
&& (AND): يُرجع true فقط إذا كان **جميع** الشروط المدمجة صحيحة.|| (OR): يُرجع true إذا كان **أي واحد** من الشروط المدمجة صحيحًا (أو كلاهما).! (NOT): يعكس القيمة المنطقية للشرط (إذا كان true يصبح false والعكس).public class CompoundConditionExample {
public static void main(String[] args) {
int age = 22;
boolean hasID = true;
boolean hasTicket = true;
// استخدام && : يجب أن يكون العمر >= 18 ولديه بطاقة هوية
if (age >= 18 && hasID) {
System.out.println("يمكنك الدخول إلى الحدث.");
} else {
System.out.println("لا يمكنك الدخول إلى الحدث.");
}
System.out.println("---");
// استخدام || : يجب أن يكون لديه بطاقة هوية أو تذكرة
if (hasID || hasTicket) {
System.out.println("يمكنك الدخول (لديك إما هوية أو تذكرة).");
} else {
System.out.println("لا يمكنك الدخول (لا هوية ولا تذكرة).");
}
System.out.println("---");
// استخدام ! : عكس الشرط
boolean isLoggedIn = false;
if (!isLoggedIn) {
System.out.println("أنت غير مسجل الدخول، يرجى تسجيل الدخول أولاً.");
} else {
System.out.println("أنت مسجل الدخول.");
}
}
}
الشروط المتداخلة تعني وضع جملة `if` (أو `if-else`) داخل كتلة `if` أو `else` أخرى. تُستخدم هذه الطريقة عندما تحتاج إلى فحص شروط فرعية بعد تحقق شرط رئيسي.
public class NestedIfExample {
public static void main(String[] args) {
int age = 20;
boolean isStudent = true;
boolean hasDiscountCoupon = false;
if (age >= 18) { // الشرط الرئيسي: هل هو بالغ؟
System.out.println("الدخول مسموح.");
if (isStudent) { // الشرط الفرعي 1: هل هو طالب؟
System.out.println("خصم للطلاب متاح.");
if (hasDiscountCoupon) { // الشرط الفرعي 2: هل لديه قسيمة خصم إضافية؟
System.out.println("مبروك! لديك خصم إضافي.");
}
} else {
System.out.println("الدخول مسموح بدون خصم.");
}
} else {
System.out.println("لا يمكنك الدخول (أقل من 18 عامًا).");
}
}
}
الشرح: يُفحص العمر أولاً. إذا كان أكبر من أو يساوي 18، ينتقل البرنامج لفحص إذا كان طالبًا. إذا كان طالبًا، يفحص إذا كان لديه قسيمة خصم. هذا يوضح كيف يمكن أن يتفرع الكود لعدة مستويات من القرارات.
تُستخدم جملة switch عندما نريد اختبار قيمة متغير معين مع عدة احتمالات محددة وثابتة. بدلاً من كتابة سلسلة طويلة من جمل `if-else if-else` عندما يكون لدينا العديد من الشروط المتساوية، يمكننا استخدام `switch` لجعل الكود أكثر وضوحًا وقابلية للقراءة.
تعمل `switch` عن طريق مقارنة قيمة تعبير (عادةً متغير) مع قائمة من قيم case (حالات). عندما يتم العثور على تطابق، يتم تنفيذ التعليمات البرمجية المرتبطة بهذه الـ `case`.
الصيغة العامة:
switch (expression) {
case value1:
// الكود الذي سينفذ إذا كانت قيمة التعبير = value1
break; // مهم للخروج من switch
case value2:
// الكود الذي سينفذ إذا كانت قيمة التعبير = value2
break;
// ... المزيد من الحالات (cases)
default:
// الكود الذي سينفذ إذا لم تتطابق قيمة التعبير مع أي من الحالات السابقة
break; // اختياري لـ default إذا كان آخر شيء في switch
}
byte، short، char، int، Enum (أنواع التعداد)، String (من Java 7 فما فوق)، أو فئات التغليف (Wrapper Classes) المقابلة (مثل Integer، Byte، إلخ).break مهمة جدًا! تنهي تنفيذ جملة `switch` فورًا وتنتقل بالتحكم إلى الكود الذي يلي `switch`. إذا لم تكتب `break`، سيستمر التنفيذ إلى الحالات التالية (Fall-through)، وهذا قد يؤدي إلى نتائج غير متوقعة.public class SwitchExample {
public static void main(String[] args) {
int day = 3; // الرقم 3 يمثل يوم الاثنين
switch (day) {
case 1:
System.out.println("السبت");
break;
case 2:
System.out.println("الأحد");
break;
case 3:
System.out.println("الاثنين");
break;
case 4:
System.out.println("الثلاثاء");
break;
case 5:
System.out.println("الأربعاء");
break;
case 6:
System.out.println("الخميس");
break;
case 7:
System.out.println("الجمعة");
break;
default: // في حال لم تتطابق القيمة مع أي من الحالات
System.out.println("الرقم المدخل لا يمثل يوماً معروفاً.");
break;
}
}
}
الشرح: بما أن `day` تساوي 3، سيتم العثور على تطابق مع `case 3`، وسيتم طباعة "الاثنين". بعد ذلك، جملة `break` ستوقف تنفيذ `switch` وتنتقل إلى نهاية الجملة.
تذكر النقاط التالية عند استخدام `switch`:
byte، short، char، و int. كما تدعم Enum و String (من Java 7). لا يمكنك استخدام `long`، `float`، `double`، أو `boolean` مباشرة في تعبير `switch`.case، سيستمر التنفيذ إلى كتل case التالية حتى يجد جملة break أو يصل إلى نهاية جملة `switch`. هذا السلوك يُعرف بـ "Fall-through".public class SwitchNoBreakExample {
public static void main(String[] args) {
int number = 2;
switch (number) {
case 1:
System.out.println("واحد");
case 2: // هذا الـ case سيتطابق، وسيبدأ التنفيذ من هنا
System.out.println("اثنان");
case 3: // لا يوجد break بعد case 2، لذا سيستمر التنفيذ إلى هنا
System.out.println("ثلاثة");
default: // ولا هنا، لذا سيستمر التنفيذ إلى default
System.out.println("أرقام أخرى");
}
}
}
الناتج سيكون:
اثنان
ثلاثة
أرقام أخرى
الشرح: بما أن `number` هي 2، سيتم تنفيذ الكود داخل `case 2`. ولأنه لا توجد جملة `break` بعد `case 2`، سيستمر التنفيذ تلقائيًا إلى `case 3` ثم إلى `default`، مما يؤدي إلى طباعة جميع الرسائل اللاحقة.
كل من جملتي `if-else` و `switch` تُستخدمان للتحكم في تدفق البرنامج بناءً على الشروط، ولكن لكل منهما استخدامات مفضلة.
>، <، >=، <=).&& و ||.تخيل `if-else` كشجرة قرارات يمكنك فيها فحص أي سؤال بأي طريقة. بينما `switch` تشبه مفتاح الاختيار حيث تختار مسارًا واحدًا بناءً على قيمة محددة.
برنامج يحدد مزايا المستخدم بناءً على نوع حسابه، والذي يتم إدخاله كنص.
public class AccountTypeChecker {
public static void main(String[] args) {
String accountType = "VIP"; // يمكن تغيير هذه القيمة للاختبار
switch (accountType) {
case "Basic":
System.out.println("مزايا محدودة: وصول إلى المحتوى الأساسي.");
break;
case "Premium":
System.out.println("مزايا إضافية: وصول إلى المحتوى المميز، دعم فني أسرع.");
break;
case "VIP":
System.out.println("جميع المزايا متاحة: وصول كامل، دعم شخصي 24/7، دعوات حصرية.");
break;
default:
System.out.println("نوع الحساب غير معروف. يرجى التحقق من المدخلات.");
break;
}
}
}
برنامج يأخذ درجة الطالب ويحدد ما إذا كان ناجحًا أو راسبًا، ويحدد تقديره.
public class StudentGradesChecker {
public static void main(String[] args) {
int grade = 72; // يمكن تغيير هذه القيمة للاختبار
if (grade >= 90) {
System.out.println("التقدير: امتياز");
} else if (grade >= 75) {
System.out.println("التقدير: جيد جدًا");
} else if (grade >= 50) {
System.out.println("التقدير: ناجح");
} else {
System.out.println("التقدير: راسب");
}
}
}
برنامج يطلب عمر المستخدم ويحدد الفئة العمرية التي ينتمي إليها.
import java.util.Scanner;
import java.util.InputMismatchException;
public class AgeCategoryDeterminer {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("أدخل عمرك: ");
try {
int age = scanner.nextInt();
if (age < 0) {
System.out.println("عمر غير صالح. العمر لا يمكن أن يكون سالباً.");
} else if (age <= 12) {
System.out.println("أنت طفل.");
} else if (age >= 13 && age <= 19) {
System.out.println("أنت مراهق.");
} else if (age >= 20 && age <= 60) {
System.out.println("أنت بالغ.");
} else { // age > 60
System.out.println("أنت كبير في السن.");
}
} catch (InputMismatchException e) {
System.out.println("مدخل غير صالح. يرجى إدخال رقم صحيح للعمر.");
} finally {
scanner.close();
}
}
}
اختبر فهمك لهذه الوحدة من خلال حل التمارين التالية:
اكتب برنامج جافا يطلب من المستخدم إدخال رقمين، ثم يطلب منه اختيار عملية حسابية (+، -، *، /) كحرف. استخدم جملة `switch` لتنفيذ العملية المطلوبة وطباعة النتيجة على الكونسول. تأكد من معالجة القسمة على صفر وأنواع المدخلات الخاطئة.
import java.util.Scanner;
import java.util.InputMismatchException;
public class SimpleCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// اكتب الكود هنا لطلب الرقمين والعملية الحسابية وتنفيذها باستخدام switch
scanner.close();
}
}
اكتب برنامج يطلب من المستخدم إدخال رقم الشهر (من 1 إلى 12). بناءً على رقم الشهر، اطبع اسم الموسم الذي يقع فيه هذا الشهر (مثلاً: الشتاء، الربيع، الصيف، الخريف).
تلميح:
import java.util.Scanner;
import java.util.InputMismatchException;
public class SeasonDeterminer {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// اكتب الكود هنا لطلب رقم الشهر وتحديد الموسم باستخدام if-else if
scanner.close();
}
}
اكتب برنامج يطلب من المستخدم إدخال كلمة مرور. قم بالتحقق من كلمة المرور بناءً على الشروط التالية:
import java.util.Scanner;
public class PasswordStrengthChecker {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("أدخل كلمة المرور: ");
String password = scanner.nextLine();
boolean isStrong = true;
String feedback = "";
// اكتب الكود هنا للتحقق من الشروط وتحديث isStrong و feedback
// مثال:
// if (password.length() < 8) {
// isStrong = false;
// feedback += "يجب أن تكون كلمة المرور 8 أحرف على الأقل.\n";
// }
if (isStrong) {
System.out.println("كلمة المرور قوية!");
} else {
System.out.println("كلمة المرور ضعيفة:\n" + feedback);
}
scanner.close();
}
}
في هذه الوحدة الحاسمة، قمتَ ببناء فهم قوي حول **جمل التحكم الشرطية (Conditional Control Statements)** في Java. لقد تعلمتَ كيف تجعل برامجك تتخذ قرارات وتنفذ مسارات مختلفة بناءً على تقييم الشروط.
if، if-else، و else-if للتعامل مع الشروط الفردية والمتسلسلة والمعقدة.&&، ||، !) لبناء منطق أكثر تعقيدًا.switch كبديل أنيق ومباشر لـ if-else if المتعددة عند مقارنة قيمة واحدة باحتمالات ثابتة.break داخل `switch` لتجنب سلوك "Fall-through" غير المرغوب فيه.إن إتقان هذه المفاهيم سيمنحك القدرة على كتابة برامج قادرة على التفكير والاستجابة للمدخلات والسيناريوهات المتغيرة، وهي مهارة لا غنى عنها في أي تطبيق برمجي. في الوحدة القادمة، سنتعمق في **حلقات التكرار (Loops)** بأنواعها المختلفة وكيفية استخدامها لتنفيذ التعليمات البرمجية بشكل متكرر وفعال.