2012-06-21 20 views
5

== ऑपरेटर (या !=) के साथ एक और स्ट्रिंग अक्षर के साथ स्ट्रिंग अक्षर की तुलना करते समय, परिणाम अच्छी तरह से परिभाषित किया गया है?सी ++ दो स्ट्रिंग अक्षरों की तुलना करें

उदाहरण के लिए, निम्नलिखित रखने की गारंटी दी जाती है?

assert("a" == "a"); 
assert("a" != "b"); 

कृपया "std :: string का उपयोग करें" जैसी सामग्री न कहें। मैं बस इस विशिष्ट मामले को जानना चाहता हूं।

+0

आपको ऐसा करने की आवश्यकता क्यों होगी? गारंटीकृत झूठी के लिए, 'जोर दें (! "संदेश यहां जाता है"); ' – chris

+1

@ क्रिस: एक के लिए जिज्ञासा। एक enum- जैसे वर्ग कार्यान्वयन विचार के लिए भी। –

+0

[जीसीसी और टर्बो सी में आउटपुट अंतर] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/3289354/output-difference-in-gcc-and-turbo-c) – kennytm

उत्तर

15
"a" == "a" 

यह अभिव्यक्ति true या false उपज सकता है; कोई गारंटी नहीं है। दो "a" स्ट्रिंग अक्षर एक ही भंडारण पर कब्जा कर सकते हैं या वे स्मृति में दो अलग-अलग स्थानों पर मौजूद हो सकते हैं।

मुझे लगता है कि सी ++ मानक में सबसे नज़दीकी भाषा है: "क्या सभी स्ट्रिंग अक्षर अलग हैं (यानी, nonoverlapping ऑब्जेक्ट्स में संग्रहीत हैं) कार्यान्वयन परिभाषित किया गया है" (सी ++ 11 §2.14.5/12)। कोई अन्य आवश्यकताएं या प्रतिबंध नहीं हैं, इसलिए परिणाम अनिर्दिष्ट छोड़ दिया गया है।

"a" != "b" 

यह अभिव्यक्ति false उपज चाहिए कोई रास्ता नहीं है कि इन दो स्ट्रिंग शाब्दिक स्मृति में एक ही स्थान पर कब्जा कर सकते हैं क्योंकि वहाँ: "a"[0] != "b"[0]


आप इस तरह से स्ट्रिंग शाब्दिक तुलना, तुम सच में सरणियों में प्रारंभिक तत्वों की ओर इशारा तुलना कर रहे हैं जब।

क्योंकि हम संकेत दिए गए, संबंधपरक तुलना तुलना कर रहे हैं (<, >, <=, और >=) भी समानता तुलना (== और !=) की तुलना में अधिक समस्याग्रस्त क्योंकि सूचक तुलना की केवल एक सीमित सेट रिलेशनल का उपयोग किया जा सकता है तुलना। दो पॉइंटर्स केवल तुलनात्मक रूप से तुलना किए जा सकते हैं यदि वे दोनों एक ही ऑब्जेक्ट में पॉइंटर्स या उसी ऑब्जेक्ट में पॉइंटर्स हैं।

दो "a" स्ट्रिंग शाब्दिक स्मृति में एक ही स्थान पर कब्जा है, तो "a" < "a" अच्छी तरह से परिभाषित किया जाएगा और false प्राप्त होते हैं, क्योंकि दोनों एक ही संकेत देता है की प्रारंभिक तत्व ('a') को इंगित।

हालांकि, अगर दो "a" स्ट्रिंग शाब्दिक स्मृति में अलग स्थानों पर कब्जा है, "a" < "a" का परिणाम अपरिभाषित, क्योंकि दो संकेत तुलना की जा रही पूरी तरह से असंबंधित वस्तुओं में बिंदु है।

क्योंकि "a" और "b" स्मृति में उसी स्थान पर कभी भी कब्जा नहीं कर सकता, "a" < "b" हमेशा व्यवहार को अपरिभाषित करता है। अन्य रिलेशनल तुलना ऑपरेटर के लिए भी यही सच है।

