दिलचस्प पोस्ट
Angularjs गतिशील एनजी-पैटर्न मान्यता एंड्रॉइड इन्टेंट का उपयोग करके एचटीएमएल मेल भेजें यदि कोई AngularJS टेम्पलेट्स में बयान मैं एक एंड्रॉइड ऐप कैसे प्रोग्राम "रीस्टार्ट" करूँ? '\ r': कमांड नहीं मिला – .bashrc / .bash_profile एचटीटीपी क्लाइंट के प्राधिकरण शीर्षलेख की स्थापना एक url के कनेक्शन को प्रतिबंधित करने के लिए socket.io मूल सेट कैसे करें सरल इंजेक्टर वेब एपीआई नियंत्रकों में निर्भरता इंजेक्ट करने में असमर्थ क्या एक TextView में कई शैलियों को संभव है? मैं अपने वेब पेज पर सही क्लिक कैसे अक्षम करूं? एक GUI पैनल के अंदर जावा कंसोल बनाएं सी में / dev / random या urandom का उपयोग कैसे करें? Django-allauth का उपयोग करते समय उपयोगकर्ता प्रोफ़ाइल को कैसे अनुकूलित करें दिए गए url से पैरामीटर कैसे निकालें सभी निकालें लेकिन NSString से संख्याएं

"स्थिर कॉन्स्ट" बनाम "# डिफाइन" बनाम "एन्यूम"

सी में निम्न बयानों में से कौन सा उपयोग करना बेहतर है?

static const int var = 5; 

या

 #define var 5 

या

 enum { var = 5 }; 

वेब के समाधान से एकत्रित समाधान ""स्थिर कॉन्स्ट" बनाम "# डिफाइन" बनाम "एन्यूम""

आम तौर पर बोलना:

 static const 

क्योंकि यह क्षेत्र का सम्मान करता है और प्रकार सुरक्षित है

केवल चेतावनी मैं देख सकता था: यदि आप चाहते हैं कि चर को संभवतः कमांड लाइन पर परिभाषित किया जाए अभी भी एक विकल्प है:

 #ifdef VAR // Very bad name, not long enough, too general, etc.. static int const var = VAR; #else static int const var = 5; // default value #endif 

जब भी संभव हो, मैक्रोज़ / एल्िप्सिस के बजाय, एक प्रकार सुरक्षित विकल्प का उपयोग करें।

यदि आपको वास्तव में मैक्रो के साथ जाने की आवश्यकता है (उदाहरण के लिए, आप __FILE__ या __LINE__ चाहते हैं), तो आप अपने मैक्रो को बहुत सावधानी से नाम दे: इसके नामकरण सम्मेलन में बूस्ट परियोजना के नाम से शुरू होने वाले सभी ऊपरी-मामले की सिफारिश करता है ( यहां BOOST_), जबकि आप लाइब्रेरी के जरिए ध्यान देंगे तो आप देखेंगे कि (आमतौर पर) विशेष क्षेत्र (पुस्तकालय) के नाम पर एक अर्थपूर्ण नाम के साथ।

यह आम तौर पर लंबा नाम बना देता है 🙂

यह उस मूल्य पर निर्भर करता है जिसके लिए आपको मूल्य की आवश्यकता होती है। आप (और बाकी सब अभी तक) तीसरे विकल्प छोड़े गए हैं:

  1. static const int var = 5;
  2. #define var 5
  3. enum { var = 5 };

