2009-09-27 15 views
11

चलें कहते हैं कि हम चार संकेतchar * का ऐरे ' 0' या " 0" पर समाप्त होना चाहिए?

char* array[] = { "abc", "def" }; 

अब क्या अंत में रखा जाना चाहिए की एक सरणी है?

char* array[] = { "abc", "def", '\0' }; 

या

char* array[] = { "abc", "def", "\0" }; 

हालांकि, दोनों काम करता है। हम केवल अंत तदनुसार

array[ index ] != '\0'; 

या

तरह जांच करने के लिए शर्त डाल करने के लिए है
array[ index ] != "\0"; 

मेरा प्रश्न जो एक बेहतर तरीका है? अधिकांश प्रोग्रामर द्वारा किसका उपयोग किया जाता है?

संपादित

अधिकांश जवाब का कहना है कि शून्य '\ 0' और "\ 0" से बेहतर है। लेकिन मैं हमेशा सोचा था कि

शून्य जो 0x0 या 0

यह गलत है के रूप में ही है के रूप में '\ 0' एक ही है?

+1

संपादित करें, सी शून्य में के बारे में एक सूचक (आमतौर पर परिभाषित (शून्य *) 0। '\ 0' एक चरित्र स्थिर है जब एक चरित्र निरंतर जहां एक सूचक की उम्मीद है का उपयोग कर रहा है। तो, और अंतर्निहित रूपांतरण होता है। यह रूप में एक पूर्ण सूचक में किसी भी पूर्णांक शून्य परिणामों का रूपांतरण होता है, लेकिन यह स्पष्ट नहीं करता है कि आप एक सूचक का इरादा रखते हैं। एक शाब्दिक निरंतर पूर्णांक शून्य आईएमओ का उपयोग करना बेहतर है। जैसा कि सी ++ में होता है, यह किसी भी पसंदीदा तरीका है मामला है, लेकिन C++ शून्य मैक्रो भी उस तरह से परिभाषित किया गया है 'का उपयोग करते हुए '\ 0'' एक' char' जो की तुलना सेब की तरह है करने के लिए एक 'चार *' तुलना कर रहा है (अपने संकलक के मानक हेडर फाइल में एक बार देख ले)। – Clifford

उत्तर

24

मैं इसे NULL के साथ समाप्त कर दूंगा। क्यूं कर? आप इनमें से किसी ऐसा नहीं कर सकते क्योंकि:

array[index] == '\0' 
array[index] == "\0" 

पहले एक एक char, जो नहीं है कि आप क्या चाहते करने के लिए एक char * तुलना कर रहा है। आपको यह करना होगा:

array[index][0] == '\0' 

दूसरा वाला काम भी नहीं करता है। आप char * की तुलना char * से कर रहे हैं, हां, लेकिन यह तुलना व्यर्थ है। यह गुजरता है अगर दो पॉइंटर्स स्मृति के एक ही टुकड़े को इंगित करते हैं। आप दो स्ट्रिंग्स की तुलना करने के लिए == का उपयोग नहीं कर सकते हैं, आपको strcmp() फ़ंक्शन का उपयोग करना होगा, क्योंकि सी में कुछ (और मेरा मतलब है) सिंटैक्टिक नब्बे के बाहर तारों के लिए कोई अंतर्निहित समर्थन नहीं है। जबकि निम्नलिखित:

array[index] == NULL 

बस ठीक काम करता है और आपके बिंदु को व्यक्त करता है।

+0

पर इंगित किया, वास्तव में, 'char * 'तुलना शायद ओपी के लिए काम करती थी, क्योंकि संकलक ने दो समान स्ट्रिंग अक्षर को एकीकृत किया था। मैं मानता हूं कि सिद्धांत सिद्धांत रूप में अर्थहीन है। –

+0

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

+1

क्या NULL '\ 0' जैसा नहीं है? मैं समझता हूं कि NULL == '\ 0' == 0x0। गलत है? –

0

अच्छा, तकनीकी रूप से '\0' एक चरित्र है जबकि "\0" एक स्ट्रिंग है, इसलिए यदि आप शून्य समाप्ति चरित्र की जांच कर रहे हैं तो पूर्व सही है। हालांकि, Chris Lutz points out in his answer के रूप में, आपकी तुलना इसके वर्तमान स्वरूप में काम नहीं करेगी।

+0

।। संतरे को न तो सही, सच है –

+1

@Chris: - कि क्या क्रिस लू का उपयोग कर ' '\ 0'' एक' int' Christoph

+0

@Christoph करने के लिए एक 'चार *' तुलना कर रहा है टीजी ने बताया।मेरे उत्तर को अपडेट करने के बजाय मैंने अपने उत्तर को – ChrisF

5

इन दोनों में से पहला, एक प्रकार की गलती है: '\ 0' एक चरित्र है, पॉइंटर नहीं। कंपाइलर अभी भी इसे स्वीकार करता है क्योंकि यह इसे एक सूचक में परिवर्तित कर सकता है।

दूसरा दूसरा संयोग से "काम करता है"। "\ 0" दो अक्षरों का एक स्ट्रिंग अक्षर है। यदि वे स्रोत फ़ाइल में एकाधिक स्थानों पर होते हैं, तो संकलक हो सकता है, लेकिन उन्हें समान बनाने की आवश्यकता नहीं है।

तो उचित तरीके से पहले एक लिखने के लिए

char* array[] = { "abc", "def", NULL }; 

है और आप array[index]==NULL के लिए परीक्षण। दूसरे के लिए परीक्षण करने का उचित तरीका array[index][0]=='\0' है; आप स्ट्रिंग में '\ 0' भी छोड़ सकते हैं (यानी इसे "" के रूप में वर्तनी करें) क्योंकि इसमें पहले से ही एक शून्य बाइट शामिल होगा।

+0

मुझे यह दिलचस्प लगता है कि इस समस्या में दो उत्तरों हैं जो काम करते हैं, लेकिन न तो तकनीकी रूप से सही है, और न ही ओपी सोचता है कि वे क्या सोचते हैं। –

0

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

+0

सम्मेलन चर-लंबाई सरणी के लिए है: NULL को सेंटीनेल मान के रूप में उपयोग करें। – u0b34a0f6ae

6

C99 कल्पना के अनुसार,

  • NULL लगातार एक अशक्त सूचक है, जो हो सकता है की आवश्यकता नहीं है के लिए विस्तारित, लेकिन आम तौर void *
  • '\0' एक चरित्र स्थिर है प्रकार की है; चरित्र स्थिरांक प्रकार int के हैं, तो यह सादा 0
  • "\0" को equivalen है एक अशक्त-समाप्त स्ट्रिंग शाब्दिक और मिश्रित शाब्दिक (char [2]){ 0, 0 }

NULL, '\0' और 0 सभी नल पॉइंटर स्थिरांक हैं के बराबर है, तो वे ', रूपांतरण पर सभी उपज अशक्त संकेत करेंगे जबकि "\0" पैदावार एक गैर-शून्य char * (के रूप में संशोधन अपरिभाषित है const के रूप में व्यवहार किया जाना चाहिए जो); क्योंकि यह सूचक शाब्दिक के प्रत्येक अवसर के लिए अलग हो सकता है, इसे सेंटीनेल मान के रूप में उपयोग नहीं किया जा सकता है।

हालांकि आप एक नल पॉइंटर निरंतर ('\0' जैसे या sizeof foo - sizeof foo + (int)0.0) के रूप में मूल्य 0 के किसी भी पूर्णांक निरंतर अभिव्यक्ति का उपयोग कर सकते हैं, तो आप NULL का उपयोग अपने इरादों स्पष्ट करना चाहिए।

+0

हालांकि * वास्तव में * नाइट पिकिंग होने के बावजूद, 'NULL' को शून्य सूचक में विस्तारित किया जाता है, यदि इसे' (शून्य *) 0' के रूप में परिभाषित किया गया है (जिस स्थिति में यह दोनों और शून्य सूचक स्थिर है) :) यदि ऐसा होता है '0' या इसी तरह के होने के लिए, यह केवल एक शून्य सूचक स्थिर है, जिसे अभी तक एक शून्य सूचक में परिवर्तित किया जाना है :) –