यदि आपने कुछ कारणों से, दो स्ट्रिंग अक्षर की तुलनात्मक रूप से तुलना करना चाहते हैं और अच्छी तरह से परिभाषित परिणाम चाहते हैं, तो आप std::less तुलनाकर्ता का उपयोग कर सकते हैं, जो सभी पॉइंटर्स पर सख्त कमजोर आदेश प्रदान करता है। std::greater, std::greater_equal, और std::less_equal तुलनाकर्ता भी हैं।यह देखते हुए कि एक ही सामग्री के साथ स्ट्रिंग अक्षर बराबर की तुलना नहीं कर सकते हैं, मुझे नहीं पता कि कोई ऐसा क्यों करना चाहेगा, लेकिन आप कर सकते हैं।

+0

मुझे लगता है कि यह अच्छा होगा अगर आप कम से कम तुलना में कम से कम चर्चा कर सकते हैं, और 'std :: øess' और दोस्तों –

+0

@ चीयर्संधथ-अलफ: अच्छा विचार; जोड़ा। साथ ही, मुझे नहीं पता कि मैंने इसका उल्लेख किया है, लेकिन मुझे लगता है कि आपने ग्रुपियर स्टैक ओवरफ्लो योगदानकर्ताओं के आसपास काम करने के लिए अपने नाम में "चीयर्स और एचथ" को कैसे शामिल किया है। ;-) –

1

विचार यह है कि सी ++ स्ट्रिंग अक्षर में सरणी हैं। चूंकि सरणी के लिए उनके द्वारा परिभाषित तुलना ऑपरेटर नहीं होते हैं, इसलिए उन्हें अगले सर्वश्रेष्ठ फिट - पॉइंटर तुलना ऑपरेटर का उपयोग करके तुलना की जाती है, क्योंकि सरणी पॉइंटर्स को पूरी तरह से क्षय हो जाती हैं, इसलिए कोई भी तुलना पता की तुलना में सामग्री की तुलना नहीं करती है। चूंकि "ए" और "बी" एक ही स्मृति स्थान पर नहीं हो सकते हैं, "ए"! = "बी" एक वास्तविक दावा है। यह एक वैध स्थैतिक दावा भी बनाता है। "ए" == "ए" के बारे में ऐसी कोई गारंटी नहीं दी जा सकती है, हालांकि जीसीसी के साथ -फर्म-कॉन्स्टेंट (अंतर्निहित -O1) एक उचित मजबूत संभावना बना सकता है और -फर्म-ऑल-कॉन्स्टेंट आपको गारंटी दे सकता है (संभावित रूप से नॉन-अनुरूप व्यवहार में परिणाम)।

यदि आप सामग्री-आधारित तुलना करना चाहते हैं, तो आप हमेशा assert(!strcmp("a", "a")) का उपयोग कर सकते हैं। या, आप constexpr आधारित strcmp किसी प्रकार का एक स्थिर अभिकथन के लिए उपयोग कर सकते हैं:

constexpr bool static_strequal_helper(const char * a, const char * b, unsigned len) { 
    return (len == 0) ? true : ((*a == *b) ? static_strequal_helper(a + 1, b + 1, len - 1) : false); 
} 

template <unsigned N1, unsigned N2> 
constexpr bool static_strequal(const char (&str1)[N1], const char (&str2)[N2]) { 
    return (N1 == N2) ? static_strequal_helper(&(str1[0]), &(str2[0]), N1) : false; 
} 

static_assert(static_strequal("asdf", "asdf"), "no error - strings are equal"); 
static_assert(static_strequal("asdf", "jkl;"), "strings are not equal"); 
assert(!strcmp("asdf", "jkl;")); //no compile error - runtime error 
//cannot use strcmp in static assert as strcmp is not constexpr... 

फिर, जी के साथ संकलन ++ -std = C++ 0x (या -std = C++ 11 जीसीसी के लिए> = 4.7) , और ...

error: static assertion failed: "strings are not equal" 
संबंधित मुद्दे