2010-05-10 11 views
6

#define निर्देश की भूमिका क्या है?सी ++ में # परिभाषा निर्देश का उद्देश्य क्या है?

+1

कृपया मैक्रोज़ का उपयोग करने के लिए * नहीं * के उदाहरण के रूप में निम्न आलेख से नमूना कोड देखें: http://stackoverflow.com/questions/2777774/a-out-termniated-garbage-output-due- टू-स्मैशिंग ऑफ स्टैक-कैसे-टू-रीम-यह –

+1

@ नाथन: चलो खराब मैक्रोज़ के असली एसओ स्रोत पर जाएं: http://stackoverflow.com/questions/652788/what-is-the-worst- वास्तविक दुनिया-मैक्रो-पूर्व प्रोसेसर दुरुपयोग-youve कभी आओ-भर में। –

+0

टॉच, @ डेविड, मैं बस स्मृति में था निकटतम के पास गया। आपके लिंक में कई अत्याचार शामिल हैं। –

उत्तर

15

#define सी और सी ++ में मैक्रोज़ बनाने के लिए उपयोग किया जाता है। आप इसके बारे में C preprocessor documentation में और अधिक पढ़ सकते हैं। त्वरित उत्तर यह है कि यह कुछ चीजें करता है:

  1. सरल मैक्रोज़ - मूल रूप से केवल टेक्स्ट प्रतिस्थापन।

    #define SOME_CONSTANT 12 
    

    बस पाठ SOME_CONSTANT12 साथ बदलता है जहाँ भी यह अपने कोड में प्रकट होता है: समय संकलित स्थिरांक एक अच्छा उदाहरण है। इस प्रकार का मैक्रो अक्सर कोड ब्लॉक के सशर्त संकलन प्रदान करने के लिए प्रयोग किया जाता है।

    #define OPTION_1 
    #define OPTION_2 
    #undef OPTION_3 
    

    और फिर परियोजना में कोड ब्लॉक #ifdef/#endif# ब्लॉक मिलान को सक्षम करने के साथ लिपटे किया जाएगा: उदाहरण के लिए, वहाँ एक हैडर परियोजना के लिए विकल्पों की सूची के साथ एक परियोजना में प्रत्येक स्रोत फ़ाइल से शामिल हो सकता है और तैयार परियोजना में उन विकल्पों को अक्षम करें। -D जीसीसी ध्वज का उपयोग समान व्यवहार प्रदान करेगा। हालांकि, इस विधि को एप्लिकेशन के लिए कॉन्फ़िगरेशन प्रदान करने का वास्तव में एक अच्छा तरीका है या नहीं, इस बारे में मजबूत राय है।

  2. तर्क के साथ मैक्रोज़ - आपको 'फ़ंक्शन-जैसी' मैक्रोज़ बनाने की अनुमति देता है जो तर्क ले सकते हैं और उन्हें कुशल बना सकते हैं। उदाहरण के लिए:

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

    इसके परिणाम के रूप में तर्क के वर्ग को वापस कर देगा; संभावित आदेश-संचालन या दुष्प्रभाव की समस्याओं के बारे में सावधान रहें! निम्न उदाहरण:

    int x = SQUARE(3);  // becomes int x = ((3) * (3)); 
    

    इच्छा ठीक काम करता है, लेकिन कुछ की तरह:

    int y = SQUARE(f()); // becomes int y = ((f()) * (f())); 
    

    दो बार, या भी बदतर f() कॉल करेगा: अपरिभाषित व्यवहार में

    int z = SQUARE(x++); // becomes int z = ((x++) * (x++)); 
    

    परिणाम!

    कुछ औजारों के साथ, तर्क के साथ मैक्रोज़ भी variadic हो सकते हैं, जो आसानी से आ सकते हैं।