+0

@litb: वास्तव में, '' \ 0 'शायद वैध शून्य सूचक स्थिर नहीं हो सकता है एक चरित्र निरंतर (सी 99 6.4.4.4) और एक पूर्णांक निरंतर नहीं (सी 99 6.4.4.1); चरित्र स्थिरांक को कभी-कभी पूर्णांक वर्ण स्थिरांक कहा जाता है, लेकिन क्या यह उन्हें C99 6.3.2.3 द्वारा आवश्यक "पूर्णांक निरंतर अभिव्यक्ति" बनाता है? – Christoph

+0

@ क्रिस्टोप 6.6/6 :) –

-1

अशक्त समाप्ति एक बुरा डिजाइन पैटर्न सबसे अच्छा इतिहास की पुस्तकों में छोड़ दिया है। सी-तारों के पीछे अभी भी जड़ता है, इसलिए इसे टाला नहीं जा सकता है। लेकिन ओपी के उदाहरण में इसका इस्तेमाल करने का कोई कारण नहीं है। (सरणी [0]) तत्वों की संख्या प्राप्त करने के लिए

किसी भी टर्मिनेटर का उपयोग न करें, और sizeof (सरणी)/sizeof का उपयोग करें।

+1

+1 को आकार के सरणी/आकार के सरणी के लिए क्यों नहीं खोजा [0]। लेकिन क्या आपको लगता है कि टर्मिनेटर का उपयोग न करने के लिए पर्याप्त कारण है? –

+1

यह केवल तभी काम करता है जब सरणी को दायरे में घोषित किया जाता है - यदि यह पॉइंटर द्वारा पारित किया जाता है तो आप 'sizeof (array)' नहीं कर सकते हैं और आप केवल पैरामीटर के माध्यम से आकार को पार करके लंबाई प्राप्त कर सकते हैं, या शून्य टर्मिनेटर की खोज कर सकते हैं । –

+0

मुझे और स्पष्ट होना चाहिए था। अपने सरणी के साथ-साथ चारों ओर तत्वों की संख्या पास करें। एक टर्मिनेटर का उपयोग करने से सुरक्षित और अधिक स्पष्ट। – Alan

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