2009-07-10 16 views
8

के लिए:सी संकेत दिए गए प्रश्न

int *a; 

a एक पते जहां एक पूर्णांक संग्रहीत किया जा सकता है। &a एक पता है जहां एक संग्रहित किया जाता है। फिर, &a कहां संग्रहीत है? और, &(&a) कहां संग्रहीत है? और, &(&(&a)) कहाँ संग्रहीत है? पते का यह संग्रह कहां बंद हो जाता है?

+1

एक पूर्णांक संग्रहीत नहीं किया जा सकता जब तक आप कुछ स्मृति को आबंटित, या तुम सच में कैसे संकेत जमा हो जाती है के लिए देख रहे हैं एक

+0

करने के लिए कुछ वैध स्मृति का पता असाइन, को यह जवाब बाहर की जाँच करें: http://stackoverflow.com/questions/991075/does-a-pointer-also-have-any-address-or-memory-allocation/991152#991152 –

+0

यहां भी: http://stackoverflow.com/questions/96285/in- सीआई-कैन-ग्रिप-पॉइंटर्स-एंड-क्लासेस/98525 # 9 8525 –

उत्तर

4

&a एक स्थिर है।

&(&a) अवैध है।

+1

उस दायरे में स्थिर = पी – DevinB

+2

'और ए' नहीं है वास्तव में एक स्थिर। परिवर्तनीय ढेर पर हो सकता है। यह रनटाइम में गणना करता है। –

+3

यह एक रैवल्यू है (यानी, जो आप एक असाइनमेंट ऑपरेटर के दाहिने तरफ रखेंगे), और इसलिए जहां तक ​​कार्यक्रम का संबंध है, तब तक निरंतर एक स्थिरता है। तथ्य यह है कि अलग-अलग रनों पर अलग-अलग मूल्य हो सकते हैं, यह अप्रासंगिक है। –

7

यदि आप स्पष्ट रूप से &a नहीं लिखते हैं तो यह कहीं भी संग्रहीत नहीं किया जाएगा। यदि आप लिखते हैं तो पता गणना की जाएगी और या तो एक अज्ञात चर (अस्थायी) या आपके द्वारा लिखे गए नामित विविधता में संग्रहीत की जाएगी।

उदाहरण के लिए:

functionCall(&a); // address will be in a temporary variable used for passing the parameter 
int** b = &a; // address will be stored in variable b 
otherFunctionCall(&&a); // illegal, since &a is an expression operator & can't be applied to it 
+0

भले ही मैं नहीं लिखूं और ए, वहां कुछ जगह होनी चाहिए जहां वास्तव में संग्रहीत किया जाता है? – dharm0us

+0

@dta: मुझे यकीन नहीं है कि मैं यहां आपका प्रश्न समझ रहा हूं ... 'ए' स्टैक पर संग्रहीत है, बस किसी अन्य स्थानीय चर की तरह। जब आप '& a' लिखते हैं, तो प्रोग्राम स्टैक' ए 'में संग्रहीत स्थान के पते की गणना करता है (यह पहले से ही स्टैक पॉइंटर को जानता है क्योंकि यह एक रजिस्टर है और यह ऑफसेट को स्टैक फ्रेम में जानता है क्योंकि यह स्थिर के रूप में संकलित है) और इसके साथ कुछ करता है, जैसा कि sharptooth द्वारा समझाया गया है। – rmeador

+0

ठीक है, हाँ। आप फिर चर के चर और पते को भ्रमित करते हैं। वे आमतौर पर बराबर नहीं होते हैं। वेरिएबल कुछ पते पर स्थित स्मृति का एक हिस्सा है और इसमें कुछ मूल्य है। – sharptooth

3

& एक एक का पता है। यह एक मान है, ऑपरेटर & पर लागू होता है, और "संग्रहीत" नहीं होता है, और इसका कोई पता नहीं है, इसलिए & (ए) अमान्य है। यह 2 + 3 की तरह है।

0

ए "int का पता" प्रकार का एक चर है; & एक चर का पता है; & (& एक) अलग-अलग एक का पता है, जो कोई मतलब नहीं

4

a बनाता है पता होगा "एक पते जहां एक पूर्णांक संग्रहीत किया जा सकता" नहीं है। a एक चरणीय है जो एक पूर्णांक के पते को पकड़ने के लिए पर्याप्त है। केवल "पूर्णांक" आप सीधे a में स्टोर कर सकते हैं एक पूर्णांक के पते, एक पूर्णांक खुद के रूप में देखा है:

int *a; 
int b; 

a = &b; 

printf("a is now %x\n", (unsigned int) a); 

यह सही है कि a अपने आप में एक पते, जो &a है, लेकिन है कि पता नहीं है रनटाइम पर, कहीं स्पष्ट रूप से संग्रहीत किया जाता है।

एक खंड में, आप कुछ है कि पूर्णांक 0 की तरह दिखता है स्टोर करने के लिए सक्षम हो सकता है:

a = 0; 

लेकिन इस "नल पॉइंटर" के लिए सिर्फ एक आशुलिपि वाक्य रचना, यानी न करने की गारंटी एक सूचक मूल्य है किसी भी वास्तविक वस्तु का पता हो।