नाम की पसंद के बारे में मुद्दों पर ध्यान न दें, फिर:

  • यदि आपको एक संकेतक के आसपास पास करना है, तो आपको (1) उपयोग करना होगा।
  • चूंकि (2) जाहिरा तौर पर एक विकल्प है, आपको पॉइंटर्स पास करने की आवश्यकता नहीं है।
  • डीबगर के प्रतीक तालिका में दोनों (1) और (3) का प्रतीक है – जो डीबगिंग को आसान बनाता है। यह अधिक संभावना है कि (2) के पास कोई प्रतीक नहीं होगा, जिससे आप सोच सकते हैं कि यह क्या है।
  • (1) वैश्विक दायरे में एरे के लिए एक आयाम के रूप में उपयोग नहीं किया जा सकता; दोनों (2) और (3) कर सकते हैं
  • (1) फ़ंक्शन गुंजाइश पर स्थिर सरणियों के लिए एक आयाम के रूप में उपयोग नहीं किया जा सकता; दोनों (2) और (3) कर सकते हैं
  • सीएएम 99 के तहत, इन सभी को स्थानीय एरे के लिए इस्तेमाल किया जा सकता है। तकनीकी तौर पर, (1) का उपयोग VLA (चर-लंबाई सरणी) के उपयोग से होता है, हालांकि 'var' द्वारा संदर्भित आयाम निश्चित रूप से आकार 5 पर तय किया जाएगा।
  • स्विच स्टेटमेंट जैसे स्थानों में (1) का उपयोग नहीं किया जा सकता; दोनों (2) और (3) कर सकते हैं
  • (1) स्थिर चर को प्रारंभ करने के लिए इस्तेमाल नहीं किया जा सकता; दोनों (2) और (3) कर सकते हैं
  • (2) वह कोड बदल सकता है जिसे आप परिवर्तित नहीं करना चाहते थे क्योंकि यह प्रीप्रोसेसर द्वारा उपयोग किया जाता है; दोनों (1) और (3) इस तरह अप्रत्याशित दुष्प्रभाव नहीं करेंगे
  • आप पता लगा सकते हैं कि (2) प्रीप्रोसेसर में सेट किया गया है या नहीं; न तो (1) न (3) वह अनुमति देता है।

इसलिए, अधिकांश संदर्भों में, विकल्पों पर 'एनाम' को पसंद करते हैं। अन्यथा, पहले और आखिरी बुलेट अंक को नियंत्रित करने वाले कारक होने की संभावना है – और अगर आपको एक बार में दोनों को संतुष्ट करने की आवश्यकता होती है तो आपको कठिन लगता है

यदि आप सी ++ के बारे में पूछ रहे थे, तो आप विकल्प (1) – स्थिर कॉन्स्ट – हर बार इस्तेमाल करेंगे

सी में, विशेष रूप से? सी में सही उत्तर है: #define उपयोग करें (या, यदि उचित हो, enum )

हालांकि यह एक const वस्तु के scoping और टाइपिंग गुणों के लिए फायदेमंद है, लेकिन वास्तव में सी (सी + + के विपरीत) में स्थिर वस्तुओं की वस्तुओं सच स्थिर नहीं हैं और इसलिए आमतौर पर ज्यादातर व्यावहारिक मामलों में वे बेकार हैं।

तो, सी में चुनाव का निर्धारण करना चाहिए कि आप अपने निरंतर उपयोग कैसे करें उदाहरण के लिए, आप एक const int ऑब्जेक्ट का उपयोग case लेबल के रूप में नहीं कर सकते (जबकि मैक्रो काम करेगा)। आप थोड़ी-क्षेत्र की चौड़ाई के रूप में एक const int ऑब्जेक्ट का उपयोग नहीं कर सकते (जबकि मैक्रो काम करेगा)। C89 / 90 में आप एक const ऑब्जेक्ट का उपयोग एक सरणी आकार निर्दिष्ट करने के लिए नहीं कर सकते (जबकि मैक्रो काम करेगा)। C99 में भी जब आप एक गैर- वीएलए सरणी की आवश्यकता होती है, तो आप एक const ऑब्जेक्ट का इस्तेमाल नहीं कर सकते हैं।

यदि यह आपके लिए महत्वपूर्ण है तो यह आपकी पसंद का निर्धारण करेगा। ज्यादातर समय, आपके पास सी #define में #define करने के लिए #define कोई भी विकल्प नहीं होगा, और किसी अन्य विकल्प को मत भूलना, जो सी- enum में सच स्थिरांक उत्पन्न करता है।

सी ++ const ऑब्जेक्ट्स में सच्चे स्थिरांक होते हैं, इसलिए सी ++ में यह const को पसंद करने के लिए लगभग हमेशा बेहतर होता है (सी ++ में स्पष्ट static लिए कोई ज़रूरत नहीं है)।

