2011-04-15 13 views
7
उदाहरण के लिए

,क्या सी मैक्रो को बाएं मूल्य के रूप में बुलाए जाने के लिए कोई चाल है?

struct node { 
    struct node *left, *right; 
}; 
#define LEFT(X) (X->left) 
#define RIGHT(X) (X->right) 

मैं मौजूदा मैक्रो इंटरफ़ेस बदले बिना इस तरह मैक्रो कॉल न करे करना चाहते हैं।

LEFT(n) = ... 

कोई विचार?

+0

उस मैक्रो का क्या उपयोग कर सकते हैं? मुझे समझ में नहीं आता कि आपको कभी ऐसा मैक्रो क्यों चाहिए। – Lundin

+0

@ लंदन मैं इसे उदाहरण के रूप में लेता हूं। वास्तविक कोड के लिए बहुत सारे गहरे-संरचित सदस्य हैं, एक्सेसर-मैक्रोज़ उपयोगी होंगे। – wsxiaoys

+0

@wsxiaoys ठीक है मैं देखता हूँ। मैं इस तरह के मैक्रोज़ को कैसे करना चाहिए इसके उदाहरण के साथ एक उत्तर पोस्ट करूंगा। – Lundin

उत्तर

8

इस प्रयास करें:

#define LEFT(X) ((X)->left+0) 
#define RIGHT(X) ((X)->right+0) 
+0

यह सबसे सरल जैसा दिखता है, लेकिन इसे अनुमानित टर्नरी ऑपरेटर की तरह अनुकूलित नहीं किया जा सकता है। – wsxiaoys

+0

वाह !! ... सरल अभी तक प्रभावशाली – BiGYaN

+0

@wsxiaoys: क्या आप वास्तव में बात नहीं करते हैं कि '0' का निरंतर जोड़ना मुश्किल है कि एक शाखा को कभी नहीं निकाला जाता है? अगर कुछ भी निश्चित रूप से आसान है! –

6
#undef LEFT 
#undef RIGHT 

//template<class T> 
inline const node * const LEFT(const node * X) { 
    return X->left; 
} 
+0

यहां' टी' क्या है? – sharptooth

+0

किंडा smarmy, लेकिन +1। मैक्रोज़ का बिल्कुल उपयोग नहीं करना सबसे अच्छी सलाह है। –

+0

सी ++ के साथ आपके पास कोई मैक्रो नहीं है ... – Petesh

3

मुझे नहीं लगता कि इसे रोकने का कोई तरीका है। मैक्रोज़ का उपयोग करने का शायद सबसे अच्छा तरीका नहीं होगा।

+1

यह समस्या का उचित समाधान है। – Lundin

1

शायद const है, हालांकि यह एक स्पष्ट प्रकार की आवश्यकता है:

#define LEFT(X) ((const struct node *) (X->left)) 

... हालांकि आप typeof संकलक एक्सटेंशन है यदि:

#define LEFT(X) ((const typeof(X->left)) (X->left)) 
+1

ये अभी भी अंतराल हैं। ओपी पॉइंटर को संपादित करना असंभव बनाने की कोशिश कर रहा है, न कि डेटा को इंगित करता है। –

5

मैं इनलाइन समारोह के साथ जाना चाहते हैं, लेकिन यदि आप एक मैक्रो चाहते हैं:

#define LEFT(X) (1 ? (X)->left : 0) 
3

आप टर्नरी ऑपरेटर का उपयोग कर सकते हैं मैक्रो का परिणाम सीई एक rvalue होने के लिए है, लेकिन त्रुटि संदेश उपयोगकर्ताओं के लिए भ्रामक हो सकता है:

struct node { 
    node *left, *right; 
}; 
#define LEFT(x) (true ? (x).left : (node*)0) 
int main() { 
    node n; 
    // LEFT(n); // error 
    node *l = LEFT(n); // OK 
} 

प्रवंचना वहाँ है कि विशिष्ट ऑपरेटर के शब्दों में है। केवल ऑपरेटर युक्त अभिव्यक्ति का प्रकार अभिव्यक्ति की दो शाखाओं का एक सामान्य प्रकार (या एक प्रकार से परिवर्तनीय) है, भले ही उनमें से केवल एक का मूल्यांकन किया जाए। अब, जब संकलक true ? x.left : (node*)0 का मूल्यांकन करता है तो यह x.left अभिव्यक्ति को हल करता है लेकिन x.left और (node*)0 के सामान्य प्रकार के साथ। उनमें से दोनों मूल रूप से एक ही प्रकार के हैं, केवल विवरण के साथ (node*)0 एक लालसा के बजाए एक रैवल्यू है।

+0

या बस 'नोड * एल = एन.एबी;' लिखें ... समस्या हल हो गई। – Lundin

0

मैं सिर्फ एक स्पष्ट डाली

#define LEFT(X) ((struct node*)(X->left)) 
#define RIGHT(X) ((struct node*)(X->right)) 

के लिए जाना चाहते हैं इस तरह के एक डाली का परिणाम हमेशा एक rvalue है।

#define LEFT(X) ((struct node const*)(X->left)) 
#define RIGHT(X) ((struct node const*)(X->right)) 
0

आप उस तरह "एक्सेसर" मैक्रो नहीं लिखते आप करते हैं: इसके अलावा में आप बदलना क्या संकेत दिए गए एक const जोड़ने के लिए इंगित कर रहे हैं के रूप में पहले से ही एक और जवाब में दिया गया था अनुमति देने के लिए नहीं चाहते हैं

typedef struct 
{ 
    ... 
} X; 

X x; 

#define LEFT (x.y.z.left) 

फिर आप किसी अन्य चर की तरह बाएं मैक्रो तक पहुंचते हैं। यह कोड को और अधिक पठनीय बनाता है जबकि एक ही समय में पूरी तरह से असुरक्षित, बदसूरत दिखने वाला, त्रुटि प्रवण, अपरिभाषित-व्यवहार बैले फ़ंक्शन-जैसी मैक्रोज़ से जुड़ा होता है।

1

सी ++ के लिए, मैं एकल + का प्रयोग करेंगे:

#define LEFT(X) (+((X)->left)) 
#define RIGHT(X) (+((X)->right)) 

एक सामान्य मैक्रो मामले के लिए, यह +0 है कि यह भी void* और समारोह संकेत के लिए काम करता जोड़ने से अधिक लाभ दिया है।सी के लिए, आप अल्पविराम ऑपरेटर

#define LEFT(X) (0, ((X)->left)) 
#define RIGHT(X) (0, ((X)->right)) 
+0

सामान्य रूप से, यह मेरे उत्तर से बेहतर है क्योंकि यह 'शून्य *' के लिए भी काम करता है। ओपी की समस्या के लिए यह वास्तव में कोई फर्क नहीं पड़ता। –

+0

@ आर .., आप सही हैं। मेरे उत्तर को अधिक सटीक होने के लिए अपडेट किया गया :) –

+0

अंत में मैं अपने कोड में '+ 0' जोड़ रहा हूं क्योंकि अल्पविराम ऑपरेटर का उपयोग करके इस तरह से" अभिव्यक्ति परिणाम अप्रयुक्त "चेतावनी – wsxiaoys

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