יסודות התכנות בשפת C#‎ · פרק 4 — פקודות תנאי (מבני בקרה)⌂📚🏠
פרק 4

פקודות תנאי (מבני בקרה)

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

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

דוגמה:

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

התחלהקלוט את מהירות המכוניתושמור אותה ב-v1האם?v > 1002כןלאהדפס על המסךAlert! You Pass Thelegal speed3סוף4

לפי דוגמה זו, התוכנית יכולה לבצע את פקודה 3 ויכולה שלא לבצע אותה, בהתאם לערך שאנו קולטים במהלך התוכנית ושומרים במשתנה v, המבטא את המהירות. לפי פקודת הבקרה (התנאי) 2, אם התשובה לשאלה היא כן (התנאי מתקיים) נבצע את פקודה 3, ואילו אם התוצאה של פקודת הבקרה (התנאי) היא לא (התנאי אינו מתקיים) לא נבצע את פקודה 3 ונתעלם ממנה.

דוגמה 4.1
כתוב תוכנית שקולטת מתלמיד את הציון שלו במקצוע מסוים. אם הציון של התלמיד נמוך מ-55, על התוכנית להדפיס לו את המילה Failed, ואם הציון שלו גדול או שווה ל-55 התוכנית מדפיסה Pass
התחלהקלוט ציון של תלמידושמור אותו ב-mark1האם?mark<552כןלאהדפס על המסךFailed3הדפס על המסךPass4סוף5

אפשר לבצע את פקודה (3) ואפשר שלא לבצע אותה, בהתאם לערך שאנו קולטים במהלך עבודת התוכנית, שאנו מקבלים מן המשתמש ושומרים בתוך המשתנה mark.

גם את פקודה (4) אפשר לבצע ואפשר שלא לבצע, בהתאם לערך שאנו קולטים מן המשתמש.

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

4.1 צורות (מקרים) של מבני הבקרה

(1) המקרה הראשון (הצורה הראשונה): תנאי if הבסיסי (הפשוט):

if (התנאי)
{
    פקודה (או פקודות) שמתבצעת רק אם התנאי מתקיים
}
המשך התוכנית
תנאי*falseלאtrueכןפקודה (או פקודות) שמתבצעתרקאם התנאי מתקיים1המשך התוכנית2

הסבר:

דוגמה 4.2
כתוב תוכנית שקולטת מספר עשרוני ומדפיסה על המסך את הערך המוחלט של מספר זה.
static void Main(string[] args)
{
    double num;
    Console.Write("Insert a number: ");
    num = double.Parse(Console.ReadLine());
    if(num<0)
    {
        num = -1 * num;
    }
    Console.WriteLine("|num| = {0}",num);
}
התחלהקלוט מספר numהאם?num<0falseלאtrueכןnum= -1 * numהדפס numסוף

כמה תוצאות של הרצת התוכנית:

Microsoft Visual Studio Debug Console
Insert a number: 5
|num| = 5
Microsoft Visual Studio Debug Console
Insert a number: -9.2
|num| = 9.2

(2) המקרה השני (הצורה השנייה): תנאי if .. else (התנאי והיפוכו):

if ( תנאי )
{
    פקודה (או פקודות) שמתבצעת אם התנאי מתקיים
}
else
{
    פקודה (או פקודות) שמתבצעת אם התנאי אינו מתקיים
}
המשך התוכנית
תנאי*falseלאtrueכןפקודה או קבוצת פקודותשמתבצעות אם התנאי מתקיים1פקודה או קבוצת פקודות שמתבצעותאם התנאי אינו מתקיים2המשך התוכנית3

אם מתקיים התנאי *, התוכנית מבצעת את קבוצת הפקודות 1, אבל מדלגת על הפקודות 2 שנמצאות בתוך else (אינה מבצעת אותן).

ואם אינו מתקיים התנאי *, התוכנית מדלגת על קבוצת הפקודות מספר 1 (אינה מבצעת אותן), אבל מבצעת את הפקודות 2 שנמצאות בתוך else.

לא ייתכן לבצע את הפקודות 1 ו-2 יחד: התוכנית מבצעת או את הפקודות מספר 1 או את הפקודות מספר 2.

הפקודות 3 מתבצעות תמיד, ללא קשר לתוצאת התנאי, והן פקודות המשך התכנות.

דוגמה 4.3
קלוט מן המשתמש מספר שאינו אפס, והדפס על המסך אם מספר זה חיובי או שלילי.
static void Main(string[] args)
{
  double n;
  Console.Write("Insert a non zero number: ");
  n = double.Parse(Console.ReadLine());
  if (n > 0)
  {
      Console.WriteLine("Positive");
  }
  else
  {
      Console.WriteLine("Negative");
  }
}
התחלההכנס מספר ← nהאם?n>0falseלאtrueכןהדפסחיוביהדפסשליליסוף

כמה תוצאות של הרצת התוכנית:

Microsoft Visual Studio Debug Console
Insert a non zero number: -8
Negative
Microsoft Visual Studio Debug Console
Insert a non zero number: 13.8
Positive

החשיבות של שימוש ב-else:

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

אפשר להשתמש בצורה זו בלבד, בלי צורך ב-else, אבל יש חשיבות לשימוש ב-else, ונלמד אותה על סמך הדוגמה הקודמת (דוגמה 4.3).

בדוגמה הקודמת (דוגמה 4.3) השתמשנו ב-else, אבל יכולנו לפתור אותה כך:

(בשימוש ב-if בלבד, בלי צורך ב-else)

static void Main(string[] args)
{
 double n;
 Console.WriteLine("insert a non zero number:");
 n = double.Parse(Console.ReadLine());
 if(n>0)
     Console.WriteLine("Positive");
 if(n<0)
     Console.WriteLine("Negative");
}

וזה יהיה במבנה הבא:

התחלההכנס מספר ← nהאם?n>0falseלאtrueכןהדפסחיוביהאם?n<0falseלאtrueכןהדפסשליליסוף

בתוכנית זו השתמשנו בשתי בדיקות, if(n>0) ו-if(n<0), כך שהמחשב בודק פעמיים גם אם אין בכך צורך. למשל, אם המספר שקלטנו חיובי, כלומר התנאי הראשון ( n>0 ) מתקיים והדפסנו Positive על המסך, אין צורך לבדוק אם n<0. אבל בגלל הפקודה if(n<0) התוכנית תבדוק פעם נוספת אם המספר שלילי.

ואילו אם נציב במקום if(n<0) את הפקודה else, אז אם התנאי הראשון מתקיים התוכנית תדלג ישירות על מה שבתוך ה-else, בלי צורך לבדוק פעם נוספת.

סיכום ההערות החשובות:

1. אם הפקודות המותנות לביצוע הן פקודה אחת בלבד בתוך if, אפשר לוותר על הסוגריים המסולסלים { }, וכך גם לגבי else.

דוגמה 4.4
if(n>0)
    Console.WriteLine("+");
else
    Console.WriteLine("-");
Console.WriteLine("The End");

פקודה מספר 2 היא פקודה מותנית ששייכת לתנאי if, והיא מתבצעת רק אם n>0.

פקודה מספר 4 היא גם פקודה מותנית ששייכת ל-else, והיא מתבצעת אם התנאי n>0 אינו מתקיים.

פקודה מספר 5 היא פקודה לא מותנית (המשך התכנות), והיא מתבצעת בכל מקרה.

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

3. נזכור תמיד שלא כדאי לשים ; מיד אחרי התנאי בלי שיהיו פקודות מותנות, כלומר לא כדאי לכתוב:

if ( תנאי ) ;

(3) המקרה השלישי (הצורה השלישית): תנאים מקוננים וחוזרים (if מקוננת):

if(   ){if(   ){}else{if(   ){}}}else{if(){}}
שאלה 4.1: כתוב תוכנית שקולטת מספר עשרוני ומדפיסה על המסך:
  • + אם המספר חיובי.
  • - אם המספר שלילי.
  • 0 אם המספר אפס.

פתרון:

static void Main(string[] args)
{
    double num;
    Console.Write("Insert a number: ");
    num = double.Parse(Console.ReadLine());
    if(num>0)
        Console.WriteLine("+");
    else if (num<0)
        Console.WriteLine("-");
    else
        Console.WriteLine("0");
}
התחלהקלוט מספרnumהאםnum>0falseלאtrueכןהדפס +האםnum<0falseלאtrueכןהדפס -הדפס 0סוף

4.2 תנאים מורכבים

בתוך הסוגריים של מבני הבקרה if מופיע התנאי. תנאי זה מורכב מהשוואה מן המקרים הבאים:

התנאי (השוואה)הסברדוגמה והערות
>אם גדולif (a>b) אם a גדול מ-b
<אם קטןif (a<b) אם a קטן מ-b
==אם שווהif (a==b) אם a שווה ל-b
!=אם לא שווהif (a!=b) אם a לא שווה ל-b
>=אם גדול או שווהif (a>=b) אם a גדול או שווה ל-b
<=אם קטן או שווהif (a<=b) אם a קטן או שווה ל-b

שים לב שהסימן == פירושו אם שווה (האם שווה?), ואילו הסימן = פירושו הצבה.

כדי שנוכל להבין את נושא התנאים המורכבים עלינו ללמוד על טיפוס נתונים חשוב בתנאים, והוא bool

טיפוס הנתונים bool:

כפי שלמדנו קודם על טיפוסי הנתונים int, double, char, יש טיפוס נתונים חשוב לפקודות התנאי, והוא bool, שיכול להכיל שני ערכים בלבד: true (אמת) ו-false (שקר).

משתנה מטיפוס bool מוכרז בדרך הבאה:

bool שם_משתנה ;

למשל, נרצה להגדיר משתנה בשם flag מטיפוס bool:

bool flag;

אפשר לתת למשתנה ערך התחלתי (אחד הערכים האפשריים, true או false) כך:

bool flag=true;
bool a=false;

קליטת נתון מן המשתמש לתוך משתנה מטיפוס bool נעשית בעזרת הפקודה הבאה:

שם המשתנה = bool.Parse(Console.ReadLine());

הנתון שאנו קולטים חייב להיות המילה true או המילה false.

הדפסת הערך של משתנה בשם a מטיפוס bool נעשית בעזרת Console.Write, כמקובל. למשל:

Console.WriteLine("the value of a is: {0}",a);

או בעזרת פעולת שרשור המחרוזות +:

Console.WriteLine("the value of a is: "+a);

הטיפוס של התנאי הוא bool, וערכו הוא true (אם התנאי מתקיים) או false (אם התנאי אינו מתקיים).

אפשר לכתוב if(true), ובמקרה זה התנאי מתקיים תמיד.

אפשר לכתוב if(false), ואז התנאי לעולם אינו מתקיים.

דוגמה 4.5
int a = 4, b = 5;
bool x;
x = a > b;
if(x)
    Console.WriteLine("A");

כאן הערך של x הוא false, ולכן לא יודפס דבר על המסך.

דוגמה 4.6
int a = 8, b = 5;
bool x;
x = a > b;
if(x)
    Console.WriteLine("A");

כאן הערך של x יהיה true, ולכן תודפס האות A על המסך.

אפשר לשלב פעולות השוואה ולוגיקה בעזרת הפעולות הלוגיות הבאות:

הפעולההסבר
&&וגם (and)
||או (or)
!היפוך לוגי (שלילה) (Not)
דוגמה 4.7
x <= 100 && x >= 0

זה יכול להיות ציון של תלמיד. כלומר:

0 ≤ x ≤ 100
דוגמה 4.8
מהם הערכים של a,b,c בסוף הקטע הבא?
bool a, b, c ;
bool x = true;
a = !x;
b = x && a;
c = b || a;
פתרון:
a = false;
b = false;
c = false;

טבלאות הפעולות הבוליאניות הלוגיות:

נסמן את הערך false באות f, ואת הערך true באות t.

טבלת && (And)
f && f = f
f && t = f
t && f = f
t && t = t
טבלת || (Or)
f || f = f
f || t = t
t || f = t
t || t = t
טבלת ! (Not)
!f = t
!t = f
שאלה 4.2: כתוב תוכנית שקולטת מן המשתמש מספר שלם המייצג ציון של תלמיד, ומבצעת את הדברים הבאים:
  • אם המספר אינו מתאים לציון של תלמיד (למשל גדול מ-100 או שלילי), על התוכנית להדפיס על המסך It`s not a mark!‎
  • אם הציון של התלמיד גדול או שווה ל-90, היא מדפיסה Excellent.
  • אם הציון של התלמיד בין 55 ל-89 כולל הקצוות, היא מדפיסה Pass.
  • אם הציון של התלמיד נמוך מ-55, היא מדפיסה Failed.

פתרון:

static void Main(string[] args)
{
    int mark;
    Console.Write("Insert a mark: ");
    mark = int.Parse(Console.ReadLine());
    if(mark>100 || mark<0)
        Console.WriteLine("It`s not a mark!");
    else
    {
        if (mark >= 90)
            Console.WriteLine("Excellent.");
        else
        {
            if (mark >= 55 && mark <= 89)
                Console.WriteLine("Pass.");
            else
                Console.WriteLine("Failed.");
        }
    }
}

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

Microsoft Visual Studio Debug Console
Insert a mark: 55
Pass.
Microsoft Visual Studio Debug Console
Insert a mark: 90
Excellent.
Microsoft Visual Studio Debug Console
Insert a mark: 48
Failed.
Microsoft Visual Studio Debug Console
Insert a mark: -4
It`s not a mark!

4.3 טבלת מעקב עם פקודות תנאי

טבלת המעקב מורכבת משורות ומעמודות בדיוק כפי שלמדנו קודם, אבל עלינו להוסיף עמודה לתנאי בין עמודות הטבלה ולמלא אותה בערך של ביטוי התנאי (true או false) כשאנו מגיעים לפקודת התנאי ומבצעים אותה. כמובן, תוצאת ביטוי התנאי תשפיע על טבלת המעקב, שכן לפי הערך של ביטוי התנאי ייקבע אילו פקודות התוכנית צריכה לבצע ועל אילו פקודות היא תדלג (לא תבצע אותן).

שאלה 4.3: כתוב תוכנית שקולטת מספר שלם ומדפיסה על המסך אם מספר זה זוגי או אי-זוגי. אחר כך כתוב טבלת מעקב עבור הקלט 207.
מספור פקודות התוכנית בטבלת המעקב: פקודה 1 היא int num;‎ ופקודה 13 היא הסוגר האחרון.
static void Main(string[] args)
{
    int num;
    Console.Write("Insert a number: ");
    num = int.Parse(Console.ReadLine());
    if(num==0)
        Console.WriteLine("Even.");
    else
    {
        if (num%2 == 0)
            Console.WriteLine("Even.");
        else
            Console.WriteLine("Odd.");
    }
}
מספר הפקודהnumnum == 0num%2 ==0המסך
1
2Insert a number: 207
3207
4207false
6207
7207
8207false
10207
11207Odd.
12207
13207
שאלה 4.4: כתוב תוכנית שקולטת 3 מספרים מן המשתמש, ועל התוכנית להדפיס את הדברים הבאים:
  • They are equal – אם שלושת המספרים שווים.
  • Two of them are equal – אם רק שניים מהם שווים.
  • They are different – אם שלושת המספרים שונים.

פתרון:

static void Main(string[] args)
{
    int num1, num2, num3;
    Console.Write("Insert the first number: ");
    num1 = int.Parse(Console.ReadLine());
    Console.Write("Insert the second number: ");
    num2 = int.Parse(Console.ReadLine());
    Console.Write("Insert the third number: ");
    num3 = int.Parse(Console.ReadLine());

    if(num1==num2 && num2==num3)
        Console.WriteLine("They are equal");
    else
    {
        if (num1 == num2 || num2 == num3 || num1 == num3)
            Console.WriteLine("Two of them are equal.");
        else
            Console.WriteLine("They are different numbers");
    }
}

נשים לב שכאן איננו יכולים לוותר על else בקלות, כי התנאים יהיו מורכבים יותר.

ראה גם שב-if הראשונה הסתפקנו בתנאי מורכב משני איברים בלבד, שביניהם הקשר "וגם" And, ולא משלושה איברים, כלומר אין צורך לכתוב: num1==num2 && num2==num3 && num1==num3

כמה מתוצאות הרצת התוכנית:

Microsoft Visual Studio Debug Console
Insert the first number: 91
Insert the second number: 91
Insert the third number: 91
They are equal
Microsoft Visual Studio Debug Console
Insert the first number: -4
Insert the second number: 16
Insert the third number: 0
They are different numbers
Microsoft Visual Studio Debug Console
Insert the first number: -8
Insert the second number: 7
Insert the third number: -8
Two of them are equal.
המאם ותד (أ. همام وتد) — כל זכויות הספר שמורות למחבר. הספר נכתב בערבית, ותרגם אותו לעברית פהד גאנם. המהדורה העברית מתפרסמת באישור המחבר, עם תיקונים שאישר. ליצירת קשר עם המחבר: hammam4112@gmail.com