2011-04-27 23 views
9

मैं सी सीख रहा हूँ के आदेश है, लेकिन मैं यह समझ में नहीं आता:सी preprocessors और संचालन

#define square(x) x*x 
a = square(2+3) //a = 11 

जब ऐसा चलाया जाता है, क्यों किया जा रहा है a अंत तक 11?

+10

, इस उदाहरण में कई कारणों से आप जब तक दिन तुम कहाँ आता है सी में मैक्रो का उपयोग कर से बचना चाहिए में से एक से पता चलता * * वास्तव में ** पता है कि आप क्या कर रहे हैं। बेशक जब वह दिन आता है, तो आपको पता चलेगा कि उन्हें विस्तार से क्यों बचें ... –

+0

@ टी.ई.डी .: मैक्रोज़ (और सामान्य रूप से प्रीप्रोसेसर) किसी अन्य की तरह एक उपकरण हैं। यह उदाहरण नहीं दिखाता है कि आपको सामान्य रूप से मैक्रोज़ का उपयोग क्यों नहीं करना चाहिए - यह केवल एक विशेष उपयोग केस दिखाता है जिसके लिए उन्हें लागू करने के लिए अनुचित है। मैक्रोज़ के अच्छे और बुरे उपयोग दोनों हैं। –

+2

उस ने कहा, अच्छे लोगों की तुलना में निश्चित रूप से अधिक बुरे उपयोग हैं :) –

उत्तर

21

यह 2+3*2+3 तक फैला है, जो 2+(3*2)+3 के बराबर है। इसे ठीक करने के कोष्ठकों का उपयोग करें:

#define square(x) ((x)*(x)) 

अब square(x++) साथ यह कोशिश करते हैं और आप और अधिक समस्याओं (अपरिभाषित व्यवहार) में चलाने की जाती है। यदि आप कर सकते हैं तो इसे मैक्रो के रूप में करने से बचें।

+3

समकक्ष सी ++ फ़ंक्शन मैक्रो के रूप में उतना ही कुशल होना चाहिए (ऑप्टिमाइज़ेशन के साथ आधुनिक कंपाइलर्स पर) और इससे ग्रस्त नहीं होगा मुसीबत। –

+2

@ मार्टिन: सही, अगर ओपी सी ++ का उपयोग कर रहा है। संकेत शायद यह सी है। मुझे लगता है कि सी 99 में इनलाइन फ़ंक्शन भी हैं, और ऐसा लगता है कि वे जीएनयू सी में एक विस्तार हैं http://en.wikipedia.org/wiki/Inline_function#Language_support –

12

square(2+3)2+3*2+3 जो बराबर है करने के लिए 2+(3*2)+3

जीसीसी पर आप -E विकल्प का उपयोग कर सकते हैं जो आपके पूर्वप्रक्रमक उत्पन्न करता है देखने के लिए [* उच्च पूर्वता + से है] के लिए विस्तारित

C:\Users\SUPER USER>type a.c 
#define square(x) x*x 

int main() 
{ 
    a = square(2+3); //a = 11 
} 

C:\Users\SUPER USER>gcc -E a.c 
# 1 "a.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "a.c" 


int main() 
{ 
    a = 2+3*2+3; 
} 

उपाय

इसे आजमाएं

#define square(x) ((x)*(x)) 
+0

टिप के लिए धन्यवाद, मैं उपयोग करूंगा -ई :) – jhon

+0

+1 न केवल समस्या को ढूंढने के लिए, बल्कि ओपी (और बाकी हम) को भी सिखाते हैं कि ऐसी समस्याओं को कैसे डिबग करें। – Heinzi

1

क्योंकि 2 + 3 अभिव्यक्ति x * x में सचमुच एवजी है, यह 2 + 3 * 2 + 3 हो जाता है, और * ऑपरेटर एक उच्च पूर्वता है ताकि आप अपेक्षित परिणाम नहीं मिलता है।

हमेशा कोष्ठक में मैक्रो तर्क और पूरे अभिव्यक्ति संलग्न इस से बचने के लिए:

#define SQUARE(x) ((x) * (x)) 

भी ध्यान रखें कि किसी भी अभिव्यक्ति आप पारित दो बार मूल्यांकन किया जाएगा, और अगर अभिव्यक्ति एक पक्ष प्रभाव के इस तरह है कि अवांछित किया जा सकता है एक असाइनमेंट के रूप में, या एक समारोह कॉल के रूप में। इन मामलों में इनलाइन फ़ंक्शन का उपयोग करना बेहतर होता है।

+2

मैक्रोज़ को भी ब्रांड्स में संलग्न करें। आपके सुझाव के साथ, '1.0/वर्ग (x)' का मूल्यांकन '1.0/(2 + 3) * (2 + 3)', ''0.04' के बजाय' 1.0'' किया जाएगा। –

+0

@ सैम: बिंदु लिया गया। Ironic, लेकिन मैंने खुद कहा है कि कुछ महीने पहले इस जवाब में: http://stackoverflow.com/questions/4455307/weird-macro-definition-issue/4455354#4455354 –

1

प्रयास करें:

#define square(x) ((x)*(x)) 
0

क्या आप जब मैक्रो का विस्तार होता है पाने के बारे में सोचते हैं। सी पूर्वप्रक्रमक के रूप में

a = 2 + 3 * 2 + 3 

इस विस्तार होगा आप सही तरीके से अपने मैक्रो निर्धारित करने की जरूरत है। हमेशा ब्रांड्स में मैक्रो चर संलग्न करें। यह आपको अपेक्षित परिणाम देगा।

#define square(x) ((x)*(x)) 

मैक्रो विस्तार इस होगा:

a = ((2 + 3) * (2 + 3)) 
बस सलाह के एक टुकड़े के रूप में
+0

आपकी सलाह मैक्रो को "सही ढंग से परिभाषित नहीं" । '1.0/वर्ग (x)' का मूल्यांकन '1.0/(2 + 3) * (2 + 3)', '' 0.04' के बजाय '1.0' किया जाएगा। –

+0

मैंने गलत तरीके से परिभाषित मैक्रो को ठीक किया है। संलग्न संश्लेषण का एक और सेट जोड़ा गया। – don

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