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

שאלה ב C


ronen100

Recommended Posts

בשפת C

הגדרתי שני structures:

typedef struct {

int x;

int y;

} a;

typdef struct {

int x;

float y;

int z;

} b;

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

לדוגמא :

int foo_a(a* s)

{

return (int)(s->x +s->y);

}

int foo_b(b* s)

{

return (int)(s->x +s->y);

}

איך אפשר לאחד לפונקציה אחת ?

שנראית בערך כך:

int foo(void *s)

{

return (int)(s->x + s->y);

}

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

אם מותר לך לעבוד בC++, התשובה ברורה מאלייה:

ירושה או templates

אם אתה מוגבל לC, אפשר לבצע את הדבר הבא (זה נראה כמו OOP עקום בהתחלה, אבל זה יכול לעבוד נהדר - הקרנל של וכל הדרייברים כתובים ככה לדוגמא):


typedef struct
{
int x;
int y;
}Base;


typedef struct
{
Base b;
float f;
} Extended;

ומכאן אתה פשוט מעביר את b מתי שצריך.

החסרון היחיד של זה הוא במידה ויש חשיבות לאופסטים של השדות במבנה(נגיד שבדוגמא לעיל הflaot צריך לשבת באמצע בין שני האינטים) אז אין לך איך לפתור את זה בשיטה הזאת. במידה וזה באמת המצב, נראה לי עדיף לך פשוט להעביר 2 פרמטרים לפונקצייה וזהו...

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

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

אם לא הבנת את המשפט, אל תעשה אותו. אם הבנת אותו, אתה יודע לא לעשות את זה.

לפעמים כאשר כותבים ספריות ופלטפורמות ב-C, מקרואים זו הדרך הטובה ביותר.

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

תודה ,

1. אני מוגבל רק ל C

2. הפתרון של EXTENDED לא מתאים .הדוגמא היא רק דוגמא המבנים הרבה יותר מסובכים ושונים רק המשמעות של המשתנים אותה משמעות ולכן אני רוצה לשלוח אותם לפונקציה אחת .

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

אני אנסה לנסח יותר טוב את הבעיה : איך להעביר לפונקציה ב C מצביע אחד שיצביע על שני STRUCTURES שונים עם שמות שדות זהים .

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

תודה ,

1. אני מוגבל רק ל C

2. הפתרון של EXTENDED לא מתאים .הדוגמא היא רק דוגמא המבנים הרבה יותר מסובכים ושונים רק המשמעות של המשתנים אותה משמעות ולכן אני רוצה לשלוח אותם לפונקציה אחת .

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

אני אנסה לנסח יותר טוב את הבעיה : איך להעביר לפונקציה ב C מצביע אחד שיצביע על שני STRUCTURES שונים עם שמות שדות זהים .

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

2 - אם המבנים שונים אבל יש להם אותה משמעות, זה בהחלט פוטנציאל למה שהראה לך moonblade.

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


typedef struct
{
int salary;
int months;
int bonus;
int employee_id;
} EmployeeRecord;

typedef struct
{
EmployeeRecord employee_data;
int has_secretary;
int num_subordinates;
} Manager;

typedef struct
{
EmployeeRecord employee_data;
int num_computers;
} Programmer;

int GetSalary(const EmployeeRecord* er)
{
if (er == NULL) return 0;
return er->salary * er->months + er->bonus;
}

int main()
{
Manager m;
Programmer p;

... /* some code */

printf("manager gets %d\n", GetSalary(&m.employee_data);
printf("programmer gets %d\n", GetSalary(&p.employee_data);

... /* some code */

return 0;
}

זו לא בהכרח הדרך הטובה ביותר, אבל זו דרך אחת פשוטה ובטוחה יחסית לתוכניות פשוטות.

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

כמו שהראה moonblade אפשר לעשות ירושה ב-C וכך לכתוב פונקציה אחת. לא בהכרח מומלץ להכל, אבל יש הרבה דברים שכתובים ככה:


typedef struct
{
int x;
int y;
} Base;

#define UPCAST_TO_BASE_PTR(x) (&((x).base))
#define INHERIT_BASE Base base

typedef struct
{
INHERIT_BASE;
char c;
float f;
} DerivedA;

typedef struct
{
INHERIT_BASE;
int z;
int w;
} DerivedB;

int BaseGetSum(const Base* base)
{
assert(base != NULL);
return base->x + base->y;
}

int main()
{
DerivedA a;
DerivedB b;
...
int sum_a = GetSum( UPCAST_TO_BASE_PTR(a) );
int sum_b = GetSum( UPCAST_TO_BASE_PTR(b) );
...
}

בעזרת קצת יותר השקעה אפשר להגיע לתוצאות טובות יותר, קלות יותר לשימוש, ובטוחות יותר.

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

ארכיון

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

×
  • צור חדש...