क्या N PULL को C पॉइंटर इनिशियलाइज़ करना संभव है?


90

मैं जैसी बातें लिखता रहा था

char *x=NULL;

इस धारणा पर

 char *x=2;

char2 पता करने के लिए एक पॉइंटर बनाएगा ।

लेकिन, द जीएनयू सी प्रोग्रामिंग ट्यूटोरियल में यह कहा गया है कि जब यह आवंटित किया जाता है तो जो भी यादृच्छिक पता होता है int *my_int_ptr = 2;वह पूर्णांक मान 2को संग्रहीत करता my_int_ptrहै।

इसका अर्थ करने के लिए अपने ही है कि प्रतीत होता है char *x=NULLबताए है जो कुछ के मूल्य में NULLएक करने के लिए डाली charस्मृति में कुछ यादृच्छिक पता है।

जबकि

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char *x=NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

वास्तव में, प्रिंट करता है

शून्य है

जब मैं इसे संकलित करता हूं और इसे चलाता हूं, तो मुझे चिंता है कि मैं अपरिभाषित व्यवहार पर, या कम से कम अंडर-निर्दिष्ट व्यवहार पर भरोसा कर रहा हूं, और मुझे लिखना चाहिए

char *x;
x=NULL;

बजाय।


72
वहाँ क्या int *x = whatever;करता है और क्या int *x; *x = whatever;करता है के बीच एक बहुत भ्रामक अंतर है। int *x = whatever;वास्तव में जैसा व्यवहार करता है int *x; x = whatever;, वैसा नहीं *x = whatever;
user2357112

78
ऐसा लगता है कि इस ट्यूटोरियल में गलतफहमी पैदा हो गई है।
user2357112

51
वेब पर बहुत सारे चमकदार ट्यूटोरियल! तुरंत पढ़ना बंद कर दें। हमें वास्तव में एक SO ब्लैकलिस्ट की आवश्यकता है जहां हम सार्वजनिक रूप से भद्दी किताबों को शर्मिंदा कर सकें ...
लुंडिन

9
@MM जो 2017 में इसे कम भद्दा नहीं बनाता है। 80 के दशक के बाद से कंपाइलर्स और कंप्यूटर के विकास को देखते हुए, यह मूल रूप से एक ही बात है जैसे कि मैं 18 वीं शताब्दी के दौरान लिखी गई एक डॉक्टर और रीडिंग मेडिसिन की किताबें थीं।
लंडिन

13
मुझे नहीं लगता कि यह ट्यूटोरियल " GNU C प्रोग्रामिंग ट्यूटोरियल" के रूप में योग्य है ...
marcelm

जवाबों:


114

क्या N PULL को C पॉइंटर इनिशियलाइज़ करना संभव है?

टीएल; डीआर हाँ, बहुत।


वास्तविक गाइड पर किए गए दावे की तरह पढ़ता है

दूसरी ओर, यदि आप केवल एकल प्रारंभिक असाइनमेंट का उपयोग करते हैं int *my_int_ptr = 2;, तो प्रोग्राम my_int_ptr2 द्वारा बताए गए मेमोरी लोकेशन की सामग्री को भरने का प्रयास करेगा । 2 क्योंकि my_int_ptrकचरा भरा हुआ है, इसलिए यह कोई भी पता हो सकता है। [...]

खैर, वे कर रहे हैं गलत है, तो आप सही हैं।

बयान के लिए, ( अब के लिए, इस तथ्य को अनदेखा करना, कि पूर्णांक रूपांतरण के लिए सूचक एक कार्यान्वयन-परिभाषित व्यवहार है )

int * my_int_ptr = 2;

my_int_ptrएक वैरिएबल (टाइप पॉइंटर से int) है, इसका अपना एक पता है (टाइप: पॉइंटर से पूर्णांक तक का पता), आप उस एड्रेस 2में एक वैल्यू स्टोर कर रहे हैं ।

अब, my_int_ptr, एक सूचक प्रकार किया जा रहा है, हम इसे कह सकते हैं, की ओर इशारा करता स्मृति स्थान पर "प्रकार" का मान द्वारा बताया में आयोजित मूल्य my_int_ptr। तो, आप अनिवार्य रूप से पॉइंटर वैरिएबल का मान असाइन कर रहे हैं , न कि पॉइंटर द्वारा बताई गई मेमोरी लोकेशन की वैल्यू।

तो, निष्कर्ष के लिए

 char *x=NULL;

