2010-07-23 38 views
10

मैं ऐसा क्यों नहीं कर सकते करने के लिए आवंटित?स्थिरांक सूचक एक सूचक

यह अजीब लगता है, क्योंकि इसे किसी अन्य सूचक को असाइन करके, आप अनिवार्य रूप से चार सूचक के कॉन्स्टेस का उल्लंघन नहीं कर रहे हैं। या आप हैं?

संपादित करें: जब मैं इस संकलन में यह कहते हैं, "त्रुटि C2440: '=': से 'चार * स्थिरांक * __ W64' परिवर्तित नहीं कर सकते करने के लिए 'चार *' '

(मैं एक अवधारणा को समझने का प्रयास कर रहा हूँ । एक किताब मैं पढ़ रहा हूँ से बस कोड को संकलित करने नहीं मिल सकता है

कोड:।

int _tmain(int argc, _TCHAR* argv[]) 
{ 

    MyString *strg = new MyString(10); 
    strg->SetString("Hello, "); 

    MyString *secondstr = new MyString(7); 
    secondstr->SetString("Tony"); 

    strg->concat(*secondstr, *strg); 

} 

सीपीपी फ़ाइल:

#include "MyStringClass.h" 
#include <string.h> 
#include "stdafx.h" 

#include "MyStringClass.h" 

void MyString::concat(MyString& a, MyString& b) 
{ 
    len = a.len + b.len; 
    s = new char[len + 1]; 
    strcpy(s, a.s); 
    strcat(s, b.s); 
    delete [] s; 

} 

void MyString::SetString(char * const str) 
{ 
    s = str; 
} 

MyString::MyString(int n) 
{ 
    s = new char[n+1]; 
    s[n+1] = '\0'; 
    len = n; 
} 

हेडर फाइल:

#include <string.h> 
#include <stdio.h> 

class MyString 
{ 
private: 
    char* s; 
    int len; 
public: 
    MyString(int n = 80); 

    void SetString (char * const str); 

    void concat (MyString& a, MyString& b); 
}; 
+2

उस कोड के साथ कुछ भी गलत नहीं है, प्रति से। वास्तविक समस्या को हल करने के लिए वास्तविक संकलन त्रुटियों के साथ हमें वास्तविक कोड क्यों नहीं दिखाएं? – GManNickG

+0

संपादन के जवाब में, "इसे संकलित करें" क्या है ... आपने संकलित कोड पोस्ट नहीं किया है। :) हमें आप जो संकलित कर रहे हैं, उसका एक छोटा सा स्निपेट दें। – GManNickG

+3

ओह माय। यह कोड प्रत्येक पंक्ति के लिए सी ++ प्रोग्रामिंग के लगभग दो बुनियादी सिद्धांतों का उल्लंघन करता है। मुझे नहीं पता कि आपको कहां से शुरू करना है कि इसमें क्या गलत है। सी ++ से आप कौन सी पुस्तक सीख रहे हैं? जो कुछ भी है, उसे मिटाएं और लिखने से पहले [परिभाषात्मक सी ++ पुस्तक गाइड और सूची] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) पर एक नज़र डालें कोई अन्य लाइन – sbi

उत्तर

12

वहाँ लगातार सूचक और निरंतर सूचक के बीच अंतर है। एक सूचक जिसका उठाई मूल्य नहीं बदला जा सकता है

int * const const_pointer = &some_int_var; // will be always pointing to this var 
const_pointer = &some_other_var; // illegal - cannot change the pointer 
*const_pointer = 2; // legal, the pointer is a pointer to non-const 

सूचक लगातार करने के लिए:

- बदला नहीं जा सकता है कि वह हमेशा आरंभीकरण के माध्यम से दिए गए एक ही वस्तु को इंगित - लगातार सूचक एक सूचक (स्मृति पते के एक नंबर) है
const int * pointer_to_const = &some_int_var; // doesn't have to be always pointing to this var 
pointer = &some_other_var; // legal, it's not a constant pointer and we can change it 
*pointer = 2; // illegal, pointed value cannot be changed 

आप हमेशा निरंतर चर यानी कॉन्स्ट पॉइंटर को गैर-कॉन्स्ट पॉइंटर (ए) में असाइन कर सकते हैं। आप पॉइंटर को कॉन्स (बी) के लिए पॉइंटर पर गैर-कॉन्स तक डाल सकते हैं। ++

int * pointer; 
int * const const_pointer = &var; 
const int * pointer_to_const; 

/* a */ 
pointer = const_pointer; // OK, no cast (same type) 

/* b */ 
pointer_to_const = pointer; // OK, casting 'int*' to 'const int*' 

/* c */ 
pointer = pointer_to_const; // Illegal, casting 'const int*' to 'int*' 

[संपादित करें] नीचे, यह नहीं मानक सी है: लेकिन आप करने के लिए गैर स्थिरांक (ग) एक सूचक को const सूचक डाली नहीं कर सकता। बहरहाल, यह आम है [/ संपादित करें]
स्ट्रिंग शाब्दिक

