שפת C/ביטויים בוליאניים ותנאים

כדי להשתמש בנתונים שנקלטו מהמשתמש ולנתב בעזרתם את התוכנה, מדי פעם צריכים לעשות בדיקה של הנתונים.

ערכים בוליאניים עריכה

אמת ושקר, וייצוגם בשפת C עריכה

ביטוי בוליאני הוא ביטוי שיכול לקבל את הערכים "אמת" ו"שקר". לעתים צריך בתכניות מחשב להכריע האם דבר הוא אמת או שקר, לדוגמה, האם נכון שערכו של המשתנה x הוא 6, או האם שקר הוא שערכו של המשתנה x קטן מערכו של המשתנה y.

בשפת C הערך המספרי 0 מציין "שקר", וכל ערך אחר מציין "אמת". בהמשך דף זה ובלולאות נראה כיצד לגרום למחשב לבצע פעולות שונות בהתאם לשאלה האם ערך כלשהו הוא אמת או שקר.

אופרטורים בוליאניים עריכה

שפת C כוללת מספר אופרטורים בוליאניים, כלומר אופרטורים שתוצאתם היא "אמת" או "שקר". לדוגמה, כדי לבדוק האם ערך המשתנה x הוא 6, רושמים

x == 6

כאשר יתבצע קטע קוד זה, יתרגם אותו המחשב ל"אמת" (ערך כלשהו שאינו 0) אם ערך x אכן 6, או ל"שקר" (הערך המספרי 0) אם ערכו שונה.

שים לב להבדל בין האופרטור == לבין פעולת ההשמה =.

לשפת C האופרטורים הבוליאניים הבאים:

  • == (להבדיל מ= המשמש להשמה) - האם שני צדי הביטוי שווים
  • =! - האם שני צדי הביטוי שונים
  • > - האם הצד הימני של הביטוי גדול מצדו השמאלי
  • < - האם הצד הימני של הביטוי קטן מצדו השמאלי
  • => - האם הצד הימני של הביטוי גדול או שווה לצדו השמאלי
  • =< - האם הצד הימני של הביטוי קטן או שווה לצדו השמאלי

תוכל לראות כיצד משתמשים באופרטורים בוליאניים בתנאי if (ייתכן שתרצה לבדוק זאת בקצרה לפני המעבר לנושא הבא).

אופרטורים לוגיים עריכה

גימום, איווי, ושלילה עריכה

ביטוי בוליאני יכול להיות מורכב גם מאוסף של ביטויים בוליאניים פשוטים יותר, המחוברים על ידי קשרים לוגיים, למשל: "אם x שווה 5 או x שווה 6", או: "אם x גדול מ-y וגם y גדול מ-z", וכדומה.

גימום (conjunction בלעז), כלומר הקשר הלוגי "וגם", מיוצג על ידי שני התווים &&:

<condition_1> && <condition_2>

כאשר condition_1 ו-condition_2 הם שני תנאים בוליאניים, והגימום הוא אמת אם ורק אם שניהם אמת. לדוגמה:

x == 5 && y == 6

הוא התנאי שערכו של x הוא 5 וגם ערכו של y הוא 6.


איווי (disjunction בלעז), כלומר הקשר הלוגי "או", מיוצג על ידי שני התווים ||:

<condition_1> || <condition_2>

כאשר condition_1 ו-condition_2 הם שני תנאים בוליאניים, והאיווי הוא אמת אם ורק אם לפחות אחד מהם הוא אמת. לדוגמה:

x == 5 || y == 6

הוא התנאי שערכו של x הוא 5 או שערכו של y הוא 6.

שלילה (negation בלעז), כלומר הקשר הלוגי "לא", מיוצג על ידי התו !:

!<condition>

כאשר condition הוא תנאי בוליאני, והשלילה היא אמת אם ורק אם התנאי הוא שקר. לדוגמה:

!(x == 5)

הוא התנאי השולל שערכו של x הוא 5.


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

a > b || (a <= b && b == 5)

תוכל לראות כיצד משתמשים באופרטורים בוליאניים בהתנאי if (ייתכן שתרצה לבדוק זאת בקצרה לפני המעבר לנושא הבא).