टिप्पणी में नीचे उल्लेख किया है, मैक्रो के अति प्रयोग या बेहद जटिल या भ्रामक मैक्रो के विकास के कई द्वारा बुरा शैली माना जाता है - हमेशा की तरह, ऊपर अपने कोड की डाल पठनीयता, रख-रखाव, और debuggability ' चालाक 'तकनीकी चालें।

+5

+1। और चूंकि ओपी ने "भूमिका" के बारे में पूछा जो 'परिभाषित' नाटक करता है, यह जोर दिया जाना चाहिए कि मैक्रोज़ का अधिक उपयोग नहीं किया जाना चाहिए। – stakx

+0

वैराडिक मैक्रोज़ सी 99 में मानक हैं, इसलिए अधिकांश आधुनिक उपकरणों को उनका समर्थन करना चाहिए। – pkh

+1

+1, लेकिन कुछ स्थितियों में स्क्वायर() * विस्तारित * के उदाहरण का एक उदाहरण जोड़ना चाहिए। – greyfade

7

# परिभाषित करें (और इसके विपरीत, #undef) का उपयोग संकलक निर्देश सेट करने के लिए किया जा सकता है जिसे तब #ifndef या #ifdef का उपयोग करने के खिलाफ परीक्षण किया जा सकता है। यह स्रोत व्यवहार के भीतर कस्टम व्यवहार को परिभाषित करने की अनुमति देता है। यह आमतौर पर विभिन्न वातावरण या डीबग कोड के लिए संकलित करने के लिए प्रयोग किया जाता है।

एक उदाहरण:

सी में
#define DEBUG 



#ifdef DEBUG 

//perform debug code 

#endif 
0

या सी ++#define आप पूर्वप्रक्रमक मैक्रोज़ बनाने के लिए अनुमति देता है।

सामान्य सी या सी ++ निर्माण प्रक्रिया पहली बात यह है कि ऐसा होता है कि Preprocessor चलाता है में, पूर्वप्रक्रमक तरह #define या # शामिल पूर्वप्रक्रमक निर्देशों और उसके बाद प्रदर्शन के लिए हालांकि स्रोत फ़ाइलों लग रहा है उनके साथ सरल संचालन।

#define के संदर्भ में प्रीप्रोसेसर सरल पाठ आधारित प्रतिस्थापन करता है।

उदाहरण के लिए यदि आप कोड

#define PI 3.14159f 

float circum = diameter*PI; 

पूर्वप्रक्रमक में बदल होता था: बस संबंधित पाठ के साथ पीआई के उदाहरण की जगह

float circum = diameter* 3.14159; 

। यह और अधिक उन्नत उपयोगों के लिए इस article MSDN

0

inCorrectUseOfHashDefine()

{

#define की भूमिका है से बाहर की जाँच लोग हैं, जो विरासत में भ्रमित करने के लिए एक #define बयान के केवल सरलतम रूप है नीले बयान से बाहर के साथ अपने कोड की तरह:

foreverandever 

की वजह से:

#define foreverandever for(;;) 

}

कृपया #define पर स्थिरांक का पक्ष लें।

यह भी संकलक निर्देशों की स्थापना के लिए ...

+2

क्यों -2? यह एक वैध बिंदु है और मैं इसके द्वारा चिपक गया। –

+0

क्योंकि यह * परिभाषित नहीं है * # डिफाईन की भूमिका है लेकिन इसका * दुरुपयोग * है। –

+0

@ रीन ओके - मैंने अपना इरादा अधिक स्पष्ट बना दिया है –

1

#define निर्देश दो आम उपयोग होता है।

पहला, यह नियंत्रित करता है कि संकलक कैसे कार्य करेगा। ऐसा करने के लिए, हमें #undef, #ifdef और #ifndef की भी आवश्यकता है। (और #endif भी ...)

आप इस तरह से "कंपाइलर तर्क" बना सकते हैं। उपयोग आम तौर पर सक्रिय करने के लिए है या नहीं कोड का एक डिबग भाग, कि तरह है:

#ifdef DEBUG 

//debug code here 

#endif 

