2016-06-16 8 views
7

के साथ एक एसोसिएटिव * फ़ंक्शन को कॉल करना * सहयोगी Arrays के साथ कुछ भी करने के साथ भ्रमित नहीं होना चाहिए।सी मैक्रोज़

मुझे पता है कि गणित के मानचित्र (या लागू) कार्यक्षमता के समान परिणाम देने के लिए मैक्रोज़ के साथ सी में फ़ंक्शन को सदिश कैसे करें। अर्थात् तर्कों की सूची में एक फ़ंक्शन लागू करें।

#define Apply(type, function, ...)    \ 
{            \ 
    void *Stop = (int[]){0};      \ 
    type **List = (type*[]){__VA_ARGS__, Stop}; \ 
    for(int i = 0; List[i] != Stop; ++i)  \ 
    function(List[i]);       \ 
}      

मैं तो मुझे लगता है कि ऊपर नहीं किया

#define FreeAllAtOnce(...) Apply(void, free, __VA_ARGS__); 

जो प्रभाव पड़ता है की तरह कुछ है कि

free(Array1); 
free(Array2); 
free(Array3); 

FreeAllAtOnce(Array1, Array2, Array3); 

के बराबर है क्या कर सकते हैं, मैंने इसे एक किताब में पढ़ा और इसका इस्तेमाल किया एच तब से ईमानदारी से।

मेरा प्रश्न है: क्या मैं कुछ बाइनरी फ़ंक्शन के माध्यम से एक सरणी को जोड़कर जोड़ सकता हूं। उदाहरण के लिए जीसीडी समारोह ले लो। मैं चाहता हूँ की तरह एक समारोह:

GCD_all(a, b, c, d, e); 

तर्क के किसी भी संख्या के लिए के रूप में

GCD(GCD(GCD(GCD(a, b), c), d), e); 

एक ही प्रभाव पड़ता है।

मैंने ऐसा करने की कोशिश की है और इसे ठीक से काम करने में सक्षम नहीं है। मुझे उस मामले में भी रूचि है जहां समारोह में अतिरिक्त पैरामीटर पास किए जा सकते हैं। कि मैं एक समारोह

Atype BinaryCombineAll(Atype a, Atype b, Atype c, Atype d, OtherType z, OtherType y) 

मुझे आशा है कि समझ में आता है है

Atype BinaryCombine(Atype a, Atype b, OtherType z, OtherType y) 
तो

: सर्वाधिक सामान्य अर्थ में मैं जैसे कार्यों के साथ ऐसा करने के लिए देख रहा हूँ। किसी भी विचार या मदद की बहुत सराहना की जाएगी!

धन्यवाद।

+0

मुझे लगता है कि आपको सी ++ 11 वैरिएडिक टेम्पलेट्स – ForceBru

+0

बीटीडब्ल्यू के साथ कुछ सफलता मिली हो सकती है, आप कैसे पहचान रहे हैं कि 'फ़ंक्शन' कितने तर्क ले सकते हैं? – ForceBru

+0

@ForceBru, मुझे सी के भीतर रहने में दिलचस्पी है। मेरे पहले उदाहरण समारोह में केवल एक तर्क होता है। मैं जो पूछ रहा हूं वो वह है जो दो (या अधिक) लेता है। – amcalde

उत्तर

2

यह नहीं बल्कि मुश्किल मशीनरी (अधिक जानकारी के लिए इस answer देखें) की आवश्यकता है, के बाद से आप सामान्य रूप से सी में पुनरावर्ती मैक्रो नहीं कर सकते हैं:

int main(void) 
{ 
    GCD(GCD(GCD(GCD(a, b), c), d), e); 
} 

NUM_ARGS:

#define _NUM_ARGS2(X,X5,X4,X3,X2,X1,N,...) N 
#define NUM_ARGS(...) _NUM_ARGS2(0,__VA_ARGS__,5,4,3,2,1,0) 
// be sure to add X6,X7,... and 6,7,... to support more arguments 

#define GCD_OF_1(a)   (a)   
#define GCD_OF_2(a,b)  GCD(a, b) 
#define GCD_OF_3(a,b,...) GCD_OF_2(GCD_OF_2(a,b),__VA_ARGS__) 
#define GCD_OF_4(a,b,...) GCD_OF_3(GCD_OF_2(a,b),__VA_ARGS__) 
#define GCD_OF_5(a,b,...) GCD_OF_4(GCD_OF_2(a,b),__VA_ARGS__) 
// in general: 
// #define GCD_OF_N(a,b,...) GCD_OF_N-1(GCD_OF_2(a,b),__VA_ARGS__) 

#define _GCD_OF_N3(N, ...) GCD_OF_ ## N(__VA_ARGS__) 
#define _GCD_OF_N2(N, ...) _GCD_OF_N3(N, __VA_ARGS__) // helper macro to expand N 
#define GCD_all(...)  _GCD_OF_N2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__) 

int main(void) 
{ 
    GCD_all(a, b, c, d, e); 
} 

gcc -E के रूप में उत्पादन का उत्पादन स्वचालित रूप से तर्कों की संख्या पाता है। इस तरह आप भविष्य में विस्तार के लिए "प्रारंभ बिंदु" मैक्रो GCD_OF_N प्राप्त करते हैं।

+0

धन्यवाद। ऐसा लगता है कि इनपुट के हर संभावित मामले को कवर करने के लिए आपको इन सभी मैक्रोज़ को पहले से ही करना होगा। मैंने ऐसा करने का एक और तरीका सोचा लेकिन इसके लिए सभी इनपुट पॉइंटर्स होने की आवश्यकता है, डेटा नहीं। – amcalde

संबंधित मुद्दे