Menu

If else ב-C++: משפטי תנאי עם דוגמאות

איך מקבלים החלטות ב-C++ עם if, else if ו-else: תנאים, שרשור הסתעפויות, קינון, האופרטור הטרנרי, if עם אתחול, והמלכודות שמכשילות מתכנתים.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

קבלת החלטות עם if

תוכניות מגיבות כל הזמן לנתונים: עבר או נכשל, במלאי או אזל, תקין או לא. משפט if הוא הדרך של C++ לבחור איזה קוד להריץ לפי תנאי.

if מקבל תנאי בסוגריים ומריץ את הבלוק שבסוגריים המסולסלים רק כשהתנאי הזה אמת:

התנאי score >= 60 הוא אמת, ולכן ההודעה מודפסת. השורה שאחרי הסוגר המסולסל הסוגר רצה תמיד, כי היא נמצאת מחוץ ל-if. שנו את score ל-40 ושורת ה-"passed" תדולג לגמרי.

התנאי מומר ל-bool. השוואות כמו >, >=, ==, != כבר מחזירות bool, אבל C++ גם מתייחסת לכל מספר שאינו אפס כאמת ול-0 כשקר, כך ש-if (count) פירושו "אם count אינו אפס". ההמרה המרומזת הזו נוחה, אבל היא גם המקור לכמה באגים קלאסיים שתראו בהמשך.

הוספת else

else נותן לכם את מסלול ה"אחרת": קוד שרץ רק כשהתנאי שקרי:

בדיוק אחד משני הבלוקים רץ, אף פעם לא שניהם ואף פעם לא אף אחד. ל-else אין תנאי משלו: הוא פשוט תופס את כל מה שה-if לא תפס.

שרשור עם else if

כשיש יותר משתי תוצאות, משרשרים תנאים עם else if. C++ בודקת אותם מלמעלה למטה ומריצה את הבלוק הראשון שהתנאי שלו אמת, ואז מדלגת על השאר:

הסדר חשוב. מכיוון ש-84 נבדק קודם מול >= 90 (שקר) ואז מול >= 80 (אמת), הבדיקה נעצרת ב-B ולא בודקת את הגבולות הנמוכים יותר. זו גם הסיבה שלא צריך score >= 80 && score < 90: ההגעה לענף השני כבר מבטיחה ש-score היה מתחת ל-90. שימו ראשון את התנאי הצר ביותר או בעל העדיפות הגבוהה ביותר.

שימו לב שאין ב-C++ מילת מפתח elif: else if הוא פשוט else שהגוף שלו הוא if נוסף. הסוגריים המסולסלים רק גורמים לזה להיקרא כמו סולם אחד.

מלכודת גדולה: = מול ==

הבאג הנפוץ ביותר במשפטי if ב-C וב-C++ הוא כתיבת = (השמה) כשהתכוונתם ל-== (השוואה):

x = 5 משים 5 ל-x, והביטוי כולו מוערך ל-5, שמומר ל-true. לכן הענף רץ תמיד, ודרסתם בשקט את x. זה מתקמפל, ורוב הקומפיילרים מוציאים רק אזהרה. שתי הגנות: הפעילו אזהרות (-Wall) כדי שהקומפיילר יסמן את זה, ושקלו לשים את הקבוע בצד הראשון, if (5 == x), כי if (5 = x) היא שגיאה מוחלטת שהקומפיילר תופס מיד.

אותה מלכודת מסתתרת גם עם bool: if (ready = true) מתקמפל ומבצע השמה, בעוד ש-if (ready == true) (או פשוט if (ready)) משווה.

שילוב וקינון של תנאים

שלבו תנאים עם && (וגם), || (או) ו-! (לא), או קננו if אחד בתוך אחר כשבדיקה הגיונית רק אחרי שבדיקה קודמת עברה:

&& ו-|| מבצעים הערכה מקוצרת (short-circuit): ב-a && b, אם a שקרי, C++ לא מעריכה את b בכלל. זה חיוני להגנה מפני גישה שגויה לזיכרון: if (ptr != nullptr && ptr->ready) בטוח, כי הגישה דרך המצביע מדולגת כש-ptr הוא null. כשאפשר, העדיפו לשטח עם && במקום קינון עמוק: תנאי שטוח קריא יותר מפירמידה של סוגריים מסולסלים.

