सूचक (कंप्यूटर प्रोग्रामिंग): Difference between revisions
No edit summary |
|||
Line 289: | Line 289: | ||
=== नियंत्रण तालिकाओं में प्रयोग करें === | === नियंत्रण तालिकाओं में प्रयोग करें === | ||
{{see also|#Function pointer|#Wild branch}} | {{see also|#Function pointer|#Wild branch}} | ||
प्रोग्राम प्रवाह को नियंत्रित करने के लिए उपयोग की जाने वाली नियंत्रण तालिकाएं सामान्य रूप से पॉइंटर्स का व्यापक उपयोग करती हैं। पॉइंटर्स, सामान्य रूप से टेबल एंट्री में एम्बेडेड होते हैं, उदाहरण के लिए, उसी टेबल एंट्री में परिभाषित कुछ शर्तों के आधार पर [[सबरूटीन]]्स को एंट्री पॉइंट्स को निष्पादित करने के लिए | प्रोग्राम प्रवाह को नियंत्रित करने के लिए उपयोग की जाने वाली नियंत्रण तालिकाएं सामान्य रूप से पॉइंटर्स का व्यापक उपयोग करती हैं। पॉइंटर्स, सामान्य रूप से टेबल एंट्री में एम्बेडेड होते हैं, उदाहरण के लिए, उसी टेबल एंट्री में परिभाषित कुछ शर्तों के आधार पर [[सबरूटीन]]्स को एंट्री पॉइंट्स को निष्पादित करने के लिए उपयोग किया जा सकता है। हालाँकि पॉइंटर्स केवल अन्य अलग-अलग, लेकिन संबंधित तालिकाओं के लिए अनुक्रमित हो सकते हैं, जिसमें वास्तविक पतों की एक सरणी होती है या खुद एड्रैस होते हैं (प्रोग्रामिंग भाषा के उपलब्ध निर्माण के आधार पर)। उनका उपयोग पहले की तालिका प्रविष्टियों (लूप प्रोसेसिंग में) को इंगित करने के लिए या कुछ तालिका प्रविष्टियों को छोड़ने के लिए आगे बढ़ने के लिए भी किया जा सकता है (जैसे कि [[स्विच स्टेटमेंट]] में या लूप से जल्दी बाहर निकलना)। इस बाद के उद्देश्य के लिए, पॉइन्टर केवल तालिका प्रविष्टि संख्या ही हो सकता है और साधारण अंकगणितीय द्वारा वास्तविक एड्रैस में परिवर्तित किया जा सकता है। | ||
== टाइप किए गए पॉइंटर्स और कास्टिंग == | == टाइप किए गए पॉइंटर्स और कास्टिंग == | ||
Line 317: | Line 317: | ||
=== पॉइंटर्स का मूल्य === | === पॉइंटर्स का मूल्य === | ||
सी और सी ++ में, भले ही दो पॉइंटर्स बराबर के रूप में तुलना करें, इसका मतलब यह नहीं है कि वे समकक्ष हैं। इन भाषाओं और [[एलएलवीएम]] में, नियम की व्याख्या इस अर्थ में की जाती है कि सिर्फ इसलिए कि दो पॉइंटर्स एक ही एड्रैस की ओर इशारा करते हैं, इसका मतलब यह नहीं है कि वे इस अर्थ में समान हैं कि उन्हें एक दूसरे के स्थान पर | सी और सी ++ में, भले ही दो पॉइंटर्स बराबर के रूप में तुलना करें, इसका मतलब यह नहीं है कि वे समकक्ष हैं। इन भाषाओं और [[एलएलवीएम]] में, नियम की व्याख्या इस अर्थ में की जाती है कि सिर्फ इसलिए कि दो पॉइंटर्स एक ही एड्रैस की ओर इशारा करते हैं, इसका मतलब यह नहीं है कि वे इस अर्थ में समान हैं कि उन्हें एक दूसरे के स्थान पर उपयोग किया जा सकता है, पॉइंटर्स के बीच के अंतर को उनके उद्गम के रूप में संदर्भित किया जाता है।<ref>{{cite web |last1=Jung |first1=Ralf |title=Pointers Are Complicated II, or: We need better language specs |url=https://www.ralfj.de/blog/2020/12/14/provenance.html}}</ref> एक पूर्णांक प्रकार जैसे कि कास्टिंग करना <code>uintptr_t</code> कार्यान्वयन-परिभाषित है और यह जो तुलना प्रदान करता है वह इस बारे में अधिक जानकारी प्रदान नहीं करता है कि क्या दो पॉइंटर्स विनिमेय हैं। इसके अलावा, बाइट्स और अंकगणित में आगे रूपांतरण पॉइंटर्स के उपयोग को ट्रैक करने की कोशिश कर रहे ऑप्टिमाइज़र को फेंक देगा, एक समस्या अभी भी अकादमिक शोध में स्पष्ट है।<ref>{{cite web |title=Pointers Are Complicated, or: What's in a Byte? |url=https://www.ralfj.de/blog/2018/07/24/pointers-and-bytes.html |last1=Jung|first1=Ralf}}</ref> | ||
Line 479: | Line 479: | ||
<code>void</code> पॉइन्टर, या<code>void*</code>, एएनएसआई सी और सी ++ में एक सामान्य पॉइन्टर प्रकार के रूप में समर्थित है। के लिए एक संकेतक <code>void</code> किसी भी ऑब्जेक्ट (फ़ंक्शन नहीं) के एड्रैस को स्टोर कर सकता है, और, सी में, असाइनमेंट पर किसी अन्य ऑब्जेक्ट पॉइंटर प्रकार में अंतर्निहित रूप से परिवर्तित हो जाता है, लेकिन इसे संदर्भित होने पर स्पष्ट रूप से कास्ट किया जाना चाहिए। | <code>void</code> पॉइन्टर, या<code>void*</code>, एएनएसआई सी और सी ++ में एक सामान्य पॉइन्टर प्रकार के रूप में समर्थित है। के लिए एक संकेतक <code>void</code> किसी भी ऑब्जेक्ट (फ़ंक्शन नहीं) के एड्रैस को स्टोर कर सकता है, और, सी में, असाइनमेंट पर किसी अन्य ऑब्जेक्ट पॉइंटर प्रकार में अंतर्निहित रूप से परिवर्तित हो जाता है, लेकिन इसे संदर्भित होने पर स्पष्ट रूप से कास्ट किया जाना चाहिए। | ||
सी प्रोग्रामिंग भाषा | के एंड आर सी का | सी प्रोग्रामिंग भाषा | के एंड आर सी का उपयोग किया <code>char*</code> "टाइप-एग्नोस्टिक पॉइंटर" उद्देश्य के लिए (एएनएसआई सी से पहले)। | ||
int x = 4; | int x = 4; | ||
void* p1 = &x; | void* p1 = &x; | ||
Line 619: | Line 619: | ||
=== [[पर्ल]] === | === [[पर्ल]] === | ||
पर्ल प्रोग्रामिंग भाषा पॉइंटर्स का समर्थन करती है, हालांकि पैक और अनपैक फ़ंक्शंस के रूप में | पर्ल प्रोग्रामिंग भाषा पॉइंटर्स का समर्थन करती है, हालांकि पैक और अनपैक फ़ंक्शंस के रूप में संभव्यता ही कभी उपयोग किया जाता है। ये केवल संकलित ऑपरेटिंग सिस्टम पुस्तकालयों के साथ साधारण बातचीत के लिए अभिप्रेत हैं। अन्य सभी स्थितियो में, पर्ल संदर्भ (कंप्यूटर विज्ञान) का उपयोग करता है, जो टाइप किए जाते हैं और पॉइन्टर अंकगणित के किसी भी रूप की स्वीकृति नहीं देते हैं। उनका उपयोग जटिल डेटा संरचनाओं के निर्माण के लिए किया जाता है।<ref>{{cite web|author=Contact details |url=http://perldoc.perl.org/perlref.html#Making-References |title=// Making References (Perl References and nested data structures) |publisher=Perldoc.perl.org |access-date=2018-04-13}}</ref> | ||
== यह भी देखें == | == यह भी देखें == | ||
{{colbegin}} * | {{colbegin}} * एड्रैस नियत | ||
* [[ | * [[बाउंडेड पॉइंटर]] | ||
* | * बफर ओवरफ्लो | ||
* [[क्रे | * [[क्रे पॉइंटर]] | ||
* [[ | * [[फैट पॉइन्टर]] | ||
* फंक्शन पॉइंटर | * फंक्शन पॉइंटर | ||
* खतरा सूचक | * खतरा सूचक | ||
Line 633: | Line 633: | ||
* [[अपारदर्शी सूचक]] | * [[अपारदर्शी सूचक]] | ||
* [[पोइंटी]] | * [[पोइंटी]] | ||
* [[ | * [[पॉइंटर स्विजल]] | ||
* संदर्भ (कंप्यूटर विज्ञान) | * संदर्भ (कंप्यूटर विज्ञान) | ||
* [[ | * [[स्टेटिक प्रोग्राम विश्लेषण]] | ||
* | * संग्रहण उल्लंघन | ||
* [[टैग किए गए सूचक]] | * [[टैग किए गए सूचक]] | ||
* [[ | * [[वेरिएबल (कंप्यूटर विज्ञान)]] | ||
* [[शून्य आधारित | * [[शून्य आधारित संख्या]] | ||
{{colend}} | {{colend}} | ||
Revision as of 21:12, 27 February 2023
I do consider assignment statements and pointer variables to be among computer science's "most valuable treasures."
Donald Knuth, Structured Programming, with go to Statements[1]
![](https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/Pointers.svg/langen-gb-300px-Pointers.svg.png)
कंप्यूटर विज्ञान में, कई प्रोग्रामिंग भाषाओं में एक पॉइंटर एक वस्तु (कंप्यूटर विज्ञान) है जो एक मेमोरी पता को स्टोर करता है। यह मेमोरी में स्थित किसी अन्य मान का हो सकता है, या कुछ स्थितियो में, मेमोरी-मैप्ड I/O|मेमोरी-मैप्ड कंप्यूटर हार्डवेयर का हो सकता है। मेमोरी में एक पॉइंटर संदर्भ एक स्थान, और उस स्थान पर संग्रहीत मान प्राप्त करना डेरेफरेंस ऑपरेटर पॉइंटर के रूप में जाना जाता है। सादृश्य के रूप में, किसी पुस्तक की अनुक्रमणिका में पृष्ठ संख्या को संबंधित पृष्ठ का संकेतक माना जा सकता है; इस तरह के पॉइंटर को डिफ्रेंसिंग दिए गए पेज नंबर के साथ पेज पर फ़्लिप करके और उस पेज पर मिले टेक्स्ट को पढ़कर किया जाएगा। पॉइन्टर चर का वास्तविक प्रारूप और सामग्री अंतर्निहित कंप्यूटर आर्किटेक्चर पर निर्भर है।
पॉइंटर्स का उपयोग करने से दोहराए जाने वाले संचालन के लिए कंप्यूटर के प्रदर्शन में काफी सुधार होता है, जैसे ट्रैवर्सिंग कलेक्शन (सार डेटा प्रकार) # रैखिक संग्रह डेटा डेटा संरचना (जैसे स्ट्रिंग एल्गोरिदम, तालिका देखो, नियंत्रण तालिका और ट्री (डेटा संरचना) संरचनाएं)। विशेष रूप से, पॉइंटर्स को कॉपी करने और डेटा को एक्सेस करने की तुलना में पॉइंटर्स को कॉपी और डीरेफेरेंस करना प्रायः समय और स्थान में बहुत सस्ता होता है।
पॉइंटर्स का उपयोग प्रक्रियात्मक प्रोग्रामिंग में सबरूटीन्स नामक सिस्टम कॉल लिए एंट्री पॉइंट्स के एड्रैस रखने के लिए और डायनामिक लिंक लाइब्रेरी # स्पष्ट रन-टाइम लिंकिंग | डायनेमिक लिंक लाइब्रेरीज़ (डीएलएल) से रन-टाइम लिंकिंग के लिए भी किया जाता है। ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में, फंक्शन पॉइंटर का उपयोग नाम बंधन विधि (कंप्यूटर प्रोग्रामिंग) के लिए किया जाता है, प्रायः आभासी विधि तालिका का उपयोग किया जाता है।
एक पॉइन्टर अधिक अमूर्त संदर्भ (कंप्यूटर विज्ञान) डेटा प्रकार का एक सरल, अधिक ठोस कार्यान्वयन है। कई भाषाएँ, विशेष रूप से निम्न-स्तरीय प्रोग्रामिंग भाषा|निम्न-स्तरीय भाषाएँ, कुछ प्रकार के पॉइन्टर का समर्थन करती हैं, हालाँकि कुछ में दूसरों की तुलना में उनके उपयोग पर अधिक प्रतिबंध हैं। जबकि पॉइन्टर का उपयोग सामान्य रूप से संदर्भों को संदर्भित करने के लिए किया गया है, यह डेटा संरचनाओं पर अधिक उचित रूप से लागू होता है जिसका अप्लिकेशन प्रोग्रामिंग अंतरफलक स्पष्ट रूप से पॉइन्टर को हेरफेर करने की स्वीकृति देता है (अंकगणित रूप से के माध्यम से)pointer arithmetic) एक मेमोरी एड्रैस के रूप में, जादू कुकी या क्षमता-आधारित सुरक्षा के विपरीत जो इसकी स्वीकृति नहीं देता है।[citation needed] क्योंकि पॉइंटर्स मेमोरी पतों तक सुरक्षित और असुरक्षित दोनों तरह की पहुंच की स्वीकृति देते हैं, इसलिए उनका उपयोग करने से जुड़े जोखिम हैं, खासकर बाद के स्थिति में। प्रिमिटिव पॉइंटर्स को प्रायः पूर्णांक के समान प्रारूप में संग्रहीत किया जाता है; हालाँकि, ऐसे पॉइन्टर को हटाने या देखने का प्रयास जिसका मान मान्य मेमोरी पता नहीं है, प्रोग्राम को क्रैश (कंप्यूटिंग) (या अमान्य डेटा सम्मिलित) कर सकता है। इस संभावित समस्या को कम करने के लिए, प्रकार की सुरक्षा के स्थिति में, पॉइंटर्स को एक अलग प्रकार माना जाता है, जिस प्रकार के डेटा को वे इंगित करते हैं, भले ही अंतर्निहित प्रतिनिधित्व एक पूर्णांक हो। अन्य उपाय भी किए जा सकते हैं (जैसे कि डेटा सत्यापन और सामंजस्य और सीमा जाँच), यह सत्यापित करने के लिए कि पॉइंटर चर में एक मान है जो एक वैध मेमोरी एड्रेस और संख्यात्मक सीमा के अंदर है जिसे प्रोसेसर संबोधित करने में सक्षम है।
इतिहास
1955 में, सोवियत कंप्यूटर वैज्ञानिक Kateryna Yushchenko (वैज्ञानिक) ने पता प्रोग्रामिंग भाषा का आविष्कार किया, जिसने अप्रत्यक्ष एड्रेसिंग और उच्चतम रैंक के एड्रेस को संभव बनाया - पॉइंटर्स के अनुरूप। सोवियत संघ के कंप्यूटरों पर इस भाषा का व्यापक रूप से उपयोग किया जाता था। हालाँकि, यह सोवियत संघ के बाहर अज्ञात था और सामान्य रूप से हेरोल्ड लॉसन को 1964 में पॉइन्टर के आविष्कार का श्रेय दिया जाता है।[2] 2000 में, लॉसन को IEEE [f] द्वारा कंप्यूटर पायनियर अवार्ड प्रदान किया गया था या पॉइंटर वेरिएबल का आविष्कार किया और इस अवधारणा को PL/I में पेश किया, इस प्रकार पहली बार एक सामान्य-उद्देश्य उच्च में लिंक्ड सूचियों को लचीले ढंग से व्यवहार करने की क्षमता प्रदान की। -स्तर की भाषा।[3] अवधारणाओं पर उनका सेमिनल पेपर CACM के जून 1967 के अंक में प्रकाशित हुआ जिसका शीर्षक था: PL/I लिस्ट प्रोसेसिंग। ऑक्सफोर्ड इंग्लिश डिक्शनरी के अनुसार, 'पॉइंटर' शब्द पहली बार प्रणाली विकास निगम द्वारा एक तकनीकी मेमोरेंडम में 'स्टैक पॉइंटर' के रूप में प्रिंट में दिखाई दिया।
औपचारिक विवरण
कंप्यूटर विज्ञान में, एक पॉइन्टर एक प्रकार का संदर्भ (कंप्यूटर विज्ञान) है।
एक डेटा प्रिमिटिव (या सिर्फ प्रिमिटिव) कोई भी डेटाम है जिसे एक मेमोरी एक्सेस (उदाहरण के लिए, एक बाइट और एक वर्ड (कंप्यूटर आर्किटेक्चर) दोनों प्रिमिटिव हैं) का उपयोग करके कंप्यूटर मेमोरी से पढ़ा या लिखा जा सकता है।
एक डेटा एग्रीगेट (या सिर्फ एग्रीगेट) प्रिमिटिव्स का एक समूह है जो मेमोरी में तार्किक पता सन्निहित है और जिसे सामूहिक रूप से एक डेटा के रूप में देखा जाता है (उदाहरण के लिए, एक एग्रीगेट 3 तार्किक रूप से सन्निहित बाइट्स हो सकता है, जिसके मान 3 निर्देशांक का प्रतिनिधित्व करते हैं अंतरिक्ष में एक बिंदु)। जब समुच्चय पूरी तरह से एक ही प्रकार के आदिम से बना होता है, तो समुच्चय को एक सरणी डेटा संरचना कहा जा सकता है; एक मायने में, एक बहु-बाइट शब्द आदिम बाइट्स की एक सरणी है, और कुछ प्रोग्राम इस तरह से शब्दों का उपयोग करते हैं।
इन परिभाषाओं के संदर्भ में, एक बाइट सबसे छोटा प्रिमिटिव है; प्रत्येक मेमोरी पता एक अलग बाइट निर्दिष्ट करता है। किसी डेटम के प्रारम्भिक बाइट का मेमोरी एड्रेस पूरे डेटाम का मेमोरी एड्रेस (या बेस मेमोरी एड्रेस) माना जाता है।
एक मेमोरी पॉइंटर (या सिर्फ पॉइंटर) एक प्रिमिटिव है, जिसका मान मेमोरी एड्रेस के रूप में उपयोग करने के लिए अभिप्रेत है; ऐसा कहा जाता है कि एक पॉइन्टर मेमोरी एड्रैस को इंगित करता है। यह भी कहा जाता है कि एक पॉइंटर डेटम [मेमोरी में] की ओर इशारा करता है जब पॉइंटर का मान डेटम का मेमोरी एड्रेस होता है।
अधिक सामान्य रूप से , एक पॉइन्टर एक प्रकार का संदर्भ (कंप्यूटर विज्ञान) है, और यह कहा जाता है कि एक पॉइन्टर मेमोरी में कहीं संग्रहीत डाटाम का संदर्भ देता है; उस डेटा को प्राप्त करने के लिए पॉइंटर को हटाना है। पॉइंटर्स को अन्य प्रकार के संदर्भों से अलग करने वाली विशेषता यह है कि एक पॉइंटर के मान को मेमोरी एड्रेस के रूप में व्याख्या किया जाना है, जो कि एक निम्न-स्तरीय अवधारणा है।
संदर्भ संकेत के स्तर के रूप में कार्य करते हैं: एक पॉइन्टर का मान निर्धारित करता है कि गणना में कौन सा मेमोरी पता (यानी, कौन सा डाटाम) उपयोग किया जाना है। क्योंकि अप्रत्यक्ष एल्गोरिदम का एक मूलभूत पहलू है, पॉइंटर्स को प्रायः प्रोग्रामिंग भाषाओं में एक मौलिक डेटा प्रकार के रूप में व्यक्त किया जाता है; स्टेटिक प्रकार (या मजबूत और कमजोर टाइपिंग) टाइप की गई प्रोग्रामिंग भाषाओं में, पॉइंटर का टाइप सिस्टम उस डेटा के प्रकार को निर्धारित करता है जिस पर पॉइंटर इंगित करता है।
स्थापत्य जड़
अधिकांश आधुनिक सॉफ़्टवेयर वास्तुशिल्प द्वारा प्रदान की जाने बाइट एड्रेसिंग क्षमताओं के शीर्ष पर पॉइंटर्स एक बहुत पतला अमूर्त (कंप्यूटर विज्ञान) हैं। सबसे सरल योजना में, एक मेमोरी एड्रेस, या एक न्यूमेरिक सरणी डेटा संरचना, सिस्टम में मेमोरी की प्रत्येक इकाई को सौंपा जाता है, जहाँ यूनिट सामान्य रूप से या तो एक बाइट या एक वर्ड (कंप्यूटर आर्किटेक्चर) होती है - यह इस बात पर निर्भर करता है कि आर्किटेक्चर बाइट है या नहीं। एड्रेसिंग | बाइट-एड्रेसेबल या शब्द-पता करने योग्य - प्रभावी रूप से सभी मेमोरी को एक बहुत बड़े एरे डेटा स्ट्रक्चर में बदल देता है। सिस्टम तब दिए गए एड्रैस पर मेमोरी यूनिट में संग्रहीत मान को पुनः प्राप्त करने के लिए एक ऑपरेशन भी प्रदान करेगा (सामान्य रूप से मशीन के सामान्य प्रयोजन रजिस्टरों का उपयोग)।
सामान्य स्थिति में, एक संकेतक इतना बड़ा होता है कि वह सिस्टम में मेमोरी की इकाइयों की तुलना में अधिक पतों को रखने के लिए पर्याप्त होता है। यह इस संभावना का परिचय देता है कि एक प्रोग्राम किसी ऐसे एड्रैस तक पहुंचने का प्रयास कर सकता है जो मेमोरी की कोई इकाई नहीं है, या तो पर्याप्त मेमोरी स्थापित नहीं है (यानी उपलब्ध मेमोरी की सीमा से परे) या आर्किटेक्चर ऐसे एड्रैस का समर्थन नहीं करता है। पहला स्थिति, कुछ प्लेटफॉर्म जैसे कि x86 आर्किटेक्चर में, विखंडन दोष (सेगफॉल्ट) कहा जा सकता है। x86-64 के वर्तमान कार्यान्वयन में दूसरा स्थिति संभव है, जहां संकेत 64 बिट लंबे हैं और एड्रैस केवल 48 बिट तक विस्तारित हैं। पॉइंटर्स को कुछ नियमों (कैनोनिकल एड्रेस) के अनुरूप होना चाहिए, इसलिए यदि एक गैर-कैनोनिकल पॉइंटर को डीरेफरेंस किया जाता है, तो प्रोसेसर एक सामान्य सुरक्षा दोष उठाता है।
दूसरी ओर, कुछ प्रणालियों में पतों की तुलना में मेमोरी की अधिक इकाइयाँ होती हैं। इस स्थिति में, एक अधिक जटिल योजना जैसे मेमोरी विभाजन या पेजिंग को अलग-अलग समय पर मेमोरी के विभिन्न भागों का उपयोग करने के लिए नियोजित किया जाता है। x86 आर्किटेक्चर के अंतिम अवतार भौतिक मेमोरी पतों के 36 बिट्स तक का समर्थन करते हैं, जिन्हें भौतिक पता एक्सटेंशन पेजिंग तंत्र के माध्यम से 32-बिट रैखिक पता स्थान पर मैप किया गया था। इस प्रकार, एक समय में संभावित कुल मेमोरी का केवल 1/16 ही एक्सेस किया जा सकता है। उसी कंप्यूटर परिवार में एक और उदाहरण इंटेल 80286 प्रोसेसर का 16-बिट संरक्षित मोड था, जो हालांकि केवल 16 एमबी भौतिक मेमोरी का समर्थन करता था, 1 जीबी तक वर्चुअल मेमोरी तक पहुंच सकता था, लेकिन 16-बिट एड्रेस का संयोजन और सेगमेंट रजिस्टरों ने एक डेटा संरचना में 64 KB से अधिक एक्सेस करना बोझिल बना दिया है।
एक सुसंगत इंटरफ़ेस प्रदान करने के लिए, कुछ आर्किटेक्चर मेमोरी-मैप्ड I/O प्रदान करते हैं, जो कुछ पतों को मेमोरी की इकाइयों को संदर्भित करने की स्वीकृति देता है जबकि अन्य कंप्यूटर में अन्य उपकरणों के डिवाइस रजिस्टरों को संदर्भित करते हैं। फाइल ऑफ़सेट्स, एरे इंडेक्स और रिमोट ऑब्जेक्ट रेफरेंस जैसी समान अवधारणाएँ हैं जो अन्य प्रकार की वस्तुओं के लिए एड्रैस के समान उद्देश्यों को पूरा करती हैं।
उपयोग करता है
पीएल/आई, सी (प्रोग्रामिंग भाषा), सी ++, पास्कल प्रोग्रामिंग भाषा, फ्रीबेसिक जैसी भाषाओं में प्रतिबंधों के बिना पॉइंटर्स का सीधे समर्थन किया जाता है, और अधिकांश विधानसभा भाषाओं में निहित रूप से। वे मुख्य रूप से संदर्भ (कंप्यूटर विज्ञान) के निर्माण के लिए उपयोग किए जाते हैं, जो बदले में लगभग सभी डेटा संरचनाओं के निर्माण के साथ-साथ एक प्रोग्राम के विभिन्न भागों के बीच डेटा पास करने के लिए मौलिक हैं।
कार्यात्मक प्रोग्रामिंग भाषाओं में जो सूचियों पर बहुत अधिक निर्भर करती हैं, डेटा संदर्भों को दोष और संबंधित तत्वों कार और सीडीआर जैसे आदिम निर्माणों का उपयोग करके अमूर्त रूप से प्रबंधित किया जाता है, जिसे कॉन्स-सेल के पहले और दूसरे घटकों के लिए विशेष संकेतक के रूप में माना जा सकता है। यह कार्यात्मक प्रोग्रामिंग के कुछ मुहावरेदार स्वाद को जन्म देता है। ऐसी लिंक की गई सूची में डेटा को संरचित करके। कंस-सूचियां, ये भाषाएं डेटा के निर्माण और प्रसंस्करण के लिए पुनरावर्तन (कंप्यूटर विज्ञान) की सुविधा प्रदान करती हैं - उदाहरण के लिए, सूचियों की सूचियों के सिर और पूंछ तत्वों तक पुनरावर्ती रूप से पहुंचकर; उदा. सीडीआर के सीडीआर की कार ले रहे हैं। इसके विपरीत, मेमोरी पतों की एक सरणी डेटा संरचना के कुछ सन्निकटन में पॉइंटर डेरेफ़रिंग पर आधारित मेमोरी प्रबंधन चर को स्लॉट के रूप में मानने की सुविधा देता है जिसमें डेटा को अनिवार्य प्रोग्रामिंग असाइन किया जा सकता है।
सरणियों के साथ काम करते समय, महत्वपूर्ण लुकअप टेबल ऑपरेशन में सामान्य रूप से पता गणना नामक एक चरण सम्मिलित होता है जिसमें सरणी में वांछित डेटा तत्व के लिए एक पॉइन्टर का निर्माण सम्मिलित होता है। अन्य डेटा संरचनाओं में, जैसे कि लिंक की गई सूचियाँ, पॉइंटर्स को संरचना के एक टुकड़े को दूसरे से स्पष्ट रूप से बाँधने के लिए संदर्भ के रूप में उपयोग किया जाता है।
पॉइंटर्स का उपयोग संदर्भ द्वारा पैरामीटर पास करने के लिए किया जाता है। यह उपयोगी है अगर प्रोग्रामर चाहता है कि फ़ंक्शन के कॉलर को फ़ंक्शन के पैरामीटर में संशोधन दिखाई दे। यह किसी फ़ंक्शन से एकाधिक मान वापस करने के लिए भी उपयोगी है।
मेमोरी आवंटन के लिए पॉइंटर्स का भी उपयोग किया जा सकता है और मेमोरी में डायनेमिक वेरिएबल्स और एरेज़ को डिलीकेट किया जा सकता है। चूंकि एक चर अपने उद्देश्य को पूरा करने के बाद प्रायः बेमानी हो जाएगा, इसे रखने के लिए मेमोरी की बर्बादी होती है, और इसलिए यह आवश्यक नहीं होने पर (मूल पॉइन्टर संदर्भ का उपयोग करके) इसे हटाने के लिए अच्छा अभ्यास है। ऐसा करने में विफलता के परिणामस्वरूप मेमोरी रिसाव हो सकता है (जहां मुक्त मेमोरी धीरे-धीरे उपलब्ध होती है, या गंभीर स्थितियो में तेजी से, कई अनावश्यक मेमोरी ब्लॉकों के संचय के कारण कम हो जाती है)।
सी पॉइंटर्स
पॉइंटर को परिभाषित करने के लिए मूल सिंटेक्स (प्रोग्रामिंग भाषाएं) है:[4]
int *ptr;
यह घोषित करता है ptr
निम्न प्रकार की वस्तु के पहचानकर्ता के रूप में:
- पॉइन्टर जो प्रकार की वस्तु को इंगित करता है
int
यह सामान्य रूप से अधिक संक्षेप में कहा जाता हैptr
का पॉइन्टर है int
.
चूंकि सी भाषा स्वत: भंडारण अवधि की वस्तुओं के लिए एक अंतर्निहित प्रारंभिकरण निर्दिष्ट नहीं करती है,[5] यह सुनिश्चित करने के लिए प्रायः ध्यान रखा जाना चाहिए कि पता किसका है ptr
अंक मान्य है; यही कारण है कि कभी-कभी यह सुझाव दिया जाता है कि एक पॉइन्टर को शून्य पॉइन्टर मान के लिए स्पष्ट रूप से प्रारंभ किया जाना चाहिए, जो परंपरागत रूप से मानकीकृत मैक्रो के साथ सी में निर्दिष्ट है NULL
:[6]
int *ptr = NULL;
C में एक अशक्त पॉइन्टर को संदर्भित करना अपरिभाषित व्यवहार उत्पन्न करता है,[7] जो विनाशकारी हो सकता है। हालाँकि, अधिकांश कार्यान्वयन[citation needed] सामान्य रूप से सेगमेंटेशन गलती के साथ, प्रश्न में प्रोग्राम के निष्पादन को रोकें।
हालाँकि, पॉइंटर्स को आरंभ करना अनावश्यक रूप से प्रोग्राम विश्लेषण में बाधा डाल सकता है, जिससे बग छिप जाते हैं।
किसी भी स्थिति में, एक बार पॉइन्टर घोषित होने के बाद, अगला तार्किक कदम इसके लिए कुछ इंगित करना है:
int a = 5; int *ptr = NULL; ptr = &a;
यह के एड्रैस का मान निर्दिष्ट करता है a
को ptr
. उदाहरण के लिए, अगर a
0x8130 के मेमोरी स्थान पर संग्रहीत किया जाता है, फिर का मान ptr
असाइनमेंट के बाद 0x8130 होगा। पॉइंटर को डिरेफेरेंस करने के लिए, एक तारांकन चिह्न का फिर से उपयोग किया जाता है:
*ptr = 8;
इसका मतलब है की सामग्री लें ptr
(जो 0x8130 है), उस एड्रैस को मेमोरी में ढूंढें और उसका मान 8 पर सेट करें।
अगर a
बाद में फिर से एक्सेस किया जाता है, इसका नया मान 8 होगा।
यदि मेमोरी की सीधे जाँच की जाए तो यह उदाहरण अधिक स्पष्ट हो सकता है।
ये मान लीजिए a
मेमोरी में पता 0x8130 पर स्थित है और ptr
0x8134 पर; यह भी मान लें कि यह 32-बिट मशीन है जैसे कि int 32-बिट चौड़ा है। निम्नलिखित कोड स्निपेट निष्पादित होने के बाद मेमोरी में क्या होगा:
int a = 5; int *ptr = NULL;
Address Contents 0x8130 0x00000005 0x8134 0x00000000
(यहां दिखाया गया पूर्ण पॉइन्टर 0x00000000 है।)
का पता बता कर a
को ptr
:
ptr = &a;
</वाक्यविन्यास हाइलाइट>
निम्नलिखित मेमोरी मान उत्पन्न करता है:
Address Contents 0x8130 0x00000005 0x8134 0x00008130
फिर dereferencing द्वारा ptr
कोडिंग द्वारा:
<वाक्यविन्यास लैंग = सी>
*पीआरटी = 8;
</वाक्यविन्यास हाइलाइट>
कंप्यूटर की सामग्री ले जाएगा ptr
(जो 0x8130 है), उस एड्रैस को 'ढूंढें', और उस स्थान पर 8 असाइन करें जो निम्नलिखित मेमोरी प्रदान करता है:
Address Contents 0x8130 0x00000008 0x8134 0x00008130
स्पष्ट रूप से, पहुँचना a
8 का मान देगा क्योंकि पिछले निर्देश ने सामग्री को संशोधित किया था a
पॉइन्टर के माध्यम से ptr
.
डेटा संरचनाओं में प्रयोग
सूची (कंप्यूटिंग), कतार (अमूर्त डेटा प्रकार) और पेड़ जैसी डेटा संरचनाएं स्थापित करते समय, संरचना को कार्यान्वित और नियंत्रित करने के तरीके को प्रबंधित करने में सहायता के लिए पॉइंटर्स होना आवश्यक है। पॉइंटर्स के विशिष्ट उदाहरण स्टार्ट पॉइंटर्स, एंड पॉइंटर्स और स्टैक (अमूर्त डेटा प्रकार) पॉइंटर्स हैं। ये संकेतक या तो निरपेक्ष हो सकते हैं (वास्तविक भौतिक पता या आभासी मेमोरी में एक आभासी पता) या सापेक्ष (एक ऑफ़सेट (कंप्यूटर विज्ञान) एक पूर्ण प्रारंभ पता (आधार) से जो सामान्य रूप से पूर्ण एड्रैस की तुलना में कम बिट्स का उपयोग करता है, लेकिन सामान्य रूप से इसकी आवश्यकता होगी हल करने के लिए एक अतिरिक्त अंकगणितीय ऑपरेशन)।
सापेक्ष एड्रैस आभासी मेमोरी सेगमेंटेशन का एक रूप हैं, और इसके कई फायदे और नुकसान साझा करते हैं। एक दो-बाइट ऑफ़सेट, जिसमें एक 16-बिट, अहस्ताक्षरित पूर्णांक होता है, का उपयोग 64 kibibytes तक सापेक्ष पता प्रदान करने के लिए किया जा सकता है (216 बाइट्स) एक डेटा संरचना की। इसे आसानी से 128, 256 या 512 KiB तक बढ़ाया जा सकता है यदि इंगित किए गए एड्रैस को आधे-शब्द, शब्द या दोहरे-शब्द सीमा पर डेटा संरचना संरेखण के लिए मजबूर किया जाता है (लेकिन, एक अतिरिक्त शिफ्ट बाएं बिटवाइज़ ऑपरेशन की आवश्यकता होती है - 1 तक, 2 या 3 बिट्स - ऑफसेट को 2, 4 या 8 के एक कारक द्वारा समायोजित करने के लिए, इसके अलावा आधार एड्रैस से पहले)। सामान्य रूप से , हालांकि, ऐसी योजनाएं बहुत परेशानी होती हैं, और प्रोग्रामर की सुविधा के लिए पूर्ण एड्रैस (और अंतर्निहित, एक फ्लैट पता स्थान) को प्राथमिकता दी जाती है।
एक बाइट ऑफ़सेट, जैसे किसी वर्ण का हेक्साडेसिमल ASCII मान (उदा. X'29') का उपयोग किसी सरणी में वैकल्पिक पूर्णांक मान (या अनुक्रमणिका) को इंगित करने के लिए किया जा सकता है (उदा., X'01'). इस तरह, वर्णों को 'कच्चे डेटा' से प्रयोग करने योग्य अनुक्रमिक सरणी डेटा संरचना में और फिर लुकअप टेबल के बिना एक पूर्ण एड्रैस पर बहुत कुशलता से अनुवादित किया जा सकता है।
सी सरणियाँ =
सी में, पॉइन्टर अंकगणितीय के संदर्भ में सरणी अनुक्रमण औपचारिक रूप से परिभाषित किया गया है; अर्थात्, भाषा विनिर्देश के लिए इसकी आवश्यकता होती है array[i]
के बराबर हो *(array + i)
.[8] इस प्रकार सी में, सरणियों को मेमोरी के लगातार क्षेत्रों के संकेत के रूप में माना जा सकता है (बिना अंतराल के),[8]और सरणियों तक पहुँचने के लिए सिंटैक्स उसके लिए समान है जिसका उपयोग पॉइंटर्स को हटाने के लिए किया जा सकता है। उदाहरण के लिए, एक सरणी array
निम्नलिखित तरीके से घोषित और उपयोग किया जा सकता है:
int array[5]; /* Declares 5 contiguous integers */ int *ptr = array; /* Arrays can be used as pointers */ ptr[0] = 1; /* Pointers can be indexed with array syntax */ *(array + 1) = 2; /* Arrays can be dereferenced with pointer syntax */ *(1 + array) = 2; /* Pointer addition is commutative */ 2[array] = 4; /* Subscript operator is commutative */
यह पाँच पूर्णांकों का एक ब्लॉक आवंटित करता है और ब्लॉक को नाम देता है array
, जो ब्लॉक के लिए एक संकेतक के रूप में कार्य करता है। पॉइंटर्स का एक अन्य सामान्य उपयोग malloc से गतिशील रूप से आवंटित मेमोरी को इंगित करना है जो अनुरोधित आकार से कम की मेमोरी का लगातार ब्लॉक देता है जिसे एक सरणी के रूप में उपयोग किया जा सकता है।
जबकि सरणियों और पॉइंटर्स पर अधिकांश ऑपरेटर समतुल्य हैं, का परिणाम sizeof
ऑपरेटर अलग है। इस उदाहरण में, sizeof(array)
का मूल्यांकन करेगा 5*sizeof(int)
(सरणी का आकार), जबकि sizeof(ptr)
का मूल्यांकन करेगा sizeof(int*)
, पॉइंटर का आकार।
किसी सरणी के डिफ़ॉल्ट मानों को इस प्रकार घोषित किया जा सकता है:
int array[5] = {2, 4, 3, 1, 5};
अगर array
32-बिट Endianness#Little-endian|little-endian मशीन पर पता 0x1000 से प्रारंभ होने वाली मेमोरी में स्थित है, तो मेमोरी में निम्न सम्मिलित होंगे (मान हेक्साडेसिमल में हैं, जैसे एड्रैस):
0 1 2 3 1000 2 0 0 0 1004 4 0 0 0 1008 3 0 0 0 100C 1 0 0 0 1010 5 0 0 0
यहाँ प्रस्तुत पाँच पूर्णांक हैं: 2, 4, 3, 1, और 5। ये पाँच पूर्णांक 32 बिट्स (4 बाइट्स) पर कब्जा कर लेते हैं, जिनमें से प्रत्येक सबसे कम-महत्वपूर्ण बाइट पहले संग्रहीत होता है (यह एक छोटा-एंडियन सीपीयू आर्किटेक्चर है) और लगातार संग्रहीत किया जाता है पता 0x1000 से प्रारंभ।
पॉइंटर्स के साथ C का सिंटैक्स है:
array
मतलब 0x1000;array + 1
मतलब 0x1004: + 1 का मतलब 1 का आकार जोड़ना हैint
, जो 4 बाइट है;*array
की सामग्री को डीरेफरेंस करने का मतलब हैarray
. मेमोरी पता (0x1000) के रूप में सामग्री को ध्यान में रखते हुए, उस स्थान पर मान देखें (0x0002);array[i]
मतलब तत्व संख्याi
, 0-आधारित, काarray
जिसका अनुवाद किया गया है*(array + i)
.
अंतिम उदाहरण यह है कि की सामग्री का उपयोग कैसे किया जाए array
. इसे तोड़ना:
array + i
(i) की मेमोरी लोकेशन हैवें का तत्वarray
, i=0 से प्रारंभ;*(array + i)
उस मेमोरी एड्रेस को लेता है और वैल्यू को एक्सेस करने के लिए इसे डीरेफर करता है।
सी लिंक की गई सूची ==
नीचे C में लिंक की गई सूची की एक उदाहरण परिभाषा दी गई है।
/* the empty linked list is represented by NULL * or some other sentinel value */ #define EMPTY_LIST NULL struct link { void *data; /* data of this link */ struct link *next; /* next link; EMPTY_LIST if there is none */ };
यह पॉइन्टर-पुनरावर्ती परिभाषा अनिवार्य रूप से हास्केल (प्रोग्रामिंग भाषा) से संदर्भ-पुनरावर्ती परिभाषा के समान है:
data Link a = Nil | Cons a (Link a)
Nil
खाली सूची है, और Cons a (Link a)
विपक्ष प्रकार का सेल है a
दूसरे लिंक के साथ भी प्रकार का a
.
हालाँकि, संदर्भों के साथ परिभाषा टाइप-चेक की गई है और संभावित रूप से भ्रमित करने वाले सिग्नल मानों का उपयोग नहीं करती है। इस कारण से, C में डेटा संरचनाओं को सामान्य रूप से आवरण समारोह के माध्यम से निपटाया जाता है, जिन्हें शुद्धता के लिए सावधानीपूर्वक जाँचा जाता है।
===पास-दर-पता संकेत === का उपयोग कर
पॉइंटर्स का उपयोग वेरिएबल्स को उनके एड्रैस से पास करने के लिए किया जा सकता है, जिससे उनका मान बदला जा सकता है। उदाहरण के लिए, निम्नलिखित सी (प्रोग्रामिंग भाषा) कोड पर विचार करें:
/* a copy of the int n can be changed within the function without affecting the calling code */ void passByValue(int n) { n = 12; } /* a pointer m is passed instead. No copy of the value pointed to by m is created */ void passByAddress(int *m) { *m = 14; } int main(void) { int x = 3; /* pass a copy of x's value as the argument */ passByValue(x); // the value was changed inside the function, but x is still 3 from here on /* pass x's address as the argument */ passByAddress(&x); // x was actually changed by the function and is now equal to 14 here return 0; }
गतिशील मेमोरी आवंटन
कुछ कार्यक्रमों में, आवश्यक मात्रा में मेमोरी इस बात पर निर्भर करती है कि उपयोगकर्ता क्या दर्ज कर सकता है। ऐसे स्थितियो में प्रोग्रामर को डायनेमिक रूप से मेमोरी आवंटित करने की आवश्यकता होती है। यह स्टैक के बजाय हीप पर मेमोरी आवंटित करके किया जाता है, जहां चर सामान्य रूप से संग्रहीत होते हैं (वेरिएबल्स को सीपीयू रजिस्टरों में भी संग्रहीत किया जा सकता है, लेकिन यह एक और स्थिति है)। डायनेमिक मेमोरी आवंटन केवल पॉइंटर्स के माध्यम से किया जा सकता है, और नाम (जैसे सामान्य चर के साथ) नहीं दिए जा सकते।
पॉइंटर्स का उपयोग मेमोरी के डायनेमिक मेमोरी एलोकेशन ब्लॉक्स के एड्रेस को स्टोर और मैनेज करने के लिए किया जाता है। इस तरह के ब्लॉक का उपयोग डेटा ऑब्जेक्ट्स या ऑब्जेक्ट्स के एरे को स्टोर करने के लिए किया जाता है। अधिकांश संरचित और ऑब्जेक्ट-ओरिएंटेड भाषा मेमोरी का एक क्षेत्र प्रदान करती हैं, जिसे हीप या फ्री स्टोर कहा जाता है, जिससे ऑब्जेक्ट्स को डायनेमिक रूप से आवंटित किया जाता है।
नीचे दिया गया उदाहरण C कोड दिखाता है कि कैसे संरचना वस्तुओं को गतिशील रूप से आवंटित और संदर्भित किया जाता है। मानक सी लाइब्रेरी फ़ंक्शन मॉलोक प्रदान करती हैmalloc()
ढेर से मेमोरी ब्लॉक आवंटित करने के लिए। यह एक पैरामीटर के रूप में आवंटित करने के लिए एक वस्तु का आकार लेता है और ऑब्जेक्ट को संग्रहीत करने के लिए उपयुक्त मेमोरी के एक नए आवंटित ब्लॉक के लिए एक पॉइन्टर लौटाता है, या आवंटन विफल होने पर यह एक अशक्त पॉइन्टर लौटाता है।
/* Parts inventory item */ struct Item { int id; /* Part number */ char * name; /* Part name */ float cost; /* Cost */ }; /* Allocate and initialize a new Item object */ struct Item * make_item(const char *name) { struct Item * item; /* Allocate a block of memory for a new Item object */ item = malloc(sizeof(struct Item)); if (item == NULL) return NULL; /* Initialize the members of the new Item */ memset(item, 0, sizeof(struct Item)); item->id = -1; item->name = NULL; item->cost = 0.0; /* Save a copy of the name in the new Item */ item->name = malloc(strlen(name) + 1); if (item->name == NULL) { free(item); return NULL; } strcpy(item->name, name); /* Return the newly created Item object */ return item; }
नीचे दिया गया कोड बताता है कि मेमोरी ऑब्जेक्ट्स को गतिशील रूप से कैसे हटाया जाता है, यानी ढेर या मुफ्त स्टोर में लौटाया जाता है। मानक सी लाइब्रेरी मुफ्त () | फ़ंक्शन प्रदान करती हैfree()
पहले आवंटित मेमोरी ब्लॉक को हटाने और इसे वापस ढेर पर वापस करने के लिए।
/* Deallocate an Item object */ void destroy_item(struct Item *item) { /* Check for a null object pointer */ if (item == NULL) return; /* Deallocate the name string saved within the Item */ if (item->name != NULL) { free(item->name); item->name = NULL; } /* Deallocate the Item object itself */ free(item); }
मेमोरी-मैप्ड हार्डवेयर
कुछ कंप्यूटिंग आर्किटेक्चर पर, पॉइंटर्स का उपयोग सीधे मेमोरी या मेमोरी-मैप्ड डिवाइसेस में हेरफेर करने के लिए किया जा सकता है।
microcontroller्स की प्रोग्रामिंग करते समय पॉइंटर्स को एड्रेस असाइन करना एक अमूल्य उपकरण है। नीचे एक सरल उदाहरण है जो एक प्रकार के int के पॉइन्टर को घोषित करता है और इसे हेक्साडेसिमल एड्रैस पर प्रारंभ करता है, इस उदाहरण में निरंतर 0x7FFF:
int *hardware_address = (int *)0x7FFF;
80 के दशक के मध्य में, पीसी की वीडियो क्षमताओं तक पहुँचने के लिए BIOS का उपयोग धीमा था। प्रदर्शन-गहन अनुप्रयोग सामान्य रूप से हेक्साडेसिमल स्थिरांक 0xB8000 को 80 अहस्ताक्षरित 16-बिट int मानों की एक सरणी के लिए पॉइंटर में कास्ट करके सीधे रंग ग्राफिक्स एडेप्टर वीडियो मेमोरी तक पहुंचने के लिए उपयोग किया जाता है। प्रत्येक मान में निम्न बाइट में एक ASCII कोड और उच्च बाइट में एक रंग सम्मिलित होता है। इस प्रकार, अक्षर 'A' को पंक्ति 5 में, कॉलम 2 को नीले रंग पर चमकीले सफेद रंग में रखने के लिए, निम्नलिखित कोड की तरह लिखा जाएगा:
#define VID ((unsigned short (*)[80])0xB8000) void foo(void) { VID[4][1] = 0x1F00 | 'A'; }
नियंत्रण तालिकाओं में प्रयोग करें
प्रोग्राम प्रवाह को नियंत्रित करने के लिए उपयोग की जाने वाली नियंत्रण तालिकाएं सामान्य रूप से पॉइंटर्स का व्यापक उपयोग करती हैं। पॉइंटर्स, सामान्य रूप से टेबल एंट्री में एम्बेडेड होते हैं, उदाहरण के लिए, उसी टेबल एंट्री में परिभाषित कुछ शर्तों के आधार पर सबरूटीन्स को एंट्री पॉइंट्स को निष्पादित करने के लिए उपयोग किया जा सकता है। हालाँकि पॉइंटर्स केवल अन्य अलग-अलग, लेकिन संबंधित तालिकाओं के लिए अनुक्रमित हो सकते हैं, जिसमें वास्तविक पतों की एक सरणी होती है या खुद एड्रैस होते हैं (प्रोग्रामिंग भाषा के उपलब्ध निर्माण के आधार पर)। उनका उपयोग पहले की तालिका प्रविष्टियों (लूप प्रोसेसिंग में) को इंगित करने के लिए या कुछ तालिका प्रविष्टियों को छोड़ने के लिए आगे बढ़ने के लिए भी किया जा सकता है (जैसे कि स्विच स्टेटमेंट में या लूप से जल्दी बाहर निकलना)। इस बाद के उद्देश्य के लिए, पॉइन्टर केवल तालिका प्रविष्टि संख्या ही हो सकता है और साधारण अंकगणितीय द्वारा वास्तविक एड्रैस में परिवर्तित किया जा सकता है।
टाइप किए गए पॉइंटर्स और कास्टिंग
कई भाषाओं में, पॉइंटर्स के पास अतिरिक्त प्रतिबंध होता है कि वे जिस ऑब्जेक्ट को इंगित करते हैं उसका एक विशिष्ट डेटा प्रकार होता है। उदाहरण के लिए, एक पूर्णांक को इंगित करने के लिए एक पॉइन्टर घोषित किया जा सकता है; भाषा तब प्रोग्रामर को उन वस्तुओं की ओर इशारा करने से रोकने का प्रयास करेगी जो पूर्णांक नहीं हैं, जैसे चल बिन्दु संख्या, कुछ त्रुटियों को समाप्त करना।
उदाहरण के लिए, सी में
int *money; char *bags;
money
एक पूर्णांक पॉइन्टर होगा और bags
एक चार पॉइन्टर होगा।
निम्नलिखित जीएनयू कंपाइलर संग्रह के तहत असंगत पॉइन्टर प्रकार से असाइनमेंट की एक कंपाइलर चेतावनी उत्पन्न करेगा
bags = money;
क्योंकि money
और bags
विभिन्न प्रकारों के साथ घोषित किए गए थे।
कंपाइलर चेतावनी को दबाने के लिए, यह स्पष्ट किया जाना चाहिए कि आप वास्तव में टाइप रूपांतरण द्वारा असाइनमेंट करना चाहते हैं
bags = (char *)money;
जो पूर्णांक पॉइन्टर को कास्ट करने के लिए कहता है money
एक चार पॉइन्टर को और असाइन करें bags
.
सी मानक के 2005 के एक मसौदे के लिए आवश्यक है कि एक प्रकार से दूसरे प्रकार से प्राप्त पॉइन्टर को कास्टिंग करने से दोनों प्रकारों के लिए संरेखण शुद्धता बनाए रखनी चाहिए (6.3.2.3 पॉइंटर्स, पैरा। 7):[9] <वाक्यविन्यास लैंग =
char *external_buffer = "abcdef"; int *internal_data; internal_data = (int *)external_buffer; // UNDEFINED BEHAVIOUR if "the resulting pointer // is not correctly aligned"
उन भाषाओं में जो पॉइंटर अंकगणित की स्वीकृति देती हैं, पॉइंटर्स पर अंकगणित प्रकार के आकार को ध्यान में रखता है। उदाहरण के लिए, एक पॉइंटर में एक पूर्णांक संख्या जोड़ने से एक और पॉइंटर उत्पन्न होता है जो उस एड्रैस की ओर इशारा करता है जो उस संख्या के प्रकार के आकार से अधिक होता है। यह हमें किसी दिए गए प्रकार की सरणी के तत्वों के एड्रैस की आसानी से गणना करने की स्वीकृति देता है, जैसा ऊपर सी सरणी उदाहरण में दिखाया गया था। जब एक प्रकार के पॉइंटर को दूसरे प्रकार के भिन्न आकार में डाला जाता है, तो प्रोग्रामर को यह उम्मीद करनी चाहिए कि पॉइंटर अंकगणित की अलग-अलग गणना की जाएगी। सी में, उदाहरण के लिए, यदि money
सरणी 0x2000 से प्रारंभ होती है और sizeof(int)
4 बाइट है जबकि sizeof(char)
1 बाइट है, तो money + 1
0x2004 को इंगित करेगा, लेकिन bags + 1
0x2001 को इंगित करेगा। कास्टिंग के अन्य जोखिमों में डेटा की हानि सम्मिलित है जब विस्तृत डेटा संकीर्ण स्थानों पर लिखा जाता है (उदा। bags[0] = 65537;
), अनपेक्षित परिणाम जब बिट शिफ्ट | बिट-शिफ्टिंग मान, और तुलना समस्याएं, विशेष रूप से हस्ताक्षरित बनाम अहस्ताक्षरित मूल्यों के साथ।
हालांकि संकलन-समय पर सामान्य रूप से यह निर्धारित करना असंभव है कि कौन सी कास्ट सुरक्षित है, कुछ भाषाएँ रन-टाइम प्रकार की जानकारी संग्रहीत करती हैं जिनका उपयोग यह पुष्टि करने के लिए किया जा सकता है कि ये खतरनाक कास्ट रनटाइम पर मान्य हैं। अन्य भाषाएँ केवल सुरक्षित जातियों के एक रूढ़िवादी सन्निकटन को स्वीकार करती हैं, या कोई भी नहीं।
पॉइंटर्स का मूल्य
सी और सी ++ में, भले ही दो पॉइंटर्स बराबर के रूप में तुलना करें, इसका मतलब यह नहीं है कि वे समकक्ष हैं। इन भाषाओं और एलएलवीएम में, नियम की व्याख्या इस अर्थ में की जाती है कि सिर्फ इसलिए कि दो पॉइंटर्स एक ही एड्रैस की ओर इशारा करते हैं, इसका मतलब यह नहीं है कि वे इस अर्थ में समान हैं कि उन्हें एक दूसरे के स्थान पर उपयोग किया जा सकता है, पॉइंटर्स के बीच के अंतर को उनके उद्गम के रूप में संदर्भित किया जाता है।[10] एक पूर्णांक प्रकार जैसे कि कास्टिंग करना uintptr_t
कार्यान्वयन-परिभाषित है और यह जो तुलना प्रदान करता है वह इस बारे में अधिक जानकारी प्रदान नहीं करता है कि क्या दो पॉइंटर्स विनिमेय हैं। इसके अलावा, बाइट्स और अंकगणित में आगे रूपांतरण पॉइंटर्स के उपयोग को ट्रैक करने की कोशिश कर रहे ऑप्टिमाइज़र को फेंक देगा, एक समस्या अभी भी अकादमिक शोध में स्पष्ट है।[11]
पॉइंटर्स को सुरक्षित बनाना
एक पॉइन्टर के रूप में एक प्रोग्राम को एक ऐसी वस्तु तक पहुँचने का प्रयास करने की स्वीकृति देता है जिसे परिभाषित नहीं किया जा सकता है, संकेत विभिन्न प्रकार के सॉफ्टवेयर बग की उत्पत्ति हो सकते हैं। हालाँकि, पॉइंटर्स की उपयोगिता इतनी अधिक है कि उनके बिना प्रोग्रामिंग कार्यों को करना मुश्किल हो सकता है। नतीजतन, कई भाषाओं ने अपने कुछ एंटी-पैटर्न के बिना पॉइंटर्स की कुछ उपयोगी विशेषताओं को प्रदान करने के लिए डिज़ाइन किए गए निर्माणों का निर्माण किया है, जिन्हें कभी-कभी पॉइंटर खतरों के रूप में भी जाना जाता है। इस संदर्भ में, पॉइंटर्स जो सीधे मेमोरी को संबोधित करते हैं (जैसा कि इस आलेख में उपयोग किया गया है) को 'के रूप में संदर्भित किया जाता है।raw pointers, स्मार्ट सूचक्स या अन्य वेरिएंट के विपरीत।
पॉइंटर्स के साथ एक बड़ी समस्या यह है कि जब तक उन्हें सीधे एक संख्या के रूप में हेरफेर किया जा सकता है, तब तक उन्हें अप्रयुक्त पतों या अन्य उद्देश्यों के लिए उपयोग किए जा रहे डेटा को इंगित करने के लिए बनाया जा सकता है। अधिकांश कार्यात्मक प्रोग्रामिंग भाषाओं और जावा (प्रोग्रामिंग भाषा) जैसी हालिया अनिवार्य भाषाओं सहित कई भाषाएं, पॉइंटर्स को एक अधिक अपारदर्शी प्रकार के संदर्भ से प्रतिस्थापित करती हैं, जिसे सामान्य रूप से केवल 'संदर्भ' के रूप में संदर्भित किया जाता है, जिसका उपयोग केवल वस्तुओं को संदर्भित करने के लिए किया जा सकता है। और इस प्रकार की त्रुटि को रोकने के लिए संख्या के रूप में हेरफेर नहीं किया गया। ऐरे इंडेक्सिंग को एक विशेष स्थिति के रूप में संभाला जाता है।
एक पॉइंटर जिसका कोई पता नहीं होता है, उसे जंगली पॉइन्टर कहा जाता है। इस तरह के गैर-प्रारंभिकृत पॉइंटर्स का उपयोग करने का कोई भी प्रयास अप्रत्याशित व्यवहार का कारण बन सकता है, या तो प्रारंभिक मान एक वैध पता नहीं है, या इसका उपयोग करने से प्रोग्राम के अन्य भागों को नुकसान हो सकता है। नतीजा प्रायः एक सेगमेंटेशन गलती, भंडारण उल्लंघन या जंगली शाखा होती है (यदि फ़ंक्शन पॉइंटर या शाखा पता के रूप में उपयोग किया जाता है)।
स्पष्ट मेमोरी आवंटन वाले सिस्टम में, उस मेमोरी क्षेत्र को हटाकर एक झूलने वाला पॉइन्टर बनाना संभव है जो इसे इंगित करता है। इस प्रकार का संकेतक खतरनाक और सूक्ष्म है क्योंकि एक हटाए गए मेमोरी क्षेत्र में वही डेटा हो सकता है जैसा कि इसे हटाए जाने से पहले किया गया था, लेकिन फिर इसे असंबंधित कोड द्वारा पुनः आवंटित और अधिलेखित किया जा सकता है, जो पहले के कोड के लिए अज्ञात था। कचरा संग्रह (कंप्यूटर विज्ञान) वाली भाषाएं इस प्रकार की त्रुटि को रोकती हैं क्योंकि दायरे में कोई और संदर्भ नहीं होने पर डीलोकेशन स्वचालित रूप से किया जाता है।
कुछ भाषाएँ, जैसे C++, स्मार्ट पॉइंटर्स का समर्थन करती हैं, जो एक संदर्भ के रूप में कार्य करने के अलावा डायनेमिक मेमोरी के आवंटन को ट्रैक करने में मदद करने के लिए संदर्भ गणना के एक सरल रूप का उपयोग करती हैं। संदर्भ चक्रों की अनुपस्थिति में, जहां कोई वस्तु अप्रत्यक्ष रूप से स्मार्ट पॉइंटर्स के अनुक्रम के माध्यम से खुद को संदर्भित करती है, ये लटकने वाले पॉइंटर्स और मेमोरी लीक की संभावना को समाप्त करते हैं। डेल्फी (प्रोग्रामिंग भाषा) तार मूल रूप से संदर्भ गणना का समर्थन करते हैं।
जंग प्रोग्रामिंग भाषा एक 'बॉरो चेकर', 'पॉइंटर लाइफटाइम', और कूड़ा संग्रह (कंप्यूटर साइंस) का सहारा लिए बिना पॉइंटर बग्स को खत्म करने के लिए नल पॉइंटर्स के लिए वैकल्पिक प्रकारों के आधार पर एक अनुकूलन पेश करती है।
विशेष प्रकार के संकेत
मूल्य द्वारा परिभाषित प्रकार
अशक्त पॉइन्टर
एक अशक्त पॉइन्टर का एक मान आरक्षित होता है जो इंगित करता है कि पॉइन्टर एक वैध वस्तु का संदर्भ नहीं देता है। अशक्त संकेतक नियमित रूप से अज्ञात लंबाई की सूची (कंप्यूटिंग) के अंत या कुछ कार्रवाई करने में विफलता जैसी स्थितियों का प्रतिनिधित्व करने के लिए उपयोग किए जाते हैं; नल पॉइंटर्स के इस उपयोग की तुलना अशक्त प्रकारों और एक विकल्प प्रकार में कुछ नहीं मान से की जा सकती है।
झूलने वाला पॉइन्टर
डैंगलिंग पॉइंटर एक पॉइंटर होता है जो किसी वैध वस्तु की ओर इशारा नहीं करता है और इसके परिणामस्वरूप प्रोग्राम क्रैश हो सकता है या अजीब व्यवहार कर सकता है। पास्कल (प्रोग्रामिंग भाषा) या सी (प्रोग्रामिंग भाषा) में, पॉइंटर्स जो विशेष रूप से इनिशियलाइज़ नहीं होते हैं, वे मेमोरी में अप्रत्याशित पतों की ओर इशारा कर सकते हैं।
निम्न उदाहरण कोड झूलने वाले पॉइन्टर को दिखाता है:
int func(void) { char *p1 = malloc(sizeof(char)); /* (undefined) value of some place on the heap */ char *p2; /* dangling (uninitialized) pointer */ *p1 = 'a'; /* This is OK, assuming malloc() has not returned NULL. */ *p2 = 'b'; /* This invokes undefined behavior */ }
यहाँ, p2
मेमोरी में कहीं भी इंगित कर सकता है, इसलिए असाइनमेंट कर रहा है *p2 = 'b';
मेमोरी के अज्ञात क्षेत्र को दूषित कर सकता है या विभाजन दोष को ट्रिगर कर सकता है।
जंगली शाखा
जहां एक पॉइंटर का उपयोग किसी प्रोग्राम के प्रवेश बिंदु के एड्रैस के रूप में किया जाता है या एक सबरूटीन की प्रारंभ होती है। फ़ंक्शन जो कुछ भी वापस नहीं करता है और या तो अप्रारंभीकृत या दूषित है, अगर इस एड्रैस पर कॉल या बिना शर्त शाखा की जाती है, तो a कहा जाता है कि जंगली शाखा हुई है। दूसरे शब्दों में, एक जंगली शाखा एक फ़ंक्शन पॉइंटर है जो जंगली (लटकती) है।
परिणाम सामान्य रूप से अप्रत्याशित होते हैं और त्रुटि स्वयं को कई अलग-अलग तरीकों से प्रस्तुत कर सकती है, जो इस बात पर निर्भर करता है कि पॉइन्टर एक वैध पता है या नहीं और उस एड्रैस पर (संयोग से) एक वैध निर्देश (ओपकोड) है या नहीं। एक जंगली शाखा का पता लगाना सबसे कठिन और निराशाजनक डिबगिंग अभ्यासों में से एक को प्रस्तुत कर सकता है क्योंकि बहुत से साक्ष्य पहले ही नष्ट हो सकते हैं या शाखा स्थान पर एक या अधिक अनुचित निर्देशों के निष्पादन से हो सकते हैं। यदि उपलब्ध हो, तो एक निर्देश सेट सिम्युलेटर सामान्य रूप से प्रभावी होने से पहले न केवल एक जंगली शाखा का पता लगा सकता है, बल्कि इसके इतिहास का पूर्ण या आंशिक निशान भी प्रदान करता है।
संरचना द्वारा परिभाषित प्रकार
ऑटोरिलेटिव पॉइंटर
एक ऑटोरिलेटिव पॉइंटर एक पॉइंटर होता है जिसका मान पॉइंटर के एड्रैस से ऑफ़सेट के रूप में व्याख्या किया जाता है; इस प्रकार, यदि डेटा संरचना में एक ऑटोरिलेटिव पॉइंटर सदस्य है जो डेटा संरचना के कुछ हिस्से को इंगित करता है, तो डेटा संरचना को ऑटो रिलेटिव पॉइंटर के मान को अपडेट किए बिना मेमोरी में स्थानांतरित किया जा सकता है।[12] उद्धृत पेटेंट एक ही चीज़ का अर्थ करने के लिए स्व-सापेक्ष पॉइन्टर शब्द का भी उपयोग करता है। हालाँकि, उस शब्द का अर्थ अन्य तरीकों से उपयोग किया गया है:
- पॉइन्टर के एड्रैस के बजाय संरचना के एड्रैस से ऑफ़सेट का मतलब;[citation needed]
- मतलब एक पॉइन्टर जिसमें अपना पता होता है, जो मेमोरी के किसी भी मनमाना क्षेत्र में पुनर्निर्माण के लिए उपयोगी हो सकता है जो एक दूसरे को इंगित करने वाले डेटा संरचनाओं का संग्रह होता है।[13]
आधारित पॉइन्टर
एक आधारित पॉइंटर एक पॉइंटर होता है जिसका मान दूसरे पॉइंटर के मान से ऑफ़सेट होता है। इसका उपयोग डेटा के ब्लॉक को स्टोर और लोड करने के लिए किया जा सकता है, ब्लॉक की प्रारंभ के एड्रैस को बेस पॉइंटर को निर्दिष्ट कर सकता है।[14]
=== उपयोग या डेटाटाइप === द्वारा परिभाषित प्रकार
एकाधिक संकेत
कुछ भाषाओं में, एक पॉइंटर दूसरे पॉइंटर को संदर्भित कर सकता है, जिसके लिए मूल मान प्राप्त करने के लिए कई डीरेफेरेंस ऑपरेशंस की आवश्यकता होती है। जबकि संकेत का प्रत्येक स्तर एक प्रदर्शन लागत जोड़ सकता है, जटिल डेटा संरचनाओं के लिए सही व्यवहार प्रदान करने के लिए कभी-कभी यह आवश्यक होता है। उदाहरण के लिए, सी में एक तत्व के संदर्भ में एक लिंक्ड सूची को परिभाषित करना सामान्य है जिसमें सूची के अगले तत्व के लिए पॉइन्टर होता है:
struct element { struct element *next; int value; }; struct element *head = NULL;
यह कार्यान्वयन पूरी सूची के लिए सरोगेट के रूप में सूची में पहले तत्व के लिए पॉइन्टर का उपयोग करता है। यदि सूची के आरंभ में एक नया मान जोड़ा जाता है, head
नए तत्व को इंगित करने के लिए बदलना होगा। चूंकि सी तर्क हमेशा मूल्य से पारित होते हैं, डबल इंडिकेशन का उपयोग करके सम्मिलन को सही ढंग से कार्यान्वित करने की स्वीकृति मिलती है, और सूची के सामने सम्मिलन से निपटने के लिए विशेष केस कोड को खत्म करने का वांछनीय दुष्प्रभाव होता है:
// Given a sorted list at *head, insert the element item at the first // location where all earlier elements have lesser or equal value. void insert(struct element **head, struct element *item) { struct element **p; // p points to a pointer to an element for (p = head; *p != NULL; p = &(*p)->next) { if (item->value <= (*p)->value) break; } item->next = *p; *p = item; } // Caller does this: insert(&head, item);
इस स्थिति में, यदि का मान item
से कम है head
, फोन करने वाले का head
नए आइटम के एड्रैस पर ठीक से अपडेट किया गया है।
एक मूल उदाहरण argv तर्क में main function#C और C++|main function in C (और C++) में है, जो प्रोटोटाइप में दिया गया है char **argv
—यह इसलिए है क्योंकि चर argv
स्वयं तार की एक सरणी (सरणियों की एक सरणी) के लिए एक पॉइन्टर है, इसलिए *argv
0 वीं स्ट्रिंग के लिए एक पॉइन्टर है (सम्मेलन द्वारा कार्यक्रम का नाम), और **argv
0वीं स्ट्रिंग का 0वां वर्ण है।
फंक्शन पॉइंटर
कुछ भाषाओं में, एक संकेतक निष्पादन योग्य कोड को संदर्भित कर सकता है, अर्थात यह किसी फ़ंक्शन, विधि या प्रक्रिया को इंगित कर सकता है। एक फ़ंक्शन पॉइंटर फ़ंक्शन के एड्रैस को आमंत्रित करने के लिए संग्रहीत करेगा। जबकि इस सुविधा का उपयोग कार्यों को गतिशील रूप से कॉल करने के लिए किया जा सकता है, यह प्रायः वायरस और अन्य दुर्भावनापूर्ण सॉफ़्टवेयर लेखकों की पसंदीदा तकनीक है।
int sum(int n1, int n2) { // Function with two integer parameters returning an integer value return n1 + n2; } int main(void) { int a, b, x, y; int (*fp)(int, int); // Function pointer which can point to a function like sum fp = ∑ // fp now points to function sum x = (*fp)(a, b); // Calls function sum with arguments a and b y = sum(a, b); // Calls function sum with arguments a and b }
बैक पॉइंटर
दोगुनी लिंक्ड सूचियों या ट्री (डेटा संरचना) में, एक तत्व पर रखा गया एक बैक पॉइंटर वर्तमान तत्व का जिक्र करते हुए आइटम को 'पॉइंट बैक' करता है। अधिक मेमोरी उपयोग की कीमत पर ये नेविगेशन और हेरफेर के लिए उपयोगी हैं।
एक सरणी अनुक्रमणिका का उपयोग कर सिमुलेशन
एक (सामान्य रूप से एक-आयामी) सरणी के सूचकांक का उपयोग करके पॉइन्टर व्यवहार को अनुकरण करना संभव है।
मुख्य रूप से उन भाषाओं के लिए जो स्पष्ट रूप से पॉइंटर्स का समर्थन नहीं करती हैं, लेकिन सरणियों का समर्थन करती हैं, ऐरे डेटा प्रकार के बारे में सोचा और संसाधित किया जा सकता है जैसे कि यह संपूर्ण मेमोरी रेंज (विशेष एरे के दायरे के अंदर) और किसी भी इंडेक्स के बारे में सोचा जा सकता है। असेंबली भाषा में एक सामान्य उद्देश्य रजिस्टर के बराबर (जो व्यक्तिगत बाइट्स को इंगित करता है लेकिन जिसका वास्तविक मूल्य सरणी की प्रारंभ के सापेक्ष है, मेमोरी में इसका पूर्ण पता नहीं)। सरणी मानते हुए, कहते हैं, एक सन्निहित 16 मेगाबाइट वर्ण डेटा संरचना, व्यक्तिगत बाइट्स (या सरणी के अंदर सन्निहित बाइट्स का एक स्ट्रिंग (कंप्यूटर विज्ञान)) को सीधे संबोधित किया जा सकता है और 31 बिट अहस्ताक्षरित पूर्णांक के साथ सरणी के नाम का उपयोग करके हेरफेर किया जा सकता है। सिम्युलेटेड पॉइंटर के रूप में (यह ऊपर दिखाए गए C सरणियों के उदाहरण के समान है)। पॉइंटर अंकगणित को वास्तविक पॉइंटर अंकगणित की तुलना में न्यूनतम अतिरिक्त ओवरहेड के साथ इंडेक्स से जोड़कर या घटाकर अनुकरण किया जा सकता है।
यह सैद्धांतिक रूप से भी संभव है, उपरोक्त तकनीक का उपयोग करके, उपयुक्त निर्देश सेट सिम्युलेटर के साथ किसी भी मशीन कोड या किसी प्रोसेसर/भाषा के इंटरमीडिएट (बाइट कोड) को किसी अन्य भाषा में अनुकरण करने के लिए जो पॉइंटर्स का समर्थन नहीं करता है (उदाहरण के लिए जावा (उदाहरण के लिए जावा) प्रोग्रामिंग भाषा) / जावास्क्रिप्ट)। इसे प्राप्त करने के लिए, बाइनरी अंक प्रणाली कोड को प्रारंभ में सिम्युलेटर के लिए सरणी के सन्निहित बाइट्स में लोड किया जा सकता है, उसी सरणी में निहित मेमोरी के अंदर पूरी तरह से पढ़ने, व्याख्या करने और क्रिया करने के लिए। यदि आवश्यक हो, तो बफ़र अधिकता समस्याओं से पूरी तरह से बचने के लिए, सामान्य रूप से संकलक के लिए सीमा जाँच की जा सकती है (या यदि नहीं, तो सिम्युलेटर में हाथ से कोडित)।
विभिन्न प्रोग्रामिंग भाषाओं में समर्थन
अदा
एडा (प्रोग्रामिंग भाषा) एक दृढ़ता से टाइप की जाने वाली भाषा है जहां सभी पॉइंटर्स टाइप किए जाते हैं और केवल सुरक्षित प्रकार के रूपांतरणों की स्वीकृति है। डिफ़ॉल्ट रूप से सभी पॉइंटर्स को इनिशियलाइज़ किया जाता है null
, और डेटा तक पहुँचने का कोई भी प्रयास a null
पॉइन्टर अपवाद हैंडलिंग को उठाए जाने का कारण बनता है। Ada में पॉइंटर्स को पहुंच प्रकार कहा जाता है। Ada 83 ने एक्सेस प्रकारों पर अंकगणित की स्वीकृति नहीं दी (हालाँकि कई कंपाइलर विक्रेता इसके लिए एक गैर-मानक विशेषता के रूप में प्रदान करते हैं), लेकिन Ada 95 पैकेज के माध्यम से एक्सेस प्रकारों पर "सुरक्षित" अंकगणित का समर्थन करता है System.Storage_Elements
.
बुनियादी
Windows प्लेटफ़ॉर्म के लिए BASIC के कई पुराने संस्करणों में स्ट्रिंग का पता वापस करने के लिए STRPTR () और एक चर का पता वापस करने के लिए VARPTR () के लिए समर्थन था। विजुअल बेसिक 5 में ओबीजेपीटीआर () के लिए एक ऑब्जेक्ट इंटरफेस का पता वापस करने के लिए और एक ADDRESSOF ऑपरेटर के लिए एक फ़ंक्शन का पता वापस करने के लिए समर्थन था। इन सभी के प्रकार पूर्णांक हैं, लेकिन उनके मान पॉइन्टर प्रकारों द्वारा रखे गए के बराबर हैं।
हालाँकि, BASIC की नई बोलियाँ, जैसे FreeBASIC या BlitzMax, में संपूर्ण संकेतक कार्यान्वयन हैं। FreeBASIC में, अंकगणित पर ANY
पॉइंटर्स (सी के बराबर void*
) के रूप में माना जाता है ANY
पॉइन्टर एक बाइट चौड़ाई थी। ANY
पॉइंटर्स को डीरेफरेंस नहीं किया जा सकता है, जैसा कि सी में भी है, बीच में कास्टिंग ANY
और किसी अन्य प्रकार के संकेतक कोई चेतावनी उत्पन्न नहीं करेंगे।
dim as integer f = 257 dim as any ptr g = @f dim as integer ptr i = g assert(*i = 257) assert( (g + 4) = (@f + 1) )
सी और सी ++
C (प्रोग्रामिंग भाषा) और C++ पॉइंटर्स वेरिएबल्स हैं जो पतों को स्टोर करते हैं और शून्य हो सकते हैं। प्रत्येक पॉइन्टर के पास एक प्रकार होता है जिसे वह इंगित करता है, लेकिन कोई पॉइन्टर प्रकारों के बीच स्वतंत्र रूप से कास्ट कर सकता है (लेकिन फ़ंक्शन पॉइंटर और ऑब्जेक्ट पॉइंटर के बीच नहीं)। एक विशेष पॉइन्टर प्रकार जिसे "शून्य पॉइन्टर" कहा जाता है, किसी भी (गैर-फ़ंक्शन) ऑब्जेक्ट को इंगित करने की स्वीकृति देता है, लेकिन इस तथ्य से सीमित है कि इसे सीधे संदर्भित नहीं किया जा सकता है (इसे कास्ट किया जाएगा)। पर्याप्त आकार के एक अभिन्न प्रकार से और उसके लिए एक पॉइन्टर को कास्ट करके पता ही प्रायः सीधे हेरफेर किया जा सकता है, हालांकि परिणाम कार्यान्वयन-परिभाषित होते हैं और वास्तव में अपरिभाषित व्यवहार का कारण बन सकते हैं; जबकि पहले सी मानकों में एक अभिन्न प्रकार नहीं था जो काफी बड़ा होने की गारंटी देता था, सी 99 निर्दिष्ट करता है uintptr_t
typedef नाम में परिभाषित किया गया है <stdint.h>
, लेकिन कार्यान्वयन के लिए इसे प्रदान करने की आवश्यकता नहीं है।
सी ++ पूरी तरह से सी पॉइंटर्स और सी टाइपकास्टिंग का समर्थन करता है। यह संकलन-समय पर कुछ अनपेक्षित खतरनाक जातियों को पकड़ने में मदद करने के लिए टाइपकास्टिंग ऑपरेटरों के एक नए समूह का भी समर्थन करता है। C++11 के बाद से, C++ मानक लाइब्रेरी|C++ मानक पुस्तकालय स्मार्ट पॉइंटर्स भी प्रदान करता है (unique_ptr
, shared_ptr
और weak_ptr
) जिसका उपयोग कुछ स्थितियों में आदिम सी पॉइंटर्स के सुरक्षित विकल्प के रूप में किया जा सकता है। C++ संदर्भ के दूसरे रूप का भी समर्थन करता है, जो पॉइन्टर से काफी भिन्न होता है, जिसे केवल एक संदर्भ (C++) या संदर्भ प्रकार कहा जाता है।
'प्वाइंटर अंकगणित', यानी, अंकगणितीय संचालन (साथ ही साथ परिमाण तुलना) के साथ एक पॉइन्टर के लक्ष्य एड्रैस को संशोधित करने की क्षमता, भाषा मानक द्वारा एकल सरणी वस्तु (या उसके ठीक बाद) की सीमा के अंदर रहने के लिए प्रतिबंधित है। और अन्यथा अपरिभाषित व्यवहार का आह्वान करेगा। एक पॉइन्टर से जोड़ना या घटाना इसे अपने डेटाटाइप के आकार के एक से अधिक द्वारा ले जाता है। उदाहरण के लिए, 4-बाइट पूर्णांक मानों में एक पॉइंटर में 1 जोड़ने से पॉइंटर के पॉइंट-टू-बाइट-एड्रेस में 4 की वृद्धि होगी। इसका प्रभाव पूर्णांकों की एक सन्निहित सरणी में अगले तत्व को इंगित करने के लिए पॉइंटर को बढ़ाने का प्रभाव है - जो है प्रायः इच्छित परिणाम। पॉइन्टर अंकगणित पर नहीं किया जा सकता है void
पॉइंटर्स क्योंकि शून्य प्रकार का कोई आकार नहीं है, और इस प्रकार इंगित पता जोड़ा नहीं जा सकता है, हालांकि जीएनयू कंपाइलर संग्रह और अन्य कंपाइलर बाइट अंकगणितीय प्रदर्शन करेंगे void*
एक गैर-मानक विस्तार के रूप में, इसे ऐसा माना जाता है जैसे कि यह था char *
.
पॉइंटर अंकगणित प्रोग्रामर को विभिन्न प्रकारों से निपटने का एक ही तरीका प्रदान करता है: बाइट्स में वास्तविक ऑफ़सेट के बजाय आवश्यक तत्वों की संख्या को जोड़ना और घटाना। (पॉइन्टर अंकगणित के साथ char *
पॉइंटर्स बाइट ऑफ़सेट का उपयोग करते हैं, क्योंकि sizeof(char)
परिभाषा के अनुसार 1 है।) विशेष रूप से, सी परिभाषा स्पष्ट रूप से सिंटैक्स की घोषणा करती है a[n]
, वह कौन सा है n
- सरणी का तत्व a
, के बराबर है *(a + n)
, जो कि द्वारा इंगित तत्व की सामग्री है a + n
. इसका अर्थ यह है कि n[a]
के बराबर है a[n]
, और कोई लिख सकता है, उदा., a[3]
या 3[a]
किसी सरणी के चौथे तत्व तक पहुँचने के लिए समान रूप से अच्छा a
.
जबकि शक्तिशाली, पॉइन्टर अंकगणित सॉफ़्टवेयर बग का स्रोत हो सकता है। यह नौसिखिए प्रोग्रामरों को भ्रमित करता है, उन्हें अलग-अलग संदर्भों में मजबूर करता है: एक अभिव्यक्ति एक सामान्य अंकगणितीय या पॉइन्टर अंकगणितीय हो सकती है, और कभी-कभी दूसरे के लिए गलती करना आसान होता है। इसके जवाब में, कई आधुनिक उच्च-स्तरीय कंप्यूटर भाषाएं (उदाहरण के लिए जावा (प्रोग्रामिंग भाषा)) पतों का उपयोग करके मेमोरी तक सीधी पहुंच की स्वीकृति नहीं देती हैं। इसके अलावा, सुरक्षित सी बोली चक्रवात प्रोग्रामिंग भाषा पॉइंटर्स के साथ कई मुद्दों को संबोधित करती है। अधिक चर्चा के लिए सी (प्रोग्रामिंग भाषा) # पॉइंटर्स देखें।
void
पॉइन्टर, याvoid*
, एएनएसआई सी और सी ++ में एक सामान्य पॉइन्टर प्रकार के रूप में समर्थित है। के लिए एक संकेतक void
किसी भी ऑब्जेक्ट (फ़ंक्शन नहीं) के एड्रैस को स्टोर कर सकता है, और, सी में, असाइनमेंट पर किसी अन्य ऑब्जेक्ट पॉइंटर प्रकार में अंतर्निहित रूप से परिवर्तित हो जाता है, लेकिन इसे संदर्भित होने पर स्पष्ट रूप से कास्ट किया जाना चाहिए।
सी प्रोग्रामिंग भाषा | के एंड आर सी का उपयोग किया char*
"टाइप-एग्नोस्टिक पॉइंटर" उद्देश्य के लिए (एएनएसआई सी से पहले)।
int x = 4; void* p1 = &x; int* p2 = p1; // void* implicitly converted to int*: valid C, but not C++ int a = *p2; int b = *(int*)p1; // when dereferencing inline, there is no implicit conversion
सी ++ निहित रूपांतरण की स्वीकृति नहीं देता है void*
अन्य पॉइन्टर प्रकारों के लिए, यहां तक कि असाइनमेंट में भी। यह लापरवाह और यहां तक कि अनपेक्षित कास्ट से बचने के लिए एक डिजाइन निर्णय था, हालांकि अधिकांश कंपाइलर अन्य कास्ट का सामना करते समय केवल चेतावनी आउटपुट करते हैं, त्रुटियां नहीं।
int x = 4; void* p1 = &x; int* p2 = p1; // this fails in C++: there is no implicit conversion from void* int* p3 = (int*)p1; // C-style cast int* p4 = reinterpret_cast<int*>(p1); // C++ cast
सी ++ में, नहीं है void&
(शून्य के संदर्भ में) पूरक करने के लिए void*
(पॉइन्टर को शून्य), क्योंकि संदर्भ उन चरों के लिए उपनामों की तरह व्यवहार करते हैं जिन्हें वे इंगित करते हैं, और कभी भी ऐसा चर नहीं हो सकता है जिसका प्रकार है void
.
पॉइंटर-टू-मेंबर
सी ++ पॉइंटर्स में कक्षा के गैर स्थैतिक सदस्यों को परिभाषित किया जा सकता है। यदि कोई वर्ग C
एक सदस्य है T a
तब &C::a
सदस्य के लिए पॉइन्टर है a
प्रकार का T C::*
. यह सदस्य ऑब्जेक्ट या फ़ंक्शन पॉइंटर # मेथड पॉइंटर्स हो सकता है।[15] उनका उपयोग ऑपरेटरों के दाईं ओर किया जा सकता है .*
और ->*
संबंधित सदस्य तक पहुँचने के लिए।
struct S { int a; int f() const {return a;} }; S s1{}; S* ptrS = &s1; int S::* ptr = &S::a; // pointer to S::a int (S::* fp)()const = &S::f; // pointer to S::f s1.*ptr = 1; std::cout << (s1.*fp)() << "\n"; // prints 1 ptrS->*ptr = 2; std::cout << (ptrS->*fp)() << "\n"; // prints 2
पॉइंटर डिक्लेरेशन सिंटैक्स ओवरव्यू
ये पॉइंटर डिक्लेरेशन पॉइंटर डिक्लेरेशन के अधिकांश वेरिएंट को कवर करते हैं। बेशक ट्रिपल पॉइंटर्स होना संभव है, लेकिन ट्रिपल पॉइंटर के पीछे मुख्य सिद्धांत पहले से ही डबल पॉइंटर में सम्मिलित हैं। यहाँ प्रयुक्त नामकरण क्या अभिव्यक्ति है typeid(type).name()
g++ या बजना का उपयोग करते समय इनमें से प्रत्येक प्रकार के लिए बराबर होता है।[16][17]
char A5_A5_c [5][5]; /* array of arrays of chars */ char *A5_Pc [5]; /* array of pointers to chars */ char **PPc; /* pointer to pointer to char ("double pointer") */ char (*PA5_c) [5]; /* pointer to array(s) of chars */ char *FPcvE(); /* function which returns a pointer to char(s) */ char (*PFcvE)(); /* pointer to a function which returns a char */ char (*FPA5_cvE())[5]; /* function which returns pointer to an array of chars */ char (*A5_PFcvE[5])(); /* an array of pointers to functions which return a char */
पॉइंटर्स-टू-मेंबर से जुड़ी निम्नलिखित घोषणाएँ केवल C ++ में मान्य हैं:
class C; class D; char C::* M1Cc; /* pointer-to-member to char */ char C::*A5_M1Cc [5]; /* array of pointers-to-member to char */ char* C::* M1CPc; /* pointer-to-member to pointer to char(s) */ char C::** PM1Cc; /* pointer to pointer-to-member to char */ char (*M1CA5_c) [5]; /* pointer-to-member to array(s) of chars */ char C::* FM1CcvE(); /* function which returns a pointer-to-member to char */ char D::* C::* M1CM1Dc; /* pointer-to-member to pointer-to-member to pointer to char(s) */ char C::* C::* M1CMS_c; /* pointer-to-member to pointer-to-member to pointer to char(s) */ char (C::* FM1CA5_cvE())[5]; /* function which returns pointer-to-member to an array of chars */ char (C::* M1CFcvE)() /* pointer-to-member-function which returns a char */
()
ई> और []
से अधिक प्राथमिकता है *
.
[18]
सी#
C Sharp (प्रोग्रामिंग भाषा) | C# प्रोग्रामिंग भाषा में, पॉइंटर्स केवल कुछ शर्तों के तहत समर्थित होते हैं: पॉइंटर्स सहित कोड के किसी भी ब्लॉक को मार्क के साथ चिह्नित किया जाना चाहिए unsafe
कीवर्ड। ऐसे ब्लॉकों को चलाने के लिए सामान्य रूप से उच्च सुरक्षा अनुमतियों की आवश्यकता होती है।
सिंटैक्स अनिवार्य रूप से सी ++ के समान है, और बताया गया पता या तो प्रबंधित कोड या प्रबंधित कोड मेमोरी हो सकता है। हालाँकि, प्रबंधित मेमोरी के लिए पॉइंटर्स (किसी प्रबंधित ऑब्जेक्ट के लिए कोई पॉइंटर) का उपयोग करके घोषित किया जाना चाहिए fixed
कीवर्ड, जो गारबेज कलेक्शन (कंप्यूटर साइंस) को मेमोरी प्रबंधन के हिस्से के रूप में इंगित वस्तु को स्थानांतरित करने से रोकता है, जबकि पॉइन्टर दायरे में है, इस प्रकार पॉइन्टर एड्रैस को वैध रखता है।
इसका उपयोग करने से इसका अपवाद है IntPtr
संरचना, जो एक सुरक्षित प्रबंधित समतुल्य है int*
, और असुरक्षित कोड की आवश्यकता नहीं है। से विधियों का उपयोग करते समय इस प्रकार को प्रायः वापस कर दिया जाता है System.Runtime.InteropServices
, उदाहरण के लिए:
// Get 16 bytes of memory from the process's unmanaged memory IntPtr pointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(16); // Do something with the allocated memory // Free the allocated memory System.Runtime.InteropServices.Marshal.FreeHGlobal(pointer);
.NET Framework|.NET फ्रेमवर्क में कई वर्ग और विधियाँ सम्मिलित हैं System
और System.Runtime.InteropServices
नामस्थान (जैसे Marshal
क्लास) जो .NET प्रकारों को रूपांतरित करते हैं (उदाहरण के लिए, System.String
) कई प्रबंधित कोड प्रकारों और पॉइंटर्स से और (उदाहरण के लिए, LPWSTR
या void*
) प्रबंधित कोड के साथ संचार की स्वीकृति देने के लिए। इस तरह के अधिकांश तरीकों में अप्रबंधित कोड के समान सुरक्षा स्वीकृति की आवश्यकता होती है, क्योंकि वे मेमोरी में मनमाने स्थानों को प्रभावित कर सकते हैं।
कोबोल
COBOL प्रोग्रामिंग भाषा पॉइंटर्स टू वेरिएबल्स का समर्थन करती है। आदिम या समूह (रिकॉर्ड) डेटा ऑब्जेक्ट घोषित किए गए LINKAGE SECTION
स्वाभाविक रूप से पॉइंटर-आधारित होते हैं, जहां प्रोग्राम के अंदर आवंटित एकमात्र मेमोरी डेटा आइटम के एड्रैस के लिए जगह होती है (सामान्य रूप से एक मेमोरी शब्द)। प्रोग्राम सोर्स कोड में, ये डेटा आइटम किसी अन्य की तरह ही उपयोग किए जाते हैं WORKING-STORAGE
चर, लेकिन उनकी सामग्री परोक्ष रूप से उनके माध्यम से पहुँचा जा सकता है LINKAGE
संकेत।
प्रत्येक पॉइंट-टू-डेटा ऑब्जेक्ट के लिए मेमोरी स्पेस सामान्य रूप से बाहरी सबरूटीन का उपयोग करके डायनेमिक मेमोरी आवंटन हैCALL
बयान या एम्बेडेड विस्तारित भाषा निर्माण जैसे कि EXEC CICS |EXEC CICS
या एसक्यूएल |EXEC SQL
बयान।
COBOL के विस्तारित संस्करण भी घोषित पॉइन्टर चर प्रदान करते हैं USAGE
IS
POINTER
खंड। ऐसे पॉइंटर वेरिएबल्स के मान स्थापित और संशोधित किए जाते हैं SET
और SET
ADDRESS
बयान।
COBOL के कुछ विस्तारित संस्करण भी प्रदान करते हैं PROCEDURE-POINTER
वेरिएबल्स, जो फंक्शन पॉइंटर को स्टोर करने में सक्षम हैं।
पीएल/आई
PL/I भाषा सभी डेटा प्रकारों (संरचनाओं के संकेत सहित), पुनरावर्तन, कंप्यूटर मल्टीटास्किंग, स्ट्रिंग हैंडलिंग और व्यापक अंतर्निर्मित सबरूटीन्स के लिए पॉइंटर्स के लिए पूर्ण समर्थन प्रदान करती है। PL/I अपने समय की प्रोग्रामिंग भाषाओं की तुलना में काफी आगे था।[citation needed] पीएल/आई पॉइंटर्स टाइप नहीं किए गए हैं, और इसलिए पॉइंटर डीरेफरेंसिंग या असाइनमेंट के लिए कोई कास्टिंग आवश्यक नहीं है। पॉइंटर के लिए डिक्लेरेशन सिंटैक्स है DECLARE xxx POINTER;
, जो xxx नाम के एक पॉइंटर को डिक्लेयर करता है। संकेतकों का प्रयोग किया जाता है BASED
चर। एक आधारित चर को एक डिफ़ॉल्ट लोकेटर के साथ घोषित किया जा सकता है (DECLARE xxx BASED(ppp);
या बिना (DECLARE xxx BASED;
), जहां xxx एक आधारित चर है, जो एक तत्व चर, एक संरचना, या एक सरणी हो सकता है, और पीपीपी डिफ़ॉल्ट पॉइन्टर है)। इस तरह के एक चर को एक स्पष्ट पॉइन्टर संदर्भ के बिना संबोधित किया जा सकता है (xxx=1;
, या डिफ़ॉल्ट लोकेटर (पीपीपी), या किसी अन्य पॉइन्टर के लिए एक स्पष्ट संदर्भ के साथ संबोधित किया जा सकता है (qqq->xxx=1;
).
पॉइंटर अंकगणित पीएल/आई मानक का हिस्सा नहीं है, लेकिन कई कंपाइलर फॉर्म के भावों की स्वीकृति देते हैं ptr = ptr±expression
. आईबीएम पीएल/आई में बिल्टिन फ़ंक्शन भी है PTRADD
अंकगणित करने के लिए। पॉइन्टर अंकगणित हमेशा बाइट्स में किया जाता है।
IBM Enterprise PL/I कम्पाइलर के पास टाइप किए गए पॉइंटर का एक नया रूप है जिसे a कहा जाता है HANDLE
.
डी
डी (प्रोग्रामिंग भाषा) सी और सी ++ का व्युत्पन्न है जो सी पॉइंटर्स और सी टाइपकास्टिंग का पूर्ण समर्थन करता है।
एफिल
एफिल (प्रोग्रामिंग भाषा) | एफिल ऑब्जेक्ट-ओरिएंटेड भाषा पॉइंटर अंकगणित के बिना मूल्य और संदर्भ शब्दार्थ को नियोजित करती है। फिर भी, पॉइन्टर वर्ग प्रदान किए जाते हैं। वे पॉइन्टर अंकगणित, टाइपकास्टिंग, स्पष्ट मेमोरी प्रबंधन प्रदान करते हैं, गैर-एफिल सॉफ्टवेयर और अन्य सुविधाओं के साथ इंटरफेसिंग।
फोरट्रान
फोरट्रान | फोरट्रान -90 ने दृढ़ता से टाइप की गई पॉइन्टर क्षमता की प्रारंभ की। फोरट्रान पॉइंटर्स में केवल एक साधारण मेमोरी एड्रेस से अधिक होता है। वे सरणी आयामों की निचली और ऊपरी सीमा, स्ट्राइड्स (उदाहरण के लिए, मनमाना सरणी अनुभागों का समर्थन करने के लिए), और अन्य मेटाडेटा को भी समाहित करते हैं। एक संघ संचालक, =>
a को जोड़ने के लिए प्रयोग किया जाता है POINTER
एक चर के लिए जिसमें a है TARGET
गुण। फोरट्रान -90 ALLOCATE
स्टेटमेंट का उपयोग पॉइंटर को मेमोरी के ब्लॉक से जोड़ने के लिए भी किया जा सकता है। उदाहरण के लिए, लिंक की गई सूची संरचना को परिभाषित करने और बनाने के लिए निम्न कोड का उपयोग किया जा सकता है:
type real_list_t real :: sample_data(100) type (real_list_t), pointer :: next => null () end type type (real_list_t), target :: my_real_list type (real_list_t), pointer :: real_list_temp real_list_temp => my_real_list do read (1,iostat=ioerr) real_list_temp%sample_data if (ioerr /= 0) exit allocate (real_list_temp%next) real_list_temp => real_list_temp%next end do
फोरट्रान-2003 प्रक्रिया संकेतकों के लिए समर्थन जोड़ता है। साथ ही, सी इंटरऑपरेबिलिटी फीचर के हिस्से के रूप में, फोरट्रान-2003 सी-स्टाइल पॉइंटर्स को फोरट्रान पॉइंटर्स और बैक में परिवर्तित करने के लिए आंतरिक कार्यों का समर्थन करता है।
जाओ
जाओ (प्रोग्रामिंग भाषा) में पॉइंटर्स होते हैं। इसकी घोषणा सिंटैक्स सी के बराबर है, लेकिन इसके विपरीत लिखा गया है, प्रकार के साथ समाप्त होता है। सी के विपरीत, गो में कचरा संग्रहण है, और पॉइंटर अंकगणित को अस्वीकार करता है। संदर्भ प्रकार, जैसे C++ में सम्मिलित नहीं हैं। कुछ अंतर्निर्मित प्रकार, जैसे मानचित्र और चैनल, बॉक्सिंग होते हैं (यानी आंतरिक रूप से वे उत्परिवर्तनीय संरचनाओं के संकेतक होते हैं), और इनका उपयोग करके प्रारंभ किया जाता है make
समारोह। पॉइंटर्स और नॉन-पॉइंटर्स के बीच एकीकृत सिंटैक्स के दृष्टिकोण में, तीर (->
) ऑपरेटर को हटा दिया गया है: पॉइंटर पर डॉट ऑपरेटर डीरेफरेंस्ड ऑब्जेक्ट के क्षेत्र या विधि को संदर्भित करता है। हालाँकि, यह केवल 1 स्तर के संकेत के साथ काम करता है।
जावा
जावा (प्रोग्रामिंग भाषा) में पॉइंटर्स का कोई स्पष्ट प्रतिनिधित्व नहीं है। इसके बजाय, संदर्भ (कंप्यूटर विज्ञान) का उपयोग करके अधिक जटिल डेटा संरचनाएं जैसे ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग और ऐरे डेटा संरचना लागू की जाती हैं। भाषा कोई स्पष्ट पॉइन्टर हेरफेर ऑपरेटर प्रदान नहीं करती है। कोड के लिए अभी भी एक अशक्त संदर्भ (अशक्त पॉइन्टर) को हटाने का प्रयास करना संभव है, हालांकि, जिसके परिणामस्वरूप रन-टाइम अपवाद हैंडलिंग को फेंक दिया जाता है। गैर-संदर्भित मेमोरी ऑब्जेक्ट्स द्वारा कब्जा कर लिया गया स्थान स्वचालित रूप से कचरा संग्रहण (कंप्यूटर साइंस) द्वारा रन-टाइम पर पुनर्प्राप्त किया जाता है।[19]
मोडुला-2
पास्कल के रूप में पॉइंटर्स बहुत अधिक लागू किए जाते हैं VAR
प्रक्रिया कॉल में पैरामीटर। मॉड्यूल-2 पास्कल की तुलना में और भी अधिक मजबूती से टाइप किया गया है, टाइप सिस्टम से बचने के कम तरीके हैं। मॉड्यूल -3 (जैसे मोडुला-3) के कुछ रूपों में कचरा संग्रह सम्मिलित है।
ओबेरॉन
मोडुला-2 की तरह ही पॉइंटर्स भी उपलब्ध हैं। टाइप सिस्टम से बचने के अभी भी बहुत कम तरीके हैं और इसलिए ओबेरॉन (प्रोग्रामिंग भाषा) और इसके वेरिएंट अभी भी मोडुला -2 या इसके वेरिएंट की तुलना में पॉइंटर्स के संबंध में अधिक सुरक्षित हैं। मॉड्यूला -3 के साथ, कचरा संग्रहण भाषा विनिर्देश का एक हिस्सा है।
पास्कल
पॉइंटर्स की विशेषता वाली कई भाषाओं के विपरीत, स्टैंडर्ड इंटरनैशनल ऑर्गनाइज़ेशन फॉर स्टैंडर्डाइज़ेशन पास्कल (प्रोग्रामिंग भाषा) केवल पॉइंटर्स को डायनेमिक रूप से बनाए गए वेरिएबल्स को संदर्भित करने की स्वीकृति देता है जो गुमनाम हैं और उन्हें मानक स्टैटिक या लोकल वेरिएबल्स को संदर्भित करने की स्वीकृति नहीं देते हैं।[20] इसमें पॉइन्टर अंकगणित नहीं है। पॉइंटर्स के पास एक संबद्ध प्रकार भी होना चाहिए और एक प्रकार का पॉइंटर किसी अन्य प्रकार के पॉइंटर के साथ संगत नहीं है (उदाहरण के लिए एक पॉइंटर एक पूर्णांक के लिए एक पॉइंटर के साथ संगत नहीं है)। यह अन्य पॉइन्टर कार्यान्वयनों के साथ अंतर्निहित प्रकार के सुरक्षा मुद्दों को समाप्त करने में मदद करता है, विशेष रूप से जो PL/I या C (प्रोग्रामिंग भाषा) के लिए उपयोग किए जाते हैं। यह झूलने वाले संकेतकों के कारण होने वाले कुछ जोखिमों को भी दूर करता है, लेकिन गतिशील रूप से संदर्भित स्थान का उपयोग करके जाने की क्षमता dispose
मानक प्रक्रिया (जिसका वही प्रभाव है free
C (प्रोग्रामिंग भाषा) में पाया गया लाइब्रेरी फंक्शन) का अर्थ है कि लटकने वाले पॉइंटर्स का जोखिम पूरी तरह से समाप्त नहीं हुआ है।[21]
हालांकि, कुछ वाणिज्यिक और खुले स्रोत में पास्कल (या डेरिवेटिव) कंपाइलर कार्यान्वयन-जैसे फ़्री पास्कल,[22] एम्बरकाडेरो डेल्फी में टर्बो पास्कल या वस्तु पास्कल- एक पॉइंटर को मानक स्थिर या स्थानीय चर को संदर्भित करने की स्वीकृति है और इसे एक पॉइंटर प्रकार से दूसरे में डाला जा सकता है। इसके अलावा, पॉइंटर अंकगणित अप्रतिबंधित है: पॉइंटर से जोड़ना या घटाना किसी भी दिशा में बाइट्स की संख्या से चलता है, लेकिन इसका उपयोग करके Inc
या Dec
इसके साथ मानक प्रक्रियाएं पॉइंटर को उस डेटा प्रकार के आकार से ले जाती हैं जिसे इंगित करने के लिए घोषित किया जाता है। नाम के तहत एक अनटाइप्ड पॉइंटर भी दिया गया है Pointer
, जो अन्य पॉइन्टर प्रकारों के साथ संगत है।
पर्ल
पर्ल प्रोग्रामिंग भाषा पॉइंटर्स का समर्थन करती है, हालांकि पैक और अनपैक फ़ंक्शंस के रूप में संभव्यता ही कभी उपयोग किया जाता है। ये केवल संकलित ऑपरेटिंग सिस्टम पुस्तकालयों के साथ साधारण बातचीत के लिए अभिप्रेत हैं। अन्य सभी स्थितियो में, पर्ल संदर्भ (कंप्यूटर विज्ञान) का उपयोग करता है, जो टाइप किए जाते हैं और पॉइन्टर अंकगणित के किसी भी रूप की स्वीकृति नहीं देते हैं। उनका उपयोग जटिल डेटा संरचनाओं के निर्माण के लिए किया जाता है।[23]
यह भी देखें
- बाउंडेड पॉइंटर
- बफर ओवरफ्लो
- क्रे पॉइंटर
- फैट पॉइन्टर
- फंक्शन पॉइंटर
- खतरा सूचक
- इटरेटर
- अपारदर्शी सूचक
- पोइंटी
- पॉइंटर स्विजल
- संदर्भ (कंप्यूटर विज्ञान)
- स्टेटिक प्रोग्राम विश्लेषण
- संग्रहण उल्लंघन
- टैग किए गए सूचक
- वेरिएबल (कंप्यूटर विज्ञान)
- शून्य आधारित संख्या
संदर्भ
- ↑ Donald Knuth (1974). "Structured Programming with go to Statements" (PDF). Computing Surveys. 6 (5): 261–301. CiteSeerX 10.1.1.103.6084. doi:10.1145/356635.356640. S2CID 207630080. Archived from the original (PDF) on August 24, 2009.
- ↑ Reilly, Edwin D. (2003). Milestones in Computer Science and Information Technology. Greenwood Publishing Group. p. 204. ISBN 9781573565219. Retrieved 2018-04-13.
Harold Lawson pointer.
- ↑ "IEEE Computer Society awards list". Awards.computer.org. Archived from the original on 2011-03-22. Retrieved 2018-04-13.
- ↑ ISO/IEC 9899, clause 6.7.5.1, paragraph 1.
- ↑ ISO/IEC 9899, clause 6.7.8, paragraph 10.
- ↑ ISO/IEC 9899, clause 7.17, paragraph 3: NULL... which expands to an implementation-defined null pointer constant...
- ↑ ISO/IEC 9899, clause 6.5.3.2, paragraph 4, footnote 87: If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined... Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer...
- ↑ 8.0 8.1 Plauger, P J; Brodie, Jim (1992). ANSI and ISO Standard C Programmer's Reference. Redmond, WA: Microsoft Press. pp. 108, 51. ISBN 978-1-55615-359-4.
An array type does not contain additional holes because all other types pack tightly when composed into arrays [at page 51]
- ↑ WG14 N1124, C – Approved standards: ISO/IEC 9899 – Programming languages – C, 2005-05-06.
- ↑ Jung, Ralf. "Pointers Are Complicated II, or: We need better language specs".
- ↑ Jung, Ralf. "Pointers Are Complicated, or: What's in a Byte?".
- ↑ us patent 6625718, Steiner, Robert C. (Broomfield, CO), "Pointers that are relative to their own present locations", issued 2003-09-23, assigned to Avaya Technology Corp. (Basking Ridge, NJ)
- ↑ us patent 6115721, Nagy, Michael (Tampa, FL), "System and method for database save and restore using self-pointers", issued 2000-09-05, assigned to IBM (Armonk, NY)
- ↑ "Based Pointers". Msdn.microsoft.com. Retrieved 2018-04-13.
- ↑ "Pointers to Member Functions". isocpp.org. Retrieved 2022-11-26.
- ↑ "c++filt(1) - Linux man page".
- ↑ "Itanium C++ ABI".
- ↑ Ulf Bilting, Jan Skansholm, "Vägen till C" (the Road to C), third edition, page 169, ISBN 91-44-01468-6
- ↑ Nick Parlante, [1], Stanford Computer Science Education Library, pp. 9–10 (2000).
- ↑ ISO 7185 Pascal Standard (unofficial copy), section 6.4.4 Pointer-types Archived 2017-04-24 at the Wayback Machine and subsequent.
- ↑ J. Welsh, W. J. Sneeringer, and C. A. R. Hoare, "Ambiguities and Insecurities in Pascal," Software: Practice and Experience 7, pp. 685–696 (1977)
- ↑ Free Pascal Language Reference guide, section 3.4 Pointers
- ↑ Contact details. "// Making References (Perl References and nested data structures)". Perldoc.perl.org. Retrieved 2018-04-13.
बाहरी संबंध
![](https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Commons-logo.svg/langen-gb-30px-Commons-logo.svg.png)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Wikiversity_logo_2017.svg/langen-gb-40px-Wikiversity_logo_2017.svg.png)
![](https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Wikibooks-logo-en-noslogan.svg/langen-gb-40px-Wikibooks-logo-en-noslogan.svg.png)
- PL/I List Processing Paper from the June, 1967 issue of CACM
- cdecl.org A tool to convert pointer declarations to plain English
- Over IQ.com A beginner level guide describing pointers in a plain English.
- Pointers and Memory Introduction to pointers – Stanford Computer Science Education Library
- Pointers in C programming Archived 2019-06-09 at the Wayback Machine A visual model for the beginners in C programming
- 0pointer.de A terse list of minimum length source codes that dereference a null pointer in several different programming languages
- "The C book" – containing pointer examples in ANSI C
- Joint Technical Committee ISO/IEC JTC 1, Subcommittee SC 22, Working Group WG 14 (2007-09-08). International Standard ISO/IEC 9899 (PDF).
{{cite book}}
:|work=
ignored (help)CS1 maint: multiple names: authors list (link).