2009-08-04 10 views
26

कैसे निर्धारित किया जाए कि एक पूर्णांक असाइन किया गया है या नहीं?सी - जांचें कि इंटीजर को

int i; /* no assignment */ 

if (/* conditional statement here to check if int i is unassigned or not */) { 
    printf("Integer is unassigned!\n"); 
} else { 
    printf("Integer is assigned!\n"); 
} 
+2

इस धागे के बारे में कुछ चर्चा है: http://stackoverflow.com/questions/473236/check-for-value-definedness-in-c – Laserallan

उत्तर

20

आप नहीं कर सकते। इसमें "अपरिभाषित" सामग्री होगी, जिसका अर्थ यह होगा कि उस समय उस स्मृति स्थान में जो भी होता है।

। । । जब तक कि मुझे वैश्विक दायरे में घोषित नहीं किया जाता है, तो इसे शून्य में शुरू किया जाएगा।

+0

@ केनी: "जब तक मुझे घोषित नहीं किया जाता" वास्तव में मैं चाहता था कि मैं चाहता हूं कहते हैं, "मैं" वेरिएबल है जिसके बारे में हम बात कर रहे हैं, धन्यवाद। –

+0

असल में, मुझे लगता है कि कोई तर्क दे सकता है कि यदि आप इसे स्पष्ट रूप से प्रारंभ नहीं करते हैं तो एक स्थैतिक चर भी असाइन नहीं किया जाता है (यह निश्चित रूप से शून्य प्रारंभ होता है)। –

+0

@Neil: अब आप अर्थशास्त्र की दुनिया में घूम रहे हैं। हर कोई (मेरे साथ) जानता है कि मूल्य आवंटित करने का क्या अर्थ है। प्रत्येक व्यक्ति यह भी जानता है कि एक चर शुरू करने का क्या अर्थ है। अब, हर किसी से पूछें "असाइनमेंट और प्रारंभिकरण के बीच क्या अलग है?" और उन्हें flounder देखो (मेरा खुद का सिर अब भी चोट लगाना शुरू कर रहा है)। –

8

सी आंतरिक रूप से इसका समर्थन नहीं करता है - जैसे कि यह आंतरिक रूप से सरणी पर जांच की सीमा का समर्थन नहीं करता है। यह गति/दक्षता और सुरक्षा के बीच एक व्यापार बंद है।

सामान्य रूप से ... अपने चर शुरू करें।

4

यदि i वैश्विक या स्थैतिक है, तो इसका मूल्य 0 होगा, अन्यथा इसका मूल्य कुछ भी हो सकता है और यह पता लगाने का कोई तरीका नहीं है कि यह कचरा है या नहीं।

1

आम तौर पर चर पुस्तकालय द्वारा 0 पर सेट किए जाते हैं, लेकिन जरूरी नहीं।

लेकिन मूल रूप से, आप नहीं कर सकते हैं। तब

int i = 0; /* Or what ever value you know won't be used elsewhere */ 

अगर आप कुछ कोड चलाने के लिए और यदि मान वहाँ स्थापित किया गया था, तो आप अपने प्रारंभिक मूल्य के लिए तुलना कर सकते हैं जाँच करना चाहते हैं: उन्हें परिभाषा में एक डिफ़ॉल्ट मान असाइन करें, उदाहरण के लिए।

+0

उदाहरण के लिए यह संदेश देखें: http://gcc.gnu.org/ml/gcc-help/2007-07/msg00097.html – Makis

+0

और ऐसा कहने में, मेरा मतलब यह नहीं था कि किसी को भी भरोसा करना चाहिए कि ऐसा होता है। यदि आपको 0 के लिए एक चर की आवश्यकता है, तो विशेष रूप से इसे उस मान पर प्रारंभ करें! – Makis

7

यह बहुत आसान है। आप जानते हैं कि इसे असाइन किया गया है क्योंकि आपने इसे प्रारंभ नहीं किया था।

+8

जाहिर है, क्योंकि आपके पास रनटाइम के दौरान सेट एक चर नहीं होगा। –

0

