क्या आप C ++ में संकेत के लिए NULL या 0 (शून्य) का उपयोग करते हैं?


193

C ++ के शुरुआती दिनों में जब इसे C के ऊपर से बोल्ट किया गया था, तो आप NULL का उपयोग नहीं कर सकते थे क्योंकि इसे परिभाषित किया गया था (void*)0। आप NULL को इसके अलावा किसी भी पॉइंटर को असाइन नहीं कर सकते हैं void*, जिससे यह बेकार हो गया है। उन दिनों में, यह स्वीकार किया गया था कि आपने 0शून्य बिंदुओं के लिए (शून्य) का उपयोग किया था ।

आज तक, मैंने शून्य को एक शून्य सूचक के रूप में उपयोग करना जारी रखा है, लेकिन मेरे आसपास के लोग उपयोग करने पर जोर देते हैं NULL। मुझे व्यक्तिगत रूप से NULLमौजूदा मूल्य के लिए एक नाम ( ) देने का कोई लाभ नहीं दिखता है - और क्योंकि मैं भी बिंदुओं को सत्य मान के रूप में परखना चाहता हूं:

if (p && !q)
  do_something();

तब शून्य का उपयोग करना अधिक समझ में आता है (जैसा कि यदि आप उपयोग करते हैं NULL, तो आप तार्किक रूप से उपयोग नहीं कर सकते हैं p && !q- आपको स्पष्ट रूप से तुलना करने की आवश्यकता है NULL, जब तक आप यह नहीं मान लेते हैं NULLकि किस स्थिति में उपयोग करें NULL)।

क्या NULL (या इसके विपरीत) पर शून्य पसंद करने का कोई उद्देश्यपूर्ण कारण है, या यह सब सिर्फ व्यक्तिगत पसंद है?

संपादित करें: मुझे जोड़ना चाहिए (और मूल रूप से कहने का मतलब है) कि RAII और अपवादों के साथ, मैं शायद ही कभी शून्य / पूर्ण बिंदुओं का उपयोग करता हूं, लेकिन कभी-कभी आपको उनकी आवश्यकता होती है।


9
प्रतीक्षा करें, क्या एक शून्य सूचक को गलत के रूप में मूल्यांकन करने की आवश्यकता नहीं है, भले ही शून्य आंतरिक रूप से शून्य हो या नहीं?
मिंग डक

5
stackoverflow.com/questions/9894013/… और c-faq.com/null/ptrtest.html इस बात की पुष्टि करें
डक

जवाबों:


185

यहाँ Stroustrup का इस पर लेना है: C ++ स्टाइल और टेक्नीक FAQ

C ++ में, की परिभाषा NULL0 है, इसलिए केवल एक सौंदर्य अंतर है। मैं मैक्रोज़ से बचना पसंद करता हूं, इसलिए मैं 0. का उपयोग करता हूं। एक अन्य समस्या NULLयह है कि लोग कभी-कभी गलती से मानते हैं कि यह 0 और / या पूर्णांक से भिन्न है। पूर्व-मानक कोड में, NULLकभी-कभी कुछ अनुपयुक्त के लिए परिभाषित किया गया था और इसलिए / से बचा जाना चाहिए था। जो इन दिनों कम आम है।

यदि आपको अशक्त सूचक का नाम देना है, तो उसे कॉल करें nullptr; इसे C ++ 11 में कहा जाता है। फिर, nullptrएक कीवर्ड होगा।

उस ने कहा, छोटे सामान पसीना मत करो।


7
C ++ 0x ने एक नए अशक्त प्रकार पर काम करना शुरू करने से पहले Bjarne ने इसे लिखा। यह मामला होगा कि NULL का उपयोग इस प्रकार के लिए किया जाएगा जब यह एक प्लेटफ़ॉर्म के लिए उपलब्ध होगा, और मुझे लगता है कि आप इस बारे में आम सहमति में सी-परिवर्तन देखेंगे।
रिचर्ड कॉर्डन

122

कुछ तर्क हैं (जिनमें से एक अपेक्षाकृत हाल ही में है) जो मुझे लगता है कि इस पर बंजर्न की स्थिति के विपरीत है।

  1. आशय का दस्तावेजीकरण

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

  1. सूचक का ओवरलोड और 'इंट' अपेक्षाकृत दुर्लभ है

वह उदाहरण जो हर कोई उद्धृत करता है:

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

