Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא לשפת C תרגול 4: ביטויים לוגיים ומשפטי תנאי מבוסס על השקפים שחוברו ע"י שי ארצי, גיתית רוקשטיין, איתן אביאור וסאהר אסמיר עבור הקורס "מבוא למדעי המחשב"

Similar presentations


Presentation on theme: "מבוא לשפת C תרגול 4: ביטויים לוגיים ומשפטי תנאי מבוסס על השקפים שחוברו ע"י שי ארצי, גיתית רוקשטיין, איתן אביאור וסאהר אסמיר עבור הקורס "מבוא למדעי המחשב""— Presentation transcript:

1 מבוא לשפת C תרגול 4: ביטויים לוגיים ומשפטי תנאי מבוסס על השקפים שחוברו ע"י שי ארצי, גיתית רוקשטיין, איתן אביאור וסאהר אסמיר עבור הקורס "מבוא למדעי המחשב" נכתב ע"י טל כהן, עודכן ע"י יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל

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

3 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©3 טיפוסי משתנים בשבוע שעבר פגשנו מבחר טיפוסים שונים למשתנים: * זהו הגודל ש-Turbo C מקצה עבור משתנים מסוג זה. מהדרים שונים יכולים להקצות גדלים שונים! למשל, במהדרים רבים int הוא בן 4 בתים. קלט/פלט ע"י* sizeofסוג המידע הנשמרשם הטיפוס %d או %c1מספרים שלמיםchar %d2מספרים שלמיםint %ld4מספרים שלמיםlong int %f4מספרים עם שבריםfloat %lf8מספרים עם שבריםdouble

