Menu

לולאת while ב-Java: תחביר, do-while וטעויות נפוצות

לולאת while ב-Java בהסבר מלא: while שבודקת את התנאי קודם, do-while שרצה לפחות פעם אחת, קריאת קלט עד ערך זקיף, break ו-continue, ואיך נמנעים מלולאות אינסופיות.

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

כשאין מונה

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

לולאת while בודקת את התנאי שלה לפני כל מעבר, כולל הראשון. אם התנאי שקרי כבר בהתחלה, הגוף לא רץ בכלל.

התנאי count > 0 נבדק קודם; אם הוא אמת, הגוף רץ; ואז חוזרים ובודקים שוב. השורה count-- היא מה שבסופו של דבר הופך את התנאי לשקרי. הסירו אותה והלולאה תרוץ לנצח.

האנטומיה של לולאת while

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

int i = 0;              // אתחול - לפני הלולאה
while (i < 5) {         // תנאי - נבדק בכל מעבר
    System.out.println(i);
    i++;                // עדכון - אתם צריכים לזכור אותו בעצמכם
}

החלק האחרון הוא המלכודת. בלולאת for העדכון יושב ממש ליד התנאי, ולכן קשה לשכוח אותו. בלולאת while הוא עוד הוראה בגוף, והבאג הנפוץ ביותר הוא להשמיט אותו ולתקוע את התוכנית.

do-while: להריץ את הגוף לפחות פעם אחת

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

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

ההבדל מ-while רגילה בולט בבירור כשהתנאי שקרי כבר מההתחלה:

רק do-while body מודפס. לולאת ה-while מדלגת לגמרי על הגוף שלה כי x < 5 היה שקרי לפני הבדיקה הראשונה.

לולאה עד ערך זקיף

שימוש קלאסי ב-while הוא קריאה עד ערך "עצירה" מיוחד: זקיף (sentinel). אין כאן מונה; פשוט ממשיכים עד שהנתונים אומרים לעצור:

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

break ו-continue בלולאות while

break ו-continue עובדות כאן בדיוק כמו בלולאת for. break יוצאת מהלולאה מיד; continue קופצת ישר חזרה לבדיקת התנאי ומדלגת על שאר המעבר הנוכחי:

זה מדפיס 1 3 5 7 9. ה-while (true) בכוונה אף פעם לא עוצרת מעצמה: ה-break היא היציאה היחידה. היזהרו עם continue בלולאת while: מכיוון שהעדכון הוא חלק מהגוף, קפיצה חזרה להתחלה עם continue לפני שקידמתם את המונה היא דרך שקטה לתקוע את הלולאה. בדוגמה למעלה n++ רץ קודם, ולכן זה בטוח.

היזהרו מלולאות אינסופיות

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

int i = 0;
while (i < 5) {
    System.out.println(i);   // i לא משתנה אף פעם -> רצה לנצח
}
int i = 0;
while (i != 10) {
    i += 3;   // 0, 3, 6, 9, 12... מדלגת ישר מעל 10 -> רצה לנצח
}

הראשונה נתקעת כי i לא מתעדכן אף פעם. השנייה נתקעת כי המונה מדלג מעל הערך המדויק שהתנאי מחפש: העדיפו < או <= על פני != כשייתכן שהצעד לא ינחת בדיוק. while (true) היא בסדר אם יש בה break מובטח; אחת שנוצרה בטעות היא פשוט באג.

הבא בתור: לולאת for-each

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

שאלות נפוצות

מה ההבדל בין while ל-do-while ב-Java?

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

מתי כדאי להשתמש בלולאת while במקום בלולאת for ב-Java?

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

איך עוצרים לולאת while אינסופית ב-Java?

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

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

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

להתחיל