הערכת ביטויים לוגיים מורכבים עריכה

 

שקלו לדלג על נושא זה

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



בעת הרצת התוכנית מתבצע חישוב של תנאי מורכב משמאל לימין, ובשימוש בקצר לוגי (שיוסבר להלן).

נתבונן בתנאי המורכב:

x == 5 || y == 6

מבין שני הביטויים כאן, הביטוי השמאלי, x == 5 הוא זה שיוערך ראשון. כעת יש שתי אפשרויות:

  • אם ביטוי זה הוא שקר, עדיין יכול הביטוי המורכב, x == 5 || y == 6, להיות אמת - יש לבדוק אם הביטוי הימני, y == 6, הוא אמת.
  • אם ביטוי זה הוא אמת, אז הביטוי המורכב, x == 5 || y == 6, בהכרח אמת. אין צורך אפילו לבדוק את הביטוי הימני. השפה מבטיחה במקרה זה לערוך קצר לוגי - היא כלל לא תעריך את y == 6.

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

<left_condition> || <right_condition>

לא יוערך הביטוי right_condition אם left_condition אמת. בתנאי המורכב

<left_condition> && <right_condition>

לא יוערך הביטוי right_condition אם left_condition שקר.

בשפת C, הידועה בקצרנותה, מתכנתים משתמשים בקצרים לוגיים באופן תדיר. לדוגמה:

(x != 0 && 1 / x < 2)

מבטיחה, על ידי קצר לוגי, שלא תתבצע בטעות חלוקה ב0.

תנאי בקרה עריכה

תנאי בקרה (selection statements) מאפשרים לציין אילו קטעי קוד יבוצעו בהתאם לתנאים כלשהם.

if עריכה

משפטי תנאי מתחילים במילה if, לאחריו ביטוי בוליאני, ולאחריו הפעולה (או הבלוק) שיש לבצע במקרה שהביטוי הבוליאני אמת:

if (<condition>)
  <action>

כאשר condition הוא התנאי הבוליאני לבדיקה, ו-action היא הפעולה (או הבלוק).

כאשר מבצעים יותר מפקודה אחת בif, הפקודות חייבות להיכלל בבלוק.

לדוגמה:

if (x == 5)
{
  printf("%d = ", x);
  printf("5!");
}

קטע קוד זה יבדוק האם הערך של x שווה ל5, ובמידה וכן, תודפס התוצאה המתאימה.

התרשים הבא מראה את התנאי בצורה גרפית:

 
התנאי if

לדוגמה, קטע הקוד:

if (x == 6)
  printf("x is 6");

ידפיס אם ערך x אכן 6 תתבצע ההדפסה (ואם לא - לא).

כמובן שנוכל ליצור תנאים מסובכים מעט יותר:

  • אפשר להשתמש באופרטורים בוליאניים ולוגיים כדי ליצור תנאים בוליאניים מורכבים לבדיקת ה-if
  • אפשר להשתמש בבלוקים כדי לבצע רצף של פקודות במקרה שהתנאי אמת


 

עכשיו תורכם:

כתוב קטע שיבדוק האם ערך משתנה x הוא 5 או 6, ומדפיס הודעה אם אכן הדבר כן.


if (x == 5 || x == 6)
  printf("x is either 5 or 6");


 

עכשיו תורכם:

כתוב קטע שיבדוק האם ערך משתנה x הוא 5, ואם כן, ישים את הערך 1 למשתנה i, ו-2 למשתנה j.


הפתרון
if (x == 5)
{
  i = 1;
  j = 2;
}


else עריכה

לפעמים צריך לציין הן מה לעשות כשתנאי מתקיים, והן מה לעשות כשאינו מתקיים. במקרה זה אפשר להשתמש בתנאי if / else.

if (<condition>)
  <action>
else
  <alternative_action>

כאן condition הוא תנאי, action הוא פקודה (או בלוק) לביצוע אם התנאי מתקיים, ו-alternative_action הוא פקודה (או בלוק) לביצוע אם אינו מתקיים.

התרשים הבא מראה את התנאי בצורה גרפית:

 
התנאי if-else


לדוגמה:

if (x == 6)
  y += 2;
else
  y = 8;

יחבר 2 ל-y אם x == 6, ויקבע את ערכו של y ל-8 אם ערכו של x אינו 6.

else if עריכה

לפעמים צריך לציין הן מה לעשות כשתנאי מתקיים, והן מה לעשות כשאינו מתקיים, אך תנאי אחר כן מתקיים. במקרה זה אפשר להשתמש בתנאי if / else if.

if (<condition>)
  <action>
else if (<alternative_condition>)
  <alternative_action>

כאן condition הוא תנאי, action הוא פקודה (או בלוק) לביצוע אם התנאי מתקיים, alternative_condition הוא תנאי לבדיקה אם condition הוא שקר, ו-alternative_action הוא פקודה (או בלוק) לביצוע אם condition הוא שקר אך alternative_condition הוא אמת.

לדוגמה:

if (x == 6)
  y += 2;
else if (x % 2 == 0)
  y = 8;

יחבר 2 ל-y אם x == 6, ויקבע את ערכו של y ל-8 אם ערכו של x אינו 6 אך x זוגי.

שילובי if / else if / else עריכה

ניתן לשלב בין שלושת תנאי הבקרה שראינו. המבנה הכללי ביותר הוא:

תנאי if, שלאחריו אפס או יותר תנאי else if, שלאחר האחרון שבהם (אם יש כאלה) תנאי else.

אופרטור התניה עריכה

אופרטור התניה מאפשר לציין ערך שתלוי בתנאי כלשהו. אופן כתיבתו הוא בצורה:

<condition> ? <true_value> : <false_value>

כאשר condition הוא ביטוי בוליאני, true_value הוא הערך אם condition תקף, ו-false_value הוא הערך אחרת. לדוגמה

a == 3 ? 1 : 2

תחילה נבדק האם a שווה ל-3 (על פי קדימות אופרטורים, האופרטור '==' קודם לאופרטור התנאי), הביטוי כולו בעל הערך 1 אם a אכן שווה ל-3, והוא בעל הערך 2 אחרת.

חשוב להבין שאפשר להשתמש באופרטור התניה כערך לכל דבר. לדוגמה, ניתן לכתוב:

int b = a == 3 ? 1 : 2;

וכן

printf("%s is the winner", a > 5 ? "moshe" : "yaakov");

switch-case עריכה

switch-case הוא סוג נוסף של משפט בקרה. המבנה שלו הוא מהצורה:

switch (<expression>)
{
case <value_0>:
  <action_0>
  break;
case <value_1>:
  <action_1>
  break;
  ...
default:
  <default_action>
}

כאשר:

  • expression הוא ערך (לרוב נתון כערכו של משתנה)
  • value_0, value_1...‎ הם ערכים קבועים.
  • action_0, action_1...‎ הם פקודות או רצפי פקודות.
  • default_action הוא פקודה או רצף פקודות.

כאשר רצף התכנית מגיע לפקודת switch, מתבצעים השלבים הבאים:

  1. הערך expression מחושב
  2. נבדק מי הוא הערך הראשון מבין הערכים value_0, value_1...‎ שערכו זהה ל-expression. הפקודה המתאימה לערך הראשון הנ"ל תבוצע.
  3. אם אף ערך מתאים ל-expression, ותנאי ברירת המחדל (default) נמצא, אז הפקודה המתאימה לו תבוצע.

התכנית הבאה מדגימה את השימוש ב-switch:

#include <stdio.h>

int main()
{
  char rep;
  
  printf("Click a number between 1 and 4");
  
  rep = getchar();
  
  switch (rep)
  {
  case '1':
    printf("You clicked 1, have a good day");
    break; 
  case '2':
    printf("You clicked 2, have a nice day");
    break; 
  case '3':
    printf("You clicked 3, have a happy day");
    break; 
  case '4':
    printf("You clicked 4, have a great day");
    break; 
  default:
    printf("You did not click a number between 1 and 4");
    return -1;
  }

  return 0;
}


הפרק הקודם:
פעולות חשבוניות
ביטויים בוליאניים ותנאים
תרגילים
הפרק הבא:
לולאות