NET/משפטי בקרה: הבדלים בין גרסאות בדף

תוכן שנמחק תוכן שנוסף
צחי (שיחה | תרומות)
פקודת goto.
צחי (שיחה | תרומות)
משהו מוזר קרה כאן
שורה 1:
{{NET}}
==if==
משפט if הוא משפט תנאי. הפקודה שבתוך המשפט תתבצע אם ורק אם התנאי מתקיים.
 
במקרה של פקודה אחת, התחביר הוא כדלהלן:
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (''condition'')<br>
&nbsp;&nbsp;''statement''}}
''condition'' הוא ביטוי בוליאני, כלומר ביטוי שערכו true או false.
 
''statement'' היא פקודה לביצוע.
 
לדוגמה:
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (x > 5)<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|x is larger than 5|String}});<br>}}
המשפט x is larger than 5 יודפס רק אם ערך המשתנה x גדול מ-5.
 
במקרה של יותר מפקודה אחת, נשתמש בסוגריים מסולסלים כדי לסמן בלוק פקודות:
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (''condition'') {
&nbsp;&nbsp;statement1<br>
&nbsp;&nbsp;statement2<br>
&nbsp;&nbsp;statement3<br>
&nbsp;&nbsp;...<br>
}
}}
לדוגמה
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (x > 5) {<br>
&nbsp;&nbsp;{{NET/Code|int|Keyword}} y = x + 2;<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine(y);
}
}}
===else===
בנוסף לציון ההוראות שיבוצעו אם ערך הביטוי הבוליאני של המשפט יהיה true, ניתן לציין גם מה יבוצע אם ערכו יהיה false, וזאת באמצעות בלוק else:
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (''condition'')<br>
&nbsp;&nbsp;''statement1''<br>
{{NET/Code|else|Keyword}}<br>
&nbsp;&nbsp;''statement2''
}}
במקרה זה, אם ערך ''condition'' הוא true, יבוצע ''statement1''. אם ערכו false, יבוצע ''statement2''. גם כאן, ''statement2'' יכול להיות בלוק של הוראות תחומות בסוגריים מסולסלות.
 
בעת שימוש במשפטי תנאי מקוננים (כלומר, ''statement1'' הוא בעצמו משפט if), מומלץ מאוד להשתמש בסוגריים מסולסלות גם עבור הוראה אחת, כדי למנוע בלבול בשיוך ה-else ל-if הנכון. נסתכל בדוגמה הבאה:
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (x < 5)<br>
&nbsp;&nbsp;{{NET/Code|if|Keyword}} (y < 3)<br>
&nbsp;&nbsp;&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|x < 5 and y < 3|String}});<br>
{{NET/Code|else|Keyword}}<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|x >&#61; 5|String}});
}}
קל לטעות ולחשוב שמשפט ה-else שייך ל-if החיצוני, אך מכיוון שהוא בא מייד לאחר ה-if הפנימי, הוא שייך לו. שימוש בסוגריים יבהיר את השייכות:
{{NET/CodeBlock|cs=
{{NET/Code|if|Keyword}} (x < 5) {<br>
&nbsp;&nbsp;{{NET/Code|if|Keyword}} (y < 3)<br>
&nbsp;&nbsp;&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|x < 5 and y < 5|String}});<br>
}<br>
{{NET/Code|else|Keyword}} {<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|x >&#61; 5|String}});<br>
}<br>
}}
 
===אופרטור תנאי===
לעתים נרצה לקבל ערך מסויים כאשר ערך ביטוי בוליאני מסויים הוא true, וערך אחר אם ערכו false.
 
