2013-07-23 10 views
37

यह सूचक नहीं। ये क्यों हो रहा है?अदालत << चार * तर्क प्रिंट तार के साथ, मूल्य

+0

क्या आप वाकई "हैलो" नहीं प्राप्त करते हैं? – sth

+0

आपको आउटपुट के रूप में 'h' मिलता है? ऐसा नहीं होना चाहिए। आपको आउटपुट के रूप में 'हैलो' प्राप्त करना चाहिए। क्या आप वाकई यहां पोस्ट किया गया कोड सही है और टाइपो या कॉपी और पेस्ट त्रुटि नहीं है? –

+0

@sth वह करता है: http://ideone.com/IDudH3 – dotixx

उत्तर

8

आप इस के लिए अपने कोड बदलना चाहिए:

cout << static_cast<const void*>(terry); 

समस्या यह है कि << ऑपरेटर स्ट्रिंग की सामग्री के मुद्रण के लिए C-शैली तार की ओर इशारा करने के लिए ओवरलोड है। यदि आप इसे कच्चे पॉइंटर पर डाल देते हैं, तो आपके पास iostreams का उपयोग करके प्रिंटिंग पॉइंटर का डिफ़ॉल्ट व्यवहार होगा।

-1

"हैलो" एक स्ट्रिंग है, यानी चार सरणी है। const char* इस सरणी के लिए एक सूचक है, इसलिए जब आप इस पॉइंटर को अस्वीकार करते हैं, तो आपको पहले तत्व का मान मिलता है।

ऐसा लगता है कि अगर आप

int a[] = {1, 2, 3}; 
int *b = a; 
cout << *b << endl; 

है तुम सिर्फ 1 मुद्रित है।

+0

मुझे स्मृति पता क्यों नहीं मिल रहा है? –

+1

@ श्रीपफ यदि आप चार पॉइंटर का मेमोरी एड्रेस प्राप्त करना चाहते हैं, तो आपको इसे पहले पॉइंटर पर डालना चाहिए, क्योंकि 'ओस्ट्रीम <<' ऑपरेटर स्ट्रिंग प्रिंट करने के लिए चार पॉइंटर्स के लिए ओवरलोड हो गया है। –

53

इसका कारण यह है कि std::cout एक char * को एक सी-स्टाइल स्ट्रिंग के पॉइंटर (पहले वर्ण) के रूप में और इसे प्रिंट करने के रूप में मानेंगे। आप के बजाय पता चाहते हैं, तो आप सिर्फ यह एक सूचक है कि इलाज नहीं है डाल सकता कि जिस तरह से, कुछ की तरह:

cout << (void *) terry; 

(या const void * डाली उपयोग करें यदि आप कास्टिंग बारे में चिंतित हैं दूर स्थिरता, कुछ ऐसा जो इस विशेष मामले में कोई मुद्दा नहीं है)।


आप उपयोगितावादी की तुलना में एक शुद्धतावादी के और अधिक कर रहे हैं, तो आप भी सी ++ static_cast, उपयोग कर सकते हैं की तर्ज पर:

cout << static_cast <const void *> (terry); 

हालांकि यह अनावश्यक इस विशेष मामले में एक को डाली है, void * ठीक काम करेगा।

#include <iostream> 
int main (void) { 
    const char *terry = "hello"; 
    std::cout << terry << '\n'; 
    std::cout << (void *) terry << '\n'; 
    std::cout << (const void *) terry << '\n'; 
    std::cout << static_cast<const void *> (terry) << '\n'; 
    return 0; 
} 

outputting (पता अपने वातावरण में अलग हो सकता है):

hello 
0x8048870 
0x8048870 
0x8048870 

ध्यान दें कि, जब static_cast उपयोग कर, आप आपके पास यह सुनिश्चित करना चाहिए निम्न नमूना कोड कार्रवाई में इन सभी विकल्पों को दर्शाता है static_cast <void *> के साथ स्थिरता को दूर करने की कोशिश नहीं करें (यही const_cast है)। यह नए सी ++ कलाकारों द्वारा किए गए चेकों में से एक है और पुरानी शैली के कलाकारों में यह सीमा नहीं है।

+1

यह 'char *' मान को सी-स्टाइल स्ट्रिंग के रूप में नहीं मानता है; यह इसे एक सी-स्टाइल स्ट्रिंग के लिए * सूचक * के रूप में (पहले वर्ण) के रूप में मानता है। –

+1

@ केथ, अर्थशास्त्र समस्या, इसके लिए क्षमा चाहते हैं। मेरा मतलब यह था कि यह इसे सी-स्टाइल स्ट्रिंग के रूप में प्रिंट करता है। मैं स्पष्ट करूंगा। – paxdiablo

+0

क्या शब्द "अर्थशास्त्र" का अर्थ यह है कि यह एक महत्वहीन भेद है? यह नहीं है –

1

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

यदि आपने कोउट के बजाय printf का उपयोग किया है, तो आप पता देखेंगे। आप पॉइंटर को किसी अन्य प्रकार में भी डाल सकते हैं, कहें (शून्य *) और आपको पता भी मिलेगा।

+0

'printf' यह तय नहीं करता कि यह कैसे प्रिंट करता है, आपको अभी भी सही प्रारूप विनिर्देशक का उपयोग करना होगा, वैसे ही आपको उसी प्रकार का उपयोग C++ में करना होगा। उदाहरण के लिए, '% s' के साथ' printf' में 'char *' के साथ 'cout' के समान सटीक समस्या होगी। पॉइंटर प्राप्त करने के लिए, आप एक प्रारूप निर्दिष्ट '% p' का उपयोग करेंगे। – paxdiablo

11

<< ऑपरेटर std::cout पर अधिभारित है। इसका व्यवहार सही ऑपरेंड के प्रकार पर निर्भर करता है। (यह वास्तव में कई विभिन्न कार्यों सभी नामित operator<< है,; संकलक का फैसला करता है, जो एक कॉल करने के लिए।)

आप दे यह एक char* या const char*, यह (के पहले अक्षर) एक सी के सूचक के रूप संकार्य व्यवहार करता है तो

cout << *terry; // prints "h" 
cout << terry[0]; // the same 

आप इसे typ के एक सूचक देते हैं:

const char * terry = "hello"; 
cout << terry; // prints "hello" 

आप इसे एक char मूल्य देना है, यह एक चरित्र के रूप में है कि मूल्य प्रिंट: शैली स्ट्रिंग, और कहा कि स्ट्रिंग की सामग्री को प्रिंट ई void*, यह प्रिंट कि सूचक मूल्य (कुछ कार्यान्वयन से परिभाषित रास्ते में, आम तौर पर हेक्साडेसिमल):

cout << static_cast<const void*>(terry); // prints something like 0x4008e4 

एक char* या const char* इलाज के रूप में एक सी शैली स्ट्रिंग के लिए एक सूचक एक विशेष मामला है, और केवल एक (जिसे मैं सोच सकता हूं) जो ऑपरेटिंग के मूल्य के अलावा कुछ प्रिंट करने के लिए operator<< का कारण बनता है। इसका कारण सी में सी ++ की जड़ों पर वापस जाता है, जिसमें "स्ट्रिंग" प्रकार नहीं होता है और char* पॉइंटर्स के माध्यम से तारों का उपयोग करता है।

operator<< के लिए std::string, और आगे के लिए विभिन्न पूर्णांक और फ़्लोटिंग-पॉइंट संख्यात्मक प्रकारों के लिए कई अन्य ओवरलोड हैं।

+0

एक और "विशेष" मामला मैं सोच सकता हूं कि एक फ़ंक्शन पॉइंटर मुद्रित करने का प्रयास कर रहा है, जो 'बूल' ओवरलोड का चयन करेगा (जब तक कि फ़ंक्शन में स्ट्रीम मैनिपुलेटर का हस्ताक्षर न हो): http://ideone.com/OkutRD (स्वीकार्य रूप से , यह 'बूल' में परिवर्तित सूचक के "मूल्य" को प्रिंट करता है, इसलिए यह 'कॉन्स्ट char * 'केस से" कम विशेष "है) –

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