और आप एक #define डीबग

एक अन्य प्रयोग लिख कर करने के लिए उदाहरण के लिए, डिबग कोड संकलन में सक्षम हो जाएगा इस तर्क सामग्री के लिए, डबल से बचने के लिए है ...

उदाहरण, फ़ाइल ए, # फ़ाइल बी और सी शामिल है लेकिन फ़ाइल बी में सी भी शामिल है।इसकी संभावना संकलन त्रुटि में परिणामस्वरूप होगी, क्योंकि "सी" दो बार मौजूद है।

#ifndef C_FILE_INCLUDED 
#define C_FILE_INCLUDED 

//the contents of header "c" go here. 

#endif 

#define के अन्य उपयोग, मैक्रो बनाते हैं:

समाधान लिखने है।

सबसे सरल लोगों

, जैसे, सरल प्रतिस्थापन से मिलकर बनता है:

#define PI 3.14159265 

float perimeter(float radius) { 
    return radius*2*PI; 
} 

या

#define SHOW_ERROR_MESSAGE printf("An serious error happened"); 

if (1 != 1) { SHOW_ERROR_MESSAGE } 

तो फिर तुम भी मैक्रो कि तर्क को स्वीकार कर सकते हैं, printf ही आमतौर पर एक मैक्रो, के साथ बनाया है एक हेडर फ़ाइल में # परिभाषित करें।

लेकिन ऐसा नहीं किया जाना चाहिए, दो reaons के लिए: पहले, गति ओएस मैक्रो, इनलाइन उपयोग करने का एक ही है, और दूसरा, हम C++ टेम्पलेट्स, कि चर प्रकार के साथ काम करता है पर अधिक नियंत्रण के लिए अनुमति देने की है। तो, तर्क के साथ मैक्रो का उपयोग करने के लिए एकमात्र कारण, की #define गार्ड शामिल हैं के लिए है (दूर द्वारा) अजीब निर्माणों, जो बाद में समझने के लिए, metaprogrammed सामान की तरह कठिन हो जाएगा ...

+0