हालाँकि, कम से कम मेरी राय में, ऊपर के साथ समस्या यह नहीं है कि हम NULL को पॉइंटर पॉइंटर निरंतर के लिए उपयोग कर रहे हैं, यह है कि हमारे पास 'फू' के ओवरलोड हैं जो बहुत भिन्न प्रकार के तर्क लेते हैं। पैरामीटर intभी एक होना चाहिए , क्योंकि किसी भी अन्य प्रकार का परिणाम अस्पष्ट कॉल होगा और इसलिए एक सहायक संकलक चेतावनी उत्पन्न करेगा।

  1. विश्लेषण उपकरण आज मदद कर सकते हैं!

यहां तक ​​कि C ++ 0x की अनुपस्थिति में, आज उपलब्ध उपकरण हैं जो यह इंगित करते हैं कि NULLपॉइंटर्स के लिए उपयोग किया जा रहा है, और 0इसका उपयोग अभिन्न प्रकारों के लिए किया जा रहा है।

  1. C ++ 11 में एक नया std::nullptr_tप्रकार होगा।

यह तालिका का सबसे नया तर्क है। की समस्या 0और NULLसक्रिय रूप से किया जा रहा है C ++ 0x के लिए संबोधित किया है, और आप गारंटी ले सकते हैं कि हर कार्यान्वयन प्रदान करता है कि के लिए है कि NULL, बहुत पहली बात यह है कि वे क्या करेंगे है:

#define NULL  nullptr

इसके NULLबजाय जो लोग उपयोग 0करते हैं, उनके लिए परिवर्तन बहुत कम या बिना किसी प्रयास के टाइप-सेफ्टी में सुधार होगा - अगर कुछ भी यह कुछ बग्स को पकड़ सकता है जहां उन्होंने उपयोग किया NULLहै 00आज का उपयोग करने वाले किसी भी व्यक्ति के लिए .... erm ... अच्छी तरह से उम्मीद है कि उन्हें नियमित अभिव्यक्तियों का अच्छा ज्ञान है ...


1
वे कुछ अच्छे बिंदु हैं, मुझे मानना ​​होगा। मुझे खुशी है कि C ++ 0x में एक अशक्त प्रकार होगा, मुझे लगता है कि यह बहुत सारे सामान को साफ करेगा।
रोब

2
@ रीचर्ड, इसके विपरीत क्यों नहीं? आप Meyers का उपयोग कर सकते हैं nullptr_t तब जब 0x उपलब्ध हो जाता है तो आप उसे हटा देते हैं #includeऔर सभी तरह से सुरक्षित साइड में रख सकते हैं।
फनीटो - फर्नांडो नीटो

15
#define NULL nullptrखतरनाक लगता है। बेहतर या बदतर के लिए, बहुत से विरासत कोड 0. के अलावा अन्य चीजों के लिए NULL का उपयोग करते हैं। उदाहरण के लिए, हैंडल को अक्सर कुछ अभिन्न प्रकार के रूप में लागू किया जाता है, और उन्हें सेट करना NULLअसामान्य नहीं है। मैंने एक शून्य-टर्मिनेटर NULLको सेट करने के लिए उपयोग करने जैसी गालियां भी देखी हैं char
एड्रियन मैककार्थी

8
@ AdrianMcCarthy: मैं केवल यह कहूंगा कि यदि कोड को चुपचाप संकलन करने और एक अलग अर्थ रखने का खतरा था, तो यह खतरनाक था। मुझे पूरा यकीन है कि यह मामला नहीं है, इसलिए वास्तव में NULL के सभी गलत उपयोगों का पता लगाया जाएगा।
रिचर्ड कॉर्डन

3
@ रीचर्ड कॉर्डन: उम, यह मानता है कि वे अन्य उपयोग NULLवास्तव में गलत हैं। कई एपीआई लंबे समय तक NULLहैंडल के साथ उपयोग किए जाते हैं, और यह वास्तव में उनमें से कई के साथ प्रलेखित उपयोग है। यह अचानक उन लोगों को तोड़ने और घोषित करने के लिए व्यावहारिक नहीं है कि वे इसे गलत कर रहे हैं।
एड्रियन मैक्कार्थी

45

NULL का उपयोग करें। NULL आपकी मंशा दर्शाता है। यह 0 है एक कार्यान्वयन विवरण जो मायने नहीं रखता है।


28
0 कार्यान्वयन विवरण नहीं है। मानक 0 को परिभाषित करता है जो भी बिट पैटर्न एक शून्य सूचक का प्रतिनिधित्व करता है।
फेर्रुकियो

5
जैसे की ..!! यार, सी ++ एक निम्न स्तर की भाषा है! 0 का प्रयोग करें, यह एक प्रसिद्ध मुहावरा है।
hasen

8
मैं समझता हूं कि यह मानक का एक हिस्सा है। यह एक कार्यान्वयन विवरण है जहां तक ​​कोड को पढ़ना है। पाठक को "NULL पॉइंटर" नहीं "0" सोचना चाहिए जो इस मामले में NULL पॉइंटर का मतलब है, न कि एक संख्या जिसके साथ मैं अंकगणित कर सकता हूं। "
एंडी लेस्टर

2
+1। एंडी के साथ सहमत हुए। @Ferruccio, प्रोग्रामर के विचार का कार्यान्वयन विवरण कंपाइलर के कार्यान्वयन को परिभाषित
उपयोगकर्ता

यदि आप जटिल हेडर के बिना सादे कोड में NULL का उपयोग करते हैं, तो आपको "NULL को इस दायरे में परिभाषित नहीं किया गया है" की त्रुटि मिलेगी ..
ArtificiallyIntelligence

37

मैं हमेशा उपयोग करता हूं:

  • NULL संकेत के लिए
  • '\0' चेरों के लिए
  • 0.0 फ्लोट्स और डबल्स के लिए

जहां 0 ठीक होगा। यह सांकेतिक इरादे की बात है। उस ने कहा, मैं इसके बारे में गुदा नहीं हूं।


25
फिर शायद फ़्लोट्स के लिए 0.0F का उपयोग करना चाहिए, निहित टाइपकास्ट से बचने के लिए
EvilTeach

35

मैंने NULL का उपयोग बहुत पहले (साथ ही साथ अन्य मैक्रोज़) के पक्ष में करना बंद कर दिया था। मैंने ऐसा न केवल इसलिए किया क्योंकि मैं मैक्रोज़ से यथासंभव बचना चाहता था, बल्कि इसलिए भी कि NULL को C और C ++ कोड में ओवर-उपयोग हो गया लगता है। इसका उपयोग तब भी किया जाता है जब भी 0 मान की आवश्यकता होती है, न कि केवल संकेत के लिए।

नई परियोजनाओं पर, मैंने इसे एक प्रोजेक्ट हेडर में रखा:

static const int nullptr = 0;

अब, जब C ++ 0x कंप्लेंट कंपाइलर आते हैं, तो मुझे केवल इतना करना है कि उस लाइन को हटा दें। इसका एक अच्छा लाभ यह है कि विज़ुअल स्टूडियो पहले से ही एक कीवर्ड के रूप में nullptr को पहचानता है और इसे उचित रूप से हाइलाइट करता है।


4
NULL का उपयोग करना अधिक पोर्टेबल दीर्घकालिक होगा। 'nullptr ’कुछ प्लेटफार्मों के लिए उपलब्ध होगा और दूसरों के लिए नहीं। यहां आपके समाधान के लिए आवश्यक है कि आप अपनी घोषणा के आसपास प्रीप्रोसेसर का उपयोग यह सुनिश्चित करने के लिए करें कि यह केवल आवश्यक होने पर ही मौजूद है। NULL यह स्वचालित रूप से करेगा।
रिचर्ड कॉर्डन

6
मैं असहमत हूं। यह छोटी अवधि में कम पोर्टेबल होगा जब तक कि कंपाइलर पकड़ न लें। दीर्घकालिक, यह सिर्फ पोर्टेबल और शायद थोड़ा अधिक पठनीय होगा।
फेरुशियो

4
साथ ही आप अपने नॉन-सी ++ 0x कंपाइलर के लिए हमेशा #define nullptr NULL कर सकते हैं।
ऐंटरू

20
    cerr << sizeof(0) << endl;
    cerr << sizeof(NULL) << endl;
    cerr << sizeof(void*) << endl;

    ============
    On a 64-bit gcc RHEL platform you get:
    4
    8
    8
    ================

कहानी का नैतिक पहलू है। जब आप पॉइंटर्स के साथ काम कर रहे हों तो आपको NULL का उपयोग करना चाहिए।

1) यह आपके इरादे की घोषणा करता है (अगर कोई चर सूचक या कुछ संख्यात्मक प्रकार है) तो यह पता लगाने की कोशिश कर अपने सभी कोड के माध्यम से मुझे खोज न करें।

2) कुछ एपीआई कॉल में जो चर तर्कों की अपेक्षा करते हैं, वे तर्क सूची के अंत को इंगित करने के लिए NULL-पॉइंटर का उपयोग करेंगे। इस स्थिति में, NULL के बजाय '0' का उपयोग करने से समस्याएँ हो सकती हैं। 64-बिट प्लेटफ़ॉर्म पर, va_arg कॉल 64-बिट पॉइंटर चाहता है, फिर भी आप केवल 32-बिट पूर्णांक पास करेंगे। मुझे लगता है जैसे आप अन्य 32-बिट्स पर भरोसा कर रहे हैं आपके लिए शून्य हो? मैंने कुछ कंपाइलर (जैसे इंटेल के icpc) देखे हैं जो इतने शालीन नहीं हैं - और इसके परिणामस्वरूप रनटाइम त्रुटियां हुई हैं।


NULLशायद पोर्टेबल नहीं है, और सुरक्षित नहीं है। ऐसे प्लेटफ़ॉर्म हो सकते हैं जो अभी भी हैं #define NULL 0( स्ट्रॉस्ट्रुप के अक्सर पूछे जाने वाले प्रश्न के अनुसार : क्या मुझे शीर्ष प्रश्न के द्वारा NULL या 0 का उपयोग करना चाहिए? यह पहले खोज परिणामों में से है)। कम से कम पुराने सी ++ में, 0पॉइंटर संदर्भ में एक विशेष वैचारिक अर्थ है। आपको बिट्स के बारे में बिल्कुल नहीं सोचना चाहिए। यह भी ध्यान रखें कि विभिन्न पूर्णांक संदर्भों में ( short, int, long long) " sizeof(0)" अलग होगा। मुझे लगता है कि यह जवाब थोड़ा गुमराह करने वाला है।
FooF

(निजी तौर पर दैनिक जीवन में एक सी प्रोग्रामर के रूप में, मैं इस सवाल का दौरा करने के लिए समझने के लिए क्यों लोग उपयोग करना चाहते हैं के लिए आया था NULLके बजाय (char *)0, (const char *)0या (struct Boo *)0या (void *)0या आशय अधिक स्पष्ट रूप से व्यक्त करने जो कुछ भी -। जा रहा है (मेरी राय में) बहुत बोझिल बिना)
foof

पक्ष में मत देना। यह msvc2013 C संकलक पर हो रहा है। 64bit, 0 में जब पॉइंटर में कन्वर्ट किया जाता है तो NULL Pointer होने की गारंटी नहीं है।
पेंग्मियाओ

16

अगर मुझे सही से याद है तो NULL को मेरे द्वारा उपयोग किए जाने वाले हेडर में अलग तरह से परिभाषित किया गया है। C के लिए इसे (void *) 0 के रूप में परिभाषित किया गया है, और C ++ के लिए इसे केवल 0. के रूप में परिभाषित किया गया है। कोड कुछ इस तरह दिखता है:

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

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

इसके अतिरिक्त मैं बूलियन मूल्यों के पूर्णांक के स्वत: रूपांतरण पर भरोसा नहीं करता, लेकिन स्पष्ट रूप से उनकी तुलना करता हूं।

उदाहरण के लिए उपयोग करना पसंद करते हैं:

if (pointer_value != NULL || integer_value == 0)

बजाय:

if (pointer_value || !integer_value)

यह कहने के लिए पर्याप्त है कि यह सब C ++ 11 में प्रेषित किया गया है, जहां कोई nullptrइसके बजाय बस का उपयोग कर सकता है NULL, और यह भी nullptr_tएक प्रकार है nullptr


15

मैं कहूंगा कि इतिहास ने बात की है और जो लोग 0 (शून्य) का उपयोग करने के पक्ष में तर्क देते थे, वे गलत थे (बज़्ने स्ट्रॉस्ट्रुप सहित)। 0 के पक्ष में तर्क ज्यादातर सौंदर्यशास्त्र और "व्यक्तिगत पसंद" थे।

C ++ 11 के निर्माण के बाद, अपने नए नल्टर प्रकार के साथ, कुछ कंपाइलरों ने सूचक तर्कों के साथ 0 से गुजरने के बारे में शिकायत (डिफ़ॉल्ट मापदंडों के साथ) शुरू कर दी है, क्योंकि 0 एक सूचक नहीं है।

यदि NULL का उपयोग करके कोड लिखा गया था, तो कोडबल के माध्यम से एक सरल खोज और प्रतिस्थापित किया जा सकता था, बजाय इसे nullptr बनाने के। यदि आप एक संकेतक के रूप में 0 की पसंद का उपयोग करके लिखे गए कोड के साथ फंस गए हैं तो इसे अद्यतन करने के लिए कहीं अधिक थकाऊ है।

और अगर आपको C ++ 03 मानक के लिए नया कोड अभी लिखना है (और nullptr का उपयोग नहीं कर सकते हैं), तो आपको वास्तव में केवल पूर्ण का उपयोग करना चाहिए। यह आपके लिए भविष्य में अपडेट करना बहुत आसान बना देगा।


11

मैं आमतौर पर 0. का उपयोग करता हूं। मुझे मैक्रोज़ पसंद नहीं हैं, और इस बात की कोई गारंटी नहीं है कि आप जिस थर्ड पार्टी हेडर का उपयोग कर रहे हैं वह कुछ अजीब होने के लिए NULL को फिर से परिभाषित नहीं करता है।

आप स्कॉट Meyers और अन्य द्वारा प्रस्तावित nullptr ऑब्जेक्ट का उपयोग कर सकते हैं जब तक कि C ++ को एक nullptr कीवर्ड नहीं मिलता है:

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

अधिक जानकारी के लिए Google "nullptr"।


9
कोई भी तृतीय-पक्ष लाइब्रेरी जो NULL को 0 (या (void*)0यदि C कोड के रूप में संकलित किया जा रहा है) के अलावा किसी अन्य चीज़ को परिभाषित करता है, तो केवल परेशानी पूछ रहा है और इसका उपयोग नहीं किया जाना चाहिए।
एडम रोसेनफील्ड

2
क्या आपने वास्तव में एक पुस्तकालय देखा है जो NULL को फिर से परिभाषित करता है? कभी? यदि इस तरह की कोई लाइब्रेरी मौजूद है, तो आपको NULL की तुलना में बड़ी समस्याएं होंगी, जैसे कि आप एक ऐसी लाइब्रेरी का उपयोग कर रहे हैं जो NULL को फिर से परिभाषित करने के लिए पर्याप्त है।
एंडी लेस्टर

1
एक दशक से अधिक समय से पहले मुझे कुछ 3-पार्टी हेडर के साथ व्यवहार करने की याद है, संभवतः ऑर्बिक्स या ऑब्जेक्टस्टोर, जिसने NULL को परिभाषित नहीं किया था। मुझे लगता है कि मुझे कई दिनों और रातों को बर्बाद करने के बाद मैक्रों की एक पैथोलॉजिकल नफरत है, जो विभिन्न 3-पार्टी हेडर को विंडोज़ के साथ काम करने की कोशिश कर रहा है।
जौन-हॉनसन

2
"मैक्रोज़ पसंद नहीं है" एक वस्तु की एक विषम समालोचना है #define। शायद आपके कहने का मतलब है कि आप सी-प्रीप्रोसेसर को पसंद नहीं करते हैं?
एंड्रयू प्रोक

@ और - NULLओवर (type *)0का एकमात्र लाभ खोज क्षमता है, यह मुझे लगता है। अन्यथा यह एक सी मुहावरा नहीं है तो अनावश्यक रूप से अप्रिय लगता है। मैं व्यक्तिगत रूप से लगता है कि NULLसभी जगह फैलाने का मुहावरा मरने के लायक है। NULLमेरी राय में बेकार मैक्रो है। ओकाम के रेजर को यहां कुछ काम मिला ...
FooF

11

मैंने एक बार एक मशीन पर काम किया जहां 0 एक वैध पता था और NULL को एक विशेष अष्टाधारी मूल्य के रूप में परिभाषित किया गया था। उस मशीन पर (0! = NULL), इसलिए जैसे कोड

char *p;

...

if (p) { ... }

आप अपेक्षा के अनुरूप काम नहीं करेंगे। आपने लिखने के लिए HAD किया

if (p != NULL) { ... }

हालांकि मेरा मानना ​​है कि अधिकांश कंपाइलर्स NULL को 0 के रूप में परिभाषित करते हैं, इन दिनों मुझे अभी भी उन वर्षों के सबक याद हैं: NULL जरूरी नहीं कि 0 हो।


26
आप एक आज्ञाकारी संकलक का उपयोग नहीं कर रहे थे। मानक कहते हैं शून्य है 0 और संकलक मेहराब के लिए एक उचित सच शून्य मूल्य में एक सूचक संदर्भ में 0 परिवर्तित करना चाहिए।
इवान टेरान

17
हाँ आप सही है। एएनएसआई द्वारा सी मानक का उत्पादन करने से पहले यह 80 के दशक के मध्य में था। तब अनुपालन जैसी कोई चीज नहीं थी और संकलक लेखक भाषा की व्याख्या करने के लिए स्वतंत्र थे क्योंकि उन्होंने फिट देखा था। इसलिए एक मानक आवश्यक था।
mxg

9

मुझे लगता है कि मानक गारंटी देता है कि NULL == 0, तो आप भी कर सकते हैं। मैं NULL को पसंद करता हूं क्योंकि यह आपकी मंशा को दस्तावेज करता है।


यदि आपके पास नेस्टेड संरचनाएं हैं, तो मुझे लगता है कि यह कहने foo.bar_ptr = (Bar *) 0से मंशा स्पष्ट होती है foo.bar_ptr = NULL। यह आदत संकलक को आपके लिए गलत धारणाओं को पकड़ने का अधिकार भी देती है। मेरे लिए, foo.bar_ptr = 0इरादे को व्यक्त करने के साथ-साथ NULLयदि मैं जानता हूं कि foo.bar_ptrयह एक सूचक है तो इसका उपयोग करना चाहिए ।
FooF

9

0 या NULL का उपयोग करने से समान प्रभाव होगा।

हालांकि, इसका मतलब यह नहीं है कि वे दोनों अच्छी प्रोग्रामिंग प्रथाएं हैं। यह देखते हुए कि प्रदर्शन में कोई अंतर नहीं है, एक अज्ञेय / सार विकल्प पर एक निम्न-स्तरीय-जागरूक विकल्प चुनना एक बुरा प्रोग्रामिंग अभ्यास है। आपके कोड के पाठकों को आपकी विचार प्रक्रिया को समझने में मदद करें

NULL, 0, 0.0, '\ 0', 0x00 और whatelse सभी एक ही चीज़ में अनुवाद करते हैं, लेकिन आपके प्रोग्राम में अलग-अलग लॉजिकल इकाइयाँ हैं। उनका उपयोग इस तरह किया जाना चाहिए। NULL एक पॉइंटर है, 0 की मात्रा है, 0x0 एक वैल्यू है जिसके बिट्स दिलचस्प हैं। आप किसी पॉइंटर को '\ 0' असाइन नहीं करेंगे कि वह कंपाइल करता है या नहीं।

मुझे पता है कि कुछ समुदाय पर्यावरण के अनुबंधों को तोड़कर पर्यावरण के गहन ज्ञान का प्रदर्शन करने के लिए प्रोत्साहित करते हैं। जिम्मेदार प्रोग्रामर, हालांकि, बनाए रखने योग्य कोड बनाते हैं और ऐसी प्रथाओं को अपने कोड से बाहर रखते हैं।


5

अजीब बात है, Stroustroup सहित किसी ने भी उल्लेख नहीं किया है। जबकि के बारे में मानकों और सौंदर्यशास्त्र कोई भी एक बहुत बात कर देखा है कि यह है खतरनाक उपयोग करने के लिए 0में NULLवास्तुकला जहां पर, की जगह चर तर्क सूची में उदाहरण के लिए sizeof(int) != sizeof(void*)। स्ट्रॉस्ट्रुप की तरह, मैं 0सौंदर्य कारणों से पसंद करता हूं , लेकिन किसी को इसका उपयोग न करने के लिए सावधान रहना होगा जहां इसका प्रकार अस्पष्ट हो सकता है।


और उन खतरनाक स्थानों में आप अभी भी उपयोग कर सकते हैं 0जो आपके द्वारा निर्दिष्ट जो प्रदान 0क्या आपका मतलब है - उदाहरण के लिए (int *)0, (char *)0, (const char *)0या (void *)0या (unsigned long long) 0या जो कुछ भी। मेरी राय में यह मंशा की तुलना में बहुत स्पष्ट है NULL
FooF

1
यकीन है, अगर आप नहीं जानते कि क्या NULLखड़ा है।
माइकल क्रेलिन -

मैं व्यक्तिगत रूप से इसे कुछ हद तक अनावश्यक रूप से बेकार कर (void *)देता हूं जब मैं सटीक प्रकार का उपयोग कर सकता हूं। मैंने सूची में जानबूझकर (आमतौर पर) 64-बिट पूर्णांक का उदाहरण दिया क्योंकि यह पॉइंटर केस के अनुरूप है। इसके अलावा, अगर मेरी याद है कि पुराने C ++ को सटीक NULLरूप 0में परिभाषित किया गया है (यह सी ++ में प्रोग्राम किए जाने के बाद से वर्ष है), तो हम प्रोग्राम शुद्धता में कोई सुधार नहीं देखते हैं। नए C ++ मानक सौभाग्य से nullptrकीवर्ड प्रदान करते हैं , इसलिए हम NULLनए C ++ लिखते समय इस कुरूपता और संपूर्ण विवाद से छुटकारा पा सकते हैं ।
FooF

खैर, इसीलिए कास्टिंग को (void*)अमूर्त किया गया है NULL। और NULLवास्तव में अधिकांश समय मंशा को स्पष्ट रूप से व्यक्त करता है। और मुझे लगता है कि आपका स्मरण गलत है। मानकों के बारे में निश्चित नहीं है, लेकिन व्यवहार में मेरा मानना ​​है कि यह रहा है (void*)0। और यस, nullptrएक अच्छा प्रेटिफ़ायर है, हालांकि यह एक ही NULLचीज़ के लिए है - निर्दिष्ट प्रकार के बिना नल-पॉइंटर निर्दिष्ट करना।
माइकल क्रेलिन - हैकर

1
@FooF, कुछ प्लेटफार्मों पर - शायद। मेरी वास्तविकता में यह काम किया और इसलिए मुझे संदेह है कि इसे एक पॉइंटर के रूप में परिभाषित किया गया है। मजबूती के लिए, हां, मैं जो कहना चाह रहा था nullptr, उसी संदेश का उपयोग कर रहा था NULL, जो केवल आपके द्वारा बताए गए इरादे को व्यक्त करने के बारे में था। ( NULLआधुनिक gccपैदावार पर रोक __null, जो भी है)।
माइकल क्रेलिन - हैकर

4

मैं जहां संभव हो C ++ संदर्भों का उपयोग करके पूरे प्रश्न से बचने की कोशिश करता हूं। बजाय

void foo(const Bar* pBar) { ... }

आप अक्सर लिखने में सक्षम हो सकते हैं

void foo(const Bar& bar) { ... }

बेशक, यह हमेशा काम नहीं करता है; लेकिन अशक्त बिंदुओं का अत्यधिक उपयोग किया जा सकता है।


3

मैं इस एक पर Stroustrup के साथ हूँ :-) चूंकि NULL भाषा का हिस्सा नहीं है, मैं 0 का उपयोग करना पसंद करता हूँ।


3

ज्यादातर व्यक्तिगत पसंद, हालांकि कोई यह तर्क दे सकता है कि NULL यह स्पष्ट करता है कि ऑब्जेक्ट एक पॉइंटर है जो वर्तमान में किसी भी चीज़ की ओर इशारा नहीं करता है, जैसे।

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

IIRC, मानक को NULL होने की आवश्यकता नहीं है, इसलिए <stddef.h> में जो भी परिभाषित किया गया है उसका उपयोग करना संभवतः आपके कंपाइलर के लिए सबसे अच्छा है।

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


3

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

इसने कहा, मुझे संकेत का उपयोग करने में कोई समस्या नहीं है क्योंकि स्वयं में सत्य मूल्य है। NULL की तरह, यह एक मुहावरेदार मुहावरा है।

C ++ 09 nullptr निर्माण जोड़ देगा जो मुझे लगता है कि लंबे समय से अधिक है।


1

मैं हमेशा 0. का उपयोग करता हूं। किसी भी वास्तविक विचार के कारण नहीं, सिर्फ इसलिए कि जब मैं पहली बार C ++ सीख रहा था तो मैंने कुछ ऐसा पढ़ा जो 0 का उपयोग करने की सिफारिश की और मैंने हमेशा इसे इस तरह से किया है। सिद्धांत रूप में पठनीयता में एक भ्रम की स्थिति हो सकती है लेकिन व्यवहार में मैं कभी भी हजारों-घंटों और लाखों लाइनों के कोड में इस तरह के मुद्दे पर नहीं आया हूं। जैसा कि स्ट्रॉस्ट्रुप कहता है, यह वास्तव में सिर्फ एक व्यक्तिगत सौंदर्य मुद्दा है जब तक कि मानक अशक्त न हो जाए।


1

