2012-12-09 15 views
5

मैं पढ़ रहा हूँ गाइल्स Dowek की प्रोग्रामिंग की सिद्धांतों Languanges:प्रारंभिक मूल्य के बिना चर को घोषित करना क्यों संभव है?

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

नोट: पुस्तक के लेखक जावा पर प्रारंभिक मूल्य के बिना चर घोषित करने की संभावना का उल्लेख करते हैं।

तो, चर की घोषणा क्यों वैध है? मैं इसका इस्तेमाल कब करूँगा?

int i; 
if (first_condition) 
    i = 1; 
elseif (second_condition) 
    i = 2; 
else 
    i = 0; 

आपका चर if बाहर घोषित करने की यह बाद में इस्तेमाल किया जा करने के लिए, लेकिन अपने मूल्य if की स्थिति के अंदर तय हो गई है की आवश्यकता होगी:

+0

मुझे विश्वास है कि उत्तर भाषा से भाषा से अलग है। –

+0

हां, यह है। पुस्तक के लेखक का उल्लेख है कि यह सुविधा जावा में मान्य है, मैं पोस्ट संपादित करूंगा। –

+1

अच्छा सवाल। मुझे आश्चर्य है कि तर्क क्या है? – xagyg

उत्तर

7

कई अलग-अलग भाषाओं के कई अलग-अलग कारण हैं।

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

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

महंगी प्रारंभ
इस बिंदु बहुत ऊपर बिंदु के समान है। मान लें कि आपके पास 1 मिलियन बार 1 मिलियन सरणी है। ऐसी सरणी शुरू करना एक महंगी प्रक्रिया है। डिफ़ॉल्ट रूप से ऐसा करने के लिए मूर्खता होगी, और इसलिए, ऐसी सुविधा, जहां स्मृति आवंटित की जाती है और फिर आवश्यकतानुसार उपयोग की जाती है।

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

5

उदाहरण के लिए, आप कुछ इस तरह हो सकता था।

1

कुछ की तरह:

//declare without giving value. 
int i; 

//set value 
i=9; 
+1

यह मेरा प्रश्न नहीं है, मेरा सवाल है: यदि कोई त्रुटि हो रही है तो प्रारंभिक मान के बिना चर को घोषित करना क्यों संभव है? –

+0

सबकुछ त्रुटि नहीं देगा ... int int की तरह; 0 देगा। लेकिन यदि आप उपयोगकर्ता उपयोगकर्ता करते हैं; फिर बाद में स्ट्रिंग एस = user.address; यह आपको त्रुटि देता है – user903772

+0

@ user903772 स्थानीय चर किसी भी चीज़ के लिए प्रारंभ नहीं किए जाते हैं, वे अपरिभाषित हैं ... "स्थानीय चर अलग-अलग हैं; संकलक कभी भी एक अनियमित स्थानीय चर के लिए डिफ़ॉल्ट मान निर्दिष्ट नहीं करता है। यदि आप अपने स्थानीय चर को प्रारंभ नहीं कर सकते हैं घोषित किया गया है, इसे उपयोग करने का प्रयास करने से पहले इसे एक मान असाइन करना सुनिश्चित करें। एक अनियमित स्थानीय चर का उपयोग करने से संकलन-समय त्रुटि हो जाएगी। " – xagyg

1

आप एक सत्यापन लिपि में उदाहरण के लिए एक खाली वर घोषणा कर सकते हैं,

