के बीच क्या अंतर है
char* name
जो एक निरंतर स्ट्रिंग शाब्दिक को इंगित करता है, और
const char* name
के बीच क्या अंतर है
char* name
जो एक निरंतर स्ट्रिंग शाब्दिक को इंगित करता है, और
const char* name
जवाबों:
char*
एक उत्परिवर्ती चरित्र / स्ट्रिंग के लिए एक परस्पर सूचक है ।
const char*
एक अपरिवर्तनीय चरित्र / स्ट्रिंग के लिए एक परस्पर सूचक है । आप इस पॉइंटर को इंगित करने वाले स्थान की सामग्री को बदल नहीं सकते। जब आप ऐसा करने का प्रयास करते हैं, तो त्रुटि संदेश देने के लिए भी कंपाइलर की आवश्यकता होती है। उसी कारण से, से रूपांतरण के लिए मान्य नहीं है।const char *
char*
char* const
एक है अपरिवर्तनीय सूचक (यह किसी अन्य स्थान को इंगित नहीं कर सकता) लेकिन , जिस पर यह अंक हैं स्थान की सामग्री परिवर्तनशील ।
const char* const
एक अपरिवर्तनीय सूचक एक अपरिवर्तनीय चरित्र / स्ट्रिंग है।
char const *
char *
करते समय विभाजन में खराबी नहीं आएगी ?
const
अगर मैं चाहता हूं कि कंपाइलर त्रुटि दे तो क्या मैं भूल गया और गलती से डेटा बदल दिया, है ना?
char *name
आप चार्ट को किस name
बिंदु पर बदल सकते हैं , और यह भी कि वह किस बिंदु पर है।
const char* name
आप चार्ट को किन name
बिंदुओं में बदल सकते हैं , लेकिन आप उस बिंदु पर चार्ट को संशोधित नहीं कर सकते।
सुधार: आप पॉइंटर बदल सकते हैं, लेकिन चार को नहीं , जो name
इंगित करता है ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx , देखें "उदाहरण" )। इस स्थिति में, const
विनिर्देशक पर लागू होता हैchar
, तारांकन नहीं।
MSDN पृष्ठ और http://en.cppreference.com/w/cpp/language/declarations के अनुसार , const
पहले घोषित *
-निर्दिष्ट अनुक्रम का हिस्सा है , जबकि const
बाद में घोषणाकर्ता *
का हिस्सा है।
एक घोषणा विनिर्देश अनुक्रम को कई घोषणाकर्ताओं द्वारा पालन किया जा सकता है, यही कारण है कि जैसा और जैसा const char * c1, c2
घोषित c1
किया गया है ।const char *
c2
const char
संपादित करें:
टिप्पणियों से, आपका प्रश्न दो घोषणाओं के बीच अंतर के बारे में पूछ रहा है जब सूचक एक स्ट्रिंग शाब्दिक को इंगित करता है।
उस स्थिति में, आपको चार बिंदुओं के लिए चार को संशोधित नहीं करना चाहिएname
, क्योंकि इसका परिणाम अपरिभाषित व्यवहार में हो सकता है । स्ट्रिंग शाब्दिक केवल मेमोरी क्षेत्रों (कार्यान्वयन परिभाषित) को पढ़ने में आवंटित किया जा सकता है और एक उपयोगकर्ता कार्यक्रम को वैसे भी इसे संशोधित नहीं करना चाहिए। ऐसा करने का कोई भी प्रयास अपरिभाषित व्यवहार में परिणाम देता है।
तो उस मामले में (स्ट्रिंग शाब्दिक के साथ उपयोग) का एकमात्र अंतर यह है कि दूसरी घोषणा आपको थोड़ा लाभ देती है। यदि आप दूसरे मामले में स्ट्रिंग शाब्दिक को संशोधित करने का प्रयास करते हैं, तो आमतौर पर कंपाइलर आपको एक चेतावनी देगा।
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
आउटपुट:
cc1: चेतावनियों को त्रुटियों के रूप में व्यवहार किया जा रहा है
prog.c: फ़ंक्शन में 'main':
prog.c: 9: error: 'strcpy' के तर्क 1 को पॉइंटर टार्गेट से क्वालीफायर से हटाता है
सूचना संकलक को दूसरे मामले के लिए चेतावनी देता है लेकिन पहले के लिए नहीं।
name
। इसके परिणामस्वरूप यूबी हो सकता है।
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
char *
मूल्य बदलने से विभाजन की गलती होती है क्योंकि हम एक स्ट्रिंग शाब्दिक (जो कि केवल मेमोरी में मौजूद है) को संशोधित करने की कोशिश कर रहे हैं
न तो मामले में आप एक स्ट्रिंग शाब्दिक को संशोधित कर सकते हैं, भले ही उस स्ट्रिंग शाब्दिक को सूचक के रूप में घोषित किया गया हो char *
या नहीं const char *
।
हालाँकि, अंतर यह है कि यदि पॉइंटर है const char *
तो कंपाइलर को डायग्नोस्टिक देना होगा यदि आप इंगित किए गए मान को संशोधित करने का प्रयास करते हैं, लेकिन यदि पॉइंटर है char *
तो ऐसा नहीं है।
extern ... name
और हो सकता है *name = 'X';
। 'उचित ऑपरेटिंग सिस्टम' पर, यह विफल हो सकता है, लेकिन एम्बेडेड सिस्टम पर, मैं यह अपेक्षा करूंगा कि यह कुछ प्लेटफॉर्म / कंपाइलर विशिष्ट हो।
मामला एक:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
उपरोक्त सेट्स शाब्दिक मान "हैलो" को इंगित करने के लिए ऊपर है, जो प्रोग्राम की बाइनरी इमेज में हार्ड-कोडेड है, जिसे केवल-पढ़ने के लिए मेमोरी के रूप में चिह्नित किया गया है, इसका मतलब है कि इस स्ट्रिंग शाब्दिक में कोई भी परिवर्तन अवैध है और यह विभाजन दोष को फेंक देगा।
मामला 2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
मामला 3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
पहला आप वास्तव में बदल सकते हैं यदि आप चाहते हैं, दूसरा आप नहीं कर सकते। const
शुद्धता के बारे में पढ़ें (अंतर के बारे में कुछ अच्छे मार्गदर्शक हैं)। वहाँ भी है char const * name
जहाँ आप इसे निरस्त नहीं कर सकते।
सवाल यह है कि क्या अंतर है
char *name
जो एक निरंतर स्ट्रिंग शाब्दिक को इंगित करता है, और
const char *cname
Ie दिया गया
char *name = "foo";
तथा
const char *cname = "foo";
2 में बहुत अंतर नहीं है और दोनों को सही देखा जा सकता है। सी कोड की लंबी विरासत के कारण, स्ट्रिंग शाब्दिकों के पास एक प्रकार का है char[]
, नहीं const char[]
, और बहुत सारे पुराने कोड हैं जो इसी तरह स्वीकार करते char *
हैं const char *
, भले ही वे तर्कों को संशोधित न करें।
सामान्य रूप से 2 का मुख्य अंतर यह है कि *cname
या cname[n]
प्रकार के lvalues का मूल्यांकन करेगा const char
, जबकि *name
या name[n]
प्रकार के lvalues का मूल्यांकन करेगा char
, जो कि परिवर्तनीय lvalues हैं । एक संकेंद्रित संदेश का उत्पादन करने के लिए एक अनुरूप संकलक की आवश्यकता होती है यदि असाइनमेंट का लक्ष्य एक परिवर्तनीय अंतराल नहीं है ; यह प्रकार के अंतराल को असाइनमेंट पर कोई चेतावनी देने की आवश्यकता नहीं है char
:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
संकलक को किसी भी मामले में संकलन को रोकने की आवश्यकता नहीं है ; यह पर्याप्त है कि यह असाइनमेंट के लिए एक चेतावनी पैदा करता है cname[0]
। परिणामी कार्यक्रम एक सही कार्यक्रम नहीं है । निर्माण का व्यवहार अपरिभाषित है । यह दुर्घटनाग्रस्त हो सकता है, या इससे भी बदतर हो सकता है, यह दुर्घटनाग्रस्त नहीं हो सकता है, और स्मृति में स्ट्रिंग शाब्दिक बदल सकता है।
वास्तव में, char* name
स्थिर करने के लिए एक संकेतक नहीं है, लेकिन एक चर के लिए एक सूचक है। आप इस अन्य प्रश्न के बारे में बात कर रहे होंगे।