==switch==
משפט switch (ב־VB:&rlm; Select Case) מאפשר לבדוק מספר ערכים אפשריים עבור ביטוי, ולבצע הוראה אחרת בכל מקרה (או לקבוע שאותה הוראה תבוצע עבור מספר ערכים מתוך האפשרויות). המשפט יכול גם להגדיר מה לבצע במקרה שערך הביטוי אינו שווה לאף אחת מהאפשרויות. תחביר המשפט הוא כדלהלן:
{{NET/CodeBlock|cs=
{{NET/Code|switch|Keyword}} (''expression'') {<br>
{{NET/Code|case|Keyword}} val1:<br>
&nbsp;&nbsp;''statement1<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
{{NET/Code|case|Keyword}} val2:<br>
&nbsp;&nbsp;''statement2<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
{{NET/Code|case|Keyword}} val3:<br>
&nbsp;&nbsp;''statement2<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
...<br>
{{NET/Code|case|Keyword}} val7:<br>
{{NET/Code|case|Keyword}} val8:<br>
&nbsp;&nbsp;''statement7<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
{{NET/Code|default|Keyword}}:<br>
&nbsp;&nbsp;''default_statement''<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
}
}}
''expression'' - ביטוי בעל ערך מספרי (מספר שלם או נקודה צפה מכל סוג) או [[NET/מחרוזות|מחרוזת]].
 
''statement1-7'' - הוראות שיבוצעו במקרה שערך ''expression הוא ''val1-8''.
 
''default_statement'' - הוראה שתבוצע אם ערך הביטוי אינו אחת מהאפשרויות שהוזכרו.
 
שים לב שיש לציין את המילה השמורה break בסוף כל אפשרות, כדי למנוע אפשרות של מעבר הביצוע לאפשרות הבאה. השמטת המילה מהווה שגיאת תחביר ותכשיל את תהליך ההידור. האפשרות היחידה בה ניתן להשמיט אותה היא במקרה כמו val7 ו-val8. במקרה זה, statement7 תבוצע אם ערך הביטוי הוא val7 או val8. בצורת כתיב זו, אין לציין הוראה כלשהי בין <code dir="ltr">case val7:</code> ל-<code dir="ltr">case val8:</code>.
 
הערכים הנבדקים צריכים להיות קבועים ומפורשים. לא ניתן לציין ביטויים או משתנים בערכי val השונים.
 
דוגמה:
{{NET/CodeBlock|cs=
{{NET/Code|Console|Class}}.WriteLine({{NET/Code|Type a number:|String}});<br>
{{NET/Code|String|Class}} str = {{NET/Code|Console|Class}}.ReadLine();<br>
{{NET/Code|switch|Keyword}} (str) {<br>
{{NET/Code|case|Keyword}} {{NET/Code|1|String}}:<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|You typed 1|String}});<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
{{NET/Code|case|Keyword}} {{NET/Code|2|String}}:<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|You typed 2|String}});<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
{{NET/Code|default|Keyword}}:<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|You typed something else|String}});<br>
&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
}
}}
 
==while==
while מגדיר לולאה המתבצעת כל עוד מתקיים תנאי בוליאני. בתוך הלולאה יש אפס או יותר פקודות, המתבצעות בכל איטרציה של הלולאה.
תחביר:
{{NET/CodeBlock|cs=
{{NET/Code|while|Keyword}} (''condition'')<br>
&nbsp;&nbsp;''statement''
}}
''condition'' ביטוי בוליאני שערכו true או false
 
''statement'' פקודה לביצוע. פקודה זו תתבצע כל עוד ערך condition הוא true.
 
סדר הביצוע של הלולאה הוא כדלהלן:
# הערך את הביטוי condition
# אם ערך condition הוא true, בצע את statement וחזור ל-1. אחרת, המשך לפקודה שאחרי משפט ה-while.
 
לדוגמה
{{NET/CodeBlock|cs=
{{NET/Code|while|Keyword}} (x < 5)<br>
&nbsp;&nbsp;x++;
}}
 
''statement'' יכול להיות גם ריק. במקרה זה ביצוע התוכנית למעשה יעצר עד שהתנאי condition יתקיים. למעשה, התנאי ייבדק שוב ושוב, עד שערכו יהיה true. התחביר במקרה זה יהיה
{{NET/CodeBlock|cs={{NET/Code|while|Keyword}} (''condition'');}}
 
במידה ויש יותר מפקודה אחת לביצוע, נכליל את הפקודות בסוגריים מסולסלות:
{{NET/CodeBlock|cs=
{{NET/Code|while|Keyword}} (''condition'') {<br>
&nbsp;&nbsp;statement1<br>
&nbsp;&nbsp;statement2<br>
&nbsp;&nbsp;statement3<br>
&nbsp;&nbsp;...<br>
}
}}
 
