קורס תכנות – סמסטר ב' תשס"ח

73
בבבב בבבבב – בבבבב ב' בבבב בבבבב – בבבבב ב' בבב"ב בבב"ב בבבבב בבבבב: בבבבבב בבבבבבבב בבבבבwww.cs.tau.ac.il/~armon/prog08b.htm

Upload: dunn

Post on 12-Jan-2016

63 views

Category:

Documents


0 download

DESCRIPTION

קורס תכנות – סמסטר ב' תשס"ח. שיעור תשיעי: כתובות ומצביעים מבנים. www.cs.tau.ac.il/~armon/prog08b.htm. נושאי השיעור היום. כתובות ומצביעים: - תזכורת ודוגמאות נוספות - מצביעים ומערכים מערכים ופונקציות מבנים. תזכורת: כתובות ומצביעים. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: קורס תכנות – סמסטר ב' תשס"ח

קורס תכנות – סמסטר ב' תשס"חקורס תכנות – סמסטר ב' תשס"ח

שיעור תשיעי: כתובות ומצביעים

מבנים

www.cs.tau.ac.il/~armon/prog08b.htm

Page 2: קורס תכנות – סמסטר ב' תשס"ח

נושאי השיעור היוםנושאי השיעור היום

כתובות ומצביעים:כתובות ומצביעים:•- תזכורת ודוגמאות נוספות- תזכורת ודוגמאות נוספות

- מצביעים ומערכים- מצביעים ומערכיםמערכים ופונקציותמערכים ופונקציות-

מבניםמבנים-

Page 3: קורס תכנות – סמסטר ב' תשס"ח

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

מכתובת מסויימת בזיכרון. מכתובת מסויימת בזיכרון.

הוא משתנה ששומר כתובת של משתנה אחר. למשל: הוא משתנה ששומר כתובת של משתנה אחר. למשל:מצביע )פויינטר(מצביע )פויינטר(• int *the_pointerint *the_pointer;;.. זה מצביע ששומר כתובת של זה מצביע ששומר כתובת שלintint..

לכל טיפוס-משתנה ניתן להגדיר מצביע לשמירת כתובת של משתנה לכל טיפוס-משתנה ניתן להגדיר מצביע לשמירת כתובת של משתנה • כזה:כזה:

char *ptav; char *ptav; double *ptr1, *ptr2, *ptr3; double *ptr1, *ptr2, *ptr3;

. . ii&& נותנת את כתובתו של משתנה, למשל נותנת את כתובתו של משתנה, למשל &&הפעולה הפעולה • נותנת את המשתנה שנמצא בכתובת מסויימת )כלומר ניגשת נותנת את המשתנה שנמצא בכתובת מסויימת )כלומר ניגשת **הפעולה הפעולה •

לערך של המשתנה שעליו הפויינטר מצביע(. למשל: לערך של המשתנה שעליו הפויינטר מצביע(. למשל: **my_pointer=10my_pointer=10;;

Page 4: קורס תכנות – סמסטר ב' תשס"ח

תזכורת: מציאת הכתובת של תזכורת: מציאת הכתובת של משתנהמשתנה

int main)(int main)(

{{

int i=10; int i=10;

}}

התוכניתהתוכנית הזיכרוןהזיכרון

75007500

טבלת טבלת הכתובותהכתובות

i i 75007500 44

משתנמשתנהה

כתובתכתובת גודלגודל1100

&&ii 75007500 זה זה

Page 5: קורס תכנות – סמסטר ב' תשס"ח

תזכורת: גישה לערך בכתובת מסויימתתזכורת: גישה לערך בכתובת מסויימת

int main)(int main)(

{{

char c=‘A’; char c=‘A’;

}}

התוכניתהתוכנית הזיכרוןהזיכרון

6565

92009200

טבלת טבלת הכתובותהכתובות

c c 92009200 11

משתנמשתנהה

כתובתכתובת

זה זה ((92009200*)*)ערך המשתנה ערך המשתנה

cc 6565, כלומר זה , כלומר זה

גודלגודל

Page 6: קורס תכנות – סמסטר ב' תשס"ח

תזכורת: גישה למשתנה על-ידי מצביעתזכורת: גישה למשתנה על-ידי מצביעקטע תוכנית להדגמת משמעות הפעולות האלה:קטע תוכנית להדגמת משמעות הפעולות האלה:•

int i=10;int i=10;

int *int *my_pointer_to_int;my_pointer_to_int;

my_pointer_to_int =my_pointer_to_int = &&i;i;

**my_pointer_to_int=100;my_pointer_to_int=100;

printf)“The value of i is now %d”, i(;printf)“The value of i is now %d”, i(;

במשתנה שהפויינטר מצביע 100שמים יודפס המספר עליו100

intהגדרת מצביע על

i שמים במצביע את כתובת המשתנה

100

i my_pointer_to_int345345

)למשל( )למשל(345345כתובת כתובת

Page 7: קורס תכנות – סמסטר ב' תשס"ח

כתובות: נקודות לתשומת לבכתובות: נקודות לתשומת לב לשנות כתובת של משתנה. לשנות כתובת של משתנה. לא ניתןלא ניתן•

..i=5000i=5000&& כלומר לא ניתן לכתוב למשל: כלומר לא ניתן לכתוב למשל:

שנמצא בכתובת מסויימת. שנמצא בכתובת מסויימת. הערךהערךניתן לשנות את ניתן לשנות את • ..’;’;AA(=‘(=‘cc*)&*)&למשל: למשל: •..’;’;c=‘Ac=‘A זה כמו לכתובזה כמו לכתוב•

לשנות את הערך שנמצא בכתובת כלשהי שאיננה לשנות את הערך שנמצא בכתובת כלשהי שאיננה מסוכןמסוכן•..;;123123(=(=40004000*)*)כתובת של משתנה. למשל כתובת של משתנה. למשל

אנחנו עלולים לשנות מקום בזיכרון ששייך למערכת ההפעלה, אנחנו עלולים לשנות מקום בזיכרון ששייך למערכת ההפעלה, •ולגרום לתוכנית לעוף. ולגרום לתוכנית לעוף.

ערכים של משתנים שהגדרנו.ערכים של משתנים שהגדרנו.לכן נשנה רק לכן נשנה רק •

Page 8: קורס תכנות – סמסטר ב' תשס"ח

תזכורת: מצביעים ופונקציותתזכורת: מצביעים ופונקציות

מאפשרת לה לשנות מאפשרת לה לשנות העברת כתובת של משתנה לפונקציההעברת כתובת של משתנה לפונקציה• אפילו שהוא לא מוגדר בה. אפילו שהוא לא מוגדר בה.אותואותו

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

Page 9: קורס תכנות – סמסטר ב' תשס"ח

תזכורת: מצביעים ופונקציות – דוגמאתזכורת: מצביעים ופונקציות – דוגמא

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

void swap)void swap)int *int *first, first, int *int *second(second(

{{

int temp;int temp;

temp=temp=**first;first;

**first=first=**second;second;

**second=temp;second=temp;

}}

;;)swap)&i, &j(swap)&i, &j השימוש למשל על-ידי:השימוש למשל על-ידי:

first ערך המשתנה שכתובתו הועברה אליוחלף עם ערך המשתנה שכתובתו הועברה

