किसी वैरिएबल को इनिशियलाइज़ करना कितना महत्वपूर्ण है


9

चर को इनिशियलाइज़ करना कितना महत्वपूर्ण है?

क्या मेमोरी को लीक करने से बचना उचित है या प्रदर्शन के फायदे हैं?


14
यह भाषा पर निर्भर करता है। कुछ भाषाओं में बग्स को रोकना बहुत महत्वपूर्ण है, बाकी में यह पठनीयता में मदद करने के लिए केवल एक अच्छी बात है।
तेलस्टिन

आपके इनपुट के लिए धन्यवाद Telastyn। क्या आप ऐसा मामला रख सकते हैं जहाँ यह भाषा के आधार पर महत्वपूर्ण हो जाता है?
विवेक

4
C ++ यहां कुख्यात है। डिबग में, स्थानीय चर nullआम संकलक द्वारा 0 (या ) के लिए प्रारंभ किए जाते हैं, लेकिन रिलीज़ के लिए संकलन करते समय यादृच्छिक कचरा होते हैं। (हालांकि मेरी सी ++ ज्ञान ~ 10 साल पहले से है, अब चीजें बदल सकती हैं)
तेलस्टिन

यह एक बार जलने-दो-बार शर्म करने का मामला है। चूँकि मैंने असिंचित चर, विशेष रूप से संकेत के कारण कीड़े देखे हैं, यह एक आदत बन गई है। प्रदर्शन के लिए, यह आमतौर पर अप्रासंगिक है। मेमोरी लीक के लिए, वास्तव में कोई मुद्दा नहीं है।
माइक डनलवे

1
@Telastyn यह उससे भी बदतर है। अपरिभाषित व्यवहार कचरा राज्य तक सीमित नहीं है, कुछ भी हो सकता है। संकलक यह मान सकता है कि असंक्रमित चर पढ़ने वाले पथ अनुपलब्ध हैं, और रास्ते में होने वाले "असंबंधित" प्रभावों को समाप्त करते हैं।
केलथ

जवाबों:


7

Uninitialized चर एक कार्यक्रम को गैर-नियतात्मक बनाते हैं। हर बार जब कार्यक्रम चलता है, तो यह अलग तरह से व्यवहार कर सकता है। ऑपरेटिंग पर्यावरण के असंबंधित परिवर्तन, दिन का समय, चंद्रमा का चरण और इस तरह के क्रमपरिवर्तन ये डेमोंस कब और कैसे प्रभावित करते हैं। कार्यक्रम दोष प्रस्तुत करने से पहले एक लाख बार चल सकता है, वे इसे हर बार कर सकते हैं, या एक और मिलियन चला सकते हैं। कई समस्याओं को "ग्लिट्स" में डाल दिया जाता है और "अनरेप्रोड्यूसीबल" के रूप में बंद किए गए ग्राहकों की रिपोर्टों को अनदेखा या अनदेखा कर दिया जाता है। किसी समस्या को 'ठीक' करने के लिए आपने कितनी बार मशीन को रिबूट किया है? आपने ग्राहक से कितनी बार कहा है "ऐसा कभी नहीं देखा, मुझे बताएं कि क्या आप इसे फिर से देखते हैं" - उम्मीद (जानते हुए) पूरी तरह से वे नहीं करेंगे!

जैसा कि एक दोष का पुनरुत्पादन परीक्षण के वातावरण में असंभव के बगल में हो सकता है, इसका अगला असंभव खोजने और ठीक करने के लिए असंभव है।

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

शुरुआती चर का एक बड़ा प्रदर्शन लाभ है, न केवल इसलिए कि एक प्रोग्राम जो सही ढंग से काम करता है, वह एक से अधिक तेजी से अनंत है जो नहीं करता है, लेकिन डेवलपर्स कम समय खोजने और दोषों को ठीक करने में खर्च करते हैं जो कि नहीं होना चाहिए और अधिक समय "वास्तविक" काम करना चाहिए।

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

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