4 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©4 char: מספר או תו? תזכורת:ערך משתנה char הינו אוסף של סיביות ( כמו כל משתנה אחר ) אפשר לפרש אותו כמספר בין -128 ל-127. אפשר גם לפרש אותו כאחד מ-256 תווי ASCII. כאשר מדפיסים משתנה char עם %c, תוכן המשתנה מתורגם לתו. כאשר קולטים משתנה char עם %c, scanf קולטת תו אחד, מתרגמת אותו לסיביות לפי טבלת ASCII ושומרת את התוצאה בתוך המשתנה. עבור כל פעולה אחרת (+, -, *,/,%, הדפסה/קלט עם %d וכו') מתייחסים למשתנה char כאל מספר!

5 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©5 שימוש בתווים בתוכנית ניתן לקבוע את ערכו של משתנה מסוג char לא רק בעזרת השמת ערך מספרי, אלא גם בעזרת השמת תו: char ch = 'B'; פעולה זאת לא באמת קובעת את ch להיות "תו", אלא ערכו נקבע להיות שווה לערך ASCII של B. כעת אם נדפיס את ch עם %c באמת נקבל B על המסך: printf("Numeric value is %d, character is %c", ch, ch); ידפיס: Numeric value is 66, character is B גרש ולא מרכאות !

6 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©6 סדר פעולות ואופרטורים ראינו שבשפת C מוגדר "סדר פעולות". –למשל, כפל קודם לחיבור. הכרנו כמה אופרטורים מיוחדים: –% - מודולו, שארית חלוקה (רק למספרים שלמים!). –++ - קידום משתנה (לפני או אחרי שם המשתנה, עם השפעות שונות) –-- - נסיגה של משתנה (כנ"ל) אופרטור נוח נוסף הינו השמה מקוצרת: +=, -=, וכו' –משמעותו של x+=y; הינה ;x=x+y, וכו'

7 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©7 המרת טיפוסים פגשנו שני סוגי המרות: –המרה אוטומטית – מתבצעת עבורנו מבלי שנבקש –המרה מכוונת – מתבצעת על-פי בקשה מפורשת המרה אוטומטית מתבצעת כשאנו מנסים להפעיל אופרטור על שני ערכים מטיפוסים שונים. המרה מכוונת נקראת לעיתים cast או type-cast. משתמשים בה כאשר תוצאה המתקבלת ע"י המרה אוטומטית היא לא התוצאה רצויה. –למשל בשביל לקבל תוצאה עם שארית בחלוקה של שלמים –אופן הכתיבה: (type)expression

8 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©8 המרת טיפוסים - דוגמה מה בעצם מתרחש בדוגמה הבאה? int a = 1,b = 2; double result = (double) a / b; 1.לפעולת cast יש קדימות על פעולת החלוקה, לכן קודם כל מתבצעת המרה מכוונת של ערך המשתנה a מ-int ל-double. 2.על מנת לבצע חלוקה, ערכים משני הצדדים חייבים להיות מאותו טיפוס. לכן מתבצעת המרה אוטומטית של ערך המשתנה b מ- int ל-double. 3.מתבצעת חלוקה: 1.0/2.0=0.5. 4.תוצאת החלוקה של שני double הינה double. לכן אין צורך בהמרה נוספת ומתבצעת השמה.

9 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©9 מצא את ה-BUG מצא שלוש שגיאות בתוכנית הבאה: #include int main(void) { char c="Y"; int price = 1999999; double half_price = (double)(price/2); printf("UPPER CASE: %c, lower case: %c\n", c, c-’A’+’a’); printf("Half price of 1,999,999 is %.2lf\n", half_price); return 0; } אילו מהשגיאות תתגלו בשלב הקומפילציה? מה עושה החישוב הזה?

10 ביטויים לוגיים

11 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©11 מהם ביטויים לוגיים? במהלך הפעולה של תוכנית, לעיתים קרובות נרצה שהתוכנית תקבל החלטה לפי ערכים שונים. למשל, "אם x>54, הדפס 'הצלחת', אחרת הדפס 'נכשלת'." החלטות יכולות להתקבל על-סמך ביטויים לוגיים, שהם: –השוואה בין מספרים (למשל, "אם x שווה בדיוק ל-100") –השוואה יחסית בין מספרים (למשל, "אם x>54") –צירוף בין כמה ביטויים פשוטים יותר (למשל, "אם x>54 וגם homework>60")

12 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©12 ייצוג ערכי אמת לכל ביטוי לוגי יש ערך אמת. ערך האמת הוא true או false ("נכון" או "שגוי"). למשל, לביטוי “x>54” יש ערך אמת true אם x גדול מ-54, וערך אמת false אחרת. אם לביטוי יש ערך אמת true, נהוג לומר שהביטוי "מתקיים". בשפות תכנות מתקדמות יש טיפוס מיוחד לערכי אמת. בשפת C הייצוג פשוט יותר: –ערך מספרי 0 מייצג false. –ערך מספרי שונה מ-0 (ובפרט, הערך 1) מייצג true.

13 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©13 פעולות השוואה כאופרטורים כעת אפשר לראות כיצד פעולות השוואה בין ערכים פועלות: אם ההשוואה מצליחה, לביטוי יש ערך 1 (כלומר, true). אחרת, לביטוי יש ערך 0 (כלומר, false). למשל, מה תדפיס התוכנית הבאה? int x = 79; int passing = (x > 54); printf(“Passing status: %d\n”, passing); למעשה, זו אינה תוכנית מלאה אלא קטע קוד. לעיתים קרובות נסתפק בהצגת קטע הקוד המהווה את "לב" התוכנית במקום להציג את התוכנית כולה.

14 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©14 אפשר להשוות כל מיני דברים... ההשוואות שהצגנו עד כה היו השוואות בין משתנים לקבועים (למשל, בין x ל-54). למעשה, ניתן להשוות בין כל צמד ביטויים. למשל, כל אלה הם ביטויים לוגיים תקינים: x + 5 > 3 * y 35 > 42 x < x + 1 וכן הלאה... האם תוכלו לדעת מה ערכו של כל ביטוי? שימו לב לחשיבות סדר הפעולות בחישוב ביטוי זה!

15 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©15 אופרטורים להשוואה ראינו את האופרטורים, להשוואה מסוג "גדול מ-" או "קטן מ-". אופרטורים נוספים: גדול-או-שווה: x >= y (בכתיבה מתמטית, x ≥y) קטן-או-שווה: x <= y (בכתיבה מתמטית, x≤ y) שווה בדיוק: x == y. שונה: x != y (בכתיבה מתמטית, x  y).

16 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©16 זהירות! ההבדל בין השמה להשוואה שימו לב: בהשוואה משתמשים בסימן "שווה" כפול. שימוש בסימן שווה יחיד פירושו השמה ולא השוואה! x = 3; ← Set the value of x to 3 x == 3 ←Logical expression, equals “1” if x is exactly 3, “0” otherwise. קל להתבלבל בין השניים; שימוש שגוי יוביל לתוצאות לא צפויות...

17 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©17 שילוב בין כמה השוואות נניח שאנו רוצים לבדוק אם ערך המשתנה temp נמצא בין 0 ל-100. –(אם למשל temp מייצג את טמפרטורת המים, נדע שהם במצב נוזלי). האם התוכנית הבאה תעבוד? double temp; int is_liquid; printf(“Enter temprature: ”); scanf(“%lf”, &temp); is_liquid = (0 < temp < 100); printf(“Is liquid (1=yes, 0=no): %d\n”, is_liquid);

18 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©18 והתוצאה... מצויין. מה קורה פה!?

19 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©19 הסבר כזכור, פעולת השוואה מניבה ערך מספרי: –1 אם ההשוואה "הצליחה", –0 אם ההשוואה "נכשלה". לכן, הביטוי 0 < temp < 100 עבור temp=249.12 חושב כך: 0 < 249.12 < 100 ראשית, מחשבים את 0 < temp. ההשוואה מתקיימת, כלומר התוצאה היא 1. כעת, מחשבים את 1 < 100... והתוצאה היא כמובן שוב 1!

20 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©20 אלגברה בוליאנית אם השיטה הקודמת נכשלה, כיצד ניתן לבצע כמה השוואות? התשובה: אלגברה בוליאנית. אופרטורים באלגברה בוליאנית מאפשרים "להשוות" בין ערכים בוליאניים. למעשה, אנחנו רוצים לחשב את: "temp>0 וגם temp<100" האופרטור "וגם" הוא אופרטור בוליאני ה"מקשר" בין שני ביטויים לוגיים. בשפת C, אופרטור זה נכתב: &&

21 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©21 התוכנית המתוקנת double temp; int is_liquid; printf(“Enter temprature: ”); scanf(“%lf”, &temp); is_liquid = (0 < temp) && (temp < 100); printf(“Is liquid (1=yes, 0=no): %d\n”, is_liquid);

22 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©22 אופרטורים בוליאניים אופרטור "וגם", x && y, מתקיים רק אם גם x וגם y הם true (כלומר, שונים מאפס). אופרטור "או", x || y, מתקיים אם לפחות אחד משני הביטויים x ו-y הוא true (כלומר, שונה מאפס). – כלומר או x, או y, או שניהם true. xyx && yx || y 0000 0לא 001 001 11 טבלה זאת נקראת טבלת אמת

23 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©23 עוד אופרטור בוליאני האופרטור הבוליאני האחרון הוא ! ("not"). אופרטור זה "הופך" את ערך האמת של ביטוי. –כמו סימן מינוס במתמטיקה, שהופך חיובי לשלילי ולהיפך. אם האופרטור פועל על 0, התוצאה היא 1. אם האופרטור פועל על ערך שונה מ-0, התוצאה היא 0. למשל: int test = 85; int homework = 65; int passing = !(test < 55 || homework < 80);

24 משפטי if

25 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©25 משפטי if: מוטיבציה עד כה, השתמשנו בתוצאות של ביטויים לוגיים פשוט כדי להדפיס ערכים (0 או 1 עבור false או true, בהתאמה). אבל כזכור, רצינו לגרום לתוכנית להתנהג באופן שונה על-פי בדיקות שונות. למשל, "אם x>54, הדפס 'הצלחת', אחרת הדפס 'נכשלת'." ניתן לבצע זאת בשפת C בעזרת משפטי if. –נקראים לעיתים "משפטי תנאי".

26 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©26 משפטי if מבנה משפט if הוא פשוט: if (expression) statement; expression הוא ביטוי כלשהו... –הסוגריים חייבים להופיע סביב הביטוי, הם חלק ממבנה פקודת if. אם הביטוי שונה מאפס, תתבצע הפקודה statement. אם הביטוי שווה לאפס, הפקודה statement לא תתבצע והתוכנית תמשיך לפקודה שבאה אחרי if. למשל: if (x < 55) printf(“You have failed!”); חשוב לזכור שזהו ביטוי המחושב ל-1 או 0. באופן כללי ניתן לשים ב-if כל ערך או ביטוי מספרי!

27 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©27 עוד דוגמא double temp; int is_liquid; printf(“Enter temprature: ”); scanf(“%lf”, &temp); is_liquid = (0 < temp) && (temp < 100); if (is_liquid) printf(“In liquid state.”); if (temp < 0) printf(“Frozen.”); if (temp > 100) printf(“Boiled.”);

28 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©28 עוד דוגמא int grade; printf(“Enter test grade: ”); scanf(“%d”, &grade); if (grade < 55) printf(“Failed.”); if (grade >= 55) printf(“Passed.”); שתי הבדיקות (השוואות של grade לקבוע 55) משלימות זו את זו: אם אחת מתקיימת, השניה בהכרח נכשלת, ולהיפך. מצבים כאלה (אם... אחרת...) הם מאוד נפוצים.

29 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©29 אם... אחרת... בגלל שמצבים של תנאים משלימים הם נפוצים, ישנו מבנה מיוחד בשפת C החוסך את הצורך בשתי בדיקות נפרדות. המבנה הוא: if (expression) statement 1 ; else statement 2 ; אם expression מתקיים, תבוצע הפקודה statement 1. אחרת, תבוצע הפקודה statement 2. בכל מקרה תבוצע רק אחת (ובדיוק אחת) משתי האפשרויות!

30 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©30 למשל... int grade; printf(“Enter test grade: ”); scanf(“%d”, &grade); if (grade < 55) printf(“Failed.”); else printf(“Passed.”); זוהי גרסה גם קלה יותר לכתיבה וגם קלה יותר להבנה, של הדוגמא הקודמת. הבדיקה מתבצעת רק פעם אחת!

31 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©31 שבירת שורות ארוכות משפטי if בכלל, ומשפטי if…else בפרט, עשויים ליצור שורות ארוכות בתוכנית. מומלץ לפרק שורות כאלה לחלקים, למשל כך: if (grade < 55) printf(“Failed.”); else printf(“Passed.”); הרווח משמאל שורות ה-statement נקרה הזחה (indentation). הוא מקל על הבנת התוכנית: במקרה זה, פקודה מוזחת היא פקודה שלא בהכרח תתבצע; היא לא חלק מחויב מרצף פעולת התוכנית.

32 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©32 עוד על הזחה חשוב להדגיש שמבחינת המהדר, –לא חשוב היכן "תשברו שורה", –אין כל משמעות מעשית להזחה. ההזחה נועדה לעזור לנו, בני-האדם, הקוראים את הקוד. היא הופכת את הקוד לקל יותר להבנה. בתרבות התכנות, הזחה אינה אופציונלית: ללא הקפדה על הזחה, קשה מאוד להבין תוכניות! –וקשה מאוד לתת להן ציונים גבוהים...

33 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©33 יותר מפעולה אחת לעיתים נרצה שאם תנאי כלשהו מתקיים, תבוצע יותר מפקודה אחת. למשל, מה תדפיס התוכנית הבאה? int grade = 25; printf(“The grade is %d\n”, grade); if (grade > 54) printf(“Passed.\n”); printf(“Very good!\n”); מה קורה פה!?

34 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©34 הסבר פשוט... כמו שאמרנו, מבחינת המהדר אין חשיבות למקום בו אתם "שוברים שורה". עם הזחה נכונה, התוכנית הקודמת נראית בעצם כך: int grade = 25; printf(“The grade is %d\n”, grade); if (grade > 54) printf(“Passed.\n”); printf(“Very good!\n”); כעת קל לראות שה-printf האחרון מתבצע בכל מקרה – הוא כלל לא קשור ל-if!

35 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©35 בכל זאת, יותר מפעולה אחת אז איך אפשר לבצע יותר מפעולה אחת בעזרת פקודת if? התשובה: שימוש בסוגריים מסולסלים. בעזרת סוגריים מסולסלים, ניתן "לקבץ" כמה statements כך שיתבצעו יחדיו, בהתאם לתנאי של ה-if. למשל: int grade = 25; printf(“The grade is %d\n”, grade); if (grade > 54) { printf(“Passed.\n”); printf(“Very good!\n”); }

36 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©36 אפשר גם ב-else... if (grade > 54) { printf(“Passed.\n”); printf(“Very good!\n”); } else { printf(“Failed.\n”); printf(“What a pity!\n”); } קבוצת פקודות בתוך סוגריים מסולסלים נקראת לעיתים "בלוק".

37 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©37 אפשר גם עבור פקודה בודדת... אפשר להשתמש בסוגריים מסולסלים גם כדי להקיף פקודה בודדת. לדעת רבים, התוצאה ברורה וקריאה יותר. למשל: if (grade < 55) { printf(“Failed.”); } else { printf(“Passed.”); }

38 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©38 סגנונות כתיבה יש מתכנתים שמעדיפים לפתוח את הסוגריים באותה שורה: if (grade < 55) { printf(“Failed.”); } else { printf(“Passed.”); } זוהי העדפה סגנונית – שתי השיטות קבילות, כל עוד שומרים על הזחה מדויקת. למהדר זה לא משנה כלום!

39 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©39 הזחה שגויה מה תבצע התוכנית הבאה עבור grade=40? if (grade < 55) if (grade > 52) grade = 55; /* factor */ else printf(“Passed without factor.”); else שייך ל-if האחרון! לכן התוכנית תדפיס “Passed without factor.” – לא מה שציפינו. תוצאה של הזחה שגויה יכולה להיות תוכנית שגויה. יש להקפיד על הזחה נכונה! כך ב-C כותבים הערות – טקסט שעוזר לנו להבין את התוכנית ושהמהדר מתעלם ממנו

40 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©40 תיקון איך אפשר לגרום ל-else להיות שייך לא ל-if האחרון? ע"י סוגריים מסולסלים: if (grade < 55) { if (grade >= 53) grade = 55; } else printf(“Passed without factor.”); עכשיו התוכנית תדפיס “Passed without factor.” רק כאשר grade>=55.

41 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©41 חידה קטע הקוד הבא מגיע מתוכנת בקרה של מטוס קל. אם הגובה הוא מעל 10,000 רגל, והמהירות קטנה מ-100 קמ"ש, יש סכנת התרסקות ומדפיסים אזהרה. האם תוכלו למצוא דרך פשוטה יותר לכתוב את הקוד? if (altitude > 10000) { if (airspeed < 100) { printf(“Warning! Crash danger!”); } שימו לב להזחה הכפולה!

42 4 תרגולמבוא למדעי המחשב. כל הזכויות שמורות ©42 עוד חידה באותה תוכנת בקרה למטוס, המשתנה visibility מציין את מידת הראות. הערך הוא תמיד אי-שלילי (אפס או יותר). אם הראות שווה לאפס, מדליקים מנורה אדומה. האם תוכלו למצוא דרך חלופית לכתוב את הקוד? איזו שיטת כתיבה עדיפה לדעתכם? if (visibility == 0) { turn_on_red_light(); }


Download ppt "מבוא לשפת C תרגול 4: ביטויים לוגיים ומשפטי תנאי מבוסס על השקפים שחוברו ע"י שי ארצי, גיתית רוקשטיין, איתן אביאור וסאהר אסמיר עבור הקורס "מבוא למדעי המחשב""

Similar presentations


Ads by Google