מבוא כללי למדעי המחשב שיעור 5

Slides:



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

מבוא למדעי המחשב לתעשייה וניהול
מבוא למדעי המחשב לתעשייה וניהול דוגמאות ותרגול נוסף במערך חד ממדי הרצאה 12.
Pointers הרצאה קריטית. השאלות הפתוחות מה זה ה- & שמופיע ב scanf מדוע כשמעבירים מחרוזת ל scanf אין צורך ב & האם ניתן להכריז על מערך שגדלו אינו ידוע בתחילת.
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
תכנות תרגול 7 שבוע : מערכים עד היום התוכניות שלנו לא ידעו לשמור כמות גדולה של מידע ללא הגדרת כמות גדולה של משתנים. עד היום התוכניות שלנו לא.
תכנות תרגול 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 דוא " ל :
מבוא כללי למדעי המחשב תרגול. הבית האדום כתובת : רחוב קוקוריקו 2 הבית הירוק כתובת : רחוב קוקוריקו 4 הבית הצהוב כתובת : רחוב קוקוריקו 1 הבית הורוד כתובת.
תכנות תרגול 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 של הסדרה הוא קירוב.
מבוא למדעי המחשב מחרוזות, מצביעים וכתובות
מבוא לשפת C תרגול 12: עוד רקורסיה
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, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
תכנות – שיעור 7. חזרה -מערכים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים זהים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים.
תכנות תרגול 14 שבוע:
תכנות תרגול 10 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים
מבוא כללי למדעי המחשב שיעור רביעי: לולאות
מבוא כללי למדעי המחשב תרגול 5. חישוב e זוהי הנוסחא לחישוב e נראה כיצד לתרגם אותה לפונקציה n n.
מבוא למדעי המחשב תרגול 6 - מערכים שעת קבלה : יום שני 11:00-12:00 דוא " ל :
תכנות תרגול 7 שבוע : מערכים עד היום התוכניות שלנו לא ידעו לשמור כמות גדולה של מידע ללא הגדרת כמות גדולה של משתנים. עד היום התוכניות שלנו לא ידעו.
תכנות תרגול 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 דוא " ל :
תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
מבוא כללי למדעי המחשב תרגול 7. מבנים מטרת המבנים היא לאפשר למתכנת להגדיר טיפוסי משתנים חדשים אשר מתאימים ספציפית לבעיה שאותה התוכנית פותרת. מטרת המבנים.
מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
תכנות תרגול 8 שבוע : מערכים עד היום התוכניות שלנו לא ידעו לשמור כמות גדולה של מידע ללא הגדרת כמות גדולה של משתנים. עד היום התוכניות שלנו לא.
1 מבוא למדעי המחשב רקורסיה. 2 רקורסיה היא שיטה לפתרון בעיות המבוססת על העיקרון העומד ביסוד אינדוקציה מתמטית: אם ידועה הדרך לפתור בעיה עבור המקרים הבסיסיים.
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
קורס תכנות שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 12. ספריות.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
1 Formal Specifications for Complex Systems (236368) Tutorial #1 Course site:
מספרים אקראיים ניתן לייצר מספרים אקראיים ע"י הפונקציה int rand(void);
Formal Specifications for Complex Systems (236368) Tutorial #1
מבוא למדעי המחשב סיבוכיות.
שיעור חמישי: מערכים ומחרוזות
מצביעים קרן כליף.
פונקציות קרן כליף.
ממשקים - interfaces איך לאפשר "הורשה מרובה".
מצביעים קרן כליף.
מבוא כללי למדעי המחשב פונקציות
מבוא כללי למדעי המחשב תרגול 4
מבוא כללי למדעי המחשב תרגול 6
סוגי משתנים קרן כליף.
מערכים של מצביעים הקצאה דינאמית
תירגול 8:מצביעים והקצאה דינאמית
שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
Presentation transcript:

מבוא כללי למדעי המחשב שיעור 5 מרצה: שי גוטנר

