פורסם 2010 בנובמבר 2215 שנים בשפת 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);}
פורסם 2010 בנובמבר 2215 שנים אם מותר לך לעבוד בC++, התשובה ברורה מאלייה:ירושה או templatesאם אתה מוגבל לC, אפשר לבצע את הדבר הבא (זה נראה כמו OOP עקום בהתחלה, אבל זה יכול לעבוד נהדר - הקרנל של לינוקס וכל הדרייברים כתובים ככה לדוגמא):typedef struct { int x; int y;}Base;typedef struct{ Base b; float f;} Extended;ומכאן אתה פשוט מעביר את b מתי שצריך.החסרון היחיד של זה הוא במידה ויש חשיבות לאופסטים של השדות במבנה(נגיד שבדוגמא לעיל הflaot צריך לשבת באמצע בין שני האינטים) אז אין לך איך לפתור את זה בשיטה הזאת. במידה וזה באמת המצב, נראה לי עדיף לך פשוט להעביר 2 פרמטרים לפונקצייה וזהו...
פורסם 2010 בנובמבר 2315 שנים אם אתה יודע ממש טוב מה אתה עושה ויש לך סיבה ממש מצויינת לעשות את זה, אפשר להגיע רחוק עם MACRO-ים.אם לא הבנת את המשפט, אל תעשה אותו. אם הבנת אותו, אתה יודע לא לעשות את זה.לפעמים כאשר כותבים ספריות ופלטפורמות ב-C, מקרואים זו הדרך הטובה ביותר.
פורסם 2010 בנובמבר 2315 שנים מחבר תודה ,1. אני מוגבל רק ל C2. הפתרון של EXTENDED לא מתאים .הדוגמא היא רק דוגמא המבנים הרבה יותר מסובכים ושונים רק המשמעות של המשתנים אותה משמעות ולכן אני רוצה לשלוח אותם לפונקציה אחת .3. לא הבנתי את הקשר של המקרו לבעייה .אני אנסה לנסח יותר טוב את הבעיה : איך להעביר לפונקציה ב C מצביע אחד שיצביע על שני STRUCTURES שונים עם שמות שדות זהים .
פורסם 2010 בנובמבר 2315 שנים תודה ,1. אני מוגבל רק ל C2. הפתרון של 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;}זו לא בהכרח הדרך הטובה ביותר, אבל זו דרך אחת פשוטה ובטוחה יחסית לתוכניות פשוטות.
פורסם 2010 בנובמבר 2315 שנים שני טיפוסים שתי פונקציות.אין קיצורי דרך.זו גם הדרך הנכונה.גם ב++C ועם templates לבסוף נוצרות שתי פונקציות.
פורסם 2010 בנובמבר 2315 שנים כמו שהראה moonblade אפשר לעשות ירושה ב-C וכך לכתוב פונקציה אחת. לא בהכרח מומלץ להכל, אבל יש הרבה דברים שכתובים ככה:typedef struct { int x; int y;} Base;#define UPCAST_TO_BASE_PTR(x) (&((x).base))#define INHERIT_BASE Base basetypedef 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) ); ...}בעזרת קצת יותר השקעה אפשר להגיע לתוצאות טובות יותר, קלות יותר לשימוש, ובטוחות יותר.
פורסם 2010 בנובמבר 2415 שנים מחבר תודה על כל העזרה , אבל השתכנעתי שכנראה לשכפל את הפונקציה היא הדרך הטובה ביותר - כך הקוד נישאר מובן ופחות באגים בהמשך
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.