2012-11-22 10 views
7

जब मैं के रूप में MinGW का उपयोग कर, im हो रही उत्पादन इस कार्यक्रम को चलाने के "="दो स्ट्रिंग अक्षर के समान सूचक मूल्य है?

#include<iostream> 

using namespace std; 

int main() 
{ 
char *str1 = "Hello"; 
char *str2 = "Hello"; 

if(str1==str2) 
cout<<"="; 
else 
cout<<"!="; 


return 0; 
} 

हालांकि, तार्किक रूप से, यह होना चाहिए! =, Coz इन संकेत दिए गए हैं और वे अलग अलग स्मृति स्थल के ओर इशारा करते हैं। जब मैं अपने कोड को अपने टर्बो सी ++ में चलाता हूं, तो मुझे मिलता है! =

+2

क्या आपने ऑप्टिमाइज़ेशन बंद कर दिया है? –

+9

"और वे विभिन्न मेमोरी स्थानों पर इशारा कर रहे हैं" ... अच्छा, यह पता चला है कि वे वास्तव में एक ही स्थान पर इंगित कर रहे हैं। इसकी अनुमति है –

+3

स्रोत कोड में दो बैकक्वॉट इसे संकलन से रोकना चाहिए (और एक अनुरूप सी ++ 11 कंपाइलर के साथ 'कॉन्स्ट' की कमी को संकलन से रोकना चाहिए)। –

उत्तर

13

आप सही हैं कि वे पॉइंटर्स हैं। हालांकि, चाहे वे अलग-अलग स्थानों पर इंगित कर रहे हों या नहीं, कार्यान्वयन पर निर्भर करता है। एक कंपाइलर के लिए केवल एक बार एक स्ट्रिंग अक्षर को स्टोर करने के लिए पूरी तरह से मान्य है और कोड में उपयोग किए जाने पर भी इसका पता उपयोग करें।

8

कोई गारंटी नहीं है कि दो पॉइंटर्स विभिन्न मेमोरी स्थानों पर इंगित कर रहे हैं। शायद ऐसा इसलिए है क्योंकि अनुकूलन, या कंपाइलर अपने नियमों का उपयोग करता है ... व्यवहार "कार्यान्वयन डीआईएफएड" है।

मानक (11 §2.14.5 सी ++ स्ट्रिंग literals) के अनुसार:

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

0

char *str1 = "Hello"; - इस लाइन को अनुमति दी गई है (कई कंपाइलर्स द्वारा), वास्तव में ऐसा करने का एक बुरा विचार है। यह मूल रूप से केवल सी के साथ पिछड़े संगतता के लिए अनुमति है, और वास्तव में * str1 परिणामों को अपरिभाषित व्यवहार में लिख रहा है। मैं संकलक सेटिंग ढूंढने की अनुशंसा करता हूं जो आपको यह करने पर चेतावनियां देता है, और यदि आपके कंपाइलर में ऐसी नई चेतावनियां ढूंढने जैसी चेतावनियों की कमी है।

सी ++ मानक संकलक और निष्पादन वातावरण "String literals" संग्रहीत किए जाने के बारे में आजादी की हास्यास्पद मात्रा देता है। वे के "literal" भाग "literal" के सूचक मूल्य के रूप में "literal" भाग के लिए वास्तव में एक सूचक का उपयोग कर सकते हैं, और उन्हें स्मृति में संग्रहीत कर सकते हैं जिसमें आप उन्हें संपादित करने का प्रयास करते समय segfault करेंगे, अप्रत्याशित नहीं है।

ध्यान दें कि char buf1[] = "Hello"; कुछ char* str1 = "Hello"; से मौलिक रूप से अलग करता है: यह वास्तव में पात्रों {'H','e','l','l','o','\0'} साथ बफर buf1 initializes।

+0

मानक 'char * str = "हैलो" को परिभाषित करता है; 'अमान्य के रूप में। जब संकलक अभी भी इसका समर्थन करते हैं, तो यह ग्राहक देखभाल के लिए है, लेकिन मानक के खिलाफ है। –

2

यह एक अपेक्षित परिणाम है। अंतर्निहित असेंबली को देखकर आप इसे सत्यापित कर सकते हैं। उदाहरण के लिए, अगर मैं के साथ निर्माण:

g++ -S ptr.c 

तो आप फ़ाइल उत्पादन में निम्नलिखित (ptr.s) देख सकते हैं:

 .file "ptr.c" 
     .def ___main;  .scl 2;  .type 32;  .endef 
     .section .rdata,"dr" 
LC0: 
     .ascii "Hello\0"    ; Note - "Hello" only appears once in 
             ; this data section! 
LC1: 
     .ascii "=\0" 
LC2: 
     .ascii "!=\0" 
     .text 
.globl _main 
     .def _main; .scl 2;  .type 32;  .endef 
_main: 
     [... some stuff deleted for brevity ...] 
LCFI5: 
     call ___main 
     movl $LC0, -12(%ebp)  ; This sets str1 
     movl $LC0, -8(%ebp)   ; This sets str2 
     movl -12(%ebp), %eax 

मैं दो प्रमुख बिट्स टिप्पणी की है - केवल एक 'हैलो' की उपस्थिति अंतर्निहित कोड के rdata खंड में है, और आप str1 और str2 को अंत में सेट कर सकते हैं, दोनों एक ही लेबल को इंगित करते हैं: LC0। यह beacuse 'हैलो' एक स्ट्रिंग अक्षर है और, महत्वपूर्ण रूप से, स्थिर है।

जैसा कि अन्य ने बताया है - यह मानकों के तहत पूरी तरह से कानूनी है।

2

एक स्ट्रिंग "Hello" तरह शाब्दिक के प्रकार, स्थिरांक चार की सरणी है इसलिए, आप कुछ है जो कभी बदलने की अनुमति नहीं है करने के लिए दो संकेत निर्देशन कर रहे हैं।

सी ++ मानक कंपेलरों को समान निरंतर मानों को एक साथ मिलाकर स्वतंत्रता देता है (ध्यान दें कि कंपाइलर ऐसा करने के लिए आवश्यक नहीं हैं)।

संबंधित: घोषणाओं इसलिए अमान्य हैं और संशोधित किया जाना चाहिए:

const char *str1 = "Hello"; 
const char *str2 = "Hello"; 

या अगर आप चाहते हैं

char const *str1 = "Hello"; 
char const *str2 = "Hello"; 

जो अच्छी तरह से पढ़ता है जब पढ़ने दाएँ-से-बाएँ:

str1 is a pointer to const char 

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