2017-12-16 28 views
10

वर्तमान में मैं बार्न स्ट्रास्ट्रुप द्वारा "सी ++ का दौरा" पढ़ रहा हूं। बात यह है कि मायने रखती है:ठीक से nullptr का उपयोग कैसे करें?

int count_x(char* p, char x) 
// count the number of occurrences of x in p[] 
// p is assumed to point to a zero-terminated array of char (or to nothing) 
{ 

    if (p == nullptr) return 0; 
     int count = 0; 

    for (; p != nullptr; ++p) 
     if (*p == x) 
      ++count; 

    return count; 
} 

मेरे अपने मुख्य:

int main(){ 

    char* str = "Good morning!"; 
    char c = 'o'; 
    std::cout << count_x(str, c) << std::endl; 

    return 0; 
} 

जब मैं कार्यक्रम चलाने यह मैं दुर्घटनाओं "संकेत दिए गए, सरणियों और संदर्भ" पर वह इस तरह nullptr उपयोग के बारे में उदाहरण दिया एक अपवाद लाइन

if (*p == x) 

पर फेंके गए हो, तो मैं पाश को बदलने के लिए इस तरह बनना:

for (; *p; p++) 
    if (*p == x) 
     ++count; 

अब सब ठीक काम करता है! मैं एमएसवीसी ++ 14.0 का उपयोग कर रहा हूँ।

  • एक ही कोड मैं ideone पर चलता था मैं एक अपवाद नहीं मिलता है, लेकिन परिणाम हमेशा 0 है जो 3 होना चाहिए:

https://ideone.com/X9BeVx

+1

@ डीईडीई: हाँ मैंने अभी कोड कॉपी और चिपकाया है। जो मैं जोड़ता हूं वह मुख्य कोड है। – WonFeiHong

+1

@DeiDei: यह कैसे सही होना चाहिए: '* p! = Nullptr'? जैसा कि मुझे लगता है कि 'nullptr' केवल पतों के पॉइंटर्स के लिए है, वे उस बिंदु पर इंगित नहीं करते हैं, जिसे वे संबोधित करते हैं। – WonFeiHong

+5

मुझे "सी ++ का दौरा" के लिए किसी भी इरेटा में यह नहीं मिला। आपको बजरने को लिखना चाहिए और उसे बताना चाहिए। यह एक गलती है। – StoryTeller

उत्तर

14

p != nullptr और *p बहुत अलग जांच।

पूर्व जांच करता है कि सूचक में स्वयं एक गैर-शून्य पता होता है। जबकि उत्तरार्द्ध जांचता है कि उस पते पर ध्यान दिया गया है जो 0 नहीं है। लूप में स्पष्ट रूप से उपयुक्त है, जहां बफर की सामग्री की जांच की जाती है, जबकि दूसरा नहीं है।

आप segfault क्योंकि आप कभी भी बफर को पढ़ना बंद नहीं करते हैं (एक वैध सूचक जो बढ़ने पर शून्य उत्पन्न करने की संभावना नहीं है)। तो आप अपनी बफर सीमा से परे पहुंचने का रास्ता समाप्त कर देते हैं।

+1

लेकिन यह गलत माना जाता है: '* p = nullptr' है ना? – WonFeiHong

+3

@WonFeiHong - हाँ, यह गलत होगा। '* पी' में पॉइंटर प्रकार नहीं है, इसलिए इसे 'nullptr' से तुलना करना संभव नहीं होगा। जब आप – StoryTeller

+1

आज़माते हैं तो आपको एक कंपाइलर त्रुटि मिल जाएगी यदि आप तुलना को अधिक स्पष्ट बनाना चाहते हैं तो आप * पी! = '\ 0' कर सकते हैं, हालांकि बस * पी ठीक काम करता है ... –

0

याद रखें कि आप सी भाषा सुविधा का उपयोग कर रहे हैं।

आपकी समस्या आपके for लूप में है। पॉइंटर आपके वर्ण सरणी के अंतिम तत्व तक पहुंचने के बाद यह nullptr पर सरणी के अंत तक इंगित करता है।

कल्पना कीजिए कि आप

 +-----+  +---+---+---+---+---+---+ 
ptr :| *======> | w | o | r | l | d |\0 | 
    +-----+  +---+---+---+---+---+---+ 

पिछले तत्व के लिए इस तरह के रूप const char *a ="world" और ptr अंक एक चरित्र सरणी जो ptr अंक '\0' और अपनी for आप नीचे के रूप में अपने कोड बदलना चाहिए है करने के लिए है:


for (; *p != 0; p++) { 
     if (*p == x) 
      ++count; 
    } 

उत्पादन: 3

+0

@ हनीफ्लैट- आप क्या उम्मीद कर रहे हैं मुझे करना है –

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