कॉन्स्ट (कंप्यूटर प्रोग्रामिंग): Difference between revisions

From Vigyanwiki
Line 14: Line 14:
f(i);
f(i);
</syntaxhighlight>
</syntaxhighlight>
क्योंकि तर्क <code>f</code> एक परिवर्तनीय पूर्णांक होना चाहिए, लेकिन <code>i</code> एक अचर पूर्णांक है. यह मिलान प्रोग्राम शुद्धता का एक रूप है, और इसे 'कॉन्स्ट-शुद्धता' के रूप में जाना जाता है। यह [[अनुबंध द्वारा प्रोग्रामिंग]] के एक रूप की अनुमति देता है, जहां फ़ंक्शन अपने प्रकार के हस्ताक्षर के हिस्से के रूप में निर्दिष्ट करते हैं कि क्या वे अपने तर्कों को संशोधित करते हैं या नहीं, और क्या उनका रिटर्न मान परिवर्तनीय है या नहीं। यह प्रकार-जांच मुख्य रूप से संकेतकों और संदर्भों में रुचि रखती है - पूर्णांक जैसे मूलभूत मूल्य प्रकार नहीं - बल्कि समग्र डेटा प्रकार या [[कंटेनर (सार डेटा प्रकार)]] जैसे टेम्पलेट प्रकारों के लिए भी। यह इस तथ्य से छिपा है कि <code>const</code> टाइप बलपूर्वक (अंतर्निहित [[प्रकार रूपांतरण]]) और सी के [[कॉल-टू-मूल्य से]] होने के कारण प्रायः छोड़ा जा सकता है (C++ और D या तो कॉल-बाय-वैल्यू या कॉल-बाय-रेफरेंस हैं)।
क्योंकि तर्क <code>f</code> एक परिवर्तनीय पूर्णांक होना चाहिए, लेकिन <code>i</code> एक अचर पूर्णांक है. यह मिलान प्रोग्राम शुद्धता का एक रूप है, और इसे 'कॉन्स्ट-शुद्धता' के रूप में जाना जाता है। यह अनुबंध द्वारा प्रोग्रामिंग के एक रूप की अनुमति देता है, जहां फ़ंक्शन अपने प्रकार के हस्ताक्षर के हिस्से के रूप में निर्दिष्ट करते हैं कि क्या वे अपने तर्कों को संशोधित करते हैं या नहीं, और क्या उनका रिटर्न मान परिवर्तनीय है या नहीं। यह प्रकार-जांच मुख्य रूप से संकेतकों और संदर्भों में रुचि रखती है - पूर्णांक जैसे मूलभूत मूल्य प्रकार नहीं - बल्कि समग्र डेटा प्रकार या [[कंटेनर (सार डेटा प्रकार)]] जैसे टेम्पलेट प्रकारों के लिए भी। यह इस तथ्य से छिपा है कि <code>const</code> टाइप बलपूर्वक (अंतर्निहित [[प्रकार रूपांतरण]]) और सी के [[कॉल-टू-मूल्य से]] होने के कारण प्रायः छोड़ा जा सकता है (C++ और D या तो कॉल-बाय-वैल्यू या कॉल-बाय-रेफरेंस हैं)।


== परिणाम ==
== परिणाम ==
Line 23: Line 23:


