2009-04-05 14 views
8

मुझे सी ++ में स्ट्रिंग अक्षर के बारे में कुछ संदेह हैं।स्ट्रिंग लिटल

char *strPtr ="Hello" ; 
char strArray[] ="Hello"; 

अब strPtr और strArray स्ट्रिंग अक्षर माना जाता है।

मेरी समझ स्ट्रिंग अक्षर के अनुसार केवल स्मृति में पढ़ा जाता है ताकि हम उनके मूल्यों को संशोधित नहीं कर सकें।

हम ऐसा नहीं कर सकते

strPtr[2] ='a'; 
and strArray[2]='a'; 

दोनों ऊपर बयान अवैध होना चाहिए। कंपाइलर दोनों मामलों में त्रुटियों को फेंक देना चाहिए।

कंपाइलर स्ट्रिंग अक्षर को केवल स्मृति में रखता है, इसलिए यदि हम उन्हें संकलित करने की कोशिश करते हैं तो संकलक त्रुटियों को फेंकता है।

इसके अलावा कॉन्स्ट डेटा को केवल पढ़ने के रूप में भी माना जाता है।

क्या यह है कि दोनों स्ट्रिंग अक्षर और कॉन्स्ट डेटा का इलाज समान तरीके से किया जाता है? क्या स्ट्रिंग अक्षर से const_cast का उपयोग करके निरंतरता को हटाया जा सकता है, इसका मूल्य बदल सकता है?

स्ट्रिंग अक्षर वास्तव में कहां संग्रहीत किया जाता है? (कार्यक्रम के डेटा खंड में)

उत्तर

16

अब strPtr और strArray स्ट्रिंग अक्षर माना जाता है।

नहीं, वे नहीं हैं। स्ट्रिंग अक्षर वे चीजें हैं जिन्हें आप अपने कोड में देखते हैं। उदाहरण के लिए, "Hello"strPtr शाब्दिक (0 अब निष्पादन योग्य में संकलित) के लिए सूचक है। ध्यान दें कि यह const char * होना चाहिए; आप कानूनी रूप से const सी मानक के अनुसार नहीं हटा सकते हैं और इसका उपयोग करते समय परिभाषित व्यवहार की अपेक्षा कर सकते हैं। strArray एक सरणी है जिसमें शाब्दिक की प्रतिलिपि है (निष्पादन योग्य में संकलित)।

उपरोक्त दोनों कथन अवैध होना चाहिए। कंपाइलर दोनों मामलों में त्रुटियों को फेंक देना चाहिए।

नहीं, यह नहीं होना चाहिए। दो कथन पूरी तरह से कानूनी हैं। परिस्थिति के कारण, पहला अपरिभाषित है। अगर वे const char एस पर पॉइंटर्स थे, तो यह एक त्रुटि होगी।

जहां तक ​​मुझे पता है, स्ट्रिंग अक्षर को अन्य अक्षर और स्थिरांक के समान परिभाषित किया जा सकता है। हालांकि, अंतर हैं:

// These copy from ROM to RAM at run-time: 
char myString[] = "hello"; 
const int myInt = 42; 
float myFloats[] = { 3.1, 4.1, 5.9 }; 

// These copy a pointer to some data in ROM at run-time: 
const char *myString2 = "hello"; 
const float *myFloats2 = { 3.1, 4.1, 5.9 }; 

char *myString3 = "hello"; // Legal, but... 
myString3[0] = 'j';   // Undefined behavior! (Most likely segfaults.) 

यहां रोम और रैम का मेरा उपयोग सामान्य है। यदि मंच केवल रैम है (उदा। अधिकांश निंटेंडो डीएस प्रोग्राम) तो डेटा रैम में हो सकता है। हालांकि, लेखन अभी भी अपरिभाषित हैं। कॉन्स डेटा का स्थान सामान्य C++ प्रोग्रामर के लिए कोई फर्क नहीं पड़ता है।

8
char *strPtr ="Hello" ; 

