const char * और char const * - क्या वे एक ही हैं?


81

मेरी समझ से, constसंशोधक को दाईं से बाईं ओर पढ़ा जाना चाहिए। उस से, मुझे लगता है कि:

const char*

एक पॉइंटर है, जिसके चार तत्वों को संशोधित नहीं किया जा सकता है, लेकिन पॉइंटर स्वयं कर सकते हैं, और

char const*

mutableचार्ट के लिए एक निरंतर सूचक है ।

लेकिन मुझे निम्नलिखित कोड के लिए निम्नलिखित त्रुटियां मिलती हैं:

const char* x = new char[20];
x = new char[30];   //this works, as expected
x[0] = 'a';         //gives an error as expected

char const* y = new char[20];
y = new char[20];   //this works, although the pointer should be const (right?)
y[0] = 'a';         //this doesn't although I expect it to work

तो यह कौनसा है? क्या मेरी समझ या मेरा संकलक (वीएस 2005) गलत है?


35
जब संदेह में हमेशा सर्पिल नियम का उपयोग करें ।
आलोक सेव

"... जिनके चार तत्वों को संशोधित किया जा सकता है, लेकिन सूचक स्वयं कर सकता है, और ..." - मुझे लगता है कि आप उन लोगों में से एक के लिए "नहीं" कहने का मतलब कर सकते हैं, लेकिन मुझे नहीं पता कि कैसे उलझन में आप हैं इसलिए मुझे पता नहीं है कि
किसको

1
इस वेबसाइट को आज़माएं: www.cdecl.org
yasouser

कंपाइलर कभी गलत नहीं होता;)
मोनोलिथ

जवाबों:


129

दरअसल, मानक के अनुसार, constतत्व को सीधे उसके बाईं ओर संशोधित करता है । constएक घोषणा की शुरुआत में उपयोग केवल एक सुविधाजनक मानसिक शॉर्टकट है। इसलिए निम्नलिखित दो कथन समतुल्य हैं:

char const * pointerToConstantContent1;
const char * pointerToConstantContent2;

यह सुनिश्चित करने के लिए कि सूचक स्वयं संशोधित नहीं है, constतारांकन के बाद रखा जाना चाहिए:

char * const constantPointerToMutableContent;

पॉइंटर और सामग्री दोनों की रक्षा करने के लिए यह इंगित करता है, दो कास्ट का उपयोग करें।

char const * const constantPointerToConstantContent;

मैंने व्यक्तिगत रूप से हमेशा कॉन्स्टिट्यूशन को अपनाया है क्योंकि जिस हिस्से को मैं संशोधित नहीं करना चाहता हूं, मैं उसे तब भी संशोधित नहीं कर सकता, जब पॉइंटर वह हिस्सा है जिसे मैं निरंतर रखना चाहता हूं।


23
'सुविधाजनक आशुलिपि' ऐसी चीज़ के लिए एक दिलचस्प विवरण है जो छोटी नहीं है और सामान्य नियमों का पालन नहीं करती है।
चुकंदर

मानक वास्तव में परवाह नहीं करता है कि आप किस आदेश का उपयोग करते हैं। धारा 7.1.6 केवल दोनों स्थानों को दिखाती है और कहती है कि केवल एक में इसका उपयोग करें।
eda-qa mort-ora-y

1
@beetstra मैं सहमत हूं। मैंने इसे थोड़ा और स्पष्ट होने के लिए "सुविधाजनक मानसिक शॉर्टकट" में बदल दिया।
ग्रीजॉन

31

यह काम करता है क्योंकि दोनों समान हैं। इसमें आप भ्रमित हो सकते हैं,

const char*  // both are same
char const*

तथा

char* const  // unmutable pointer to "char"

तथा

const char* const  // unmutable pointer to "const char"

[इसे याद रखने के लिए, यहाँ एक सरल नियम है, '*' पहले पूरे LHS को प्रभावित करता है ]


ठीक है, मैं अब समझ गया। बहुत बहुत धन्यवाद।
लुचियन ग्रिगोर

1
unmutable pointer to char*.यह एक अनमोल सूचक है जो इंगित charनहीं करता है char *
आलोक सेव

25

ऐसा इसलिए है क्योंकि नियम है:

RULE: constजब तक बाईं ओर कुछ भी नहीं है, तब तक बाँध दिया जाता है, फिर इसे दाईं ओर बाँधा जाता है :)

इसलिए, इन्हें इस प्रकार देखें:

(const --->> char)*
(char <<--- const)*

दोनों एक ही! ओह, और --->>और <<---नहीं ऑपरेटर हैं, वे तो बस क्या दिखाने constको बांधता है।


2
हाँ, सही ऑपरेटर है -->>और यह केवल मूल्यों पर संचालित होता है। प्रयास करें int i = 8; std::cout << (i -->> 1) << std::endl;:)
अलेक्जेंडर मालाखोव

11

( 2 सरल चर आरंभीकरण प्रश्न से )

वास्तव में अंगूठे का एक अच्छा नियम const:

घोषणाएं राइट-टू-लेफ्ट पढ़ें।

(वन्देवोर्डे / जोसुत "सी ++ टेम्प्लेट्स: द कम्प्लीट गाइड" देखें)

जैसे:

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

जब से मैं इस नियम का पालन करता हूं, मैंने कभी भी इस तरह की घोषणाओं का गलत अर्थ नहीं निकाला।

(- सिसब रिटकारक-रेप नो टन, सिसाब नेकोट-रेप नो टफेल-ओटी-थगीर नेम आई हगोहट: टिडे


+1 यह शानदार है, धन्यवाद! मैं अपने सिर const char* constको उम्र भर के लिए पाने की कोशिश कर रहा हूं और आपको धन्यवाद अब मुझे मिल गया है।
OMGtechy

5

यहां बताया गया है कि मैं हमेशा कैसे व्याख्या करने की कोशिश करता हूं:

char *p

     |_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".

char * const p

     |_____ again start from the asterisk. "content of constant (since we have the `const` 
            modifier in the front) `p` is a `char`".

char const *p

           |_____ again start from the asterisk. "content of `p` is a constant `char`".

आशा है कि इससे सहायता मिलेगी!


0

आपके दोनों मामलों में आप एक निरंतर चार की ओर इशारा कर रहे हैं।

const char * x  //(1) a variable pointer to a constant char
char const * x  //(2) a variable pointer to a constant char
char * const x  //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?

डिफ़ॉल्ट रूप से, constजो अंदर है , उस पर लागू होता है, लेकिन यह उस पर लागू हो सकता है जो इसके दाईं ओर है, अगर इसमें (1) के रूप में, इससे आगे कुछ भी नहीं है।


पिछले एक: एक निरंतर चर सूचक, एक स्थिर चर करने के लिए एक स्थिर सूचक को।
सेको

यदि "निरंतर चर सूचक" से आपका मतलब "निरंतर सूचक" है, तो आपने इसे भाई!
लिनो मीडियाविला

अच्छी तरह से (5) यह एक चर पॉइंटर है जो एक स्थिर पॉइंटर से एक निरंतर चार तक सिर्फ इसलिए जाता है क्योंकि पहचानकर्ता "x" से पहले अंतिम तारांकन के दाईं ओर कोई "कॉन्स्ट" नहीं है। लेकिन (6) जो एक निरंतर पॉइंटर बन जाता है, शेष सभी समान हो जाते हैं।
लिनो मीडियाविला
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.