== अन्य उपयोग ==
== अन्य उपयोग ==
इसके अतिरिक्त, एक (गैर स्थैतिक) सदस्य-फ़ंक्शन के रूप में घोषित किया जा सकता है <code>const</code>. इस मामले में, यह (कंप्यूटर प्रोग्रामिंग)|<code>this</code> ऐसे फ़ंक्शन के अंदर पॉइंटर प्रकार का होता है <code>object_type const *</code> केवल प्रकार के बजाय <code>object_type *</code>.<ref>{{cite web |url=http://eel.is/c++draft/class.this#:this,type_of |title=The <code>this</code> pointer |website=Draft C++ Standard |access-date=2020-03-30 |quote=The type of <code>this</code> in a member function whose type has a ''cv-qualifier-seq cv'' and whose class is <code>X</code> is “pointer to ''cv'' <code>X</code>”.}}</ref> इसका मतलब यह है कि इस ऑब्जेक्ट के लिए गैर-कॉन्स्ट फ़ंक्शंस को ऐसे फ़ंक्शन के अंदर से नहीं बुलाया जा सकता है, न ही फ़ील्ड (कंप्यूटर विज्ञान) को संशोधित किया जा सकता है। C++ में, एक सदस्य चर को इस प्रकार घोषित किया जा सकता है <code>[[mutable object|mutable]]</code>, यह दर्शाता है कि यह प्रतिबंध उस पर लागू नहीं होता है। कुछ मामलों में, यह उपयोगी हो सकता है, उदाहरण के लिए [[कैश (कंप्यूटिंग)]], संदर्भ गणना और [[डेटा सिंक्रनाइज़ेशन]] के साथ। इन मामलों में, वस्तु का तार्किक अर्थ (स्थिति) अपरिवर्तित है, लेकिन वस्तु भौतिक रूप से स्थिर नहीं है क्योंकि इसका बिटवाइज़ प्रतिनिधित्व बदल सकता है।
इसके अतिरिक्त, एक (गैर स्थैतिक) सदस्य-फ़ंक्शन के रूप में घोषित किया जा सकता है <code>const</code>. इस मामले में, यह (कंप्यूटर प्रोग्रामिंग)|<code>this</code> ऐसे फ़ंक्शन के अंदर पॉइंटर प्रकार का होता है <code>object_type const *</code> केवल प्रकार के बजाय <code>object_type *</code>.<ref>{{cite web |url=http://eel.is/c++draft/class.this#:this,type_of |title=The <code>this</code> pointer |website=Draft C++ Standard |access-date=2020-03-30 |quote=The type of <code>this</code> in a member function whose type has a ''cv-qualifier-seq cv'' and whose class is <code>X</code> is “pointer to ''cv'' <code>X</code>”.}}</ref> इसका अर्थ यह है कि इस ऑब्जेक्ट के लिए गैर-कॉन्स्ट फ़ंक्शंस को ऐसे फ़ंक्शन के अंदर से नहीं बुलाया जा सकता है, न ही फ़ील्ड (कंप्यूटर विज्ञान) को संशोधित किया जा सकता है। C++ में, एक सदस्य चर को इस प्रकार घोषित किया जा सकता है <code>[[mutable object|mutable]]</code>, यह दर्शाता है कि यह प्रतिबंध उस पर लागू नहीं होता है। कुछ मामलों में, यह उपयोगी हो सकता है, उदाहरण के लिए [[कैश (कंप्यूटिंग)]], संदर्भ गणना और [[डेटा सिंक्रनाइज़ेशन]] के साथ है। इन मामलों में, वस्तु का तार्किक अर्थ (स्थिति) अपरिवर्तित है, लेकिन वस्तु भौतिक रूप से स्थिर नहीं है क्योंकि इसका बिटवाइज़ प्रतिनिधित्व बदल सकता है।


== सिंटेक्स ==
== सिंटेक्स ==
Line 134: Line 134:


=== पैरामीटर और चर ===
=== पैरामीटर और चर ===
<code>const</code> फ़ंक्शन पैरामीटर और वेरिएबल (वैश्विक या स्थानीय सहित स्थिर चर या स्वचालित) दोनों पर घोषित किया जा सकता है। उपयोग के बीच व्याख्या भिन्न-भिन्न होती है। ए <code>const</code> स्थिर चर (वैश्विक चर या स्थिर स्थानीय चर) एक स्थिरांक है, और इसका उपयोग गणितीय स्थिरांक जैसे डेटा के लिए किया जा सकता है, जैसे <code>double const PI = 3.14159</code> - वास्तविक रूप से लंबा, या समग्र संकलन-समय पैरामीटर। a <code>const</code> स्वचालित चर (गैर स्थैतिक स्थानीय चर) का अर्थ है कि [[एकल असाइनमेंट]] हो रहा है, हालांकि हर बार एक अलग मान का उपयोग किया जा सकता है, जैसे कि <code>int const x_squared = x * x</code>. ए <code>const</code> पास-बाय-रेफरेंस में पैरामीटर का मतलब है कि संदर्भित मूल्य संशोधित नहीं है - यह [[अनुबंध द्वारा डिजाइन]] का हिस्सा है - जबकि ए <code>const</code> पास-बाय-वैल्यू में पैरामीटर (या पॉइंटर स्वयं, पास-बाय-रेफरेंस में) इंटरफ़ेस में कुछ भी नहीं जोड़ता है (जैसा कि मान कॉपी किया गया है), लेकिन इंगित करता है कि आंतरिक रूप से, फ़ंक्शन पैरामीटर की स्थानीय प्रतिलिपि को संशोधित नहीं करता है (यह एक एकल असाइनमेंट है)। इस कारण से, कुछ लोग इसका उपयोग करने के पक्ष में हैं <code>const</code> केवल पास-बाय-रेफरेंस के लिए पैरामीटर में, जहां यह अनुबंध बदलता है, लेकिन पास-बाय-वैल्यू के लिए नहीं, जहां यह कार्यान्वयन को उजागर करता है।
<code>const</code> फ़ंक्शन पैरामीटर और वेरिएबल (वैश्विक या स्थानीय सहित स्थिर चर या स्वचालित) दोनों पर घोषित किया जा सकता है। उपयोग के बीच व्याख्या भिन्न-भिन्न होती है। ए <code>const</code> स्थिर चर (वैश्विक चर या स्थिर स्थानीय चर) एक स्थिरांक है, और इसका उपयोग गणितीय स्थिरांक जैसे डेटा के लिए किया जा सकता है, जैसे <code>double const PI = 3.14159</code> - वास्तविक रूप से लंबा, या समग्र संकलन-समय पैरामीटर। a <code>const</code> स्वचालित चर (गैर स्थैतिक स्थानीय चर) का अर्थ है कि [[एकल असाइनमेंट]] हो रहा है, हालांकि हर बार एक अलग मान का उपयोग किया जा सकता है, जैसे कि <code>int const x_squared = x * x</code>. ए <code>const</code> पास-बाय-रेफरेंस में पैरामीटर का अर्थ है कि संदर्भित मूल्य संशोधित नहीं है - यह [[अनुबंध द्वारा डिजाइन]] का हिस्सा है - जबकि ए <code>const</code> पास-बाय-वैल्यू में पैरामीटर (या पॉइंटर स्वयं, पास-बाय-रेफरेंस में) इंटरफ़ेस में कुछ भी नहीं जोड़ता है (जैसा कि मान कॉपी किया गया है), लेकिन इंगित करता है कि आंतरिक रूप से, फ़ंक्शन पैरामीटर की स्थानीय प्रतिलिपि को संशोधित नहीं करता है (यह एक एकल असाइनमेंट है)। इस कारण से, कुछ लोग इसका उपयोग करने के पक्ष में हैं <code>const</code> केवल पास-बाय-रेफरेंस के लिए पैरामीटर में, जहां यह अनुबंध बदलता है, लेकिन पास-बाय-वैल्यू के लिए नहीं, जहां यह कार्यान्वयन को उजागर करता है।


== C++ ==
== C++ ==
Line 328: Line 328:
अन्य लैंग्वेजएँ प्रकार के निरंतरता भाग में C/C++ का अनुसरण नहीं करती हैं, हालाँकि उनमें प्रायः सतही रूप से समान संरचनाएँ होती हैं और वे इसका उपयोग कर सकती हैं <code>const</code> कीवर्ड. साधारणतया इसका उपयोग केवल स्थिरांक (स्थिर वस्तुओं) के लिए किया जाता है।
अन्य लैंग्वेजएँ प्रकार के निरंतरता भाग में C/C++ का अनुसरण नहीं करती हैं, हालाँकि उनमें प्रायः सतही रूप से समान संरचनाएँ होती हैं और वे इसका उपयोग कर सकती हैं <code>const</code> कीवर्ड. साधारणतया इसका उपयोग केवल स्थिरांक (स्थिर वस्तुओं) के लिए किया जाता है।


C# में एक है <code>const</code> कीवर्ड, लेकिन मौलिक रूप से भिन्न और सरल शब्दार्थ के साथ: इसका मतलब एक संकलन-समय स्थिरांक है, और यह प्रकार का हिस्सा नहीं है।
C# में एक है <code>const</code> कीवर्ड, लेकिन मौलिक रूप से भिन्न और सरल शब्दार्थ के साथ: इसका अर्थ एक संकलन-समय स्थिरांक है, और यह प्रकार का हिस्सा नहीं है।


[[निम (प्रोग्रामिंग भाषा)|निम (प्रोग्रामिंग लैंग्वेज)]] में एक है <code>const</code> C# के समान कीवर्ड: यह प्रकार का हिस्सा बनने के बजाय एक संकलन-समय स्थिरांक भी घोषित करता है। हालाँकि, निम में, किसी भी अभिव्यक्ति से एक स्थिरांक घोषित किया जा सकता है जिसका संकलन समय पर मूल्यांकन किया जा सकता है।<ref>[http://nim-lang.org/docs/manual.html#statements-and-expressions-const-section Nim Manual: Const section]</ref> C# में, केवल C# अंतर्निर्मित प्रकारों को ही घोषित किया जा सकता है <code>const</code>; कक्षाओं, संरचनाओं और सरणियों सहित उपयोगकर्ता-परिभाषित प्रकार नहीं हो सकते <code>const</code>.<ref>[https://msdn.microsoft.com/en-us/library/e6w8fe1b.aspx const (C# Reference)]</ref>
[[निम (प्रोग्रामिंग भाषा)|निम (प्रोग्रामिंग लैंग्वेज)]] में एक है <code>const</code> C# के समान कीवर्ड: यह प्रकार का हिस्सा बनने के बजाय एक संकलन-समय स्थिरांक भी घोषित करता है। हालाँकि, निम में, किसी भी अभिव्यक्ति से एक स्थिरांक घोषित किया जा सकता है जिसका संकलन समय पर मूल्यांकन किया जा सकता है।<ref>[http://nim-lang.org/docs/manual.html#statements-and-expressions-const-section Nim Manual: Const section]</ref> C# में, केवल C# अंतर्निर्मित प्रकारों को ही घोषित किया जा सकता है <code>const</code>; कक्षाओं, संरचनाओं और सरणियों सहित उपयोगकर्ता-परिभाषित प्रकार नहीं हो सकते <code>const</code>.<ref>[https://msdn.microsoft.com/en-us/library/e6w8fe1b.aspx const (C# Reference)]</ref>

Revision as of 23:44, 12 August 2023

कुछ प्रोग्रामिंग लैंग्वेजेज में, कॉन्स्ट (const) एक प्रकार क्वालीफायर टाइप करें (डेटा प्रकार पर लागू एक कीवर्ड (कंप्यूटर प्रोग्रामिंग)) है जो इंगित करता है कि डेटा केवल पढ़ने के लिए है। जबकि इसका उपयोग कॉन्स्टेंट (कंप्यूटर प्रोग्रामिंग) घोषित करने के लिए किया जा सकता है, const सी-परिवार की सूची में लैंग्वेजेज की प्रोग्रामिंग लैंग्वेजएं प्रकार का हिस्सा होने के कारण अन्य लैंग्वेजेज में समान निर्माणों से भिन्न होती हैं, और इस प्रकार पॉइंटर (कंप्यूटर प्रोग्रामिंग), संदर्भ, समग्र डेटा प्रकार और प्रकार-चेकिंग के साथ संयुक्त होने पर जटिल व्यवहार होता है। अन्य लैंग्वेजेज में, डेटा एक मेमोरी स्थान पर नहीं होता है, बल्कि प्रत्येक उपयोग पर संकलन समय पर कॉपी किया जाता है।[1] जो लैंग्वेजएँ इसका उपयोग करती हैं उनमें C (प्रोग्रामिंग लैंग्वेज), C++, D (प्रोग्रामिंग लैंग्वेज), जावास्क्रिप्ट, जूलिया (प्रोग्रामिंग लैंग्वेज), और रस्ट (प्रोग्रामिंग लैंग्वेज) सम्मिलित हैं।

परिचय

जब किसी वस्तु (कंप्यूटर विज्ञान) घोषणा (कंप्यूटर प्रोग्रामिंग) में लागू किया जाता है,[lower-alpha 1] यह इंगित करता है कि वस्तु एक स्थिरांक (कंप्यूटर प्रोग्रामिंग) है: इसका मान (कंप्यूटर विज्ञान) एक चर (कंप्यूटर विज्ञान) के विपरीत, बदला नहीं जा सकता है। यह मूल उपयोग - स्थिरांक घोषित करने के लिए - कई अन्य लैंग्वेज में समानताएं हैं।

हालाँकि, अन्य लैंग्वेजेज के विपरीत, लैंग्वेज के C परिवार में const प्रकार का भाग है, वस्तु का भाग नहीं। उदाहरण के लिए, सी में, int const x = 1; एक वस्तु घोषित करता है x का int const लिखें const प्रकार का हिस्सा है, जैसे कि इसे पार्स किया गया हो (int const) x - जबकि Ada (प्रोग्रामिंग लैंग्वेज) में, X : constant INTEGER := 1_ एक स्थिरांक (एक प्रकार की वस्तु) घोषित करता है X का INTEGER लिखें constant वस्तु का हिस्सा है, लेकिन प्रकार का हिस्सा नहीं है

इसके दो सूक्ष्म परिणाम हैं. पहले तो, const अधिक जटिल प्रकार के भागों पर लागू किया जा सकता है - उदाहरण के लिए, int const * const x; एक स्थिर पूर्णांक के लिए एक स्थिर सूचक घोषित करता है, जबकि int const * x; एक स्थिर पूर्णांक के लिए एक चर सूचक घोषित करता है, और int * const x; एक चर पूर्णांक के लिए एक स्थिर सूचक घोषित करता है। दूसरे, क्योंकि const प्रकार का भाग है, इसे प्रकार-जाँच के भाग के रूप में मेल खाना चाहिए। उदाहरण के लिए, निम्नलिखित कोड अमान्य है:

void f(int& x);
// ...
int const i;
f(i);

क्योंकि तर्क f एक परिवर्तनीय पूर्णांक होना चाहिए, लेकिन i एक अचर पूर्णांक है. यह मिलान प्रोग्राम शुद्धता का एक रूप है, और इसे 'कॉन्स्ट-शुद्धता' के रूप में जाना जाता है। यह अनुबंध द्वारा प्रोग्रामिंग के एक रूप की अनुमति देता है, जहां फ़ंक्शन अपने प्रकार के हस्ताक्षर के हिस्से के रूप में निर्दिष्ट करते हैं कि क्या वे अपने तर्कों को संशोधित करते हैं या नहीं, और क्या उनका रिटर्न मान परिवर्तनीय है या नहीं। यह प्रकार-जांच मुख्य रूप से संकेतकों और संदर्भों में रुचि रखती है - पूर्णांक जैसे मूलभूत मूल्य प्रकार नहीं - बल्कि समग्र डेटा प्रकार या कंटेनर (सार डेटा प्रकार) जैसे टेम्पलेट प्रकारों के लिए भी। यह इस तथ्य से छिपा है कि const टाइप बलपूर्वक (अंतर्निहित प्रकार रूपांतरण) और सी के कॉल-टू-मूल्य से होने के कारण प्रायः छोड़ा जा सकता है (C++ और D या तो कॉल-बाय-वैल्यू या कॉल-बाय-रेफरेंस हैं)।

परिणाम

कॉन्स्ट-नेस के विचार का अर्थ यह नहीं है कि मेमोरी में संग्रहीत चर अलेखनीय है। की अपेक्षा, const-नेस एक संकलन-समय निर्माण है जो इंगित करता है कि एक प्रोग्रामर को क्या करना चाहिए, जरूरी नहीं कि वे क्या कर सकते हैं। हालाँकि, ध्यान दें कि पूर्वनिर्धारित डेटा के मामले में (जैसे char const * स्ट्रिंग शाब्दिक), सी const प्रायः अलेखनीय होता है।

अचर से भेद

जबकि प्रोग्राम चलने के दौरान एक स्थिरांक अपना मान नहीं बदलता है, एक ऑब्जेक्ट घोषित किया जाता है const प्रोग्राम चलने के दौरान वास्तव में इसका मान बदल सकता है। एक सामान्य उदाहरण डिजिटल इनपुट की वर्तमान स्थिति जैसे एम्बेडेड सिस्टम के भीतर केवल पढ़ने योग्य रजिस्टर हैं। डिजिटल इनपुट के लिए डेटा रजिस्टर को प्रायः घोषित किया जाता है const और volatile. इन रजिस्टरों की सामग्री प्रोग्राम के बिना कुछ भी किए बदल सकती है (volatile) लेकिन आप उन्हें भी नहीं लिखेंगे (const).

अन्य उपयोग

इसके अतिरिक्त, एक (गैर स्थैतिक) सदस्य-फ़ंक्शन के रूप में घोषित किया जा सकता है const. इस मामले में, यह (कंप्यूटर प्रोग्रामिंग)|this ऐसे फ़ंक्शन के अंदर पॉइंटर प्रकार का होता है object_type const * केवल प्रकार के बजाय object_type *.[2] इसका अर्थ यह है कि इस ऑब्जेक्ट के लिए गैर-कॉन्स्ट फ़ंक्शंस को ऐसे फ़ंक्शन के अंदर से नहीं बुलाया जा सकता है, न ही फ़ील्ड (कंप्यूटर विज्ञान) को संशोधित किया जा सकता है। C++ में, एक सदस्य चर को इस प्रकार घोषित किया जा सकता है mutable, यह दर्शाता है कि यह प्रतिबंध उस पर लागू नहीं होता है। कुछ मामलों में, यह उपयोगी हो सकता है, उदाहरण के लिए कैश (कंप्यूटिंग), संदर्भ गणना और डेटा सिंक्रनाइज़ेशन के साथ है। इन मामलों में, वस्तु का तार्किक अर्थ (स्थिति) अपरिवर्तित है, लेकिन वस्तु भौतिक रूप से स्थिर नहीं है क्योंकि इसका बिटवाइज़ प्रतिनिधित्व बदल सकता है।

सिंटेक्स

C, C++ और D में, उपयोगकर्ता द्वारा परिभाषित डेटा सहित सभी डेटा प्रकार घोषित किए जा सकते हैं const, और स्थिरांक-शुद्धता निर्देश देती है कि सभी चर या वस्तुओं को तब तक घोषित किया जाना चाहिए जब तक कि उन्हें संशोधित करने की आवश्यकता न हो। का ऐसा सक्रिय उपयोग const मूल्यों को समझना, ट्रैक करना और उनके बारे में तर्क करना आसान बनाता है,[3] और इस प्रकार यह कोड की पठनीयता और बोधगम्यता को बढ़ाता है और टीमों में काम करना और कोड को बनाए रखना आसान बनाता है क्योंकि यह किसी मूल्य के इच्छित उपयोग के बारे में जानकारी संचारित करता है। यह कोड के बारे में तर्क करते समय संकलक के साथ-साथ डेवलपर को भी सहायता कर सकता है। यह अधिक कुशल कोड उत्पन्न करने के लिए एक अनुकूलन कंपाइलर को भी सक्षम कर सकता है।[4]

सरल डेटा प्रकार

सरल गैर-सूचक डेटा प्रकारों के लिए, इसे लागू करना const क्वालीफायर सीधा है. यह ऐतिहासिक कारणों से कुछ प्रकारों के दोनों ओर जा सकता है (उदाहरण के लिए, const char foo = 'a'; के बराबर है char const foo = 'a';). कुछ कार्यान्वयन पर, का उपयोग कर रहे हैं const दो बार (उदाहरण के लिए, const char const या char const const) एक चेतावनी उत्पन्न करता है लेकिन कोई त्रुटि नहीं।

संकेत और संदर्भ

सूचक और संदर्भ प्रकार के लिए, का अर्थ const अधिक जटिल है - या तो सूचक स्वयं, या इंगित किया जा रहा मान, या दोनों, हो सकते हैं const. इसके अलावा, वाक्यविन्यास भ्रमित करने वाला हो सकता है। एक सूचक को एक के रूप में घोषित किया जा सकता है const लिखने योग्य मान के लिए सूचक, या a के लिए लिखने योग्य सूचक const मूल्य, या const की ओर सूचक const कीमत। ए const पॉइंटर को प्रारंभ में असाइन किए गए ऑब्जेक्ट से भिन्न ऑब्जेक्ट को इंगित करने के लिए पुन: असाइन नहीं किया जा सकता है, लेकिन इसका उपयोग उस मान को संशोधित करने के लिए किया जा सकता है जिसे यह पॉइंटी कहा जाता है).[5][6][7][8][9] C++ में संदर्भ चर एक वैकल्पिक वाक्यविन्यास है const सूचक. ए के लिए एक सूचक const दूसरी ओर, ऑब्जेक्ट को किसी अन्य मेमोरी स्थान पर इंगित करने के लिए पुन: असाइन किया जा सकता है (जो एक ही प्रकार का या परिवर्तनीय प्रकार का ऑब्जेक्ट होना चाहिए), लेकिन इसका उपयोग उस मेमोरी को संशोधित करने के लिए नहीं किया जा सकता है जिसे वह इंगित कर रहा है। ए const ए की ओर सूचक const ऑब्जेक्ट को घोषित भी किया जा सकता है और इसका उपयोग न तो नियुक्त व्यक्ति को संशोधित करने के लिए किया जा सकता है और न ही किसी अन्य ऑब्जेक्ट को इंगित करने के लिए पुन: असाइन किया जा सकता है। निम्नलिखित कोड इन सूक्ष्मताओं को दर्शाता है:

void Foo( int * ptr,
          int const * ptrToConst,
          int * const constPtr,
          int const * const constPtrToConst )
{
    *ptr = 0; // OK: modifies the pointed to data
    ptr  = NULL; // OK: modifies the pointer

    *ptrToConst = 0; // Error! Cannot modify the pointed to data
    ptrToConst  = NULL; // OK: modifies the pointer

    *constPtr = 0; // OK: modifies the pointed to data
    constPtr  = NULL; // Error! Cannot modify the pointer

    *constPtrToConst = 0; // Error! Cannot modify the pointed to data
    constPtrToConst  = NULL; // Error! Cannot modify the pointer
}

सी कन्वेंशन

कन्वेंशन के लिए सामान्य सी परंपरा का पालन करते हुए, घोषणा का उपयोग किया जाता है, और * एक पॉइंटर में पॉइंटर पर लिखा होता है, जो Dरेफ़रेंसिंग को दर्शाता है। उदाहरण के लिए, घोषणा में int *ptr, असंदर्भित रूप *ptr एक int, जबकि संदर्भ प्रपत्र ptr एक का सूचक है int. इस प्रकार const नाम को इसके दाईं ओर संशोधित करता है। इसके बजाय C++ कन्वेंशन संबद्ध करने के लिए है * प्रकार के साथ, जैसे कि int* ptr, और पढ़ें const बाईं ओर प्रकार को संशोधित करने के रूप में। int const * ptrToConst इस प्रकार पढ़ा जा सकता है*ptrToConst एक है int const(मान स्थिर है), याptrToConst एक है int const *(सूचक एक स्थिर पूर्णांक का सूचक है)। इस प्रकार:

int *ptr;                          // *ptr is an int value
int const *ptrToConst;             // *ptrToConst is a constant (int: integer value)
int * const constPtr;              // constPtr is a constant (int *: integer pointer)
int const * const constPtrToConst; // constPtrToConst is a constant pointer and points
                                   // to a constant value

C++ कन्वेंशन

मूल्य के बजाय प्रकार का विश्लेषण करने के C++ कन्वेंशन के बाद, अंगूठे का एक नियम (रूल ऑफ़ थम) यह है कि घोषणा को दाएं से बाएं ओर पढ़ा जाए। इस प्रकार, तारे के बाईं ओर की हर चीज़ को नुकीले प्रकार के रूप में पहचाना जा सकता है और तारे के दाईं ओर की हर चीज़ को सूचक गुण के रूप में पहचाना जा सकता है। उदाहरण के लिए, उपरोक्त हमारे उदाहरण में, int const * एक लिखने योग्य सूचक के रूप में पढ़ा जा सकता है जो एक गैर-लिखने योग्य पूर्णांक को संदर्भित करता है, और int * const एक गैर-लिखने योग्य सूचक के रूप में पढ़ा जा सकता है जो एक लिखने योग्य पूर्णांक को संदर्भित करता है।

एक अधिक सामान्य नियम जो आपको जटिल कन्वेंशन और परिलैंग्वेजेज को समझने में सहायता करता है, इस तरह काम करता है:

  1. वह पहचानकर्ता ढूंढें जिसकी घोषणा आप समझना चाहते हैं
  2. जहां तक ​​संभव हो दाईं ओर पढ़ें (यानी, घोषणा के अंत तक या अगले समापन कोष्ठक तक, जो भी पहले आए)
  3. जहां से आपने शुरू किया था वहां वापस जाएं, और बाईं ओर पीछे की ओर पढ़ें (यानी, घोषणा की शुरुआत तक या पिछले चरण में पाए गए समापन कोष्ठक से मेल खाने वाले खुले-कोष्ठक तक)
  4. जब आप घोषणा की शुरुआत में पहुँच जाते हैं तो आपका काम पूरा हो जाता है। यदि नहीं, तो अंतिम मिलान किए गए समापन कोष्ठक से आगे, चरण 2 पर जारी रखें।

यहाँ एक उदाहरण है:

Part of expression
double (**const (*fun(int))(double))[10]
Meaning
(reading downwards)
Identifier
                  fun
fun is a ...
Read to the right
                     (int))
function expecting an int ...
Find the matching (
                (*
returning a pointer to ...
Continue right
                           (double))
a function expecting a double ...
Find the matching (
        (**const
returning a constant pointer to
a pointer to ...
Continue right
                                    [10]
blocks of 10 ...
Read to the left
double
doubles.

बाईं ओर पढ़ते समय, यह महत्वपूर्ण है कि आप तत्वों को दाईं से बाईं ओर पढ़ें। तो एक int const * यह एक const int के लिए एक सूचक बन जाता है, न कि एक int के लिए एक const सूचक।

कुछ मामलों में C/C++ इसकी अनुमति देता है const कीवर्ड को प्रकार के बाईं ओर रखा जाना चाहिए। यहां कुछ उदाहरण दिए गए हैं:

const int *ptrToConst;            //identical to: int const *ptrToConst,
const int *const constPtrToConst; //identical to: int const *const constPtrToConst

हालाँकि C/C++ ऐसी परिलैंग्वेजेज की अनुमति देता है (जो परिलैंग्वेजेज को बाएं से दाएं पढ़ते समय अंग्रेजी लैंग्वेज से काफी मेल खाती हैं), कंपाइलर अभी भी उपरोक्त प्रक्रिया के अनुसार परिलैंग्वेजेज को पढ़ता है: दाएं से बाएं। लेकिन डाल रहा हूँ const इससे पहले कि क्या स्थिर होना चाहिए, आप जो लिखना चाहते हैं और कंपाइलर जो तय करता है कि आपने क्या लिखा है, के बीच बेमेल का परिचय देता है। पॉइंटर्स से पॉइंटर्स पर विचार करें:

int **ptr;            // a pointer to a pointer to ints
int const **ptr       // a pointer to a pointer to constant int value
                      // (not a pointer to a constant pointer to ints)
int *const *ptr       // a pointer to a const pointer to int values
                      // (not a constant pointer to a pointer to ints)
int **const ptr       // a constant pointer to pointers to ints
                      // (ptr, the identifier, being const makes no sense)
int const **const ptr // a constant pointer to pointers to constant int values

सूचक परिलैंग्वेजेज के संबंध में अंतिम नोट के रूप में: सूचक प्रतीक (*) को सदैव यथासंभव दाईं ओर लिखें। सूचक प्रतीक को प्रकार से जोड़ना मुश्किल है, क्योंकि यह दृढ़ता से एक सूचक प्रकार का सुझाव देता है, जो कि मामला नहीं है। यहां कुछ उदाहरण दिए गए हैं:

int* a;          /* write: */     int *a;    // a is a pointer to an int
int* a, b;       // CONFUSING 
                 /* write: */     int *a, b; // a is a pointer to an int, 
                 //                             but b is a mere int
int* a, *b;      // UGLY: both a and b are pointers to ints
                 /* write: */     int *a, *b;

इस समस्या से बचने के लिए, Bjarne Stroustrup के FAQ में C++ कन्वेंशन का उपयोग करते समय प्रति पंक्ति केवल एक वेरिएबल घोषित करने की अनुशंसा की गई है।[10] संदर्भों और प्रतिद्वंद्विता संदर्भों को परिभाषित करने पर भी यही विचार लागू होते हैं:

int var = 22;
int const &refToConst = var;         // OK
int const& ref2 = var, ref3 = var;   // CONFUSING:
                                     // ref2 is a reference, but ref3 isn't:
                                     // ref3 is a constant int initialized with
                                     // var's value
int &const constRef = var;           // ERROR: as references can't change anyway.

// C++:
int&& rref = int(5), value = 10;     // CONFUSING:
                                     // rref is an rvalue reference, but value is
                                     // a mere int. 
                                     /* write: */ int &&rref = int(5), value = 10;

पॉइंटर्स के लिए बहुआयामी सरणियों और संदर्भों (या पॉइंटर्स) का उपयोग करते समय अधिक जटिल घोषणाएँ सामने आती हैं। हालाँकि कभी-कभी इस पर बहस भी होती है[who?] कि ऐसी घोषणाएँ भ्रामक और त्रुटि-प्रवण हैं और इसलिए उन्हें टाला जाना चाहिए या उच्च-स्तरीय संरचनाओं द्वारा प्रतिस्थापित किया जाना चाहिए, इस खंड के शीर्ष पर वर्णित प्रक्रिया का उपयोग सदैव अस्पष्टता या भ्रम पैदा किए बिना किया जा सकता है।

पैरामीटर और चर

const फ़ंक्शन पैरामीटर और वेरिएबल (वैश्विक या स्थानीय सहित स्थिर चर या स्वचालित) दोनों पर घोषित किया जा सकता है। उपयोग के बीच व्याख्या भिन्न-भिन्न होती है। ए const स्थिर चर (वैश्विक चर या स्थिर स्थानीय चर) एक स्थिरांक है, और इसका उपयोग गणितीय स्थिरांक जैसे डेटा के लिए किया जा सकता है, जैसे double const PI = 3.14159 - वास्तविक रूप से लंबा, या समग्र संकलन-समय पैरामीटर। a const स्वचालित चर (गैर स्थैतिक स्थानीय चर) का अर्थ है कि एकल असाइनमेंट हो रहा है, हालांकि हर बार एक अलग मान का उपयोग किया जा सकता है, जैसे कि int const x_squared = x * x. ए const पास-बाय-रेफरेंस में पैरामीटर का अर्थ है कि संदर्भित मूल्य संशोधित नहीं है - यह अनुबंध द्वारा डिजाइन का हिस्सा है - जबकि ए const पास-बाय-वैल्यू में पैरामीटर (या पॉइंटर स्वयं, पास-बाय-रेफरेंस में) इंटरफ़ेस में कुछ भी नहीं जोड़ता है (जैसा कि मान कॉपी किया गया है), लेकिन इंगित करता है कि आंतरिक रूप से, फ़ंक्शन पैरामीटर की स्थानीय प्रतिलिपि को संशोधित नहीं करता है (यह एक एकल असाइनमेंट है)। इस कारण से, कुछ लोग इसका उपयोग करने के पक्ष में हैं const केवल पास-बाय-रेफरेंस के लिए पैरामीटर में, जहां यह अनुबंध बदलता है, लेकिन पास-बाय-वैल्यू के लिए नहीं, जहां यह कार्यान्वयन को उजागर करता है।

C++

विधियाँ

उपयोगकर्ता-परिभाषित प्रकारों (संरचनाओं और वर्गों) के लिए डिज़ाइन-दर-अनुबंध दृष्टिकोण का लाभ उठाने के लिए, जिसमें विधियों के साथ-साथ सदस्य डेटा भी हो सकता है, प्रोग्रामर उदाहरण विधियों को const के रूप में टैग कर सकता है यदि वे ऑब्जेक्ट को संशोधित नहीं करते हैं डेटा सदस्य. इस प्रकार इंस्टेंस विधियों में const क्वालिफायर लागू करना कॉन्स्ट-शुद्धता के लिए एक आवश्यक सुविधा है और कई अन्य ऑब्जेक्ट-ओरिएंटेड भाषाओं जैसे जावा (प्रोग्रामिंग लैंग्वेज) और सी# या माइक्रोसॉफ्ट के C++/सीएलआई या C++ के लिए प्रबंधित एक्सटेंशन में उपलब्ध नहीं है।


जबकि const विधियों को कॉल किया जा सकता है const और गैर-const वस्तुएं समान, गैर-const विधियों को केवल गैर द्वारा ही लागू किया जा सकता है-const वस्तुएं. const ई> इंस्टेंस विधि पर संशोधक द्वारा इंगित ऑब्जेक्ट पर लागू होता हैthisसूचक, जो सभी उदाहरण विधियों को पारित एक अंतर्निहित तर्क है। इस प्रकार होना const पद्धतियाँ निहितार्थ पर स्थिरांक-शुद्धता लागू करने का एक तरीका हैthisअन्य तर्कों की तरह ही सूचक तर्क।

यह उदाहरण दर्शाता है:

class C
{
    int i;
public:
    int Get() const // Note the "const" tag
      { return i; }
    void Set(int j) // Note the lack of "const"
      { i = j; }
};

void Foo(C& nonConstC, C const& constC)
{
    int y = nonConstC.Get(); // Ok
    int x = constC.Get();    // Ok: Get() is const

    nonConstC.Set(10); // Ok: nonConstC is modifiable
    constC.Set(10);    // Error! Set() is a non-const method and constC is a const-qualified object
}

उपरोक्त कोड में, अन्तर्निहितthisकी ओर सूचक Set() प्रकार हैC *const; जहांकिthisकी ओर सूचक Get() प्रकार हैC const *const, यह दर्शाता है कि विधि इसके माध्यम से अपनी वस्तु को संशोधित नहीं कर सकती हैthisसूचक.

प्रायः प्रोग्रामर दोनों की आपूर्ति करेगा const और एक गैर-const दोनों प्रकार के कॉलर्स को समायोजित करने के लिए एक कक्षा में एक ही नाम (लेकिन संभवतः काफी भिन्न उपयोग) वाली विधि है। विचार करना:

class MyArray
{
    int data[100];
public:
    int &       Get(int i)       { return data[i]; }
    int const & Get(int i) const { return data[i]; }
};

void Foo( MyArray & array, MyArray const & constArray )
{
    // Get a reference to an array element
    // and modify its referenced value.

    array.Get( 5 )      = 42; // OK! (Calls: int & MyArray::Get(int))
    constArray.Get( 5 ) = 42; // Error! (Calls: int const & MyArray::Get(int) const)
}

constde>-कॉलिंग ऑब्जेक्ट की प्रकृति यह निर्धारित करती है कि कौन सा संस्करण है MyArray::Get() लागू किया जाएगा और इस प्रकार कॉल करने वाले को एक संदर्भ दिया गया है या नहीं जिसके साथ वह हेरफेर कर सकता है या केवल ऑब्जेक्ट में निजी डेटा का निरीक्षण कर सकता है।

दोनों विधियों में तकनीकी रूप से अलग-अलग हस्ताक्षर हैं क्योंकि उनकाthisपॉइंटर्स के विभिन्न प्रकार होते हैं, जिससे कंपाइलर को सही पॉइंटर्स चुनने की अनुमति मिलती है। (लौटते हुए ए const एक का संदर्भ int, केवल वापस करने के बजाय int मूल्य के अनुसार, दूसरी विधि में अधिकता हो सकती है, लेकिन उसी तकनीक का उपयोग मनमाने प्रकारों के लिए किया जा सकता है, जैसा कि मानक टेम्पलेट लाइब्रेरी में होता है।)

स्थिरांक-शुद्धता में खामियां

C और C++ में शुद्ध स्थिरांक-शुद्धता में कई खामियां हैं। वे मुख्य रूप से उपस्थिता कोड के साथ अनुकूलता के लिए उपस्थित हैं।

पहला, जो केवल C++ पर लागू होता है, का उपयोग है const_cast, जो प्रोग्रामर को स्ट्रिप करने की अनुमति देता है const क्वालीफायर, किसी भी वस्तु को परिवर्तनीय बनाना है।

उपस्थिता कोड और लाइब्रेरीज़ का उपयोग करते समय क्वालीफायर को अलग करने की आवश्यकता उत्पन्न होती है जिन्हें संशोधित नहीं किया जा सकता है लेकिन जो स्थिर-सही नहीं हैं। उदाहरण के लिए, इस कोड पर विचार करें:

// Prototype for a function which we cannot change but which
// we know does not modify the pointee passed in.
void LibraryFunc(int* ptr, int size);

void CallLibraryFunc(int const * ptr, int size)
{
    LibraryFunc(ptr, size); // Error! Drops const qualifier

    int* nonConstPtr = const_cast<int*>(ptr); // Strip qualifier
    LibraryFunc(nonConstPtr, size);  // OK
}

हालाँकि, किसी ऑब्जेक्ट को संशोधित करने का कोई भी प्रयास जो स्वयं घोषित हो const आईएसओ C++ मानक के अनुसार कास्ट कास्ट के परिणामस्वरूप अपरिभाषित व्यवहार होता है।

उपरोक्त उदाहरण में, यदि ptr घोषित वैश्विक, स्थानीय या सदस्य चर का संदर्भ देता है const, या ढेर पर आवंटित एक वस्तु new int const, कोड केवल तभी सही है यदि LibraryFunc वास्तव में द्वारा बताए गए मान को संशोधित नहीं करता है ptr.

सी लैंग्वेज में एक खामी की आवश्यकता है क्योंकि एक निश्चित स्थिति उपस्थित है। स्थिर भंडारण अवधि वाले चर को प्रारंभिक मान के साथ परिभाषित करने की अनुमति है। हालाँकि, इनिशियलाइज़र केवल स्ट्रिंग स्थिरांक और अन्य शाब्दिक जैसे स्थिरांक का उपयोग कर सकता है, और चर नाम जैसे गैर-स्थिर तत्वों का उपयोग करने की अनुमति नहीं है, चाहे इनिशियलाइज़र तत्व घोषित किए गए हों const या नहीं, या स्थैतिक अवधि चर घोषित किया जा रहा है या नहीं const या नहीं। आरंभ करने का एक गैर-पोर्टेबल तरीका है const वैरिएबल जिसमें स्थिर भंडारण अवधि होती है। बाद के असाइनमेंट के बाईं ओर सावधानीपूर्वक टाइपकास्ट का निर्माण करके, a const वैरिएबल को प्रभावी ढंग से हटाकर लिखा जा सकता है const विशेषता और इसे अन्य की तरह गैर-स्थिर तत्वों के साथ 'प्रारंभ' करना const चर और ऐसे। ए में लिखना const परिवर्तनीय इस तरह से इरादा के अनुसार काम कर सकता है, लेकिन यह अपरिभाषित व्यवहार का कारण बनता है और गंभीरता से स्थिरांक-शुद्धता का खंडन करता है:

size_t const    bufferSize = 8*1024;
size_t const    userTextBufferSize;  //initial value depends on const bufferSize, can't be initialized here

...

int setupUserTextBox(textBox_t *defaultTextBoxType, rect_t *defaultTextBoxLocation)
{
    *(size_t*)&userTextBufferSize = bufferSize - sizeof(struct textBoxControls);  // warning: might work, but not guaranteed by C
    ...
}

एक और खामी[11] C और C++ दोनों पर लागू होता है। विशेष रूप से, लैंग्वेजएँ निर्देश देती हैं कि सदस्य सूचक और संदर्भ इसके संबंध में उथले हैं const-उनके स्वामियों की प्रकृति - अर्थात, एक युक्त वस्तु है const सब कुछ है const सदस्य पॉइंटी (और रेफरी) को छोड़कर अन्य सदस्य अभी भी परिवर्तनशील हैं। स्पष्ट करने के लिए, इस C++ कोड पर विचार करें:

struct S
{
    int val;
    int *ptr;
};

void Foo(S const & s)
{
    int i  = 42;
    s.val  = i;  // Error: s is const, so val is a const int
    s.ptr  = &i; // Error: s is const, so ptr is a const pointer to int
    *s.ptr = i;  // OK: the data pointed to by ptr is always mutable,
                 //     even though this is sometimes not desirable
}

यद्यपि वस्तु s पास किया Foo() स्थिर है, जो इसके सभी सदस्यों को स्थिर बनाता है, पॉइंटी तक पहुंच योग्य है s.ptr अभी भी परिवर्तनीय है, हालाँकि यह दृष्टिकोण से वांछनीय नहीं हो सकता है const-शुद्धता क्योंकि s केवल पॉइंटी का स्वामी हो सकता है। इस कारण से, मेयर्स का तर्क है कि सदस्य संकेतकों और संदर्भों के लिए डिफ़ॉल्ट गहरा होना चाहिए const-नेस, जिसे a द्वारा ओवरराइड किया जा सकता है mutable क्वालीफायर जब पॉइंटी कंटेनर के स्वामित्व में नहीं होता है, लेकिन यह रणनीति उपस्थिता कोड के साथ संगतता समस्याएं पैदा करेगी। इस प्रकार, ऐतिहासिक कारणों से, यह खामी C और C++ में खुली रहती है।

बाद वाले लूपहोल को पॉइंटर को a के पीछे छिपाने के लिए क्लास का उपयोग करके बंद किया जा सकता है const-सही इंटरफ़ेस, लेकिन ऐसी कक्षाएं या तो सामान्य प्रतिलिपि शब्दार्थ का समर्थन नहीं करती हैं const ऑब्जेक्ट (जिसका अर्थ है कि युक्त वर्ग को सामान्य शब्दार्थ द्वारा कॉपी नहीं किया जा सकता है) या स्ट्रिपिंग की अनुमति देकर अन्य खामियों की अनुमति दें const-असावधानीपूर्वक या जानबूझकर नकल के माध्यम से।

अंत में, C मानक लाइब्रेरी में कई फ़ंक्शन C23 (C मानक संशोधन) से पहले स्थिरांक-शुद्धता का उल्लंघन करते हैं, क्योंकि वे a स्वीकार करते हैं const एक वर्ण स्ट्रिंग पर सूचक और एक गैर लौटाएँ-const एक ही स्ट्रिंग के एक भाग के लिए सूचक. strstr और strchr इन कार्यों में से हैं। C++ मानक लाइब्रेरी के कुछ कार्यान्वयन, जैसे कि Microsoft[12] कुछ फ़ंक्शंस के दो फ़ंक्शन ओवरलोडिंग संस्करण प्रदान करके इस खामी को बंद करने का प्रयास करें: aconstसंस्करण और एक गैर-constसंस्करण।

समस्याएँ

स्थिरता को व्यक्त करने के लिए टाइप सिस्टम का उपयोग विभिन्न जटिलताओं और समस्याओं को जन्म देता है, और तदनुसार इसकी आलोचना की गई है और C, C++ और D के संकीर्ण सी परिवार के बाहर इसे नहीं अपनाया गया है। जावा और C, जो C और C++ से काफी प्रभावित हैं, दोनों को स्पष्ट रूप से खारिज कर दिया गया है। const-स्टाइल प्रकार क्वालीफायर, इसके बजाय पहचानकर्ता पर लागू होने वाले कीवर्ड द्वारा स्थिरता व्यक्त करते हैं (final जावा में, const और readonly C# में)। यहां तक ​​कि C और C++ के भीतर भी, का उपयोग const काफी भिन्न होता है, कुछ परियोजनाएँ और संगठन इसका लगातार उपयोग करते हैं, और अन्य इससे बचते हैं।

strchr समस्या

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

यह समस्या विशेष रूप से सी मानक लाइब्रेरी में सरल कार्यों के लिए भी उत्पन्न होती है strchr; इस अवलोकन का श्रेय 1980 के दशक के मध्य में रिची द्वारा टॉम प्लम को दिया गया है।[13] strchr e> फ़ंक्शन स्ट्रिंग में एक वर्ण का पता लगाता है; औपचारिक रूप से, यह चरित्र की पहली घटना के लिए एक सूचक लौटाता है c स्ट्रिंग में s, और क्लासिक सी (के एंड आर सी) में इसका प्रोटोटाइप है:

char *strchr(char *s, int c);
strchr e> फ़ंक्शन इनपुट स्ट्रिंग को संशोधित नहीं करता है, लेकिन रिटर्न वैल्यू का उपयोग प्रायः कॉलर द्वारा स्ट्रिंग को संशोधित करने के लिए किया जाता है, जैसे:
if (p = strchr(q, '/'))
    *p = ' ';

इस प्रकार एक ओर इनपुट स्ट्रिंग हो सकती है const (चूंकि यह फ़ंक्शन द्वारा संशोधित नहीं है), और यदि इनपुट स्ट्रिंग है const रिटर्न वैल्यू भी उतनी ही होनी चाहिए - सबसे सरल इसलिए क्योंकि यह बिल्कुल इनपुट पॉइंटर लौटा सकता है, यदि पहला अक्षर मेल खाता है - लेकिन दूसरी ओर रिटर्न वैल्यू नहीं होनी चाहिए const यदि मूल स्ट्रिंग नहीं थी const, क्योंकि कॉल करने वाला मूल स्ट्रिंग को संशोधित करने के लिए पॉइंटर का उपयोग करना चाह सकता है।

C++ में यह फ़ंक्शन ओवरलोडिंग के माध्यम से किया जाता है, साधारणतया एक टेम्पलेट (C++)C++) के माध्यम से कार्यान्वित किया जाता है, जिसके परिणामस्वरूप दो फ़ंक्शन होते हैं, ताकि रिटर्न मान समान हो const-इनपुट के रूप में योग्य प्रकार:[lower-alpha 2]

char* strchr(char* s, int c);
char const* strchr(char const* s, int c);

इन्हें बदले में एक टेम्पलेट द्वारा परिभाषित किया जा सकता है:

template <T>
T* strchr(T* s, int c) { ... }

D में इसे इसके माध्यम से नियंत्रित किया जाता है inout कीवर्ड, जो स्थिरांक, अपरिवर्तनीय, या अयोग्य (परिवर्तनीय) के लिए वाइल्डकार्ड के रूप में कार्य करता है, उपज:[14][lower-alpha 3]

inout(char)* strchr(inout(char)* s, int c);

हालाँकि, C में इनमें से कुछ भी संभव नहीं है क्योंकि C में फ़ंक्शन ओवरलोडिंग नहीं है, और इसके बजाय, इसे एक एकल फ़ंक्शन द्वारा नियंत्रित किया जाता है जहां इनपुट स्थिर है लेकिन आउटपुट लिखने योग्य है:

char *strchr(char const *s, int c);

यह मुहावरेदार सी कोड की अनुमति देता है लेकिन यदि इनपुट वास्तव में कॉन्स्ट-योग्य था, तो प्रकार की सुरक्षा का उल्लंघन करते हुए कॉन्स्ट क्वालिफायर को हटा देता है। यह समाधान रिची द्वारा प्रस्तावित किया गया था और बाद में इसे अपनाया गया। यह अंतर C और C++ की अनुकूलता की विफलताओं में से एक है।

C23 (C मानक संशोधन) के बाद से, इस समस्या को सामान्य कार्यों के उपयोग से हल किया जाता है। strchr और समस्या से प्रभावित अन्य कार्य वापस आ जाएंगे const यदि कोई उन्हें पास कर दिया गया है तो सूचक और यदि कोई अयोग्य सूचक उन्हें पास कर दिया गया है तो एक अयोग्य सूचक।[15]

D

के संस्करण 2 में, const से संबंधित दो कीवर्ड उपस्थित हैं।[16] immutable e> कीवर्ड उस डेटा को दर्शाता है जिसे किसी भी संदर्भ के माध्यम से संशोधित नहीं किया जा सकता है। const e> कीवर्ड परिवर्तनशील डेटा के गैर-परिवर्तनीय दृश्य को दर्शाता है। C++ के विपरीत const, D const और immutable गहरे हैं या, और किसी भी चीज़ तक पहुंच योग्य है const या immutable वस्तु है const या immutable क्रमश।

D में स्थिरांक बनाम अपरिवर्तनीय का उदाहरण

int[] foo = new int[5];  // foo is mutable.
const int[] bar = foo;   // bar is a const view of mutable data.
immutable int[] baz = foo;  // Error:  all views of immutable data must be immutable.

immutable int[] nums = new immutable(int)[5];  // No mutable reference to nums may be created.
const int[] constNums = nums;  // Works.  immutable is implicitly convertible to const.
int[] mutableNums = nums;  // Error:  Cannot create a mutable view of immutable data.

D में सकर्मक या गहरे स्थिरांक का उदाहरण

class Foo {
    Foo next;
    int num;
}

immutable Foo foo = new immutable(Foo);
foo.next.num = 5;  // Won't compile.  foo.next is of type immutable(Foo).
                   // foo.next.num is of type immutable(int).

इतिहास

const 1981 में Bjarne Stroustrup द्वारा C में क्लासेस, C++ के पूर्ववर्ती के साथ पेश किया गया था, और इसे मूल रूप से कहा जाता था readonly.[17][18] प्रेरणा के संबंध में स्ट्रॉस्ट्रुप लिखते हैं:[18]: इसने दो कार्य किए: एक प्रतीकात्मक स्थिरांक को परिभाषित करने के एक तरीके के रूप में जो दायरे और प्रकार के नियमों का पालन करता है (अर्थात, मैक्रो का उपयोग किए बिना) और मेमोरी में किसी वस्तु को अपरिवर्तनीय मानने के एक तरीके के रूप में। मैक्रोज़ के स्कोप्ड और टाइप किए गए विकल्प के रूप में पहला उपयोग, फ़ंक्शन-जैसे मैक्रोज़ के लिए समान रूप से पूरा किया गया था inline कीवर्ड. लगातार संकेत, और * const डेनिस रिची द्वारा संकेतन का सुझाव दिया गया था और इसलिए इसे अपनाया गया।[18]

const फिर मानकीकरण के हिस्से के रूप में सी में अपनाया गया, और अन्य प्रकार के क्वालीफायर के साथ एएनएसआई सी (और बाद के संस्करणों) में दिखाई देता है, volatile.[19] एक और क्वालिफायर, noalias, X3J11 समिति की दिसंबर 1987 की बैठक में सुझाव दिया गया था, लेकिन इसे अस्वीकार कर दिया गया था; इसका लक्ष्य अंततः पूरा हुआ restrict C99 में कीवर्ड. रिची इन परिवर्धनों का बहुत अधिक समर्थन नहीं करते थे, उनका तर्क था कि वे अपना महत्व नहीं रखते हैं, लेकिन अंततः मानक से उन्हें हटाने के लिए तर्क नहीं दिया।[20] D बाद में विरासत में मिला const C++ से, जहां इसे टाइप कंस्ट्रक्टर (टाइप क्वालिफायर नहीं) के रूप में जाना जाता है और इसमें दो और टाइप कंस्ट्रक्टर जोड़े गए हैं, immutable और inout, संबंधित उपयोग के मामलों को संभालने के लिए।[lower-alpha 4]

अन्य लैंग्वेजएँ

अन्य लैंग्वेजएँ प्रकार के निरंतरता भाग में C/C++ का अनुसरण नहीं करती हैं, हालाँकि उनमें प्रायः सतही रूप से समान संरचनाएँ होती हैं और वे इसका उपयोग कर सकती हैं const कीवर्ड. साधारणतया इसका उपयोग केवल स्थिरांक (स्थिर वस्तुओं) के लिए किया जाता है।

C# में एक है const कीवर्ड, लेकिन मौलिक रूप से भिन्न और सरल शब्दार्थ के साथ: इसका अर्थ एक संकलन-समय स्थिरांक है, और यह प्रकार का हिस्सा नहीं है।

निम (प्रोग्रामिंग लैंग्वेज) में एक है const C# के समान कीवर्ड: यह प्रकार का हिस्सा बनने के बजाय एक संकलन-समय स्थिरांक भी घोषित करता है। हालाँकि, निम में, किसी भी अभिव्यक्ति से एक स्थिरांक घोषित किया जा सकता है जिसका संकलन समय पर मूल्यांकन किया जा सकता है।[21] C# में, केवल C# अंतर्निर्मित प्रकारों को ही घोषित किया जा सकता है const; कक्षाओं, संरचनाओं और सरणियों सहित उपयोगकर्ता-परिभाषित प्रकार नहीं हो सकते const.[22]

जावा के पास नहीं है const - इसके बजाय यह है final, जिसे स्थानीय चर कन्वेंशन पर लागू किया जा सकता है और पहचानकर्ता पर लागू होता है, प्रकार पर नहीं। ऑब्जेक्ट सदस्यों के लिए इसका एक अलग ऑब्जेक्ट-ओरिएंटेड उपयोग है, जो नाम की उत्पत्ति है।

जावा लैंग्वेज विशिष्टता का संबंध है const एक आरक्षित कीवर्ड के रूप में - यानी, जिसे परिवर्तनीय पहचानकर्ता के रूप में उपयोग नहीं किया जा सकता है - लेकिन इसमें कोई शब्दार्थ नहीं दिया गया है: यह एक आरक्षित शब्द है (इसे पहचानकर्ताओं में उपयोग नहीं किया जा सकता है) लेकिन एक कीवर्ड नहीं है (इसका कोई विशेष अर्थ नहीं है)। ऐसा माना जाता है कि कीवर्ड का आरक्षण C++-शैली को सम्मिलित करने के लिए जावा लैंग्वेज के विस्तार की अनुमति देने के लिए हुआ const तरीके और सूचक const प्रकार। कार्यान्वयन के लिए एक एन्हांसमेंट अनुरोध टिकट const जावा सामुदायिक प्रक्रिया में शुद्धता उपस्थित है, लेकिन 2005 में इसे इस आधार पर बंद कर दिया गया था कि इसे बैकवर्ड-संगत तरीके से लागू करना असंभव था।[23]समकालीन एडा 83 में स्वतंत्र रूप से एक स्थिर वस्तु और एक की धारणा थी constant कीवर्ड,[24][lower-alpha 5] इनपुट पैरामीटर और लूप पैरामीटर पूरी तरह से स्थिर हैं। यहां ही constant वस्तु का गुण है, प्रकार का नहीं।

जावास्क्रिप्ट में एक है const घोषणा जो एक ब्लॉक-स्कोप्ड वैरिएबल को परिभाषित करती है जिसे पुन: असाइन नहीं किया जा सकता है और न ही पुनः घोषित किया जा सकता है। यह एक वेरिएबल के लिए केवल पढ़ने योग्य संदर्भ को परिभाषित करता है जिसे दोबारा परिभाषित नहीं किया जा सकता है, लेकिन कुछ स्थितियों में वेरिएबल का मान संभावित रूप से बदल सकता है, जैसे कि यदि वेरिएबल किसी ऑब्जेक्ट को संदर्भित करता है और इसकी एक संपत्ति बदल जाती है।[25]

यह भी देखें

टिप्पणियाँ

  1. Formally when the const is part of the outermost derived type in a declaration; pointers complicate discussion.
  2. Note that pointer declaration syntax conventions differ between C and C++: in C char *s is standard, while in C++ char* s is standard.
  3. Idiomatic D code would use an array here instead of a pointer.[14]
  4. D also introduced the shared type constructor, but this is related to use cases of volatile, not const.
  5. The Ada standard calls this a "reserved word"; see that article for usage.

संदर्भ

  1. "लगातार वस्तुएँ - जंग संदर्भ". doc.rust-lang.org. Retrieved 2022-06-22.
  2. "The this pointer". Draft C++ Standard. Retrieved 2020-03-30. The type of this in a member function whose type has a cv-qualifier-seq cv and whose class is X is "pointer to cv X".
  3. Herb Sutter and Andrei Alexandrescu (2005). C++ Coding Standards. p. 30. Boston: Addison Wesley. ISBN 0-321-11358-6
  4. "Why is the kfree() argument const?". lkml.org. 2013-01-12.
  5. "5.1. Extensions implemented in GNU Fortran: 5.1.16 Cray pointers". जीएनयू फोरट्रान कंपाइलर. 2006. Archived from the original on 2022-12-21. Retrieved 2022-12-21.
  6. Fahey, Mark R.; Nagle, Dan (1999-04-19). "Cray Fortran Pointers vs. Fortran 90 Pointers and Porting from the Cray C90 to the SGI Origin2000" (PDF). Vicksburg, Massachusetts, USA: US Army Corps of Engineers Waterways Experiment Station, Major Shared Resource Center. Archived (PDF) from the original on 2022-12-23. Retrieved 2022-12-23. (8 pages)
  7. "Appendix C: Fortran 90 Features and Differences > Features > Cray Pointers". Fortran User's Guide. Oracle Corporation. 2010. Archived from the original on 2021-09-21. Retrieved 2022-12-23.
  8. "Appendix C: Fortran 90 Features and Differences > Features > Cray Character Pointers". Fortran User's Guide. Oracle Corporation. 2010. Archived from the original on 2021-09-21. Retrieved 2022-12-23. {{cite web}}: |archive-date= / |archive-url= timestamp mismatch (help)
  9. "Chapter 4. Data Types". फोरट्रान भाषा संदर्भ मैनुअल, खंड 1. Vol. 1. Silicon Graphics, Inc. 1999 [1993]. Document Number: 007-3692-004. Archived from the original on 2022-12-23. Retrieved 2022-12-23. (NB. Derived from "FORTRAN 90 HANDBOOK" (1992, McGraw-Hill, Inc.) by Walter S. Brainerd, Jeanne C. Adams, Jeanne T. Martin, Brian T. Smith, and Jerrold L. Wagener.)
  10. "Stroustrup: C++ Style and Technique FAQ".
  11. Scott Meyers (2005). Effective C++, Third Edition. pp. 21-23. Boston: Addison Wesley. ISBN 978-0-321-33487-9
  12. "strchr, wcschr, _mbschr (CRT)". Msdn.microsoft.com. Retrieved 2017-11-23.
  13. "Dennis Ritchie: Why I do not like X3J11 type qualifiers".
  14. 14.0 14.1 डी प्रोग्रामिंग लैंग्वेज, आंद्रेई अलेक्जेंड्रेस्कु, 8.8: एक क्वालीफायर को पैरामीटर से परिणाम तक प्रचारित करना
  15. "WG14-N3020 : Qualifier-preserving standard library functions" (PDF). open-std.org. 2022-06-13. Archived (PDF) from the original on October 13, 2022.
  16. "const(FAQ) – D Programming Language". Digitalmars.com. Retrieved 2013-08-18.
  17. Bjarne Stroustrup, "Extensions of the C Language Type Concept.", Bell Labs internal Technical Memorandum, January 5, 1981.
  18. 18.0 18.1 18.2 Sibling Rivalry: C and C++, Bjarne Stroustrup, 2002, p. 5
  19. Dennis M. Ritchie, "The Development of the C Language Archived July 15, 2012, at archive.today", 2003: "X3J11 also introduced a host of smaller additions and adjustments, for example, the type qualifiers const and volatile, and slightly different type promotion rules."
  20. "Let me begin by saying that I'm not convinced that even the pre-December qualifiers ('const' and 'volatile') carry their weight; I suspect that what they add to the cost of learning and using the language is not repaid in greater expressiveness. 'Volatile', in particular, is a frill for esoteric applications, and much better expressed by other means. Its chief virtue is that nearly everyone can forget about it. 'Const' is simultaneously more useful and more obtrusive; you can't avoid learning about it, because of its presence in the library interface. Nevertheless, I don't argue for the extirpation of qualifiers, if only because it is too late."
  21. Nim Manual: Const section
  22. const (C# Reference)
  23. "Bug ID: JDK-4211070 Java should support const parameters (like C++) for code maintainence [sic]". Bugs.sun.com. Retrieved 2014-11-04.
  24. 1815A[dead link], 3.2.1. Object Declarations Archived October 20, 2014, at the Wayback Machine:
    "The declared object is a constant if the reserved word constant appears in the object declaration; the declaration must then include an explicit initialization. The value of a constant cannot be modified after initialization. Formal parameters of mode in of subprograms and entries, and generic formal parameters of mode in, are also constants; a loop parameter is a constant within the corresponding loop; a subcomponent or slice of a constant is a constant."
  25. "कॉन्स्ट". MDN. Retrieved 31 October 2017.

बाहरी संबंध