$error=''; 
if(empty($_POST['first_name']{ 
$error=$error."You did not enter a name"; 

}

इस तरह है, लेकिन मैं केवल यह प्रयोग करेंगे, तो उपरोक्त के रूप में, इसे फिर से शुरू करने के तुरंत बाद कोड, ताकि उसे 'mislaid' नहीं मिलेगा।

3

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

  1. स्मृति आवंटन चर साधन घोषणा करते हुए पूछा प्रकार का उदाहरण बनाकर, आदि आदि
  2. फिर स्मृति के उस स्थान को प्रारंभ करने, इसे फिर से भरने की तरह, आबंटित स्मृति स्थान के लिए डिफ़ॉल्ट मान ले जाने के लिए अधिक संसाधन की आवश्यकता 0s के साथ करता है, तो डिफ़ॉल्ट मान 0. है:

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

तो यदि कोई भाषा आपको घोषणा पर एक वैरिएबल (या स्वयं द्वारा ऐसा करता है) शुरू करने के लिए मजबूर करती है तो यह लाइन के नीचे एक त्रुटि के अवसरों को कम कर देती है, लेकिन यह उस चीज़ के लिए प्रसंस्करण शक्ति बर्बाद कर सकती है जिसे आप वास्तव में नहीं चाहते थे।

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

भाषाएं तय करती हैं कि वे कौन सी पथ लेना चाहते हैं, अधिकतर वे अपनी शक्ति पर विचार करते हैं।

यदि यह प्रोग्रामर को नियंत्रण रखने का मौका देने के बारे में है, और अत्यधिक अनुकूलित प्रोग्राम बनाते हैं तो वे आमतौर पर अधिक सामान के अलावा, प्रारंभ किए बिना वर्र्स घोषित करने की अनुमति देंगे।

लेकिन यदि भाषा अधिक त्रुटि मुक्त प्रोग्राम लिखने के लिए प्रोग्रामर को मजबूर करने के बारे में है, तो यह दूसरा रास्ता लेगा।

2

जावा की आवश्यकता के लिए एक वर्ग वस्तु के क्षेत्र हमेशा लिखा होना चाहिए कि इससे पहले कि वे पढ़ रहे थे, यह है कि आवश्यकता होगी थे, तो या तो

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

  • प्रत्येक फ़ील्ड never been written मान रखने में सक्षम होना चाहिए जो इसे किसी भी अन्य मूल्य से अलग किया जा सकता है।

  • कंपाइलर को यह निर्धारित करने के लिए हलिंग समस्या को हल करना होगा कि कोई फ़ील्ड लिखे बिना पढ़ा जा सकता है या नहीं।

  • भाषा को इस संभावना को स्वीकार करना होगा कि बिना किसी उपयोगकर्ता कोड के एक फ़ील्ड पढ़ा जाएगा।

इन संभावित विकल्पों में से # 4 कम से कम बुराई है।अपरिभाषित व्यवहार से बचने के लिए, जावा उस फ़ील्ड को पढ़ने के व्यवहार को परिभाषित करता है जिसे कभी लिखा नहीं गया है: इसमें इसके प्रकार के लिए डिफ़ॉल्ट मान होगा।

+0

केवल उदाहरण फ़ील्ड में डिफ़ॉल्ट मान हैं।प्रारंभिकरण के बिना स्थानीय क्षेत्र का उपयोग करने का प्रयास करने से संकलन त्रुटि हो जाएगी। तथ्य यह है कि इंस्टेंस फ़ील्ड को प्रारंभ करने की आवश्यकता नहीं है, एक अच्छी डिजाइन की तुलना में एक कंपाइलर सरलीकरण का अधिक है। यह उत्तर इसे अच्छी तरह से समझाता है: https://stackoverflow.com/questions/1560685/why-must-local-variables-cluding-primitives-always-be-initialized-in-java –

+0

शायद मुझे "क्लास इंस्टेंस" कहा जाना चाहिए था "वर्ग ऑब्जेक्ट" से, लेकिन मुझे नहीं लगता कि उस दूसरे प्रश्न के उत्तर पर विचार किया जाना चाहिए कि अगर भाषा को उस उदाहरण फ़ील्ड की आवश्यकता होती है तो क्या आवश्यक होगा। हेलिंग समस्या को हल किए बिना संकलक उत्पन्न करने के लिए संकलक को अनुमति देना या प्रत्येक फ़ील्ड के लिए "कभी भी लिखित" मान आरक्षित करना "सरलीकरण" हो सकता है, लेकिन मैं इसे सरल व्यावहारिकता के रूप में अधिक मानता हूं। – supercat

1

ठीक है यहाँ एक उदाहरण है। मैं वर्तमान में वैश्विक मूल्यों को स्थापित कर रहा हूं जो पीडीएफ मंचों पर लगातार स्थापित हैं। इस एप्लिकेशन के लिए मैं इन मानों को डेटा संग्रहण के रूप में टेक्स्ट फ़ील्ड की तरह उपयोग करना चाहता हूं। सबसे अच्छी विधि नहीं है लेकिन यह इस उदाहरण के लिए काम करता है। सैकड़ों छिपा पाठ फ़ील्ड के साथ अपने मंच को पॉप्युलेट करने के बजाय मैं मूल्यों को लगातार वैश्विक चर के रूप में सेट कर सकता हूं।

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

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

इसके अतिरिक्त

यह जब घोषित मान देना कुशल, लेकिन नहीं सामान्य प्लेस होल्डर मूल्यों है। अधिकांश स्क्रिप्ट्स int में int x = 5 कहने के समान सरल नहीं है; अधिकतर हम जैसे डेटा पर कॉल करते हैं .getField ("TextBox3")। मान; या कुछ अन्य लाइन कोड। " या या सत्य आपका कार्य सामान्य रूप से किसी मान का उचित उपयोग करने में विफल होने पर भी कार्य कर सकता है। मूल्य निर्दिष्ट नहीं करके, यदि आप अपने चर का उपयोग करने में विफल रहते हैं, तो आपके फ़ंक्शन की समस्या विफल होने पर संभावनाओं को कम करने की अनुमति देने में विफल हो जाएगी। यदि int x; अभी भी NaN है जब आप x का उपयोग अपने डेटा संग्रह और सत्यापन से करते हैं, तो समस्या का स्रोत होने की संभावना है।

सामान्य में शीर्ष पर सभी मान घोषित करें और सामान्य मूल्यों को सेट करने से बचें जब तक आपको यह करना न पड़े। यदि आप इसे x के मानों को परिभाषित करने जा रहे हैं तो इसे int x = 0 पर सेट न करें;

संबंधित मुद्दे