पॉइंटर वैरिएबल xको इनिशियलाइज़ करता है NULL, न कि पॉइंटर द्वारा बताए गए मेमोरी एड्रेस पर वैल्यू

यह भी ऐसा ही है

 char *x;
 x = NULL;    

विस्तार:

अब, कड़ाई से अनुरूप, एक बयान की तरह

 int * my_int_ptr = 2;

अवैध है, क्योंकि इसमें बाधा उल्लंघन शामिल है। स्पष्ट होना,

  • my_int_ptr एक सूचक चर है, टाइप करें int *
  • एक पूर्णांक निरंतर, 2प्रकार है intपरिभाषा के द्वारा,।

और वे "संगत" प्रकार नहीं हैं, इसलिए यह आरंभीकरण अमान्य है क्योंकि यह सरल असाइनमेंट के नियमों का उल्लंघन कर रहा है, जिसका उल्लेख लुंडिन के उत्तर में वर्णित अध्याय .16.5.16.1 / P1 में किया गया है ।

यदि किसी की दिलचस्पी इस बात से है कि आरंभीकरण कैसे सरल असाइनमेंट की कमी से जुड़ा है, तो उद्धृत करना C11, अध्याय §6.7.9, P11

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


@ Random832n वे कर रहे हैं गलत। मैंने अपने उत्तर में संबंधित भाग उद्धृत किया है, कृपया मुझे सही करें अन्यथा। ओह, और जानबूझकर जोर दिया।
सौरव घोष

"" गैरकानूनी है, क्योंकि इसमें बाधा उल्लंघन शामिल है ... एक पूर्णांक शाब्दिक, 2 का प्रकार int है, परिभाषा के अनुसार। " समस्याग्रस्त है। ऐसा लगता है क्योंकि 2एक है int, असाइनमेंट एक समस्या है। परंतु यह इससे अधिक है। NULLint, ए भी हो सकता है int 0। यह सिर्फ इतना char *x = 0;है कि अच्छी तरह से परिभाषित है और char *x = 2;नहीं है। 6.3.2.3 प्वाइंटर 3: Btw (सी एक को परिभाषित नहीं करता पूर्णांक शाब्दिक , केवल स्ट्रिंग शाब्दिक और यौगिक शाब्दिक0एक है पूर्णांक निरंतर )
को पुनः स्थापित मोनिका - chux

@chux आप बहुत सही हैं, लेकिन यह char *x = (void *)0;अनुरूप नहीं है? या यह केवल अन्य भावों के साथ है जो मूल्य देता है 0?
सौरव घोष

10
@ सौरवघोष: मान के साथ पूर्णांक स्थिरांक 0विशेष हैं: वे स्पष्ट रूप से सामान्य पूर्णांक अभिव्यक्तियों को सूचक प्रकारों के लिए सामान्य नियमों से अलग नल बिंदुओं में परिवर्तित करते हैं।
स्टीव जेसोप

1
1974 सी संदर्भ नियमावली द्वारा वर्णित भाषा ने आरंभिक अभिव्यक्तियों को निर्दिष्ट करने की अनुमति नहीं दी, और ऐसे अभिव्यक्तियों की कमी "घोषणा दर्पण का उपयोग" को अधिक व्यावहारिक बनाती है। सिंटैक्स int *p = somePtrExpressionIMHO है बल्कि भयानक है क्योंकि ऐसा लगता है कि यह मूल्य निर्धारित कर रहा है, *pलेकिन यह वास्तव में मूल्य निर्धारित कर रहा है p
22

53

ट्यूटोरियल गलत है। आईएसओ सी में, int *my_int_ptr = 2;एक त्रुटि है। जीएनयू सी में, इसका मतलब उसी के समान है int *my_int_ptr = (int *)2;। यह पूर्णांक 2द्वारा निर्धारित किए गए अनुसार, कुछ अंदाज में पूर्णांक को मेमोरी एड्रेस में परिवर्तित करता है ।

यह उस पते (यदि कोई है) द्वारा संबोधित स्थान में कुछ भी संग्रहीत करने का प्रयास नहीं करता है। यदि आप लिखने के लिए गए थे *my_int_ptr = 5;, तो यह 5उस पते द्वारा बताए गए स्थान पर संख्या को संग्रहीत करने का प्रयास करेगा ।


