Presentation is loading. Please wait.

Presentation is loading. Please wait.

תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי

Similar presentations


Presentation on theme: "תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי"— Presentation transcript:

1 תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי shulyl@tau.ac.il

2 2-3/6/02Software 1 - Shuly Lev-Yehudi2 Multiple Indirection (Pointers to Pointers) addressvalue address value Pointer Variable Pointer Variable Single Indirection Multiple Indirection

3 2-3/6/02Software 1 - Shuly Lev-Yehudi3 Multiple Indirection (cont.) הגדרת מצביע למצביע : ; float **newbalance  newbalance אינו מצביע למספר floating-point אלא מצביע למצביע ל - float. כדי לגשת לערך עצמו יש להפעיל את אופרטור ה -* פעמיים : int x, *p, **q; x = 10; p = &x; q = &p; printf(“%d”, **q); /* print the value of x */

4 2-3/6/02Software 1 - Shuly Lev-Yehudi4 Initializing Pointers אחרי שמצביע הוגדר אך לפני שהושם לו ערך, הוא מכיל ערך לא ידוע (“ זבל ”).  אם ננסה להשתמש במצביע לפני שיש לו ערך “ חוקי ”, סביר שהתכנית תעוף ( וכנראה גם מערכת ההפעלה )! מוסכמה : מצביע שכרגע אינו מצביע למיקום בר - תוקף בזיכרון, מאותחל ל - null ( שהוא 0). מצביע שערכו null אינו מצביע לכלום. נשתמש בערך null כדי לציין למשל, סוף של מערך של מצביעים.

5 2-3/6/02Software 1 - Shuly Lev-Yehudi5 Initializing Pointers (cont.) Search (char *p[], char *name) { register int i; for (i=0; p[i]; ++i) if (!strcmp(p[i], name)) return; return -1; } כאן, ערך null מציין את סוף המערך. הלולאה רצה כל עוד לא נמצא name ולא הגענו למצביע שערכו null.

6 2-3/6/02Software 1 - Shuly Lev-Yehudi6 Initializing Pointers (cont.) ניתן לאתחל מצביע ל - char במחרוזת כאילו שהוא מערך : char *p = “hello world”; ה - compiler שומר את כל קבועי המחרוזות ב - string table ולכן הפקודה תכניס ל -p את הכתובת של הקבוע “hello world” כפי שהוא מאוחסן ב - string table.

7 2-3/6/02Software 1 - Shuly Lev-Yehudi7 Pointers to Functions למרות שפונקציה אינה משתנה, יש לה מקום פיזי בזיכרון שניתן לשמור אותו במצביע. כתובת של פונקציה היא נקודת הכניסה לפונקציה ולכן ניתן להשתמש במצביע לפונקציה כדי לקרוא לה. כתובת של פונקציה היא שם הפונקציה ללא סוגריים או ארגומנטים ( בדומה לכתובת של מערך ). דוגמא :

8 2-3/6/02Software 1 - Shuly Lev-Yehudi8 Pointers to Functions(cont.) void check (char *a, char *b, int (*cmp)(const char *, const char *)); void main(void) { char s1[80], s2[80]; int (*p)(const char *, const char *); p = strcmp; gets(s1); gets(s2); check(s1, s2, p); } void check (char *a, char *b, int (*cmp)(const char *, const char *)) { printf(“testing for equality\n”); if (!(*cmp)(a,b)) printf(“equal”); else printf(“not equal”); } הביטוי (cmp)(a,b*) קורא ל -strcmp. ניתן לקרוא ל -check גם כך : check(s1, s2, strcmp);

9 2-3/6/02Software 1 - Shuly Lev-Yehudi9 Dynamic Allocation Functions ה קצאה דינמית - הקצאת שטח בזמן ריצה. זיכרון דינמי מוקצה על ה - heap - שטח הנמצא בין התכנית והשטח הקבוע שלה (data), לבין ה - stack. פונקציות עיקריות : malloc - מקצה שטח, free - משחררת. צריך את השורה : include stdlib.h # prototype: void *malloc(size_t number_of_bytes); מחזירה מצביע ל - void שפרושו שניתן לשים את הערך החוזר במצביע מכל סוג שהוא.

10 2-3/6/02Software 1 - Shuly Lev-Yehudi10 Dynamic Allocation Functions (cont.) בהצלחה - מוחזר מצביע ל - byte הראשון בשטח שהוקצה. בכשלון - כאשר אין מספיק מקום - מוחזר null. לדוגמא : ; char *p p = malloc(1000);  אין צורך ב - cast, הערך מוסב אוטומטית לפי ה -type בצד שמאל ( ב -++C לא נעשית הסבה אוטומטית !). הקצאת 50 integers. ה -sizeof נחוץ ל -portability: int *p; p = malloc(50 * sizeof(int));

11 2-3/6/02Software 1 - Shuly Lev-Yehudi11 Dynamic Allocation Functions (cont.)  יש לבדוק האם הערך החוזר אינו null! free מחזירה למערכת שטח שהוקצה קודם. prototype: void free(void *p); p הוא מצביע לשטח שהוקצה קודם.  חשוב לא לקרוא ל - free עם ארגומנט לא נכון !

12 2-3/6/02Software 1 - Shuly Lev-Yehudi12 Problems with Pointers שימוש בערך לא טוב של מצביע יכול לגרום לכתיבה לשטח אחר. טעויות נפוצות :  uninitialized pointer: /* this program is wrong */ void main(void) { int x, *p; x = 10; *p = x; } p לא אותחל ולכן הערך 10 נכתב במקום לא ידוע בזיכרון. הבעיה משמעותית בתכנית גדולה.

13 2-3/6/02Software 1 - Shuly Lev-Yehudi13 Problems with Pointers (cont.)  Misunderstanding of how to use a pointer: /* this program is wrong */ void main(void) { int x, *p; x = 10; p = x; printf(“%d”, *p); } printf לא תדפיס את הערך 10 אלא ערך כלשהו אחר. לתיקון יש לכתוב : p = &x;

14 2-3/6/02Software 1 - Shuly Lev-Yehudi14 Problems with Pointers (cont.)  Incorrect assumptions about variables locations: אי אפשר לדעת היכן המשתנים ממוקמים בזיכרון. לכן אם ננסה להשוות בין מצביעים שאינם מצביעים לאובייקט משותף, נקבל תוצאה לא צפויה : char s[80], y[80]; char *p1, *p2; p1 = s; p2 = y; if (p1 < p2)... לא נכון להניח ש - s ו -y מוקצים ברצף.

15 2-3/6/02Software 1 - Shuly Lev-Yehudi15 Problems with Pointers (cont.) באותו אופן לא נכון לאתחל את המערכים first ו - second במספרים 0 עד 19 ( למרות שבחלק מה - compilers זה יעבוד ): int first[10], second[10]; int *p, i; p = first; for (i=0; i < 20; i++) *p++ = i;


Download ppt "תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי"

Similar presentations


Ads by Google