C प्रोग्रामिंग में पॉइंटर्स: C प्रोग्रामिंग में पॉइंटर क्या है? प्रकार
सी भाषा में पॉइंटर क्या है?
RSI सूचक सी में, एक वेरिएबल है जो दूसरे वेरिएबल का पता संग्रहीत करता है। पॉइंटर का उपयोग किसी अन्य पॉइंटर फ़ंक्शन को संदर्भित करने के लिए भी किया जा सकता है। पॉइंटर को बढ़ाया/घटाया जा सकता है, यानी अगले/पिछले मेमोरी स्थान को इंगित करने के लिए। पॉइंटर का उद्देश्य मेमोरी स्पेस को बचाना और तेज़ निष्पादन समय प्राप्त करना है।
C में पॉइंटर्स का उपयोग कैसे करें
यदि हम v को int प्रकार का चर घोषित करते हैं, तो v वास्तव में एक मान संग्रहीत करेगा।
v अब शून्य के बराबर है.
हालाँकि, प्रत्येक चर का, मान के अलावा, अपना पता भी होता है (या, सरल शब्दों में कहें तो, वह मेमोरी में कहाँ स्थित है)। चर नाम से पहले एम्परसेंड (&) लगाकर पता प्राप्त किया जा सकता है।
यदि आप स्क्रीन पर किसी चर का पता प्रिंट करते हैं, तो यह पूरी तरह से यादृच्छिक संख्या की तरह दिखाई देगा (इसके अलावा, यह रन से रन में भिन्न हो सकता है)।
आइये इसे C उदाहरण में पॉइंटर के साथ व्यवहार में आज़माएँ
इस प्रोग्राम का आउटपुट -480613588 है।
अब, पॉइंटर क्या है? मान संग्रहीत करने के बजाय, पॉइंटर एक चर का पता संग्रहीत करेगा।
पॉइंटर वेरिएबल
इंट *y = &v;
परिवर्तनशील | सूचक |
---|---|
A मूल्य में संग्रहीत नामित भंडारण/स्मृति पता | A परिवर्तनशील कि को अंक का भंडारण/स्मृति पता एक और परिवर्तनशील |
पॉइंटर घोषित करना
चरों की तरह, संकेत भी सी प्रोग्रामिंग आपके प्रोग्राम में इस्तेमाल किए जाने से पहले उन्हें घोषित किया जाना चाहिए। पॉइंटर्स को आप जो भी नाम देना चाहें दे सकते हैं, बशर्ते वे C के नामकरण नियमों का पालन करें। पॉइंटर घोषणा का निम्न रूप होता है।
data_type * pointer_variable_name;
यहाँ,
- डाटा प्रकार C के चर प्रकारों में पॉइंटर का आधार प्रकार है और उस चर के प्रकार को इंगित करता है जिसकी ओर पॉइंटर इंगित करता है।
- तारांकन चिह्न (*: गुणन के लिए प्रयुक्त वही तारांकन चिह्न) जो अप्रत्यक्ष ऑपरेटर है, एक सूचक घोषित करता है।
आइए इस C पॉइंटर्स ट्यूटोरियल में कुछ मान्य पॉइंटर घोषणाएं देखें:
int *ptr_thing; /* pointer to an integer */ int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1 ; /* pointer to a character */ float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */
पॉइंटर आरंभ करें
पॉइंटर घोषित करने के बाद, हम इसे वैरिएबल एड्रेस के साथ मानक वैरिएबल की तरह आरंभीकृत करते हैं। यदि C प्रोग्रामिंग में पॉइंटर अप्रारंभीकृत हैं और किसी प्रोग्राम में उपयोग किए जाते हैं, तो परिणाम अप्रत्याशित और संभावित रूप से विनाशकारी हो सकते हैं।
किसी चर का पता पाने के लिए, हम एम्परसेंड (&) ऑपरेटर का उपयोग करते हैं, जिसे उस चर के नाम से पहले रखा जाता है जिसका पता हमें चाहिए। पॉइंटर आरंभीकरण निम्नलिखित सिंटैक्स के साथ किया जाता है।
पॉइंटर सिंटैक्स
pointer = &variable;
पॉइंटर चित्रण के लिए एक सरल प्रोग्राम नीचे दिया गया है:
#include <stdio.h> int main() { int a=10; //variable declaration int *p; //pointer variable declaration p=&a; //store address of variable a in pointer p printf("Address stored in a variable p is:%x\n",p); //accessing the address printf("Value stored in a variable p is:%d\n",*p); //accessing the value return 0; }
आउटपुट:
Address stored in a variable p is:60ff08 Value stored in a variable p is:10
Operaटो | अर्थ |
---|---|
* | 2 उद्देश्य पूरे करता है
|
& | केवल 1 उद्देश्य पूरा करता है
|
सी में पॉइंटर्स के प्रकार
निम्नलिखित विभिन्न प्रकार हैं सी में पॉइंटर्स के प्रकार:
नल पॉइंटर
हम पॉइंटर घोषणा के दौरान शून्य मान निर्दिष्ट करके शून्य पॉइंटर बना सकते हैं। यह विधि तब उपयोगी होती है जब आपके पास पॉइंटर को कोई पता निर्दिष्ट नहीं होता है। शून्य पॉइंटर में हमेशा 0 मान होता है।
निम्नलिखित प्रोग्राम शून्य सूचक के उपयोग को दर्शाता है:
#include <stdio.h> int main() { int *p = NULL; //null pointer printf(“The value inside variable p is:\n%x”,p); return 0; }
आउटपुट:
The value inside variable p is: 0
शून्य सूचक
In सी प्रोग्रामिंगशून्य पॉइंटर को जेनेरिक पॉइंटर भी कहा जाता है। इसका कोई मानक डेटा प्रकार नहीं होता है। शून्य पॉइंटर शून्य कीवर्ड का उपयोग करके बनाया जाता है। इसका उपयोग किसी भी चर का पता संग्रहीत करने के लिए किया जा सकता है।
निम्नलिखित प्रोग्राम void पॉइंटर के उपयोग को दर्शाता है:
#include <stdio.h> int main() { void *p = NULL; //void pointer printf("The size of pointer is:%d\n",sizeof(p)); return 0; }
आउटपुट:
The size of pointer is:4
जंगली सूचक
यदि पॉइंटर को किसी भी चीज़ के लिए आरंभीकृत नहीं किया जा रहा है तो उसे वाइल्ड पॉइंटर कहा जाता है। इस प्रकार के C पॉइंटर कुशल नहीं होते हैं क्योंकि वे किसी अज्ञात मेमोरी लोकेशन की ओर इशारा कर सकते हैं जिससे हमारे प्रोग्राम में समस्याएँ आ सकती हैं और इससे प्रोग्राम क्रैश हो सकता है। वाइल्ड पॉइंटर के साथ काम करते समय हमेशा सावधान रहना चाहिए।
निम्नलिखित प्रोग्राम वाइल्ड पॉइंटर के उपयोग को दर्शाता है:
#include <stdio.h> int main() { int *p; //wild pointer printf("\n%d",*p); return 0; }
आउटपुट:
timeout: the monitored command dumped core sh: line 1: 95298 Segmentation fault timeout 10s main
'c' में अन्य प्रकार के पॉइंटर्स इस प्रकार हैं:
- लटकता हुआ सूचक
- जटिल सूचक
- सूचक के पास
- दूर सूचक
- बहुत बड़ा सूचक
प्रत्यक्ष और अप्रत्यक्ष एक्सेस पॉइंटर्स
सी में, किसी चर सामग्री तक पहुंचने और उसमें हेरफेर करने के दो समान तरीके हैं
- प्रत्यक्ष पहुँच: हम सीधे चर नाम का उपयोग करते हैं
- अप्रत्यक्ष पहुँच: हम चर के लिए एक पॉइंटर का उपयोग करते हैं
आइये नीचे दिए गए प्रोग्राम की सहायता से इसे समझते हैं
#include <stdio.h> /* Declare and initialize an int variable */ int var = 1; /* Declare a pointer to int */ int *ptr; int main( void ) { /* Initialize ptr to point to var */ ptr = &var; /* Access var directly and indirectly */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); /* Display the address of var two ways */ printf("\n\nThe address of var = %d", &var); printf("\nThe address of var = %d\n", ptr); /*change the content of var through the pointer*/ *ptr=48; printf("\nIndirect access, var = %d", *ptr); return 0;}
प्रोग्राम को बिना किसी त्रुटि के संकलित करने के बाद, परिणाम यह है:
Direct access, var = 1 Indirect access, var = 1 The address of var = 4202496 The address of var = 4202496 Indirect access, var = 48
सी में पॉइंटर अंकगणित
पॉइंटर ऑपरेशन को निम्नलिखित चित्र में संक्षेपित किया गया है
प्राथमिकता संचालन (प्राथमिकता)
सी पॉइंटर्स के साथ काम करते समय, हमें निम्नलिखित प्राथमिकता नियमों का पालन करना चाहिए:
- ऑपरेटर * और & की प्राथमिकता एकल ऑपरेटर (निषेध!, वृद्धि++, कमी–) के समान है।
- उसी अभिव्यक्ति में, एकल ऑपरेटर *, &,!, ++, – का मूल्यांकन दाएं से बाएं किया जाता है।
यदि P सूचक किसी X चर की ओर संकेत करता है, तो जहाँ भी X लिखा जा सकता है, वहाँ * P का प्रयोग किया जा सकता है।
निम्नलिखित अभिव्यक्तियाँ समतुल्य हैं:
int X =10 int *P = &Y; For the above code, below expressions are true
अभिव्यक्ति | समतुल्य अभिव्यक्ति |
---|---|
वाई=*पी+1
*पी=*पी+10 *पी+=2 ++*पी (*पी)++ |
वाई=एक्स+1
एक्स=एक्स+10 एक्स+=2 ++एक्स एक्स++ |
बाद के मामले में, कोष्ठकों की आवश्यकता होती है: चूंकि एकल ऑपरेटर * और ++ का मूल्यांकन दाएं से बाएं किया जाता है, इसलिए कोष्ठकों के बिना सूचक P में वृद्धि होगी, न कि उस ऑब्जेक्ट में जिस पर P इंगित करता है।
नीचे दी गई तालिका अंकगणितीय और बुनियादी ऑपरेशन दिखाती है जिसका उपयोग सी पॉइंटर्स से निपटने के लिए किया जा सकता है
Operaउत्पादन | व्याख्या |
---|---|
असाइनमेंट | int *P1,*P2 पी1=पी2; P1 और P2 एक ही पूर्णांक चर को इंगित करते हैं |
वृद्धि और ह्रास | इंट *P1; पी1++;पी1– ; |
ऑफसेट जोड़ना (स्थिर) | यह पॉइंटर को तालिका में N तत्वों को स्थानांतरित करने की अनुमति देता है। पॉइंटर को चर के प्रकार के बाइट (बाइट्स) की संख्या से N गुना बढ़ाया या घटाया जाएगा। पी1+5; |
सी पॉइंटर्स और ऐरेज़ उदाहरणों के साथ
परंपरागत रूप से, हम सरणी तत्वों को उसके इंडेक्स का उपयोग करके एक्सेस करते हैं, लेकिन पॉइंटर्स का उपयोग करके इस विधि को समाप्त किया जा सकता है। पॉइंटर्स प्रत्येक सरणी तत्व तक पहुँचना आसान बनाते हैं।
#include <stdio.h> int main() { int a[5]={1,2,3,4,5}; //array initialization int *p; //pointer declaration /*the ptr points to the first element of the array*/ p=a; /*We can also type simply ptr==&a[0] */ printf("Printing the array elements using pointer\n"); for(int i=0;i<5;i++) //loop for traversing array elements { printf("\n%x",*p); //printing array elements p++; //incrementing to the next element, you can also write p=p+1 } return 0; }
आउटपुट:
1 2 3 4 5
पॉइंटर में कोई विशेष संख्या जोड़ने से पॉइंटर स्थान को जोड़ ऑपरेशन द्वारा प्राप्त मान पर ले जाया जाएगा। मान लीजिए कि p एक पॉइंटर है जो वर्तमान में मेमोरी स्थान 0 की ओर इशारा करता है, यदि हम निम्नलिखित जोड़ ऑपरेशन, p+1 करते हैं तो यह इस तरीके से निष्पादित होगा:
चूंकि p वर्तमान में 0 जोड़ने के बाद स्थान 1 की ओर इंगित करता है, इसलिए मान 1 हो जाएगा, और इसलिए सूचक मेमोरी स्थान 1 की ओर इंगित करेगा।
C पॉइंटर्स और स्ट्रिंग्स उदाहरणों के साथ
स्ट्रिंग चार ऑब्जेक्ट्स की एक सरणी है, जो शून्य वर्ण '\ 0' के साथ समाप्त होती है। हम पॉइंटर्स का उपयोग करके स्ट्रिंग्स में हेरफेर कर सकते हैं। C उदाहरण में यह पॉइंटर इस अनुभाग को समझाता है
#include <stdio.h> #include <string.h> int main() { char str[]="Hello Guru99!"; char *p; p=str; printf("First character is:%c\n",*p); p =p+1; printf("Next character is:%c\n",*p); printf("Printing all the characters in a string\n"); p=str; //reset the pointer for(int i=0;i<strlen(str);i++) { printf("%c\n",*p); p++; } return 0; }
आउटपुट:
First character is:H Next character is:e Printing all the characters in a string H e l l o G u r u 9 9 !
स्ट्रिंग्स से निपटने का एक अन्य तरीका पॉइंटर्स की एक सरणी के साथ है, जैसा कि निम्नलिखित प्रोग्राम में है:
#include <stdio.h> int main(){ char *materials[ ] = { "iron", "copper", "gold"}; printf("Please remember these materials :\n"); int i ; for (i = 0; i < 3; i++) { printf("%s\n", materials[ i ]);} return 0;}
आउटपुट:
Please remember these materials: iron copper gold
सी में पॉइंटर्स के लाभ
- पॉइंटर्स मेमोरी स्थानों तक पहुंचने के लिए उपयोगी होते हैं।
- पॉइंटर्स किसी सरणी संरचना के तत्वों तक पहुंचने का एक कुशल तरीका प्रदान करते हैं।
- पॉइंटर्स का उपयोग गतिशील मेमोरी आवंटन के साथ-साथ डी-एलोकेशन के लिए भी किया जाता है।
- पॉइंटर्स का उपयोग जटिल डेटा संरचनाओं जैसे लिंक्ड सूची, ग्राफ, वृक्ष आदि को बनाने के लिए किया जाता है।
सी में पॉइंटर्स के नुकसान
- पॉइंटर्स को समझना थोड़ा जटिल है।
- पॉइंटर्स विभिन्न त्रुटियों को जन्म दे सकते हैं, जैसे सेगमेंटेशन दोष, या किसी मेमोरी स्थान तक पहुंच सकते हैं जिसकी बिल्कुल भी आवश्यकता नहीं है।
- यदि किसी पॉइंटर को गलत मान प्रदान किया जाता है, तो इससे मेमोरी दूषित हो सकती है।
- पॉइंटर्स मेमोरी लीकेज के लिए भी जिम्मेदार होते हैं।
- पॉइंटर्स, वेरिएबल्स की तुलना में अपेक्षाकृत धीमे होते हैं।
- प्रोग्रामर्स को पॉइंटर्स के साथ काम करना बहुत कठिन लगता है; इसलिए पॉइंटर्स को सावधानीपूर्वक संचालित करना प्रोग्रामर की जिम्मेदारी है।
सारांश
- पॉइंटर और कुछ नहीं बल्कि एक मेमोरी स्थान है जहां डेटा संग्रहीत किया जाता है।
- मेमोरी स्थान तक पहुंचने के लिए पॉइंटर का उपयोग किया जाता है।
- पॉइंटर्स के विभिन्न प्रकार होते हैं जैसे नल पॉइंटर, वाइल्ड पॉइंटर, वॉयड पॉइंटर और अन्य प्रकार के पॉइंटर्स।
- तत्वों तक अधिक कुशलता से पहुंचने के लिए पॉइंटर्स का उपयोग ऐरे और स्ट्रिंग के साथ किया जा सकता है।
- हम किसी फ़ंक्शन को गतिशील रूप से लागू करने के लिए फ़ंक्शन पॉइंटर्स बना सकते हैं।
- पॉइंटर पर अंकगणितीय संक्रियाएं की जा सकती हैं जिन्हें पॉइंटर अंकगणित के रूप में जाना जाता है।
- पॉइंटर्स फ़ंक्शन की ओर भी इशारा कर सकते हैं, जिससे पॉइंटर्स की एक सरणी को परिभाषित करने के मामले में विभिन्न फ़ंक्शन को कॉल करना आसान हो जाता है।
- जब आप विभिन्न परिवर्तनीय डेटा प्रकारों से निपटना चाहते हैं, तो आप टाइपकास्ट शून्य पॉइंटर का उपयोग कर सकते हैं।