==do ... while==
לולאת do-while מבוצעת לפחות פעם אחת, לפני שהתנאי נבדק. לולאה זו טובה במקרים בהם רוצים לבצע פקודה מסויימת לפחות פעם אחת, בלי קשר להתקיימות התנאי. התחביר שלה הוא כדלהלן:
{{NET/CodeBlock|cs=
{{NET/Code|do|Keyword}} {
&nbsp;&nbsp;statement1<br>
&nbsp;&nbsp;statement2<br>
&nbsp;&nbsp;statement3<br>
&nbsp;&nbsp;...<br>
} {{NET/Code|while|Keyword}} (''condition'');
|vb=
{{NET/Code|Do|Keyword}}<br>
&nbsp;&nbsp;statement1<br>
&nbsp;&nbsp;statement2<br>
&nbsp;&nbsp;statement3<br>
&nbsp;&nbsp;...<br>
{{NET/Code|Loop While|Keyword}} ''condition''
}}
הלולאה מבוצעת בסדר הבא:
# בצע את ההוראות בלולאה
# בדוק את ערך הביטוי הבוליאני ''condition''. אם ערכו true, חזור ל-1. אחרת, צא והמשך לאחר הלולאה.
 
בשפת Visual Basic יש צורה נוספת ללולאה זו. בצורה זו, הלולאה מבוצעת כל עוד התנאי condition '''אינו''' מתקיים. מבחינה לוגית, הדבר שקול לביצוע הלולאה כל עוד שלילת התנאי היא true. הצורה נכתבת כך:
{{NET/CodeBlock|vb=
{{NET/Code|Do|Keyword}}<br>
&nbsp;&nbsp;statement1<br>
&nbsp;&nbsp;statement2<br>
&nbsp;&nbsp;statement3<br>
&nbsp;&nbsp;...<br>
{{NET/Code|Loop Unless|Keyword}} ''condition''<br>
}}
והיא שקולה לצורה
{{NET/CodeBlock|vb=
{{NET/Code|Do|Keyword}}<br>
&nbsp;&nbsp;statement1<br>
&nbsp;&nbsp;statement2<br>
&nbsp;&nbsp;statement3<br>
&nbsp;&nbsp;...<br>
{{NET/Code|Loop While Not|Keyword}} ''condition''<br>
}}
אם ערך condition הוא false, שלילתו היא true, ולכן הלולאה ממשיכה להתבצע.
 
==for==
בצורת השימוש הבסיסית, לולאת for מיועדת לביצוע הוראה או קבוצת הוראות מספר קבוע מראש של פעמים. התחביר שלה הוא כדלהלן.
{{NET/CodeBlock|cs=
{{NET/Code|for|Keyword}} (''init''; ''condition''; ''update'')<br>
&nbsp;&nbsp;''statement''}}
''init'' - איתחול הלולאה
 
''condition'' - ביטוי בוליאני. הלולאה תתבצע אם ורק אם ערך ביטוי זה true
 
''update'' - הוראה לעדכון
 
''statement'' - הוראה לביצוע
 
