C में नीचे दिए गए कथनों में से कौन सा प्रयोग करना बेहतर है?
static const int var = 5;
या
#define var 5
या
enum { var = 5 };
C में नीचे दिए गए कथनों में से कौन सा प्रयोग करना बेहतर है?
static const int var = 5;
या
#define var 5
या
enum { var = 5 };
जवाबों:
यह इस बात पर निर्भर करता है कि आपको किस मूल्य की आवश्यकता है। आपने (अब तक और सभी ने) तीसरा विकल्प छोड़ दिया:
static const int var = 5;
#define var 5
enum { var = 5 };
नाम की पसंद के बारे में मुद्दों की अनदेखी, फिर:
इसलिए, अधिकांश संदर्भों में, विकल्पों पर 'एनम' को प्राथमिकता दें। अन्यथा, पहली और आखिरी बुलेट पॉइंट्स को नियंत्रित करने वाले कारक होने की संभावना है - और अगर आपको दोनों को एक साथ संतुष्ट करने की आवश्यकता है, तो आपको कठिन सोचना होगा।
यदि आप C ++ के बारे में पूछ रहे थे, तो आप विकल्प (1) - स्टेटिक कास्ट - हर बार उपयोग करेंगे।
enum
है कि वे int
([C99] 6.7.2.2/3) के रूप में कार्यान्वित किए जाते हैं । एक #define
आपको अहस्ताक्षरित और लंबे U
और L
प्रत्यय के साथ निर्दिष्ट करता है , और const
आपको एक प्रकार देता है। enum
सामान्य प्रकार के रूपांतरणों के कारण समस्याएँ हो सकती हैं।
enum
और न ही #define
अतिरिक्त जगह का उपयोग करता है, प्रति से। मान ऑब्जेक्ट कोड में डेटा खंड या हीप या स्टैक पर संग्रहीत किए जाने के बजाय निर्देशों के भाग के रूप में दिखाई देगा। आपके पास कुछ स्थान आवंटित होगा static const int
, लेकिन यदि आप कोई पता नहीं लगाते हैं तो कंपाइलर इसे अनुकूलित कर सकता है।
enum
S (और static const
) के लिए एक और 'वोट' : उन्हें बदला नहीं जा सकता। a 'd define
हो सकता है #undefine
, जहाँ a enum
और static const
दिए गए मान पर नियत हैं।
आम तौर पर बोलना:
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_ ), पुस्तकालय से इनकार करते समय आप यह देखेंगे (आम तौर पर) विशेष क्षेत्र (पुस्तकालय) के नाम के बाद और फिर सार्थक नाम के साथ।
यह आम तौर पर लंबे नामों के लिए बनाता है :)
static
जिनका पता लिया जाता है, उन्हें बने रहना चाहिए; और यदि पता लिया जाता है तो एक #define
या enum
(कोई पता नहीं) का उपयोग नहीं किया जा सकता है ... इसलिए मैं वास्तव में यह देखने में विफल हूं कि क्या विकल्प का उपयोग किया जा सकता था। यदि आप "संकलन समय मूल्यांकन" के साथ दूर कर सकते हैं, तो आप extern const
इसके बजाय देख सकते हैं ।
#if
अधिक बेहतर हो सकता है #ifdef
बूलियन झंडे के लिए है, लेकिन इस मामले में यह यह असंभव को परिभाषित करने बनाना होगा var
के रूप में 0
कमांड लाइन से। तो इस मामले में, #ifdef
अधिक समझ में आता है, जब तक के 0
लिए एक कानूनी मूल्य है var
।
सी में, विशेष रूप से? C में सही उत्तर है: उपयोग #define
(या, यदि उपयुक्त हो, enum
)
हालांकि const
, किसी वस्तु की टेढ़ी-मेढ़ी और टाइपिंग संपत्तियों का होना फायदेमंद है, जबकि const
C में वास्तविकता में ऑब्जेक्ट्स (C ++ के विपरीत) सही स्थिरांक नहीं हैं और इसलिए आमतौर पर अधिकांश व्यावहारिक मामलों में बेकार होते हैं।
इसलिए, सी में चुनाव द्वारा निर्धारित किया जाना चाहिए कि आप अपने निरंतर उपयोग की योजना कैसे बनाते हैं। उदाहरण के लिए, आप किसी const int
ऑब्जेक्ट को case
लेबल के रूप में उपयोग नहीं कर सकते (जबकि मैक्रो काम करेगा)। आप किसी const int
वस्तु को बिट-फील्ड चौड़ाई (जबकि मैक्रो काम करेंगे) के रूप में उपयोग नहीं कर सकते । C89 / 90 में आप const
सरणी आकार निर्दिष्ट करने के लिए किसी ऑब्जेक्ट का उपयोग नहीं कर सकते (जबकि मैक्रो काम करेगा)। यहां तक कि C99 में आप किसी const
ऑब्जेक्ट का उपयोग उस सरणी आकार को निर्दिष्ट करने के लिए नहीं कर सकते हैं जब आपको गैर- वीएलए सरणी की आवश्यकता होती है।
यदि यह आपके लिए महत्वपूर्ण है तो यह आपकी पसंद का निर्धारण करेगा। ज्यादातर समय, आपके पास #define
सी में उपयोग करने के अलावा कोई विकल्प नहीं होगा और दूसरे विकल्प को न भूलें, जो कि सी में सही स्थिरांक पैदा करता है enum
।
C ++ में const
ऑब्जेक्ट सही स्थिरांक होते हैं, इसलिए C ++ में const
वेरिएंट को प्राथमिकता देना लगभग हमेशा बेहतर होता है ( static
C ++ में स्पष्ट की कोई आवश्यकता नहीं )।
const int
केस-लेबल में वस्तुओं का उपयोग करना सी भाषा के सभी संस्करणों में अवैध है। (बेशक, आपका कंपाइलर एक गैर-मानक C ++ के रूप में समर्थन करने के लिए स्वतंत्र है - भाषा विस्तार की तरह।)
const
केवल पढ़ने का मतलब है। const int r = rand();
पूरी तरह से कानूनी है।
constexpr
तुलना में उपयोग करना बेहतर है । const
stl
array
bitset
switch()
कथन में परीक्षण करना होगा , case
एक में नहीं । मैंने अभी-अभी इस पर पकड़ लिया है got
के बीच का अंतर static const
और #define
है कि पूर्व का उपयोग करता है स्मृति और बाद में भंडारण के लिए स्मृति का उपयोग नहीं करता है। दूसरे, आप किसी पते का पास नहीं कर सकते, #define
जबकि आप किसी के पते को पास नहीं कर सकते static const
। वास्तव में यह इस बात पर निर्भर करता है कि हम किस परिस्थिति में हैं, हमें इन दोनों में से किसी एक का चयन करना होगा। दोनों अलग-अलग परिस्थितियों में अपने सर्वश्रेष्ठ में हैं। कृपया यह न समझें कि एक दूसरे से बेहतर है ... :-)
अगर ऐसा होता, तो डेनिस रिची ने अकेले सबसे अच्छा रखा होता ... हाहाहा ... :-)
const
स्मृति का उपयोग करता है। GCC (4.5.3 और कुछ नए संस्करणों के साथ परीक्षण) const int
-O3 का उपयोग करते समय आसानी से आपके कोड में एक प्रत्यक्ष शाब्दिक में अनुकूलन करता है । इसलिए यदि आप कम रैम एंबेडेड डेवलपमेंट (जैसे AVR) करते हैं तो यदि आप GCC या किसी अन्य संगत कंपाइलर का उपयोग करते हैं तो आप सुरक्षित रूप से C का उपयोग कर सकते हैं। मैंने इसका परीक्षण नहीं किया है, लेकिन क्लैंग से यही बात करने की उम्मीद है कि बी.डब्ल्यू.टी.
सी #define
में अधिक लोकप्रिय है। आप उदाहरण के लिए सरणी आकार घोषित करने के लिए उन मूल्यों का उपयोग कर सकते हैं:
#define MAXLEN 5
void foo(void) {
int bar[MAXLEN];
}
एएनएसआई सी आपको static const
इस संदर्भ में एस का उपयोग करने की अनुमति नहीं देता है जहां तक मुझे पता है। C ++ में आपको इन मामलों में मैक्रोज़ से बचना चाहिए। तुम लिख सकते हो
const int maxlen = 5;
void foo() {
int bar[maxlen];
}
और यहां तक कि बाहर छोड़ दें static
क्योंकि आंतरिक संबंध const
पहले से ही [सी ++ में] द्वारा निहित है ।
const int MY_CONSTANT = 5;
एक फ़ाइल में हो सकता है और इसे extern const int MY_CONSTANT;
दूसरे में एक्सेस कर सकता हूं । मैं const
डिफ़ॉल्ट व्यवहार को बदलने के बारे में मानक (C99 कम से कम) में कोई जानकारी नहीं पा सका "6.2.2: 5 यदि किसी वस्तु के लिए एक पहचान for एर की घोषणा में and ले गुंजाइश है और कोई भंडारण-वर्ग की युक्ति, एर नहीं है, तो इसका लिंकेज बाहरी है"।
bar
एक वीएलए (चर लंबाई सरणी) है; संकलक कोड उत्पन्न करने की संभावना है जैसे कि इसकी लंबाई स्थिर थी।
const
C का एक और दोष यह है कि आप दूसरे को इनिशियलाइज़ करने में मूल्य का उपयोग नहीं कर सकते हैं 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;
यहां तक कि यह एक कास्ट के साथ काम नहीं करता है क्योंकि कंपाइलर इसे एक स्थिर के रूप में नहीं देखता है:
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 uint8_t const ARRAY_SIZE = 16;
अचानक नहीं संकलन अब थोड़ा चुनौतीपूर्ण हो सकता है, खासकर जब #define ARRAY_SIZE 256
हेडर के पेचीदा वेब में गहरी दस परतों को दफन किया जाता है। कि सभी कैप नाम ARRAY_SIZE
परेशानी के लिए पूछ रहे हैं। मैक्रोज़ के लिए ALL_CAPS आरक्षित करें, और ALL_CAPS फॉर्म में नहीं होने वाले मैक्रो को कभी भी परिभाषित न करें।
const
। यह और अधिक उत्कीर्ण किया जा सकता है!
अगर आप इससे दूर हो सकते हैं, तो static const
इसके कई फायदे हैं। यह सामान्य स्कोप सिद्धांतों का पालन करता है, डिबगर में दिखाई देता है, और आमतौर पर उन नियमों का पालन करता है जो चर मानते हैं।
हालांकि, कम से कम मूल सी मानक में, यह वास्तव में एक स्थिर नहीं है। यदि आप उपयोग करते हैं #define var 5
, तो आप int foo[var];
एक घोषणा के रूप में लिख सकते हैं , लेकिन आप ऐसा नहीं कर सकते (सिवाय इसके एक संकलक विस्तार के रूप में) static const int var = 5;
यह C ++ में ऐसा नहीं है, जहां static const
संस्करण का उपयोग #define
संस्करण कहीं भी किया जा सकता है, और मुझे विश्वास है कि C99 के मामले में भी यही है।
हालांकि, #define
लोअरकेस नाम के साथ एक स्थिरांक का नाम कभी न रखें । यह अनुवाद इकाई के अंत तक उस नाम के किसी भी संभावित उपयोग को ओवरराइड करेगा। मैक्रो स्थिरांक में होना चाहिए जो प्रभावी रूप से अपने स्वयं के नामस्थान है, जो परंपरागत रूप से सभी पूंजी पत्र हैं, शायद एक उपसर्ग के साथ।
const
C99 में अभी भी वास्तविक स्थिरांक नहीं है। आप const
C99 में ए के साथ ऐरे आकार की घोषणा कर सकते हैं , लेकिन केवल इसलिए कि C99 वेरिएबल लेंथ एरे का समर्थन करता है। इस कारण से, यह केवल वही काम करेगा जहां वीएलएएएस की अनुमति है। उदाहरण के लिए, C99 में भी, आप अभी भी const
a में सदस्य सरणी के आकार को घोषित करने के लिए उपयोग नहीं कर सकते हैं struct
।
const int
आकार के साथ आरंभ करने देगा जैसे कि यह C ++ कास्ट या मैक्रो था। क्या आप मानक से GCC के इस विचलन पर निर्भर होना चाहते हैं, निश्चित रूप से आपकी पसंद है, मैं व्यक्तिगत रूप से इसके साथ जाऊंगा जब तक कि आप वास्तव में GCC या Clang की तुलना में किसी अन्य संकलक का उपयोग नहीं कर सकते, बाद में यहाँ एक ही सुविधा है (Clang के साथ परीक्षण) 3.7)।
यह हमेशा #define के बजाय कास्ट का उपयोग करने के लिए बेहतर है। ऐसा इसलिए है क्योंकि कांसेप्ट को कंपाइलर और # डेफिन द्वारा प्रीप्रोसेसर द्वारा इलाज किया जाता है। यह ऐसा है जैसे #define खुद कोड (मोटे तौर पर बोलने) का हिस्सा नहीं है।
उदाहरण:
#define PI 3.1416
प्रतीकात्मक नाम पीआई को संकलक द्वारा कभी नहीं देखा जा सकता है; प्रीप्रोसेसर द्वारा इसे हटाया जा सकता है इससे पहले कि स्रोत कोड किसी कंपाइलर के पास पहुंच जाए। परिणामस्वरूप, PI नाम प्रतीक तालिका में दर्ज नहीं हो सकता है। यदि आप निरंतरता के उपयोग को शामिल करते हुए संकलन के दौरान एक त्रुटि प्राप्त करते हैं, तो यह भ्रामक हो सकता है, क्योंकि त्रुटि संदेश 3.1416 को संदर्भित कर सकता है, पीआई को नहीं। यदि PI को एक हेडर फ़ाइल में परिभाषित किया गया है जिसे आपने नहीं लिखा है, तो आपको पता नहीं चलेगा कि 3.1416 कहां से आया है।
यह समस्या एक प्रतीकात्मक डिबगर में भी फसल कर सकती है, क्योंकि, फिर से, आप जिस नाम से प्रोग्रामिंग कर रहे हैं वह प्रतीक तालिका में नहीं हो सकता है।
समाधान:
const double PI = 3.1416; //or static const...
#define var 5
अगर आपको चीजें पसंद हैं तो आप परेशानी का कारण बनेंगे 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
^
ध्यान दें कि एनम एक त्रुटि देता है जब परिभाषित एक चेतावनी देता है।
परिभाषा
const int const_value = 5;
हमेशा एक निरंतर मान को परिभाषित नहीं करता है। कुछ संकलक (उदाहरण के लिए 0.9.26 tcc ) सिर्फ "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
तो मशीन कोड को संपादित करके भी संशोधित किया जा सकता है।
5
। लेकिन कोई संशोधित नहीं कर सकता #define
क्योंकि यह प्रीप्रोसेसर मैक्रो है। यह बाइनरी प्रोग्राम में मौजूद नहीं है। यदि कोई उन सभी स्थानों को संशोधित करना चाहता CONST_VALUE
था, जहां एक का उपयोग किया जाता था, तो उसे एक-एक करके करना पड़ता था।
#define CONST 5
, फिर if (CONST == 5) { do_this(); } else { do_that(); }
, और संकलक else
शाखा को समाप्त कर देता है । CONST
6 में बदलने के लिए आप मशीन कोड को कैसे संपादित करने का प्रस्ताव रखते हैं ?
#define
यह बुलेट-प्रूफ नहीं है।
#define
। स्रोत कोड और recompile को संपादित करने का एकमात्र वास्तविक तरीका यही है।
हालाँकि यह सवाल पूर्णांक के बारे में था, यह ध्यान देने योग्य है कि #define और enums बेकार हैं यदि आपको एक स्थिर संरचना या स्ट्रिंग की आवश्यकता है। ये दोनों आमतौर पर संकेत के रूप में कार्य करने के लिए पारित किए जाते हैं। (स्ट्रिंग्स के साथ इसकी आवश्यकता है; संरचनाओं के साथ यह अधिक कुशल है।)
पूर्णांक के लिए के रूप में, यदि आप बहुत सीमित स्मृति के साथ एक एम्बेडेड वातावरण में हैं, तो आपको इस बारे में चिंता करने की आवश्यकता हो सकती है कि निरंतर कहाँ संग्रहीत है और इसे कैसे एक्सेस किया जाता है। कंपाइलर रन समय में दो कॉन्स्ट्स जोड़ सकता है, लेकिन कंपाइल टाइम में दो #Dfines जोड़ें। एक #define स्थिरांक को एक या एक से अधिक MOV [तत्काल] निर्देशों में परिवर्तित किया जा सकता है, जिसका अर्थ है कि स्थिरांक प्रोग्राम मेमोरी में प्रभावी रूप से संग्रहीत है। डेटा मेमोरी में एक कॉन्स्टेंट कॉन्स्टेंट को .const सेक्शन में स्टोर किया जाएगा। हार्वर्ड वास्तुकला के साथ सिस्टम में, प्रदर्शन और स्मृति उपयोग में अंतर हो सकते हैं, हालांकि वे संभवतः छोटे होंगे। वे आंतरिक छोरों के हार्ड-कोर अनुकूलन के लिए मायने रख सकते हैं।
मत सोचो कि "जो हमेशा सबसे अच्छा होता है" के लिए एक उत्तर है, लेकिन, जैसा कि मैथ्यू ने कहा
static const
सुरक्षित है #define
हालाँकि, मेरे सबसे बड़े पालतू जानवर के दृश्य स्टूडियो में डिबगिंग करते समय आप चर नहीं देख सकते हैं। यह एक त्रुटि देता है कि प्रतीक नहीं पाया जा सकता है।
संयोग से, एक विकल्प #define
, जो उचित ढलान प्रदान करता है, लेकिन "वास्तविक" स्थिर की तरह व्यवहार करता है, "एनम" है। उदाहरण के लिए:
enum {number_ten = 10;}
कई मामलों में, एन्यूमरेटेड प्रकारों को परिभाषित करना और उन प्रकारों के चर बनाना उपयोगी है; यदि ऐसा किया जाता है, तो डिबगर अपने गणना नाम के अनुसार चर प्रदर्शित करने में सक्षम हो सकते हैं।
हालांकि ऐसा करने के साथ एक महत्वपूर्ण चेतावनी: सी ++ में, एन्यूमरेटेड प्रकार के पूर्णांक के साथ सीमित संगतता है। उदाहरण के लिए, डिफ़ॉल्ट रूप से, कोई उन पर अंकगणित नहीं कर सकता है। मुझे लगता है कि एनम के लिए एक जिज्ञासु डिफ़ॉल्ट व्यवहार होना चाहिए; हालांकि "सख्त एनम" प्रकार का होना अच्छा होता, सी + + आमतौर पर सी के साथ संगत होने की इच्छा को देखते हुए, मुझे लगता है कि "एनम" प्रकार का डिफ़ॉल्ट व्यवहार पूर्णांकों के साथ विनिमेय होना चाहिए।
int
, इसलिए "एनम हैक" का उपयोग अन्य पूर्णांक प्रकारों के साथ नहीं किया जा सकता है। (गणना प्रकार कुछ कार्यान्वयन-परिभाषित पूर्णांक प्रकार के साथ संगत है, जरूरी नहीं int
, लेकिन इस मामले में वह प्रकार गुमनाम है जो कोई फर्क नहीं पड़ता।)
int
एक एन्यूमरेशन-टाइप किए गए वैरिएबल (जो कंपाइलर को करने की अनुमति देता है) के अलावा कोई अन्य टाइप करता है और कोई इस तरह के वैरिएबल को असाइन करने की कोशिश करता है अपने स्वयं के गणन का सदस्य। काश मानक समितियाँ निर्दिष्ट शब्दार्थ के साथ पूर्णांक प्रकारों की घोषणा के पोर्टेबल तरीके जोड़ देतीं। किसी भी मंच, char
आकार की परवाह किए बिना , एक प्रकार की घोषणा करने में सक्षम होना चाहिए जो मॉड 65536 को लपेट देगा, भले ही कंपाइलर को बहुत सारे AND R0,#0xFFFF
या समकक्ष निर्देश जोड़ना हो ।
uint16_t
, हालांकि यह एक गणन प्रकार नहीं है। उपयोगकर्ता को दिए गए एन्यूमरेशन प्रकार का प्रतिनिधित्व करने के लिए उपयोग किए जाने वाले पूर्णांक प्रकार को निर्दिष्ट करने के लिए अच्छा होगा, लेकिन आप व्यक्तिगत मूल्यों के typedef
लिए uint16_t
और उसी के साथ श्रृंखला की एक ही प्रभाव को प्राप्त कर सकते #define
हैं।
2U < -1L
सही और दूसरों के रूप में गलत का मूल्यांकन करेंगे, और अब हम इस तथ्य के साथ फंस गए हैं कि कुछ प्लेटफॉर्म एक तुलना uint32_t
और int32_t
हस्ताक्षर किए गए के बीच लागू करेंगे और कुछ के रूप में अहस्ताक्षरित, लेकिन इसका मतलब यह नहीं है कि समिति सी को एक ऊर्ध्व-संगत उत्तराधिकारी को परिभाषित नहीं कर सकती है जिसमें ऐसे प्रकार शामिल हैं जिनके शब्दार्थ सभी संकलक पर संगत होंगे।
एक साधारण अंतर:
पूर्व-प्रसंस्करण समय में, निरंतर को इसके मूल्य के साथ बदल दिया जाता है। इसलिए आप डिरेफेरेंस ऑपरेटर को डिफाइन नहीं कर सकते, लेकिन आप डीरेफेरेंस ऑपरेटर को वैरिएबल पर लागू कर सकते हैं।
जैसा कि आप मान लेंगे, परिभाषित है कि स्थिर गति है।
उदाहरण के लिए, होना:
#define mymax 100
आप नहीं कर सकते printf("address of constant is %p",&mymax);
।
लेकिन होने
const int mymax_var=100
आप कर सकते हैं printf("address of constant is %p",&mymax_var);
।
अधिक स्पष्ट होने के लिए, परिभाषित को पूर्व-प्रसंस्करण चरण में इसके मूल्य से बदल दिया जाता है, इसलिए हमारे पास कार्यक्रम में कोई चर संग्रहीत नहीं है। हमारे पास प्रोग्राम के टेक्स्ट सेगमेंट से सिर्फ कोड है जहां परिभाषित किया गया था।
हालांकि, स्थैतिक कास्ट के लिए हमारे पास एक चर है जो कहीं आवंटित किया गया है। Gcc के लिए, स्थैतिक कास्ट को प्रोग्राम के टेक्स्ट सेगमेंट में आवंटित किया जाता है।
ऊपर, मैं संदर्भ ऑपरेटर के बारे में बताना चाहता था ताकि संदर्भ को संदर्भ से बदल दें।
const
क्वालिफायर के लिए बहुत अलग शब्दार्थ हैं । सी में एनम-कॉन्स्टेंट के अलावा सिम्बिका स्थिरांक नहीं हैं । A const int
परिवर्तनशील है। आप भाषा और विशिष्ट कार्यान्वयन को भी भ्रमित करते हैं। वस्तु को रखने की कोई आवश्यकता नहीं है। और यह gcc के लिए भी सही नहीं है: आम तौर पर यह अनुभाग const
में योग्य चर रखता है .rodata
। लेकिन यह लक्ष्य प्लेटफॉर्म पर निर्भर करता है। और आपका मतलब है ऑपरेटर का पता &
।
हमने MBF16X पर उत्पादित कोडांतरक कोड को देखा ... दोनों वेरिएंट अंकगणित संचालन (उदाहरण के लिए ADD तत्काल) के लिए एक ही कोड में परिणाम करते हैं।
तो पुरानी शैली है, const int
जबकि प्रकार की जाँच के लिए पसंद किया #define
जाता है। शायद यह संकलक-विशिष्ट है। तो अपने उत्पादित कोडांतरक कोड की जाँच करें।
मुझे यकीन नहीं है कि अगर मैं सही हूं, लेकिन मेरी राय में #define
डी मूल्य कॉलिंग किसी भी अन्य सामान्य रूप से घोषित चर (या कास्ट वैल्यू) को कॉल करने की तुलना में बहुत तेज है। ऐसा इसलिए है क्योंकि जब प्रोग्राम चल रहा है और इसे कुछ सामान्य रूप से घोषित चर का उपयोग करने की आवश्यकता है, तो उस चर को प्राप्त करने के लिए स्मृति में सटीक स्थान पर कूदने की आवश्यकता है।
इसके विपरीत जब यह #define
d मान का उपयोग करता है , तो प्रोग्राम को किसी भी आवंटित मेमोरी में कूदने की आवश्यकता नहीं है, यह सिर्फ मूल्य लेता है। यदि #define myValue 7
और प्रोग्राम कॉलिंग myValue
, यह ठीक वैसा ही व्यवहार करता है जैसे कि जब यह कॉल करता है 7
।