1
मुझे नहीं पता था कि पॉइंटर से पॉइंटर कन्वर्ज़न लागू होना परिभाषित है। जानकारी के लिए धन्यवाद।
टास्किनॉर

1
@taskinoor कृपया ध्यान दें कि इस स्थिति में केवल एक रूपांतरण है जो आप इसे एक कलाकार द्वारा मजबूर करते हैं, जैसा कि इस उत्तर में है। यदि कलाकारों के लिए नहीं है, तो कोड को संकलित नहीं करना चाहिए।
लुंडिन

2
@taskinoor: हाँ, C में विभिन्न रूपांतरण काफी भ्रामक हैं। इस प्रश्न में रूपांतरणों पर दिलचस्प जानकारी है: C: जब सूचक प्रकारों के बीच कास्टिंग होती है तो अपरिभाषित व्यवहार नहीं होता है?
साल्स्के

17

यह स्पष्ट करने के लिए कि ट्यूटोरियल गलत क्यों है, int *my_int_ptr = 2;एक "बाधा उल्लंघन" है, यह कोड है जिसे संकलित करने की अनुमति नहीं है और संकलक को इसका सामना करने पर आपको एक निदान देना होगा।

6.5.16.1 सरल कार्य के अनुसार:

प्रतिबन्ध

निम्नलिखित में से एक धारण करेगा:

  • बाएं ऑपरेंड में परमाणु, योग्य, या अयोग्य अंकगणित प्रकार होते हैं, और दाईं ओर अंकगणितीय प्रकार होते हैं;
  • बाएं ऑपरेंड में एक संरचना का एक परमाणु, योग्य या अयोग्य संस्करण है या राइट के प्रकार के साथ संगत यूनियन प्रकार;
  • बाएं ऑपरेंड में परमाणु, योग्य, या अयोग्य सूचक प्रकार होता है, और (लेवल रूपांतरण के बाद बाएं ऑपरेंड के प्रकार पर विचार करते हुए) दोनों ऑपरेंड संगत प्रकारों के योग्य या अयोग्य संस्करणों के संकेत होते हैं, और बाईं ओर से टाइप किए गए प्रकार सभी होते हैं इस प्रकार के क्वालिफायर को दाईं ओर इंगित किया गया है;
  • बाएं ऑपरैंड में परमाणु, योग्य, या अयोग्य सूचक सूचक प्रकार होता है, और (बाएं प्रकार को बदलने के बाद लेवुए रूपांतरण के बाद का प्रकार होता है) एक ऑपरेंड एक ऑब्जेक्ट प्रकार का एक संकेतक है, और दूसरा एक योग्य या अयोग्य संस्करण के लिए एक संकेतक है शून्य, और बाईं ओर से टाइप किए गए प्रकार में दाईं ओर इंगित किए गए प्रकार के सभी क्वालिफायर हैं;
  • बाएं ऑपरेंड एक परमाणु, योग्य, या अयोग्य सूचक है, और दाईं ओर एक अशक्त सूचक स्थिरांक है; या
  • बाएं ऑपरेंड में परमाणु, योग्य, या अयोग्य _बूल टाइप होता है, और दाईं ओर एक पॉइंटर होता है।

इस मामले में बाएं ऑपरेंड एक अयोग्य सूचक है। कहीं भी यह उल्लेख नहीं है कि सही ऑपरेंड को पूर्णांक (अंकगणित प्रकार) होने की अनुमति है। तो कोड सी मानक का उल्लंघन करता है।

जीसीसी को खराब व्यवहार करने के लिए जाना जाता है जब तक कि आप स्पष्ट रूप से इसे मानक सी कंपाइलर नहीं बताते हैं। यदि आप कोड को संकलित करते हैं -std=c11 -pedantic-errors, तो यह सही ढंग से एक निदान देगा जैसा कि उसे करना चाहिए।


4
सुझाव देने के लिए upvoted- संवेदनशीलता-त्रुटियों। हालांकि मैं संभवत: संबंधित -वेद्यात्मक का उपयोग करूंगा।
फगरिकिपनी

2
आपके कथन का एक अपवाद है कि सही ऑपरेंड को पूर्णांक बनने की अनुमति नहीं है: धारा 6.3.2.3 कहता है, "मान 0 के साथ पूर्णांक निरंतर अभिव्यक्ति, या टाइप करने के लिए डाली गई ऐसी अभिव्यक्ति void *, एक शून्य सूचक स्थिरांक कहलाता है।" अपनी बोली में दूसरे-से-अंतिम बुलेट बिंदु पर ध्यान दें। इसलिए, int* p = 0;लिखने का एक कानूनी तरीका है int* p = NULL;। यद्यपि उत्तरार्द्ध स्पष्ट और अधिक पारंपरिक है।
डेविसलर

