2011-09-09 10 views
7

मान लीजिएमुझे आश्चर्य है कि वास्तव में क्या और एक रिटर्न?

पहला मामला

int a; 
int *p= &a ; it works no error 

दूसरा मामला

long int a; 
long int b; 
b = & a; it wont work 

हम में से अधिकांश का कहना है कि ख एक चर नहीं सूचक है। लेकिन नीचे देखें।

तो सवाल यह है कि &a उस पते को वापस भेजता है जो एक हस्ताक्षरित पूर्णांक है तो हम इसे सामान्य चर में क्यों निर्दिष्ट नहीं कर सकते? लेकिन केवल पॉइंटर्स क्यों? नीचे

b = (unsigned int) &a ; it works after typecasting though its not practicable. 

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

आपके सभी उत्तरों के लिए धन्यवाद लेकिन वास्तविक प्रश्न वास्तव में &a रिटर्न क्या है? पूर्णांक मूल्य या नहीं? यदि यह पूर्णांक संख्या है तो एक चर यह क्यों नहीं रख सकता है? लंबे int = 65535 \ valid क्यों int = & बी नहीं है यदि पता बी का मान 65535

मुझे पॉइंटर के रूप में उपयोग करने के लिए चिंतित नहीं है, तो प्रश्न केवल मूल्य को बचाने के बारे में है। पते का खंडन नहीं। 32 या 64 बिट कह रहे लोग, मैं इसके बारे में चिंतित नहीं हूं। पता अगर यह एक पूर्णांक संख्या है तो पता क्यों नहीं सहेज सकता है?

मेरा मतलब है क्यों नहीं कर सकते हम मान असाइन, मैं चर की ओर इशारा के गुणों आवंटित करने के लिए लेकिन सिर्फ मूल्य thats आवंटित यह

a=65535 
b = a \\ works it assigns b - 65535 
&a=65535 
b = & a \\ doesn't work, if address is a some integer value,why we can't store it in a variable? 

(उदाहरण के सामान्य सूचक के रूप में 16 बिट ले यह नहीं कह रहा हूँ पता) आकार 2 बाइट्स है और परिवर्तनीय आकार 2 बाइट्स है, हम पते को अन्य चर में क्यों नहीं स्टोर कर सकते हैं अगर पता पूर्णांक मान है, तो मेरे प्रश्न में मुझे कई उत्तरों मिलते हैं जैसे ++ यह 4 से पॉइंटर और वैल्यू 1 से वैरिएबल तक चिंतित है, चिंतित नहीं है इसके बारे में सिर्फ मूल्य असाइन करना अधिक महत्वपूर्ण सवाल है।

b = & a ; address of a is 4000 
    ++b ; becomes 4001 thats it,thats not a problem 
+2

"सामान्य चर" क्या है? "पॉइंटर्स अंदर कुछ करना चाहिए" सही। आपको और क्या जानने की आवश्यकता है? वे ** ** पूर्णांक नहीं हैं। वे पॉइंटर्स हैं। कृपया "सामान्य चर" से आपका क्या मतलब है, यह बताने के लिए ** अपना प्रश्न अपडेट करें। –

+2

हालांकि यह हुड के नीचे एक पूर्णांक है, प्रकार मेल नहीं खाते हैं, इसलिए आप उन्हें असाइन नहीं कर सकते हैं। ऐसा लगता है कि 'असंबंधित क्लासए' और 'असंबंधित क्लासबी' केवल बाइट हैं, तो आप एक दूसरे को क्यों असाइन नहीं कर सकते? यह प्रकार प्रणाली का हिस्सा है। –

उत्तर

22

इंटीग्रर्स, यहां तक ​​कि long int, हमेशा सूचक के समान आकार नहीं होने जा रहे हैं। कभी-कभी वे होंगे (उदाहरण के लिए, अधिकांश 32-बिट आर्किटेक्चर में sizeof(int) == sizeof(void *) है), कभी-कभी वे अलग होंगे (उदाहरण के लिए, कुछ 64-बिट आर्किटेक्चर में sizeof(long) == sizeof(void *) है लेकिन कुछ नहीं - विंडोज पर विजुअल सी ++ एक कंपाइलर का एक प्रमुख उदाहरण है जहां sizeof(long) != sizeof(void *))।

वहाँ भी तथ्य यह है कि void * बस long int रूप में एक ही प्रकार नहीं है।

एक वर्ग Foo और एक वर्ग Bar, इसलिए तरह परिभाषित कल्पना कीजिए:

class Foo { 
    public: int a; 
}; 

class Bar { 
    public: int b; 
}; 

यह कारण है कि आप प्रकार Bar के एक चर करने के लिए वर्ग Foo का एक उदाहरण असाइन नहीं कर सकते पूछ की तरह है - वे नहीं कर रहे हैं वही बात, भले ही इस मामले में Foo और Bar दोनों समान अंतर्निहित बिट पैटर्न हैं।

+0

अद्भुत, @ डीन हार्डिंग। अद्भुत अद्भुत –

6

