2013-03-24 193 views
2
typedef struct node{ 
     int term; 
     struct node *next; 
}node; 
typedef void(*PTR)(void *); 
typedef void(*PTR1)(void *,int,int); 
typedef int(*PTR2)(void *,int); 
typedef void(*PTR3)(void *,int); 
typedef void(*PTR4)(void *,void *,void *); 

typedef struct list{ 
     node *front,*rear; 
     PTR3 INSERT; 
     PTR *MANY; 
     PTR DISPLAY,SORT,READ; 
     PTR4 MERGE; 
}list; 

void constructor(list **S) 
{ 
    (*S)=calloc(1,sizeof(list)); 
    (*S)->front=(*S)->rear=NULL; 
    (*S)->INSERT=push_with_value; 
    (*S)->READ=read; 
    (*S)->SORT=sort; 
    (*S)->DISPLAY=display;  
    (*S)->MERGE=merger;  

    (*S)->MANY=calloc(2,sizeof(PTR)); 
    (*S)->MANY[1]=read; 


} 
int main() 
{ 
    list *S1,*S2,*S3; 
    constructor(&S1); 
    constructor(&S2); 
    constructor(&S3); 

    S1->MANY[1](S1); 
    S1->SORT(S1); 
    S1->DISPLAY(S1); 
    return 0; 
} 

在所有這些函數的參數void *被強制轉換爲list *在函數內。 有什麼方法可以通過將MANY[1]更改爲READ_IT;之類的其他名稱來呼叫S1->READIT;函數指針

我打算創建一個通用的頭文件,以便我可以將它用於我的所有程序。 由於我不知道我需要多少個函數指針,我打算創建每個函數指針類型的動態數組。

+5

那些所有帽子變量名都非常累人。 – 2013-03-24 18:23:52

+1

對於函數和變量,良好的命名約定是'UpperCamelCase'類型和'lowerCamelCase'。但更重要的是,一旦你決定遵循一些約定,你應該保持這種方式。 – LihO 2013-03-24 18:26:03

+0

感謝您的建議......我將在未來的編碼中牢記這一點:) – 2013-03-24 18:26:57

回答

1
typedef struct list{ 
    node *front,*rear; 
    PTR3 INSERT; 
    PTR READIT; 
    PTR DISPLAY,SORT,READ; 
    PTR4 MERGE; 
}list; 

...

(*S)->READIT = read; 

...

S1->READIT(S1); 
0

看看Linux內核實現的(雙鏈接)的列表,如定義here(和隨後/引用文件)。他們遍佈各地。大部分的操作是在宏中完成的,例如在列表的所有節點上運行一個操作。

如果您試圖定義的內容越來越複雜,請退後一步,尋找更簡單的替代方案。事先不要一概而論;如果不使用泛化,則是浪費;如果稍後需要某些(略)不同的東西,那麼這是一個糟糕的匹配,需要解決方法或重新實現。看看C++ STL list公開的接口,這些人在這件事上想了很長時間(儘管在不同的環境中)。

或者只是咬緊牙關,並使用C++,如果你想成爲完整的面向對象。

+0

感謝分享! – 2013-03-26 14:23:21