1
जो पैथोलॉजिकल ऑबफ्यूजन को int m = 1, n = 2 * 2, * p = 1 - 1, q = 2 - 1;भी कानूनी बनाता है।
डेविसलर

@Davislor इस उत्तर में मानक उद्धरण में बुलेट पॉइंट 5 द्वारा कवर किया गया है (सहमत हैं कि सारांश बाद में संभवतः इसका उल्लेख करना चाहिए)
MM

1
@ मुझे लगता है कि एक अच्छी तरह से गठित कार्यक्रम को intptr_tदाएं-हाथ की अनुमति वाले प्रकारों में से एक में स्पष्ट रूप से परिवर्तित करने की आवश्यकता होगी । यही है, void* a = (void*)(intptr_t)b;बिंदु 4 द्वारा कानूनी है, लेकिन (intptr_t)bन तो एक संगत पॉइंटर प्रकार है, न ही ए void*, और न ही एक न्यूल पॉइंटर स्थिर है, और void* aन तो एक अंकगणितीय प्रकार है और न ही _Bool। मानक कहता है कि रूपांतरण कानूनी है, लेकिन ऐसा नहीं है कि यह निहित है।
डेविसलर

15

int *my_int_ptr = 2

जब यह आवंटित किया जाता है, तो जो कुछ भी यादृच्छिक पता my_int_ptr में है, पूर्णांक मान को संग्रहीत करता है।

यह पूरी तरह से गलत है। यदि यह वास्तव में लिखा गया है, तो कृपया एक बेहतर पुस्तक या ट्यूटोरियल प्राप्त करें।

int *my_int_ptr = 2एक पूर्णांक सूचक को परिभाषित करता है जो पता 2 को इंगित करता है। यदि आप पते तक पहुंचने का प्रयास करते हैं तो आपको सबसे अधिक दुर्घटना होने की संभावना होगी 2

*my_int_ptr = 2, यानी intलाइन के बिना , जो भी यादृच्छिक पता my_int_ptrइंगित कर रहा है , उसके लिए मूल्य दो संग्रहीत करता है। यह कहने के बाद, आप NULLएक पॉइंटर को असाइन कर सकते हैं जब यह परिभाषित किया जाता है। char *x=NULL;पूरी तरह से वैध सी है।

संपादित करें: यह लिखते समय मुझे पता नहीं था कि सूचक रूपांतरण के लिए पूर्णांक कार्यान्वयन परिभाषित व्यवहार है। कृपया विवरण के लिए @MM और @SouravGhosh द्वारा अच्छे उत्तर देखें।


1
यह पूरी तरह से गलत है क्योंकि यह किसी अन्य कारण से नहीं, बल्कि एक बाधा का उल्लंघन है। विशेष रूप से, यह गलत है: "int * my_int_ptr = 2 एक पूर्णांक सूचक को परिभाषित करता है जो 2 पते को इंगित करता है"।
लुंडिन

@ लुंडिन: आपका वाक्यांश "किसी अन्य कारण से नहीं" स्वयं गलत और भ्रामक है। यदि आप टाइप संगतता समस्या को ठीक करते हैं, तो आप अभी भी इस तथ्य से बचे हुए हैं कि ट्यूटोरियल का लेखक गलत तरीके से यह बता रहा है कि पॉइंटर इनिशियलाइज़ेशन और असाइनमेंट कैसे काम करते हैं।
को ऑर्बिट

14

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

int *x = NULL;सही सी है, लेकिन यह बहुत ही भ्रामक है, मैं इसे बकवास भी कहूंगा, और इसने कई नौसिखियों के लिए भाषा की समझ को बाधित किया है। यह सोचता है कि बाद में हम ऐसा कर सकते हैं *x = NULL;जो कि असंभव है। आप देखते हैं, चर का प्रकार नहीं है int, और चर का नाम नहीं है *x, और न ही *घोषणा में के साथ सहयोग में कोई कार्यात्मक भूमिका निभाता है =। यह विशुद्ध रूप से घोषणात्मक है। तो, यह बहुत अधिक समझ में आता है:

int* x = NULL;यह भी सही C है, यद्यपि यह मूल K & R कोडिंग शैली का पालन नहीं करता है। यह पूरी तरह से स्पष्ट करता है कि प्रकार है int*, और पॉइंटर चर है x, इसलिए यह स्पष्ट रूप से स्पष्ट हो जाता है कि यहां तक ​​कि बिना मूल्य NULLके भी संग्रहीत किया जा रहा है x, जो कि एक पॉइंटर है int

इसके अलावा, एक नियम को प्राप्त करना आसान बनाता है: जब स्टार वैरिएबल नाम से दूर होता है तो यह एक घोषणा है, जबकि स्टार को नाम से जोड़ा जा रहा है, पॉइंटर डेरेफेरिंग है।

तो, अब यह एक बहुत अधिक समझ में आता है और आगे हम या तो कर सकते हैं नीचे है कि हो जाता है x = NULL;या *x = 2;दूसरे शब्दों में यह यह आसान तरीका देखने के लिए एक नौसिखिया के लिए बनाता है variable = expressionपर ले जाया जाता pointer-type variable = pointer-expressionहै और dereferenced-pointer-variable = expression। (शुरुआत के लिए, 'अभिव्यक्ति' से मेरा मतलब है 'व्याप्त')।

भाषा की वाक्य रचना में दुर्भाग्यपूर्ण विकल्प यह है कि स्थानीय चर घोषित करते समय आप कह सकते हैं कि int i, *p;पूर्णांक और पूर्णांक को एक सूचक घोषित करता है, इसलिए यह विश्वास दिलाता है कि *नाम का एक उपयोगी हिस्सा है। लेकिन यह नहीं है, और यह वाक्यविन्यास सिर्फ एक विचित्र विशेष मामला है, सुविधा के लिए जोड़ा गया है, और मेरी राय में इसका अस्तित्व कभी नहीं होना चाहिए, क्योंकि यह उस नियम को अमान्य करता है जिसे मैंने ऊपर प्रस्तावित किया था। जहां तक ​​मुझे पता है, भाषा में कहीं भी यह वाक्यविन्यास सार्थक नहीं है, लेकिन अगर यह है, तो यह उस तरह की विसंगति की ओर इशारा करता है जिस तरह से सूचक प्रकार सी में परिभाषित किए गए हैं। हर जगह, एकल-चर घोषणाओं में, पैरामीटर सूचियों में। संरचना सदस्यों, आदि के रूप में आप के type* pointer-variableबजाय अपने संकेत की घोषणा कर सकते हैं type *pointer-variable; यह पूरी तरह से कानूनी है और अधिक समझ में आता है।


int *x = NULL; is correct C, but it is very misleading, I would even say nonsensical,... मुझे असहमत होने के लिए सहमत होना होगा। It makes one think.... सोचना बंद करो, पहले एक सी किताब पढ़ो, कोई अपराध नहीं।
सौरव घोष

^ ^ यह मेरे लिए एकदम सही समझ में आता है। इसलिए, मुझे लगता है कि यह व्यक्तिपरक है।
माइक नाइस

5
@SouravGhosh एक राय के रूप में मुझे लगता है कि सी को डिज़ाइन किया जाना चाहिए था, ताकि int* somePtr, someotherPtrदो बिंदुओं की घोषणा हो, वास्तव में, मैं लिखता था int* somePtrलेकिन यह उस बग की ओर जाता है जिसका आप वर्णन करते हैं।
फगिरिकिपनी

1
@fagricipni मैंने इस वजह से कई चर घोषणा सिंटैक्स का उपयोग करना बंद कर दिया। मैं एक-एक करके अपने चर घोषित करता हूं। यदि मैं वास्तव में उन्हें एक ही पंक्ति में चाहता हूं, तो मैं उन्हें कॉमा के बजाय अर्ध-कॉलोन के साथ अलग करता हूं। "अगर कोई जगह खराब है, तो उस जगह पर मत जाओ।"
माइक नकिस

2
@fagricipni ठीक है, अगर मैं linux को खरोंच से डिज़ाइन कर सकता था, तो मैं createइसके बजाय इस्तेमाल करता creat। :) बात यह है, यह है कि यह कैसे है और हमें उस के अनुकूल होने के लिए खुद को ढालना होगा। यह सभी दिन के अंत में व्यक्तिगत पसंद के लिए उबलता है, सहमत है।
सौरव घोष

6

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

int * p = NULL;
...
if (...) {
    p = (int*) malloc(...);
    ...
}
...
free(p);

चूंकि आईएसओ-आईईसी 9899 मानक के अनुसार freeजब तर्क होता है NULL, तो ऊपर दिया गया कोड (या उसी तर्ज पर कुछ और सार्थक) वैध होता है।


5
जब तक C कोड को C ++ के रूप में भी संकलित नहीं किया जाना चाहिए, तब तक C में मॉलॉक का परिणाम देना निरर्थक है।
बिल्ली

आप सही हैं, void*आवश्यकतानुसार परिवर्तित हो गया है। लेकिन एक C और C ++ कंपाइलर के साथ काम करने वाले कोड के लाभ हो सकते हैं।
लुका सिटी

1
@ लुकासी सी और सी ++ अलग-अलग भाषाएं हैं। यदि आप दूसरे के लिए डिज़ाइन किए गए कंपाइलर का उपयोग करके किसी एक के लिए लिखी गई स्रोत फ़ाइल को संकलित करने का प्रयास करते हैं तो केवल आपके लिए प्रतीक्षा करने में त्रुटियां हैं। यह सी कोड लिखने की कोशिश कर रहा है जिसे आप पास्कल टूल का उपयोग करके संकलित कर सकते हैं।
ईविल डॉग पाई

1
अच्छी सलाह। मैं (कोशिश करता हूं) हमेशा अपने पॉइंटर कांस्टेंट को किसी चीज से शुरू करूं। आधुनिक सी में, यह आमतौर पर उनका अंतिम मूल्य हो सकता है और वे औसत दर्जे के रेस मेंconst घोषित किए गए पॉइंटर्स हो सकते हैं , लेकिन यहां तक ​​कि जब एक पॉइंटर को म्यूटेबल होना चाहिए (जैसे कि एक लूप में या इसके द्वारा उपयोग किया जाता है realloc()), इसे NULLबग को पकड़ने के लिए सेट करना जहां यह पहले उपयोग किया जाता है। यह अपने वास्तविक मूल्य के साथ सेट है। अधिकांश प्रणालियों पर, डेरेफेरिंग NULLअसफलता के बिंदु पर एक सेगफॉल्ट का कारण बनता है (हालांकि अपवाद हैं), जबकि एक अनइंस्टॉल किए गए पॉइंटर में कचरा होता है और इसे लिखना मनमाना स्मृति को भ्रष्ट करता है।
डेविसलर

1
इसके अलावा, डिबगर में यह देखना बहुत आसान है कि एक पॉइंटर शामिल है NULL, लेकिन एक वैध से कचरा पॉइंटर को बताना बहुत मुश्किल हो सकता है। इसलिए यह सुनिश्चित करना उपयोगी है कि NULLघोषणा के क्षण से सभी संकेत हमेशा मान्य हैं या ।
डेविसलर


1

यह सही है।

int main()
{
    char * x = NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

यह कार्य जो करता है उसके लिए सही है। यह 0 के पते को चार सूचक x पर नियत करता है। यही है, यह पॉइंटर x को मेमोरी एड्रेस 0 पर इंगित करता है।

वैकल्पिक:

int main()
{
    char* x = 0;

    if ( !x )
        printf(" x points to NULL\n");

    return EXIT_SUCCESS;
}

मेरा अनुमान है कि आप क्या चाहते थे:

int main()
{
    char* x = NULL;
    x = alloc( sizeof( char ));
    *x = '2';

    if ( *x == '2' )
        printf(" x points to an address/location that contains a '2' \n");

    return EXIT_SUCCESS;
}

x is the street address of a house. *x examines the contents of that house.

"यह चार सूचक x को 0 का पता प्रदान करता है।" -> हो सकता है। C पॉइंटर का मान निर्दिष्ट नहीं करता है , केवल वही char* x = 0; if (x == 0)सत्य होगा। संकेत जरूरी पूर्णांक नहीं हैं।
chux -

यह 'पॉइंटर x को मेमोरी एड्रेस 0' पर इंगित नहीं करता है। यह सूचक मान को एक अनिर्दिष्ट अमान्य मान पर सेट करता है जिसे 0 या NULL से तुलना करके परीक्षण किया जा सकता है। वास्तविक ऑपरेशन कार्यान्वयन-परिभाषित है। यहाँ कुछ भी नहीं है जो वास्तविक प्रश्न का उत्तर देता है।
लोर्ने की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.