आप कर सकते हैं और यह बहुत ही सामान्य था, अब यह हालांकि के रूप में यह एक 64-बिट सूचक के साथ 64 प्लेटफार्मों पर नहीं किया जा सकता एक उचित पोर्टेबिलिटी मुद्दा है और एक 32-बिट पूर्णांक है।

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

यह आधुनिक उपयोग में अत्यधिक समझदार नहीं है क्योंकि यह आसानी से गलतियों और भ्रम की ओर ले जा सकता है। कंपाइलर डिज़ाइन में सुरक्षा सुधार टाइप करें इस तरह के उपयोग को अस्वीकार करते हैं लेकिन सी 99 uintptr_t और intptr_t के साथ कुछ समान समर्थन को फिर से पेश करता है जो "ऑब्जेक्ट पॉइंटर्स रखने में सक्षम इंटीजर प्रकार" हैं।

क्यों हम [एक पूर्णांक] चर करने के लिए [एक सूचक] असाइन नहीं कर सकते:

अपने प्रश्न की व्याख्या करने के लिए?

उत्तर है: क्योंकि यह असेंबलर नहीं है, सी और सी ++ strongly typed भाषाएं हैं।

3

यह सी या सी ++ के लिए विशिष्ट नहीं है। यह सभी दृढ़ता से टाइप की गई भाषाओं में समान है। यह अंग्रेजी में भी एक डिग्री के लिए सच है। हम कह सकते हैं कि "पुस्तक का रंग नीला है", लेकिन "पुस्तक का रंग लकड़ी नहीं है"। टाइप संभावित मान को प्रतिबंधित करता है जो एक चर हो सकता है।

एक चर int* प्रकार केवल मूल्यों है कि पूर्णांक के पते दिए गए हैं पकड़ कर सकते हैं और प्रकार long int के एक चर केवल LONG_MIN और LONG_MAX समावेशी के बीच मान हो सकते हैं। यह मूल्यों के केवल दो पूरी तरह से अलग सेट है।

सी और सी ++ पूर्ण नहीं हैं। टाइपकास्टिंग आपको कुछ प्रतिबंधों को बाईपास करने की अनुमति देगा। जैसे (int) 3.5 संकलक को बताता है कि आप गैर-पूर्णांक मान 3.5 को लगभग समान पूर्णांक मान में कनवर्ट करना चाहते हैं। यह बेहतर काम करता है यदि दो प्रकार अधिक समान हैं। अन्य भाषाओं में ऐसे टाइपकास्टिंग नहीं हो सकते हैं; वहां आपको इसके बजाय एक फ़ंक्शन कॉल करने की आवश्यकता हो सकती है। जैसे ROUND(3.5, INT)

+0

'(int) 3.5' ​​एक बुरा उदाहरण है क्योंकि यह एक कलाकार के बजाय रूपांतरण दिखाता है। यदि यह वास्तविक कलाकार था, तो मूल्य '3' नहीं होगा लेकिन बिट अनुक्रम की व्याख्या जो भी हो। – blubb

+0

@ सिमॉन: सी ++ में, यह अनजाने में एक कलाकार है। सटीक होने के लिए एक 'static_cast '। यह भी एक रूपांतरण है; दोनों अनन्य नहीं हैं। आप एक 'reinterpret_cast' के बारे में सोच रहे हैं, जो कि अन्य कास्ट प्रकारों में से एक है। हालांकि, आप 'reinterpret_cast (3.5) 'नहीं कर सकते; संभावित रूपांतरणों की सूची में 'int' से' int' नहीं है। (§ 5.2.10) – MSalters

7

पते जो एक अहस्ताक्षरित पूर्णांक

नहीं है देता है, ऐसा नहीं है। एक सूचक (पता) एक सूचक है। अवधि।

+0

यद्यपि आप जो कह रहे हैं वह सच में सच है, यह पॉइंटर नौसिखिया के लिए वास्तव में सहायक नहीं है, जिसे मैं मानता हूं ओपी है। – MGZero

+0

एमजीजेरो - मैं इस बात की सराहना करता हूं कि वह * समस्या के बारे में सोचता है, और मैं उसे उन चरणों में इंगित करता हूं जहां वह गलत मानते हैं। मुझे विश्वास है कि वह आगे सोचकर समस्या को हल करने में सक्षम है। यह आईएमएचओ बेहतर है कि चांदी के टैबलेट पर सबकुछ मिलता है। – Ingo

2

निको, आईएमएचओ टाइप की गई भाषाओं का बिंदु यह है कि आप केवल एक चीज को दूसरे को असाइन नहीं कर सकते हैं, भले ही वे सभी निम्नतम स्तर पर बिट्स का एक गुच्छा हो।

1

पॉइंटर्स आमतौर पर पूर्णांक के रूप में लागू होते हैं, लेकिन सी ++ विनिर्देश केवल उनके व्यवहार को परिभाषित करता है (जहां बराबर या अलग दो पॉइंटर्स इत्यादि होते हैं)।

एक संकेतक में एक सूचक को बदलना किसी अन्य वर्ग/प्रकार के एक उदाहरण को बदलने जैसा है।

