2010-10-29 59 views
9

क्या कोड की इन दो पंक्तियों को एक ही परिणाम प्राप्त होता है? अगर मेरे पास इन लाइनों को फ़ंक्शन में रखा गया था, तो दोनों मामलों में स्टैक पर संग्रहीत स्ट्रिंग है? क्या कोड का पहला पंक्ति में शून्य टर्मिनेटर घोषित करने की आवश्यकता नहीं होने के अलावा, मुझे एक दूसरे के ऊपर एक का उपयोग क्यों करना चाहिए?सी में, क्या मैं एक सूचक घोषणा में एक स्ट्रिंग को प्रारंभ कर सकता हूं वैसे ही मैं एक चार सरणी घोषणा में एक स्ट्रिंग प्रारंभ कर सकता हूं?

char s[] = "string"; 
char* s = "string\0"; 
+7

बस जानकारी के लिए, आपको दूसरे उदाहरण में \ 0 की आवश्यकता नहीं है। डबल कोट्स का उपयोग करते समय, \ 0 हमेशा सरणी में डाला जाता है। – RMAAlmeida

+0

और सिर्फ शब्दावली के लिए, आप किस बारे में बात कर रहे हैं वे असाइनमेंट नहीं हैं, लेकिन प्रारंभकर्ताओं के साथ घोषणाएं हैं। वे विभिन्न नियमों का पालन करते हैं। ईजी आपके पहले कथन को असाइनमेंट के रूप में अनुमति नहीं दी जाएगी, आप सरणी असाइन नहीं कर सकते हैं। –

+0

संभावित डुप्लिकेट [सी: पॉइंटर और सरणी के बीच अंतर] (http://stackoverflow.com/questions/1335786/c-differences-between-pointer-and-array) –

उत्तर

23

नहीं, उन दो पंक्तियों को एक ही परिणाम प्राप्त नहीं होता है।

char s[] = "string" 7 बाइट्स की एक संशोधित सरणी में परिणाम देता है, जो प्रारंभ में सामग्री 's' 't' 'r' 'i' 'n' 'g' '\0' से भरा हुआ है (सभी स्ट्रिंग-शाब्दिक से रनटाइम पर कॉपी किए गए हैं)।

char *s = "string" कुछ पढ़ने के लिए पॉइंटर में परिणाम केवल मेमोरी स्ट्रिंग-शाब्दिक "स्ट्रिंग" युक्त है।

यदि आप अपनी स्ट्रिंग की सामग्री को संशोधित करना चाहते हैं, तो सबसे पहले जाने का एकमात्र तरीका है। यदि आपको केवल स्ट्रिंग के लिए केवल पढ़ने की पहुंच की आवश्यकता है, तो दूसरा थोड़ा तेज होगा क्योंकि स्ट्रिंग को प्रतिलिपि बनाने की आवश्यकता नहीं है।


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

+5

इसके अलावा, दूसरे को केवल भयानक विरासत के लिए अनुमति है कारणों। आपको 'const char * s =" string "का उपयोग करना चाहिए;' –

+0

@Steve: C++ के लिए मैं पूरी तरह से आपसे सहमत हूं। सी के लिए, मैं थोड़ी अधिक छूट देता हूं, क्योंकि व्यवहार में बहुत सारे तरीके हैं जो 'कॉन्स्ट' आपके रास्ते में आते हैं। (जिसे कॉन्स-विषाक्तता भी कहा जाता है) –

+2

यदि मैं डोडी पुस्तकालयों का उपयोग कर रहा हूं, तो मैं आपके साथ सहमत हूं (कभी-कभी)। अगर कोड मेरे नियंत्रण में है तो मैं इसे ठीक करता हूं ताकि 'const' मेरे रास्ते में न हो। विकल्प स्ट्रिंग्स की प्रतियां लेना है जिन्हें डोडी एपीआई के लिए गैर-कॉन्स पैरामीटर के रूप में पारित किया जाना है। कभी-कभी ऐसा करने में सक्षम होता है, उदाहरण के लिए यदि स्ट्रिंग पास की जा रही है तो कॉल के करीब एक शाब्दिक परिभाषित किया गया है, या वैश्विक के रूप में, तो उपर्युक्त दो विकल्पों में से पहले का उपयोग करें। अन्य बार यह एक पिटा है, इस मामले में आप या तो स्ट्रड की हिट ले सकते हैं, या 'कॉन्स्ट' (जो "असुरक्षित" है, को हटा सकते हैं, लेकिन फिर आप पहले से ही "असुरक्षित" एपीआई का उपयोग कर रहे हैं)। –

2

इन दोनों के बीच अंतर:।

char a[] = "string"; 
char* b = "string"; 

है कि एक वास्तव में ढेर पर एक स्थिर सरणी है है, जबकि ख के लिए सूचक है एक निरंतर। आप एक की सामग्री को संशोधित कर सकते हैं, लेकिन ख नहीं।

1

अन्य उत्तर मैं कोशिश करूँगा के अलावा समझाने के लिए क्यों आप इस कार्यक्रम प्रवाह पर बाद में *s चर संशोधित नहीं कर सकते।

सैद्धांतिक रूप

जब एक कार्यक्रम में भरा हुआ है

  • कोड खंड: स्मृति यह 3 क्षेत्रों (वर्ग) है अपने कार्यक्रम का मूल पाठ यहाँ संग्रहीत किया जाता है
  • डेटा खंड (यह केवल पढ़ने के लिए क्षेत्र है): किसी भी वैश्विक या स्थैतिक चर जो एक राशि शामिल पूर्व परिभाषित मान और संशोधित किया जा सकता है
  • स्टैक सेगमेंट: यहां उन कार्यों को लोड किया गया है जिन्हें वे कहते हैं। मानों का सेट (एक स्टैक फ्रेम) प्रत्येक फ़ंक्शन कॉल के लिए स्टैक पर धक्का दिया जाता है जिसमें फ़ंक्शन और स्थानीय चर से रिटर्न पता होता है।

आपके मामले में s[] चर main() समारोह है, जो मूल्य "string" साथ आरंभ नहीं हो जाता, एक स्थानीय चर (सरणी) है। इस प्रकार, यह ढेर पर संग्रहीत है और संशोधित किया जा सकता है।

*s चर एक सूचक है जो कोड खंड में स्थित एक निरंतर "string\0" के पते पर इंगित करता है। केवल पढ़ने के क्षेत्र होने के नाते, आप इसकी सामग्री को संशोधित नहीं कर सकते हैं।