इसे समझाने के लिए असेंबली का उपयोग करने के लिए खेद है, लेकिन मुझे लगता है कि यह समझने का सबसे अच्छा तरीका है कि संकलक द्वारा संदर्भ कैसे लागू किए जाते हैं।इस कोड के
#include <iostream>
using namespace std;
int main()
{
int i = 10;
int *ptrToI = &i;
int &refToI = i;
cout << "i = " << i << "\n";
cout << "&i = " << &i << "\n";
cout << "ptrToI = " << ptrToI << "\n";
cout << "*ptrToI = " << *ptrToI << "\n";
cout << "&ptrToI = " << &ptrToI << "\n";
cout << "refToNum = " << refToI << "\n";
//cout << "*refToNum = " << *refToI << "\n";
cout << "&refToNum = " << &refToI << "\n";
return 0;
}
आउटपुट इस
i = 10
&i = 0xbf9e52f8
ptrToI = 0xbf9e52f8
*ptrToI = 10
&ptrToI = 0xbf9e52f4
refToNum = 10
&refToNum = 0xbf9e52f8
की तरह है चलो disassembly को देखो (मैं इस। 8,9 के लिए GDB का इस्तेमाल किया और यहां 10 कोड की लाइन नंबर दिए गए हैं)
8 int i = 10;
0x08048698 <main()+18>: movl $0xa,-0x10(%ebp)
यहां $0xa
10 (दशमलव) है जिसे हम i
पर असाइन कर रहे हैं। -0x10(%ebp)
का अर्थ है ebp register
-16 (दशमलव) की सामग्री। -0x10(%ebp)
स्टैक्स पर i
के पते पर इंगित करता है।
9 int *ptrToI = &i;
0x0804869f <main()+25>: lea -0x10(%ebp),%eax
0x080486a2 <main()+28>: mov %eax,-0x14(%ebp)
असाइन ptrToI
को i
का पता। ptrToI
पता -0x14(%ebp)
पर स्थित स्टैक पर है, जो ebp
- 20 (दशमलव) है।
10 int &refToI = i;
0x080486a5 <main()+31>: lea -0x10(%ebp),%eax
0x080486a8 <main()+34>: mov %eax,-0xc(%ebp)
अब कैच है! लाइन 9 और 10 के डिस्सेप्लर की तुलना करें और आप पर्यवेक्षक होंगे कि -0x14(%ebp)
को -0xc(%ebp)
द्वारा लाइन संख्या 10 में बदल दिया गया है। -0xc(%ebp)
RefToNum का पता है। यह ढेर पर आवंटित किया गया है। लेकिन आप इस पते को कभी भी कोड से प्राप्त नहीं कर पाएंगे क्योंकि आपको पता जानने की आवश्यकता नहीं है।
तो; एक संदर्भ स्मृति पर कब्जा करता है। इस मामले में यह स्टैक मेमोरी है क्योंकि हमने इसे स्थानीय चर के रूप में आवंटित किया है। यह कितनी मेमोरी पर कब्जा करता है? जितना अधिक सूचक होता है।
अब देखते हैं कि हम संदर्भ और पॉइंटर्स तक कैसे पहुंचते हैं। सादगी के लिए मैं विधानसभा का टुकड़ा
16 cout << "*ptrToI = " << *ptrToI << "\n";
0x08048746 <main()+192>: mov -0x14(%ebp),%eax
0x08048749 <main()+195>: mov (%eax),%ebx
19 cout << "refToNum = " << refToI << "\n";
0x080487b0 <main()+298>: mov -0xc(%ebp),%eax
0x080487b3 <main()+301>: mov (%eax),%ebx
अब ऊपर दो पंक्तियों की तुलना का ही हिस्सा दिखाया गया है, आप हड़ताली समानता देखेंगे। -0xc(%ebp)
refToI
का वास्तविक पता है जो आपके लिए कभी भी सुलभ नहीं है। सरल शब्दों में, यदि आप सामान्य सूचक के रूप में संदर्भ के बारे में सोचते हैं, तो संदर्भ का उपयोग करना संदर्भ द्वारा इंगित पते पर मूल्य लाने जैसा है। इसका मतलब है कोड के नीचे दो पंक्तियों आप एक ही परिणाम
cout << "Value if i = " << *ptrToI << "\n";
cout << " Value if i = " << refToI << "\n";
दे देंगे अब इस
15 cout << "ptrToI = " << ptrToI << "\n";
0x08048713 <main()+141>: mov -0x14(%ebp),%ebx
21 cout << "&refToNum = " << &refToI << "\n";
0x080487fb <main()+373>: mov -0xc(%ebp),%eax
मुझे लगता है कि आप को पहचानना यहाँ क्या हो रहा है में सक्षम हैं की तुलना करें। यदि आप &refToI
के लिए पूछते हैं, तो -0xc(%ebp)
पता स्थान की सामग्री लौटा दी गई है और -0xc(%ebp)
है जहां refToi
रहता है और इसकी सामग्री i
का पता नहीं है।
एक आखिरी बात, यह पंक्ति क्यों टिप्पणी की गई है?
//cout << "*refToNum = " << *refToI << "\n";
क्योंकि *refToI
की अनुमति नहीं है और यह आपको एक संकलन समय त्रुटि दे देंगे।
"मुझे लगा कि उस स्तर को गहराई से समझने से मुझे अवधारणा सूचक बनाम संदर्भ बेहतर समझ जाएगा" मुझे नहीं लगता कि इससे कोई मदद मिलेगी। –
आप इसे आजमा सकते हैं: http://eetimes.com/discussion/programming-pointers/4023307/References-vs-Pointers – Vlad
@ MR.Anubis ..... आपका क्या मतलब है? – howtechstuffworks