+0

यह जवाब सही नहीं है ... लेकिन यह एक निश्चित +1 है क्योंकि मुझे लगता है कि यह निश्चित रूप से पूछताछ के लिए मूल प्रश्न को समझाने/जवाब देने का सबसे अच्छा मौका है। – Beska

0

काफी नहीं। a एक चर है जिसमें कुछ पूर्णांक का पता संग्रहीत किया जा सकता है। &aa का पता है, i। ई। परिवर्तनीय a का पता, जिसमें कुछ पूर्णांक का पता हो सकता है।

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

0

आपके पास पॉइंटर के लिए पॉइंटर हो सकता है।

पूर्व:

void foo(int **blah) 
{ 
int *a = *blah; 

... 
} 

एक सूचक स्मृति का समय लग करता है। यह सिर्फ एक छोटा सा कंटेनर है जो कुछ का पता रखता है। यह सिर्फ "कोई जगह नहीं" ले सकता है क्योंकि कंप्यूटर में सबकुछ किसी भी तरह से संख्याओं द्वारा प्रदर्शित किया जाता है। यह सिर्फ इतना है कि जहां तक ​​सी/सी ++ सम्मिलित है, int * ए केवल किसी वस्तु के लिए सूचक है और कोई स्थान नहीं लेता है। यह आपको किसी भी प्रकार की मेमोरी को प्रबंधित करने से रोकता है ... यह कोड को कोड से अलग रखता है।

+0

एक सूचक निश्चित रूप से स्मृति लेता है। int * ए; स्टैक पर एक स्थानीय चर आवंटित करता है, जो आपके मशीन पर एक सूचक को स्टोर करने के लिए कई बाइट्स की आवश्यकता होती है। – Dima

1

आप हमेशा के लिए जा रहा रख सकते हैं:

int value = 742; 
int *a = &value; 
void *b = &a; 
void *c = &b; 
void *d = &c; 

तुम कुछ भी करने के लिए बिना निर्दिष्ट किए एक लाइन पर डाल दिया नहीं होगा - उस मामले में यह अवैध होगा।

+0

हां, लेकिन शून्य का उपयोग आमतौर पर फहराया जाता है। Int ** बी, int *** c, int **** d, आदि लिखना बेहतर होगा। – Dima

0

int * a; 'ए' नामक एक इंट के लिए एक सूचक है। और ए; int * ए का अपमान है। यह खुद को इंगित कर रहा है। यह वही है जो आप उस चर को इंगित करने के लिए उपयोग करेंगे जिसे आप फ़ंक्शन से फ़ंक्शन तक पास करना चाहते थे। "पता वापस पाने" के लिए अपमान केवल एक फैंसी शब्द है & (& (ए)) पहले बताए गए वैध अभिव्यक्ति नहीं है। आप पॉइंटर को पॉइंटर पर पॉइंटर बना सकते हैं। यह आपकी सोच क्या हो सकता है। ऐसे मामले में आप प्रश्न में अंतिम सूचक को खराब कर देंगे और कंप्यूटर को समझना चाहिए कि आप किस बारे में बात कर रहे हैं।

"संग्रहीत" प्रश्न का उत्तर देने के लिए; ढेर पर

कृपया, अगर मैं कुछ भी गलत हूं, तो मुझे बताएं।

0

& एक संख्या है जो एक रैल्यू है: यदि आप एक वैरिएबल में चाहते हैं तो आप इसे कहीं भी स्टोर कर सकते हैं, जिसे आपने int * टाइप किया है या आवंटित किया होगा।

बुद्धि के लिए

:

int a = 42; 
&a; /* this does not store the address of a because you've not assigned the value to a variable */ 
int **aptr = &a; /* aptr is on the stack */ 
int **aptr2 = (int*)malloc(sizeof(int*)); 
aptr2 = &a; /* aptr2 is in the heap */ 

& (& क) कानूनी सिंटैक्स नहीं है। आप किसी पूर्णांक पर एक सूचक के लिए सूचक चाहते हैं:

int b = 39; 
int *bptr = &b; 
int **ptr2bptr = &bptr; 

आप अविवेक के स्तर का निर्माण करने के लिए है।

के साथ आप ऊपर तो यह कर सकते हैं अगर आप चाहते हैं:

printf("%d\n", *aptr); 
printf("%d\n", *aptr2); 
printf("%d\n", *bptr); 
printf("%d\n", **ptr_to_bptr); 

के उत्पादन उत्पादन:

42 
42 
39 
39 
2

int *a एक चर एक सूचक का आकार है, बस int b की तरह एक स्वत: होगा int चर।

इस घोषणा एक समारोह में है, तो उस चर स्वत: और इसके लिए [stack] (http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) रनटाइम पर (एक सरल ढेर घटती आवंटित स्मृति)। पर

तो घोषणा वैश्विक है संग्रहीत है, फिर 'ए' बस निष्पादन योग्य के .DATA क्षेत्र में मैप किया गया है।