היזהרו משרשור השוואות שלא אומר את מה שהוא נראה שאומר: if (0 < x < 10) לא בודק טווח. הוא מעריך את 0 < x ל-bool (0 או 1), ואז משווה את זה מול 10, וזה תמיד אמת. כתבו במקום זאת if (0 < x && x < 10).

האופרטור הטרנרי

כשכל מה שאתם רוצים הוא לבחור בין שני ערכים, האופרטור הטרנרי ?: הוא שורה אחת קומפקטית. קראו את condition ? a : b כ"אם התנאי מתקיים אז a, אחרת b":

הטרנרי מפיק ערך שאפשר להשים, להעביר או להדפיס ישירות, דבר ש-if רגיל לא יכול לעשות. שמרו אותו לבחירה פשוטה: אם אחד הענפים צריך כמה פקודות או לוגיקה של ממש, if-else מלא נשאר קריא, בעוד שטרנרי מקונן הופך מהר לחידה. (דקות אחת: לשני הענפים צריך להיות טיפוס משותף, אז אל תערבבו, למשל, מחרוזת ו-int.)

if עם אתחול (C++17)

מאז C++17 אפשר להצהיר על משתנה ישירות בתוך ה-if, עם טווח שמוגבל ל-if/else בלבד. כך עוזרים קצרי חיים לא דולפים לקוד שמסביב:

החלק שלפני ה-; רץ פעם אחת, והתוצאה שלו גלויה גם בתנאי וגם ב-else. זה מצוין לתבניות של "חשב משהו, ואז הסתעף לפיו", ומכיוון שהחישוב וההמרה של התוצאה קורים פעם אחת מראש, נמנעים מחישוב חוזר או משימוש בטעות בערך ישן מאוחר יותר. השתמשו בזה בכל פעם שמשתנה זמני נחוץ רק להסתעפות.

מלכודת: הסוגריים המסולסלים החסרים

C++ מרשה לוותר על סוגריים מסולסלים כשבענף יש פקודה אחת, אבל זה מזמין באג עדין: ההזחה משקרת:

if (loggedIn)
    cout << "Welcome\n";
    cout << "Loading dashboard\n";   // לא חלק מה-if!

רק השורה הראשונה נשלטת על ידי ה-if. השנייה רצה תמיד, בלי קשר ל-loggedIn, למרות שההזחה רומזת אחרת. מקרה קלאסי קרוב הוא נקודה-פסיק תועה: if (x > 0); מסיים את ה-if עם גוף ריק, כך שהבלוק שאחריו רץ ללא תנאי. השתמשו תמיד בסוגריים מסולסלים, גם לשורה אחת, ורוב הטעויות מהסוג הזה ייעלמו.

הבא בתור: switch

שרשראות if-else if מושלמות כשכל ענף בודק תנאי אחר. אבל כשבודקים ערך אחד מול הרבה אפשרויות קבועות, כמו בחירה בתפריט, enum או קוד סטטוס, סולם else if ארוך נעשה חזרתי וקל לסדר אותו לא נכון. משפט switch נבנה בדיוק בשביל זה, והוא הנושא של העמוד הבא.

שאלות נפוצות

איך כותבים משפט if-else ב-C++?

שימו תנאי בסוגריים אחרי if, את הקוד שירוץ בסוגריים מסולסלים, ובלוק else אופציונלי למקרה שהתנאי שקרי: if (score >= 60) { cout << "Pass"; } else { cout << "Fail"; }. התנאי מומר ל-bool, ולכן כל מספר שאינו אפס נחשב אמת ו-0 נחשב שקר.

מה ההבדל בין = ל-== במשפט if ב-C++?

== משווה בין שני ערכים, ו-= בודד מבצע השמה. הכתיבה if (x = 5) משימה 5 ל-x ואז בודקת את 5 (תמיד אמת), באג קלאסי. זה מתקמפל עם אזהרה בלבד, ולכן הפעילו אזהרות ושקלו לכתוב את הקבוע ראשון: if (5 == x).

מהו האופרטור הטרנרי ב-C++?

האופרטור הטרנרי condition ? valueIfTrue : valueIfFalse הוא if-else קומפקטי שמפיק ערך. למשל string label = age >= 18 ? "adult" : "minor"; בוחר אחד משני ערכים. השתמשו בו לבחירת ערך פשוטה, ועברו ל-if-else מלא כשבכל ענף יש לוגיקה של ממש.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל