מה זה?

עד עכשיו כל שורת קוד רצה בדיוק פעם אחת, מלמעלה למטה. אבל תוכנית אמיתית צריכה “להחליט” — האם המשתמש בגיר? האם הסיסמה נכונה? — ולפעמים “לחזור על עצמה” — הדפסת כל הפריטים ברשימה, ולא רק את הראשון. תנאים (if/else/switch) פותרים את ה"החלטה"; לולאות (for/while/foreach) פותרות את ה"חזרה".

מילות מפתח שחשוב לזכור

• if / else if / else — מריצים קטע קוד רק אם תנאי מתקיים (או האלטרנטיבה שלו)

• switch — בוחר בין כמה מקרים אפשריים לפי ערך אחד, נוח כשיש הרבה חלופות לאותו משתנה

• for — לולאה עם מספר איטרציות ידוע מראש (למשל “10 פעמים”)

• while — לולאה שרצה כל עוד תנאי מתקיים, גם אם לא ידוע מראש כמה פעמים

• foreach — לולאה שעוברת על כל איבר באוסף (מערך, List וכו’) בלי לנהל אינדקס ידנית

int age = 20;
if (age >= 18)
{
    Console.WriteLine("Adult");
}
else
{
    Console.WriteLine("Minor");
}
// switch — cleaner than multiple if/else when there are many cases for the same variable
int day = 3;
string dayName = day switch
{
    1 => "Sunday",
    2 => "Monday",
    3 => "Tuesday",
    _ => "Unknown"   // default
};
Console.WriteLine(dayName);
// for — when you know in advance how many times to repeat
for (int i = 1; i <= 5; i++)
{
    Console.WriteLine($"Iteration {i}");
}

// while — when you don't know in advance, only the stopping condition
int attempts = 0;
while (attempts < 3)
{
    Console.WriteLine($"Attempt {attempts + 1}");
    attempts++;
}
  flowchart TD
    A["Start"] --> B{"age >= 18?"}
    B -->|"Yes"| C["Print: Adult"]
    B -->|"No"| D["Print: Minor"]

הסבר עיקרי

מתי switch עדיף על if/else if שרשרת — כש-אותו משתנה נבדק מול כמה ערכים אפשריים (כמו יום בשבוע, קוד סטטוס), switch קריא בהרבה מרצף if (day == 1) ... else if (day == 2) .... אם התנאים מורכבים או בודקים משתנים שונים כל פעם, if/else עדיין הבחירה הנכונה.

for מול while — הכלל המעשי: אם ידוע מראש בדיוק כמה פעמים לחזור (למשל “על כל איבר במערך”), for הוא הבחירה הטבעית — יש בו מונה מובנה. אם העצירה תלויה בתנאי שיכול להשתנות באמצע (כמו “עד שהמשתמש מקליד ’exit’”), while מתאים יותר כי אין מספר איטרציות ידוע מראש.

foreach הוא for בלי ניהול אינדקס — כשרוצים פשוט “לעבור על כל איבר” באוסף, foreach (var item in collection) חוסך את הסיכון לטעויות off-by-one (כמו i <= length במקום i < length) שקורות בקלות בלולאת for עם אינדקס ידני.

יתרונות

תנאים ולולאות הופכים תוכנית מרצף קשיח ל"חכמה" — יכולה להתאים את עצמה לנתונים; switch עם ביטוי (switch expression) קצר וקריא במיוחד לבחירה בין הרבה חלופות; foreach מונע שגיאות אינדקס נפוצות בלולאות ידניות.

חסרונות

קינון עמוק מדי של if בתוך if בתוך if הופך קוד לקשה לקריאה (“Arrow Code”); לולאת while עם תנאי שגוי עלולה ליצור לולאה אינסופית שתוקעת את התוכנית.

נקודות חשובות

• switch מתאים לבדיקת אותו משתנה מול כמה ערכים; if/else לתנאים כלליים יותר

• for — מספר איטרציות ידוע מראש; while — תלוי בתנאי דינמי

• foreach עדיף על for עם אינדקס כשפשוט עוברים על כל איברי אוסף

• לולאת while (true) בלי תנאי עצירה פנימי (break) יוצרת לולאה אינסופית

טעויות נפוצות

• קינון if עמוק מדי במקום לפרק ללוגיקה ברורה יותר או להשתמש ב-switch

• שכחת i++ בלולאת while — יוצרת לולאה אינסופית בטעות

• שימוש ב-for (int i = 0; i <= array.Length; i++) (עם <= במקום <) — גורם ל-IndexOutOfRangeException

סיכום

if/else/switch מאפשרים לתוכנית “להחליט” בין אפשרויות; for/while/foreach מאפשרים לה “לחזור” על פעולה. הבחירה הנכונה בין for ל-while תלויה בשאלה אם מספר האיטרציות ידוע מראש, ו-foreach הוא הבחירה הבטוחה והקריאה ביותר כשפשוט עוברים על כל איברי אוסף.

דוקומנטציה רשמית

Microsoft Learn — Selection statements (if, switch)

Microsoft Learn — Iteration statements (for, while, foreach)


תרגילים

תרגיל 1 — בדיקת זוגי/אי-זוגי

המשימה: כתבו לולאת for שעוברת על המספרים 1 עד 20, ומדפיסה ליד כל מספר האם הוא זוגי או אי-זוגי (% לבדיקת שארית).

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

תרגיל 2 — switch על ציון

המשימה: כתבו switch expression שמקבל ציון מספרי (0-100) ומחזיר אות: 90+ → “A”, 80-89 → “B”, 70-79 → “C”, מתחת → “F”.

בדיקה: קלט 95 מחזיר "A"; קלט 65 מחזיר "F".


פרויקט מסכם

המשימה: כתבו תוכנית “ניחוש מספר” — התוכנית “חושבת” על מספר קבוע (למשל 42), והמשתמש מנסה לנחש אותו בלולאה עד שהוא צודק.

דרישות:

  1. לולאת while שרצה עד שהניחוש נכון
  2. בכל ניסיון — קלט מהמשתמש (Console.ReadLine + int.TryParse), והדפסת רמז: “גבוה מדי” / “נמוך מדי” / “נכון!”
  3. ספירת מספר הניסיונות עם משתנה מונה, והדפסתה בסיום

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

מה בפרק הבא

בפרק הבא — מערכים מול List<T>: איך שומרים כמה ערכים יחד, וההבדל בין אוסף בגודל קבוע (מערך) לאוסף שיכול לגדול ולהתכווץ (List<T>).