किसी भी अधिक & संकेत संलग्न अस्थायी चर आप होल्डम के लिए उपयोग कर रहे हैं की वजह से 'संग्रहण बनाएं' कर सकते हैं,;):

b = &a; //the address in the executable's .DATA or on the stack (if `a` auto) 
c = &b; //the address of `b` on the stack, independent of `a` or `&a` 
d = &c; //the address of `c` on the stack, independent of `a` or `&a` 
z = &(&a); //error: invalid lvalue in unary '&' 

अंतिम पंक्ति तथ्य के बारे में शिकायत है कि & संकार्य की आवश्यकता है lvalue होने के लिए। यही है, कुछ असाइन करने योग्य - जैसे b और c उपरोक्त। (&a) एक अभिव्यक्ति का परिणाम है जो कहीं भी संग्रहीत नहीं है, इसलिए lvalue नहीं है।

0
int* a; 

यह लाइन बस एक पूर्णांक के लिए एक सूचक घोषित करता है। उस सूचक में एक स्मृति स्थान होता है, जिसे आप & ए का उपयोग करने का पता प्राप्त कर सकते हैं। & एक ऑपरेटर है जो जो कुछ भी चल रहा है उसका पता देता है। लेकिन अगर आप कहीं भी इस मान को असाइन नहीं करते हैं, तो &-संभव नहीं है।

& पर आपके प्रश्न के अनुसार, एक रजिस्टर में सबसे अधिक संभावना है। यदि आप मूल्य का उपयोग नहीं करते हैं, तो इसे तुरंत हटा दिया जाएगा।

1

अपने समस्या की जड़ पर स्मृति और संकेत के भौतिक प्रकृति के समझ की कमी हो रहा है (और रजिस्टरों है, जिसके कारण आप & (& क) ऐसा नहीं कर सकते स्मृति पते नहीं हैं,)। कोड कैसे काम करता है। जैसा कि मुझे यकीन है कि आप जानते हैं, भौतिक स्मृति आसन्न कोशिकाओं के एक बड़े समूह में शामिल है। इन कोशिकाओं के पते निश्चित रूप से कंप्यूटर द्वारा तय किए गए हैं और हार्ड-कोड किए गए हैं, न कि आपके द्वारा उपयोग किए जाने वाले सॉफ़्टवेयर ऐप्स या प्रोग्रामिंग भाषा द्वारा। जब आप & ए का संदर्भ लेते हैं, तो आप उस स्मृति के भौतिक ब्लॉक का जिक्र कर रहे हैं जो वर्तमान में आपके मूल्य को कंप्यूटर रैम में संग्रहीत कर रहा है। "ए" बस एक ऐसा नाम है जिसे आपने कंप्यूटर दिया है ताकि यह पता चल सके कि आपके द्वारा संग्रहीत मूल्य को खोजने के लिए स्मृति का क्या ब्लॉक है। मुझे लगता है कि काफी मेमोरी पता शामिल है।
अब पॉइंटर्स पर जाएं। एक सूचक अभी तक एक और स्मृति पता है, जिसे कंप्यूटर द्वारा संदर्भित किया जाता है। यह आपके पास जो भी नाम है, वह है। इस मामले में इसे उसी नाम के अलावा कुछ और कहा जाना चाहिए जिसे आपने अपना पहला मूल्य दिया था। चलिए इसे "बी" कहते हैं। आपने इसे कैसे घोषित किया है इसके आधार पर। बी का मेमोरी लोकेशन केवल एक प्रकार का डेटा रखने में सक्षम है .... एक और मेमोरी लोकेशन .... इसलिए जब मैं कहता हूं: बी = & मैं कह रहा हूं कि 'बी' का मेमोरी पता (जिसे केवल डिज़ाइन किया गया है) मेमोरी पतों को पकड़ें), 'ए' के ​​मेमोरी एड्रेस को पकड़ना है। इस बीच शहर के दूसरी तरफ, 'ए' के ​​स्मृति पते में एक पूर्णांक संग्रहित है।

मुझे उम्मीद है कि यह भ्रमित नहीं हो रहा है, मैंने यहां आपके सभी तकनीकी-बच्चों को पाने की कोशिश नहीं की। यदि आप अभी भी उलझन में हैं। फिर से पोस्ट करें, बीएल अगली बार कोड के साथ समझाओ।

-UBcse

1

सी में, एक चर x एक मूल्य के रूप में कार्य कर सकते हैं (=, के दाहिने हाथ की ओर, जहां यह एक rvalue कहा जाता है), या यह एक कंटेनर के लिए के रूप में कार्य कर सकते हैं मूल्य (बाईं ओर बाईं तरफ, जहां इसे lvalue कहा जाता है)। आप x का पता ले सकते हैं, क्योंकि आप का पता ले सकते हैं lvalue — यह आपको कंटेनर के लिए सूचक देता है। लेकिन चूंकि एक सूचक एक रैल्यू है, न कि कंटेनर, आप कभी भी &(&x) नहीं ले सकते हैं। वास्तव में किसी भी lvalue l, &l कानूनी है लेकिन &(&l) कभी कानूनी नहीं है।

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