עבור לתוכן

בעיה עם רשימה מקורשת (הוספה לסוף רשימה)

Featured Replies

פורסם

אני רשמתי את הקוד הבא:



[code]typedef struct user
{
int data;
struct user *next;
}user;


user *head=NULL;


void createNode(user *newUser)
{
user *temp;
temp = (user*) malloc(sizeof(user));
if(temp == NULL)
{
printf("Insufficent memory");
system("PAUSE");
exit(1);
}
temp = head;
while(temp != NULL)
temp = temp->next;
temp->next = newUser;
}
void registerUser()
{
user *current;
current = (user*) malloc(sizeof(user));
if(current == NULL)
exit(1);
current->data = 4;
current->next = NULL;
createNode(current);
}


int main()
{
head = NULL;
registerUser();
system("PAUSE");
return 0;
}//main

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

פורסם

ברוך הבא לפורום. מה הקשר ל-Low Level? סי היא שפת עילית. הועבר לפורום הרלוונטי.

אני ממליץ שתערוך את הכותרת ותוסיף שם את השפה בה אתה עובד.

ולבעייתך - ב-createNode אתה יוצר user חדש ושם אותו ב-temp, אבל מיד אחרי זה אתה דורך על temp (ע"י temp = head). חוץ מזה, הלולאה שמתקדמת עד לסוף הרשימה נעצרת כש-temp הוא NULL, ככה שקריאה ל-temp->next כמובן תגרום לשגיאה. חוץ מזה, בשום מקום אתה לא מאתחל את head למשהו שאינו NULL.

פורסם
  • מחבר

ברוך הבא לפורום. מה הקשר ל-Low Level? סי היא שפת עילית. הועבר לפורום הרלוונטי.

אני ממליץ שתערוך את הכותרת ותוסיף שם את השפה בה אתה עובד.

ולבעייתך - ב-createNode אתה יוצר user חדש ושם אותו ב-temp, אבל מיד אחרי זה אתה דורך על temp (ע"י temp = head). חוץ מזה, הלולאה שמתקדמת עד לסוף הרשימה נעצרת כש-temp הוא NULL, ככה שקריאה ל-temp->next כמובן תגרום לשגיאה. חוץ מזה, בשום מקום אתה לא מאתחל את head למשהו שאינו NULL.

תודה על התגובה אבל HEAD חייב להיות NULL כי אין לי עוד מידע בכל מקרה, רק אחריו אמור להתווסף מידע.

פורסם

אין צורך לצטט את ההודעה שישר מעליך.

אז תחשוב איך מטפלים בהכנסה של האיבר הראשון לרשימה.

פורסם

נראה לי קצת סיבכת פה, לפי מה שהבנתי אתה יוצר את האיבר החדש שלך ב- registerUser ומכניס אותו לרשימה ב-createNode.

השורה הזאת לא נחוצה:


temp = (user*) malloc(sizeof(user));

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

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

פורסם
  • מחבר

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

1. ליצור משתנה זמני בשביל ליצור ולמלאות עוד חלק לרשימה (דוגמה current). (שיצביע על NULL)

2. ליצור משתנה (temp) שיקבל את הכתובת של ה HEAD וירוץ עד ש temp->Next יצביע על NULL

3. לעשות temp->Next = current.

בגלל זה אני לא מבין למה זה לא עובד :s07:

פורסם

1. סבבה, עובד טוב.

2. יש לך כאן שלוש בעיות - קודם כל מה ש-wiz-master ציין, שאתה לא צריך לעשות malloc ל-temp. בנוסף שתי הבעיות שאני ציינתי - אתה צריך לאתחל את head למשהו בפעם הראשונה שאתה מוסיף איבר כלשהו, וחוץ מזה הלולאה שלך שגויה.

3. גם כן סבבה.

תחשוב - אם head הוא null, ואתה מוסיף איבר אחד לרשימה, איך היא צריכה להיראות? על מה head צריך להצביע?

פורסם
  • מחבר

אוקיי, אז נגיד שעשיתי תנאי שאם HEAD = NULL אז שהוא קודם ימלא את HEAD

ואחרי זה עשיתי שאם הוא לא שווה לNULL אז שהוא יצור משתנה חדש זמני ואז ימלא אותו

אחרי שהוא ממלא אותו אז שירוץ עד לסוף הרשימה ויצביע עליו, עדיין לא עובד הוא קורס אחרי שהוא מקבל מספר:




void registerUser()
{
if(head == NULL)
{
scanf("%d",&head->data);
head->next = NULL;
}
else
{
user *current;
user *temp = head;
while(temp->next != NULL)
temp = temp->next;
current = (user*) malloc(sizeof(user));
if(current == NULL)
exit(1);
scanf("%d",&current->data);
current->next = NULL;
temp->next = current;
}
}

פורסם

אבל אם head == NULL אז אתה לא יכול לעשות head->data - זה יזרוק לך שגיאה. אתה צריך לאתחל את head. חוץ מזה, לפי הקוד שלך כשאתה קורא ל-registerUser בפעם הראשונה זה נוצרים לך שני משתמשים (ה-head וה-currentUser). זה בסדר כמובן אם אתה משתמש ב-head בתור "dummy" (איבר דמה ברשימה, שלא מתייחסים לקיומו).

פורסם
  • מחבר

מצטער אני פשוט לא מבין מה הולך...

כל מקום אומרים לי משהו אחר, שיגעו אותי להשתמש ב tail אבל זה סתם מסבך, אמרו לי להציב את HEAD כ NULL אבל אחרי זה אני לא יכול להציב בו ערכים או לגרום לו להצביע לאנשהו.

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

ניסיתי אפילו כמה פונקציות מוכנות אבל הן לא עובדות..

פורסם

הרעיון שלך בסדר, פשוט צריך לתקן קצת. כל מה שאתה צריך לעשות זה להוסיף malloc במקרה שבו head == NULL.

פורסם
  • מחבר

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



void registerUser()
{
if(head == NULL)
{
head = (user*) malloc(sizeof(user));
scanf("%d",&head->data);
head->next = NULL;
}
else
{
user *current;
user *temp = head;
while(temp->next != NULL)
temp = temp->next;
current = (user*) malloc(sizeof(user));
if(current == NULL)
exit(1);
scanf("%d",&current->data);
current->next = NULL;
temp->next = current;
}
}


int main()
{
int i;
registerUser();
user *current = head;
while(current->next != NULL)
printf("%d",current->data);
system("PAUSE");
return 0;
}//main

פורסם
  • מחבר

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

ארכיון

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

דיונים חדשים