संपादित करें: कुछ भाषाओं में (जैसे C #) यह संभव नहीं है कि एकरंजीकृत चर का उपयोग किया जाए, क्योंकि प्रोग्राम संकलित नहीं किया जाएगा, या निष्पादित होने पर एक त्रुटि की रिपोर्ट करेगा। हालाँकि, इन विशेषताओं वाली कई भाषाओं में संभावित रूप से असुरक्षित कोड के लिए इंटरफेस होते हैं, इसलिए ऐसे इंटरफेस का उपयोग करते समय ध्यान रखा जाना चाहिए, जो कि असिंचित चर का परिचय न दें।


6
कई प्रोग्रामिंग भाषाएं स्वचालित रूप से अपने चर को कुछ पूर्वनिर्धारित मूल्य पर सेट करती हैं, इसलिए आप यहां जो कहते हैं, उनमें से अधिकांश उन भाषाओं पर लागू नहीं होते हैं।
रॉबर्ट हार्वे

2
सिर्फ @RobertHarvey ने जो कहा, उसे दोहराना C # पर लागू नहीं होता है। जब आप उन्हें घोषित करते हैं, तो अपने चर को शुरू करने के लिए कोई प्रदर्शन लाभ नहीं होता है, और एक असम्बद्ध चर का उपयोग करना असंभव है, इसलिए आप उस पर अप्रतिबंधित बग को दोष नहीं दे सकते। (यह है एक गैर-आरंभिकृत वर्ग क्षेत्र का उपयोग करना संभव है, लेकिन यह एक डिफ़ॉल्ट मान पर सेट हो जाता है और उस मामले में एक चेतावनी उत्पन्न करता है)
Bobson

4
@mattnz - मुद्दा यह है कि ऐसी भाषाओं के लिए जो C # (या जावा) की तरह व्यवहार करते हैं, इस सलाह में से कुछ भ्रामक या एकमुश्त गलत हैं। एक भाषा अज्ञेय प्रश्न के रूप में, इसमें एक भाषा अज्ञेय प्रतिक्रिया होनी चाहिए, जिसका अर्थ है उन भाषाओं को संबोधित करना जो आरंभिक चर को सुरक्षित रूप से और साथ ही साथ संभाल नहीं करते हैं।
बोबसन

1
मैं यह भी जोड़ना चाहता हूं कि किसी भी आधे सभ्य संकलक / स्थिर विश्लेषक के रूप में असंगठित चर मुद्दे को ढूंढना मुश्किल नहीं है
पीके।

1
जावा (और C # संभवतः) के लिए समय से पहले स्थानीयकरण को अनावश्यक बनाना और यकीनन अधिक बग को जन्म देता है। उदाहरण के लिए, इसे असाइन करने से पहले अशक्त करने के लिए एक चर को सशर्त रूप से सेट करना संकलक की क्षमता को यह बता देता है कि कोड के माध्यम से पथों में से एक चर को असाइन नहीं किया जा सकता है।
जिमीजैम्स

7

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

किसी भी प्रकार का एक चर जिसमें एक अशक्त डिफ़ॉल्ट है, डिफ़ॉल्ट मान संग्रहीत करने के लिए कुछ मेमोरी लेगा।


6

एक गैर-विनिर्मित चर का उपयोग करने की कोशिश करना हमेशा एक बग होता है, इसलिए यह उस बग की संभावना को कम करने के लिए समझ में आता है।

संभवतः समस्या को कम करने के लिए सबसे आम दृष्टिकोण प्रोग्रामिंग भाषाओं को स्वचालित रूप से डिफ़ॉल्ट मान के लिए प्रारंभ करना है, इसलिए कम से कम यदि आप किसी चर को प्रारंभ करना भूल जाते हैं, तो यह कुछ के 0बजाय कुछ ऐसा होगा 0x16615c4b

यह बग का एक बड़ा प्रतिशत हल करता है, अगर आपको किसी भी तरह शून्य से आरंभिक चर की आवश्यकता होती है। हालाँकि, एक वैरिएबल का उपयोग करना जो एक गलत मूल्य पर आरंभीकृत किया गया था, केवल एक का उपयोग करना उतना ही बुरा है जितना कि आरम्भ में इसका उपयोग नहीं किया गया था। वास्तव में, कभी-कभी यह और भी खराब हो सकता है, क्योंकि त्रुटि अधिक सूक्ष्म और पता लगाने में मुश्किल हो सकती है।

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

जहाँ तक प्रदर्शन जाता है, यह शायद नगण्य है। असिंचित चर के साथ सबसे खराब, आपके पास एक अतिरिक्त असाइनमेंट है, और आवश्यकता से अधिक समय के लिए कुछ मेमोरी टाई। अच्छे संकलक बहुत से मामलों में अंतर को अनुकूलित कर सकते हैं।

मेमोरी लीक पूरी तरह से असंबंधित है, हालांकि ठीक से आरंभिक चर कम समय के लिए दायरे में होते हैं, और इसलिए प्रोग्रामर के गलती से लीक होने की संभावना कुछ हद तक कम हो सकती है।


हमेशा? आपका मतलब है कि "हमेशा" के रूप में "कैसे एक निश्चित वैलग्राइंड संदेश ने ओपनएसएसएल को बेकार" " marc.info/?t=114651088900003&r=1&w=2 के आगे प्रदान किया ? " या क्या आप दूसरे का मतलब है, "लगभग हमेशा" एक?
जेन्सजी

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

मुझे बारीकियों में दिलचस्पी होगी। मुझे उन मामलों में संदेह होगा कि चर वास्तव में एकतरफा नहीं हैं, लेकिन घोषित स्थल पर प्रोग्रामर द्वारा सीधे के अलावा एक तरह से आरंभ किया जाता है। या उन्हें कुछ अप्रत्यक्ष साधनों द्वारा नियुक्त किए जाने से पहले नियुक्त किया जाता है।
कार्ल ब्वेलफेल्ट

5

प्रारंभिक मान, प्रारंभिक मूल्य मायने रखता है। यदि प्रारंभिक मूल्य मायने रखता है, तो हाँ, स्पष्ट रूप से आपको यह सुनिश्चित करना चाहिए कि यह आरंभिक है। अगर इससे कोई फर्क नहीं पड़ता है, तो इसका मतलब है कि यह बाद में इनिशियलाइज़ हो जाएगा।

अनावश्यक इनिशियलाइज़ेशन के कारण व्यर्थ सी.पी. हालांकि ये व्यर्थ चक्र कुछ कार्यक्रमों में महत्वपूर्ण नहीं हो सकते हैं, अन्य कार्यक्रमों में, हर एक चक्र महत्वपूर्ण है क्योंकि गति प्राथमिक चिंता का विषय है। इसलिए यह समझना बहुत महत्वपूर्ण है कि किसी के प्रदर्शन के लक्ष्य क्या हैं और यदि चर को शुरू करने की आवश्यकता है या नहीं।

मेमोरी लीक एक पूरी तरह से अलग मुद्दा है जिसमें आम तौर पर मेमोरी आवंटन फ़ंक्शन को जारी करना और बाद में मेमोरी के ब्लॉक को रीसायकल करना शामिल है। एक पोस्ट ऑफिस के बारे में सोचो। तुम जाओ और एक मेलबॉक्स के लिए पूछना। वे आपको एक देते हैं। तुम एक और वर माँग लो। वे आपको एक और देते हैं। नियम यह है कि जब आप एक मेल बॉक्स का उपयोग करके किया जाता है जिसे आपको इसे वापस देने की आवश्यकता होती है। यदि आप इसे वापस देना भूल जाते हैं तो उन्हें लगता है कि आपके पास अभी भी है, और बॉक्स को किसी और द्वारा फिर से उपयोग नहीं किया जा सकता है। तो स्मृति का एक हिस्सा बंधा हुआ है और इसका उपयोग नहीं किया जा रहा है, और इसे ही मेमोरी रिसाव कहा जाता है। यदि आप किसी बिंदु पर बक्से के लिए पूछते रहते हैं तो आप स्मृति से बाहर निकल जाएंगे। मैंने इसकी देखरेख की है, लेकिन यह मूल विचार है।


-1 आप यह परिभाषित कर रहे हैं कि इस संदर्भ में क्या अर्थ है।
पीटर बी।

@ पीटर बी, मुझे आपकी टिप्पणी समझ नहीं आ रही है। कृपया, यदि आप कहें, मैं कैसा हूं, "इस संदर्भ में प्रारंभिककरण का क्या मतलब है" को फिर से परिभाषित करना। धन्यवाद
अण्डाकार दृश्य

आप अपना वाक्य पढ़ें, यह परिपत्र तर्क है: "प्रारंभिक, का अर्थ है कि प्रारंभिक मूल्य मायने रखता है। यदि प्रारंभिक मूल्य मायने रखता है, तो हाँ, स्पष्ट रूप से आपको यह सुनिश्चित करना चाहिए कि इसे आरंभीकृत किया गया है। यदि यह कोई फर्क नहीं पड़ता, तो इसका मतलब है कि यह मिल जाएगा। बाद में आरंभ किया गया। "
पीटर बी

@ पीटर बी, कुछ लोग प्रोग्रामेटिक कारण के बजाय सामान्य नियम के रूप में इनिशियलाइज़ करते हैं, यानी वे इनिशियलाइज़ करते हैं कि इनिशियल वैल्यू मायने रखती है या नहीं। क्या यह OQ का दिल नहीं है: चर को शुरू करना कितना महत्वपूर्ण है? वैसे भी, आप यहाँ से मतदान कर चुके हैं।
अण्डाकार दृश्य

2

जैसा कि दूसरों ने कहा, यह भाषा पर निर्भर करता है। लेकिन मैं चर को इनिशियलाइज़ करने के बारे में अपने जावा (और प्रभावी जावा) विचारों को प्रदर्शित करूँगा। ये कई अन्य उच्च स्तरीय भाषाओं के लिए उपयोग करने योग्य होनी चाहिए।

लगातार और वर्ग चर

कक्षा चर - staticजावा में चिह्नित - स्थिरांक की तरह हैं। इन चर को सामान्य रूप से अंतिम और प्रारंभिक रूप से परिभाषा के बाद =या एक वर्ग इनिलाइज़र ब्लॉक के भीतर से शुरू किया जाना चाहिए static { // initialize here }

खेत

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

nullकिसी प्रकार के झंडे या विशेष मूल्य के रूप में उपयोग करने के आग्रह का विरोध करें । राज्य को रखने के लिए एक विशिष्ट क्षेत्र को शामिल करना बेहतर है। नाम के साथ एक क्षेत्र stateजो एक Stateसंचय के मूल्यों का उपयोग करता है एक अच्छा विकल्प होगा।

विधि पैरामीटर

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

स्थानीय चर

स्थानीय चर स्वचालित रूप से आरंभिक नहीं होते हैं; उनके मूल्य का उपयोग किए जाने से पहले उन्हें आरंभ करने की आवश्यकता है। यह सुनिश्चित करने के लिए एक तरीका है कि आपका चर आरंभिक है, उन्हें सीधे किसी प्रकार के डिफ़ॉल्ट मान के लिए प्रारंभ करना है। हालांकि यह कुछ ऐसा है जो आपको नहीं करना चाहिए । अधिकांश समय डिफ़ॉल्ट मान वह मान नहीं होता जिसकी आप अपेक्षा करते हैं।

केवल चर को ठीक से परिभाषित करना बेहतर है जहां आपको चर की आवश्यकता होती है। यदि चर केवल एक मान लेने के लिए है (जो अच्छे कोड में अधिकांश चर के लिए सच है) तो आप चर को चिह्नित कर सकते हैं final। यह सुनिश्चित करता है कि स्थानीय चर बिल्कुल शून्य या दो बार नहीं, एक बार असाइन किया गया है। एक उदाहरण:

public static doMethod(final int x) {
    final int y; // no assignment yet, it's final so it *must* be assigned
    if (x < 0) {
        y = 0;
    } else if (x > 0) {
        y = x;
    } else {
        // do nothing <- error, y not assigned if x = 0
        // throwing an exception here is acceptable though
    }
}

ध्यान दें कि यदि उपयोग किए जाने से पहले एक चर असमान बना रहता है तो कई भाषाएं आपको चेतावनी देंगी। यदि आप अनावश्यक रूप से चिंता नहीं करते हैं, तो देखने के लिए भाषा विशिष्टताओं और मंचों की जाँच करें।


1

Uninitializing चर के साथ कोई समस्या नहीं है।

समस्या केवल तब होती है जब आप एक चर को पढ़ते हैं जो अभी तक नहीं लिखा गया है।

संकलक और / या चर के प्रकार पर निर्भर करते हुए, एप्लिकेशन स्टार्टअप पर प्रारंभ किया जाता है। या नहीं।

यह स्वचालित उपयोग पर भरोसा नहीं करने के लिए सामान्य उपयोग है।


0

प्रारंभिक चर (स्पष्ट या स्पष्ट रूप से) महत्वपूर्ण है। वैरिएबल को इनिशियलाइज़ नहीं करना हमेशा एक त्रुटि है (इन्हें प्रारंभिक रूप से अनुमानित किया जा सकता है, हालाँकि नीचे देखें)। C # संकलक (उदाहरण के रूप में) जैसे आधुनिक कंपाइलर इसे एक त्रुटि मानते हैं और आपको कोड निष्पादित नहीं करने देंगे। एक uninitialized चर बस बेकार और हानिकारक है। जब तक आप एक यादृच्छिक संख्या जनरेटर नहीं बना रहे हैं, आप एक नियतात्मक और प्रतिलिपि प्रस्तुत करने योग्य परिणाम उत्पन्न करने के लिए कोड के एक टुकड़े से उम्मीद करते हैं। यह केवल तभी प्राप्त किया जा सकता है जब आप आरंभिक चर के साथ काम करना शुरू करते हैं।

वास्तव में दिलचस्प सवाल यह है कि क्या एक चर स्वचालित रूप से आरंभिक है या आपको इसे मैन्युअल रूप से करना है या नहीं। यह प्रयुक्त भाषा पर निर्भर करता है। उदाहरण के लिए, सी #, क्लास स्तर पर "वैरिएबल" अर्थात, हमेशा उस वैरिएबल प्रकार के लिए डिफ़ॉल्ट मान के लिए स्वचालित रूप से आरंभिक किया जाता है default(T)। यह मान सभी जीरो से मिलकर थोड़ा पैटर्न से मेल खाता है। यह भाषा विनिर्देश का हिस्सा है न कि भाषा के कार्यान्वयन का एक तकनीकी विवरण। इसलिए आप सुरक्षित रूप से इस पर भरोसा कर सकते हैं। यह सुरक्षित है कि किसी चर को स्पष्ट रूप से प्रारंभ नहीं किया जा सकता है (और केवल यदि) भाषा विनिर्देश बताता है कि यह प्रारंभिक रूप से अनुमानित है।यदि आप दूसरा मान चाहते हैं, तो आपको चर को स्पष्ट रूप से प्रारंभ करना होगा। तथापि; C # स्थानीय चर में, अर्थात विधियों में घोषित चर, स्वचालित रूप से प्रारंभ नहीं होते हैं और आपको हमेशा चर को स्पष्ट रूप से प्रारंभ करना चाहिए।


2
यह C # विशिष्ट प्रश्न नहीं है।
डगएम

@ डगमग: मुझे पता है। यह C # विशिष्ट उत्तर नहीं है, मैंने उदाहरण के रूप में C # लिया।
ओलिवियर जैकोट-डेसकोम्बर्स

सभी भाषाओं को स्पष्ट रूप से आरंभिक रूप से चर की आवश्यकता नहीं होती है। आपका "प्रारंभ नहीं करना हमेशा एक त्रुटि है" कथन गलत है, और इससे प्रश्न पर कोई स्पष्टता नहीं आती है। आप अपने उत्तर को संशोधित करना चाह सकते हैं।
डगएम

@DougM: क्या आप मेरी सजा की देखरेख कर रहे हैं "वास्तव में दिलचस्प सवाल यह है कि क्या एक चर स्वचालित रूप से आरंभीकृत किया गया है या आपको इसे मैन्युअल रूप से करना है?"
ओलिवियर जैकोट-डेसकोम्बर्स

आप एक पैरा के बीच में नीचे दफन एक मतलब है? हाँ। आपको इसे अधिक प्रमुख बनाना चाहिए था, और अपने "हमेशा" दावे के लिए एक क्वालीफायर जोड़ना चाहिए।
डग्म
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.