2012-05-24 12 views
5

तो मैं निम्नलिखित परीक्षण किया? मुझे पता है कि मैं पते की तुलना कर रहा हूं। यह तारों की तुलना करने के लिए नहीं है, लेकिन क्या समान स्ट्रिंग अक्षर एक स्मृति स्थान में संग्रहीत हैंस्ट्रिंग अक्षर जिसमें ' 0' है - वे समान क्यों नहीं हैं?</p> <pre><code>char* a = "test"; char* b = "test"; char* c = "test0"; </code></pre> <p>और अब सवाल:</p> <p>1) क्या यह है कि <code>a==b</code> गारंटी

2) a==c क्यों नहीं है? क्या संकलक यह देखने में सक्षम नहीं होना चाहिए कि वे एक ही स्ट्रिंग का जिक्र कर रहे हैं?

3) c के अंत में जोड़ा गया है, भले ही इसमें पहले से ही एक है?

मैं इसके लिए 3 अलग-अलग प्रश्न पूछना नहीं चाहता था क्योंकि वे किसी तरह से संबंधित, खेद है।

नोट: टैग सही है, मुझे सी ++ में रूचि है। (हालांकि कृपया निर्दिष्ट करें कि सी के लिए व्यवहार अलग है या नहीं)

+7

'char const * a = ...' होना चाहिए। –

+0

ए और बी का एक ही मान है, लेकिन इसका मतलब यह नहीं है कि वे _same_ स्ट्रिंग हैं। –

+0

@HunterMcMillen - असल में यह वही है जो इसका मतलब होगा। –

उत्तर

18

क्या यह गारंटी है कि एक == बी?

नहीं। लेकिन यह द्वारा §2.14.5/12 अनुमति दी है:

सभी स्ट्रिंग शाब्दिक अलग हैं या नहीं है (यानि, nonoverlapping वस्तुओं में जमा हो जाती) कार्यान्वयन परिभाषित किया गया है। स्ट्रिंग अक्षर को संशोधित करने का प्रयास करने का प्रभाव अपरिभाषित है।

और आपको लगता है कि अंतिम वाक्य char const* के बजाय char* का उपयोग करने से देख सकते हैं के रूप में परेशानी के लिए एक नुस्खा है (और अपने संकलक यह खारिज किया जाना चाहिए, सुनिश्चित करें कि आप चेतावनी सक्षम और उच्च अनुरूपता स्तरों चुना है)।

क्यों एक == सी नहीं है? क्या संकलक यह देखने में सक्षम नहीं होना चाहिए कि वे एक ही स्ट्रिंग का जिक्र कर रहे हैं?

नहीं, उन्हें पात्रों की एक ही श्रृंखला का जिक्र करने की आवश्यकता नहीं है। एक में पांच तत्व हैं, दूसरा छः है। एक कार्यान्वयन दो ओवरलैपिंग स्टोरेज में स्टोर कर सकता है, लेकिन इसकी आवश्यकता नहीं है।

सी के अंत में एक अतिरिक्त \ 0 जोड़ा गया है, भले ही इसमें पहले से ही एक है?

हां।

+0

यह भी समझा जा सकता है कि "परीक्षण" 'एक शाब्दिक 'char const [5]' संदर्भ में क्यों ए और बी * ओवरलैप हो सकता है लेकिन सी नहीं होगा। – AJG85

+0

धन्यवाद। एक और प्रश्न। यदि मैं 'a' और' c' की तुलना करने के लिए 'strcmp' का उपयोग करता हूं, तो क्या यह कहेंगे कि वे बराबर हैं? इसके अलावा, क्या यह 'a == c' के लिए अनुमति है? – AMCoder

+0

@ AJG85 क्यों 'c' ओवरलैप नहीं होगा? मानक स्पष्ट रूप से इसे अनुमति देता है (उद्धरण उत्तर में है और यह समान शाब्दिक तक सीमित नहीं है), और एक प्रोग्राम अपरिभाषित व्यवहार का आह्वान किए बिना अंतर नहीं बता सकता है। –

6

1 - बिल्कुल नहीं। एक शक्ति == बी हालांकि यद्यपि संकलक एक ही स्थिर स्ट्रिंग साझा करना चुनता है।

2 - क्योंकि वे एक ही स्ट्रिंग