static const और #define बीच अंतर यह है कि पूर्व स्मृति का उपयोग करता है और बाद में स्टोरेज के लिए स्मृति का उपयोग नहीं करता है दूसरे, आप #define का पता नहीं दे सकते हैं, जबकि आप एक static const का पता दे सकते हैं दरअसल, यह हम पर निर्भर करता है कि हम किस परिस्थिति में हैं, हमें इन दो में से एक का चयन करना होगा। दोनों अलग-अलग परिस्थितियों में अपने सर्वश्रेष्ठ पर हैं कृपया मान लें कि एक अन्य की तुलना में बेहतर है … 🙂

यदि यह मामला होता, तो डेनिस रिची ने अकेले सबसे अच्छा अकेला रखा होता … हाहाह … 🙂

सी #define में ज्यादा लोकप्रिय है उदाहरण के लिए आप सरणी आकार घोषित करने के लिए उन मानों का उपयोग कर सकते हैं:

 #define MAXLEN 5 void foo(void) { int bar[MAXLEN]; } 

एएनएसआई सी आपको इस संदर्भ में static const को इस्तेमाल करने की अनुमति नहीं देता है। सी ++ में आपको इन मामलों में मैक्रो से बचना चाहिए। तुम लिख सकते हो

 const int maxlen = 5; void foo() { int bar[maxlen]; } 

और यहां तक ​​कि static भी छोड़ दें क्योंकि आंतरिक लिंकिंग पहले ही const द्वारा [सी ++ में] निहित है।

सी में const एक और दोष यह है कि आप दूसरे const को प्रारंभ करने में मान का उपयोग नहीं कर सकते हैं

 static int const NUMBER_OF_FINGERS_PER_HAND = 5; static int const NUMBER_OF_HANDS = 2; // initializer element is not constant, this does not work. static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND * NUMBER_OF_HANDS; 