को परिभाषित करता है strPtr एक स्ट्रिंग शाब्दिक "Hello" की ओर इशारा करते चार के लिए सूचक - इस सूचक के प्रभावी प्रकार const char * है। strPtr के माध्यम से पॉइंटटे में कोई संशोधन की अनुमति नहीं है (यदि आप ऐसा करने का प्रयास करते हैं तो यूबी को आमंत्रित करता है)। पुराने सी कोड के लिए यह पिछड़ा संगतता सुविधा है।यह सम्मेलन सी ++ 0x में बहिष्कृत है।

बदलें: एक स्ट्रिंग शाब्दिक के प्रकार के लिए "। स्थिरांक चार की सरणी" [...]

"चार की सरणी" में बदल गया है स्ट्रिंग शाब्दिक स्थिरांक बनाया अनुलग्नक सी देखें तर्क: यह अनुचित ओवरलोडेड फ़ंक्शन को कॉल करने से बचाता है, जो इसकी तर्क को संशोधित करने में सक्षम होने की उम्मीद कर सकता है।

मूल सुविधा पर प्रभाव: अच्छी तरह से परिभाषित सुविधा के अर्थशास्त्र में बदलें। कनवर्ट करने में कठिनाई: सरल वाक्य रचनात्मक परिवर्तन, क्योंकि स्ट्रिंग अक्षर को चार * में परिवर्तित किया जा सकता है; (4.2)। सबसे आम मामलों के लिए एक नया लेकिन पदावनत मानक रूपांतरण द्वारा नियंत्रित किया जाता है:

char* p = "abc"; // valid in C, deprecated in C++

char* q = expr ? "abc" : "de"; // valid in C, invalid in C++

व्यापक रूप से इस्तेमाल कैसे: कार्यक्रम संभावित परिवर्तनीय स्मृति की ओर इशारा के रूप में स्ट्रिंग शाब्दिक के इलाज के लिए एक वैध कारण है कि शायद दुर्लभ हैं।

char strArray[] ="Hello"; 

strPtr की घोषित प्रकार है - यह अशक्त टर्मिनेटर अर्थात 6 अक्षर सहित स्ट्रिंग Hello युक्त अनिर्दिष्ट आकार के पात्रों की एक सरणी है। हालांकि, प्रारंभिकरण इसे एक पूर्ण प्रकार बनाता है और इसका प्रकार 6 वर्णों की सरणी है। strPtr के माध्यम से संशोधन ठीक है।

स्ट्रिंग अक्षर वास्तव में कहां संग्रहीत किया जाता है?

कार्यान्वयन परिभाषित किया गया।

+0

"घोषित प्रकार का strPtr है", क्या आपका मतलब strArray है? – 4pie0

1

बड़े C और C++ compilers विशुद्ध रूप से निम्न स्तर कोडिंग पर आधारित थे जहां डेटा संरक्षण के उच्च मानकों उपलब्ध नहीं थे, और वे भी सी और सी में लागू नहीं किया जा सकता है, आम तौर ++ आप कुछ भी आप चाहते हैं लिख सकते हैं ..

यदि आप जानते हैं कि पते के साथ कैसे खेलना है, तो आप अपने कॉन्स पॉइंटर्स को एक्सेस और संशोधित करने के लिए भी एक कोड लिख सकते हैं।

हालांकि सी ++ कुछ संकलन स्तर सुरक्षा को लागू करता है, लेकिन रनटाइम पर कोई सुरक्षा नहीं है। आप निश्चित रूप से अपने स्वयं के ढेर तक पहुंच सकते हैं, और इसके मूल्यों का उपयोग कॉन्स्ट पॉइंटर में आने वाले किसी भी डेटा में हेरफेर करने के लिए भी कर सकते हैं।

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

प्रमुख अंतर यह है कि, सी ++ आपको केवल समय सुरक्षा संकलित कर सकता है, लेकिन सी # आपको रनटाइम पर भी सुरक्षा प्रदान करेगा।

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