जवाबों:
एक अपरिवर्तनीय एक चर की तुलना में अधिक "वैचारिक" है। सामान्य तौर पर, यह प्रोग्राम स्टेट की एक संपत्ति है जो हमेशा सच होती है। एक फ़ंक्शन या विधि जो यह सुनिश्चित करती है कि अपरिवर्तनीय धारण को कहा जाता है कि वह अपरिवर्तनीय बनाए रखता है।
उदाहरण के लिए, एक द्विआधारी खोज ट्री में अपरिवर्तनीय हो सकता है कि प्रत्येक नोड के लिए, नोड के बाएं बच्चे की कुंजी नोड की अपनी कुंजी से कम है। इस पेड़ के लिए एक सही ढंग से लिखा सम्मिलन फ़ंक्शन उस अपरिवर्तनीय को बनाए रखेगा।
जैसा कि आप बता सकते हैं, यह उस तरह की चीज नहीं है जिसे आप एक चर में स्टोर कर सकते हैं: यह कार्यक्रम के बारे में अधिक विवरण है । यह पता लगाने से कि आपके प्रोग्राम को किस प्रकार के आक्रमणकारियों को बनाए रखना चाहिए, फिर अपने कोड की समीक्षा करके यह सुनिश्चित करें कि यह वास्तव में उन आक्रमणकारियों को बनाए रखता है, आप अपने कोड में तार्किक त्रुटियों से बच सकते हैं।
यह एक ऐसी स्थिति है जिसे आप अपने तर्क में किसी विशेष स्थान पर हमेशा सही होना जानते हैं और यह जांचने के लिए कि कब क्या गलत हो गया है।
मैं आमतौर पर उन्हें एल्गोरिदम या संरचनाओं के संदर्भ में अधिक देखता हूं।
उदाहरण के लिए, आपके पास एक लूप इनवेरिएंट हो सकता है जो मुखर हो सकता है - प्रत्येक पुनरावृत्ति की शुरुआत या अंत में हमेशा सच होता है। यही है, अगर आपके लूप को एक स्टैक से दूसरे में वस्तुओं के संग्रह को संसाधित करना चाहिए था, तो आप कह सकते हैं कि स्टैक 1 | + + | स्टैक 2 | = c, लूप के ऊपर या नीचे।
यदि अशुभ जांच विफल हो गई, तो यह इंगित करेगा कि कुछ गलत हो गया है। इस उदाहरण में, इसका मतलब यह हो सकता है कि आप अंतिम स्टैक आदि पर संसाधित तत्व को आगे बढ़ाना भूल गए।
विकिपीडिया का जादू: आक्रमणकारी (कंप्यूटर विज्ञान)
कंप्यूटर विज्ञान में, एक विधेय, जो कि यदि सही है, संचालन के एक विशिष्ट अनुक्रम में सत्य रहेगा, तो उस अनुक्रम में (a) अपरिवर्तनीय कहा जाता है।
जैसा कि यह पंक्ति बताती है:
कंप्यूटर विज्ञान में, एक विधेय, जो कि यदि सही है, संचालन के एक विशिष्ट अनुक्रम में सत्य रहेगा, तो उस अनुक्रम में (a) अपरिवर्तनीय कहा जाता है।
इस आशा को बेहतर ढंग से समझने के लिए C ++ में यह उदाहरण मदद करता है।
एक परिदृश्य पर विचार करें जहां आपको कुछ मान प्राप्त करने हैं और उनमें से एक के रूप में बुलाया चर में उन्हें कुल संख्या प्राप्त करना है count
और उन्हें चर के रूप में कहा जाता हैsum
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
उपरोक्त के लिए कोड कुछ इस तरह होगा,
int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}
उपरोक्त कोड क्या करता है?
1) इनपुट को पढ़ता है cin
और उन्हें अंदर डालता हैx
2) एक सफल पढ़ने के बाद वेतन वृद्धि count
औरsum = sum + x
3) 1-2 बार दोहराएं जब तक कि स्टॉप न हो जाए (यानी ctrl + D)
अपरिवर्तनीय सच होना चाहिए हमेशा । तो शुरू में आप बस इसी के साथ अपना कोड शुरू करते हैं
while(cin>>x){
}
यह लूप मानक इनपुट से डेटा पढ़ता है और एक्स में स्टोर करता है। सही और उचित। लेकिन आक्रमणकारी झूठा हो जाता है क्योंकि हमारे आक्रमणकारी के पहले भाग का पालन नहीं किया गया (या सच रखा गया)।
// we have read count grades so far, and
सरल! वेतन वृद्धि की गणना।
तो ++count;
अच्छा होगा!। अब हमारा कोड कुछ इस तरह बन जाता है,
while(cin>>x){
++count;
}
अब भी हमारा अपरिवर्तनीय (एक अवधारणा जो TRUE होनी चाहिए) गलत है क्योंकि अब हम अपने अपरिवर्तनीय के दूसरे भाग को संतुष्ट नहीं करते हैं ।
// sum is the sum of the first count grades
तो अब क्या करना है?
जोड़ना x
को sum
और में संग्रहीत sum
( sum+=x
) और अगली बार
cin>>x
एक्स में एक नया मान पढ़ा जाएगा।
अब हमारा कोड कुछ इस तरह बन जाता है,
while(cin>>x){
++count;
sum+=x;
}
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
कोड:
while(cin>>x){
++count;
sum+=x;
}
आह !. अब लूप इनवेरिएंट ट्रू है हमेशा होता है और कोड ठीक काम करता है।
उपरोक्त उदाहरण एंड्रयू-कोनिंग और बारबरा-ई द्वारा त्वरित C ++ पुस्तक से लिया और संशोधित किया गया था
इसके बाद से यह क्या है, क्लीन कोड लिखने में इन्वर्टर काफी उपयोगी होते हैं, क्योंकि वैचारिक रूप से यह जानने के लिए कि आपके कोड में कौन-से इन्वर्टर मौजूद होने चाहिए, आप आसानी से यह तय कर सकते हैं कि उन उद्देश्यों तक पहुँचने के लिए अपने कोड को कैसे व्यवस्थित करें। जैसा कि इलियर ने उल्लेख किया है, वे डिबगिंग में भी उपयोगी हैं, यह देखने के लिए कि क्या अपरिवर्तनीय बनाए रखा जा रहा है, अक्सर यह देखने का एक अच्छा तरीका है कि यदि आप जो भी प्रदर्शन करने का प्रयास कर रहे हैं वह वास्तव में वही कर रहा है जो आप इसे करना चाहते हैं।
यह आमतौर पर एक मात्रा है जो कुछ गणितीय कार्यों के तहत नहीं बदलती है। एक उदाहरण एक अदिश राशि है, जो घूर्णन के तहत नहीं बदलती है। उदाहरण के लिए, चुंबकीय अनुनाद इमेजिंग में, यह एक घूर्णी अपरिवर्तनीय द्वारा ऊतक संपत्ति को चिह्नित करने के लिए उपयोगी है, क्योंकि तब इसका अनुमान आदर्श रूप से स्कैनर में शरीर के उन्मुखीकरण पर निर्भर नहीं करता है।
यह जवाब मेरे 5 साल के बच्चे के लिए है। एक स्थिर या निश्चित संख्यात्मक मान के रूप में एक अपरिवर्तनीय के बारे में मत सोचो। लेकिन यह हो सकता है। हालाँकि, यह उससे कहीं अधिक है।
बल्कि, एक अपरिवर्तनीय अलग-अलग संस्थाओं के बीच एक निश्चित संबंध की तरह है। उदाहरण के लिए, आपकी उम्र हमेशा आपके जैविक माता-पिता की तुलना में कम होगी। आपकी उम्र, और आपके माता-पिता दोनों की उम्र समय बीतने के साथ बदल जाती है, लेकिन जो संबंध मैंने ऊपर बताया है, वह एक आक्रमणकारी है।
एक अपरिवर्तनीय भी एक संख्यात्मक स्थिरांक हो सकता है। उदाहरण के लिए, pi
इसके व्यास पर वृत्त की परिधि के बीच एक अपरिवर्तनीय अनुपात का मान है। सर्कल कितना भी बड़ा या छोटा क्यों न हो, वह अनुपात हमेशा रहेगा pi
।
ADT अपरिवर्तनीय डेटा फ़ील्ड्स (उदाहरण चर) के बीच संबंधों को निर्दिष्ट करता है जो किसी भी इंस्टेंस विधि के निष्पादन से पहले और बाद में हमेशा सही होना चाहिए।
एक अपरिवर्तनीय का एक उत्कृष्ट उदाहरण है और यह पुस्तक जावा कॉनएरेबिलिटी इन प्रैक्टिस में क्यों मायने रखता है ।
हालांकि जावा-केंद्रित, उदाहरण कुछ कोड का वर्णन करता है जो किसी पूर्णांक के कारकों की गणना के लिए जिम्मेदार है। उदाहरण कोड प्रदान की गई अंतिम संख्या को कैश करने का प्रयास करता है, और जिन कारकों को प्रदर्शन में सुधार करने के लिए गणना की गई थी। इस परिदृश्य में एक अपरिवर्तनीय है जिसका उदाहरण कोड में हिसाब नहीं दिया गया था, जिसने एक समवर्ती परिदृश्य में दौड़ की स्थिति के लिए अतिसंवेदनशील कोड छोड़ दिया है।
यहाँ सभी उत्तर बहुत अच्छे हैं, लेकिन मुझे लगा कि मैं इस मामले पर और प्रकाश डाल सकता हूँ:
भाषा के दृष्टिकोण से अपरिवर्तनीय का अर्थ कुछ ऐसा है जो कभी नहीं बदलता है। हालांकि अवधारणा वास्तव में गणित से आती है, यह प्रेरण के साथ संयुक्त होने पर लोकप्रिय प्रमाण तकनीकों में से एक है।
यहाँ बताया गया है कि एक प्रमाण कैसे मिलता है, यदि आप एक ऐसे आक्रमणकारी को खोज सकते हैं जो प्रारंभिक अवस्था में है, और यह कि राज्य के लिए लागू किसी भी [कानूनी] परिवर्तन की परवाह किए बिना जारी रहता है, तो आप यह साबित कर सकते हैं कि यदि एक निश्चित राज्य के पास यह नहीं है अपरिवर्तनीय तब यह कभी भी नहीं हो सकता है, कोई फर्क नहीं पड़ता कि प्रारंभिक अवस्था में परिवर्तनों का क्रम क्या लागू होता है।
अब सोचने का पिछला तरीका (फिर से प्रेरण के साथ संयुक्त) कंप्यूटर सॉफ्टवेयर के तर्क को भविष्यवाणी करना संभव बनाता है। विशेष रूप से महत्वपूर्ण है जब निष्पादन लूप में जाता है, जिसमें एक अपरिवर्तनीय का उपयोग यह साबित करने के लिए किया जा सकता है कि एक निश्चित लूप एक निश्चित परिणाम देगा या यह एक निश्चित तरीके से प्रोग्राम की स्थिति को कभी नहीं बदलेगा।
जब अपरिवर्तनीय का उपयोग एक लूप लॉजिक की भविष्यवाणी करने के लिए किया जाता है, जिसे लूप इनवेरिएंट कहा जाता है । यह छोरों के बाहर इस्तेमाल किया जा सकता है, लेकिन छोरों के लिए यह वास्तव में महत्वपूर्ण है, क्योंकि आपके पास अक्सर बहुत अधिक संभावनाएं होती हैं, या अनंत संभावनाएं होती हैं।
ध्यान दें कि मैं कंप्यूटर सॉफ़्टवेयर के तर्क को "विधेय" शब्द का उपयोग करता हूं, और सिद्ध नहीं करता। और ऐसा इसलिए है क्योंकि गणित अपरिवर्तनीय है को एक प्रमाण के रूप में इस्तेमाल किया जा सकता है, तो यह कभी भी साबित नहीं हो सकता है कि निष्पादित होने पर कंप्यूटर सॉफ़्टवेयर का उत्पादन होगा जो कि अपेक्षित है, इस तथ्य के कारण कि सॉफ्टवेयर कई अमूर्तों के शीर्ष पर निष्पादित होता है, जिसे कभी भी साबित नहीं किया जा सकता है। वे उम्मीद करेंगे कि क्या होगा (उदाहरण के लिए हार्डवेयर अमूर्त के बारे में सोचें)।
अंत में जबकि सैद्धांतिक और कठोरता से सॉफ़्टवेयर लॉजिक की भविष्यवाणी करना केवल मेडिकल, और सैन्य जैसे उच्च महत्वपूर्ण अनुप्रयोगों के लिए महत्वपूर्ण है। डिबगिंग होने पर ठेठ प्रोग्रामर की सहायता के लिए अभी भी इनवेरिएंट का उपयोग किया जा सकता है। इसका उपयोग यह जानने के लिए किया जा सकता है कि एक निश्चित स्थान पर कहाँ कार्यक्रम विफल हो गया क्योंकि यह एक निश्चित अशुद्धि बनाए रखने में विफल रहा है - हम में से बहुत से लोग इसके बारे में एक विचार दिए बिना वैसे भी इसका उपयोग करते हैं।