שאלה קטנה ב-++C - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שאלה קטנה ב-++C


zag_zag

Recommended Posts

יש לי מבנה נתונים כלשהו, נקרא לו ST.

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

ST *head

כאשר head הוא שם המצביע.

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

בינתיים כתבתי את זה:

void func(ST *ptr)

{

ST *ptr2;

change ptr2 value

ptr = ptr2;

}

וקראתי לפונקציה עם זה:

func(&*head)

האם זה אמור לעבוד?

קישור לתוכן
שתף באתרים אחרים

ST *head

void 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);

אותו דבר בדיוק

קישור לתוכן
שתף באתרים אחרים

תודה, ושאלה נוספת:

איך אני ניגש למבנה ש-ptr מצביע עליו?

נניח שיש לי שדה ב-ST שנקרא field. ממה שהבנתי, כדי לגשת לשדה הזה דרך ptr אני צריך לכתוב את זה:

**ptr -> field

אבל אני מקבל שגיאת קומפליציה -

"pointer to sturcture required on left side of -> or ->*"

איפה הטעות שלי?

קישור לתוכן
שתף באתרים אחרים

אם הגדרת

ST *head

ואתה רוצה לגשת לשדה field אתה צריך לעשות

head->field or (*head).field

שים לב שלאופרטור חץ יש עדיפות על כוכבית.

אם הגדרת

ST **head

ואתה רוצה לגשת לשדה field אתה צריך לעשות

(*head)->field or (**head).field

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

קישור לתוכן
שתף באתרים אחרים

תודה, ושאלה אחרונה:

בזמן הרצת התוכנית אני מקבל הודעת שגיאה כזו -

Thread stopped at *

Fault: access violation at

0x4010b1: read of address

0x0

כאשר * הוא שם הכונן והקובץ

זו התוכנית:

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)

מה אני עושה לא בסדר?

קישור לתוכן
שתף באתרים אחרים

קודם כל הסתבכת קשות עם מבציעים

הטעות שלך נמצאת פה

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;

}

מקווה שעכשיו הכל ברור

קישור לתוכן
שתף באתרים אחרים

אם אתה לא מניח תקינות קלט אתה צריך לטפל במקרים ש-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;

}

}

קישור לתוכן
שתף באתרים אחרים

Holy, תודה רבה על העזרה שלך :)

בסוף באמת בילבלתי בין שני משתנים, כשאחד היה אמור להיות NULL והשני לא

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

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...