Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא כללי למדעי המחשב פונקציות www.cs.tau.ac.il/courses/cs4math/09b.

Similar presentations


Presentation on theme: "מבוא כללי למדעי המחשב פונקציות www.cs.tau.ac.il/courses/cs4math/09b."— Presentation transcript:

1 מבוא כללי למדעי המחשב פונקציות

2 שאלה כיצד נוכל לחשב את הסכום הבא: = ?

3 פתרון אפשרי #include <stdio.h> int main() { int i; double sum=0, result=1; for(i=1; i<=20; i++) result=result*2; sum +=result; result=1; for(i=1; i<=15; i++) result=result*3; for(i=1; i<=17; i++) result=result*5; printf(“2^20 + 3^15 + 5^17= %g”, sum); return 0; } אם היו יותר מחוברים - היינו צריכים לחזור פעמים נוספות על אותן שורות עם מספרים אחרים זה מאריך את התוכנית פי כמה וכמה, מסרבל אותה, ויוצר פתח לבאגים

4 מה היינו רוצים? היינו רוצים להגדיר פעם אחת פקודה חדשה, שתבצע חישוב של חזקה, ואז להשתמש בפקודה החדשה הזאת כמה פעמים, כל פעם עבור מספרים אחרים. למשל היינו רוצים שנוכל לחשב את התוצאה של על-ידי: sum = power (2, 20) + power (3,15) + power (5,17); שפת C אכן מאפשרת הגדרת פקודות חדשות, כפי שניראה היום. פקודות חדשות כאלה נקראות ב-C "פונקציות".

