C: الجمل الشرطية
الجمل الشرطية كإشارات المرور عند تقاطع الطرق — عندما يتحقق الشرط تسلك طريقًا، وإلا تسلك طريقًا آخر. تكتسب البرامج ذكاءها من خلال اتخاذ القرارات.
1. جملة if
if هي أبسط جملة شرطية. عندما يكون الشرط صحيحًا (غير صفري)، يُنفَّذ الكود داخل الأقواس؛ وعندما يكون خاطئًا (صفري)، يُتجاوز.
#include <stdio.h>
int main(void) {
int score = 95;
if (score >= 90) {
printf("Excellent!\n");
}
printf("Program continues\n");
return 0;
}
Excellent!
Program continues
if، يمكن حذف الأقواس. ومع ذلك، يُنصح بشدة باستخدام الأقواس دائمًا لتجنب أخطاء المنطق عند إضافة جمل لاحقًا ونسيان إضافة الأقواس.
2. جملة if-else
توفر if-else فرعين: إذا كان الشرط صحيحًا، يُنفَّذ كتلة if؛ وإذا كان خاطئًا، تُنفَّذ كتلة else. أحدهما سينفذ حتمًا.
#include <stdio.h>
int main(void) {
int age = 16;
if (age >= 18) {
printf("You are an adult\n");
} else {
printf("You are a minor\n");
}
return 0;
}
You are a minor
(1) مشكلة else المعلّق
عند تتداخل عدة جمل if، يرتبط else بأقرب if:
#include <stdio.h>
int main(void) {
int a = 5, b = 0;
if (a > 10)
if (b > 0)
printf("A\n");
else
printf("B\n");
return 0;
}
يبدو أن else مرتبط بأول if، لكنه في الواقع مرتبط بثاني if، لذلك لا يُطبَع شيء. إضافة الأقواس يجعل الارتباط واضحًا:
if (a > 10) {
if (b > 0) {
printf("A\n");
} else {
printf("B\n");
}
}
3. سلسلة if-else if-else
عند الحاجة للتحقق من عدة شروط بالتسلسل، استخدم else if لربط عدة فروع:
#include <stdio.h>
int main(void) {
int score = 78;
if (score >= 90) {
printf("Grade: A\n");
} else if (score >= 80) {
printf("Grade: B\n");
} else if (score >= 70) {
printf("Grade: C\n");
} else if (score >= 60) {
printf("Grade: D\n");
} else {
printf("Grade: F\n");
}
return 0;
}
Grade: C
تُقيَّم شروط else if من الأعلى إلى الأسفل. بمجرد تحقق شرط، تُتجاوز جميع الفروع اللاحقة. ترتيب الشروط مهم.
4. الجمل الشرطية المتداخلة
يمكن تداخل if داخل if آخر لمنطق شرطي أدق:
#include <stdio.h>
int main(void) {
int age = 25;
char gender = 'M';
if (age >= 18) {
if (gender == 'M') {
printf("Adult male\n");
} else {
printf("Adult female\n");
}
} else {
printf("Minor\n");
}
return 0;
}
Adult male
else if.
5. جملة switch-case
تنتقل switch إلى فرع case المطابق بناءً على قيمة تعبير عدد صحيح. مثالية للتفرع على قيم منفصلة.
(1) الصياغة الأساسية
switch (expression) {
case constant1:
statement;
break;
case constant2:
statement;
break;
default:
statement;
break;
}
#include <stdio.h>
int main(void) {
int day = 3;
switch (day) {
case 1: printf("Monday\n"); break;
case 2: printf("Tuesday\n"); break;
case 3: printf("Wednesday\n"); break;
case 4: printf("Thursday\n"); break;
case 5: printf("Friday\n"); break;
case 6: printf("Saturday\n"); break;
case 7: printf("Sunday\n"); break;
default: printf("Invalid day\n"); break;
}
return 0;
}
Wednesday
(2) أهمية break
بعد أن تطابق switch حالة case، تُنفَّذ جميع الجمل من تلك النقطة فصاعدًا حتى تصادف break أو نهاية switch. يُسمّى هذا "الاختراق" (fall-through).
#include <stdio.h>
int main(void) {
int num = 2;
switch (num) {
case 1: printf("One\n");
case 2: printf("Two\n");
case 3: printf("Three\n");
default: printf("Default\n");
}
return 0;
}
Two
Three
Default
break هو الخطأ الأكثر شيوعًا في switch. ما لم تستخدم الاختراق عمدًا، أضف break دائمًا في نهاية كل case.
(3) استخدام الاختراق لدمج الفروع
أحيانًا تحتاج عدة تصنيفات case لتنفيذ نفس المنطق. يمكنك حذف break عمدًا:
#include <stdio.h>
int main(void) {
char grade = 'B';
switch (grade) {
case 'A':
case 'B':
case 'C':
printf("Pass\n"); break;
case 'D':
printf("Retake\n"); break;
case 'F':
printf("Fail\n"); break;
default:
printf("Invalid grade\n"); break;
}
return 0;
}
Pass
(4) قيود switch
- يجب أن يكون التعبير من نوع عدد صحيح (
intأوcharأوenum، إلخ)؛ الأعداد العشرية والسلاسل النصية غير مسموحة - يجب أن تكون القيمة بعد
caseثابتًا وقت التجميع، وليس متغيرًا - يجب ألا تتكرر قيم
case
6. المؤثر الشرطي (الثلاثي)
يمكن للمؤثر الشرطي ?: أن يحل محل جمل if-else البسيطة. ذُكر في الدرس 6؛ إليك المزيد من أمثلة الاستخدام:
#include <stdio.h>
int main(void) {
int a = -5;
int abs_a = a >= 0 ? a : -a;
printf("|%d| = %d\n", a, abs_a);
int x = 10, y = 10;
printf("%s\n", x == y ? "Equal" : "Not equal");
return 0;
}
|-5| = 5
Equal
if-else بدلًا من ذلك.
▶ مثال
تحديد نوع الجسم بناءً على مؤشر كتلة الجسم BMI، مع عرض منطق شرطي متعدد الفروع:
#include <stdio.h>
int main(void) {
double weight = 70.0;
double height = 1.75;
double bmi = weight / (height * height);
printf("BMI: %.1f\n", bmi);
if (bmi < 18.5) {
printf("Underweight\n");
} else if (bmi < 24.0) {
printf("Normal\n");
} else if (bmi < 28.0) {
printf("Overweight\n");
} else {
printf("Obese\n");
}
return 0;
}
BMI: 22.9
Normal
▶ مثال
تنفيذ اختيار قائمة بسيط باستخدام switch:
#include <stdio.h>
int main(void) {
int choice = 2;
printf("===== Menu =====\n");
printf("1. New Game\n");
printf("2. Continue\n");
printf("3. Settings\n");
printf("4. Exit\n");
printf("================\n");
printf("Your choice: %d\n", choice);
switch (choice) {
case 1: printf("Starting new game!\n"); break;
case 2: printf("Loading save...\n"); break;
case 3: printf("Opening settings\n"); break;
case 4: printf("Exiting game\n"); break;
default: printf("Invalid choice\n"); break;
}
return 0;
}
===== Menu =====
1. New Game
2. Continue
3. Settings
4. Exit
================
Your choice: 2
Loading save...
❓ أسئلة شائعة
if؟if/else، لكن يُنصح باستخدامها دائمًا لتجنب الأخطاء الناتجة عن نسيان إضافة أقواس عند إضافة جمل لاحقًا.switch تقييم الأعداد العشرية أو السلاسل النصية؟switch يقبل فقط تعبيرات أعداد صحيحة. لا تعمل الأعداد العشرية ولا السلاسل النصية. لمقارنة السلاسل، استخدم سلسلة if-else if.default؟else if و if المتداخل؟else if هي بنية متعددة الفروع مسطحة أسهل قراءة؛ أما if المتداخل فهو تسلسلي مناسب عندما تعتمد الشروط على بعضها. يمكن الاستبدال بينهما — اختر الأكثر وضوحًا.📖 ملخص
ifيعالج شرطًا واحدًا، وif-elseيختار بين اثنين، وelse ifيختار بين عدة فروع- استخدم الأقواس دائمًا لتجنب مشاكل else المعلّق ومشاكل الصيانة المستقبلية
switchمثالي للتفرع على قيم أعداد صحيحة منفصلة؛ لا تنسَbreakلكلcase- الاختراق في
switchيمكنه دمج الفروع، لكن نسيانbreakمصدر خطأ شائع - المؤثر الثلاثي
?:مناسب للاختيارات الثنائية البسيطة؛ استخدمif-elseللمنطق المعقد
📝 تمارين
- اكتب برنامجًا يقرأ عددًا صحيحًا ويحدد ما إذا كان موجبًا أم سالبًا أم صفرًا، ثم يطبع النتيجة.
- اكتب برنامجًا يقرأ رقم شهر (1-12) ويستخدم
switchلإخراج عدد أيام ذلك الشهر (بافتراض سنة غير كبيسة، أي فبراير 28 يومًا). - اكتب برنامجًا يقرأ محرفًا ويحدد ما إذا كان حرفًا كبيرًا أم حرفًا صغيرًا أم رقمًا أم محرفًا آخر.