3 की बात नहीं कर रहे हैं - हाँ।

व्यवहार सी और सी ++ के बीच कोई अलग नहीं है सिवाय इसके कि सी ++ कंपाइलर्स को गैर-कॉन्स्ट char * के असाइनमेंट को अस्वीकार कर देना चाहिए।

+0

'char *' रूपांतरण के लिए शाब्दिक स्ट्रिंग को बहिष्कृत किया गया है, लेकिन C++ में वर्जित नहीं है। –

+0

@james इसे C++ 11 –

+0

@ JohannesSchaub-litb में प्रतिबंधित है: कोई रास्ता नहीं! यह सबसे अच्छी खबर है जो मैंने पूरे दिन सुना है। जी ++ 4.7, क्लैंग 3.1, और वीसी 11 सभी रूपांतरण स्वीकार करते हैं, लेकिन मैं उस दिन की प्रतीक्षा करता हूं जब वे ऐसा नहीं करते :-) –

2

यहां समस्या यह है कि आप पॉइंटर और टेक्स्टुअल समकक्ष की अवधारणाओं को मिश्रित कर रहे हैं।

जब आप a == b या a == c कहते हैं तो आप पूछ रहे हैं कि पॉइंटर्स एक ही भौतिक पते पर इंगित करते हैं या नहीं। परीक्षण में पॉइंटर्स की पाठ्य सामग्री के साथ कुछ लेना देना नहीं है।

प्राप्त करने के लिए शाब्दिक तुल्यता का उपयोग करना चाहिए strcmp

+0

ध्यान दें कि 'strcmp' * पहले * शून्य पर रुक जाएगा, इसलिए स्ट्रिंग्स' ए' और 'सी' बराबर की तुलना करेंगे, भले ही कोई दूसरे की तुलना में लंबा हो। –

+0

@MarkRansom यह पाठ की समझ में बराबर लंबाई है, हालांकि स्ट्रैम्प पर विचार किया जाएगा। शायद मुझे अपने उत्तर को 3 क्षेत्रों में विस्तारित करना चाहिए जो यहां महत्वपूर्ण हो सकते हैं: सूचक समकक्ष, पाठ समकक्षता और स्मृति समतुल्य – JaredPar

+0

-1 क्षमा करें, लेकिन मेरे पास पॉइंटर तुलना करना है क्योंकि मैं पॉइंटर्स की तुलना करना चाहता हूं। सवाल यही है। – AMCoder

4

1) यह गारंटी है कि एक == ख?

यह नहीं है। ध्यान दें कि आप पते की तुलना कर रहे हैं और वे अलग-अलग स्थानों पर इशारा कर सकते हैं। अधिकांश स्मार्ट कंपाइलर्स इस डुप्लिकेट शाब्दिक स्थिरांक को फोल्ड करेंगे, इसलिए पॉइंटर्स बराबर की तुलना कर सकते हैं, लेकिन फिर मानक द्वारा इसकी गारंटी नहीं है।

2) एक == सी क्यों नहीं है? क्या संकलक यह देखने में सक्षम नहीं होना चाहिए कि वे एक ही स्ट्रिंग का जिक्र कर रहे हैं?

आप पॉइंटर्स की तुलना करने की कोशिश कर रहे हैं, वे विभिन्न मेमोरी स्थानों को इंगित करते हैं। भले ही आप इस तरह के पॉइंटर्स की सामग्री की तुलना कर रहे हों, फिर भी वे असमान हैं (अगला प्रश्न देखें)।

3) सी के अंत में एक अतिरिक्त \ 0 जोड़ा गया है, भले ही इसमें पहले से ही एक है?

हाँ, वहां है।

+0

मुझे पता है कि मैं पते की तुलना कर रहा हूं, सवाल से गुजर रहा हूं। प्रश्न को साफ़ करने के लिए - एक ही मेमोरी में स्थित समान स्ट्रिंग अक्षर हैं? – AMCoder

+0

मुझे लगता है कि 'ए' और' सी' के लिए पॉइंटर्स बराबर हो सकते हैं। एक कार्यक्रम यूबी का आह्वान किए बिना अंतर नहीं बता सकता है। –

+0

@ आर। मार्टिनो फर्नांडीस: यह एक अच्छा मुद्दा है, मुझे विश्वास है कि आप सही हैं। –