यहां तक ​​कि यह एक const के साथ काम नहीं करता क्योंकि कंपाइलर इसे स्थिर के रूप में नहीं देखता है:

 static uint8_t const ARRAY_SIZE = 16; static int8_t const lookup_table[ARRAY_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant! 

मुझे इन मामलों में टाइप const का उपयोग करने में खुशी होगी, अन्यथा …

यदि आप इसके साथ भाग ले सकते हैं, तो static const कई फायदे हैं। यह सामान्य दायरे के सिद्धांतों का पालन करता है, डिबगर में दिखाई देता है, और आम तौर पर उन नियमों का पालन करता है जो चर का पालन करते हैं

हालांकि, मूल सी मानक में कम से कम, यह वास्तव में स्थिर नहीं है। यदि आप #define var 5 उपयोग करते हैं, तो आप int foo[var]; लिख सकते हैं int foo[var]; एक घोषणा के रूप में, लेकिन आप ऐसा नहीं कर सकते (एक कंपाइलर विस्तार के रूप में के रूप में " static const int var = 5; " के साथ। यह C ++ में मामला नहीं है, जहां static const संस्करण कहीं भी #define संस्करण का उपयोग किया जा सकता है, और मेरा मानना ​​है कि यह भी C99 के साथ मामला है

हालांकि, कभी भी नाम नहीं एक #define स्थिरांक के साथ एक लोअरकेस नाम। यह अनुवाद यूनिट के अंत तक उस नाम के किसी भी संभावित उपयोग को ओवरराइड करेगा। मैक्रो स्थिरांक प्रभावी रूप से अपने नामस्थान है, जो पारंपरिक रूप से सभी पूंजी पत्र हैं, शायद उपसर्ग के साथ होनी चाहिए।

#define var 5 आपको परेशानी का कारण होगा यदि आपके पास mystruct.var जैसी mystruct.var

उदाहरण के लिए,

 struct mystruct { int var; }; #define var 5 int main() { struct mystruct foo; foo.var = 1; return 0; } 

प्रीप्रोसेसर इसे बदल देगा और कोड संकलित नहीं करेगा। इस कारण से, पारंपरिक कोडन शैली का सुझाव है कि सभी निरंतर #define करता है कि संघर्ष से बचने के लिए बड़े अक्षरों का उपयोग किया जाता है।

मैंने एक अंतर दिखाने के लिए त्वरित परीक्षण कार्यक्रम लिखा था:

 #include <stdio.h> enum {ENUM_DEFINED=16}; enum {ENUM_DEFINED=32}; #define DEFINED_DEFINED 16 #define DEFINED_DEFINED 32 int main(int argc, char *argv[]) { printf("%d, %d\n", DEFINED_DEFINED, ENUM_DEFINED); return(0); } 

यह इन त्रुटियों और चेतावनियों के साथ संकलित है:

 main.c:6:7: error: redefinition of enumerator 'ENUM_DEFINED' enum {ENUM_DEFINED=32}; ^ main.c:5:7: note: previous definition is here enum {ENUM_DEFINED=16}; ^ main.c:9:9: warning: 'DEFINED_DEFINED' macro redefined [-Wmacro-redefined] #define DEFINED_DEFINED 32 ^ main.c:8:9: note: previous definition is here #define DEFINED_DEFINED 16 ^ 

ध्यान दें कि enum एक चेतावनी देता है जब परिभाषित करता है एक त्रुटि देता है।

ऐसा मत सोचो कि "हमेशा सबसे अच्छा" के लिए एक जवाब है, लेकिन जैसा कि मथायी ने कहा

static const

प्रकार सुरक्षित है #define साथ मेरा सबसे बड़ा पालतू #define , हालांकि, जब वह दृश्य स्टूडियो में डिबगिंग करता है तो आप चर को देख नहीं सकते यह एक त्रुटि देता है कि प्रतीक पाया नहीं जा सकता।

संयोग से, #define करने के लिए एक विकल्प, जो उचित स्कोपिंग प्रदान करता है, लेकिन "असली" स्थिर की तरह व्यवहार करता है, "एन्यूम" है। उदाहरण के लिए:

 enum {number_ten = 10;} 

कई मामलों में, एन्यूमरेटेड प्रकारों को परिभाषित करने और उन प्रकारों के चर बनाने के लिए उपयोगी है; अगर ऐसा किया जाता है, तो डिबगर उनके गणन नाम के अनुसार चर को प्रदर्शित करने में सक्षम हो सकते हैं।

ऐसा करने के साथ एक महत्वपूर्ण चेतावनी, हालांकि: सी ++ में, एन्यूमरेटेड प्रकारों में पूर्णांक के साथ सीमित संगतता है। उदाहरण के लिए, डिफ़ॉल्ट रूप से, कोई उन पर अंकगणितीय नहीं कर सकता। मुझे लगता है कि enums के लिए एक उत्सुक डिफ़ॉल्ट व्यवहार होना; जबकि सी के साथ आम तौर पर संगत सी + + की इच्छा को देखते हुए, "कड़े एन्यूम" प्रकार होना अच्छा होता, मुझे लगता है कि "एंमान" प्रकार के डिफ़ॉल्ट व्यवहार को पूर्णांक के साथ विनिमेय होना चाहिए

परिभाषा

 const int const_value = 5; 

हमेशा एक स्थिर मूल्य को परिभाषित नहीं करता है कुछ कंपाइलर (उदाहरण के लिए टीसीसी 0.9.26 ) केवल "const_value" नाम के साथ पहचाने जाने वाली स्मृति आवंटित करें पहचानकर्ता "const_value" का उपयोग करके आप इस मेमोरी को संशोधित नहीं कर सकते। लेकिन आप फिर भी एक और पहचानकर्ता का उपयोग करके स्मृति को संशोधित कर सकते हैं:

 const int const_value = 5; int *mutable_value = (int*) &const_value; *mutable_value = 3; printf("%i", const_value); // The output may be 5 or 3, depending on the compiler. 

इसका अर्थ है परिभाषा

 #define CONST_VALUE 5 

एक निरंतर मान परिभाषित करने का एकमात्र तरीका है जिसे किसी भी तरह से संशोधित नहीं किया जा सकता है।

यह हमेशा #define के बजाय const का उपयोग करने के लिए बेहतर है ऐसा इसलिए क्योंकि const को कंपाइलर द्वारा और #प्रप्रोसेसर द्वारा परिभाषित किया जाता है। यह # की तरह है परिभाषित खुद कोड का हिस्सा नहीं है (लगभग बोल)

उदाहरण:

 #define PI 3.1416 

प्रतीकात्मक नाम पीआई कम्पाइलर द्वारा कभी नहीं देखा जा सकता है; इसे स्रोत कोड से पहले एक प्रिप्रोसर द्वारा हटाया जा सकता है, यहां तक ​​कि कंपाइलर भी हो सकता है नतीजतन, नाम PI प्रतीक तालिका में दर्ज नहीं हो सकता है यदि आप लगातार उपयोग के संकलन के दौरान एक त्रुटि प्राप्त करते हैं, तो यह भ्रमित हो सकता है, क्योंकि त्रुटि संदेश 3.1416 का उल्लेख कर सकता है, पीआई नहीं। अगर पीआई को एक हेडर फाइल में परिभाषित किया गया था जिसे आपने नहीं लिखा था, तो आपको नहीं पता था कि कहां से 3.1416 आए थे

यह समस्या भी प्रतीकात्मक डीबगर में फसल कर सकती है, क्योंकि फिर से, जिस नाम के साथ आप प्रोग्रामिंग कर रहे हैं वह प्रतीक तालिका में नहीं हो सकता है।

उपाय:

 const double PI = 3.1416; //or static const... 

एक सरल अंतर:

प्री-प्रसंस्करण समय में, निरंतर को इसके मूल्य से बदल दिया जाता है। इसलिए आप डिफरेंस ऑपरेटर को परिभाषित करने के लिए लागू नहीं कर सकते, लेकिन आप डिरेफर ऑपरेटर को एक चर में लागू कर सकते हैं।

जैसा कि आप मानते हैं, परिभाषित करता है कि स्थिर const स्थिर है

उदाहरण के लिए,

 #define mymax 100 

आप printf("address of constant is %p",&mymax); नहीं कर सकते printf("address of constant is %p",&mymax);

लेकिन होने

 const int mymax_var=100 

आप printf("address of constant is %p",&mymax_var); कर सकते हैं printf("address of constant is %p",&mymax_var);

अधिक स्पष्ट होने के लिए, परिभाषा को पूर्व-प्रसंस्करण चरण में इसके मूल्य से प्रतिस्थापित किया जाता है, इसलिए हमारे पास कार्यक्रम में कोई भी चर जमा नहीं होता है। हमारे पास प्रोग्राम के टेक्स्ट सेगमेंट का कोड है जहां परिभाषित किया गया था।

हालांकि, स्थिर const के लिए हमारे पास एक ऐसा चर है जो कहीं आवंटित किया गया है। जीसीसी के लिए, स्थैतिक कॉन्स्ट को प्रोग्राम के टेक्स्ट सेगमेंट में आवंटित किया जाता है।

ऊपर, मैं संदर्भ ऑपरेटर के बारे में बताना चाहता था, इसलिए संदर्भ के साथ dereference बदलें।

हमने MBF16X पर उत्पादित कोडांतरक कोड को देखा … दोनों प्रकार के अंकगणितीय कार्यों (उदाहरण के लिए, तत्काल जोड़ें) के लिए एक ही कोड में परिणाम होता है।

तो const int को टाइप चेक के लिए पसंद किया जाता है जबकि #define पुरानी शैली है शायद यह संकलक-विशिष्ट है। तो अपने उत्पादित कोडांतरक कोड की जांच करें

मैंने # परिभाषित विधियों को स्थिर के दायरे को नियंत्रित करने के लिए इस्तेमाल किया है, इस प्रकार सी ++ में एक निजी वर्ग चर में नकल कर रहा है

 #define MAXL 4 // some code #undef MAXL