मैं अक्सर पॉइंटर्स के फायदे (निम्न स्तर की प्रोग्रामिंग को छोड़कर) देखने के लिए संघर्ष करता हूं।
क्यों एक स्ट्रिंग या चार [] के बजाय चार * का उपयोग करें या क्या सूचक अंकगणित लाता है।
तो क्या हैं और संकेत के मामलों का उपयोग करें?
मैं अक्सर पॉइंटर्स के फायदे (निम्न स्तर की प्रोग्रामिंग को छोड़कर) देखने के लिए संघर्ष करता हूं।
क्यों एक स्ट्रिंग या चार [] के बजाय चार * का उपयोग करें या क्या सूचक अंकगणित लाता है।
तो क्या हैं और संकेत के मामलों का उपयोग करें?
जवाबों:
डायनेमिक मेमोरी लोकेशन, कई डेटा स्ट्रक्चर्स और बड़ी मात्रा में डेटा की कुशल हैंडलिंग के लिए पॉइंटर्स आवश्यक हैं। पॉइंटर्स के बिना, आपको विश्व स्तर पर या फ़ंक्शंस या समकक्ष में सभी प्रोग्राम डेटा आवंटित करना होगा, और यदि आपके पास मूल रूप से अनुमति दी गई थी, तो डेटा की मात्रा में वृद्धि होने पर आपको कोई सहारा नहीं होगा। मैं यहां निरपेक्षता का उपयोग करने में संकोच करता हूं, लेकिन जहां तक मुझे पता है कि सभी आधुनिक कंप्यूटर भाषाओं में किसी न किसी रूप में संकेत होते हैं।
अधिकांश भाषाओं में जो पॉइंटर्स का उपयोग करते हैं, कुछ निश्चित प्रकार के संदर्भ हैं जो पॉइंटर्स हैं, और शायद कुछ विशेष प्रकार के संदर्भ हैं, और आगे कोई उल्लेखनीय अंतर नहीं है। लिस्प cons
सेल पॉइंटर्स की एक जोड़ी है, हालाँकि fixnum
यह पॉइंटर नहीं है। जावा में, वर्ग के उदाहरण के लिए उपयोग किया जाने वाला चर एक सूचक है, लेकिन int
यह नहीं है। भाषा सिंटैक्स यह प्रतिबिंबित नहीं करता है।
सी असामान्य है कि संकेत वैकल्पिक, स्पष्ट हैं, और स्पष्ट सूचक अंकगणित की अनुमति देते हैं। यह लिखना पूरी तरह से संभव है struct foo bar; struct foo * baz;
, और एक बार आपके द्वारा मेमोरी आवंटित करने के बाद आप baz
दोनों का उपयोग कर सकते हैं bar
और एस baz
का प्रतिनिधित्व कर सकते हैं struct foo
। चूँकि संकेत वैकल्पिक होते हैं, अत: इसमें भिन्नताएँ होना उपयोगी होता है। (यह स्मार्ट पॉइंटर्स के लिए C ++ में आवश्यक है, जैसा कि दिया गया है boost::shared_ptr<foo> bar;
, bar.reset()
इसका एक अर्थ है और bar->reset()
बहुत अलग होने की संभावना है।)
(वास्तव में, स्पष्ट संकेत अक्सर अन्य भाषाओं में उपयोग किए जाते थे जब सी मूल रूप से विकसित किया जा रहा था, जैसे ^
पास्कल। सी आज की आम उपयोग की तुलना में एक पुरानी भाषा है, और यह दिखाता है।)
सी के डिजाइन लक्ष्यों में से एक यूनिक्स को लिखना था, और इसलिए इसे एक विस्तृत तरीके से मेमोरी स्थानों को संभालने की आवश्यकता थी। (सी वास्तव में सिस्टम कार्यान्वयन भाषाओं के परिवार में से एक है जब इसे डिज़ाइन किया जा रहा था, तो नियंत्रण डेटा कंप्यूटरों के लिए एक और उदाहरण Cybol जा रहा है। C वह है जो एक बड़ा हिट बन गया है।) इसलिए, सी पॉइंटर्स को सीधे हेरफेर करना संभव है। मेमोरी एड्रेस को असाइन करना और नए की गणना करना। इसने सी। सी। सरणियों में कुछ डिज़ाइन निर्णयों का भी नेतृत्व किया जो कि सूचक अंकगणितीय पर बहुत अधिक आधारित हैं, और वास्तव में एक सरणी बहुत अधिक परिस्थितियों में एक सूचक में गिरावट करती है। चर को C फ़ंक्शन में संदर्भ द्वारा पास करना पॉइंटर द्वारा किया जाता है। अन्य समकालीन भाषाओं के रूप में संदर्भों द्वारा सरणियों और पासिंग चर की कोई मजबूत आवश्यकता नहीं थी, इसलिए सी उन्हें नहीं मिला।
तो, इसका उत्तर यह है कि, आजकल अधिकांश भाषाओं में, आप बिना तथ्य याद किए लगातार पॉइंटर्स का उपयोग करते हैं। C में, और कुछ हद तक C ++ में, आप पॉइंटर्स का उपयोग या तो निम्न-स्तरीय चीजों के लिए करते हैं, या उच्च-स्तरीय चीजों को पूरा करने के लिए, जिनके लिए कोई विशेष अंकन नहीं है।
जटिल डेटा संरचनाएं। आप एक लिंक की गई सूची या बिंदुओं के बिना एक द्विआधारी पेड़ की तरह कुछ नहीं बना सकते हैं।
वहाँ कोई "पेशेवरों" और संकेत के "विपक्ष" हैं। वे सिर्फ एक उपकरण हैं, हथौड़े की तरह।
C ++, Java और अन्य प्रकार की भाषाओं में सन्दर्भ केवल 'सुरक्षित बिंदु' हैं। और ये संदर्भ जावा में बहुत उपयोग किए जाते हैं।
NULL
, और उनके बनाए जाने के बाद उन्हें संशोधित नहीं किया जा सकता है।
बहुत अधिक किसी भी कंप्यूटर प्रोग्राम को स्मृति में मूल्यों का निरीक्षण करने और बदलने की जरूरत है (जिन्हें पीकिंग और पोकिंग के रूप में जाना जाता है, हममें से जो बहुत पुराने हैं)। आपको यह नियंत्रित करने की आवश्यकता है कि स्मृति में वे मान कहां हैं, ताकि परिणाम पूर्वानुमेय हो (और कुछ मामलों में, आदेश महत्वपूर्ण है: निष्पादन योग्य कोड लोड करना एक उदाहरण है)। इसलिए आपके पास एक डेटा प्रकार होना चाहिए जो मेमोरी में किसी स्थान का प्रतिनिधित्व करता है। यहां तक कि अगर आपके प्रोग्रामिंग वातावरण छुपा है कि एक अमूर्त के तहत, यह अभी भी वहाँ है।
char*
संकेत का एक गंभीर उदाहरण है। आप शायद std::string
(या कुछ बेहतर प्रकार का उपयोग करके बेहतर हैं जो आपकी यूनिकोड / एएनएसआई / मल्टीबाइट विशेषता) को संभालता है char*
। संकेत के लगभग किसी भी अन्य उदाहरण के लिए ( Employee*
, PurchaseOrder*
, ...), तथापि, वहाँ कई लाभ हैं:
वास्तव में, पॉइंटर्स इतने महत्वपूर्ण हैं कि अधिकांश भाषाएं जो वास्तव में उनके पास नहीं हैं, वे वास्तव में उनके पास हैं। C # और Java में संदर्भ प्रकार अनिवार्य रूप से ठोस वस्तुओं के रूप में प्रच्छन्न बिंदु हैं।
अब, पॉइंटर मैनिपुलेशन ( p++
एक पॉइंटर पर, या p += delta
) एक पूरी 'नोटेर कहानी है। कुछ लोग सोचते हैं कि यह खतरनाक है, कुछ लोग सोचते हैं कि यह बहुत अच्छा है। लेकिन यह आपके प्रश्न से और भी अधिक है।
पॉइंटर्स तेज़ हो सकते हैं और डेटा संरचनाओं और प्रोग्राम निष्पादन पदचिह्न को नीचे रखने में, कम ओवरहेड को उकसा सकते हैं। (कृपया 'कैन' शब्द पर ध्यान दें।)
सामान्य तौर पर, नियम है, यदि आपने एक संसाधन आवंटित किया है, या तो अपना स्वयं का आवंटन करके या अपनी ओर से कुछ कर रहे हैं, तो यह आपका काम है कि इसे कब जारी किया जाए।
उपर्युक्त करने का भार ज़िम्मेदारी को डेवलपर पर वापस रख रहा है, बजाय रनटाइम के ऐसा करने के बजाय। इसके कुछ और फायदे हैं कि चीजों को लंबे समय तक जीवित रखा जा सकता है, या सीमाओं को पार किया जा सकता है, या अधिक उपयुक्त समय पर निपटाया जा सकता है, या चारों ओर एक कचरा कलेक्टर के वजन को ले जाने की आवश्यकता नहीं है।
विदेशी मामलों में, आमतौर पर अपवादों और दायरे को शामिल करते हुए, कुछ किनारे मामले होते हैं जिनके लिए कोड की सफाई से बचने के लिए किसी को थोड़ा अधिक सावधान रहने की आवश्यकता होती है। वास्तविक रूप से, इन मामलों को चारों ओर डिजाइन किया जा सकता है। हम कई दशकों तक प्रबंधित कोड के बिना रहते थे।
अक्सर क्या संकेत देता है "कठिन" केवल समझ में नहीं आ रहा है कि हार्डवेयर स्तर पर क्या हो रहा है। यह अप्रत्यक्ष से ज्यादा कुछ नहीं है।
पॉइंटर्स आपको अधिक कच्ची पहुंच प्रदान करते हैं, और यह बहुत सहायक, चतुर या आवश्यक हो सकता है। आप कहीं भी इंगित कर सकते हैं और इसे बहुत अधिक समझ सकते हैं। यदि आप अच्छे के लिए अपनी ईश्वर जैसी शक्तियों का उपयोग करते हैं, तो यह बहुत अच्छा है।
कोन साइड आमतौर पर किसी चीज़ को रिलीज़ करने के लिए, या इसे एक से अधिक बार रिलीज़ करके, या इसके रिलीज़ होने के बाद किसी चीज़ को रिफ़र करने से, या जब आप कहीं भी इशारा नहीं कर रहे होते हैं, तो इसे रिफ़ायर करके बर्बाद कर देते हैं। ये चीजें अक्सर शानदार दुर्घटनाओं का कारण बनती हैं, और ईमानदार होना आमतौर पर संकेत देता है कि आपको तर्क समस्या मिल गई है, बजाय संकेत नाजुक हैं।
यदि आप एक ठोस डेवलपर हैं, तो पॉइंटर्स का उपयोग करना किसी भी अन्य डेटा संरचना की तुलना में अधिक समस्याग्रस्त नहीं होना चाहिए। फिर से, यह रॉकेट साइंस नहीं है, और लोगों ने दशकों तक बिना पलक झपकाए इसे किया। यह सिर्फ इन दिनों के माध्यम से कम सिखाया जाता है।
सभी ने कहा, जब तक आपको पॉइंटर्स की आवश्यकता नहीं होती, तब तक जो अच्छा कचरा संग्रह प्रदान करता है, वह शालीनता और एक्सोइटिक मामले एक प्रबंधित वातावरण में काम करता है जो बहुत अच्छा है। कुछ मेमोरी को हथियाने, उसका उपयोग करने और इसे छोड़ने के लिए सक्षम होने के लिए बहुत अच्छा है, यह जानते हुए कि कुछ समय बाद, यह डिसेर्बर्ड हो सकता है, अगर यह ऐसा करने के लिए समझ में आता है। कोडर के हिस्से पर यह थोड़ा कम कोड है, बदले में कुछ अतिरिक्त उठाने के लिए।
सबसे अच्छा जवाब वास्तव में सवाल में शामिल है: संकेत निम्न-स्तरीय प्रोग्रामिंग के लिए हैं। दी, यदि आप C का उपयोग कर रहे हैं, तो पॉइंटर्स का उपयोग नहीं करना आपकी पीठ के पीछे बंधे एक हाथ से प्रोग्रामिंग करने जैसा है, लेकिन इसका उत्तर इसके बजाय एक उच्च-स्तरीय भाषा का उपयोग करना है।