Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Studies

משפט if

סינטקס והגדרות

משפט if יאפשר לתוכנית שלנו להחליט האם לבצע או לדלג על קטע קוד מסוים בהתאם להאם תנאי כלשהו מתקיים. מספר דוגמאות לתנאים שימושיים בתכנות:

  1. בדיקת סיסמא - נבקש מהמשתמש להכניס סיסמא. אם הכניס אחת נכונה, ניתן לו גישה למחשב - אחרת נמנע ממנו להכנס.
  2. בדיקת נתונים - אם מישהו מבקש להזמין באינטרנט 4 מגני מסך, נבדוק מול הנתונים האם יש מספיק לתת לו ובמידה וכן נאשר את המשלוח שלו.
  3. צ’אט - במידה ואדם א’ רוצה לשלוח הודעה לאדם ב’, נבודק האם אדם ב’ לא חסם את אדם א’, ובמידה ולא נאשר את שליחת ההודעה.

לפני שנגדיר את הסינטקס בצורה מדויקת, נבחן דוגמא אינטואיטיבית:

#include <stdio.h>
#define PASSWORD 7521
int main() {
    int password;
    printf("Please enter your password\n");
    scanf("%d", &password);
    if (password == PASSWORD) {
        printf("Access granted!\n");
    } else {
        printf("Access denied!\n");
    }
}

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

Note

נזכיר כי הביטוי password == PASSWORD הוא מסוג בוליאני - ערכו יכול להיות true או false, ולכן הוא מתאים לשמש תנאי שיתכן ומתקיים ויתכן ולא.

כעת בצורה מדויקת יותר - תנאים ממומשים ע“י מילת המפתח if, כאשר הסינטקס לכתיבת משפט if הוא:


if (boolean statement) {
    // Execute only if statement is true
}
// Continue execution here

נפרק את המרכיבים:

  1. המילה if מתחילה את המשפט ולאחריה סוגריים רגילים ().
  2. בתור הסוגריים נמצא ביטוי בוליאני כלשהו - כמו שראינו בהרצאה הקודמת, ביטוי בוליאני יכול לקבל את הערכים true או false בלבד.
  3. כאשר הביטוי הבוליאני הוא true, נעבור לביצוע בלוק הקוד בתוך הסוגריים המסולסלים. אחרת, נקפוץ מיד לאחר קצה הבלוק.

Note

ב-C ובשפות אחרות קיימות מספר מילות מפתח (keywords) בהן לא ניתן להשתמש לאף צורך חוץ ממה שהשפה מגדירה. if היא מילת מפתח כזו - לא ניתן להגדיר משתנה בשם int if = 5 למשל.

לדוגמא - נבדוק האם יש מספיק מצרכים להכין עוגה:


#include <stdio.h>
#include <stdbool.h>
int main() {
    int eggs_in_stock = 3;
    int eggs_needed;
    printf("Enter number of needed eggs\n");
    scanf("%d", &eggs_needed);
    if(eggs_in_stock >= eggs_needed) {
        printf("You can make cake!\n");
    }
}

Note

אין צורך להגדיר משתנה בוליאני bool can_make_cake = eggs_in_stock >= eggs_needed - הקומפיילר מבצע casting לבוליאני באופן אוטומטי לכל ביטוי שנכתוב בתוך משפט if.

Lazy Evaluation

נזכיר כי בחישוב ביטוי בוליאני ניתן לדלג על חלק מהחישובים במידה והביטוי כבר ידוע, כמו במקרים x && false ו-x || true.

נבחן כדוגמא תוכנית שבוחנת עבור מספר כלשהו \(n\) האם המספר \(\frac{1}{n}\) קטן מ-\(\frac{1}{2}\):

#include <stdio.h>
#define UPPER_BOUND 0.5
int main() {
    int n;
    scanf("%d", &n);
    if (n != 0) {
        if ((1 / n) < UPPER_BOUND) {
            printf("1 / %d is less than %.2lf\n", n, UPPER_BOUND);
        }
    }
}

נשים לב לבדיקה האם \(n\) אינו אפס על מנת להגן על התוכנית מחלוקה ב-0. ניתן להשתמש ב-lazy evaluation על מנת לפשט את התוכנית, ולכתוב במקום:

#include <stdio.h>
#define UPPER_BOUND 0.5
int main() {
    int n;
    scanf("%d", &n);
    if (n != 0 && (1 / n) < UPPER_BOUND) {
        printf("1 / %d is less than %.2lf\n", n, UPPER_BOUND);
    }
}

במידה ו-n < 0, מגננון ה-lazy evaluation נכנס לפעולה ולכן החלק השני בתנאי לא יתבצע - ההגנה מתבצעת כך או כך.

כתיבה ללא סוגריים מסולסלים

השפה מאפשרת לכתוב משפט if ללא סוגריים מסולסלים, כך:

// Code before
if(eggs_in_stock >= eggs_needed)
    printf("You can make cake!");
// Do more stuff after

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


if(eggs_in_stock >= eggs_needed)
    printf("You can make cake!\n");
    printf("Cake for everybody!");
// Do other stuff

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


if(eggs_in_stock >= eggs_needed) {
    printf("You can make cake!\n")
}
printf("Cake for everybody!")
// Do other stuff

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