עבור לתוכן

מבנה הרשימה המקושרת

Featured Replies

פורסם

אם נתונה לי רשימה מקושרת:


typedef struct timer_s{
int time;
fun_t fun;
struct timer_s* next;
}
timer;

לא הבנתי מה המשמעות של:

timer;

הרי מבנה הרשימה נמצא תחת הסוגריים המסולסלות...

תודה.

פורסם

timer הוא בעצם קשור ל typedef ששמת שם .. מה שעשית הוא בעצם להגדיר משתנה חדש שהשם שלו יהיה timer ... (בדיוק כמו שיש char / int עכשיו יש גם timer)

אם תצהיר בתוכנית על משתנה מסוג timer המשתנה יהיה מבנה כמו שמוצהר בתוך הסוגריים ..

הבנת אותי?

פורסם
  • מחבר

הבנתי אותך... זה אומר שכל מה שאני אגדיר מ- timer יהיה לו בתכונות מה ?

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

ועוד משהו.. האם ה- typedef הוא שאיפשר לי ליצור משתנה נוסף לאחר המבנה או שבלעדיו גם הייתי יכול ליצור ?

תודה.

פורסם

את השאלה הראשונה לא ממש הבנתי...

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

שאלה אחרונה בעקרון ברגע שהצהרת על זה

struct timer_s{

int time;

fun_t fun;

struct timer_s* next;

}

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

השימוש ב typedef הוא כזה

typedef שם_חדש שם_ישן

דוגמא

typedef int iem

עכשיו גם אפשר להציר על משתנה iem אשר לו תכונות כמו לint.

פורסם

הסיבה ל-typedef כאן היא בגלל מגבלה שקיימת ב-C בנוגע ל-struct. נניח שאני מגדיר struct באופן הבא:

struct MyStruct {
int x;
char y;
}

הבעיה היא שהשם של הטיפוס הזה הוא לא MyStruct, אלא struct MyStruct. כלומר, על מנת ליצור משתנה מטיפוס MyStruct אתה חייב להוסיף שוב את המילה struct, כלומר ההצהרה תהיה משהו כזה:

struct MyStruct s;

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

int foo(struct MyStruct s);

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

typedef struct MyStruct MyStruct_t;

השורה הזו מגדירה טיפוס בשם "MyStruct_t" שזהה לטיפוס "struct MyStruct". עכשיו, כל פעם שתרצה להגדיר משתנה מהטיפוס הזה, יספיק לך לעשות:

MyStruct_t s;

בלי ה-struct.

יתרה מכך, הקומפיילר נותן לך "קיצור דרך" - משלבים את הגדרת ה-struct ואת ה-typedef באותה שורה, כלומר:

typedef struct MyStruct {
int x;
char y;
} MyStruct_t;

הקוד הזה שקול לשילוב של שתי ההגדרות הנ"ל.

קומפיילרים מסויימים, אגב, מאפשרים להגדיר ב-typedef את אותו השם, כלומר:

typedef struct MyStruct MyStruct;

ואז לא צריך לתת לטיפוס שני שמות שונים.

יש כמובן עוד שימושים ל-typedef, בעיקר בשביל מודולריות.

פורסם
  • מחבר

תודה על ההסבר המושקע :D

שאלה נוספת, במבנה הספציפי שלי, אם אני אגדיר משתנה מטיפוס timer, אילו מאפיינים הוא יורש מהמבנה הספציפי הזה?

הראשון יהיה מאפיין של זמן שמוגדר במבנה כ-time ע"י ההצהרה int time והשני זה fun_t fun מה זה אומר ?

פורסם

למה "מאפיינים"? אלו הם האיברים של המבנה. הוא לא "יורש" כלום, זו פשוט ההגדרה שלו.

fun_t fun אומר שיהיה לו איבר בשם fun, שהטיפוס שלו הוא fun_t (הטיפוס הזה צריך להיות מוגדר במקום אחר כלשהו, ולפי הת'רדים הקודמים שלי למיטב זכרוני הוא מייצג מצביע לפונקציה).

פורסם
  • מחבר

אני יכול לייצג את המצביע לפונק' כך:

typedef void (*fun_t) (void); 

נכון ?

פורסם

מה הכוונה ב"לייצג"? השורה הזו מגדירה את הטיפוס.

פורסם
  • מחבר

כן. התכוונתי ללהגדיר.

זאת בעצם השורה שהיתה חסרה בשביל המבנה לא ?

פורסם
  • מחבר

תודה :)

ובאותו הקשר...

אם יש לי את הפונק':


void add_timer (int sec, fun_t fun)
{
timer* curr, *new_timer;
new_timer=(timer*)malloc(sizeof(timer));
new_timer->time=sec;
new_timer->fun=fun;
new_timer->next=NULL;

curr=head;
if(curr==NULL)
{
head=new_timer;
return;
}

while((curr->next!=NULL)&& (curr->next->time<sec))
curr=curr->next;

new_timer->next=curr->next;
curr->next=new_timer;

return;
}

כאשר המטרה בפונק' הינה להוסיף טיימר למאגר נתונים, כאשר

typedef void(*fun_t)void

מצביע לפונק'.

אני טוען שניתן את:

while((curr->next!=NULL) && (curr->next->time<sec))

לצמצם ל-

while (curr->next!=NULL)

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

ועוד משהו...

את:

curr=curr->next;

הבנתי, זה מקדם את הנוכחי באחד כדי שאני אוכל להעביר אותו אח"כ לטיימר החדש שיצרנו ממקודם,

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

new_timer->next=curr->next;
curr->next=new_timer;

ולא יכול להסתפק רק ב-

new_timer->next=curr->next;

??

תודה !

פורסם

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

פורסם
  • מחבר

עכשיו הבנתי...

תודה :)

פורסם

אני טוען שניתן את:

while((curr->next!=NULL) && (curr->next->time<sec))

לצמצם ל-

while (curr->next!=NULL)

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

בשלב זה היית צריך לשאול למה לא פשוט לוותר על הלולאה לגמרי אפילו עם הורדת התנאי שלך (עדין (O(n ) לטובת הכנסה ישירה לראש הרשימה (O(1 .אבל... מה ששניצל אמר...

ארכיון

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

דיונים חדשים