5 איך זה ניראה ב-C הגדרת הפונקציה מופיעה לפני התוכנית (לפני ה- (main
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; הגדרת הפונקציה מופיעה לפני התוכנית (לפני ה- (main

6 איך זה ניראה ב-C ההגדרה כוללת את שם הפונקציה #include <stdio.h>
double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; ההגדרה כוללת את שם הפונקציה

7 איך זה ניראה ב-C ההגדרה כוללת את שם הפונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; ההגדרה כוללת את שם הפונקציה היא כוללת גם את המשתנים שעליהם הפונקציה מוגדרת (בדומה לפונקציות במתמטיקה)

8 איך זה ניראה ב-C ההגדרה כוללת את שם הפונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; ההגדרה כוללת את שם הפונקציה היא כוללת גם את המשתנים שעליהם הפונקציה מוגדרת (בדומה לפונקציות במתמטיקה) ואת סוג הערך שהפונקציה מחשבת ("מחזירה")

9 איך זה ניראה ב-C #include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; השורה הראשונה נקראת "כותרת הפונקציה" (header, prototype) גוף הפונקציה (מה שרוצים שיתבצע כשמשתמשים בה) מופיע אחרי הכותרת בתוך סוגריים מסולסלים. פקודת return אומרת מה ערך הפונקציה ("מה היא מחזירה")

10 איך זה ניראה ב-C #include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; השורה הראשונה נקראת "כותרת הפונקציה" (header, prototype) כאן גוף הפונקציה מחשב כמה זה base בחזקת exponent ושם את התוצאה במשתנה בשם result הפונקציה הזו מחזירה את הערך שנמצא במשתנה בשם result

11 איך זה ניראה ב-C #include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; כשמשתמשים בפונקציה, רושמים בסוגריים עבור איזה ערכים מעוניינים לחשב אותה ריצת התוכנית תמיד תתחיל כאן: בזמן הריצה, כשמגיעים לשימוש בפונקציה, המחשב יעבור לחשב את ערך הפונקציה, ורק לאחר מכן ימשיך בתוכנית

12 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0;

13 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; solution

14 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; solution

15 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 solution

16 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i solution

17 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 1 result solution

18 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 1 1 result solution

19 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 1 2 result solution

20 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 2 2 result solution

21 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 2 4 result solution

22 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 11 אחרי 10 איטרציות 1024 result solution

23 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; base 2 exponent 10 i 11 1024 result solution

24 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; 1024 solution

25 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; 1024 solution 1024

26 הדגמת הריצה בשימוש פונקציה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,10); printf(“2^10 = %g”, solution); return 0; 1024 solution 1024

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

28 שימוש בפונקציות בתכנות קורה לעיתים קרובות שרוצים להגדיר פקודות חדשות.
הסיבה הנפוצה ביותר לכך היא כשרוצים להשתמש באותו קטע תוכנית כמה פעמים בתוכנית (יתכן שעם נתונים שונים). שפת C מאפשרת כאמור להגדיר פקודות חדשות (שנקראות "פונקציות"), ולאחר מכן להשתמש בהן. הגדרות פונקציות יופיעו לפני התוכנית הראשית (לפני ה- main). נתאר מה הגדרה כזאת כוללת (כותרת הפונקציה וגוף הפונקציה).

29 מה כוללת הגדרת פונקציה (פקודה חדשה)?
1. השם שבחרנו לפונקציה (למשל power עבור חזקה). - כללי השמות המותרים הם כמו הכללים לשמות-משתנים. - אסור לתת לפונקציה שם שכבר נתנו למשתנה. 2. איזה ערכים דרושים לביצוע הפונקציה ("המשתנים שעליהם היא פועלת"). - למשל לחישוב חזקה דרושים שני ערכים (בסיס ומעריך). שניהם אמורים להיות מספרים ממשיים. 3. סוג הערך שהפונקציה מחשבת ("מחזירה"). למשל התוצאה של חזקה היא מספר ממשי. - כל אלה נקראים "כותרת הפונקציה" (prototype, header).

30 דוגמא: כותרת להגדרת פונקציה שמחשבת חזקה
double power (double base, double exponent) הערכים שהפונקציה מקבלת שם סוג הפונקציה הערך המוחזר (מוגדרים עבורם משתנים, שיש להם שמות, כך שניתן להשתמש בהם לתיאור גוף הפונקציה)

31 דוגמא: אם מגדירים חזקה רק למעריכים שלמים
double power (double base, int exponent) הערכים שהפונקציה מקבלת שם סוג הפונקציה הערך המוחזר (מוגדרים עבורם משתנים, שיש להם שמות, כך שניתן להשתמש בהם לתיאור גוף הפונקציה)

32 מה עוד כוללת הגדרת פונקציה (פקודה חדשה)?
4. צריך כמובן לרשום את קטע-התוכנית שמבצע את הפקודה החדשה (מה שאנחנו רוצים שיקרה כשמשתמשים בה). יופיע בתוך סוגריים מסולסלים אחרי כותרת הפונקציה. מותר להגדיר בתחילתו משתנים נוספים. 5. צריך להגדיר מה הערך שהפונקציה מחזירה. - נעשה בעזרת פקודת return.

33 דוגמא: הגדרת פונקציה לחישוב חזקה
double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } חישוב החזקה (הערך שנמצא במשתנה base בחזקת הערך שנמצא במשתנה exponent) הערך שהפונקציה מחשבת (מחזירה)

34 הגדרת פונקציות לסיכום, הגדרת פונקציה מבוצעת באופן הבא: למשל:
(הגדרת משתנים לערכים שמועברים לפונקציה) שם הפונקציה טיפוס הערך המוחזר { פקודות הפונקציה return הערך המוחזר למשל: double power(double base, int exponent) int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } בתוך פונקציה אפשר לעשות כל מה שאפשר לעשות ב- main: להגדיר משתנים ולבצע פקודות (כולל להפעיל פונקציות).

35 שימוש בפונקציה ("קריאה לפונקציה")
בשימוש בפונקציה רושמים את שמה, ורושמים בסוגריים עבור איזה ערכים ספציפיים רוצים להשתמש בה. למשל: result=power(5,10); a=32*(power(b,5)+17); הערכים יכולים להיות גם ערכים של משתנים או תוצאה של חישוב (צריכים להתאים לטיפוסים שנקבעו בהגדרת הפונקציה). כשקוראים לפונקציה, המחשב עובר לבצע את קטע-התוכנית של הפונקציה, מחשב מה הערך שלה (כלומר מה הערך שהיא מחזירה), ולאחר מכן ממשיך בביצוע התוכנית. ניתן לשמור את הערך המוחזר במשתנה או לבצע איתו חישובים. התחלת הריצה היא תמיד ב- main.

36 דוגמא: שימוש בפונקציית חזקה
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; ריצת התוכנית תמיד תתחיל כאן: הפונקציה נקראת (מחושבת) כל פעם עבור הערכים המתאימים, והתוצאות מוחזרות

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

38 פונקציות – סיום הפונקציה
אם הפונקציה אמורה להחזיר ערך, צריך לסיים אותה על-ידי פקודת return, שבה מוחזר ערך מטיפוס מתאים (ריצת הפונקציה נפסקת ע"י פקודת return). יכולות להיות לפונקציה כמה אפשרויות סיום, שהבחירה ביניהן תתבצע לפי תנאים. למשל: int greater(int a, int b) { if (a>b) return 1; else return 0; } עם סיום ריצת הפונקציה, חוזרים למקום שממנו הפונקציה נקראה. כל המשתנים שלה מתבטלים ולא מוגדרים יותר.

39 פונקציות - דוגמא #include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; הפונקציה נקראת (מחושבת) כל פעם עבור הערכים המתאימים, והתוצאות מוחזרות

40 mainפונקציית כל תוכנית C מכילה פונקציה בשם main, שבה התוכנית מתחילה.
הערך שמוחזר ממנה מועבר למערכת ההפעלה. טיפוסו צריך להיות int. אם ערכו 0 המשמעות היא שהתוכנית הסתיימה באופן תקין. פונקציית main יכולה גם לקבל משתנים ממערכת ההפעלה (ערכים שנכתבים בשורת הפקודה כשמריצים את התוכנית), אבל יכולה לפעול גם בלי לקבל משתנים. int main() { printf(“Hello World!\n”); return 0; }

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

42 סיבות נוספות לשימוש בפונקציות
כדי להשתמש בחלק מתוכנית שכתבנו בתוכניות אחרות שנכתוב. נוכל להכין ספריות של פונקציות שימושיות שכתבנו ולהשתמש בהן בתוכניות אחרות שנכתוב. יש כבר ספריות מוכנות כאלה ב- C, כמו stdio.h.

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

44 משתנים בפונקציה -דוגמא
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double solution; solution=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, solution); return 0; base, exponent, i, result מוגדרים רק בתוך הפונקציה power solutionהמשתנה main מוגדר רק בתוך הפונקציה

45 משתנים בפונקציה - דוגמא
#include <stdio.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } int main() double i; i=power(2,20)+power(3,15)+power(5,17); printf(“2^20 + 3^15 + 5^17= %g”, i); return 0; אפשר להגדיר בפונקציות שונות משתנים באותו שם, והם אינם קשורים זה לזה

46 פונקציות – העברת ערכים נשים לב: לפונקציה מועברים ערכים – לא משתנים. שינויים במשתנה שאליו הוכנס הערך לא משפיעים על המשתנה המקורי. למשל בדוגמא הבאה: #include<stdio.h> int square (int num) { num=num*num; return num; } int main() int num=16; printf(“%d is the square of %d”, square(num), num); return 0; הפלט: 256 is the square of 16

47 פונקציות – העברת ערכים נשים לב: לפונקציה מועברים ערכים – לא משתנים. שינויים במשתנה שאליו הוכנס הערך לא משפיעים על המשתנה המקורי. למשל בדוגמא הבאה: #include<stdio.h> int square (int num) { num=num*num; return num; } int main() int num=16; printf(“%d is the square of %d”, square(num), num); return 0; הפלט: 256 is the square of 16 כאן מועבר הערך 16 המשתנה num שב- main לא מושפע מהשינויים במשתנה שאליו הועבר ערכו

48 משתנים גלובליים אפשר, אבל לא מומלץ, להגדיר משתנים בתחילת הקובץ, לא בתוך אף פונקציה. במקרה כזה הם יהיו מוגדרים בכל הפונקציות שמופיעות בקובץ. זה נקרא "משתנים גלובליים". זה לא מומלץ כי זה עלול ליצור באגים (עושים שינוי בפונקציה אחת ולא שמים לב שזה משפיע על פונקציה אחרת), ופוגע בהפרדה הלוגית בין הפונקציות.

49 קבועים הזכרנו בעבר שאפשר להגדיר משתנה שערכו ישאר קבוע על-ידי תוספת המילה const: const double pi=3.1415; אמרנו שמעדיפים לראות בתוכנית שמות משמעותיים של קבועים מאשר מספרים שמקורם לא ברור. אבל אמרנו שמשתנה יוגדר רק בתוך פונקציה מסויימת. אם רוצים להגדיר ערכים קבועים שיהיו בשימוש כל חלקי התוכנית, אין צורך במשתנה גלובלי, וניתן להגדיר קבוע על-ידי: #define pi זו פקודה ל- preprocessor שמחליפה את המילה pi במספר בכל התוכנית לפני תחילת התרגום לשפת מכונה.

50 הכרזה על פונקציות אמרנו שכדי להשתמש בפונקציה, צריך שהיא תהיה מוגדרת.
לכן רשמנו תמיד את הפונקציה לפני ה- main, שבו השתמשנו בה. אופציה נוספת היא לרשום הכרזה (declaration) של הפונקציה בתחילת הקובץ, ולרשום את המימוש שלה (definition) בסופו, או בקובץ נפרד.

51 הכרזה על פונקציות דוגמא להכרזה ((declaration, prototype:
double power(double base, int exponent); ומותר גם בלי שמות המשתנים: double power(double, int); כשרק בסוף הקובץ נרשום את ההגדרה המלאה (definition): double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } שימו לב שבהגדרת פונקציה אין ; בכותרת (רק בהכרזה)

52 הכרזה על פונקציות – למה זה טוב
לפעמים נוח לראות בתחילת הקובץ את הפונקציות העיקריות ולהשאיר את פונקציות העזר בסוף. הרבה פעמים התוכנית מחולקת לכמה קבצים שאומרים לקומפיילר לצרף יחד, ואז ההגדרה (המימוש) של הפונקציה צריכה להופיע רק באחד מהם, ובאחרים מופיעה רק ההכרזה. בפרט, זה המצב כשאנחנו משתמשים בספריות של פונקציות, כמו stdio.h.

53 הכרזה על פונקציות – ספריות
השורה #include<stdio.h> פשוט אומרת לקומפיילר לצרף לתחילת הקובץ שלנו את הקובץ stdio.h מתוך קבצי ההכרזות של C. הקובץ הזה מכיל הכרזות של פונקציות קלט/פלט שימושיות (כמו printf,scanf). כך אנחנו יכולים להשתמש בהן בתוכנית שלנו בלי להכיר את המימוש שלהן, ובזמן הקומפילציה הלינקר מצרף את המימוש מתוך הספריות הקיימות של C.

54 ספריות נוספות ב- C יש ספריות נוספות שנוכל להשתמש בהן. למשל ב- math.h נוכל למצוא פונקציות כמו sin,cos,tan,abs,fabs,log,sqrt,pow ב- ctype.h יש פונקציות שעוסקות בסוג של תווים, כמו islower, toupper, ועוד. תכירו בהמשך ספריות נוספות.

55 העברת מערך לפונקציה כיצד נכתוב פונקציה שמקבל כערך מערך ומבצעת חישוב על איבריו? נניח שנרצה לכתוב פונקציה שמקבלת מערך של מספרים ומחזירה את סכום איברי המערך. העברת מערך לפונקציה מתבצעת למעשה ע"י העברת כתובת ההתחלה של המערך. int sum(int a[ ], int size); prototype

56 העברת מערך לפונקציה aזהו פשוט כתובת ההתחלה של מערך של int.
הפרמטר השני הוא גודל המערך. הפרמטר הראשון לפונקציה הוא כתובת ההתחלה של המערך ואינו נותן מידע לגבי גודל המערך. לכן, נעביר את המידע הזה כפרמטר נוסף לפונקציה.

57 דוגמא: פונקציה שסוכמת מערך של שלמים
#include <stdio.h> int calc_sum(int arr[ ], int size) { int i, sum = 0; for(i=0; i<size; i++) sum=sum+arr[i]; return sum; } int main() { int input[10], i; for(i=0; i<10; i++) scanf("%d", &input[i]); printf("The sum is %d\n", calc_sum(input, 10)); return 0; פונקציית הסכום (גודל המערך מועבר במשתנהsize ) עוברים על תאי המערך בלולאה, סוכמים אותם, ומחזירים את הסכום. קליטת ערכים למערך קריאה לפונקציה והדפסת התוצאה

58 העברת מערך לפונקציה ההגדרות הבאות שקולות: int f(float arr[]);

59 מחרוזות מחרוזות ב C הן פשוט מערכים שאיבריהם הם תווים.
המוסכמה בנוגע למחרוזות היא שמחרוזות מסתימות ב תו מיוחד אשר מסמן את סוף המחרוזת. תו זה הוא ‘\0’ שקוד ה ascii שלו הוא 0.

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

61 מחרוזות int strlen(char s[ ]) { int cnt=0; while ( s[cnt] != ’\0’ )
return cnt; } מה עושה הפונקציה הזו? איפה משתמשים בעובדה שמחרוזת מסתיימת בתו מסוים?

62 סימון סוף המחרוזת: התו המיוחד '0\'
כל הפעולות שנכיר על מחרוזות דואגות בעצמן לשמירת המוסכמה הזו של תו הסיום. למשל פעולת האיתחול הזו: char word[ ]=“HELLO”; שקולה לפעולת האיתחול הזו: char word[ ]={‘H’,’E’,’L’,’L’,’O’,’\0’}; (כלומר מחרוזת באורך 5 דורשת מערך של 6 תווים). ‘H’ ‘E’ ‘L’ ‘L’ ‘O’ ‘\0’ word[0] word[5]

63 הוספת תו-הסיום '0\' word[5]=‘\0’;
אם ניצור מערך של תווים בלי תו-הסיום, ונירצה להפעיל עליו פעולות על מחרוזות (שנכיר בהמשך), אז נצטרך להוסיף את התו '0\' אחרי התווים ששמנו בו. למשל אם נירצה להשתמש בפעולות על מחרוזות עבור המערך: אז נצטרך להוסיף את התו '0\' אחרי האות 'O' על-ידי : word[5]=‘\0’; ‘H’ ‘E’ ‘L’ ‘L’ ‘O’ word[0] word[6] ‘H’ ‘E’ ‘L’ ‘L’ ‘O’ ‘\0’ word[0] word[6]

64 הספריה string.h – פונקציות לדוגמא
פונקציה למציאת אורך מחרוזת (לפי מקום התו '0\'): int strlen(const char str[ ]); האורך לא כולל את התו '0\'. - השימוש ניראה כך: len = strlen(my_string); (למשל עבור מחרוזת שהוגדרה char my_string[6]=“Hello”; יוחזר 5) פונקציה להשוואה בין מחרוזות: int strcmp(const char str1[ ], const char str2[ ]); מחזירה 0 אם המחרוזות זהות, כלומר שוות בכל תו עד לתו ‘\0’. אחרת מוחזר מס' שונה מ-0: חיובי אם המחרוזת הראשונה גדולה יותר לקסיקוגרפית (כלומר לפי סדר מילוני, סדר טבלת-האסקי), ושלילי אם היא קטנה יותר.

65 - דוגמאות נוספותstring.h
העתקת המחרוזת שבמשתנה source למחרוזת target תתבצע על-ידי: strcpy(target, source); שירשור מחרוזות (מעתיק את str2 לסוף str1): strcat(str1, str2); חיפוש ההופעה הראשונה של התו במשתנה c מסוג char במחרוזת str: strchr(str, c); חיפוש ההופעה הראשונה של מחרוזת str2 במחרוזת str1: strstr(str1, str2); בעתיד נפרט יותר על השימוש בפעולות האלה ועל פעולות נוספות בספריה הזאת.


Download ppt "מבוא כללי למדעי המחשב פונקציות www.cs.tau.ac.il/courses/cs4math/09b."

Similar presentations


Ads by Google