second אל

Page 10: קורס תכנות – סמסטר ב' תשס"ח

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

int *address_of _the_higher_number)int *a, int*b(;int *address_of _the_higher_number)int *a, int*b(;

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

סיומה. למשל הפונקציה הבאה תגרום לשגיאה:סיומה. למשל הפונקציה הבאה תגרום לשגיאה:int *give_pointer_to_zero)( int *give_pointer_to_zero)( { { int i=0;int i=0; return &i;return &i;}}

00ii

Page 11: קורס תכנות – סמסטר ב' תשס"ח

מצביעים ומערכיםמצביעים ומערכים עבור התאים עבור התאים רצופיםרצופיםהגדרת מערך מקצה בזיכרון מקומות הגדרת מערך מקצה בזיכרון מקומות •

שלו.שלו.

בנוסף, מוקצה משתנה ששמו הוא שם-המערך, שמכיל את בנוסף, מוקצה משתנה ששמו הוא שם-המערך, שמכיל את • )לא ניתן לשנות את ערכו(. )לא ניתן לשנות את ערכו(. כתובת התא הראשון של המערךכתובת התא הראשון של המערך

לכן אפשר לגשת לתאי מערך גם ע"י חישוב הכתובת שלהם. לכן אפשר לגשת לתאי מערך גם ע"י חישוב הכתובת שלהם. •..array[5]array[5] שקול ל- שקול ל- ((array+5array+5*)*)למשל למשל

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

500

array

array[0] array[9]

.. . . . . . . ..

)למשל(500כתובת

Page 12: קורס תכנות – סמסטר ב' תשס"ח

מצביעים ומערכיםמצביעים ומערכיםאי-אפשר לשנות כתובת של מערך )היא נקבעת כשהוא אי-אפשר לשנות כתובת של מערך )היא נקבעת כשהוא •

מוגדר(. מוגדר(. ..array=0array=0, או , או array=array1array=array1לכן לא ניתן לכתוב לכן לא ניתן לכתוב •

לשים כתובת של מערך בתוך מצביע. אפשר לכתוב: לשים כתובת של מערך בתוך מצביע. אפשר לכתוב:אפשראפשר•

char *array_ptr;char *array_ptr;

array_ptr=array;array_ptr=array; ( ( ;;array_ptr = &array[0]array_ptr = &array[0])השורה האחרונה שקולה לשורה:)השורה האחרונה שקולה לשורה:•

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

לשנות אותה.לשנות אותה.

)שמים במצביע את כתובת התא הראשון )שמים במצביע את כתובת התא הראשון במערך(במערך(

Page 13: קורס תכנות – סמסטר ב' תשס"ח

גישה לתאי-מערך לפי הכתובתגישה לתאי-מערך לפי הכתובתאם הגדרנו למשל:אם הגדרנו למשל:•

int array[10];int array[10];int *array_ptr;int *array_ptr;array_ptr=array;array_ptr=array;

33 כמו משתנים אחרים.כמו משתנים אחרים.לפי הכתובת שלהם, לפי הכתובת שלהם, אז אפשר לגשת לתאי-המערך גם אז אפשר לגשת לתאי-המערך גם במערך(: במערך(:55 בתא מס' בתא מס' 100100הפעולות הבאות עושות אותו דבר )שמות הפעולות הבאות עושות אותו דבר )שמות

array[5]=100;array[5]=100;**)array+5(=100;)array+5(=100;**)array_ptr+5(=100;)array_ptr+5(=100;

תאים תאים 55- המחשב יודע כמה בתים להתקדם כשאנחנו מבקשים להתקדם ב-- המחשב יודע כמה בתים להתקדם כשאנחנו מבקשים להתקדם ב-• תופס תופס intint והוא יודע כמה בתים כל והוא יודע כמה בתים כל intintקדימה, כי הגדרנו שטיפוס הערכים הוא קדימה, כי הגדרנו שטיפוס הערכים הוא

)כאמור, ערכי המערך שמורים בזיכרון ברצף(.)כאמור, ערכי המערך שמורים בזיכרון ברצף(.

תאים אחרי התא תאים אחרי התא 55גישה לתא שנמצא גישה לתא שנמצא הראשוןהראשון

מצביע על התא הראשון מצביע על התא הראשון (())במערךבמערך

Page 14: קורס תכנות – סמסטר ב' תשס"ח

גישה למערך לפי כתובת – דוגמא גישה למערך לפי כתובת – דוגמא נוספתנוספת

נאמר שמוגדרים:נאמר שמוגדרים:•

int i,array[10]={0};int i,array[10]={0};

int *ptr;int *ptr; הקטעים הבאים עושים בדיוק אותו דבר )מדפיסים את הקטעים הבאים עושים בדיוק אותו דבר )מדפיסים את 33אז אז •

המערך(:המערך(:

• for )i=0; i<10; i++(for )i=0; i<10; i++(

printf)“%d ”, array[i](;printf)“%d ”, array[i](;

• for )i=0; i<10; i++(for )i=0; i<10; i++(

printf)“%d ”,printf)“%d ”, *)array+i( *)array+i((;(;

• forfor ))ptr=array; ptrptr=array; ptr <= &array[9]; ptr++<= &array[9]; ptr++((

printf)“%d ”,printf)“%d ”, *ptr *ptr(;(;

קידום קידום הדפסה ע"י הדפסה ע"י )3 )3 מכתובת התא מכתובת התא מצביעמצביע

הראשון עד כתובת הראשון עד כתובת התא האחרוןהתא האחרון

הדפסה על-ידי הדפסה על-ידי )1 )1גישה רגילה לתאי גישה רגילה לתאי

המערךהמערך

הדפסה על-ידי גישה לכל תא הדפסה על-ידי גישה לכל תא )2 )2 הכתובת שלו יחסית לתא הכתובת שלו יחסית לתא לפילפי

הראשוןהראשון

Page 15: קורס תכנות – סמסטר ב' תשס"ח

מערכים ופונקציות - הסברמערכים ופונקציות - הסבר

אמרנו בעבר שכשמעבירים מערך לפונקציה שינויים שנעשה אמרנו בעבר שכשמעבירים מערך לפונקציה שינויים שנעשה •ישפיעו על המערך המקורי. ישפיעו על המערך המקורי. בפונקציה בפונקציה

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

למשל, כפי שאמרנו, הפונקציה הבאה תאפס מערך שמועבר למשל, כפי שאמרנו, הפונקציה הבאה תאפס מערך שמועבר •אליה:אליה:

void zero_array)int a[ ], int size( void zero_array)int a[ ], int size( { { int i;int i; for)i=0 ; i<size; i++( for)i=0 ; i<size; i++( a[i]=0;a[i]=0;}}

Page 16: קורס תכנות – סמסטר ב' תשס"ח

מערכים ופונקציות - הסברמערכים ופונקציות - הסבר

אמרנו בעבר שכשמעבירים מערך לפונקציה שינויים שנעשה אמרנו בעבר שכשמעבירים מערך לפונקציה שינויים שנעשה • ישפיעו על המערך המקורי.ישפיעו על המערך המקורי.בפונקציה בפונקציה

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

למשל, כפי שאמרנו, הפונקציה הבאה תאפס מערך שמועבר למשל, כפי שאמרנו, הפונקציה הבאה תאפס מערך שמועבר •אליה:אליה:

void zero_array)void zero_array)int *aint *a, int size( , int size( { { int i;int i; for)i=0 ; i<size; i++( for)i=0 ; i<size; i++( a[i]=0;a[i]=0;}}

נציין שאם פונקציה מצפה לקבל נציין שאם פונקציה מצפה לקבל , אפשר להעביר אליה , אפשר להעביר אליה מצביעמצביע

מערך מהסוג הזה, כי בשני מערך מהסוג הזה, כי בשני המקרים מה שמועבר הוא המקרים מה שמועבר הוא

כתובת בזיכרון.כתובת בזיכרון.

Page 17: קורס תכנות – סמסטר ב' תשס"ח

מערכים ופונקציותמערכים ופונקציות

( ( strcmp, strlenstrcmp, strlenלמשל הפונקציות שהזכרנו על מחרוזות )כמו למשל הפונקציות שהזכרנו על מחרוזות )כמו •.. * *charcharמוגדרות למעשה עבור מצביעים מסוג מוגדרות למעשה עבור מצביעים מסוג

באחריותנו להפעיל אותן באמת על מחרוזת )כלומר רצף תווים באחריותנו להפעיל אותן באמת על מחרוזת )כלומר רצף תווים •\'( ולא סתם על מצביע לתו או מערך של תווים \'( ולא סתם על מצביע לתו או מערך של תווים 00שמסתיים ב- 'שמסתיים ב- '

)נקבל תוצאות שגויות אם אין את תו הסיום(.)נקבל תוצאות שגויות אם אין את תו הסיום(.

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

(. (. כתובת ההתחלהכתובת ההתחלהשמועבר זה רק שמועבר זה רק שוב, זה באחריותנו שתתבצע בפונקציה פעולה הגיונית ושהיא שוב, זה באחריותנו שתתבצע בפונקציה פעולה הגיונית ושהיא •

תדע מה גודל המערך ולא תחרוג ממנו.תדע מה גודל המערך ולא תחרוג ממנו.

Page 18: קורס תכנות – סמסטר ב' תשס"ח

""מצביע על כלוםמצביע על כלום"" לא מצביע לשום משתנהלא מצביע לשום משתנהלפעמים נירצה לסמן שמצביע לפעמים נירצה לסמן שמצביע •

)למשל לפני שהתחלנו להשתמש בו(.)למשל לפני שהתחלנו להשתמש בו(.• 00מקובל לעשות זאת ע"י זה שנכניס אליו את הכתובת מקובל לעשות זאת ע"י זה שנכניס אליו את הכתובת •

)שאיננה כתובת אפשרית של משתנה(.)שאיננה כתובת אפשרית של משתנה(.

. זהו קבוע . זהו קבוע NULLNULL מקובל לרשום מקובל לרשום 00למעשה, במקום לרשום למעשה, במקום לרשום •..stdlib.hstdlib.h בספריה בספריה definedefine##, שמוגדר ע"י , שמוגדר ע"י 00שערכו שערכו

>>include<stdlib.hinclude<stdlib.h## למשל: למשל: int *ptr=NULL;int *ptr=NULL;

’’00‘\‘\ לבין תו סיום מחרוזת לבין תו סיום מחרוזת NULLNULLלא לבלבל בין הכתובת לא לבלבל בין הכתובת •

Page 19: קורס תכנות – סמסטר ב' תשס"ח

#include<stdlib.h>#include<stdlib.h>

char *my_strchr)char *str, char tav(char *my_strchr)char *str, char tav(

{{

while))*str != ‘\0’( && )*str != tav((while))*str != ‘\0’( && )*str != tav((

str++;str++;

if )*str == tav( return str;if )*str == tav( return str;

return NULLreturn NULL

}}

מתקדמים עד שמצאנו את מתקדמים עד שמצאנו את התו או הגענו לסוף התו או הגענו לסוף

המחרוזתהמחרוזת

דוגמא: חיפוש תו במחרוזתדוגמא: חיפוש תו במחרוזת

אם מצאנו מוחזר מצביע להופעה אם מצאנו מוחזר מצביע להופעה הראשונההראשונה

NULLNULLאם לא מצאנו מחזירים אם לא מצאנו מחזירים

מקבלת מצביע מקבלת מצביע לתחילת מחרוזת לתחילת מחרוזת

ותוותו

Page 20: קורס תכנות – סמסטר ב' תשס"ח

#include<stdlib.h>#include<stdlib.h>char *my_strchr)char *str, char tav(char *my_strchr)char *str, char tav({{ while))*str != ‘\0’( && )*str != tav((while))*str != ‘\0’( && )*str != tav(( str++;str++; if )*str == tav( return str;if )*str == tav( return str; return NULL;return NULL;}}

int main)(int main)({ { char word[]=“HELLO”, tav=‘L’, *place;char word[]=“HELLO”, tav=‘L’, *place; place=my_strchr)word, tav(;place=my_strchr)word, tav(; return 0;return 0;}}

מתקדמים עד שמצאנו את מתקדמים עד שמצאנו את התו או הגענו לסוף התו או הגענו לסוף

המחרוזתהמחרוזת

דוגמא: חיפוש תו במחרוזתדוגמא: חיפוש תו במחרוזת

אם מצאנו מוחזר מצביע להופעה אם מצאנו מוחזר מצביע להופעה הראשונההראשונה

NULLNULLאם לא מצאנו מחזירים אם לא מצאנו מחזירים

הדגמת אופן הקריאה לפונקציה הזוהדגמת אופן הקריאה לפונקציה הזו

מקבלת מצביע מקבלת מצביע לתחילת מחרוזת לתחילת מחרוזת

ותוותו

Page 21: קורס תכנות – סמסטר ב' תשס"ח

מערכים ופונקציות – נקודה לתשומת מערכים ופונקציות – נקודה לתשומת לבלב

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

int * zero_array)(int * zero_array)(

{ {

int array[100]={0};int array[100]={0};

return array;return array;

}}

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

Page 22: קורס תכנות – סמסטר ב' תשס"ח

מצביעים ומערכים - סיכוםמצביעים ומערכים - סיכום

: הוא מכיל כתובת )של : הוא מכיל כתובת )של סוג של מצביעסוג של מצביעמשתנה מערך הוא משתנה מערך הוא •התא הראשון במערך(, אבל אי-אפשר לשנות אותה.התא הראשון במערך(, אבל אי-אפשר לשנות אותה.

זו הסיבה שבהעברת מערך לפונקציה המערך המקורי מושפע.זו הסיבה שבהעברת מערך לפונקציה המערך המקורי מושפע.•

אפשר לגשת לתא במערך גם בעזרת חישוב כתובתו יחסית אפשר לגשת לתא במערך גם בעזרת חישוב כתובתו יחסית •;;100100(=(=array+5array+5*)*)לכתובת התחלת המערך. למשל: לכתובת התחלת המערך. למשל:

שאלות?שאלות?

Page 23: קורס תכנות – סמסטר ב' תשס"ח

נקודה לתשומת-לב: איתחול מה נקודה לתשומת-לב: איתחול מה שמוצבעשמוצבע

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

int *ptr;int *ptr;*ptr=10;*ptr=10;

בהתאם, בהגדרת מצביע לא ניתן לכתוב ערכים למקום שהוא בהתאם, בהגדרת מצביע לא ניתן לכתוב ערכים למקום שהוא • לרשום: לרשום:לא ניתןלא ניתןמצביע עליו. למשל מצביע עליו. למשל

int *my_array={1,2,3};int *my_array={1,2,3};

יכתוב לכתובת שנמצאת במצביע לפני שאיתחלנו יכתוב לכתובת שנמצאת במצביע לפני שאיתחלנו אותואותו

Page 24: קורס תכנות – סמסטר ב' תשס"ח

סיכום מצביעיםסיכום מצביעים

דיברנו על:

כתובות בזיכרון•

מצביעים והשימוש בהם•

מערכים ומצביעים•

מערכים ופונקציות•

Page 25: קורס תכנות – סמסטר ב' תשס"ח

??שאלות נוספותשאלות נוספות

מצביעיםמצביעים

Page 26: קורס תכנות – סמסטר ב' תשס"ח

מבנים

Page 27: קורס תכנות – סמסטר ב' תשס"ח

CCטיפוסי משתנים בשפת טיפוסי משתנים בשפת הכרנו במהלך הקורס את טיפוסי המשתנים הבסיסיים שניתן לייצג בשפת הכרנו במהלך הקורס את טיפוסי המשתנים הבסיסיים שניתן לייצג בשפת •

CC.מספר שלם/ממשי, תו, מחרוזת, ומערך.: מספר שלם/ממשי, תו, מחרוזת, ומערך :

כשכתבנו תוכניות לפתרון בעיות כלשהן, יצגנו את נתוני התוכנית ע"י כשכתבנו תוכניות לפתרון בעיות כלשהן, יצגנו את נתוני התוכנית ע"י •משתנים מהטיפוסים האלה.משתנים מהטיפוסים האלה.

כידוע, בבעיות מציאותית יכולים להיות אובייקטים מורכבים, שלא בהכרח כידוע, בבעיות מציאותית יכולים להיות אובייקטים מורכבים, שלא בהכרח •מתאימים ליצוג ע"י מספר, תו, או אפילו מערך.מתאימים ליצוג ע"י מספר, תו, או אפילו מערך.

למשל בבעיות גיאומטריות מדובר על נקודות, ישרים, מצולעים, וכדומה.למשל בבעיות גיאומטריות מדובר על נקודות, ישרים, מצולעים, וכדומה.•מינהלת-האוניברסיטה מטפלת בפקולטות, קורסים, סטודנטים, וכו'.מינהלת-האוניברסיטה מטפלת בפקולטות, קורסים, סטודנטים, וכו'.•

Page 28: קורס תכנות – סמסטר ב' תשס"ח

CCטיפוסי משתנים בשפת טיפוסי משתנים בשפת

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

האלה.האלה.

טיפוס שייצג מספר טיפוס שייצג מספר למשל, לטיפול במספרים מרוכבים היינו רוצים למשל, לטיפול במספרים מרוכבים היינו רוצים •מרוכב. מרוכב.

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

במערכת המידע של האוניברסיטה נירצה טיפוסי-משתנים עבור במערכת המידע של האוניברסיטה נירצה טיפוסי-משתנים עבור •סטודנט, קורס, וכו' )שכל אחד מהם כולל כמה שדות-מידע סטודנט, קורס, וכו' )שכל אחד מהם כולל כמה שדות-מידע

רלוונטיים(.רלוונטיים(.

Page 29: קורס תכנות – סמסטר ב' תשס"ח

יצירת טיפוסי משתנים חדשיםיצירת טיפוסי משתנים חדשים

להגדיר טיפוסי משתנים להגדיר טיפוסי משתנים מאפשרת לנו מאפשרת לנו CCשפת שפת • שיתאימו לבעיה שאנחנו רוצים לפתור. שיתאימו לבעיה שאנחנו רוצים לפתור.חדשיםחדשים

(. הפקודה (. הפקודה structurestructure ) )"מבנה""מבנה"טיפוס חדש כזה נקרא טיפוס חדש כזה נקרא •..structstructשתשמש אותנו לכך היא שתשמש אותנו לכך היא

בדרך-כלל מבנה כולל כמה משתנים, שנקראים בדרך-כלל מבנה כולל כמה משתנים, שנקראים • )דוגמא בשקף הבא(. )דוגמא בשקף הבא(."שדות""שדות"

Page 30: קורס תכנות – סמסטר ב' תשס"ח

הגדרת מבנה חדש – דוגמאהגדרת מבנה חדש – דוגמא

. . YY ו- ו- XX מיוצגת על-ידי שתי קואורדינטות, מיוצגת על-ידי שתי קואורדינטות, נקודה במישורנקודה במישור•

הגדרת מבנה שייצג נקודה תיראה למשל כך: הגדרת מבנה שייצג נקודה תיראה למשל כך:

structstruct point { point {

double x;double x;

double y;double y;

}; }; בתחילת הקובץבתחילת הקובץההגדרה הזו לא תופיע בתוך פונקציה, אלא ההגדרה הזו לא תופיע בתוך פונקציה, אלא •

(.(.definedefine## וה- וה- includeinclude##)בד"כ מייד אחרי שורות ה- )בד"כ מייד אחרי שורות ה- כעת ניתן להגדיר בתוכנית משתנים מהסוג הזה, כפי כעת ניתן להגדיר בתוכנית משתנים מהסוג הזה, כפי •

שניראה בשקף הבא. שניראה בשקף הבא.

Page 31: קורס תכנות – סמסטר ב' תשס"ח

הגדרת מבנה חדש – המשך הגדרת מבנה חדש – המשך הדוגמאהדוגמא דוגמא להגדרת משתנים מהטיפוס החדש:דוגמא להגדרת משתנים מהטיפוס החדש:•

int main)(int main)(

{{

struct pointstruct point P1,P2; P1,P2;

return 0;return 0;

}}(, (, pointpointבכך הגדרנו שתי נקודות )שני משתנים מסוג מבנה בכך הגדרנו שתי נקודות )שני משתנים מסוג מבנה •

שלכל אחת מהן יש שני שדות.שלכל אחת מהן יש שני שדות.P1P2

xx

yy

xx

yy

Page 32: קורס תכנות – סמסטר ב' תשס"ח

הגדרת מבנה חדש – המשך הגדרת מבנה חדש – המשך ניתן לגשת לכל אחד מהשדות של מבנה ולכתוב/לקרוא ניתן לגשת לכל אחד מהשדות של מבנה ולכתוב/לקרוא הדוגמאהדוגמא

אליו/ממנו. למשל:אליו/ממנו. למשל:

int main)(int main)(

{{

struct pointstruct point P1,P2; P1,P2;

P1P1..x = 6;x = 6;

P1P1..y = 7;y = 7;

P2P2..x = 4;x = 4;

P2P2..y = 2;y = 2;

printf)“%g\n”, P1printf)“%g\n”, P1..y(;y(;

return 0;return 0;

}}

P1P2

4

72

6xx

yy

xx

yy

((77)יודפס )יודפס

Page 33: קורס תכנות – סמסטר ב' תשס"ח

מבנים - נושאיםמבנים - נושאים

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

Page 34: קורס תכנות – סמסטר ב' תשס"ח

מבנים - תיאור פורמלימבנים - תיאור פורמליהגדרת מבנה )טיפוס משתנה חדש(:הגדרת מבנה )טיפוס משתנה חדש(:•

structstruct שם הטיפוס החדששם הטיפוס החדש{{

שם-שדהשם-שדה טיפוס טיפוס ;;

… …....

שם-שדהשם-שדה טיפוס טיפוס ;;

} } ;; הגדרת משתנה מהסוג החדש שהגדרנו:הגדרת משתנה מהסוג החדש שהגדרנו:•

structstruct שם הטיפוס החדששם הטיפוס החדששם משתנה שם משתנה ;; של משתנה שהוא מבנה נעשית ע"י של משתנה שהוא מבנה נעשית ע"יפנייה לשדהפנייה לשדה•

שם השדהשם השדה..שם המשתנהשם המשתנה

Page 35: קורס תכנות – סמסטר ב' תשס"ח

הגדרת מבנה חדש - הדוגמא הגדרת מבנה חדש - הדוגמא הקודמתהקודמת

#include<stdio.h>#include<stdio.h>struct point {struct point {

double x;double x;double y;double y;

}; }; int main)(int main)({{ struct pointstruct point P1,P2; P1,P2; P1P1..x = 6;x = 6; P1P1..y = 7;y = 7; P2P2..x = 4;x = 4; P2P2..y = 2;y = 2; printf)“%g\n”, P1printf)“%g\n”, P1..y(;y(; return 0;return 0;}}

P1P2

4

72

6xx

yy

xx

yy

Page 36: קורס תכנות – סמסטר ב' תשס"ח

איתחול מבניםאיתחול מבנים

גם משתנים מטיפוס חדש אפשר לאתחל בשורת ההגדרה. גם משתנים מטיפוס חדש אפשר לאתחל בשורת ההגדרה. •למשל בהתייחס לדוגמא הקודמת:למשל בהתייחס לדוגמא הקודמת:

struct pointstruct point P = {6,7}; P = {6,7};..77 ל- ל- yy והשדה והשדה66 יאותחל ל- יאותחל ל- PP של המשתנה של המשתנהxxהשדה השדה •

באופן כללי, האיתחול הוא לפי סדר השדות בהגדרת באופן כללי, האיתחול הוא לפי סדר השדות בהגדרת •המבנה, כלומר האיבר הראשון ברשימת האיתחול יכנס המבנה, כלומר האיבר הראשון ברשימת האיתחול יכנס

לשדה הראשון, השני לשני, וכן הלאה )אם האיתחול הוא לשדה הראשון, השני לשני, וכן הלאה )אם האיתחול הוא חלקי, השאר יאותחל באפסים(.חלקי, השאר יאותחל באפסים(.

Page 37: קורס תכנות – סמסטר ב' תשס"ח

מבנים – הגדרהמבנים – הגדרה

מהם מבניםמהם מבנים•הגדרת מבניםהגדרת מבנים•איתחול מבניםאיתחול מבנים•שאלות?שאלות?•

Page 38: קורס תכנות – סמסטר ב' תשס"ח

פעולות על מבניםפעולות על מבנים

מתבצעת בצורה הרגילה:מתבצעת בצורה הרגילה: בין מבנים מאותו סוגבין מבנים מאותו סוגהשמה השמה •

P1 = P2; P1 = P2; . )העתקה . )העתקה P1P1 לתוך לתוך מועתקמועתק פשוט פשוט P2P2התוכן של התוכן של •

שדה-שדה(שדה-שדה( )שינוי שלו )שינוי שלו מועתקמועתקאם אחד השדות הוא מערך אז גם הוא אם אחד השדות הוא מערך אז גם הוא •

(.(.P2P2 לא ישפיע על לא ישפיע על P1P1ב- ב-

אינן פועלותאינן פועלות ופעולות חשבוןופעולות חשבון )== והאחרות( )== והאחרות( פעולות השוואהפעולות השוואה• )זה לא יתקמפל(.)זה לא יתקמפל(. עבור מבניםעבור מבנים

כלומר נצטרך לכתוב פונקציות עבור הפעולות שנירצה כלומר נצטרך לכתוב פונקציות עבור הפעולות שנירצה •ליישם )למשל נשווה את כל אחד מהשדות כדי לבצע ליישם )למשל נשווה את כל אחד מהשדות כדי לבצע

השוואה(.השוואה(.

Page 39: קורס תכנות – סמסטר ב' תשס"ח

pointpoint דוגמא: פונקציה להשוואת דוגמא: פונקציה להשוואת מבנימבני

int equal)int equal)struct pointstruct point p, p, struct pointstruct point q(q(

{{

return ) )p.x == q.x( && )p.y == q.y((return ) )p.x == q.x( && )p.y == q.y((

}}

, ואחרת , ואחרת 11אם הנקודות זהות יוחזר אם הנקודות זהות יוחזר 00

Page 40: קורס תכנות – סמסטר ב' תשס"ח

דוגמא לשימוש במבניםדוגמא לשימוש במבניםנכתוב פונקציה שמחשבת מרחק בין שתי נקודות:נכתוב פונקציה שמחשבת מרחק בין שתי נקודות:•

double dist) double dist) struct pointstruct point p, p, struct pointstruct point q( q(

{{

double d;double d;

d = )p.x – q.x(*)p.x – q.x( + )p.y–q.y(*)p.y-q.y(;d = )p.x – q.x(*)p.x – q.x( + )p.y–q.y(*)p.y-q.y(;

return sqrt)d(;return sqrt)d(;

}}

כדי להשתמש בפונקציה כדי להשתמש בפונקציה >>include<math.hinclude<math.h##)יופיע בתחילת הקובץ )יופיע בתחילת הקובץ sqrtsqrt))

Page 41: קורס תכנות – סמסטר ב' תשס"ח

דוגמת שימוש במבנים - המשךדוגמת שימוש במבנים - המשך……..

int main)(int main)(

{{struct pointstruct point p,q; p,q;

printf)“Enter x and y coord. of the first point\n”(;printf)“Enter x and y coord. of the first point\n”(;

scanf)“%lf%lf”, &p.x,&p.y(;scanf)“%lf%lf”, &p.x,&p.y(;

printf)“Enter x and y coord. of the second point\n”(; printf)“Enter x and y coord. of the second point\n”(;

scanf)“%lf%lf”, &q.x,&q.y(;scanf)“%lf%lf”, &q.x,&q.y(;

printf)“Their distance is %g\n”, dist)p,q((;printf)“Their distance is %g\n”, dist)p,q((;

return 0;return 0;

}}

Page 42: קורס תכנות – סמסטר ב' תשס"ח

פונקציות ומבניםפונקציות ומבניםאיך מבני הנקודות מועברים לפונקציה?איך מבני הנקודות מועברים לפונקציה?•

Page 43: קורס תכנות – סמסטר ב' תשס"ח

פונקציות ומבניםפונקציות ומבניםאיך מבני הנקודות מועברים לפונקציה?איך מבני הנקודות מועברים לפונקציה?•

של השדות שלהם של השדות שלהם הערכים הערכיםהם מועברים על ידי העתקתהם מועברים על ידי העתקת•לפרמטרים של הפונקציה. לפרמטרים של הפונקציה.

..intint(, כמו עבור (, כמו עבור ((call by valuecall by valueכמו במשתנים רגילים כמו במשתנים רגילים •..mainmainשינוי הנקודה בפונקציה לא ישנה את הנקודה ב- שינוי הנקודה בפונקציה לא ישנה את הנקודה ב- •

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

Page 44: קורס תכנות – סמסטר ב' תשס"ח

פונקציות ומבנים – נקודה לתשומת-לבפונקציות ומבנים – נקודה לתשומת-לב

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

המערך מועברת(.המערך מועברת(.

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

Page 45: קורס תכנות – סמסטר ב' תשס"ח

מבנים - פעולותמבנים - פעולות

השמה בין מבנים מותרת )מתבצעת העתקה שדה-שדה(השמה בין מבנים מותרת )מתבצעת העתקה שדה-שדה(•פעולות השוואה ופעולות חשבון לא עובדותפעולות השוואה ופעולות חשבון לא עובדות•ניתן להעביר מבנים לפונקציה ולהחזיר ממנה מבנה, והם ניתן להעביר מבנים לפונקציה ולהחזיר ממנה מבנה, והם •

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

שאלות?שאלות?•

Page 46: קורס תכנות – סמסטר ב' תשס"ח

מבנים – סיכום בינייםמבנים – סיכום בינייםשימוש במבנים מאפשר הגדרת טיפוסי משתנים חדשים שימוש במבנים מאפשר הגדרת טיפוסי משתנים חדשים •

שקרובים לעולם-הבעיה שאנחנו פותרים.שקרובים לעולם-הבעיה שאנחנו פותרים.

לא ניתן להשתמש בפעולות החשבון וההשוואה הרגילות על לא ניתן להשתמש בפעולות החשבון וההשוואה הרגילות על •מבנים - יש להגדיר פונקציות עבורן בהתאם לצורך )רק מבנים - יש להגדיר פונקציות עבורן בהתאם לצורך )רק

פעולת ההשמה מוגדרת, ובה מתבצעת גם העתקת פעולת ההשמה מוגדרת, ובה מתבצעת גם העתקת מערכים(. מערכים(.

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

מועתק ולא מועבר המערך המקורי(.מועתק ולא מועבר המערך המקורי(.

כעת נדבר על מבנים ומצביעים, מערכים של מבנים, ומבנים כעת נדבר על מבנים ומצביעים, מערכים של מבנים, ומבנים •בתוך מבנים.בתוך מבנים.

Page 47: קורס תכנות – סמסטר ב' תשס"ח

מבנים ומצביעיםמבנים ומצביעים

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

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

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

בקריאה לפונקציה ישוכפל רק המצביע לכל מבנה, ובעזרת המצביע בקריאה לפונקציה ישוכפל רק המצביע לכל מבנה, ובעזרת המצביע •נוכל לשנות את המבנה המקורי.נוכל לשנות את המבנה המקורי.

Page 48: קורס תכנות – סמסטר ב' תשס"ח

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

שלו(. למשל:שלו(. למשל:

struct point P={5,6}; struct point P={5,6};

struct pointstruct point **ptr; ptr;

ptr = &P ;ptr = &P ;

55

66

P

ptr

P.xP.x

P.yP.y

Page 49: קורס תכנות – סמסטר ב' תשס"ח

מצביעים ומבנים – גישה לשדות מצביעים ומבנים – גישה לשדות המבנההמבנה

שמצביע על שמצביע על ptrptr דרך דרך PPבדוגמא הזאת, כדי להגיע לשדות של בדוגמא הזאת, כדי להגיע לשדות של •PP -כרגיל: כרגיל:**, אפשר להשתמש ב- , אפשר להשתמש ב

• )*ptr(.)*ptr(.x = 3; x = 3; שקול לשקול ל- - P.P.x = 3;x = 3;• )*ptr(.)*ptr(.y = 7; y = 7; שקול לשקול ל- - P.P.y = 7;y = 7;

)צריך סוגריים כי אחרת לנקודה יש קדימות()צריך סוגריים כי אחרת לנקודה יש קדימות(

Page 50: קורס תכנות – סמסטר ב' תשס"ח

מצביעים ומבנים – גישה לשדות מצביעים ומבנים – גישה לשדות המבנההמבנה

שמצביע על שמצביע על ptrptr דרך דרך PPבדוגמא הזאת, כדי להגיע לשדות של בדוגמא הזאת, כדי להגיע לשדות של •PP -כרגיל: כרגיל:**, אפשר להשתמש ב- , אפשר להשתמש ב

• )*ptr(.)*ptr(.x = 3; x = 3; שקול לשקול ל- - P.P.x = 3;x = 3;• )*ptr(.)*ptr(.y = 7; y = 7; שקול לשקול ל- - P.P.y = 7;y = 7;

<-<-אבל בדרך-כלל נשתמש לצורך זה בסימון מקוצר: חץ אבל בדרך-כלל נשתמש לצורך זה בסימון מקוצר: חץ •• ptr->ptr->x = 3; x = 3; שקול לשקול ל-- P.P.x = 3;x = 3;• ptr->ptr->y = 7; y = 7; שקול לשקול ל-- P.P.y = 7;y = 7;

גישה לשדה במבנה שמצביעים עליו.גישה לשדה במבנה שמצביעים עליו.כלומר משמעות החץ היא כלומר משמעות החץ היא •

)צריך סוגריים כי אחרת לנקודה יש קדימות()צריך סוגריים כי אחרת לנקודה יש קדימות(

Page 51: קורס תכנות – סמסטר ב' תשס"ח

מצביעים ומבנים - דוגמאמצביעים ומבנים - דוגמאפונקציית ההשוואה כשמועברים מצביעים:פונקציית ההשוואה כשמועברים מצביעים:•

int equal) struct point int equal) struct point **p, struct point p, struct point **q(q(

{{

return ))preturn ))p->->x == qx == q->->x( && )px( && )p->->y == qy == q->->y((;y((;

}}

((לשדה של המבנה שמצביעים עליולשדה של המבנה שמצביעים עליו)הגישה עם חץ היא )הגישה עם חץ היא

int equal)struct point p, struct pointint equal)struct point p, struct point q( q( ::במקוםבמקום

{{

return ) )preturn ) )p..x == qx == q..x( && )px( && )p..y == qy == q..y((;y((;

} } )) לשדה של מבנהלשדה של מבנההגישה עם נקודה היא הגישה עם נקודה היא ((

הקריאה לפונקציה ע"י הקריאה לפונקציה ע"י equal)&P1,&P2(equal)&P1,&P2(

)equal)P1, P2(equal)P1, P2הקריאה לפונקציה ע"י הקריאה לפונקציה ע"י

Page 52: קורס תכנות – סמסטר ב' תשס"ח

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

עצמם:עצמם:

double dist)struct pointdouble dist)struct point **p, struct pointp, struct point **q(q( {{

double d,dx,dy;double d,dx,dy; dx = pdx = p->->x - qx - q->->x;x; dy = pdy = p->->y - qy - q->->y;y; d = dx*dx + dy*dy; d = dx*dx + dy*dy; return sqrt)d(;return sqrt)d(;

}};;mainmain??printf)“The distance is %g\n”, dist)printf)“The distance is %g\n”, dist)&&P1,P1,&&P2(P2())איך תיראה הקריאה ב-איך תיראה הקריאה ב-

Page 53: קורס תכנות – סמסטר ב' תשס"ח

מבנים ומצביעיםמבנים ומצביעים

כמו עם טיפוסי-משתנים רגיליםכמו עם טיפוסי-משתנים רגילים•גישה לשדות של המבנה המוצבע ע"י גישה לשדות של המבנה המוצבע ע"י •

->->שאלות?שאלות?•

Page 54: קורס תכנות – סמסטר ב' תשס"ח

מבנים – כתיבה מקוצרתמבנים – כתיבה מקוצרת

struct pointstruct pointשמו של הטיפוס החדש שהגדרנו הוא שמו של הטיפוס החדש שהגדרנו הוא •באמצעות הפקודה באמצעות הפקודה structstruct אפשר לחסוך את כתיבת המילהאפשר לחסוך את כתיבת המילה•

typedeftypedef,, :שמאפשרת לתת שם חדש לטיפוס-משתנה: שמאפשרת לתת שם חדש לטיפוס-משתנה

struct point {struct point {

double x;double x;

double y;double y;

};};

typedef typedef struct pointstruct point point point; ;

טיפוס קייםטיפוס קייםשם חדששם חדש

Page 55: קורס תכנות – סמסטר ב' תשס"ח

מבנים – כתיבה מקוצרתמבנים – כתיבה מקוצרת

typedef typedef struct pointstruct point { {double x;double x;double y;double y;

} } pointpoint;;

במקום לכתוב במקום לכתובpointpoint נוכל לכתוב נוכל לכתוב typedeftypedefבזכות ה- בזכות ה- •• struct pointstruct point:זה שקול לחלוטין(. למשל: )זה שקול לחלוטין(. למשל(

double dist)double dist)point point p, p, pointpoint q(q(

אפשר גם לכתוב את שתי השורות יחד באופן הבא:אפשר גם לכתוב את שתי השורות יחד באופן הבא:

Page 56: קורס תכנות – סמסטר ב' תשס"ח

typedeftypedefעוד על עוד על יכולה לשמש גם כדי לתת שם יכולה לשמש גם כדי לתת שם typedeftypedef נציין שהפקודהנציין שהפקודה•

חדש לטיפוס קיים שאיננו מבנה.חדש לטיפוס קיים שאיננו מבנה.

למשל אם נרצה לתת שם מיוחד ל-למשל אם נרצה לתת שם מיוחד ל-•unsigned intunsigned int

אפשר לכתוב: אפשר לכתוב: typedeftypedef unsigned intunsigned int UINTUINT;;

עכשיו בכל מקום בתוכנית שנרצה נוכל להשתמש עכשיו בכל מקום בתוכנית שנרצה נוכל להשתמש •..unsigned intunsigned int כדי להגדיר כדי להגדיר UINTUINTב-ב-

unsigned intunsigned int ui; ui; שקול לשקול ל- - UINTUINT ui ui;;

שם קיים שם חדש

Page 57: קורס תכנות – סמסטר ב' תשס"ח

מבנה בתוך מבנהמבנה בתוך מבנה

..מבנים אחריםמבנים אחריםשדות של מבנה יכולים להיות בעצמם שדות של מבנה יכולים להיות בעצמם •

מלבן מלבן לדוגמא, נאמר שנירצה להגדיר מבנה שמתאר לדוגמא, נאמר שנירצה להגדיר מבנה שמתאר •במישור שמקביל לצירים. במישור שמקביל לצירים.

Page 58: קורס תכנות – סמסטר ב' תשס"ח

מבנה בתוך מבנה - דוגמא מבנה בתוך מבנה - דוגמא

שני קודקודים נגדייםשני קודקודים נגדייםמלבן שמקביל לצירים נקבע על-ידי מלבן שמקביל לצירים נקבע על-ידי •כאלה:כאלה:

p

q

Page 59: קורס תכנות – סמסטר ב' תשס"ח

מבנה בתוך מבנהמבנה בתוך מבנה

struct rect {struct rect {double xl, xh, yl, yh;double xl, xh, yl, yh;

};};

struct rect {struct rect { pointpoint p; p; pointpoint q; q;

};};typedef struct rect typedef struct rect rectrect;;

אפשר להגדיר את זה על-ידי הקואורדינטות של שני :הקודקודים

)נדגים כאן גם את נקודות2אבל יותר נוח וברור להגדיר ע"י (:typedefהרישום המקוצר עם

Page 60: קורס תכנות – סמסטר ב' תשס"ח

מבנה בתוך מבנה - אתחולמבנה בתוך מבנה - אתחול

גם מבנה שיש בתוכו מבנה אפשר לאתחל בשורת ההגדרה:גם מבנה שיש בתוכו מבנה אפשר לאתחל בשורת ההגדרה:•rect r = { rect r = { {5,6}{5,6} , , {10,2}{10,2} }; };

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

אפשר כמובן גם לאתחל כל שדה ישירות אחרי ההגדרה:אפשר כמובן גם לאתחל כל שדה ישירות אחרי ההגדרה:•rr..pp..x = 5;x = 5;rr..pp..y = 6;y = 6;rr..qq..x = 10;x = 10;rr..qq..y = 2;y = 2;

p q

Page 61: קורס תכנות – סמסטר ב' תשס"ח

מערך של מבניםמערך של מבנים

כמו טיפוסי משתנים אחרים, אפשר גם להגדיר מערך של כמו טיפוסי משתנים אחרים, אפשר גם להגדיר מערך של •מבנים.מבנים.

למשל, אפשר להגדיר מערך של נקודות:למשל, אפשר להגדיר מערך של נקודות:•

int main)(int main)(

{{

pointpoint my_point_array[20];my_point_array[20];

……

}}

Page 62: קורס תכנות – סמסטר ב' תשס"ח

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

MaxRectMaxRectשם הפונקציה יהיה שם הפונקציה יהיה • מערך של מלבנים )כלומר מערך של מלבנים )כלומר הפרמטרים שהיא תקבל:הפרמטרים שהיא תקבל:•

הכתובת של המלבן הראשון במערך(, וגודל המערך.הכתובת של המלבן הראשון במערך(, וגודל המערך. מצביע למלבן מצביע למלבןהערך המוחזר:הערך המוחזר:•

מערך של מבנים - דוגמאמערך של מבנים - דוגמא

Page 63: קורס תכנות – סמסטר ב' תשס"ח

MaxRectMaxRect תכנון הפונקציהתכנון הפונקציה

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

היא תשמור את האורך המקסימלי שנמצא עד עכשיו ואת היא תשמור את האורך המקסימלי שנמצא עד עכשיו ואת •אינדקס המלבן שבו הוא נמצא.אינדקס המלבן שבו הוא נמצא.

אם האלכסון הנוכחי גדול יותר מהמקסימלי שהיה עד אם האלכסון הנוכחי גדול יותר מהמקסימלי שהיה עד •עכשיו, נעדכן את המקסימום ואת האינדקס. עכשיו, נעדכן את המקסימום ואת האינדקס.

בסוף יוחזר מצביע באמצעות האינדקס ששמרנו.בסוף יוחזר מצביע באמצעות האינדקס ששמרנו.•

Page 64: קורס תכנות – סמסטר ב' תשס"ח

איך ניראה מערך של מלבנים איך ניראה מערך של מלבנים בזיכרוןבזיכרון

rectrect

rectrect

rectrect

rectrect

rectrect

rectrect

rectrect

point ppoint p

point qpoint q

double xdouble x

double ydouble y

double xdouble x

double ydouble y

כל מלבן מכיל שני כל מלבן מכיל שני שדות מסוג נקודהשדות מסוג נקודה

כל נקודה מכילה שני כל נקודה מכילה שני doubledoubleשדות מסוג שדות מסוג

המלבנים נשמרים המלבנים נשמרים ברצף בזיכרוןברצף בזיכרון

Page 65: קורס תכנות – סמסטר ב' תשס"ח

rect *MaxRect)rect arr[ ], int size(rect *MaxRect)rect arr[ ], int size({{

double max=0;double max=0;int i, int i, max_index=0;max_index=0;for )i = 0 ; i < size ; i++(for )i = 0 ; i < size ; i++({{

if )dist)arr[i].p, arr[i].q( > max(if )dist)arr[i].p, arr[i].q( > max({{

max = dist)arr[i]. p, arr[i].q(;max = dist)arr[i]. p, arr[i].q(;max_index = i;max_index = i;

}}}}return arr + max_index;return arr + max_index;

}}

מלבן עם אלכסון מקסימלי –מלבן עם אלכסון מקסימלי –MaxRectMaxRect

מועברים המערך וגודלומועברים המערך וגודלו

נבדק אורך האלכסון.נבדק אורך האלכסון.

אם מצאנו אלכסון ארוך אם מצאנו אלכסון ארוך יותר אז מעדכנים את יותר אז מעדכנים את המקסימום והאינדקסהמקסימום והאינדקס

עוברים בלולאה על כל המלבניםעוברים בלולאה על כל המלבנים

מחזירים מצביע למלבן המקסימלי מחזירים מצביע למלבן המקסימלי )כתובת ההתחלה ועוד האינדקס )כתובת ההתחלה ועוד האינדקס

שלו(שלו(

אורך האלכסון המקס' עד כה מאותחל לאפסאורך האלכסון המקס' עד כה מאותחל לאפסאינדקס המלבן המקס' עד כה מאותחל לאפסאינדקס המלבן המקס' עד כה מאותחל לאפס

Page 66: קורס תכנות – סמסטר ב' תשס"ח

אתחול מערך של מבניםאתחול מערך של מבנים

גם מערך של מבנים אפשר לאתחל בשורת ההגדרה, על-ידי גם מערך של מבנים אפשר לאתחל בשורת ההגדרה, על-ידי •כתיבת ערכי איתחול לכל מבנה לפי הסדר. כתיבת ערכי איתחול לכל מבנה לפי הסדר.

לדוגמא עבור מערך של מלבנים: לדוגמא עבור מערך של מלבנים: •

rect arr[20] = { rect arr[20] = { {{ 3,4} , {5,6}}{{ 3,4} , {5,6}} , ,

{{ 4,7} , {9,10}}{{ 4,7} , {9,10}} , … } , … }

Page 67: קורס תכנות – סמסטר ב' תשס"ח

מבנה בתוך מבנה בתוך •מבנהמבנה

מערך של מבניםמערך של מבנים•שאלות?שאלות?•

Page 68: קורס תכנות – סמסטר ב' תשס"ח

מבנים – עוד דוגמאמבנים – עוד דוגמא

מבנים יכולים כאמור להכיל שדות מסוגים שונים.מבנים יכולים כאמור להכיל שדות מסוגים שונים.• )בהנחה ששמו באורך של )בהנחה ששמו באורך של סטודנטסטודנטדוגמא למבנה שמייצג דוגמא למבנה שמייצג •

תווים(: תווים(:4040פחות מ- פחות מ- struct student{struct student{

int id;int id; char name[char name[440]; 0]; double average;double average;};};typedef typedef struct studentstruct student student student;;

Page 69: קורס תכנות – סמסטר ב' תשס"ח

מבנים - סטודנטמבנים - סטודנטנוכל למשל להגדיר מערך של הסטודנטים בכיתה:נוכל למשל להגדיר מערך של הסטודנטים בכיתה:

# define CLASS_SIZE # define CLASS_SIZE 5500

int main)(int main)(

{{

student student class[CLASS_SIZE]; class[CLASS_SIZE];

……..

}}נכתוב לדוגמא פונקציה שמדפיסה את שמות הסטודנטים נכתוב לדוגמא פונקציה שמדפיסה את שמות הסטודנטים •

המצטיינים ומחזירה את מספרםהמצטיינים ומחזירה את מספרם

הוא הוא CLASS_SIZECLASS_SIZE)נניח ש- )נניח ש- קבוע שמכיל את מס' הסטודנטים קבוע שמכיל את מס' הסטודנטים

בכיתה(בכיתה(

Page 70: קורס תכנות – סמסטר ב' תשס"ח

דוגמא: פונקציה למציאת דוגמא: פונקציה למציאת המצטייניםהמצטיינים

int top_students)int top_students)student student students[ students[ ] (] ({{

int i, cnt = 0;int i, cnt = 0;for)i = 0; i < CLASS_SIZE; i++(for)i = 0; i < CLASS_SIZE; i++({{

if )students[ i ]if )students[ i ]..average > 90(average > 90({{ printf)“%s\n”, students[ i ]printf)“%s\n”, students[ i ]..name(;name(; cnt++;cnt++;}}

}}return cnt;return cnt;

}}כאמור מחזירים את מספר המצטייניםכאמור מחזירים את מספר המצטיינים

Page 71: קורס תכנות – סמסטר ב' תשס"ח

מבנים - סיכוםמבנים - סיכום טיפוסי משתנים חדשיםטיפוסי משתנים חדשיםשימוש במבנים מאפשר הגדרת שימוש במבנים מאפשר הגדרת •

שקרובים לעולם-הבעיה שאנחנו פותרים.שקרובים לעולם-הבעיה שאנחנו פותרים.

להשתמש בהם כמו בטיפוסים רגילים מבחינת להשתמש בהם כמו בטיפוסים רגילים מבחינת אפשראפשר•הגדרת מערך של מבנים, מצביעים על מבנה, העברה הגדרת מערך של מבנים, מצביעים על מבנה, העברה

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

להשתמש בפעולות החשבון וההשוואה הרגילות להשתמש בפעולות החשבון וההשוואה הרגילות לא ניתןלא ניתן•על מבנים - יש להגדיר פונקציות עבורן בהתאם לצורך.על מבנים - יש להגדיר פונקציות עבורן בהתאם לצורך.

..structstruct ניתן לחסוך את כתיבת המילה ניתן לחסוך את כתיבת המילה typedeftypedefע"י ע"י •

Page 72: קורס תכנות – סמסטר ב' תשס"ח

??שאלות נוספותשאלות נוספות

קורס תכנות – שיעור תשיעיקורס תכנות – שיעור תשיעי

Page 73: קורס תכנות – סמסטר ב' תשס"ח

בהצלחה בהצלחה

תכנות - שיעור תשיעיתכנות - שיעור תשיעי