वाह, मेरे पोस्ट को टाइप करने के लिए हमेशा के लिए लिया गया, अब ऐसा लगता है कि मैंने अभी दो पिछले लोगों की पोस्ट कॉपी की है और उन्हें एक में मैश किया है :( – speeder

2

सबसे आम उपयोग करना है :

// header.hh 
#ifndef HEADER_HH_ 
#define HEADER_HH_ 

namespace pony { 
// ... 
} 

#endif 

#define का एक अन्य आम उपयोग एक विन्यास फाइल, जिसे आम तौर config.h फ़ाइल है, जहां विभिन्न राज्यों और शर्तों के आधार पर हम #define मैक्रो बनाने में है। फिर, हमारे कोड में हम विभिन्न मैक्रोज़ के लिए अलग-अलग संकलनों का समर्थन करने के लिए #ifdef, #elif defined() आदि के साथ इन मैक्रोज़ का परीक्षण करते हैं। यह शामिल-गार्ड मुहावरे जितना ठोस नहीं है और आपको यहां सावधान रहना होगा क्योंकि यदि शाखा गलत है तो आप बहुत अस्पष्ट कंपाइलर त्रुटियां, या बदतर, रनटाइम व्यवहार प्राप्त कर सकते हैं।

सामान्य में, के अलावा अन्य गार्ड आप के माध्यम से (दो बार, अधिमानतः) समस्या के बारे में सोचते हैं, और यदि आप इसे हल करने के लिए पूर्वप्रक्रमक बजाय संकलक उपयोग कर सकते हैं देखने की जरूरत शामिल हैं। कंपाइलर प्रीप्रोसेसर से बस चालाक है। इतना ही नहीं, लेकिन संकलक संभवतः प्रीप्रोसेसर को भ्रमित नहीं कर सकता है, जबकि प्रीप्रोसेसर सबसे निश्चित रूप से संकलक को भ्रमित और गुमराह कर सकता है।

0

#defines के बारे में अधिकांश चीजें पहले से ही कहा गया है, लेकिन यह है कि सी ++ उनके उपयोग के अधिकांश के लिए बेहतर प्रतिस्थापन है स्पष्ट नहीं है: आसानी से एक स्थिरांक "चर द्वारा बदला जा सकता है

  1. #define संख्यात्मक स्थिरांक परिभाषित करने के लिए ", कि, एक # परिभाषा के रूप में, संकलित निष्पादन योग्य में वास्तव में मौजूद नहीं है। AFAIK इसे लगभग सभी परिस्थितियों में उपयोग किया जा सकता है जहां आप सरणी सीमाओं सहित # परिभाषित संख्यात्मक स्थिरता का उपयोग कर सकते हैं। मेरे लिए मुख्य लाभ यह है कि इस तरह के स्थिरांक स्पष्ट रूप से टाइप किए जाते हैं, इसलिए मैक्रोज़ में "बस सुनिश्चित करने के लिए" को जोड़ने की आवश्यकता नहीं होती है, और स्कॉप्ड किया जाता है, इसलिए उन्हें नामस्थान/कक्षाओं/कार्यों में रखा जा सकता है, बिना सभी प्रदूषित किए आवेदन।

 

const int max_array_size=50; 
int an_array[max_array_size]; 
    मैक्रो बनाने की
  1. #define: मैक्रो अक्सर टेम्पलेट्स द्वारा प्रतिस्थापित किया जा सकता है; उदाहरण के लिए, खतरनाक मैक्स मैक्रो

 

#define MAX(a,b) ((a)<(b)?(b):(a)) 

है, जो कई कमियां है (उदाहरण के लिए बार-बार बहस मूल्यांकन, अपरिहार्य इनलाइन विस्तार) के लिए, अधिकतम समारोह से बदला जा सकता है

template<typename T> T & max(T & a, T & b) 
{ 
    return a<b?b:a; 
} 

जो टाइप-सुरक्षित हो सकता है (इस संस्करण में दो तर्कों को एक ही प्रकार के होने के लिए मजबूर किया जाता है), इनलाइन का विस्तार किया जा सकता है साथ ही साथ (यह संकलक निर्णय भी नहीं), केवल एक बार तर्कों का मूल्यांकन करता है (जब यह कहा जाता है), और scoped है। एक और विस्तृत स्पष्टीकरण here पाया जा सकता है।

फिर भी, मैक्रो अभी भी के लिए इस्तेमाल किया जाना चाहिए, असंतुलित कोष्ठक है कि कोड के अधिक लाइन का विस्तार अजीब भाषा एक्सटेंशन, किसी तरह का बनाने के लिए आदि

1

सी ++ में, गार्ड में शामिल हैं, #define बहुत ही संकीर्ण है , विशेष भूमिकाओं:

  • हैडर गार्ड, अन्य उत्तर
  • मानक पुस्तकालयों के साथ बातचीत में बताया। उदाहरण के लिए, windows.h सहित पहले WINDOWS_LEAN_AND_MEAN परिभाषित करना MAX की तरह अक्सर-समस्याग्रस्त मैक्रोज़ बंद कर देता है।
  • उन्नत मैक्रोज़ स्ट्रिंगनाइज़ेशन (यानी मैक्रोज़ जो डिबगिंग संदेश प्रिंट करते हैं) या टोकन-पेस्टिंग शामिल हैं।

आपको से निम्नलिखित उद्देश्यों के लिए #define का उपयोग करना चाहिए। कारण कई हैं; इंस्टेस this FAQ entry के लिए देखें।

  • संकलन-समय स्थिरांक। इसके बजाय const का उपयोग करें।
  • सरल मैक्रो फ़ंक्शन। इसके बजाय inline फ़ंक्शंस और टेम्पलेट्स का उपयोग करें।
संबंधित मुद्दे