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

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

מבוא למדעי המחשב לתעשייה וניהול
מבוא כללי למדעי המחשב תרגול 1. כתיבת התוכנה כתיבת התוכנית עצמה נעשית ע " י כתיבת קובץ טקסט רגיל אשר תוכנו מקיים את כללי שפת C כתיבת התוכנית עצמה נעשית.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
מבוא למדעי המחשב תרגול 2 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
תכנות תרגול 9 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
תכנות תרגול 6 שבוע : חישוב e זוהי הנוסחא לחישוב e נראה כיצד לתרגם אותה לפונקציה n n.
תרגול 5 רקורסיות. רקורסיה קריאה של פונקציה לעצמה –באופן ישיר או באופן עקיף היתרון : תכנות של דברים מסובכים נעשה ברור ונוח יותר, מכיוון שזו למעשה צורת.
מבוא כללי למדעי המחשב שיעור 4 מרצה: שי גוטנר. חזרה - משתנים מסוג char משתנים אלו מיצגים תווים. משתנים אלו מיצגים תווים. לכל תו יש קוד מספרי שמייצג אותו.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
רקורסיות נושאי השיעור מהן רקורסיות פתרון רקורסיות : שיטת ההצבה שיטת איטרציות שיטת המסטר 14 יוני יוני יוני 1514 יוני יוני יוני 1514.
תכנות תרגול 2 שבוע : שבוע שעבר כתבו תוכנית המגדירה שלושה משתנים מאתחלת אותם ל 1 2 ו 3 ומדפיסה את המכפלה שלהם את ההפרש שלהם ואת הסכום שלהם.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
מבוא למדעי המחשב תרגול 8 - מחרוזות שעת קבלה : יום שני 11:00-12:00 דוא " ל :
1 Formal Specifications for Complex Systems (236368) Tutorial #5 Refinement in Z: data refinement; operations refinement; their combinations.
תכנות תרגול 9 שבוע : מערכים int a; a=5; int a[10]; a[2] = 5; 5 a a[0] a[1] a[2] a[9]  5 משתנה בודד מערך גישה למשתנה השלישי במערך.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
שיעור שישי: מערכים ופונקציות
חלון הפקודות מיועד לבצע פעולה אחת בכל פעם. כיצד אפשר לבצע רשימת פקודות או אפליקציות מורכבות ?
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
מבוא למדעי המחשב מחרוזות, מצביעים וכתובות
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
תכנות תרגול 6 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מבוא כללי למדעי המחשב שיעור 5
תכנות – שיעור 7. חזרה -מערכים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים זהים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים.
תכנות תרגול 10 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
תכנות תרגול 3 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים
מבוא כללי למדעי המחשב שיעור רביעי: לולאות
תכנות תרגול 5 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות תרגול 4 שבוע : לולאות for לולאות for for (counter=1 ;counter
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
מבוא למדעי המחשב תרגול 3 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
Last time on Clang משתנה: "פתק" המשמש את המחשב לשמירת מידע. לכל משתנה יש שם וטיפוס כללים לשמות משתנים –חייבים להכיל רק אותיות, מספרים ו '_' –חייבים להתחיל.
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
מבוא למדעי המחשב תרגול 5 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
תכנות תרגול 8 שבוע : מערכים עד היום התוכניות שלנו לא ידעו לשמור כמות גדולה של מידע ללא הגדרת כמות גדולה של משתנים. עד היום התוכניות שלנו לא.
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
Practice session 3 תחביר ממשי ( קונקרטי ) ותחביר מופשט ( אבסטרקטי ) שיטות חישוב : Applicative & Normal Evaluation Partial Evaluation.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
Practice session 3.  תחביר ממשי ( קונקרטי ) ותחביר מופשט ( אבסטרקטי )  שיטות חישוב : Applicative & Normal Evaluation.
מבנה נתונים ואלגוריתמים ) לשעבר - עיבוד מידע( ד"ר אבי רוזנפלד ד"ר אריאלה ריכרדסון.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 12. ספריות.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
מספרים אקראיים ניתן לייצר מספרים אקראיים ע"י הפונקציה int rand(void);
Programming Arrays.
מבוא למדעי המחשב לתעשייה וניהול
מבוא למדעי המחשב סיבוכיות.
מ- JAVA ל- C קרן כליף.
שיעור חמישי: מערכים ומחרוזות
מצביעים קרן כליף.
SQL בסיסי – הגדרה אינדוקטיבית
קורס תכנות – סמסטר ב' תשס"ח
פונקציות קרן כליף.
פונקציות קרן כליף.
שיעור שישי: מחרוזות, מצביעים
פונקציות קרן כליף.
מבוא כללי למדעי המחשב תרגול 4
סוגי משתנים קרן כליף.
מחרוזות קרן כליף.
תוכנה 1 תרגול 13 – סיכום.
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
Presentation transcript:

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

שאלה כיצד נוכל לחשב את הסכום הבא: 220+315+517= ?

פתרון אפשרי #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; } אם היו יותר מחוברים - היינו צריכים לחזור פעמים נוספות על אותן שורות עם מספרים אחרים זה מאריך את התוכנית פי כמה וכמה, מסרבל אותה, ויוצר פתח לבאגים

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

איך זה ניראה ב-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

איך זה ניראה ב-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; ההגדרה כוללת את שם הפונקציה

איך זה ניראה ב-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; ההגדרה כוללת את שם הפונקציה היא כוללת גם את המשתנים שעליהם הפונקציה מוגדרת (בדומה לפונקציות במתמטיקה)

איך זה ניראה ב-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; ההגדרה כוללת את שם הפונקציה היא כוללת גם את המשתנים שעליהם הפונקציה מוגדרת (בדומה לפונקציות במתמטיקה) ואת סוג הערך שהפונקציה מחשבת ("מחזירה")

איך זה ניראה ב-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 אומרת מה ערך הפונקציה ("מה היא מחזירה")

איך זה ניראה ב-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

איך זה ניראה ב-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; כשמשתמשים בפונקציה, רושמים בסוגריים עבור איזה ערכים מעוניינים לחשב אותה ריצת התוכנית תמיד תתחיל כאן: בזמן הריצה, כשמגיעים לשימוש בפונקציה, המחשב יעבור לחשב את ערך הפונקציה, ורק לאחר מכן ימשיך בתוכנית

הדגמת הריצה בשימוש פונקציה #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;

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

הדגמת הריצה בשימוש פונקציה #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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

משתנים בפונקציה -דוגמא #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 מוגדר רק בתוך הפונקציה

משתנים בפונקציה - דוגמא #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; אפשר להגדיר בפונקציות שונות משתנים באותו שם, והם אינם קשורים זה לזה

פונקציות – העברת ערכים נשים לב: לפונקציה מועברים ערכים – לא משתנים. שינויים במשתנה שאליו הוכנס הערך לא משפיעים על המשתנה המקורי. למשל בדוגמא הבאה: #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

פונקציות – העברת ערכים נשים לב: לפונקציה מועברים ערכים – לא משתנים. שינויים במשתנה שאליו הוכנס הערך לא משפיעים על המשתנה המקורי. למשל בדוגמא הבאה: #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 לא מושפע מהשינויים במשתנה שאליו הועבר ערכו

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

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

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

הכרזה על פונקציות דוגמא להכרזה ((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; } שימו לב שבהגדרת פונקציה אין ; בכותרת (רק בהכרזה)

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

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

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

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

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

דוגמא: פונקציה שסוכמת מערך של שלמים #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 ) עוברים על תאי המערך בלולאה, סוכמים אותם, ומחזירים את הסכום. קליטת ערכים למערך קריאה לפונקציה והדפסת התוצאה

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

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

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

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

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

הוספת תו-הסיום '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]

הספריה 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: חיובי אם המחרוזת הראשונה גדולה יותר לקסיקוגרפית (כלומר לפי סדר מילוני, סדר טבלת-האסקי), ושלילי אם היא קטנה יותר.

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