Presentation is loading. Please wait.

Presentation is loading. Please wait.

הרצאה 3: משפטים, תנאים ולולאות

Similar presentations


Presentation on theme: "הרצאה 3: משפטים, תנאים ולולאות"— Presentation transcript:

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

2 מבוא למדעי המחשב. כל הזכויות שמורות ©
תוכנייה משפטים בשפת C - (Statements) משפטי תנאי לולאות for while דוגמאות: מציאת GCD (אלגוריתם אוקלידס) מציאת שורש (שיטת ניוטון-רפסון) מציאת מספר ראשוני מבוא למדעי המחשב. כל הזכויות שמורות ©

3 משפטים (פקודות) בשפת C - Statements
משפט ביטוי (expression statement): ביטוי שאחריו ';' נחשב כמשפט. לעיתים קיימות תוצאות לוואי למשפט כזה ולעיתים לא. משפט ריק (empty statement): מורכב מ-';' בלבד. אין למשפט תוצאות לוואי. משפט מורכב (compound statement): רצף משפטים המוקפים בסוגריים מסולסלים {} נחשב כמשפט אחד. רצף כזה נקרא גם בלוק. x = y++; a + b; ; { t = x; x = y; y = t; } מבוא למדעי המחשב. כל הזכויות שמורות ©

4 מבוא למדעי המחשב. כל הזכויות שמורות ©
תוכנייה משפטים בשפת C - (Statements) משפטי תנאי לולאות for while דוגמאות: מציאת GCD (אלגוריתם אוקלידס) מציאת שורש (שיטת ניוטון-רפסון) מבוא למדעי המחשב. כל הזכויות שמורות ©

5 מבוא למדעי המחשב. כל הזכויות שמורות ©
משפט if if (expression) statement זהו משפט מהצורה: אם ערך האמת של expression הינו True, מבצעים את statement. אם ערך האמת של expression הינו False, מדלגים על ביצוע statement (ועוברים למשפט הבא אחריו). לרוב, statement יהיה משפט מורכב. לדוגמה: expression ≠0 Statement if(b*b < 4*a*c) } printf(“no real solution to the quadratic equation.\n”); return 1; } מבוא למדעי המחשב. כל הזכויות שמורות ©

6 מבוא למדעי המחשב. כל הזכויות שמורות ©
משפט if-else if (expression) statement1 else statement2 זהו משפט מהצורה: אם ערך האמת של expression הינו True, מבצעים את statement1 מדלגים על statement2 ועוברים למשפט הבא. אם ערך האמת של expression הינו False, מדלגים על statement1, מבצעים את statement2 ואז ממשיכים לבא. לדוגמה: expression ≠0 st1 st2 if(tomorrow_is_rainy == ‘y’) printf(“Take your umbrella.\n"); else printf(“Leave the umbrella at home.\n"); מבוא למדעי המחשב. כל הזכויות שמורות ©

7 מבוא למדעי המחשב. כל הזכויות שמורות ©
קינון if-else מה מבצע המשפט הבא? ה-else מקושר תמיד ל-if האחרון. 1 =1 a b =2 2 if(a==1) if(b==2) printf("***"); else printf("###"); *** ### ### ### מבוא למדעי המחשב. כל הזכויות שמורות ©

8 מבוא למדעי המחשב. כל הזכויות שמורות ©
קינון if-else מה מבצע המשפט הבא? ה-else מקושר תמיד ל-if האחרון. ניתן להפריד ביניהם באמצעות {...}. 1 =1 a b =2 2 if(a==1) if(b==2) printf("***"); else printf("###"); *** *** ### ### ### ### מבוא למדעי המחשב. כל הזכויות שמורות © 8 8

9 מבוא למדעי המחשב. כל הזכויות שמורות ©
קינון if-else מה מבצע המשפט הבא? ה-else מקושר תמיד ל-if האחרון. ניתן להפריד ביניהם באמצעות {...}. 1 =1 a b =2 2 *** ### ### ### if(a==1) { if(b==2) printf("***"); } else printf("###"); מבוא למדעי המחשב. כל הזכויות שמורות © 9 9

10 מבוא למדעי המחשב. כל הזכויות שמורות ©
תוכנייה משפטים בשפת C - (Statements) משפטי תנאי לולאות for while דוגמאות: מציאת GCD (אלגוריתם אוקלידס) מציאת שורש (שיטת ניוטון-רפסון) מציאת מספר ראשוני מבוא למדעי המחשב. כל הזכויות שמורות ©