0

यदि आप पॉइंटर तुलना कर रहे हैं! = बी, बी! = सी, और सी! = ए। जब तक कि संकलक पर्याप्त ध्यान देने योग्य नहीं है कि आपके पहले दो तार समान हैं।

यदि आप एक strcmp (str, str) करते हैं तो आपके सभी तार मिलान के रूप में वापस आ जाएंगे।

मुझे यकीन नहीं है कि संकलक सी को अतिरिक्त शून्य समाप्ति जोड़ देगा, लेकिन मुझे लगता है कि यह होगा।

3

पहले ध्यान दें कि यह स्थिरांक होना चाहिए * जैसा कि स्ट्रिंग अक्षर का क्षय हो रहा है।

  1. दोनों '' '0' (लंबाई = 5) द्वारा 't' 'e' '' t '' के साथ शुरू किए गए सरणी बनाते हैं। समानता की तुलना करना केवल आपको बताएगा कि क्या वे दोनों एक ही सूचक के साथ शुरू होते हैं, न कि उनके पास समान सामग्री है (हालांकि तर्कसंगत रूप से, दोनों विचार एक-दूसरे का अनुसरण करते हैं)।
  2. एक नहीं सी के बराबर है क्योंकि वही नियम लागू, = एक = 'टी' 'ई' 'एस' 'टी' \ 0 'और ख' टी '' ई '' एस '' टी '' \ 0 '' \ 0 '
  3. हाँ, संकलक हमेशा यह करता है और आप expicitly में नहीं करना चाहिए आप इस तरह एक स्ट्रिंग करा रहे हैं तो। यदि आपने हालांकि एक सरणी को क्रेट किया है और इसे मैन्युअल रूप से पॉप्युलेट किया है, तो आपको यह सुनिश्चित करना होगा कि आप \ 0 जोड़ें।

ध्यान दें कि मेरे # 3, कॉन्स char [] = "हैलो वर्ल्ड" के लिए अंत में स्वचालित रूप से \ 0 भी मिल जाएगा, मैं मैन्युअल रूप से सरणी भरने का संदर्भ दे रहा था, संकलक इसे काम नहीं कर रहा था।

+0

मुझे नहीं लगता कि 'ए' और' सी 'की गारंटी असमान है। मानक कार्यान्वयन को ओवरलैपिंग स्टोरेज में अक्षरों को स्टोर करने की अनुमति देता है, और प्रोग्राम यूबी का आविष्कार किए बिना अंतर नहीं बता सकते हैं। –

+0

मैं वास्तव में आपके साथ यह जांचने के लिए सहमत हूं कि यह एक अंतरंग बिंदु था जिसे मैंने नहीं सुना था। मेरा मुद्दा अभी भी होगा कि संकलक निश्चित रूप से 2 शून्य मामले में दो शून्य टर्मिनेटर रखेगा, हालांकि संचालन असमान बनाता है, भले ही तारों को पढ़ना और उनके पॉइंटर्स की जांच करना बराबर होगा। साथ ही, यदि आपने सी के लिए बनाए गए स्ट्रिंग की लंबाई रिकॉर्ड की है, तो आप सुरक्षित रूप से स्ट्रेल() को 1 से पहले पढ़ सकते हैं और आप एक के लिए नहीं कर सकते (जब तक कि वे आपके द्वारा बताए गए स्थान पर न हों, लेकिन आप ' टी गारंटी देने में सक्षम हो)। –

+0

* यहां तक ​​कि अगर संकलक उन्हें एक ही स्थान * में संग्रहीत, 'एक [5]' अपरिभाषित व्यवहार आह्वान होता है, ('ग के रूप में एक ही स्थान पर मूल्य को पढ़ने के लिए [5]' कोशिश करता है जो) 'क्योंकि A' अंक आकार 5 की एक सरणी। इससे कोई फर्क नहीं पड़ता कि एक ही जगह में एक और सरणी बिछाती है। –

0

जैसा कि अन्य उत्तरों में कुछ बार कहा गया है, आप पॉइंटर्स की तुलना कर रहे हैं।हालांकि, मैं जोड़ता हूं कि strcmp(b,c) सत्य होना चाहिए, क्योंकि यह पहले \0 पर जांच करना बंद कर देता है।

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

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