b = (uint) &a; क्यों काम करता है, शायद यह कार्यान्वयन-निर्भर है। (और आर्क-आश्रित)।

2

यदि पता पूर्णांक प्रारूप है तो क्यों हस्ताक्षर किए गए या लंबे पूर्णांक इसे सहेजते हैं। मैं सोच रहा था, इसके पीछे कुछ गुप्त गुप्त होना चाहिए।

पता एक पूर्णांक नहीं है; यह एक पता है। एक 64 बिट सिस्टम पर, यह:

int *p; 

एक 64 बिट चर आबंटित करता है, इस जबकि:

int b; 

एक 32 बिट चर आवंटित करता है। वे वही नहीं हैं। वे कुछ प्रणालियों पर एक ही आकार के रूप में प्रतीत हो सकते हैं, लेकिन वे समान नहीं हैं। ++ ऑपरेटर के एक उदाहरण के रूप में विचार करें। 32 बिट सिस्टम पर, पॉइंटर पर ++ पॉइंटर 4 से बढ़ाता है, जबकि एक पूर्णांक पर ++ पूर्णांक को 1 से बढ़ाता है। कंपाइलर आपको यह बताकर आपकी मदद करने की कोशिश कर रहा है कि आप कुछ गलत कर रहे हैं।

1

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

डेटा (चर) में इसके साथ जानकारी है .. मेटा डेटा। इसका आकार, मूल्य, डेटाटाइप .... वह पता जहां यह संग्रहीत है। एक पॉइंटर उस मेटा डेटा, पते का अंतिम टुकड़ा धारण कर रहा है। यह एक विशेष डेटाटाइप है जो प्राथमिक कार्य है पते को पकड़ना। सूचक का मूल्य डेटा के मूल्य से स्वतंत्र है, वे 2 अलग-अलग चीजें हैं। पॉइंटर का मूल्य आपको बताता है कि आप जिस डेटा को ढूंढ रहे हैं उसे कहां ढूंढना है। यही कारण है कि आप जिस तरीके से कोशिश कर रहे हैं उसमें आप एक पॉइंटर में पूर्णांक नहीं डाल सकते हैं। यह कहने जैसा है कि आप कुछ सड़क पते पर रहते हैं, और आप भी वह पता हैं। कल्पना कीजिए कि अगर लोग आपको आपके पते से बुलाते हैं, तो वह मूर्खतापूर्ण होगा!

इस पर विचार करें: आपके पास एक्स नामक एक वर्ग है, जिसमें कुछ सदस्य हैं। आप इस कक्षा में एक सूचक बनाते हैं। सूचक अभी भी एक हेक्स प्रारूप के साथ एक पता रखता है .. लेकिन वस्तु को 4 या 8 बाइट (32 बिट और 64 बिट क्रमशः) मूल्य में तोड़ा नहीं जा सकता है! ध्यान दें, सभी डेटाटाइप में पॉइंटर का प्रारूप वही है, चाहे उनका मूल्य चाहे।

int a; int *p= &a; 

अब .. कारण यह क्यों काम करता है क्योंकि आपने चर के पते को लिया और इसे पॉइंटर पी में रखा। कीवर्ड ADDRESS है, जो एक पॉइंटर रखता है।

long int a; 
long int b; 
b = & a; 

यह काम नहीं किया है क्योंकि आप ख है, जो सिर्फ एक चर रहा है में एक का पता (एक सूचक) डालने की कोशिश की।

इसे सरलता से रखने के लिए, आप एक सामान्य चर में कोई पता नहीं डाल सकते हैं। एक पता केवल एक सूचक में संग्रहीत किया जा सकता है।

0

आपकी प्रारंभिक सोच में एक गलतफहमी है: "सामान्य चर" और "poitners" हैं। ऐसी कोई अवधारणा नहीं है। केवल "चर" और "प्रकार" हैं।

  • पूर्णांक
  • वर्ग व्यक्ति एक व्यक्ति वर्णन के लिए एक कंटेनर है एक "एक पूर्णांक मूल्य के लिए कंटेनर" है।
  • int * एक पूर्णांक के पते के लिए एक कंटेनर है
  • व्यक्ति * किसी व्यक्ति के पते के लिए एक कंटेनर है।

& ऑपरेटर एक चर का पता देता है, और इसका प्रकार "उस प्रकार का सूचक" है। असाइनमेंट केवल किसी दिए गए प्रकार की अभिव्यक्ति से संगत प्रकार के चर के लिए जा सकते हैं। int, int *, व्यक्ति और व्यक्ति * सभी एक दूसरे के असंगत हैं। आप एक इंट * को एक इंट के लिए असाइन नहीं कर सकते हैं क्योंकि आप एक व्यक्ति को किसी इंट या इंट को इंटरेक्ट नहीं कर सकते हैं। जब तक कि आपके पास कोई ऐसा फ़ंक्शन न हो जो आपको एक अभिव्यक्ति लिखने के लिए प्रेरित करता है, एक दूसरे से दूसरे प्रकार को लौटाता है। बस operator & करता है और &a अभिव्यक्ति आपको देता है।

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