सी में, एक पूर्णांक एक अनिर्धारित मूल्य पर बनाता है जब इसे बनाया जाता है। इसका अर्थ यह है कि यदि उस पूर्णांक का आपका पहला उपयोग एक रजिस्टर/मेमोरी लोकेशन/डिवाइस से 58 9 3872 के साथ आता है, तो वह उस पूर्णांक का मान है। (माइलेज डिबग/रिलीज संकलन के लिए भिन्न होता है।)

इस के साथ काम कर की सामान्य विधि एक अतर्कसंगत डिफ़ॉल्ट उपयोग करने के लिए है:

int number_of_widgets; 
int number_of_widgets_assigned = 0; 

if (number_of_widgets_assigned) 
    do something 
else 
    do something else 
number_of_widgets_assigned = 1; 
: अपने राज्य से संकेत मिलता है

int number_of_widgets = -1; 

... या एक झंडा

यह पता लगाने का कोई और तरीका नहीं है कि कुछ हार्डवेयर सौंपा गया है - जब तक कि आप अपने हार्डवेयर की डिबगिंग सुविधाओं में शामिल नहीं होना चाहते हैं और मुझे संदेह है कि यह वार्तालाप इस बारे में नहीं है।

1

सभी पिछले उत्तरों के रूप में, रनटाइम पर इसका पता लगाने का कोई तरीका नहीं है। हालांकि, लगभग static code analysis tool आपको बिना असाइन किए गए चर के लिए चेतावनी देता है।

4

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

जीसीसी के लिए:

-Wuninitialized -O1 

आप सशर्त कोड लिखने के लिए करना चाहते हैं:

int a = 3; 
int b; 
int *p = (rand() > RAND_MAX/2) ? &a : &b; 
if (is_uninitialized(*p)) // blah 

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

1

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

मैं को कोड के अंदर जांचने के लिए सुझाव देता हूं। चूंकि यह संकलक चेतावनियों का कारण बन सकता है (वैरिएबल 'i' का उपयोग मूल्य को सौंपने से पहले किया जाता है), नई त्रुटियों को पेश करें और मध्यम से बड़े कार्यक्रमों में सफलता पर बहुत कम मौका है।

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

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

यदि यह रनटाइम जांच है जो आप चाहते हैं, तो आप चर-आउट-रेंज मान में चर को घुमाकर शुरू कर सकते हैं। उदाहरण के लिए -1 अन्यथा पोस्टिव मूल्य के लिए। तो फिर तुम जाँच कर सकते हैं

#define UNASSIGNED_VALUE -1 
    static int number_of_apples = UNASSIGNED_VALUE; 
    if (UNASSIGNED_VALUE == number_of_apples) 
    { 
     // error handling 
    } 

के लिए यह एक सही 'unintialized' चर, लेकिन कम से कम आप पता लगा सकते हैं कि क्या कानूनी सीमा में क्रम कार्य किया गया नहीं है।

0

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

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

4

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

  • अपने लक्ष्य को यकीन है कि सभी चर प्रारंभ कर रहे हैं बनाने के लिए है, तो valgrind जैसे किसी उपकरण का महंगा रन-टाइम विश्लेषण के माध्यम से अप्रारंभीकृत चर गतिशील, का उपयोग करता है पता लगा सकते हैं।

  • अपने लक्ष्य को यकीन है कि निजी डेटा ठीक एक बार आरंभ नहीं हो जाता बनाने के लिए है, तो सामान्य विधि मैं प्रयोग करेंगे

    int i; 
    static bool initialized = 0; 
    
    ... 
    if (!initialized) { 
        initialized = 1; 
        i = ... i's initial value ...; 
    } 
    
0

साथ बचाने के लिए सी # में है:

Nullable<int> i = null; /* null assignment */ 

if (i == null) { 
    printf("Integer is unassigned!\n"); 
} else { 
    printf("Integer is assigned!\n"); 
} 

यकीन नहीं है कि यह सी में अनुवाद किया गया है, हालांकि।

+0

आप दोनों सी #, और सी सिंटैक्स का उपयोग कर रहे हैं !, यह कोड हाइब्रिड cuz C# में printf नामक एक विधि नहीं है, इसके बजाय यह कंसोल है। –