באמצעות משפט )א ( הסתעפויות : 3פרק if

‫‪25/04/2010‬‬
‫פרק ‪ :3‬הסתעפויות )א( באמצעות משפט ‪if‬‬
‫פרק זה יציג בעיקר את ‪ 3‬המושגי העיקריי הבאי‪ :‬הסתעפות )התפצלות( של‬
‫תוכנית בעזרת משפט ‪ ;if‬ביטוי לִ ינִ י‪ ,‬העשוי לקבל ער( "שקר" )=‪ (0‬או "אמת"‬
‫)=‪ ;(1‬ואוֶֹ ָרטוֹר לִ ינִ י )לוגי(‪ ,‬כמו‪ :‬ג )&&(‪ ,‬או )||(‪ ,‬ו לא )!(‪ .‬משפט ‪ if‬הינו‬
‫דוגמא למשפט בקרה‪ .‬משפטי בקרה )‪ (control statements‬בשפת תכנות תפקיד‬
‫הוא לשנות את רצ‪ ,‬התוכנית של שורה אחר שורה‪ ,‬כדי לאפשר‪ :‬דילוג על שורות‪,‬‬
‫הסתעפות לפי החלטת התוכנית‪ ,‬חזרה על מספר שורות ע או ללא תנאי ועוד‪.‬‬
‫מושגי נוספי שידונו בפרק הינ‪ :‬קבועי‪ ,‬ביטויי מורכבי‪ ,‬בלוקי‪ ,‬סדר‬
‫קדימות של אופרטורי‪ ,‬סינו קלט )בעזרת ‪ (if‬וניפוי טעויות )‪.(debugging‬‬
‫)א(‪ .‬התחביר של משפט ‪if‬‬
‫הסתעפות )התפצלות( של התוכנית מתקבלת‪ ,‬כאשר ברגע מסוי התוכנית תבצע או‬
‫משפט אחד או משפט שני‪ ,‬של משפט ‪ .if‬התחביר של משפט ‪(if statement) if‬‬
‫מאפשר ‪ 2‬תבניות המוצגות במסגרות למטה‪ .‬האפשרות במסגרת הראשונה‪ ,‬של‬
‫תבנית חלקית‪ ,‬משמיטה את האופציה של משפט ‪ .else‬האפשרות השניה‪,‬‬
‫במסגרת התחתונה‪ ,‬מתארת תבנית מלאה של משפט ‪.if‬‬
‫;>משפט< )>תנאי<( ‪if‬‬
‫)>תנאי<( ‪if‬‬
‫;>משפט ‪<1‬‬
‫‪else‬‬
‫;>משפט ‪<2‬‬
‫ה>תנאי< של משפט ‪ if‬הוא ביטוי לִ ינִ י )‪ (boolean expression‬המוק‪ ,‬בסוגריי‬
‫בגלל ‪ ,if‬ושיש לו ער" לִ ינִ י )‪ .(boolean value‬ער( בוליאני הוא או "שקר" שהוא‬
‫‪ ,0‬או "אמת" שהוא כל ער( אשר שונה מאפס ובפרט ‪ .1‬לדוגמא‪ ,‬תנאי מעבר של‬
‫מבח הוא‪ ,‬הא מתקיי )‪ .(grade >= 60‬א התנאי מתקיי )אמת( אז יבוצע‬
‫>משפט ‪ <1‬וא התנאי איננו מתקיי )שקר( אז יבוצע >משפט ‪ .<2‬כל >משפט<‬
‫בשפה עשוי להיות או משפט פשוט‪ ,‬או משפט מורכב )למשל‪ ,‬בלוק של משפטי(‪,‬‬
‫או משפט ריק‪ .‬א >משפט ‪ <2‬ריק אז אי לכתוב את משפט ‪ ,else‬כמו בתבנית‬
‫במסגרת העליונה וכמו בתוכנית בהמש(‪ ,‬בשורות ‪ .33 ,31 ,29‬במקרה כזה‪ ,‬א‬
‫לתנאי יש ער( אמת אז >משפט ‪ <1‬מתבצע‪ ,‬וא ער( שקר אז התוכנית תדלג עליו‬
‫לביצוע המשפט שבא אחרי משפט ‪.if‬‬
‫______________________________________________________________________‬
‫ ‪ 45‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
25/04/2010
&‫ סיווג ציוני‬:1 ‫דוגמא‬
90 ≤) ‫ תו( סיווג של ציוני חריגי לטוב‬,‫התוכנית מאפשרת בחירת ציו הגיוני‬
:‫ נכשל( וג דיווח על ציוני אלה‬60 >) ‫מעולה( ולרע‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/* If_Rand.cpp */
// if ‫סיווג ציונים ע"י‬
// -------------------
#include <iostream>
using namespace std;
int
grade;
// ‫משתנה גלובלי‬
void init();
void categorize();
void try_again();
int main()
{
init();
if (1 <= grade && grade <= 100)//‫בדיקה האם קלט מתאים‬
categorize();
else
try_again();
}
void init()
// ‫קליטת ציון מהמשתמש‬
{
cout << " What is your grade (1-100) ? ";
cin >> grade;
// ‫קליטת הציון‬
}
void categorize()
{
if (grade < 60 || 90 <= grade)
cout << " Your grade is";
if (grade >= 90)
cout << " excellent ! \n";
if (grade < 60)
cout << " too bad !
\n";
cout << '\n';
}
// ‫סיווג הציון‬
void try_again()
{
cout<< "\n Try again by ReRunning the program \n\n";
}
:‫ דוגמאות של פלט הריצה‬4
What is your grade (1-100) ? 94
Your grade is excellent !
Press any key to continue . . .
______________________________________________________________________
46 if ‫ משפט‬:3 ‫פרק‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫‪What is your grade (1-100) ? 56‬‬
‫! ‪Your grade is too bad‬‬
‫‪Press any key to continue . . .‬‬
‫‪What is your grade (1-100) ? 85‬‬
‫‪Press any key to continue . . .‬‬
‫‪What is your grade (1-100) ? 120‬‬
‫‪Try again by ReRunning the program‬‬
‫‪Press any key to continue . . .‬‬
‫)ב(‪ .‬אופרטורי& בוליאניי& )לוגיי&(‬
‫בתוכנית הקודמת היו ביטויי בוליאניי בתו( משפטי ‪ .if‬חלק היו ביטויי&‬
‫בוליאניי& פשוטי&‪ ,‬כמו )‪ (grade >= 90‬בשורה ‪ ,31‬או )‪ (grade < 60‬בשורה ‪.33‬‬
‫אחרי היו ביטויי& בוליאניי& מורכבי& כמו )‪(1 <= grade && grade <= 100‬‬
‫בשורה ‪ ,15‬או )‪ (grade < 60 || 90 <= grade‬בשורה ‪ .29‬ביטויי בוליאניי‬
‫נקראי ג ביטויי& לוגיי&‪.‬‬
‫הביטויי הבוליאניי הבאי פשוטי‪) (4 == 6) ,(3 < 7) ,(0) ,(2) :‬כאשר == הוא‬
‫אופרטור ההשוואה( ו )‪ !=) (5 != 5‬הוא אופרטור השונות או אופרטור אי'השוויו((‪.‬‬
‫לסוגריי בביטויי הנ"ל יש רק תפקיד ויזואלי )בכל זאת‪ ,‬הסוגריי חייבי להופיע‬
‫לאחר המילה ‪ .(if‬ביטויי אלה מהווי קבועי& בוליאניי& )קבועי& לוגיי&(‪ ,‬כי‬
‫לכל אחד מה יש ער( קבוע‪ ,‬או ‪) 0‬שקר(‪ ,‬או לא ‪) 0‬אמת(‪ .‬כ( למשל‪ ,‬הער( של‬
‫הביטוי )‪ (3 < 7‬הוא ‪ 1‬והער( של ‪ 2‬הביטויי אחריו הוא ‪ .0‬בניגוד לה‪ (x < 3) ,‬הינו‬
‫ביטוי פשוט משתנה‪ ,‬שערכו תלוי בער( של ‪ ,x‬וכ(‪ ,‬הוא עשוי להשתנות ולהיות ‪0‬‬
‫או ‪ .1‬ביטויי בוליאניי ניתני‪ ,‬בי היתר‪ ,‬להצבה לתו( משתני בוליאניי‪ ,‬כמו‬
‫הביטוי הבא‪ .b = (x < 3); :‬משתנה בוליאני )‪ (boolean variable‬עשוי להיות‬
‫מטיפוס ‪ ,int‬שיש לו משמעות נוספת שהיא או‪ :‬אמת )=‪ ,(1‬או‪ :‬שקר )=‪.(0‬‬
‫ביטויי& בוליאניי& מורכבי& נוצרי ע"י אופרטורי& בוליאניי& )פעולות לוגיות(‬
‫הפועלי על ביטויי בוליאניי )פשוטי יותר(‪ ,‬ואז ה מחזירי ער( בוליאני‪ .‬כ(‬
‫למשל‪ ,‬פגשנו את האופרטור הבוליאני || בתוכנית הקודמת בשורה ‪ 29‬וג את‬
‫האופרטור הבוליאני && בשורה ‪ 15‬ש‪ .‬בהמש(‪ ,‬נדגי את האופרטורי‬
‫הבוליאניי‪ ,‬בעזרת ביטויי בוליאניי‪ ,‬כמו‪ b1 ,b :‬ו ‪:b2‬‬
‫______________________________________________________________________‬
‫ ‪ 47‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫! )לא( פעולה לוגית חדמקומית‪ .‬הער( של )‪ (!b‬יהיה אמת כאשר )‪ (b‬שקר ולהפ(‪.‬‬
‫דוגמא‪ :‬לאחר‪ b = (5 < 3); :‬המשפט‪ cout << (! b); :‬ידפיס ‪) 1‬בידקו!(‪.‬‬
‫&& )וג&( פעולה לוגית דומקומית‪ .‬א ‪ b1‬ו ‪ b2‬הינ ביטויי לוגיי‪ ,‬אז‬
‫)‪ (b1 && b2‬הוא אמת אורקא הער( )‪ (b1‬וג& הער( )‪ (b2‬אמת‪,‬‬
‫אחרת‪ ,‬הוא שקר‪.‬‬
‫דוגמא‪ cout << (1 < 100 && 101 < 100); :‬ידפיס ‪) 0‬שקר( )בידקו!(‪.‬‬
‫|| )או( פעולה דומקומית‪ (b1 || b2) .‬אמת א ורק א )‪ (b1‬או )‪ (b2‬אמת‪.‬‬
‫דוגמא‪ cout << (1 < 100 || 101 < 100); :‬ידפיס ‪) 1‬אמת( )בידקו!(‪.‬‬
‫נית להציג את כל האופרטורי הבוליאניי בעזרת לוחות'אמת שלה‪:‬‬
‫‪!b1‬‬
‫‪b1 && b2‬‬
‫‪b1 || b2‬‬
‫‪b2‬‬
‫‪b1‬‬
‫שקר‬
‫אמת‬
‫אמת‬
‫אמת‬
‫אמת‬
‫שקר‬
‫שקר‬
‫אמת‬
‫שקר‬
‫אמת‬
‫אמת‬
‫שקר‬
‫אמת‬
‫אמת‬
‫שקר‬
‫אמת‬
‫שקר‬
‫שקר‬
‫שקר‬
‫שקר‬
‫ביטויי& בוליאניי& שקולי& לוגית ה למשל‪ (!(3 < 1)) :‬ו )‪ ,(1 <= 3‬וג זוג‬
‫הביטויי‪ (0) :‬ו )‪ ,(b1 && !b1‬וג הזוג‪ (b1) :‬ו )‪ .(b1 && 1‬נית לראות כל זאת‬
‫מכ(‪ ,‬שלכל זוג ביטויי מהנ"ל יש אותו לוחאמת )בידקו למשל‪ ,‬את הזוג האחרו(‪.‬‬
‫א ‪ b1‬ו ‪ b2‬שקולי לוגית‪ ,‬כלומר‪ ,‬יש לה אות לוחותאמת‪ ,‬אז נסמ זאת ע"י‬
‫‪) b1 ~ b2‬התו ִתילְ ָדה '~' מופיע במקלדת מעל התו של תג )או גרש( ' ונית להקלידו‬
‫באמצעות >'<‪ ,<Shift>+‬כלומר‪ ,‬לחיצה ארוכה על >‪ <Shift‬ובוזמנית על‬
‫המקש >'<‪ .‬תו זה איננו שיי( לשפת ‪ ,C++‬אלא לשפה העברית והוא משמש אותנו‬
‫לתאר תכונות של השפה ‪ ,C++‬כמו‪ ,‬אילו ביטויי בשפה זו הינ שקולי לוגית‪.‬‬
‫נציג עתה חלק מתכונותיה של האופרטורי הבוליאניי )הפעולות הלוגיות(‪:‬‬
‫תכונות של לא ' !‬
‫‪:‬‬
‫))‪ ,(b) ~ (! (! b‬וג‪.(0) ~ (! (1)) :‬‬
‫תכונות של ג& ' && ‪:‬‬
‫)‪ (0) ~ (b && !b) , (b) ~ (b && b‬וג‪:‬‬
‫))‪.(b) ~ (b && (1‬‬
‫תכונות של או ' || ‪:‬‬
‫)‪ (1) ~ (b || !b) , (b) ~ (b || b‬וג‪:‬‬
‫))‪.(b) ~ (b || (0‬‬
‫חוקי ֶדה'מו ְֹרגַ(‪:‬‬
‫א‪,(! (b1 && b2)) ~ ((!b1) || (!b2)) .‬‬
‫ב‪.(! (b1 || b2)) ~ ((!b1) && (!b2)) .‬‬
‫______________________________________________________________________‬
‫ ‪ 48‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫)ג(‪ .‬סדר הקדימויות של האופרטורי& הבוליאניי&‬
‫התוכנית בדוגמא ‪ 2‬בהמש( תדגי את חישוב הערכי של ביטויי בוליאניי‪ .‬היא‬
‫תחשב ‪ 2‬גרסאות שונות של כל אחד משני זוגות הביטויי הבאי עבור שלושת‬
‫הביטויי‪:b3 = (5 != 5); ,b2 = (4 == 6); ,b1 = (3 < 7); :‬‬
‫‪(b1 || b2 && b3 || b2) .1‬‬
‫} ~ )‪{ ((b1 || (b2 && b3)) || b2‬‬
‫‪(!b3 || !b2 && !b1) .2‬‬
‫} ~ )))‪{ ((!b3) || ((!b2) && (!b1‬‬
‫הערה‪:‬‬
‫הקו התחתי הכפול בצד שמאל מדגיש את הפעולות הבוליאניות שיבוצעו ראשונות‪.‬‬
‫דוגמא ‪ :2‬ביטויי& לוגיי& ופעולות לוגיות עליה&‬
‫התוכנית הבאה תדגי את פעולת האופרטורי הלוגיי על ביטויי לוגיי ועל‬
‫משתני בוליאניי‪:‬‬
‫ביטויים לוגיים עם פעולות לוגיות ‪//‬‬
‫‪// -------------------------------‬‬
‫‪/* Bool_Var.cpp */‬‬
‫>‪#include <iostream‬‬
‫;‪using namespace std‬‬
‫הצהרת משתנים שלמים )בוליאניים(‪int b1, b2, b3, result;//‬‬
‫;)(‪void boolean_values‬‬
‫;)(‪void boolean_operators‬‬
‫)(‪int main‬‬
‫{‬
‫;)(‪boolean_values‬‬
‫;)(‪boolean_operators‬‬
‫}‬
‫ביטויים לוגים )בוליאניים( פשוטים‪void boolean_values()//‬‬
‫{‬
‫<< ‪b1 = (3 < 7); cout‬‬
‫;‪" b1 ~ (3 < 7) ~ " << b1‬‬
‫;‪b2 = (4 == 6); cout << "\n b2 ~ (4 == 6) ~ " << b2‬‬
‫;‪b3 = (5 != 5); cout << "\n b3 ~ (5 != 5) ~ " << b3‬‬
‫;'‪cout << '\n‬‬
‫}‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬
‫‪7‬‬
‫‪8‬‬
‫‪9‬‬
‫‪10‬‬
‫‪11‬‬
‫‪12‬‬
‫‪13‬‬
‫‪14‬‬
‫‪15‬‬
‫‪16‬‬
‫‪17‬‬
‫‪18‬‬
‫‪19‬‬
‫‪20‬‬
‫‪21‬‬
‫‪22‬‬
‫‪23‬‬
‫‪24‬‬
‫______________________________________________________________________‬
‫ ‪ 49‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫)(‪25 void boolean_operators‬‬
‫פעולות לוגיות )בוליאניות( ‪//‬‬
‫{ ‪26‬‬
‫‪27‬‬
‫‪result‬‬
‫=‬
‫;‪b1 || b2 && b3 || b2‬‬
‫‪28‬‬
‫;‪cout << "\n b1 || b2 && b3 || b2 ~ " << result‬‬
‫‪29‬‬
‫‪result‬‬
‫;)‪= (b1 || b2) && (b3 || b2‬‬
‫‪30‬‬
‫;‪cout << "\n (b1 || b2) && (b3 || b2) ~ " << result‬‬
‫‪31‬‬
‫;'‪cout << '\n‬‬
‫‪32‬‬
‫‪result‬‬
‫=‬
‫;)‪(!b3) || (!b2) && (!b1‬‬
‫‪33‬‬
‫;‪cout << "\n (!b3) || (!b2) && (!b1) ~ " << result‬‬
‫‪34‬‬
‫‪result‬‬
‫;)‪= ((!b3) || (!b2)) && (!b1‬‬
‫‪35‬‬
‫;‪cout << "\n ((!b3) || (!b2)) && (!b1) ~ " << result‬‬
‫‪36‬‬
‫;"‪cout << "\n\n‬‬
‫} ‪37‬‬
‫‪b1 ~ (3 < 7) ~ 1‬‬
‫‪b2 ~ (4 == 6) ~ 0‬‬
‫‪b3 ~ (5 != 5) ~ 0‬‬
‫‪b1 || b2 && b3 || b2 ~ 1‬‬
‫‪(b1 || b2) && (b3 || b2) ~ 0‬‬
‫‪(!b3) || (!b2) && (!b1) ~ 1‬‬
‫‪((!b3) || (!b2)) && (!b1) ~ 0‬‬
‫‪Press any key to continue . . .‬‬
‫הערה ‪:1‬‬
‫הסימוני‪ ' ~ 1' :‬או '‪ ' ~ 0‬המשמעות שלה היא שקילות לוגית ל"אמת" או‬
‫ל"שקר" בהתאמה‪.‬‬
‫הערה ‪:2‬‬
‫הפונקציה האחרונה בתוכנית מדגימה ג את סדר הקדימויות של האופרטורי‬
‫הבוליאניי‪ :‬ל && קדימות גבוהה מזו של || א( ל ! הקדימות הגבוהה ביותר‪.‬‬
‫לכ‪ 2 ,‬הביטויי הראשוני )שורות ‪ 27‬ו ‪ (29‬אינ שקולי‪ ,‬וכ( ג ‪ 2‬האחרוני‬
‫)שורות ‪ 32‬ו ‪ .(34‬מצב זה דומה לסדר פעולות חשבו‪ ,‬כמו בביטוי‪ ,5 + 4·32 :‬שבו‬
‫סדר הפעולות אינו משמאל לימי‪ ,‬אלא לפי הכלל שהחזקה קודמת לכפל הקוד‬
‫לחיבור‪ .‬כ(‪ ,‬בשורה ‪ ,(b1 || b2 && b3 || b2) :27‬הפעולה הראשונה ש‬
‫תהיה‪.b2 && b3 :‬‬
‫הערה ‪:3‬‬
‫הביטוי‪ ((b1 || b2) && (b3 || b2)) :‬משורה ‪ 29‬שקול ל )‪,((b1 && b3) || b2‬‬
‫כלומר‪ ,‬מתקיי כא חוק הפילוג של || מעל &&‪ ,‬ולמעשה קיי ג חוק הפילוג של‬
‫&& מעל || שלא מודג כא‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 50‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫הערה ‪:4‬‬
‫הביטוי‪ ((!b3) || (!b2) && (!b1)) :‬משורה ‪ ,32‬שקול לוגית לביטוי‪:‬‬
‫)))‪ ((!b3) || (!(b2 || b1‬לפי חוק דהמורג השני‪ ,‬והוא ג שקול ל‬
‫)))‪ (!(b3 && (b2 || b1‬לפי חוק דהמורג הראשו )הא מותר להשמיט‬
‫זוג סוגריי כלשהו?(‪.‬‬
‫הערה ‪:5‬‬
‫שיטת החישוב של האופרטורי הבוליאניי נקראת בש חישוב'מקוצר‬
‫)‪ ,(short circuit evaluation‬שמשמעותה היא שחישוב הביטויי‪ ,‬משמאל לימי‪,‬‬
‫מסתיי כאשר ערכו של הביטוי נקבע סופית‪ ,‬ג א טר הגענו לסופו‪ .‬כ(‪ ,‬בעת‬
‫חישוב הביטוי‪ ,b1 && b2 && b3 :‬א ‪ b1‬יקבל את הער( ‪ ,0‬החישוב יעצר‪ b2 ,‬ו‬
‫‪ b3‬לא יחושבו‪ ,‬והביטוי כולו יקבל את הער( ‪ .0‬לתכונה זו יש חשיבות‪ ,‬למשל במקרה‬
‫של ביטויי העשויי להכיל חילוק ב ‪ ,0‬כמו הביטוי‪,(x != 0 && 1/x < 1) :‬‬
‫ואז עצירת החישוב תמנע את החילוק ב ‪ .0‬באופ כללי‪ ,‬השפה מאפשרת לחשב את‬
‫הער( של ביטוי בלי לחשב את כל חלקיו!‬
‫הצעות פעילות להפעלת האופרטורי& הבוליאניי&‪:‬‬
‫)‪.(1‬‬
‫)‪.(2‬‬
‫;‪) <== int n = 1, k‬איתחול ‪ n‬והצהרת ‪(k‬‬
‫;)‪ n) <== n = n && (k=3‬מקבל אותו ער(‪ k ,‬מתעדכ(‪k = 3, n = 1 :‬‬
‫)‪ n) <== n = n && (k==4); .(3‬מתעדכ‪ k ,‬ללא שינוי(‪:‬‬
‫‪k = 3, n = 0‬‬
‫)‪ n) <== n = n || (k / 2); .(4‬מתעדכ‪ k ,‬ללא שינוי(‪:‬‬
‫‪k = 3, n = 1‬‬
‫)‪ n) <== n = !n && (k=k+1); .(5‬מתעדכ ‪ k‬לא משתנה!(‪:‬‬
‫‪k = 3, n = 0‬‬
‫לאופרטור ההשוואה == קדימות על && ולזה קדימות על אופרטור ההשמה )הצבה(‬
‫=‪ ,‬ולכ‪ ,‬הסוגריי ב )‪ (3‬ניתני להשמטה בעוד שהסוגריי ב )‪ (2‬וב )‪ (5‬חיוניי‪.‬‬
‫בכל זאת‪ ,‬הביטוי הימני ב )‪ (5‬נית להחלפה עלידי‪ !n && ++k :‬כי ל ‪ ++‬קדימות‬
‫על && )ומה ע הביטוי‪ .(?!n && k++ :‬בסעי‪ k (5) ,‬איננו משתנה בגלל אותה‬
‫שיטת חישובמקוצר של ביטויי בוליאניי‪ .‬היות והחלק הראשו של הביטוי הוא‬
‫שקר והתוצאה של הפעלת && על כל ביטוי חייבת להיות שקר‪ ,‬לכ‪ ,‬הביטוי השני‬
‫אינו מחושב‪ ,‬כלומר‪ ,‬איננו מתבצע! ולכ ‪ k‬נשאר ע אותו ער(‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 51‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫)ד(‪ .‬התפצלות מקוננת‬
‫בפונקציה אחת יכולי להופיע מספר משפטי התפצלות‪ :‬או בזה אחר זה‪ ,‬כמו‬
‫בדוגמא ‪ 1‬בסעי‪) ,‬א( בשורות ‪ ,2934‬וג בדוגמא ‪ 3‬בהמש( בשורות ‪ ,6467‬או אחד‬
‫בתו( השני‪ ,‬כלומר בצורה מקוננת‪ ,‬כמו באותה דוגמא בהמש( בשורות ‪.4958‬‬
‫דוגמא ‪ :3‬חישוב האור" של מספר‬
‫תוכנית זו מחשבת את האור( של מספר קצר חיובי )עד ‪ 5‬ספרות(‪ .‬לפני החישוב היא‬
‫בודקת‪ ,‬הא המספר אכ מתאי‪ ,‬כלומר‪ ,‬היא "מסננת" את הקלט‪ ,‬ומציבה את‬
‫הער( הבוליאני המתקבל במשתנה הבוליאני ‪) ok‬שורה ‪ .(34‬בהתא לער( של ‪ok‬‬
‫הריצה מתפצלת בהמש( )לשורה ‪ 37‬או לשורה ‪.(40‬‬
‫חישוב אורך מספר ע"י סדרת משפטי ‪// if‬‬
‫‪// --------------------------------‬‬‫‪// for global constant SHRT_MAX‬‬
‫‪/* If_Leng.cpp */‬‬
‫>‪#include <iostream‬‬
‫>‪#include <limits.h‬‬
‫;‪using namespace std‬‬
‫קבוע מחרוזתי‪const char POSIT[]= "a positive integer";//‬‬
‫קבוע למספר קצר מקסימלי ‪const short LIMIT = SHRT_MAX; //‬‬
‫הצהרה על ‪ 2‬משתנים גלובליים ‪//‬‬
‫;‪number, length‬‬
‫‪short‬‬
‫;)(‪void input_num‬‬
‫;)(‪void check_ok‬‬
‫;)(‪void check_length‬‬
‫)(‪int main‬‬
‫{‬
‫;)(‪input_num‬‬
‫;)(‪check_ok‬‬
‫;‪number *= 10‬‬
‫;)(‪check_ok‬‬
‫;'‪cout << '\n‬‬
‫}‬
‫)(‪void input_num‬‬
‫בקשה לקליטת מספר שלם חיובי ‪//‬‬
‫{‬
‫;‪cout << " Input " << POSIT‬‬
‫;" ‪cout << "(<= " << LIMIT << "):‬‬
‫;‪cin >> number‬‬
‫}‬
‫)(‪void check_ok‬‬
‫בדיקה האם המספר עד ‪ 5‬ספרות ‪//‬‬
‫{‬
‫בהמשך‪ ,‬הצבת ביטוי בוליאני בתוך משתנה בוליאני ‪//‬‬
‫;)‪int ok = (0 < number && number <= LIMIT‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬
‫‪7‬‬
‫‪8‬‬
‫‪9‬‬
‫‪10‬‬
‫‪11‬‬
‫‪12‬‬
‫‪13‬‬
‫‪14‬‬
‫‪15‬‬
‫‪16‬‬
‫‪17‬‬
‫‪18‬‬
‫‪19‬‬
‫‪20‬‬
‫‪21‬‬
‫‪22‬‬
‫‪23‬‬
‫‪24‬‬
‫‪25‬‬
‫‪26‬‬
‫‪27‬‬
‫‪28‬‬
‫‪29‬‬
‫‪30‬‬
‫‪31‬‬
‫‪32‬‬
‫‪33‬‬
‫‪34‬‬
‫‪35‬‬
‫______________________________________________________________________‬
‫ ‪ 52‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
25/04/2010
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
if (! ok)
// ‫אם הערך לא טוב‬
cout << "\n The number " << number << " is not "
<< POSIT << '\n';
else
{
check_length();
cout << "\n Length of " << number << " is "
<< length << '\n';
}
}
void check_length()
// ‫ שלבים‬5
{
if (number >= 10000)
length = 5;
else if (number >= 1000)
length = 4;
else if (number >= 100)
length = 3;
else if (number >= 10)
length = 2;
else
length = 1;
}
/*
void check_length()
{ //
‫וללא ביטויים לוגיים‬
length = 1;
if (number >= 10)
length =
if (number >= 100)
length =
if (number >= 1000)
length =
if (number >= 10000)
length =
//
? ‫ למעלה‬if-‫המופעים של משפטי‬
}
*/
‫ עם‬if-‫דוגמא של סולם‬
if-‫התחכמות ללא סולם‬
2;
3;
4;
5;
‫האפשר להחליף את סדר‬
:‫ דוגמאות של הרצה‬4
Input a positive integer(<= 32767): 1234
Length of 1234 is 4
Length of 12340 is 5
Input a positive integer(<= 32767): 3500
Length of 3500 is 4
The number -30536 is not a positive integer
______________________________________________________________________
53 if ‫ משפט‬:3 ‫פרק‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫‪Input a positive integer(<= 32767): 7000‬‬
‫‪Length of 7000 is 4‬‬
‫‪Length of 4464 is 4‬‬
‫‪Input a positive integer(<= 32767): 32768‬‬
‫‪The number 0 is not a positive integer‬‬
‫‪The number 0 is not a positive integer‬‬
‫הערה ‪:1‬‬
‫בתוכנית למעלה ישנו משפט ‪ if‬מקונ( ב ‪ 5‬רמות‪ .‬בד"כ‪ ,‬ככל שיש יותר רמות כ(‬
‫התוכנית קשה יותר להבנה‪ .‬הפונקציה השניה‪ ,‬במשפט ההערה‪ ,‬המתפרס על פני שורות‬
‫‪ ,6070‬מדגימה כיצד נית לפשט מעט סיבוכיות כזו‪ ,‬א( זאת על חשבו יעילות התוכנית‪:‬‬
‫המחשב יבדוק ש בכל מקרה את ‪ 4‬משפטי ‪ ,if‬בניגוד למצב בסול& ‪else-if‬‬
‫בשורות ‪ .4958‬בסול כזה התנאי נבדקי אחד אחר השני מלמעלה למטה‪ ,‬עד שאחד‬
‫התנאי מתקיי‪ .‬במקרה כזה יתבצע המשפט המופיע בהמשכו‪ ,‬ושאר התנאי כבר לא‬
‫יבדקו‪ .‬א א‪ ,‬תנאי אינו מתקיי‪ ,‬אז מתבצע המשפט המופיע בהמש( ל ‪ else‬האחרו‪.‬‬
‫הערה ‪:2‬‬
‫בשורה ‪ ,36‬הביטוי הבוליאני )תנאי( )‪ (! ok‬שקול לוגית לביטוי )‪,(ok == 0‬‬
‫כלומר‪ ,‬בודק הא המספר "לא טוב"‪ .‬באופ דומה‪ ,‬הביטוי הבוליאני )תנאי(‬
‫מהצורה )‪ (ok‬שקול לוגית ל )‪ (ok != 0‬ובמקרה זה ג ל )‪,(ok == 1‬‬
‫כלומר‪ ,‬ביטויי אלה בודקי הא המספר הינו "טוב"‪.‬‬
‫הערה ‪:3‬‬
‫בשורות ‪ 78‬מוגדרי ‪ 2‬קבועי‪ ,‬אחד מחרוזתי‪ ,POSIT ,‬והשני מספרי‪LIMIT ,‬‬
‫מטיפוס ‪ .short‬קבוע )‪ ,(constant‬בדומה למשתנה‪ ,‬מכיל ער( כלשהו‪ .‬אבל‬
‫ה"קופסא" שלו סגורה ע מכסה "שקו‪ ",‬המאפשר לראות את ערכו‪ ,‬א( לא לשנות‬
‫ער( זה‪ .‬ישנ מספר שימושי נפוצי בקבועי‪ ,‬בעיקר‪ ,‬למת ש לקבועי‬
‫סטנדרטיי‪ ,‬כמו ‪ PI‬עבור ‪ ;3.14‬או למקשי מיוחדי‪ ,‬כמו הקבוע המחרוזתי‬
‫‪ ENTER‬עבור התו '‪) '\n‬שהקוד‪ ASCII‬שלו הוא ‪ 13‬בבסיס ‪ ;(10‬או לקבועי‬
‫בוליאניי‪ ,‬כמו ‪ TRUE‬עבור ‪ 1‬ו ‪ FALSE‬עבור ‪ ;0‬או לציו גבולות של תחו‬
‫השתנות של משתנה כלשהו‪ ,‬כמו ‪ LIMIT‬בדוגמא למעלה; ועוד‪ .‬כפי שנית לראות‪,‬‬
‫מקובל להשתמש באותיות גדולות עבור שמות הקבועי‪.‬‬
‫הערה ‪:4‬‬
‫הקבוע המחרוזתי ‪ POSIT‬בשורה ‪ 7‬מוגדר ע"י סוגריי מרובעות ריקות‪ ,‬כי אורכו‬
‫נקבע ע"י מספר התווי )‪ (18+1‬במחרוזת המצויה מימי לאופרטור ההצבה‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 54‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫הערה ‪:5‬‬
‫בחלו ריצה הרביעי קיבלנו דיווח ש ‪ 32768‬אינו חיובי‪ ,‬כי הוא חורג מהתחו המוגדר‬
‫ע"י הקבוע ‪) LIMIT‬בשורה ‪ ,(8‬המאפשר לטפל במספרי קצרי באור( עד ‪ 5‬ספרות‪.‬‬
‫בכל זאת‪ ,‬המספר המקסימלי מטיפוס ‪ short‬הוא הקבוע ‪ SHRT_MAX‬המוגדר‬
‫בספריה >‪ <limits.h‬ע"י הער( ‪ .32767‬כל נסיו להכניס מהמקלדת מספר גדול יותר‬
‫למשתנה מטיפוס ‪ short‬יגרו לקיצוצו ל ‪ .0‬מצב דומה קיי עבור המספר המינימלי‬
‫‪ (-32768 =) SHRT_MIN‬וג בטיפוסי אחרי‪ ,‬כמו ‪ (2,147,483,647 =) INT_MAX‬ו‬
‫‪ (-2,147,483,648 =) INT_MIN‬עבור הטיפוס ‪ ,int‬וג ‪ (127 =) CHAR_MAX‬ו‬
‫‪ (-128 =) CHAR_MIN‬עבור הטיפוס ‪) char‬ערכי אלו תקפי בגרסת ‪Visual C++ .NET‬‬
‫ועשויי להיות שוני בגרסאות אחרות של שפת ‪.(C++‬‬
‫הערה ‪:6‬‬
‫בחלו ריצה השני קיבלנו דיווח מוזר עבור המספר ‪ ,35000‬שלמעשה הוא ‪-30536‬‬
‫ולכ אינו חיובי‪ ,‬בעוד שחלו הריצה השלישי דיווח לנו ש ‪ 70000‬שווה ל ‪.4464‬‬
‫הסיבה לכ( היא שתחו המספרי השלמי מטיפוס ‪ short‬כא הוא בי ‪ -32,768‬לבי‬
‫‪ 32,767‬והוא מעגלי‪ ,‬ואז העוקב של ‪ 32,767‬הוא ‪ .-32,768‬באופ כללי‪ ,‬כל מספר ‪ n‬מחו‪B‬‬
‫לתחו הנ"ל מיוצג ע"י נוסחה המבטאת את ה"מעגליות" )מודולו( של המספרי‪:‬‬
‫‪(n + 32,768) % 65,536 - 32,768‬‬
‫מכא ש ‪ 35,000‬מטיפוס ‪ short‬שווה למעשה ל ‪ ,-30,536‬ו ‪ 70,000‬ל ‪.4,464‬‬
‫בלוקי&‪:‬‬
‫שורות ‪ 4044‬בתוכנית למעלה‪ ,‬הכלואות בי סוגריי מסולסלי )מתולתלי(‪ ,‬כמו‬
‫התוכ של כל פונקציה‪ ,‬הינ בלוק פנימי )תתבלוק( של משפט ‪ else‬אחרי משפט ‪if‬‬
‫בתו( הבלוק של הפונקציה ‪ check_ok‬בשורות ‪ .3245‬למעשה‪ ,‬הבלוק הוא המשפט‬
‫היחיד שאיננו מסתיי בתו ';' של סו‪ ,‬משפט‪ .‬בלוק יכול להכיל משפטי פשוטי וג‬
‫משפטי מורכבי‪ ,‬כמו בלוקי פנימיי יותר‪ .‬בנוס‪ ,,‬בלוק עשוי להכיל הצהרות‬
‫על משתני )ואפילו הצהרות על פונקציות(‪ ,‬בכל זאת‪ ,‬משתנה המוצהר בתו( בלוק‪,‬‬
‫נקרא משתנה לוקלי )לבלוק( והוא מוכר רק בתוכו‪ .‬הקצאת הזכרו עבורו מתבצעת‬
‫ע התחלת ביצוע הבלוק וזכרו זה משתחרר בסיו הבלוק‪.‬‬
‫)ה(‪ .‬משפט ‪ if‬כמסננת'קלט‬
‫מסננת'קלט היא קטע תוכנית‪ ,‬כמו משפט ‪ ,if‬המסנ או מונע מפונקציה לקבל קלט‬
‫לא מתאי‪ ,‬למשל‪ ,‬מהמשתמש או מפונקציה אקראית‪ .‬כ(‪ ,‬בדוגמא קודמת התוכנית‬
‫התבצעה רק א הקלט התאי‪ ,‬ואחרת דיווחה על התקלה‪ .‬אפשרות נוספת‪,‬‬
‫שתודג בפרקי הבאי‪ ,‬הינה לבקש קלט "טוב"‪ ,‬שוב ושוב‪ ,‬עד אשר זה יתקבל‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 55‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
25/04/2010
&‫ מספרי& חיוביי‬2 ‫ מנה של‬:4 ‫דוגמא‬
‫ אמורה היתה להדגי כיצד אפשר להמנע מחילוק באפס בעזרת‬,‫התוכנית הבאה‬
‫ ה כדי לחזור ולייש‬,‫ סינו הקלט הורחב לכל מספר אישלילי‬,‫ אבל‬.‫מסננת קלט‬
.‫ בעת חילוק‬,‫ למשל‬,‫ וה כדי לחזור על המרת טיפוסי משתני‬,‫פעולה לוגית‬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* Ratio.cpp */
// ‫המרת טיפוסים בחילוק‬
// -------------------
#include <iostream>
using namespace std;
double a1, b1;
// ‫משתנים ממשיים גלובליים‬
void input();
void check();
void divide();
int main()
{
input();
check();
}
void input()
{
cout << " Enter 2 positive numbers (e.g. 20 7): ";
cin >> a1 >> b1;
}
void check()
{
if ( (b1 <= 0) || (a1 <= 0) ) // || = or ‫פעולה לוגית‬
cout << "\n Not positive numbers \n";
else
divide();
}
void divide()
{
int
a2, b2;
double ratio1 = a1 / b1;
// ‫משתנים לוקליים‬
// ‫מנה ממשית‬
cout << " \n The real ratio1 is " << ratio1;
a2 = a1; b2 = b1; // int -‫ ל‬double -‫המרה אוטומטית מ‬
double ratio2 = a2 / b2; //double -‫ ל‬int -‫המרה כזו מ‬
cout << "\n\n Quasi int ratio2 is " << ratio2;
//double-‫ ל‬int-‫המרה יזומה מ‬
double ratio3 = (double) a2 / b2;
cout << "\n\n The real ratio3 is " << ratio3;
int ratio4 = int(a1/b1); //int -‫ ל‬double -‫המרה כזו מ‬
cout << "\n\n Real int ratio4 is " << ratio4;
cout << "\n\n";
}
______________________________________________________________________
56 if ‫ משפט‬:3 ‫פרק‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫‪Enter 2 positive numbers (e.g. 20 7): 20 7‬‬
‫‪real ratio1 is 2.85714‬‬
‫‪The‬‬
‫‪Quasi int ratio2 is 2‬‬
‫‪real ratio3 is 2.85714‬‬
‫‪int ratio4 is 2‬‬
‫‪The‬‬
‫‪Real‬‬
‫‪Press any key to continue . . .‬‬
‫הודעות אזהרה‪:‬‬
‫לאחר הידור התוכנית )למשל ע"י >‪ (<Ctrl+F7‬מתקבלות ‪ 2‬הודעות האזהרה הבאות‬
‫המתייחסות ל ‪ 2‬המשפטי בשורה ‪) 38‬מפני איבוד מידע בהמרות(‪:‬‬
‫‪Ratio.cpp(38) : warning C4244: '=' : conversion from 'float' to 'int', possible loss of data‬‬
‫‪Ratio.cpp(38) : warning C4244: '=' : conversion from 'float' to 'int', possible loss of data‬‬
‫כיצד אפשר להמנע מה‪ ,‬כלומר‪ ,‬מה לעשות כדי שה לא יופיעו?‬
‫הערה‪:‬‬
‫בתוכנית ישנ ‪ 2‬שורות )‪ 34‬ו ‪ (46‬של הצהרות משתני מטיפוס ‪ int‬ו ‪ 4‬שורות )‪,6‬‬
‫‪ 40 ,35‬ו ‪ (43‬מטיפוס ‪ .double‬מתוכ‪ 2 ,‬שורות )‪ 6‬ו ‪ (34‬מיועדות לנתוני‬
‫)ממשיי או שלמי בהתאמה( ושאר השורות מיועדות למנות שונות שלה ‪ 3‬מה‬
‫למנות ממשיות )‪ (ratio1-ratio3‬ואחת למנה שלמה )‪.(ratio4‬‬
‫הסברי&‪:‬‬
‫חלו הריצה מציג אותו ער( של ‪ 2‬למשתני ‪) ratio2‬ממשי( ו ‪) ratio4‬של(‪ ,‬ובכל‬
‫זאת‪ ,‬ערכיה אינ זהי‪ .‬כיצד אפשר לראות זאת? אחת הדרכי הינה להתבונ‬
‫בחלו ‪) Watch1‬החלו השמאלי התחתו בתמונה בהמש((‪ .‬כדי לקבל אותו‪ ,‬נשי את‬
‫לסמַ ( )‪ ,(Run to Cursor‬למשל‪,‬‬
‫ה ָסמַ ( )ה ‪ (Cursor‬בתחילת שורה ‪ 47‬ונבצע הרצה'עד' ָ‬
‫ע"י הקשת המקשי >‪ ,<Ctrl+F10‬או ע"י הקשת העכבר בצלמית‬
‫(‪.‬‬
‫בתמונה בהמש( אפשר לראות שאכ הסמ עומד על שורה ‪ 47‬לפי ‪ 3‬קריטריוני‪ :‬יש‬
‫בשוליי השמאליי של התוכנית ח‪ B‬צהוב המצביע על )"מאיר"( שורה זו; מימי לו‬
‫מצוי הסמ עצמו )קטע אנכי "מהבהב" לפני ‪ ;(cout‬ובצד ימי של שורתהמצב של החלו‬
‫)למטה( כתוב‪) Ln 47 Col 1 :‬כיתוב המציי את מיקו הסמ שורה וטור(‪.‬‬
‫כפי שרואי בחלו ‪) Watch1‬השמאלי התחתו‪ ,‬כרטיסיה חמישית( הער( של ‪ ratio4‬הוא‬
‫‪ ,2‬בעוד שהער( של ‪ ratio2‬הוא למעשה ‪ ,2.0‬כי כאשר מנה שלמה של ‪ 2‬משתני שלמי‬
‫מוצבת במשתנה ממשי )שורה ‪ ,(40‬היא מומרת למספר ממשי ו ‪ 2‬הופ( להיות ‪.2.0‬‬
‫______________________________________________________________________‬
‫ ‪ 57‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫כ( אפשר לראות שהקלטי השלמי מהמשתמש‪ ,‬של המספרי ‪ 20‬ו ‪ ,7‬כאשר ה‬
‫מוכנסי לתו( משתני ממשיי‪ ,‬ה מומרי אוטומטית לממשיי )שורה ‪ 21‬בתוכנית‬
‫ושורות ‪ 12‬בחלו ‪ ,(Watch1‬ואז המנה שלה‪) ratio1 ,‬שורה ‪ 35‬בתוכנית ושורה ‪5‬‬
‫בחלו ‪ ,(Watch1‬ממשית כצפוי‪ .‬כאשר ה מוכנסי לתו( משתני שלמי ה הופכי‪,‬‬
‫אכ‪ ,‬לשלמי )שורה ‪ 38‬בתוכנית ושורות ‪ 34‬בחלו ‪ .(Watch1‬אילו היינו מקלידי‬
‫ממשיי אמיתיי‪ ,‬כמו ‪ 20.0‬ו ‪ 6.9‬בשורה ‪ ,21‬ההצבות בשורה ‪ 38‬היו ממירות אות‬
‫ל ‪ int‬ע"י קיצו‪ B‬חלק השבור )‪ 6.9‬היה הופ( להיות ‪ ,(6.0‬ולכ האזהרות למעלה‪.‬‬
‫כמוכ‪ ,‬כאשר מציבי את המנה של ‪ 2‬ממשיי בתו( משתנה מטיפוס של )שורה ‪,(46‬‬
‫המנה הממשית המתקבלת‪ ,2.85714 ,‬מומרת ע"י קיצו‪ B‬למספר השל ‪ .2‬אילו היינו‬
‫מקלידי את הממשיי ‪ 20.0‬ו ‪) 6.9‬בשורה ‪ ,(21‬אזי המנה הממשית ‪) 2.89855‬בער((‬
‫היתה הופכת ל ‪ 2‬ב ‪) ratio4‬שורה ‪ 8‬בחלו ‪ ,(Watch1‬ובניגוד לכ(‪ ratio2 ,‬היה מקבל‬
‫)שורה ‪ (40‬את הער( ‪) 3.0‬במקו ‪ !(2.0‬בידקו זאת! למה?‬
‫לבסו‪ ,,‬אפשר לראות כא חלו חדש‪ ,‬חלו( מחסנית'הקריאות )‪,(Call Stack Window‬‬
‫למטה בצד ימי‪ .‬בחלו זה אפשר לראות שהרצת התוכנית צעדאחרצעד מצויה כרגע‬
‫לפני שורה ‪ 47‬בפונקציה ‪ ,divide‬לפני שורה ‪ 30‬ב ‪ check‬וג לפני שורה ‪ 16‬ב ‪.main‬‬
‫______________________________________________________________________‬
‫ ‪ 58‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫)ו(‪ .‬ניפוי שגיאות )‪(debugging‬‬
‫מסנניקלט בתוכניות‪ ,‬תפקיד למנוע שגיאות הרצה בעת ריצת התוכניות‪ .‬למעשה‪,‬‬
‫ישנ ‪ 3‬סוגי עיקריי של שגיאות‪ :‬שגיאות הידור‪ ,‬שגיאות הרצה ושגיאות לוגיות‪.‬‬
‫הסוג הראשו‪ ,‬שגיאות הידור‪ ,‬הנקרא ג שגיאות תחביר‪ ,‬נובע בגלל סיבות‪ ,‬כמו‪:‬‬
‫טעויות כתיב‪ ,‬השמטת ';'‪ ,‬שימוש במשתנה לא מוצהר‪ ,‬קריאה לפונקציה שלא‬
‫הוצהרה או שלא הוגדרה וכד'‪ .‬בדר(כלל קל לתק שגיאות הידור‪ ,‬כי כאשר‬
‫המהדר נתקל בשגיאה כזו הוא מודיע על כ( בחלו פלט ההודעות )החלו השמאלי‬
‫התחתו( שבו מוצגת רשימת הודעות השגיאה או האזהרה ומידע על כל אחת מה‪.‬‬
‫שגיאות הרצה ה שגיאות הנובעות מצירו‪ ,‬פקודות‪ ,‬ההופ( להיות בלתי חוקי‬
‫במהל( ריצת התוכנית‪ ,‬למרות התחביר התקי‪ .‬כ( למשל‪ ,‬ביטוי ע פעולת חילוק‪,‬‬
‫שבו ביטוי המכנה מקבל את הער( ‪ ,0‬בשלב כלשהו של הריצה‪ ,‬יגרו לשגיאת‬
‫הרצה‪ .‬שגיאות הרצה‪ ,‬כמו שגיאות הידור‪ ,‬קל יחסית לתקנ‪ ,‬כי אז פעולת הריצה‬
‫נפסקת ומקבלי הודעה מתאימה‪ .‬בכל זאת‪ ,‬יש לבצע "בדיקת כל המקרי" כדי‬
‫למנוע את היווצרות של שגיאות אלה‪.‬‬
‫שגיאות לוגיות גורמות לתוכנית לבצע פעולה אחרת מאשר התכוונו אליה‪ ,‬כמו‬
‫למשל‪ ,‬בפעולת חילוק של שלמי לא נקבל את החלק השבור של המנה‪ .‬שגיאות‬
‫אלה קשות לאיתור‪ ,‬ואז צרי( להשתמש במנפה טעויות )מנפה ‪ (debugger‬כדי‬
‫לגלות את מקור השגיאה‪.‬‬
‫המנפה מבוסס על ‪ 2‬טכניקות‪ .‬האחת‪ ,‬הינה סריקת )מעקב( ִדיָ אגִ ינְ ג של התוכנית באחת‬
‫מהשיטות כמו‪ :‬צעדכניסהלפונקציה )‪ ,(Step Into‬צעדמעללפונקציה )‪(Step Over‬‬
‫ועוד‪ .‬הטכניקה השניה‪ ,‬הינה התבוננות בחלו( ‪ Watch‬בערכי המשתני ובהשתנות‬
‫תו( כדי סריקת ִדי‪ ָC‬אגִ י ְנג של התוכנית‪.‬‬
‫ההפעלה של סריקת ִדי‪ ָC‬אגִ י ְנג בשיטת צעד'כניסה'לפונקציה )‪ (Step Into‬נעשית ע"י‬
‫הקשה על המקש >‪ <F11‬או ע"י הקשת העכבר בצלמית‬
‫‪ .‬לאחר הקשה ראשונה‬
‫כזו מתבצע תהלי( הידור התוכנית‪ ,‬וכאשר אי שגיאות תחביר‪" ,‬מוארת" השורה‬
‫הראשונה אחרי ‪ main‬ע"י ח‪ B‬צהוב‪ .‬כל לחיצה נוספת על >‪ <F11‬גורמת לביצוע‬
‫השורה הנוכחית ו"הארת" השורה הבאה‪ .‬א השורה הנוכחית מכילה קריאה‬
‫______________________________________________________________________‬
‫ ‪ 59‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫לפונקציה‪ ,‬אז >‪ <F11‬גור לכניסה לתו( הקוד שלה ולהארת השורה הראשונה‬
‫אחרי הכותרת שלה‪ .‬שימוש חוזר שוב ושוב ב >‪ <F11‬מאפשר לסרוק את הביצוע‬
‫של כל התוכנית בשלמותה צעדאחרצעד‪.‬‬
‫ההפעלה של סריקת ִדי‪ ָC‬אגִ י ְנג בשיטת צעד'מעל'לפונקציה )‪ (Step Over‬מופעלת ע"י‬
‫המקש >‪) <F10‬או ע"י הקשת העכבר בצלמית‬
‫(‪ .‬הפעולה של >‪ <F10‬דומה ל‬
‫>‪ <F11‬פרט לאות שורות ע קריאה לתתפונקציה‪ .‬במקרי כאלה‪ ,‬במקו‬
‫להכנס לתו( קוד הפונקציה ולבצע סריקת ִדי‪ ָC‬אגִ י ְנג שלה‪ ,‬המחשב מבצע את כולה‬
‫כאילו היתה פקודה אחת )ללא כניסה לקוד שלה(‪ .‬באופציה זו משתמשי עבור‬
‫פונקציות‪ ,‬שכבר נבדקו ונופו משגיאות‪ ,‬או שאיננו רוצי לנפות את תוכנ בגלל‬
‫סיבות אחרות‪ ,‬כמו מגבלות זמ‪ .‬ע"י שימוש חוזר שוב ושוב ב >‪ <F10‬אנו יכולי‬
‫לסרוק את הביצוע של כל התוכנית בשלמותה פונקציהאחרפונקציה‪.‬‬
‫שיטות סריקה נוספות‪:‬‬
‫שתי שיטות הסריקה למעלה ניתנות לשילוב בעת ההרצה של כל תוכנית מחשב‪ ,‬וכ(‬
‫ג מומל‪ B‬לעבוד אית בהתא לצור(‪ .‬אבל ישנ אופציות נוספות‪ ,‬כמו‪:‬‬
‫צעד'יציאה'מפונקציה )‪ (Step Out‬ע"י המקשי >‪) <Shift+F11‬או ע"י הקשת‬
‫העכבר בצלמית‬
‫(‪ ,‬למשל‪ ,‬כאשר נכנסי לתו( הספריה שבה מוגדרי‬
‫<< ‪ cout‬או >> ‪ cin‬ורוצי לחזור לתוכנית עצמה;‬
‫סיו&' ִדיָ אגִ ינְ ג )‪ (Stop Debugging‬ע"י המקשי >‪ ,<Shift+F5‬כשמוצאי את‬
‫הָ אג )טעות(;‬
‫סריקה'מחודשת )‪ (Restart‬ע"י המקשי >‪ ,<Ctrl+Shift+F5‬כאשר ישנה הרגשת‬
‫פספוס של שורה קודמת ורוצי להתחיל את הסריקה מחדש‪ .‬במקרה כזה מומל‪B‬‬
‫לסמַ ( )‪ ,(Run to Cursor‬למשל‪ ,‬ע"י הקשת המקשי >‪<Ctrl+F10‬‬
‫לבצע הרצה'עד' ָ‬
‫לאחר שנעביר את הסָ מַ קוד לכ לשורה ממנה נרצה לבצע סריקה מחודשת‪.‬‬
‫הטכניקה השניה של ניפוי שגיאות היא התבוננות בחלו( ‪ ,Watch‬העשוי להכיל שמות‬
‫משתני וביטויי מורכבי יותר ולהציג את ערכיה‪ .‬המשתני יופיעו בחלו ‪,Watch1‬‬
‫כמודג בתמונה בסעי‪) ,‬ה(‪ ,‬לאחר שנקליד אות ש שורהאחרשורה‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 60‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫)ז(‪ .‬סיכו&‬
‫הסיכו יתייחס לשני המושגי המופשטי העיקריי שפגשנו בפרק‪ :‬אופרטורי‬
‫בוליאניי וביטויי בוליאניי‪ .‬אלא שהדיו יורחב לאופרטורי וביטויי בכלל‪.‬‬
‫)‪ .(1‬אופרטורי& )פעולות(‬
‫בשפה יש מספר רב של אופרטורי )פעולות( מסוגי שוני הנותני לה גמישות‬
‫רבה‪ .‬ה פועלי על ביטויי )שיידונו לאחר מכ(‪ ,‬ותמיד יש לה תוצאה תוצאת‬
‫הפעולה‪ .‬נתאר אות בהמש( בצורה תמציתית לפי הסיווג הבא‪ :‬אופרטורי‬
‫חשבוניי )אריתמטיי(‪ ,‬אופרטורי השמה‪ ,‬אופרטורי השוואתיי )של יחסי סדר(‪,‬‬
‫אופרטורי בוליאניי )לוגיי(‪ ,‬אופרטור הפסיק ואופרטורי של סיביות )אבל‪,‬‬
‫קיימי אופרטורי נוספי‪ ,‬כמו אופרטורי הקלט‪/‬פלט >> ו << בהתאמה ועוד(‪.‬‬
‫אופרטורי& חשבוניי& )אריתמטיי&(‬
‫האופרטורי& החשבוניי&‪ % , / , * , - , + :‬ה אופרטורי& דו'מקומיי& )ִ ינ ִָריי&(‬
‫נדי&(‪ ,‬אחד מכל צד של האופרטור‪ ,‬א(‪ ,‬האופרטורי ‪ +‬ו ‪-‬‬
‫ע ‪ 2‬ארגומנטי& )אוֶֹ ַר ִ‬
‫הינ ג אופרטורי& חד'מקומיי& )אנ ִָריי&(‪ 5 .‬האופרטורי ה‪ ִC‬ינ ִָריי מחזירי‬
‫ער( שהוא תוצאת הפעולה )סכו‪ ,‬הפרש‪ ,‬מכפלה‪ ,‬מנה ושארית בהתאמה(‪.‬‬
‫האסוציאטיביות שלה הינה משמאל לימי‪ ,‬כלומר‪ ,‬א הפעולה מופיעה מספר‬
‫פעמי בזה אחר זה‪ ,‬אז הסדר יהיה משמאל לימי‪ .‬הפעולות המתבצעות על יד ה‬
‫בהתא לצפוי‪ ,‬פרט לשני מקרי‪ .‬האחד הוא חילוק שלמי אשר מתבצע תו(‬
‫קיצו‪ B‬המנה המתמטית )כמו‪ (14 / 5 = 2 :‬כאשר אינה שלמה‪ .‬המקרה השני הוא‬
‫השארית )כמו‪ , 14 % 5 = 4 :‬ולא‪ (14 % 5 = 0.8 :‬שאיננה מוגדרת לממשיי‪ .‬בשני‬
‫מקרי אלה התוצאה עבור ערכי שליליי הינה תלויית גרסה‪ .‬בנוס‪ ,,‬כאשר ‪4‬‬
‫האופרטורי הראשוני פועלי על ביטויי חשבוניי מטיפוסי שוני‪ ,‬כמו‬
‫שלמי וממשיי‪ ,‬ה יבצעו המרה של התוצאה לטיפוס הגדול ביותר )מבחינת‬
‫הזכרו( והתוצאה שלה תהיה בהתא לטיפוס זה‪.‬‬
‫אופרטור ההשמה‬
‫אופרטור ההשמה הוא אופרטור ‪ ִC‬ינ ִָרי‪ ,‬המיוצג ע"י תו שוויו יחיד =‪ .‬הקדימות שלו‬
‫נמוכה מאד‪ ,‬ורק לאופרטור הפסיק קדימות נמוכה יותר‪ .‬האסוציאטיביות שלו‬
‫הינה מימי לשמאל‪ ,‬כלומר א הפעולה מופיעה מספר פעמי בזה אחר זה‪ ,‬אז‬
‫______________________________________________________________________‬
‫ ‪ 61‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫הסדר יהיה מימי לשמאל )כמו פעולת החזקה )!(‪ ,‬ובניגוד לרוב הפעולות האחרות(‪.‬‬
‫הפעולות המתבצעות על ידו ה‪ :‬חישוב הביטוי מימי; המרת הביטוי הימני לטיפוס‬
‫המשתנה משמאל )א צרי((; הצבת הער( המתקבל לתו( המשתנה משמאל;‬
‫והחזרת הער( של אותו משתנה‪ ,‬ער( שהוא התוצאה של האופרטור‪ .‬תוצאה זו ניתנת‬
‫להדפסה‪ ,‬למשל‪ ,‬כמו ע"י המשפט הבא‪ ,cout << (x = 35.7); :‬שידפיס ‪35.7‬‬
‫א ‪ x‬מטיפוס ממשי‪ 35 ,‬א מטיפוס ‪ int‬ואת התו '‪ '#‬א מטיפוס ‪.char‬‬
‫אופרטורי השמה עצמית‬
‫אופרטורי אלה‪ -- , ++ , %= , /= , *= , -= , += :‬ה ג חשבוניי וג של‬
‫השמה‪ .‬למשל‪ ,‬עבור האיתחול‪ int x = 30; :‬המשפט‪ x /= 4; :‬ישי את‬
‫המנה ‪ 7‬ב ‪ ,x‬ואז‪ ,‬המשפט‪ x %= 4; :‬ישי את השארית ‪ 3‬ב ‪ %=) x‬פועל רק על‬
‫אוֹ‪ַ ֶG‬רנדי שלמי(‪ 2 .‬האופרטורי האחרוני‪ ,‬של הגדלה עצמית והקטנה עצמית‪,‬‬
‫ה א‪I‬נ ִָריי בעוד ש ‪ 5‬הראשוני ‪ ִC‬ינ ִָריי‪ .‬בדומה להשמה‪ ,‬האסוציאטיביות של‬
‫כל ה‪ ִC‬ינ ִָריי הינה מימי לשמאל‪ .‬פעולות אלה ניתנות לשירשור‪ ,‬כמו למשל‪ ,‬עבור‬
‫האיתחול‪ int x = 30, y = 9; :‬המשפט‪ y %= x /= 4; :‬יגרו לכ( ש ‪x‬‬
‫יכיל את הער( ‪ 7‬ו ‪ y‬יכיל את הער( ‪ .2‬הער( ‪ 7‬הוא ג התוצאה של הפעולה =‪,/‬‬
‫והער( ‪ 2‬הוא ג התוצאה של הפעולה =‪ .%‬כדי לשרשר אופרטורי כאלה יש‬
‫להקפיד על כ( שבצד שמאל של כל אחד מה יופיע משתנה ולא ער( מספרי‪ ,‬כ(‬
‫שהביטוי‪ (y %= 30 /= 4) :‬אינו תקי‪ ,‬כי ‪ 30‬איננו משתנה‪.‬‬
‫האופרטורי הא‪I‬נ ִָריי של הגדלה‪/‬הקטנה עצמית מוקדמת‪/‬מאוחרת ‪ ++‬ו ‪,--‬‬
‫כול פועלי על משתני‪ .‬כמוכ‪ ,‬כול משני את ער( המשתנה ב ‪ ,1‬וכול‬
‫מחזירי תוצאה תוצאת האופרטור‪ .‬כ( למשל‪ ,‬עבור המשפט‪ x = y = 3; :‬תוצאת‬
‫האופרטור )‪ (++x‬היא ‪ ,4‬א( התוצאה של האופרטור )‪ (y++‬היא ‪ ,3‬למרות ש ‪ y‬יכיל‬
‫בעקבותיה את ‪ ,4‬ואכ‪ ,‬המשפט ;)‪ cout << (y++‬ידפיס ‪ .3‬כמוכ מתקיימות‬
‫השקילויות הבאות‪ ,‬מנקודת מבט של תוצאת הביטוי ותוצאת הלוואי )‪ (side effect‬של‬
‫ההצבה‪:‬‬
‫‪ 3‬הביטויי הבאי הינ שקולי‪) ++x, x += 1, x = x + 1 :‬א( לא ‪;(x++‬‬
‫וג ‪ 3‬הביטויי הבאי שקולי‪) --x, x -= 1, x = x - 1 :‬א( לא ‪.(x--‬‬
‫תפקיד של כל אופרטורי ההשמה העצמית לקצר את הכתיבה של אות ביטויי‬
‫ע פעולות חשבוניות ופעולת הצבה‪ ,‬ובכ( ג לשפר את הקריאות שלה‪ ,‬בהיות‬
‫התרגו לשפת ‪ C++‬של ביטויי בשפה הטבעית‪ ,‬כמו הגדל‪/‬הקט פי‪/‬ב‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 62‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫אופרטורי& השוואתיי& )של יחסי סדר(‬
‫האופרטורי& ההשוואתיי&‪ ,‬שכול ‪ ִC‬ינ ִָריי‪ ,‬הינ‪ . != , == , <= , < , >= , > :‬שני‬
‫הארגומנטי שלה )אחד מכל צד( הינ מספריי‪ ,‬א( התוצאה שלה הינה‬
‫בוליאנית )‪ 1‬או ‪ ,(0‬ולכ‪ ,‬ה ניתני לקישור ע האופרטורי הבוליאניי )שיוצגו‬
‫ג בהמש((‪ ,‬כמו במשפט ההשמה הבא‪:‬‬
‫;)‪b = (3 < 7) || (5 >= 5) && (4 == 6‬‬
‫נית להוריד את סימני הסוגריי ממשפט השמה זה‪ ,‬היות והקדימות שלה גבוהה‬
‫מזו של האופרטורי הבוליאניי‪ .‬בכל זאת ‪ b‬יקבל את הער( ‪ 1‬ולא את ‪ ,0‬כי‬
‫הקדימות של && גבוהה מזו של ||‪ ,‬ולכ המשפט הנ"ל שקול למשפט‪:‬‬
‫;)‪b = 3 < 7 || (5 >= 5 && 4 == 6‬‬
‫כפי שנית לראות במשפט האחרו שבו סימני הסוגריי מיותרי‪ ,‬מומל‪ B‬להשתמש‬
‫בה כדי להקל על הבנת המשפטי‪ ,‬ולפחות‪ ,‬בכל מקו שבו ה מסייעי לכ(‪.‬‬
‫אופרטורי& בוליאניי& )לוגיי&(‬
‫האופרטורי& הבוליאניי&‪ ,‬שנידונו בהרחבה בסעי‪) ,‬ב( בפרק זה‪ ,‬ה‪|| , && :‬‬
‫ה‪ ִC‬ינ ִָריי‪ ,‬והאופרטור הא‪I‬נ ִָרי !‪ .‬התוצאה המוחזרת שלה היא תמיד או ‪ 0‬או ‪ .1‬ה‬
‫פועלי על ביטויי בוליאניי‪ ,‬והפעולות המתבצעות על יד ה בהתא ללוחות האמת‬
‫שלה‪ .‬למשל‪ ,‬הביטוי )‪ (!0‬מחזיר את התוצאה ‪ (0 && b) ,1‬מחזיר את התוצאה ‪ 0‬לכל‬
‫ער( של הביטוי ‪ ,b‬ו )‪ (1 || b‬מחזיר את התוצאה ‪ 1‬לכל ער( של ‪ .b‬האסוציאטיביות‬
‫שלה‪ ,‬כמו של האופרטורי החשבוניי‪ ,‬הינה משמאל לימי‪.‬‬
‫אופרטור הפסיק‬
‫אופרטור הפסיק הינו ‪ ִC‬ינ ִָרי והאסוציאטיביות שלו משמאל לימי‪ ,‬כלומר‪ ,‬הוא‬
‫מבטיח את חישוב הארגומנט )האוֹ‪ַ ֶG‬רנד( השמאלי לפני הימני‪ .‬א ‪ exp1‬ו ‪exp2‬‬
‫הינ ביטויי )קיצור של ‪ ,(expression‬אז הביטוי המורכב )‪ (exp1, exp2‬יחשב‬
‫תחילה את הביטוי ‪ ,exp1‬אח"כ את הביטוי ‪ ,exp2‬ולבסו‪ ,,‬יחזיר כתוצאה את הער(‬
‫המחושב של ‪ .exp2‬כ( למשל‪ ,‬לאחר ביצוע ‪ 2‬המשפטי הבאי‪:‬‬
‫;)‪a = (b += 1, 2 * c - b‬‬
‫;‪int a, b = 2, c = 3‬‬
‫הער( של שלושת המשתני יהיה ‪ .3‬הסוגריי בדוגמא הכרחיי כי לאופרטור‬
‫הפסיק יש עדיפות הכי נמוכה‪ .‬בד"כ‪ ,‬השימוש באופרטור זה אינו מומל‪ ,B‬כי הוא‬
‫______________________________________________________________________‬
‫ ‪ 63‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫מקשה על הבנת המשפט‪ .‬כ( למשל‪ ,‬המשפט השני למעלה יהיה ברור הרבה יותר‬
‫א הוא יכתב בצורה מפוצלת לשני משפטי& באופ הבא‪:‬‬
‫;‪b += 1‬‬
‫;‪a = 2 * c - b‬‬
‫;‪int a, b = 2, c = 3‬‬
‫אופרטורי& של סיביות‬
‫האופרטורי& של סיביות )ביטי& ‪ (bits‬הינ‪) & :‬וג(‪) | ,‬או(‪) ~ ,‬לא(‪) >> ,(XOR) ^ ,‬הזזה‬
‫ימינה( ו << )הזזה שמאלה(‪ .‬לא קיי טיפוס משתנה לסיבית‪ ,‬שהינה יחידת‬
‫הזכרו המינימלית‪ ,‬לכ הטיפול בסיביות נעשה רק באמצעות האופרטורי שלה‪.‬‬
‫הדיו בנושא זה חורג מתחו עניננו ולכ לא יורחב‪ .‬בכל זאת‪ 8 ,‬סיביות שוות‬
‫לזכרו של בית אחד‪ ,‬כאשר בית היא יחידת הזכרו הבסיסית עבור טיפוסי‬
‫המשתני‪ .‬הטיפוס ‪ char‬תופס לפחות ‪ 1‬בית‪ short ,‬לפחות ‪ 2‬בתי‪ long ,‬ו ‪ float‬‬
‫לפחות ‪ 4‬בתי‪ ,‬ו ‪ double‬לפחות ‪ 8‬בתי )ראו סעי‪ ,‬ט' בפרק ‪.(2‬‬
‫טבלת סדר קדימויות של האופרטורי&‬
‫טבלה זו קובעת ‪ 9‬דרגות עוצמה לכל האופרטורי שפורטו למעלה‪ ,‬כאשר עוצמה ‪ 1‬הינה‬
‫בעלת העדיפות הראשונה לביצוע‪ .‬בתו( כל טור בטבלה‪ ,‬סדר הקדימויות הוא לפי סדר‬
‫הופעת האופרטורי‪ ,‬משמאל לימי או הפו(‪ ,‬בהתא לאסוציאטיביות של כל אופרטור‪.‬‬
‫‪8‬‬
‫‪9‬‬
‫‪,‬‬
‫)פסיק(‬
‫=‬
‫=‪+‬‬
‫‪7‬‬
‫‪6‬‬
‫&&‬
‫||‬
‫)גם(‬
‫)או(‬
‫)לוגי( )לוגי(‬
‫‪3‬‬
‫‪2‬‬
‫‪1‬‬
‫‪5‬‬
‫‪4‬‬
‫==‬
‫<‬
‫‪+‬‬
‫*‬
‫‪++‬‬
‫=!‬
‫=<‬
‫‪-‬‬
‫‪/‬‬
‫‪--‬‬
‫=‪-‬‬
‫>‬
‫=*‬
‫=>‬
‫=‪/‬‬
‫)יחסי סדר(‬
‫‪%‬‬
‫ָרי(‬
‫‪)-‬אּונִ‬
‫)פעולות(‬
‫)חשבון(‬
‫ָרי(‬
‫‪)+‬אּונִ‬
‫! )לא(‬
‫)לוגי(‬
‫=‪%‬‬
‫)השמה(‬
‫הערה‪ :‬השוו טבלה זו ע ה ‪ ,Help‬ה' ‪ Index‬והפריט ‪.Precedence of operators‬‬
‫הערה‪:‬‬
‫במקרה של ריבוי האופרטורי ‪ -- ,++‬באותו ביטוי‪ ,‬אי כללי לסדר הביצוע‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 64‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫)‪ .(2‬ביטויי&‬
‫כל ביטוי מאופיי ע"י תוצאה וטיפוס‪ .‬החישוב של תוצאת הביטוי )ג‪ :‬ער"‬
‫הביטוי( נעשה באמצעות האופרטורי‪ ,‬והמחשב מחזיר ער( זה לפי טיפוסיה‪.‬‬
‫נית לסווג ביטויי‪ ,‬מצד אחד לפי‪ :‬ביטויי משתני )שנידונו בפרק הקוד(‬
‫לעומת ביטויי קבועי ומצד שני לפי ביטויי פשוטי לעומת ביטויי מורכבי‪.‬‬
‫בנוס‪ ,,‬נית לסווג לפי טיפוסיה‪.‬‬
‫קבועי& )פשוטי&(‬
‫קבוע הוא ביטוי שהער( שלו קבוע‪ ,‬אינו יכול להשתנות‪ .‬דוגמא לביטוי קבוע הוא‬
‫הקבוע המספרי השל‪ ,‬שהוא פשוט מספר של )אפס‪ ,‬חיובי או שלילי(‪ .‬הוא יכול‬
‫להיות כתוב בבסיס ‪ ,10‬או ‪) 8‬או ְֹקטָ לִ י(‪ ,‬או ‪) 16‬הֶ ְקסַ ֶד ִצימָ לִ י(‪ .‬קבוע של& עשרוני‬
‫בבסיס ‪ 10‬הוא רצ‪ ,‬של ספרות עשרוניות‪ ,‬שהראשו בה אינו אפס‪ ,‬כמו ‪.1234‬‬
‫קבוע של& או ְֹק ָטלִ י )בבסיס ‪ (8‬מתחיל בספרה אפס ומכיל ספרות רק בי ‪ 0‬ל ‪7‬‬
‫)ללא ‪ 8‬ו ‪ (9‬כמו ‪ ,011‬שערכו בבסיס ‪ 10‬הוא ‪ .(1⋅8+1 =) 9‬קבוע של& הֶ ְק ַס ֶדצִ ימָ לִ י‬
‫)בבסיס ‪ (16‬הוא רצ‪ ,‬של ְספָ רוֹת הֶ ְק ַס ֶדצִ ימָ לִ יוֹת )מ ‪ 0‬עד ‪ f‬או ‪ ,(F‬המתחיל בתווי ‪0x‬‬
‫או ‪ ,0X‬כמו ‪ 0xa9‬שערכו בבסיס ‪ 10‬הוא ‪.(16⋅a+9 = 16⋅10+9 =) 169‬‬
‫לקבועי מספריי )מטיפוס ‪ (int‬יש ‪ 3‬רמותדיוק‪ :‬רמת'דיוק קצרה )‪(short int‬‬
‫אמצעית )‪ (int‬ורמת'דיוק ארוכה )‪ .(long int‬הקצרה תופסת לפחות ‪ 2‬בתי )‪16‬‬
‫סיביות( בזכרו‪ ,‬ואז‪ ,‬התחו שלה הוא בי ‪ -215‬לבי ‪ ,215-1‬בעוד שהארוכה תופסת‬
‫לפחות ‪ 4‬בתי )‪ 32‬סיביות( בזכרו‪ ,‬ואז‪ ,‬התחו שלה הוא בי ‪ -231‬לבי ‪ .231-1‬כמו‬
‫כ צריכי להתקיי עבור ‪ 2‬כללי‪:‬‬
‫א‪) .‬רמתדיוק ‪) ≥ (short‬רמתדיוק ‪) ≥ (int‬רמתדיוק ‪;(long‬‬
‫ב‪) .‬רמתדיוק ‪) > (short‬רמתדיוק ‪.(long‬‬
‫כ( למשל‪ ,‬בסביבת ‪) Visual C++‬רמתדיוק ‪) = (int‬רמתדיוק ‪ ,(long‬ובסביבת‬
‫‪) Turbo C++‬רמתדיוק ‪) = (int‬רמתדיוק ‪.(short‬‬
‫______________________________________________________________________‬
‫ ‪ 65‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫כדי לציי שרמת דיוק של קבוע של הינה ארוכה מסיימי אותו ע האות ‪,L‬‬
‫כמו‪ .0xaeL ,011L ,8L :‬באופ דומה קבועי מטיפוס ‪ unsigned‬יהיו ע סיומת‬
‫התו ‪ ,U‬וקבועי ממשיי מטיפוס ‪) float‬במקו ‪ (double‬יהיו ע הסיומת ‪.F‬‬
‫קבוע של מסוג אחר הוא הקבוע התווי מטיפוס ‪ .char‬קבוע זה מאופיי ע"י התו‬
‫'\' אשר אחריו תו אחד או מספר תווי נוספי‪ ,‬כמו‪ '\n' :‬תו שורהחדשה‪.‬‬
‫החשיבות של תו זה בגלל הקושי להקישו בחלו עור(‪ ,‬כי בניגוד לרוב המקשי‬
‫האחרי‪ ,‬המקש >‪ <Enter‬גור למעבר לשורה חדשה ולא להדפסת התו של שורה‬
‫חדשה‪ .‬כאשר התווי הנוספי‪ ,‬אחרי '\'‪ ,‬מייצגי קבוע של )בבסיס או ְֹקטָ לִ י(‪,‬‬
‫אז הוא אחד מ ‪ 256‬התווי הקיימי לפי קוד‪ .ASCII‬כ( לדוגמא‪ ,‬נבחי בי‬
‫הקבועי השלמי הבאי‪) 062 ,62 :‬בבסיס ‪ ,8‬ושערכו העשרוני ‪) 0x62 ,(50‬בבסיס‬
‫‪ ,16‬שערכו העשרוני ‪ (98‬ו '‪) '\062‬שערכו העשרוני‪ ,‬כאמור‪ ,50 ,‬ולכ הוא התו '‪ '2‬של‬
‫הספרה ‪.(2‬‬
‫קבועי‪ ,‬אחרי לגמרי‪ ,‬הינ הקבועי המחרוזתיי רצ‪ ,‬תווי הכלואי בי מרכאות‬
‫כפולות )"( מקדימה ומאחור‪ ,‬כמו לדוגמא‪ ,"2 b or ! 2 b" :‬המחרוזת הריקה ""‬
‫והמחרוזת "שתי ‪ \n‬שורות ‪ ."\n‬יש לשי לב לכ( ש '‪) '\n‬תו( שונה מ "‪) "\n‬מחרוזת‬
‫בת תו אחד(‪ ,‬למרות שהדפסת גורמת לתוצאה זהה מעבר לתחילת שורה חדשה‪.‬‬
‫למעשה‪ ,‬כל מחרוזת )וכ( ג "‪ ("\n‬תופסת בית אחד נוס‪ ,‬בזכרו עבור תו סיו‪,‬‬
‫שהינו הכרחי לכל מחרוזת )ג לריקה(‪ .‬תו סיו מחרוזת נקרא תו סו‪'1‬מחרוזת‬
‫והוא מיוצג ע"י '‪ ,'\0‬שהינו תו'שקו‪ ,1‬כלומר בלתינראה‪ .‬מכא‪ ,‬שקבוע מחרוזתי‬
‫ע ‪ n‬תווי )נראי‪ ,‬לא שקופי( תופס‪ ,‬למעשה‪ n+1 ,‬בתי בזכרו‪ ,‬בפרט‪,‬‬
‫המחרוזת הריקה "" מכילה בדיוק רק את התו סו‪,‬מחרוזת '‪.'\0‬‬
‫ביטויי& מורכבי&‬
‫בסעי‪ ,‬קוד ראינו קבועי פשוטי‪ .‬יתכנו ג ביטויי קבועי מורכבי המתקבלי‬
‫ע"י הפעלת אופרטורי על קבועי פשוטי‪ ,‬כמו הביטוי המורכב ‪2 - 1 / 3‬‬
‫)שהתוצאה שלו הינה ‪ 2‬מטיפוס ‪ .(int‬באופ כללי‪ ,‬הקבוע והמשתנה ה ביטויי‬
‫פשוטי‪ .‬לעומת‪ ,‬ביטויי& מורכבי& מתקבלי ע"י הפעלת אופרטורי ופונקציות‬
‫על ביטויי פשוטי‪ ,‬או על ביטויי מורכבי פחות‪.‬‬
‫______________________________________________________________________‬
‫ ‪ 66‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫כדי להבי זאת נתבונ במשפט הבא‪ ,‬הנעזר בפונקצית השורש הריבועי ‪sqrt‬‬
‫מתו( הספריה ‪ ,math.h‬המופיע אחרי משפט האיתחול ;‪:int n = 1‬‬
‫;))‪n = (n != (sqrt (9 + '7') == 8‬‬
‫יש בו ‪ 3‬קבועי‪ 2 ,‬מופעי של משתנה אחד‪ 4 ,‬אופרטורי ופונקציה אחת‪ .‬נעקוב‬
‫אחר דר( החישוב שלו‪.‬‬
‫תתהביטוי שיחושב ראשו הוא הביטוי החשבוני‪ 9+'7' :‬המחזיר ער( של ‪64‬‬
‫)כי הער( התווי של התו '‪ '7‬הוא ‪ 55‬ופעולת החיבור ממירה אותו ל ‪ 55‬מטיפוס ‪.(int‬‬
‫תתהביטוי השני הוא ביטוי מסוג חדש ביטוי פונקציונלי‪,sqrt (9+'7') :‬‬
‫המחזיר את התוצאה הממשית ‪ 8.0‬של השורש הריבועי של ‪.64‬‬
‫תתהביטוי שיחושב אחריו‪ (sqrt (9+'7') == 8) :‬הוא ביטוי בוליאני )לוגי(‬
‫המשווה‪ ,‬בי ‪ 8‬לבי ‪ .8.0‬למרות השוני בטיפוסי הוא מחזיר את הער( ‪") 1‬אמת"(‪,‬‬
‫כי האופרטור == ממיר את ה ‪ 8‬השל לטיפוס ממשי הטיפוס ‪ double‬של‬
‫הפונקציה ‪.sqrt‬‬
‫תתהביטוי הבא ג הוא ביטוי בוליאני )לוגי(‪(n != (sqrt (9+'7') == 8)) :‬‬
‫בודק קיו שונות בי הער( הבוליאני ‪ 1‬מימי לפעולה =! לבי הער( הנוכחי ‪ 1‬של‬
‫המשתנה ‪ n‬משמאל לפעולה‪ ,‬ולכ הוא מחזיר את הער( ‪) 0‬כי ה אינ שוני(‪.‬‬
‫תתהביטוי האחרו הוא ביטוי ההשמה‪,n = (n != (sqrt (9+'7') == 8)) :‬‬
‫המציב בתו( המשתנה ‪ n‬את הער( החדש ‪ .0‬זוהי ג התוצאה של הביטוי המורכב‬
‫כולו‪ ,‬כי התוצאה של ביטוי השמה הוא בהתא לער( המצוי במשתנה באג‪ ,‬שמאל‬
‫לאחר ההצבה‪ .‬תוצאה זו ניתנת אפילו להדפסה‪ ,‬למשל‪ ,‬ע"י המשפט הבא‪:‬‬
‫;) ))‪cout << ( n = (n != (sqrt (9 + '7') == 8‬‬
‫התוצאה של ביטוי השמה יכולה לשמש ג כער( בוליאני‪ ,‬כמו בדוגמא הבאה‪:‬‬
‫;‪if (x = 5 - y) cout << x‬‬
‫זהו משפט תקי רק תאורטית‪ ,‬א( לא מומל‪ B‬מעשית‪ ,‬ולכ הוא גור לאזהרה‬
‫המתקבלת בחלו פלט ההודעות‪" :‬אפשרות של הצבה לא תקינה"‪ .‬האזהרה נובעת‬
‫בגלל החשש לטעות ושכוונת המתכנת‪ ,‬למעשה‪ ,‬היתה לשימוש בביטוי בוליאני‪:‬‬
‫;‪if (x == 5 - y) cout << x‬‬
‫______________________________________________________________________‬
‫ ‪ 67‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬
‫‪25/04/2010‬‬
‫תרגיל מס' ‪ ' 3‬הסתעפויות )‪(I‬‬
‫בעיה )א(‪ :‬תרגול ביטויי& לוגיי&‬
‫)‪ .(1‬נתוני ביטויי לוגיי‪.b3 = (2 != 5) ,b2 = (5 == 7) ,b1 = (1 <= 6) :‬‬
‫חשבו את הביטויי הבאי רצוי תחילה בע"פ ואח"כ בעזרת תוכנית‪ ,‬שתכיל‬
‫את הביטויי ע תוספת של כל הסוגריי בהתא לסדר הנכו‪.‬‬
‫‪|| b1 && b3) .1‬‬
‫‪|| b1) && b3) .2‬‬
‫‪(b2 && b3‬‬
‫‪(b2 && (b3‬‬
‫‪(! b1 && b2 || ! b3 ) .3‬‬
‫‪(! (b1 && b2 || ! b3)) .4‬‬
‫‪((b1 == b3) || (b1 == b2) && (b3 == b2)) .5‬‬
‫‪((b1 == b3) || b1 == b2 && (b3 == b2)) .6‬‬
‫)‪ .(2‬קיימי משתני בוליאניי ‪ a‬ו ‪ .b‬פשטו את הביטויי הלוגיי הבאי‪ ,‬כלומר‪ ,‬כיתבו‬
‫)ללא תכנות( ביטויי שקולי פשוטי יותר באמצעות תכונותיה של האופרטורי‬
‫הלוגיי‪ ,‬ובידקו את תשובותיכ ע"י כתיבה של לוחות האמת שלה‪:‬‬
‫‪(a || b || ! a && ! b) .1‬‬
‫‪(! (! a || b) && ! a) .2‬‬
‫רמז‪ :‬שימו סימני סוגריי בהתא לסדר הנכו והשתמשו בחוקי ֶדהמוֹרגַ‪.‬‬
‫בעיה )ב(‪ :‬מקסימו& )מינימו&( בי( ‪ 4‬מספרי&‬
‫כיתבו תוכנית למציאת המספר המקסימלי )המינימלי( בי ‪ 4‬מספרי‪.‬‬
‫בעיה )ג(‪ :‬נוסחת הֵ ירוֹ( )‪(Heron‬‬
‫כיתבו תוכנית לחישוב שטח משולש לפי שלוש צלעותיו בעזרת נוסחת הֵ יר ֹו‪:‬‬
‫_________________‬
‫)‪S = √ d · (d - a) · (d - b) · (d - c‬‬
‫כאשר ‪ c ,b ,a‬ה הצלעות‪ d ,‬הוא מחצית ההיק‪ S ,,‬השטח‪ ,‬ו ‪ S2‬ריבוע שטח‬
‫המשולש‪ .‬התוכנית תדאג לוודא קיו )כמו של "המשולש" ‪.(2,4,7‬‬
‫הערה‪ :‬תנאי המשולש לקיומו‪ ,‬שסכו ‪ 2‬צלעות גדול מהשלישית‪ ,‬שקול ל ‪.S2 = S2 > 0‬‬
‫בעיה )ד(‪ :‬מספרי& רומיי&‬
‫הכינו תוכנית שתהפו( כל מספר טבעי )עד ‪ (5000‬לכתב רומי‪ .‬כ(‪ ,‬עבור הקלט‪,1078 :‬‬
‫הפלט יהיה‪.(I = 1 ,V = 5 ,X = 10 ,L = 50 ,C = 100 ,D = 500 ,M = 1000) MLXXVIII :‬‬
‫______________________________________________________________________‬
‫ ‪ 68‬‬
‫פרק ‪ :3‬משפט ‪if‬‬
‫ד"ר עוזי ערמו‬