חזרה - פונקציות הגדרה של פונקציה : return_value_type function_name(parameter list) } declarations statements { גוף הפונקציה (מימוש)

חזרה - פונקציות return_value_type function name float Maximum (float x, float y) { if (x > y) return x; else return y; } parameter list בפונ' ניתן להשתמש בפרמטרים שהעוברו ובמשתנים המוגדרים בה.

קבועים אם רוצים להגדיר ערכים קבועים שיהיו בשימוש כל חלקי התוכנית, אין צורך במשתנה גלובלי, וניתן להגדיר קבוע על-ידי: #define PI 3.1415 (מעדיפים לראות בתוכנית שמות משמעותיים של קבועים מאשר מספרים שמקורם לא ברור)

הפיכת תוכנית עם main בלבד לתוכנית עם פונקציות נוספות int main() { int i, n, fact=1; scanf(“%d”,&n); for(i = 1; i <= n; i++) fact *= i; printf(“%d\n”,fact); return 0; } מה עושה התוכנית? איזה חלק נהפוך לפונ' ?

הפיכת תוכנית עם main בלבד לתוכנית עם פונקציות נוספות int fact(int); int main() { int n; scanf(“%d”,&n); printf(“%d! = %d”, n, fact(n)); return 0; } Prototype Function Call

הפיכת תוכנית עם main בלבד לתוכנית עם פונקציות נוספות Function Definition int fact(int n) { int i, res = 1; for (i = 1; i <= n; i ++) res *= i; return res; }

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

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

rand() בשפת C ניתן לייצר מספרים פסאודו-אקראיים ע"י הפונקציה int rand(void); X = rand(); הפונקציה נמצאת ב-stdlib.h הפונקציה מחזירה מספר בטווח 0-RAND_MAX אם משתמשים ב-rand מוטב לבצע קריאה אחת ל-srand בתחילת התוכנית void srand(unsigned int);

שימוש ב- srand השימוש יהיה כך srand(time(NULL)); time פונקציה שמחזירה את הזמן ונמצאת בספרייה time.h

rand איך נייצר ערכים אקראיים בטווח אחר מאשר 0-RAND_MAX?

rand איך נייצר ערכים אקראיים בטווח אחר מאשר 0-RAND_MAX? נשתמש בשארית rand() % 10 /*randomly in 0 – 9*/ rand() % 10 + 1 /* randomly in 1 – 10*/

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

פונקציות – תוכנית המחשבת סכום המספרים עד n #include <stdio.h> int compute_sum(int n); int main() { int n=3,sum; printf(“%d\n”,n); sum = compute_sum(n); printf(“%d\n”,sum); return 0; }

פונקציות – תוכנית המחשבת סכום המספרים עד n int compute_sum(int n) { int sum = 0; for( ; n > 0 ; --n) sum + = n; return sum; } איזה משתנים מוגדרים והיכן?

פונקציות – תוכנית המחשבת סכום המספרים עד n main Comupte_sum n sum 3 2 1 5 6 n sum 3 6

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

רקורסיות compute_sum(n) = compute_sum(n-1) + n compute_sum(1) = 1 הגדרה זו היא הגדרה רקורסיבית של הפונקציה. חישוב הסכום של n איברים מסתמך על תוצאת הסכום של n-1 האיברים הקודמים. חובה ! תנאי התחלה.

נוסחת הרקורסיה תנאי קצה compute_sum(n) = compute_sum(n-1) + n compute_sum(1) = 1 תנאי קצה 1 n n-1 n-2 n-3 … מה סכום המספרים

מימוש רקורסיה #include <stdio.h> int compute_sum(int n); int main() { int n=3,sum; printf(“%d\n”,n); sum = compute_sum(n); printf(“%d\n”,sum); return 0; }

מימוש רקורסיה תנאי קצה int compute_sum(int n) { if ( n == 1 ) return 1; return n + compute_sum(n-1); } נוסחת הרקורסיה

רקורסיות - ריצה נניח שב-main יש לנו את הקריאה הבאה: compute_sum(5); הערך המוחזר ערכי הקריאה מקום הקריאה 5 + sum(4) Sum(5) main() 4+sum(3) Sum(4) 3+sum(2) Sum(3) 2 + sum(1) Sum(2) 1 Sum(1)

עצרת נסתכל על ההגדרה של עצרת כפי שראינו בעבר n*(n-1) = 1*2*3* …n! מהי ההגדרה הרקורסיבית של העצרת ?

עצרת נסתכל על ההגדרה של עצרת כפי שראינו בעבר n*(n-1) = 1*2*3* …n! מהי ההגדרה הרקורסיבית של העצרת ? n! = (n-1)! * n 1! = 1 , 0! = 1

int fact(int n) { if (n<=1) return 1; return n * fact(n-1); } int fact_i(int n) { int prod=1; while (n>1) prod *= n; n--; } return prod;

רקורסיות - ריצה נניח שב-main יש לנו את הקריאה הבאה: fact(4); הערך המוחזר ערכי הקריאה מקום הקריאה 4*fact(3) fact(4) main() 3*fact(2) fact(3) 2*fact(1) fact(2) 1 fact(1)

רקורסיות - ריצה נניח שב-main יש לנו את הקריאה הבאה: fact_i(4); הערך המוחזר prod n 1 4 3 4*3 2 24 4*3*2

חישוב סכום הספרות בדומה לשיעורי הבית נרצה לחשב את סכום הספרות של מספר רעיון כללי:

חישוב סכום הספרות של מספר נרצה לחשב את סכום הספרות של מספר רעיון כללי: לולאה כאשר בכל פעם מחלצים את ספרת האחדות: sum = 0 while ( n != 0 ) sum = sum + ספרת אחדות n = n / 10

חישוב סכום הספרות int DigitSum(int n) { int sum = 0; while(n >0) sum += n %10; n /= 10; } return sum;

חישוב סכום הספרות מעבר לרקורסיה תנאי קצה נוסחת הנסיגה

חישוב סכום הספרות int DigitSumRec(int n) } if (n > 0) return n % 10 + DigitSumRec(n / 10); else return 0; {

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

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

רקורסיות למה בפועל יש יותר משתנים ממה שנראה לנו ? כל קריאה רקורסיבית מייצרת עוד עותק של המשתנים המקומיים של הפונקציה. בכל אחת המקריאות הללו נכנסים לפונקציה מבלי שסיימנו את הפונקציה הקודמת המשתנים המקומיים של הפונקציה הקודמת עדין קיימים וכעת נוצרים העתקים חדשים של המשתנים המקומיים של הפונקציה.

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

קריאה לפונקציה 5 y 2 משתנים מקומיים Foo(5, y, 2);

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

דוגמא מסכמת נתונה הנוסחה הרקורסיבית הבאה עבור סדרת פיבונאצ'י: Fib(0) = 0, Fib(1) = 1; Fin(n) = Fib(n -1) + Fib(n-2) הערכים של סדרה זאת הם: 0,1,1,2,3,5,…… כיצד נתרגם את הנוסחא הזו לתוכנית רקורסיבית ? במה שונה נוסחא זו ממה שראינו עד עכשיו?

דוגמא מסכמת int Fib(int n) { if (n<= 1) return n; else return Fib(n-1) + Fib(n -2); }

דוגמא מסכמת n ערך מספר קריאות 1 2 3 23 28657 92735 24 46368 150049

החלפה בין משתנים החלפת הערכים החלפת הערכים נסתכל על התוכנית הבאה: int main() { int a,b,x,y,temp; ... temp = x; x = y; y = temp; … temp = a; a = b; b = temp; } החלפת הערכים החלפת הערכים

החלפה בין משתנים כפי שלמדנו במצב כזה הינו רוצים שתהיה פונקציה שתבצע את החלפה הזו בין המשתנים.

החלפה בין משתנים נכתוב פונקציה כזו בשם swap void swap(int p, int q) { int temp; temp = p; p = q; q = temp; }

החלפה בין משתנים int main() { int a=10,b=2,x=3,y=5; ... swap(x,y); swap(a,b); }

החלפה בין משתנים נעקוב אחרי הקריאה לפונקציה swap(x,y); 3 x 6 y void swap (int p,int q) { int temp; temp = p; p = q; q = temp; } 6 p 3 q

מצביעים ראינו שכל משתנה שהגדרנו בתוכנית שלנו מוצקה עבורו תא באזור כלשהו בזיכרון. int main() { int x,y; } לכל תא כזה יש כתובת בזיכרון של המחשב. כדי להגיע לכתובת של משתנה משתמשים באופרטור &. x y

מצביעים מה יחזירו &x ו &y . x 5000 y 5004

מצביעים ניתן להגדיר משתנים שסוגם הוא מצביע. משתנים כאלה מחזיקים בתוכם את הכתובות. int main() { int x,y; int *p; p = &x; } 5000 x 5000 y 5004 p 9008

מצביעים כדי לסמן שמצביע לא מצביע לשום מקום נהוג להשים לו NULL p = NULL; אפשר לחשוב על משתנה מסוג מצביע כאל חץ: x y p

מצביעים int main() { int x=7,*p = &x; printf(“Value %d Pointer %p\n”, x, p); } כדי להדפיס את הערך שאליו מצביע p. printf(“Value %d\n”,*p) פורמט הדפסה של משתנה מסוג מצביע

מצביעים יש לשים לב שאין הצבעה לביטויים ולקבועים &3 &(k+99)

Call by value and call by reference נחזור לפונקצית ה swap. הבעיה הייתה שהחלפת הערכים התבצעה בין הפרמטרים של הפונקציה ולא בין המשתנים עצמם.

Call by reference int main() { int a=10,b=2,x=3,y=5; ... swap(&x,&y); swap(&a,&b); } void swap (int* p,int* q) int temp; temp = *p; *p = *q; *q = temp;

Call by reference בכדי לממש call by reference יש לבצע את הדברים הבאים: 1 להגדיר את הפרמטרים של הפונקציה כמצביעים void swap(int *p, int *q) 2 להשתמש בגוף הפונקציה בערכים שאליהם הם מצביעים *p = *q; 3 בקריאה לפונקציה להעביר כתובות כארגומנטים swap(&x, &y);

חזרה - מערכים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים זהים char a[10]; int b[50]; הגודל חייב להיות קבוע. פנייה לאיברי המערך מתבצעת ע"י a[k] כאשר k בין 0 ל- )-1גודל המערך) אתחול ע"י לולאה או רשימת אתחול

מצביעים מצביע הוא משתנה שמכיל כתובות int *p, *q; char *p; פנייה לכתובות p = &x; p = q; פנייה לערך ש-p מצביע אליו: *p = 5; x = *p;

הקשר בין מערכים ומצביעים כאשר אנחנו מגדירים מערך בגודל 20 של שלמים אזי יש לנו 20 משתנים מסוג int בזיכרון. מה הכתובת של משתנים אלו ? int a[20]; a[0] כמו לכל משתנה, גם לאיברי המערך ישנה כתובת. כיצד נגיע לכתובת זו? a[19]

הקשר בין מערכים ומצביעים ניתן להגיע לכתובות בדרך הרגילה int *p; p = &a[0]; נזכור שהמערך ממוקם בצורה רציפה בזיכרון לכן כתובות איברי המערך הן רציפות, למשל: 5000 5004 5008

משמעות שם המערך פניה לשם המערך נותנת לנו את כתובת המערך שהיא למעשה מצביע לאיבר הראשון במערך. בשם המערך ניתן להשתמש כדי לקבל את הכתובת הזו. לא ניתן לשנות אותו (כלומר הוא מצביע קבוע) int *p; p = a; p מצביע לראש המערך. (את p כמובן שניתן לשנות)

חשבון של מצביעים ניתן להשתמש בפעולות חיבור וחיסור על כתובות. זה שימושי בעיקר בשילוב עם מערכים. *(a+i) שקול a[i]; *(p+i) שקול p[i];

חשבון של מצביעים מספר דרכים לכתוב לולאה שרצה על מערך: for (i=0; i<n; i++) sum + = a[i]; for (p = a, i=0; i<n; i++) sum + = *(p+i); for (p=a; p<=&a[n-1]; p++) sum + = *p;

חשבון של מצביעים כיצד ה++ יודע לקדם את המצביע לאיבר הבא ? הבעיה: המערך יכול להיות של תווים, של שלמים או של כל דבר. המרחק בין התאים הוא שונה! מה המרחק עבור int ? מה המרחק עבור char ?

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

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

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

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

העברת מערך לפונקציה int sum(int a[ ], int size) { int i, res = 0; for(i = 0; i < size; i++) res += a[i]; return res; }

העברת מערך לפונקציה int sum(int *p, int size) { int i, res = 0; for( i = 0; i < size; i++ ) res += p[i]; return res; }

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

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

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

מחרוזות int strlen(char *s) { char *ptr=s; while (*ptr++ != ’\0’) ; return ptr-s-1; } מה בעצם קורה בתנאי קידום הלולאה ומה הדרך הנכונה לקרוא את זה?

מחרוזות int strdo(char *s,char ch) { int cnt=0; while (*s != ’\0’) if (*s == ch) cnt++; s++; } return cnt; מה עושה הפונקציה הזו?