כמו בלולאות האחרות, גם כאן, כאשר יש יותר מהוראה אחת לביצוע בכל מחזור של הלולאה, הן יקובצו בבלוק:
{{NET/CodeBlock|cs=
{{NET/Code|for|Keyword}} (''init''; ''condition''; ''update'') {<br>
&nbsp;&nbsp;''statement1''<br>
&nbsp;&nbsp;''statement2''<br>
&nbsp;&nbsp;''statement3''<br>
&nbsp;&nbsp;...
}
}}
הלולאה תבוצע בסדר הבא:
# בצע את ''init''
# אם ערך ''condition'' הוא true, בצע את ''statement''. אחרת, המשך לאחר הלולאה.
# בצע את ''update''
# חזור לצעד 2.
לדוגמה:
{{NET/CodeBlock|cs=
{{NET/Code|for|Keyword}} ({{NET/Code|int|Keyword}} i = 0; i < 5; i++) {<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine({{NET/Code|i &#61; |String}} + i);<br>
}
}}
בדוגמה זו, חלק ה-''init'' מאתחל משתנה חדש מסוג <code>int</code> עם הערך 0. משתנה זה יהיה ידוע רק בתוך הבלוק של משפט ה-if. בתחילה הביטוי i < 5 הוא true, ולכן מודפסת המחרוזת
<source lang="text">i = 0</source>
לאחר מכן ערך i עולה באחד בעזרת האופרטור ++, וערך התנאי נבדק שוב. הוא יהיה true עד שערך i יהיה 5, אז יופסק ביצוע הלולאה והתוכנית תמשיך להוראה הראשונה שאחריה. הפלט המלא יהיה
<source lang="text">
i = 0
i = 1
i = 2
i = 3
i = 4
</source>
עם זאת, אין חובה להשתמש בחלקים השונים של המשפט דווקא עם מספרים. ניתן לבצע כל הוראת השמה בחלק ה-''init'', לבצע כל הוראה בחלק ה-''update'', ולבדוק כל ביטוי בוליאני בחלק ה-''condition'' בלי קשר לחלקים האחרים. בנוסף, בחלק ה-''update'' ניתן לבצע מספר הוראות, מופרדות בפסיקים. כל החלקים הם אופציונליים, וניתן לוותר על כל אחד מהם ועל כולם גם יחד (אך אין לוותר על סימני הנקודה-פסיק). לדוגמה:
{{NET/CodeBlock|cs=
{{NET/Code|for|Keyword}} (;;) {
{{NET/Code|statement|C#Comment}}
}
}}
לולאה זו תתבצע אינסוף פעמים.
 
דוגמה:
{{NET/CodeBlock|cs=
{{NET/Code|String|Class}}[] strArr = {{{NET/Code|one|String}}, {{NET/Code|two|String}}, {{NET/Code|three|String}}};<br>
{{NET/Code|int|Keyword}} i = 0;<br>
{{NET/Code|String|Class}} str = strArr[1];<br>
{{NET/Code|for|Keyword}} ({{NET/Code|String|Class}} s = strArr[i]; {{NET/Code|Object|Class}}.ReferenceEquals(str, strArr); s = strArr[i]) {<br>
&nbsp;&nbsp;i++;<br>
}
}}
 
==foreach==
לולאת foreach (ב-VB: &rlm;For Each) מיועדת למעבר על כל האיברים הנמצאים במבנה נתונים המממש את הממשק [[NET/IEumerable|IEnumerable]]. בכל איטרציה של הלולאה מקבלים גישה לאיבר נוסף במבנה הנתונים, וניתן לקרוא אותו, לבצע עליו פעולות, וכד'. לא ניתן להוסיף או למחוק איברים ממבנה הנתונים בתוך הלולאה, משום שהדבר יפגע בלולאה, ולא יאפשר לדעת מה האיבר הבא. תחביר הלולאה הוא כדלהלן:
{{NET/CodeBlock|cs=
{{NET/Code|foreach|Keyword}} (''typename'' t {{NET/Code|in|Keyword}} ''collection'') {<br>
&nbsp;&nbsp;''statement''
}
}}
''typename'' - שם המחלקה של האיברים במבנה הנתונים
 
''collection'' - ביטוי המחזיר ערך מסוג מחלקה המממשת את '''IEnumerable'''. מומלץ לשים במקום זה משתנה ולא קריאה לשגרה או מאפיין, משום שהקריאה של הביטוי תבוצע בכל מחזור של הלולאה, ותבזבז זמן עיבוד על ביצוע אותה פעולה שוב ושוב.
 
''statement'' - הוראה לביצוע
 
כאשר <code>t</code> הוא משתנה מסוג ''typename'' המוכר בתוך הלולאה, ומקבל בכל פעם את האיבר הבא במבנה הנתונים. המילה השמורה <code>in</code> היא חלק בלתי נפרד מתחביר הלולאה, ואין להשמיט אותה.
 
ניקח לדוגמה מבנה נתונים מסוג מערך. [[NET/מערכים|כזכור]], כל מערך הוא אובייקט של המחלקה [[NET/Array|Array]], המממשת את IEnumerable. נסתכל על קטע הקוד הבא:
{{NET/CodeBlock|cs=
{{NET/Code|String|Class}} strArr[] = {{NET/Code|new|Keyword}} {{NET/Code|String|Class}}[] {{{NET/Code|one|String}}, {{NET/Code|two|String}}, {{NET/Code|three|String}}};<br>
{{NET/Code|foreach|Keyword}} ({{NET/Code|String|Class}} s {{NET/Code|in|Keyword}} strArr) {<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine(s);<br>
}
}}
קוד זה יקבל בכל איטרציה את ערך המחרוזת הבאה במערך אל המשתנה <code>s</code>, וידפיס אותו.
 
יש לציין שלולאת foreach מהירה בהרבה מלולאת [[#for|for]], ולכן במקומות שבהם ניתן להשתמש בה, עדיף לעשות זאת, במיוחד כאשר מטפלים במבני נתונים המחזיקים מאות איברים.
 
למען האמת, לולאת foreach אינה מוסיפה תכונה חדשה לשפה. תפקידה הוא רק להקל על המתכנת, הן בכתיבת קוד והן בקריאתו. הלולאה למעשה מהווה קיצור דרך לכתיבת קוד מפורש, שיקרא לשגרות המוגדרות בממשק '''IEnumerable''', ו־[[NET/IEnumerator|IEnumerator]] המוחזר מהשגרה [[NET/IEnumerable/GetEnumerator|GetEnumerator]] שלו. הדוגמה הקודמת שקולה למעשה לכתיבת הקוד הבא:
{{NET/CodeBlock|cs=
{{NET/Code|String|Class}} strArr[] = {{NET/Code|new|Keyword}} {{NET/Code|String|Class}}[] {{{NET/Code|one|String}}, {{NET/Code|two|String}}, {{NET/Code|three|String}}};<br>
{{NET/Code|IEnumerator|Class}} myEnum = strArr.GetEnumerator();<br>
{{NET/Code|while|Keyword}} (myEnum.MoveNext()) {<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine(myEnum.Current);<br>
}
}}
 
==break ו-continue==
המילים השמורות <code>continue</code> (ב־VB:&rlm; <code>Continue For</code> או <code>Continue While</code>) ו-<code>break</code> מאפשרות שליטה רבה יותר על לולאות for ו-while, על ידי שינוי סדר הפעולה של הלולאה.
===break===
המילה השמורה break מפסיקה לאלתר את פעולת הלולאה, ומעבירה את השליטה להוראה הראשונה שאחריה. לדוגמה:
{{NET/CodeBlock|cs=
{{NET/Code|for|Keyword}} ({{NET/Code|int|Keyword}} i = 1; i <= 100; i++) {<br>
&nbsp;&nbsp;{{NET/Code|if|Keyword}} (i == 5) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;{{NET/Code|break|Keyword}};<br>
&nbsp;&nbsp;}<br>
&nbsp;&nbsp;{{NET/Code|Console|Class}}.WriteLine(i);<br>
}
}}
בדוגמה זו, הלולאה תופסק לאחר חמישה צעדים, כאשר ערך <code>i</code> יהיה 5.
 
המילה break משמשת כאמור גם במבנה הבקרה [[#switch|switch]].
===continue===
המילה השמורה <code>continue</code> מפסיקה את האיטרציה הנוכחית של הלולאה, וממשיכה לאיטרציה הבאה (תוך בדיקת ערך הביטוי הבוליאני בלולאות המתאימות). אם ניקח את הדוגמה הקודמת,
שורה 22 ⟵ 324:
</source>
שים לב שדילגנו על מספר 5. כאשר <code>i</code> היה שווה 5, דילגנו לאיטרציה הבאה ולא ביצענו את ההדפסה.
 
==goto==
ההוראה <code>goto</code> מעבירה את המשך ביצוע התוכנית לשורה המצויינת בעזרת תווית באותה שגרה, בלי קשר למיקום או המבנה התחבירי בו היא מופיעה. מסיבה זו רצוי '''מאוד''' לא להשתמש במילה זו לעולם. שימוש בפקודת <code>goto</code> שובר את הלוגיקה של התוכנית ומקשה על ניפוי שגיאות, ונחשב ככלל כהרגל תכנותי רע. לצורך שלמות המידע, נביא את תחביר הפקודה.
{{NET/CodeBlock|cs=
{{NET/Code|goto|Keyword}} my_label;<br/>