zag_zag פורסם 2003 ביולי 5 Share פורסם 2003 ביולי 5 יש לי מבנה נתונים כלשהו, נקרא לו ST.הצהרתי על מצביע למבנה כזה, כלומר כתבתי את זה:ST *headכאשר head הוא שם המצביע.אני רוצה לשנות את ערך המצביע בפונקציה, איך אני עושה דבר כזה?בינתיים כתבתי את זה:void func(ST *ptr){ ST *ptr2; change ptr2 value ptr = ptr2;}וקראתי לפונקציה עם זה:func(&*head)האם זה אמור לעבוד? קישור לתוכן שתף באתרים אחרים More sharing options...
Holy פורסם 2003 ביולי 5 Share פורסם 2003 ביולי 5 ST *headvoid func(ST **ptr){ ST *ptr2; change ptr2 value *ptr = ptr2;}func(&head)נגיד אתה עובד עם intאתה עושהint i;viod fun(int *a) { int b; *a=b;}fun(&i);אותו דבר בדיוק קישור לתוכן שתף באתרים אחרים More sharing options...
zag_zag פורסם 2003 ביולי 6 מחבר Share פורסם 2003 ביולי 6 תודה, ושאלה נוספת:איך אני ניגש למבנה ש-ptr מצביע עליו?נניח שיש לי שדה ב-ST שנקרא field. ממה שהבנתי, כדי לגשת לשדה הזה דרך ptr אני צריך לכתוב את זה:**ptr -> fieldאבל אני מקבל שגיאת קומפליציה - "pointer to sturcture required on left side of -> or ->*"איפה הטעות שלי? קישור לתוכן שתף באתרים אחרים More sharing options...
Holy פורסם 2003 ביולי 6 Share פורסם 2003 ביולי 6 אם הגדרת ST *head ואתה רוצה לגשת לשדה field אתה צריך לעשות head->field or (*head).field שים לב שלאופרטור חץ יש עדיפות על כוכבית.אם הגדרת ST **head ואתה רוצה לגשת לשדה field אתה צריך לעשות (*head)->field or (**head).field שוב חובה לשים סגוריים בגלל סדר פעולות, אתה רוצה קודם לראות לאן head מצביע ורק אז לגשת לשדה. קישור לתוכן שתף באתרים אחרים More sharing options...
zag_zag פורסם 2003 ביולי 6 מחבר Share פורסם 2003 ביולי 6 תודה, ושאלה אחרונה:בזמן הרצת התוכנית אני מקבל הודעת שגיאה כזו - Thread stopped at *Fault: access violation at0x4010b1: read of address0x0 כאשר * הוא שם הכונן והקובץזו התוכנית:struct Tree { int Key; Tree *p; Tree *Left; Tree *Right;};void TreeInsert(Tree **root,Tree **z){ Tree *x,*y; y = NULL; x = *root; while (x != NULL) { y = x; if ((*z) -> Key < x -> Key) x = x -> Left; else x = x -> Right; } (*z) -> p = y; if (y == NULL) root = z; else if ((*z) -> Key < x -> Key) y -> Left = *z; else y -> Right = *z;}void main(){ Tree *r,*z; r = new Tree; z = new Tree; r -> Key = 5; r -> p = NULL; r -> Left = NULL; r -> Right = NULL; z -> Key = 10; z -> p = NULL; z -> Left = NULL; z -> Right = NULL; TreeInsert(&r,&z);}את הודעת השגיאה אני מקבל על השורה הזו:if ((*z) -> Key < x -> Key)מה אני עושה לא בסדר? קישור לתוכן שתף באתרים אחרים More sharing options...
Holy פורסם 2003 ביולי 6 Share פורסם 2003 ביולי 6 מה בדיוק נסית לעשות?עריכה - הבנתי כבר לבדר קישור לתוכן שתף באתרים אחרים More sharing options...
Holy פורסם 2003 ביולי 6 Share פורסם 2003 ביולי 6 קודם כל הסתבכת קשות עם מבציעיםהטעות שלך נמצאת פה if (y == NULL) root = z; else if ((*z) -> Key < x -> Key) y -> Left = *z; else y -> Right = *z;הרי אם הגעת לכאן אז מהלולאה הקודמת x=NULL אז אתה לא יכול לגשת לשדה הזה, לדעתי זה צריך להיות y->key.חוץ מזה root = z פשוט לא יעשה כלום. הרי root הוא משתנה מקומי, אם כבר אז *root = *zהרבה יותר פשוט היה לעשות ככהstruct Tree { int Key; Tree *p; Tree *Left; Tree *Right;};void TreeInsert(Tree *root,Tree *z){ Tree *x,*y; y = NULL; x = root; while (x != NULL) { y = x; if (z->Key < x->Key) x = x->Left; else x = x->Right; } z->p = y; if (y == NULL) root = z; else if (z->key < y->Key) y -> Left = z; else y -> Right = z;}void main(){ Tree *r,*z; r = new Tree; z = new Tree; r -> Key = 5; r -> p = NULL; r -> Left = NULL; r -> Right = NULL; z -> Key = 10; z -> p = NULL; z -> Left = NULL; z -> Right = NULL; TreeInsert(r,z);}כל הקטע להגדיר מצביע למצביע זה אם אתה רוצה לשנות את המיקום שהמצביע מצביע אליו, לא את התוכן של מבנה הנתנונים ככה שכל זה מיותרלדוגמא אם יש לך פונקציה שיוצרת עץ ע"י הקצאה דינמית אז אתה חייב להחזיר מצביע למה שהיא יצרה והצלחה/כישלון. במקרה הזה בשביל להחזיר מצביע למה שהיא יצרה נעביר לפונקציה פרמטר נוסף שבו יאוכסן מצביע לעץ, כדי לשנות את המיקום של המצביע צריך להעביר מצביע למצביע לעץint init(tree **x) { tree *a; a = new tree; *x = a; return 0;}מקווה שעכשיו הכל ברור קישור לתוכן שתף באתרים אחרים More sharing options...
Holy פורסם 2003 ביולי 6 Share פורסם 2003 ביולי 6 אם אתה לא מניח תקינות קלט אתה צריך לטפל במקרים ש-root==NULL או z==NULLדרך אגב יותר ברור ויפה לעשות ככהvoid TreeInsert(Tree *x,Tree *z){ Tree *y; if(x==NULL) ??? /* big problem... maybe return Failure or just return */ if(z==NULL) return; y = NULL; while (x != NULL) { y = x; if (z->Key < x->Key) { if(x->Left == NULL) { z->p = x; x->Left = z; return; } x = x->Left; } else { if(x->Right == NULL) { z->p = x; x->Right = z; return; } x = x->Right; } } קישור לתוכן שתף באתרים אחרים More sharing options...
zag_zag פורסם 2003 ביולי 6 מחבר Share פורסם 2003 ביולי 6 Holy, תודה רבה על העזרה שלך בסוף באמת בילבלתי בין שני משתנים, כשאחד היה אמור להיות NULL והשני לא עריכה: את בדיקת תקינות הקלט אני לא צריך לבצע, כי אני מריץ את הפרוצדורה הזו אך ורק אחרי הקצאת ערך חדש בעץ קישור לתוכן שתף באתרים אחרים More sharing options...
Recommended Posts
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.