"Hello" 

स्थिरांक (const char * const) के लिए निरंतर सूचक में बदल जाती है।

char *pointer = "Hello"; // Illegal, cannot cast 'const char*' to 'char*' 
char * const const_pointer = "Hello"; // Illegal, cannot cast 'const char*' to 'char*' 
const char * pointer_to_const = "Hello"; // OK, we can assign a constant to a variable of the same type (and the type is 'const char*') 
"Hello" = pointer_to_const; // Illegal cannot re-assign a constant 

उपरोक्त उदाहरण में दूसरा अपने मामले है। आपने पॉइंटर-टू-गैर-कॉन्स को पॉइंटर-टू-कॉन्स के साथ प्रारंभ करने की कोशिश की, जब आपके फ़ंक्शन के तर्क के रूप में स्ट्रिंग शाब्दिक पास किया गया। इससे कोई फर्क नहीं पड़ता कि ये पॉइंटर्स स्थिर हैं या नहीं, इससे कोई फर्क नहीं पड़ता कि वे क्या इंगित करते हैं।

सारांश:
1) यदि आप किसी अन्य प्रकार का एक सूचक को किसी प्रकार की एक सूचक डाली हैं, तो आप सूचक करने वाली गैर स्थिरांक सूचक करने वाली स्थिरांक डाली नहीं कर सकता।
2) यदि आपके पास निरंतर सूचक है, तो वही नियम अन्य स्थिरांक के रूप में लागू होते हैं - आप एक चर के लिए निरंतर असाइन कर सकते हैं लेकिन आप चर को एक स्थिर (इसे प्रारंभ करने के अलावा) असाइन नहीं कर सकते हैं।

// संपादित
GMAN के रूप में बताया, सी ++ 98 मानक (§4.2/2) परोक्ष एक गैर स्थिरांक चार सूचक को स्ट्रिंग शाब्दिक (जो लगातार चार सरणियों कर रहे हैं) कास्ट करने के लिए अनुमति देता है। यह पिछड़े संगतता की वजह से है (सी भाषा में कोई स्थिरांक नहीं है)।

बेशक इस तरह के एक रूपांतरण से गलतियों का कारण बन सकता है और कंपाइलर्स नियम का उल्लंघन करेंगे और एक त्रुटि दिखाएंगे। हालांकि, संगतता मोड में जीसीसी केवल एक चेतावनी दिखाता है।

+2

इसमें कुछ गलत जानकारी है, जो गलत परिणामों को जन्म देती है। एक स्ट्रिंग शाब्दिक एक [सरणी कक्ष का सरणी] है (http://stackoverflow.com/questions/3303164/why-isnt-if-maya-maya-true-in-c/3303212#3303212), न कि 'कॉन्स चार * '(हालांकि, चूंकि यह एक सरणी है, यह इस तरह क्षय हो सकता है)। हालांकि यह सच है कि इस तरह की एक सरणी को आम तौर पर 'char *' में परिवर्तित नहीं किया जा सकता है, स्ट्रिंग अक्षर में यह विशेष रूपांतरण होता है। (यह बहिष्कृत है, और केवल पिछड़ा संगतता के लिए मौजूद है।) तो आपके सभी तीन कोड उदाहरण पूरी तरह कानूनी हैं। – GManNickG

+0

मैंने लिखा था कि "यह एक सूचक में परिवर्तित हो जाता है", नहीं "यह एक सूचक है"। इसे एक सूचक में परिवर्तित किया जाता है जो उस सरणी को इंगित करता है जिसके बारे में आप कह रहे हैं। और आप गलत हैं - स्ट्रिंग अक्षर को स्पष्ट रूप से 'char *' में परिवर्तित नहीं किया जा सकता है। शायद आप चार सरणी प्रारंभिकरण के साथ उलझन में हैं। – adf88

+1

नहीं, मैं नहीं हूं। §4.2/2: "एक स्ट्रिंग शाब्दिक (2.13.4) जो एक विस्तृत स्ट्रिंग अक्षर नहीं है, को" पॉइंटर से चार "के रूप में परिवर्तित किया जा सकता है; एक विस्तृत स्ट्रिंग अक्षर को" पॉइंटर "के रूप में परिवर्तित किया जा सकता है wchar_t "। किसी भी मामले में, परिणाम सरणी के पहले तत्व के लिए एक सूचक है। यह रूपांतरण केवल तभी माना जाता है जब एक स्पष्ट उपयुक्त सूचक लक्ष्य प्रकार होता है, और जब एक सामान्यता से परिवर्तित करने की सामान्य आवश्यकता नहीं होती है एक रैवल्यू। [नोट: यह रूपांतरण बहिष्कृत है। अनुलग्नक डी देखें।] "जैसे मैंने कहा, सभी तीन पंक्तियां कानूनी हैं। (ठीक है, आपके पास अब चार है; पहला 3.) – GManNickG

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