किसी ने मुझे एक बार कहा था ... मैं NULL को 69 पर फिर से परिभाषित करने जा रहा हूं। तब से मैं इसका उपयोग नहीं करता: पी

यह आपके कोड को काफी कमजोर बनाता है।

संपादित करें:

मानक में सब कुछ सही नहीं है। मैक्रो NULL एक कार्यान्वयन-परिभाषित C ++ null पॉइंटर है जो पूरी तरह से C NULL मैक्रो के साथ पूरी तरह से संगत नहीं है, इसके अलावा जो प्रकार छिपाना निहित है वह इसे एक बेकार में बदल देता है और त्रुटियों टूल में प्रवण होता है।

NULL एक अशक्त सूचक के रूप में नहीं बल्कि O / OL शाब्दिक के रूप में व्यवहार करता है।

मुझे बताएं अगला उदाहरण भ्रमित करने वाला नहीं है:

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

इन सबके कारण, नए मानक में std :: nullptr_t प्रकट होता है

यदि आप नए मानक के लिए इंतजार नहीं करना चाहते हैं और नल्टर का उपयोग करना चाहते हैं, तो मेयर्स द्वारा प्रस्तावित की तरह कम से कम एक सभ्य का उपयोग करें (देखें jon.h टिप्पणी)।


5
NULLC ++ मानक का एक अच्छी तरह से परिभाषित हिस्सा है। अपने प्रोजेक्ट में मानक मैक्रो एडिट कोड को फिर से परिभाषित करना पसंद करने वाले लोगों को आपके कोड को 'असुरक्षित' बनाता है; का उपयोग NULLनहीं करता है।
CB Bailey

1

वैसे मैं जब भी संभव हो 0 या NULL पॉइंटर्स का उपयोग नहीं करने का तर्क देता हूं।

इनका उपयोग करना आपके कोड में जल्द या बाद में विभाजन दोष पैदा करेगा। मेरे अनुभव में, और गेरालर में संकेत C ++ में बग के सबसे बड़े स्रोत में से एक है

इसके अलावा, यह आपके कोड पर "if-not-null" स्टेटमेंट की ओर जाता है। बहुत अच्छे अगर आप हमेशा एक वैध स्थिति पर भरोसा कर सकते हैं।

लगभग हमेशा एक बेहतर विकल्प होता है।


2
एक गारंटी विभाजन गलती (और यह है आधुनिक प्रणालियों पर इसकी गारंटी है जब आप भिन्नता 0) है उपयोगी डीबगिंग के लिए। बेतरतीब कचरे को हटाने और जो परिणाम होता है उसे जानने से बेहतर है।
ऑर्बिट

-4

0 के लिए एक सूचक सेट करना केवल इतना स्पष्ट नहीं है। खासकर अगर आपको C ++ के अलावा कोई भाषा आती है। इसमें सी के साथ-साथ जावास्क्रिप्ट भी शामिल है।

मैं हाल ही में कुछ कोड के साथ delt कर रहा हूँ:

virtual void DrawTo(BITMAP *buffer) =0;

पहली बार शुद्ध आभासी कार्य के लिए। मैंने सोचा कि यह एक सप्ताह के लिए कुछ जादू की झबरजश होगी। जब मैंने महसूस किया कि यह मूल रूप से फ़ंक्शन पॉइंटर को ए पर सेट कर रहा था null(क्योंकि वर्चुअल फ़ंक्शंस सिर्फ C ++ के अधिकांश मामलों में फ़ंक्शन पॉइंटर हैं) तो मैंने खुद को लात मारी।

virtual void DrawTo(BITMAP *buffer) =null;

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


सामान्य तौर पर मैं पॉइंटर्स के लिए NULl से 0 पसंद करता हूं। हालाँकि '= 0?' C ++ में शुद्ध आभासी फ़ंक्शन घोषित करने का एक मुहावरेदार तरीका है। मैं आपको दृढ़ता से सलाह दूंगा कि आप '= NULL' का उपयोग न करें। इस विशेष मामले के लिए।
डानियो

यह StackOverflow पर सबसे मजेदार टिप्पणी है। आप शायद पहले से ही अब जानते हैं कि आपने जो उदाहरण दिया है वह शुद्ध आभासी फ़ंक्शन के लिए एक सिंटैक्स है न कि एक सूचक। और हाँ @danio सही है, आपको शुद्ध आभासी फ़ंक्शन के लिए NULL का उपयोग नहीं करना चाहिए।
sgowd
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.