11 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאות קטע קוד המתבצע מספר פעמים נקרא לולאה (loop). מספר הפעמים תלוי בערכו של ביטוי המחושב במהלך ריצת התכנית. כל אחד מביצועי הלולאה נקרא איטרציה (iteration). ב- C קיימים שלושה משפטים המאפשרים ביצוע לולאות: while statement for statement do-while statement מבוא למדעי המחשב. כל הזכויות שמורות ©

12 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת while while (expression) statement זהו משפט מהצורה: כל עוד ערך האמת של expression הינו True, מבצעים את statement. לדוגמה, חישוב עצרת: לא ההגדרה המדויקת (נתקן כשנגיע לרקורסיה) expression ≠0 statement n! = 1*2*3 … *(n-1)*n מבוא למדעי המחשב. כל הזכויות שמורות ©

13 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת while while (expression) statement זהו משפט מהצורה: כל עוד ערך האמת של expression הינו True, מבצעים את statement. לדוגמה, חישוב עצרת: expression ≠0 statement unsigned factorial = 1; int n, i = 2; scanf(“%d”, &n); // Test for success while(i <= n) { factorial *= i++; } printf("n!= %u", factorial); מבוא למדעי המחשב. כל הזכויות שמורות © 13 13

14 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת while while (expression) statement זהו משפט מהצורה: כל עוד ערך האמת של expression הינו True, מבצעים את statement. לדוגמה, חישוב עצרת: expression ≠0 statement unsigned factorial = 1; int n, i = 1; scanf(“%d”, &n); while (i++ < n) { // Not recommended factorial *= i; } printf("n!= %u", factorial); מבוא למדעי המחשב. כל הזכויות שמורות © 14 14

15 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת do-while do statement while(expression); זהו משפט מהצורה: מבצעים את statement כל עוד ערך האמת של expression הינו True (פעם אחת לפחות). לדוגמה, קליטת מספר חיובי: statement expression ≠0 int x; do { printf("Please enter a positive number: "); scanf("%d", &x); } while (x <= 0); מבוא למדעי המחשב. כל הזכויות שמורות ©

16 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת for זהו משפט מהצורה: מבצעים את expression1 (אתחול) ואז כל עוד ערך האמת של expression2 (תנאי) הינו True, מבצעים את statement ואז expression3 (קידום). כ"א משלושת הביטויים יכול להיות ריק. שקול ל: expression1 for(expression1;expression2;expression3) statement expression2 ≠0 statement expression3 expression1 while (expression2) { statement expression3 } כמעט! מבוא למדעי המחשב. כל הזכויות שמורות ©

17 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת for - המשך sum = 0; for(i = 1; i <= n; i++) sum += i * i; חישוב הביטוי : חישוב עצרת: השווה מול השימוש ב-while: for(i = 2 ; i <= n; i++) factorial *= i; printf("n!= %d", factorial); i = 2; while(i <= n) { factorial *= i; i++; } printf("n!= %d", factorial); מבוא למדעי המחשב. כל הזכויות שמורות ©

18 דוגמה: מציאת המספר הקטן ביותר בקלט
נכתוב תוכנית המקבלת כקלט סדרה של n מספרים (שלמים) ומוצאת עבורם את הערך המינימאלי. אלגנטי? קריאת הערכים נעשית פעם מחוץ ללולאה, ובהמשך בתוכה. ואם נרצה את כל הקריאות בלולאה? נאתחל את min ל- INT_MAX קבוע המוגדר ב-limits.h וערכו הוא הערך השלם הגדול ביותר שיכול משתנה מטיפוס int לקבל. זה אינו הפתרון היחיד האפשרי! scanf("%d", &min); for(i = 1; i < n; i++) { scanf("%d", &num); if(num < min) min = num; } #include<limits.h> ... min = INT_MAX; for(i = 0; i < n; i++) { scanf("%d", &num); if(num < min) min = num; } מבוא למדעי המחשב. כל הזכויות שמורות ©

19 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאת for - המשך שימוש באופרטור פסיק ,: חישוב ביטוי מהצורה exp1, exp2 מתבצע ע"י חישוב exp1 ולאחריו חישוב exp2. ערכו (טיפוסו) של ביטוי זה הינו ערכו (טיפוסו) של exp2. קודם ראינו את התוכנית דרך נוספת לביצוע הסכום הנ"ל: ככלל, בסוגריים הצמודים ל-for יופיעו ביטויים הקשורים בבקרת הלולאה (אך לא בתכנה), ולכן נעדיף את הפתרון הראשון שראינו. sum = 0; for(i = 1; i <= n; i++) sum += i * i; for(sum = 0, i = 1; i <= n; sum += i * i, i++); מבוא למדעי המחשב. כל הזכויות שמורות ©

20 משפטי break ו- continue
משפטים מיוחדים לצורך שבירת רצף הביצוע בקוד. break כאשר מופיע בתוך switch גורם לסיום ה-switch ומעבר למשפט הבא. כאשר מופיע בתוך לולאה, גורם לסיום הלולאה ומעבר למשפט הבא. continue ניתן לשימוש בלולאות בלבד. גורם למעבר לסוף האיטרציה הנוכחית בלולאה. מבוא למדעי המחשב. כל הזכויות שמורות ©

21 מבוא למדעי המחשב. כל הזכויות שמורות ©
דוגמה לשימוש ב- break קטע קוד זה מסכם את המספרים בקלט עד (לא כולל) המספר השלילי הראשון. sum = 0; while(1) { scanf("%d",&num); if(num < 0) break; sum += num; } מבוא למדעי המחשב. כל הזכויות שמורות ©

22 דוגמה לשימוש ב- continue
קטע קוד זה מבצע קריאה של 100 מספרים שלמים וסוכם את אי-השליליים שביניהם. מה ההבדל בין הקוד העליון לקוד הבא? האם הם שקולים? בקוד זה נידרש לספק 100 מספרים אי-שליליים על מנת לסיים התוכנית. מה נדרש לשנות על מנת לקבל שקילות לתוכנית העליונה? for(i = 0; i < 100; i++) { scanf("%d",&num); if(num < 0) continue; sum += num; } i = 0; while(i < 100) { scanf("%d",&num); if(num < 0) continue; sum += num; i++; } מבוא למדעי המחשב. כל הזכויות שמורות ©

23 לתרגם לולאת for ללולאת while – קל?
for(expression1;expression2;expression3) statement בהנתן האם התרגום הבא שקול? רק אם ב- statement אין continue ! expression1 while (expression2) { statement expression3 } מבוא למדעי המחשב. כל הזכויות שמורות © 23 23

24 מבוא למדעי המחשב. כל הזכויות שמורות ©
לולאות אינסופיות לולאות בהן ערך הביטוי הנבדק שונה מ-0 תמיד. לולאות אינסופיות נגרמות לעיתים בשל שגיאה ובמקרים אלו ניתן לצאת מהן על ידי עצירת התכנית באמצעות מערכת ההפעלה (או כיבוי המחשב). ניתן לייצר לולאות אינסופיות במכוון. לדוגמה: היציאה מלולאות אינסופיות מכוונות נעשית באמצעות פקודות כגון .return, break הסיבה הנפוצה למבנה זה: תנאי היציאה מורכב מכדי להתאים לכותרת הלולאה. while(1) { … } for( ;1; ) { … } for( ; ; ) { … } מבוא למדעי המחשב. כל הזכויות שמורות ©

25 דיוק בבדיקת תנאי הלולאה
האם שתי הלולאות הבאות מבצעות את אותה הפעולה ? ככלל, נעדיף אופרטורים של סדר (>=, <=, <, >) על פני אופרטורים של השוואה (==, !=) בתנאי הביצוע של לולאות. לא תמיד ועוד פחות ב- C++ for(x = 0.0; x < 3.0; x += 0.2) for(x = 0.0; x != 3.0; x += 0.2) for (i = 0, x = 0.0; i < 15; i++, x += 1.0/5.0) for (i = 0, x = 0.0; i < 15; i++, x = i/5.0) בשימוש בערכי "נקודה צפה" האחרון עדיף ממש: אין שגיאות ניהול לולאה ואין הצטברות שגיאות עיגול מבוא למדעי המחשב. כל הזכויות שמורות ©

26 מבוא למדעי המחשב. כל הזכויות שמורות ©
תוכנייה משפטים בשפת C - (Statements) משפטי תנאי לולאות for while דוגמאות: מציאת GCD (אלגוריתם אוקלידס) מציאת שורש (שיטת ניוטון-רפסון) מציאת מספר ראשוני 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

27 מציאת המכנה המשותף הגדול ביותר (GCD)
GCD: מחלק משותף גדול ביותר (Greatest Common Divider). בהינתן שני שלמים חיוביים m ו-n gcd(m,n) הוא השלם הגדול ביותר שמחלק את שניהם. פתרון ביה"ס יסודי: פרק את שני המספרים לגורמים ראשוניים. מכפלת הגורמים הראשוניים המשותפים היא ה-GCD. לדוגמא: n=270 m=700 n = 2 * 33 * 5 m = 22 * 52 * 7 gcd(700, 270) = 2 * 5 = 10 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

28 פירוק מספר לגורמים ראשוניים
המשפט היסודי של האריתמטיקה (שהוכח ע"י אוקלידס) קובע כי כל מספר שלם יכול להיכתב בצורה ייחודית כמכפלת מספרים ראשוניים. פירוק מספר n לגורמים: אם n ראשוני, הוסף את n לקבוצת המחלקים ועצור. אחרת, עבור סדרתית על המספרים הראשוניים עד שורש n. הוסף את p, המספר הראשוני הראשון המחלק את n, לקבוצת המחלקים וחזור על התהליך עם n/p. לדוגמה, עבור n=30: = 2 * = 3 * = 5 קושי: האלגוריתם אינו מעשי עבור n גדול. למשל עבור מספר בן 18 ספרות יש צורך לעבור על כל הראשוניים עד 1,000,000,000 (השורש שלו!). מסיבה זו, פירוק לגורמים ראשוניים משמש בסיס לקריפטוגרפיה מודרנית. 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

29 אלגוריתם אויקלידס לחישוב GCD
אלגוריתם אוקלידס מתבסס על הטענות המתמטיות הבאות: q מחלק את m ואת n אם ורק אם q מחלק את n ואת r = m % n. ← נובע מהשוויון m = r + k * n. עבור n השונה מ-0 gcd(n,m%n) gcd(m,n) =. gcd(m, 0) = m עבור m שאינו 0. מה קורה אם n > m? Euclid Aristotle Eudoxus of Cnidus 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

30 מבוא למדעי המחשב. כל הזכויות שמורות ©
ההיגיון הבסיסי נניח כי qהוא מחלק כלשהו המחלק באופן שלם הן את m והן את n. נניח כי m>n. ברור כי gcd(m,n)=gcd(m-n,n) באופן דומה, gcd(m,n)=gcd(m-2n,n), וכו'. אם נמשיך בהפחתה נגיע לקשר: gcd(m,n)=gcd(n,m%n). היפוך הסדר נובע מכך שבהכרח: m%n<n. m-n m-2n m q n 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

31 אלגוריתם אויקלידס, דוגמאות
דוגמא 1 דוגמא 2 m = k*n + r n m n m 700 = 2* 270 = 1* 160 = 1* 110 = 2* 50 = 5*10 + 0 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

32 אלגוריתם אויקלידס, הוכחת נכונות
נסמן ב-mi ו-ni את ערכי המשתנים m ו-n בתום האיטרציה ה-i. שמורה (תכונה שנשמרת במהלך האלגוריתם): gcd(m0,n0) = gcd(mi,ni) הוכחת השמורה נעשית באינדוקציה על i: בסיס: מיידי. הנחה: gcd(m0,n0) = gcd(mi,ni) צעד האינדוקציה: gcd(mi+1,ni+1) = gcd(ni,mi%ni) = gcd(mi,ni) = gcd(m0,n0) בתום האיטרציה האחרונה: gcd(m0,n0) = gcd(mN,nN) = gcd(mN,0) = mN אלגוריתם טענה מתמטית הנחת האינדוקציה 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

33 אלגוריתם אויקלידס, קידוד
#include <stdio.h> int main() { int m, n; scanf("%d%d", &n, &m); if (n < 0) n = -n; if (m < 0) m = -m; while(n != 0) { int temp = n; n = m % n; m = temp; } if(m != 0) printf("The gcd is %d\n", m); return 0; RUN 4 הרצאה מבוא למדעי המחשב. כל הזכויות שמורות ©

34 דוגמה: מציאת שורשי משוואה
הגדרת הבעיה: חשב את נקודת החיתוך של פונקציה נתונה f(x) עם ה-0, כלומר פתור f(x)=0, עבור x ממשי. אפשר בשיטת חיפוש "אריה במדבר". נתחיל בקטע, [x0, x1], בו מובטח קיום פתרון ו"נסגור" עליו משני הכיוונים f(x) x0 x1 x x4 x3 x2 מבוא למדעי המחשב. כל הזכויות שמורות ©

35 דוגמה: מציאת שורשי משוואה
הגדרת הבעיה: חשב את נקודת החיתוך של פונקציה נתונה f(x) עם ה-0, כלומר פתור f(x)=0, עבור x ממשי. ניישם שיטה איטרטיבית לחיפוש הפתרון –שיטת ניוטון-רפסון. נתחיל בנקודה x0 וממנה נעדכן לנקודות המתקרבות לחציית ציר ה-x. f(x) x מבוא למדעי המחשב. כל הזכויות שמורות © 35 35

36 מבוא למדעי המחשב. כל הזכויות שמורות ©
עקרון הפעולה נזכיר פיתוח לטור טיילור סביב נקודה: לפונקציות חלקות ו- מספיק קטן, נקבל כי x f(x) x+ מבוא למדעי המחשב. כל הזכויות שמורות ©

37 מציאת שורשים בשיטת ניוטון-רפסון
שיטת ניוטון-רפסון (Newton-Raphson) - שיטה למציאת שורש של פונקציה גזירה בתחום נתון ע"י קיזוז הסטייה שלה. נתוני עזר נדרשים: נקודה x0 קרובה לשורש, ושיטה יעילה לחישוב הנגזרת של הפונקציה. x0 מבוא למדעי המחשב. כל הזכויות שמורות ©

38 שיטת ניוטון-רפסון - המשך
השיטה: חזור: עבור לנקודה שבה חותך המשיק (הנגזרת) את הציר האופקי xi+1 = xi - f(xi) / f'(xi) הנחה: הקטע איננו מכיל נקודות קיצון (שבהן הנגזרת מתאפסת) f(x0) / (x0 - x1) = tan α = f'(x0) f(x0) x1 x0 מבוא למדעי המחשב. כל הזכויות שמורות ©

39 שיטת ניוטון-רפסון - הדגמה
x1 x0 x2 x3 מבוא למדעי המחשב. כל הזכויות שמורות ©

40 שיטת ניוטון-רפסון - תנאי עצירה
בפתרון שנראה, נשתמש במספר האיטרציות כתנאי עצירה. שילוב התנאים ל- δ ו- ε נשאיר כתרגיל. | xi+1 - xi | < δ | f(xi+1) | < ε xi < ε xi+1 < δ מבוא למדעי המחשב. כל הזכויות שמורות ©

41 קוד מקור עבור הפונקציה f(x)=x2-9
#include <stdio.h> #define MAX_ITERATIONS 10 int main() { double a, fa, fda; int i; scanf("%lf", &a); fa = a*a - 9; for(i = 0; i < MAX_ITERATIONS && (fa != 0); ++i) { fa = a*a - 9; fda = 2*a; /* what if fda == 0 ? */ a = a - fa/fda; printf("Iteration: %d, Solution: %.12f\n", i, a); } printf("Solution is: %.12f\n", a); return 0; RUN בעיה: נדרש לכתוב תוכנית חדשה לכל פונקציה f. פתרון: שימוש בפונקציות ומצביעים לפונקציות (בהמשך). מבוא למדעי המחשב. כל הזכויות שמורות ©

42 אלגוריתם לבדיקת ראשוניות
בהינתן שלם חיובי n, יש לקבוע האם הוא ראשוני. n איננו ראשוני אם ורק אם יש ל-n מחלק בתחום 2,3,…,n-1. int is_prime = 1, n, i; ... if (n < 0) n = -n; if (n < 2) is_prime = 0; else { for(i = 2; i < n; i++) if(n % i == 0) } if(is_prime) printf("%d is a prime\n", n); else printf("%d is not a prime\n", n); RUN מבוא למדעי המחשב. כל הזכויות שמורות ©

43 בדיקת ראשוניות: הצעות ייעול
#include <math.h> ... int is_prime = 1, n, i; if (n < 0) n = -n; if(n < 2 || (n != 2 && n % 2 == 0)) is_prime = 0; else { int sqrt_n = sqrt(n) + 0.5; for(i = 3; i <= sqrt_n; i+=2) if(n % i == 0){ break; } printf("%d is %sa prime\n", n, is_prime ? "" : "not "); RUN אם n איננו 2 אך מתחלק ב-2 אזי הוא אינו ראשוני. מספיק לבדוק מחלקים אפשריים עד שורש n. כיוון ש-n אינו זוגי, ניתן לדלג על בדיקת המחלקים הזוגיים. כשנמצא מחלק שלם, אין סיבה להמשיך בבדיקה. מבוא למדעי המחשב. כל הזכויות שמורות ©


Download ppt "הרצאה 3: משפטים, תנאים ולולאות"

Similar presentations


Ads by Google