मैं आपके प्रश्न की व्याख्या दो प्रश्नों के रूप में करूँगा: 1) क्यों ->
मौजूद है, और 2) क्यों .
स्वचालित रूप से सूचक को निष्क्रिय नहीं करता है। दोनों सवालों के जवाब में ऐतिहासिक जड़ें हैं।
क्यों ->
मौजूद है?
सी भाषा के पहले संस्करणों में से एक में (जिसे मैं " सी संदर्भ मैनुअल " के लिए सीआरएम के रूप में संदर्भित करूंगा , जो मई 1975 में 6 वें संस्करण यूनिक्स के साथ आया ->
था ), ऑपरेटर का बहुत विशिष्ट अर्थ था, संयोजन *
और .
संयोजन का पर्याय नहीं
सीआरएम द्वारा वर्णित सी भाषा कई मायनों में आधुनिक सी से बहुत अलग थी। CRM संरचना में सदस्यों ने बाइट ऑफ़सेट की वैश्विक अवधारणा को लागू किया , जिसे बिना किसी प्रकार के प्रतिबंध के किसी भी पते के मूल्य में जोड़ा जा सकता है। यानी सभी संरचना सदस्यों के सभी नामों का स्वतंत्र वैश्विक अर्थ था (और, इसलिए, अद्वितीय होना चाहिए)। उदाहरण के लिए आप घोषित कर सकते हैं
struct S {
int a;
int b;
};
और नाम a
ऑफसेट 0 के लिए खड़ा होगा, जबकि नाम b
ऑफसेट 2 के लिए खड़ा होगा ( int
आकार 2 का प्रकार और कोई पैडिंग नहीं)। भाषा को अनुवाद इकाई में सभी संरचनाओं के सभी सदस्यों की आवश्यकता है या तो अद्वितीय नाम हैं या समान ऑफसेट मूल्य के लिए खड़े हैं। उदाहरण के लिए एक ही अनुवाद इकाई में आप अतिरिक्त घोषणा कर सकते हैं
struct X {
int a;
int x;
};
और यह ठीक होगा, क्योंकि नाम a
लगातार ऑफसेट 0. के लिए खड़ा होगा , लेकिन यह अतिरिक्त घोषणा
struct Y {
int b;
int a;
};
औपचारिक रूप से अमान्य होगा, क्योंकि इसने a
ऑफसेट 2 के b
रूप में और ऑफसेट 0 के रूप में "पुनर्परिभाषित" करने का प्रयास किया था ।
और यह वह जगह है जहां ->
ऑपरेटर आता है। चूंकि प्रत्येक संरचना सदस्य नाम का अपना आत्मनिर्भर वैश्विक अर्थ था, इसलिए भाषा ने इन जैसे भावों का समर्थन किया
int i = 5;
i->b = 42; /* Write 42 into `int` at address 7 */
100->a = 0; /* Write 0 into `int` at address 100 */
पहले असाइनमेंट को कंपाइलर द्वारा "टेक एड्रेस 5
, ऐड ओन इट्स 2
टू ऐड " और परिणामी पते पर मान असाइन 42
किया गया था int
। यानी ऊपर आवंटित होगा 42
करने के लिए int
पते पर मूल्य 7
। ध्यान दें कि इस प्रयोग ->
ने बायीं ओर के अभिव्यक्ति के प्रकार की परवाह नहीं की। बाएं हाथ की ओर की व्याख्या एक सांख्यिक संख्यात्मक पते के रूप में की गई (जैसा कि यह एक सूचक या पूर्णांक है)।
इस तरह की प्रवंचना *
और .
संयोजन संभव नहीं था । आप नहीं कर सके
(*i).b = 42;
चूंकि *i
पहले से ही एक अमान्य अभिव्यक्ति है। *
ऑपरेटर, क्योंकि यह से अलग है .
इसके संकार्य पर, लगाता अधिक सख्त प्रकार की आवश्यकताओं। इस सीमा के आसपास काम करने की क्षमता प्रदान करने के लिए सीआरएम ने ->
ऑपरेटर को पेश किया , जो बाएं हाथ के ऑपरेंड के प्रकार से स्वतंत्र है।
जैसा कि कीथ ने टिप्पणियों में उल्लेख किया है, यह ->
और *
+ .
संयोजन के बीच का अंतर है जिसे सीआरएम 7.1.8 में "आवश्यकता की छूट" के रूप में संदर्भित कर रहा है: आवश्यकता के विश्राम को छोड़कर जो E1
सूचक प्रकार का है, अभिव्यक्ति E1−>MOS
बिल्कुल इसके बराबर है(*E1).MOS
बाद में, के एंड आर सी में कई विशेषताओं को मूल रूप से सीआरएम में वर्णित किया गया था। "संरचनात्मक सदस्य के रूप में वैश्विक ऑफसेट पहचानकर्ता" का विचार पूरी तरह से हटा दिया गया था। और ->
ऑपरेटर की कार्यक्षमता पूरी तरह से *
और .
संयोजन की कार्यक्षमता के समान हो गई ।
क्यों .
सूचक को स्वचालित रूप से बाधित नहीं कर सकता है?
फिर से, भाषा के सीआरएम संस्करण में .
ऑपरेटर के बाएं ऑपरेटर को एक अंतराल होना आवश्यक था । यह केवल उस ऑपरेंड पर लगाई गई आवश्यकता थी (और ->
जैसा कि ऊपर बताया गया है , उससे अलग है )। ध्यान दें कि CRM को एक संरचनात्मक प्रकार के लिए बाएं ऑपरेंड की आवश्यकता नहीं थी .
। यह सिर्फ एक आवेग होना चाहिए, कोई लवल्यू । इसका मतलब है कि सी के सीआरएम संस्करण में आप इस तरह कोड लिख सकते हैं
struct S { int a, b; };
struct T { float x, y, z; };
struct T c;
c.b = 55;
इस मामले में संकलक निरंतर मेमोरी ब्लॉक में बाइट-ऑफसेट 2 पर तैनात मूल्य 55
में लिखेगा , भले ही कोई भी नाम टाइप न हो।int
c
struct T
b
। कंपाइलर वास्तविक प्रकार की बिल्कुल भी परवाह नहीं करेगा c
। सभी के बारे में परवाह है कि c
यह एक प्रकार का फल था: कुछ प्रकार की लेखन योग्य स्मृति ब्लॉक।
अब ध्यान दें कि अगर आपने ऐसा किया है
S *s;
...
s.b = 42;
कोड को वैध माना जाएगा (चूंकि s
यह भी एक लवल्यू है) और कंपाइलर केवल बाइट-ऑफसेट में ही सूचक मेंs
डेटा लिखने का प्रयास करेगा । कहने की जरूरत नहीं है, इस तरह की चीजें आसानी से मेमोरी ओवररन हो सकती हैं, लेकिन भाषा ऐसे मामलों से खुद को चिंतित नहीं किया।
ओवरलोडिंग ऑपरेटर के बारे में प्रस्तावित विचार भाषा के उस संस्करण में Ie .
पॉइंटर प्रकारों के लिए काम नहीं करेगा: ऑपरेटर का .
पहले से ही बहुत विशिष्ट अर्थ था जब पॉइंटर्स के साथ (लैवल्यू पॉइंटर्स के साथ या किसी भी अंतराल के साथ)। यह बहुत ही अजीब कार्यक्षमता थी, इसमें कोई संदेह नहीं है। लेकिन यह उस समय था।
बेशक, यह अजीब कार्यक्षमता अतिभारित पेश करने के खिलाफ एक बहुत मजबूत कारण नहीं है .
सी - के एंड आर सी के पुन: संस्करण में संकेत के लिए ऑपरेटर (जैसा कि आपने सुझाव दिया था) नहीं है, लेकिन ऐसा नहीं किया गया है। हो सकता है कि उस समय सी के सीआरएम संस्करण में कुछ विरासत कोड लिखा गया था जिसे समर्थन किया जाना था।
(1975 सी संदर्भ मैनुअल के लिए URL स्थिर नहीं हो सकता है। एक और प्रतिलिपि, संभवतः कुछ सूक्ष्म अंतरों के साथ, यहाँ है ।)