हेल्लो दोस्तों इस पोस्ट में बताने जा रहा हूँ की c language में पॉइंटर क्या होते है और इसका उपयोग करना क्यों जरुरी है| कहा उपयोग होता है| कहा नहीं! चलिए जान लेते है | पोस्ट को लास्ट तक पढ़े और अपने दोस्तों को भी शेयर करे |
सी में पॉइंटर क्या है?
C में पॉइंटर, एक वेरिएबल है जो दूसरे वेरिएबल के एड्रेस को स्टोर करता है। एक पॉइंटर का उपयोग किसी अन्य पॉइंटर फ़ंक्शन को संदर्भित करने के लिए भी किया जा सकता है। एक पॉइंटर को बढ़ाया/घटाया जा सकता है, यानी अगले/पिछले मेमोरी लोकेशन को इंगित करने के लिए। पॉइंटर का उद्देश्य मेमोरी स्पेस को बचाना और तेजी से निष्पादन (execute) समय प्राप्त करना है। इस पोस्ट में, हम उदाहरणों की मदद से सी प्रोग्रामिंग में पॉइंटर्स पर चर्चा करेंगे।
सी में पॉइंटर्स के बारे में चर्चा करने से पहले, एक वेरिएबल के एड्रेस से हमारा क्या मतलब है यह समझने के लिए एक सरल उदाहरण लेते हैं।
पॉइंटर्स के बिना एक वेरिएबल के एड्रेस तक पहुंचने का तरीका समझने के लिए एक सरल उदाहरण?
इस program में, हमारे पास int type की एक variable num है। Num की value 20 है और यह value स्मृति में कहीं संग्रहीत होना चाहिए, है ना? प्रत्येक वेरिएबल के लिए एक मेमोरी स्पेस allocated किया जाता है जिसमें उस वेरिएबल का value होता है, इस मेमोरी स्पेस का एक पता (address) होता है। उदाहरण के लिए हम एक घर में रहते हैं और हमारे घर का एक पता है, जो अन्य लोगों को हमारा घर खोजने में मदद करता है। उसी तरह वेरिएबल की वैल्यू को मेमोरी एड्रेस में स्टोर किया जाता है, जो सी प्रोग्राम को जरूरत पड़ने पर उस वैल्यू को खोजने में मदद करता है।
तो मान लें कि वेरिएबल num को दिया गया पता (location) 000000000062FE1C है, जिसका अर्थ है कि जो भी वैल्यू हम num को असाइन करेंगे उसे लोकेशन पर स्टोर किया जाना चाहिए: 000000000062FE1C। नीचे दिए गए आरेख को देखें।
Syntax :-
Example :-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> int main() { int num = 20; printf ( "Value of variable num is: %d" , num); /* To print the address of a variable we use %p * format specifier and ampersand (&) sign just * before the variable name like &num. */ printf ( "\nAddress of variable num is: %p" , &num); return 0; } |
Output:-
1 2 3 4 5 | Value of variable num is: 20 Address of variable num is: 000000000062FE1C -------------------------------- Process exited after 0.0277 seconds with return value 0 Press any key to continue . . . |
C . में पॉइंटर्स का एक सरल उदाहरण:-
यह प्रोग्राम दिखाता है कि कैसे एक pointer declared और उपयोग किया जाता है। कई अन्य चीजें हैं जो हम पॉइंटर्स के साथ कर सकते हैं, हमने इस पोस्ट में बाद में उनकी चर्चा की है। अभी के लिए, हमें केवल यह जानने की जरूरत है कि किसी वेरिएबल के पते से पॉइंटर को कैसे लिंक किया जाए।
ये बात भी जानता जरूरी हैं : डेटा टाईप के पॉइंटर और वेरिएबल का मिलान होना चाहिए, एक int pointer, int variable का पता रख सकता है, इसी तरह फ्लोट डेटा टाईप के साथ declared एक पॉइंटर फ्लोट वेरिएबल का पता रख सकता है। नीचे दिए गए उदाहरण में, पॉइंटर और वेरिएबल दोनों ही int types के हैं।
Example :-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> int main() { //Variable declaration int num = 20; //Pointer declaration int *p; //Assigning address of num to the pointer p p = # printf ( "Address of variable num is: %p" , p); return 0; } |
Output:-
1 2 3 4 | Address of variable num is: 000000000062FE1C -------------------------------- Process exited after 0.0277 seconds with return value 0 Press any key to continue . . . |
सी पॉइंटर्स – ऑपरेटर्स जो पॉइंटर्स के साथ उपयोग किए जाते हैं |
जब हम पॉइंटर के साथ काम कर रहे होते हैं, तो हमें निम्नलिखित दो ऑपरेटरों का उपयोग करने की आवश्यकता होती है।
1. (Indirection operator or dereference operator or object at location or value at address)
2. & (address-of operator)
*& (address-of operator): & एक यूनरी ऑपरेटर है। ऑपरेटर का पता हमेशा एक चर का मूल पता देता है। किसी भी वेरिएबल के शुरुआती सेल एड्रेस को बेस एड्रेस कहा जाता है।
* (Indirection operator): Indirection (*) ऑपरेटर एक unary ऑपरेटर है। इसका उपयोग पॉइंटर वेरिएबल बनाने के लिए किया जाता है। Indirection Operator हमेशा किसी पते की value लौटाता है, यानी हम किस पते से गुजर रहे हैं, उस पते से संबंधित value प्राप्त किया जाएगा।
* Declaration of Pointer:
Syntax: Datatype *ptr_name;
Example: int *p;
यहाँ, वेरिएबल से पहले का * चिह्न यह दर्शाता है कि यह एक पॉइंटर वेरिएबल है। डेटाटाइप और variable नाम के बीच अप्रत्यक्ष ऑपरेटरों की आवश्यकता होनी चाहिए। पॉइंटर वेरिएबल के डिक्लेरेशन में जगह देना अनिवार्य नहीं है।
Initialization of Pointer:
Syntax:
Datatype variable;
Datatype *ptr = &variable;
Example:-
void main()
{
int i;
Int * ptr;
}
यहाँ, i integer टाइप का एक variable है और यह एक value टाइप variable है जिसमें हमेशा एक पूर्णांक मान होता है। ptr int* टाइप का एक variable है और यह एक एड्रेस टाइप variable है जिसमें हमेशा एक integer variable पता होता है।
Program Example:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> int main() { int a; printf ( "Enter a Number: " ); scanf ( "%d" , &a); printf ( "Entered Value is %d: " , a); printf ( "\n" ); printf ( "The Address is %d: " , &a); return 0; } |
Output:-
1 2 3 4 5 6 | Enter a Number: 40 Entered Value is 40: The Address is 6487580: -------------------------------- Process exited after 12.37 seconds with return value 0 Press any key to continue . . . |
पॉइंटर का उपयोग दिखाने के लिए उदाहरण:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include<stdio.h> int main () { int a; int *ptr; ptr = &a; a = 10; printf ( "\n %p %p" , &a, ptr); printf ( "\n %d %d" , a, *ptr); *ptr = 20; * printf ( "\n %u %u" , &a, ptr); * printf ( "\n %d %d" , a, *ptr); * return 0; * } |
Output:-
1 2 3 4 5 6 7 | 0x7ffe79938c84 0x7ffe79938c84 10 10 2039712900 2039712900 20 20 -------------------------------- Process exited after 12.37 seconds with return value 0 Press any key to continue . . . |
किसी भी वेरिएबल पर जब हम ऑपरेटर (&) का एड्रेस अप्लाई कर रहे होते हैं तो यह हमेशा बेस एड्रेस यानी शुरुआती सेल लोकेशन को ही कलेक्ट करेगा। पते पर जब हम अप्रत्यक्ष ऑपरेटर (*) लागू कर रहे हैं तो यह उस address का value लौटाता है।
उपरोक्त कार्यक्रम (program) में, ptr में a (&a) का पता होता है, इसलिए ptr और & value समान होते हैं। *ptr हमेशा ऑब्जेक्ट देता है यानी value इसलिए ‘*ptr’ और ‘a’ value समान हैं।
Implementation में जब हम वेरिएबल का address प्रिंट कर रहे हैं तो %x, %p, %u के लिए जाएं। %lu और %lp प्रारूप विनिर्देशक (format specifier)। %x, %p, %lp address को हेक्साडेसिमल प्रारूप में प्रिंट करेगा, और %u, %lu पते को decimal format में प्रिंट करेगा।
नोट: एड्रेस प्रिंट करने के लिए हम %d प्रारूप विनिर्देशक (format specifer) का उपयोग नहीं कर सकते क्योंकि भौतिक पता हेक्साडेसिमल प्रारूप में 0*0000 से 0*ffff की सीमा से दशमलव प्रारूप 0 से 65535 में होगा, इसलिए यह श्रेणी समर्थित नहीं होगी %डी। भौतिक पते में कोई – ve प्रतिनिधित्व उपलब्ध नहीं है लेकिन %d डेटा भी प्रिंट करेगा।
%p और %x . के बीच अंतर दिखाने के लिए उदाहरण:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include<stdio.h> int main () { int a; int *ptr; ptr = &a; a = 11; printf ( "\n %p %p" , &a, ptr); printf ( "\n %d %d" , a, *ptr); *ptr = 22; * printf ( "\n %x %x" , &a, ptr); * printf ( "\n %d %d" , a, *ptr); * return 0; * } |
Output:-
1 2 3 4 5 6 7 | 0x7ffc38989914 0x7ffc38989914 11 11 38989914 38989914 22 22 -------------------------------- Process exited after 12.37 seconds with return value 0 Press any key to continue . . . |
नीचे दिए गए प्रोग्राम में आउटपुट क्या होगा?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include<stdio.h> int main () { int a, b; int *ptr; ptr = &a; a = 10; b = 20; printf ( "\n %d %d %d" , a, b, *ptr); *ptr = 30; *ptr = &b; * *ptr = 40; printf ( "\n %d %d %d" , a, b, *ptr); return 10; } |
Output:- ??
नोट: implementation में जब हमें पॉइंटर लोकेशन को एक वेरिएबल से दूसरे वेरिएबल में बदलने की आवश्यकता होती है, तो पॉइंटर को एड्रेस को फिर से असाइन करके, हम पॉइंटर लोकेशन बदल सकते हैं।
सी भाषा में पॉइंटर के प्रकार:
मेमोरी मैनेजमेंट मॉडल के आधार पर पॉइंटर्स को 3 प्रकारों में वर्गीकृत किया जाता है:
1.Near Pointer
2.Far Pointer
3.Huge Pointer
Near Pointer:
पॉइंटर वेरिएबल जो 1MB डेटा के केवल 1 सेगमेंट को हैंडल कर सकता है, उसे near Pointer कहा जाता है। नियर पॉइंटर डेटा सेगमेंट को छोड़कर किसी अन्य सेगमेंट की ओर इशारा नहीं करता है। near pointer का आकार 2 बाइट्स है। जब हम नियर पॉइंटर वैल्यू को बढ़ा रहे होते हैं तो यह केवल ऑफसेट एड्रेस को बढ़ाता है। जब हम संबंधपरक ऑपरेटरों (relational operators) को near pointer पर लागू कर रहे हैं तो यह केवल ऑफसेट पते की तुलना करता है। डिफ़ॉल्ट रूप से, किसी भी प्रकार का पॉइंटर केवल निकट होता है। जब हम नियर पॉइंटर का उपयोग करके पता प्रिंट कर रहे होते हैं, तो हमें केवल %d या %x या %u प्रारूप विनिर्देशक का उपयोग करने की आवश्यकता होती है। नियर कीवर्ड का उपयोग करके हम पॉइंटर के पास बना सकते हैं।
Far Pointer:
पॉइंटर वेरिएबल जो 1MB डेटा के किसी भी सेगमेंट को हैंडल कर सकता है उसे फ़ार पॉइंटर कहा जाता है। जब हम far pointer के साथ काम कर रहे होते हैं, तो यह 0X0-0XF की सीमा से किसी भी खंड को संभाल सकता है, लेकिन एक समय में केवल एक खंड। far pointer का आकार 4bytes है क्योंकि इसमें खंड और ऑफसेट पता भी होता है। जब हम फार पॉइंटर वैल्यू को बढ़ा रहे होते हैं, तो यह केवल ऑफसेट एड्रेस को बढ़ाता है। जब हम दूर सूचक पर एक संबंधपरक ऑपरेटर लागू कर रहे हैं तो यह ऑफसेट पते के साथ खंड पते की तुलना करता है। जब हम दूर सूचक का उपयोग करके पता प्रिंट कर रहे हैं तो हमें %lp या %lu प्रारूप विनिर्देशक का उपयोग करने की आवश्यकता है। दूर कीवर्ड का उपयोग करके, हम एक दूर सूचक बना सकते हैं।
Huge Pointer:
पॉइंटर वेरिएबल जो 1MB डेटा के किसी भी सेगमेंट को हैंडल कर सकता है, Huge Pointer कहलाता है। जब हम एक Huge Pointer के साथ काम कर रहे होते हैं, तो यह 0X0-0XF की सीमा से किसी भी सेगमेंट को संभाल सकता है, लेकिन एक समय में केवल 1 सेगमेंट। जब हम एक Huge Pointer के साथ काम कर रहे होते हैं, तो यह 4B मेमोरी पर कब्जा कर लेता है क्योंकि इसमें सेगमेंट और ऑफ़सेट एड्रेस भी होता है। जब हम बड़े पॉइंटर वैल्यू को बढ़ा रहे होते हैं, तो यह ऑफसेट एड्रेस के साथ-साथ सेगमेंट एड्रेस को भी बढ़ाता है। जब हम Huge Pointer की तुलना कर रहे हैं, तो यह सामान्यीकरण मूल्य की तुलना करता है। जब हम एक बड़े पॉइंटर का उपयोग करके पता प्रिंट कर रहे होते हैं तो हमें %lp या %lu प्रारूप विनिर्देशक का उपयोग करने की आवश्यकता होती है। विशाल कीवर्ड का उपयोग करके, हम एक विशाल पॉइंटर बना सकते हैं।
सी लैंगेज में पॉइंटर्स का उपयोग करने के क्या फायदे हैं?
1.Data access: C प्रोग्रामिंग लैंग्वेज एक procedure-oriented language है यानी फंक्शन्स का उपयोग करके एप्लिकेशन विकसित किए जाते हैं। एक फ़ंक्शन से दूसरे फ़ंक्शन में, जब हमें डेटा एक्सेस करने की आवश्यकता होती है, तो एक पॉइंटर की आवश्यकता होती है।
2.Memory Management: केवल पॉइंटर्स का उपयोग करके, dynamic memory allocation संभव है यानी हम रनटाइम मेमोरी प्रबंधन को संभाल सकते हैं।
3.Database/ Data structures: पॉइंटर का उपयोग करके हम डेटा संरचना को अधिक कुशलता से संभाल सकते हैं। केवल पॉइंटर्स का उपयोग करके विकसित करने के लिए आवश्यक किसी भी प्रकार की डेटा संरचनाएं, यदि डेटा संरचनाएं उपलब्ध नहीं हैं तो डेटाबेस बनाना संभव नहीं है।
4.Performance: पॉइंटर्स का उपयोग करके, हम प्रोग्राम की execution speed को बढ़ा सकते हैं।
5.एक पॉइंटर का उपयोग करके, हम उस डेटा तक पहुँच सकते हैं जो फ़ंक्शन के बाहर उपलब्ध है।
इस पोस्ट में बस इतना ही हम अगले टॉपिक पर नेक्स्ट पोस्ट में बात करेंगे | आप साथ ही साथ पुरानी पोस्ट भी पढ़ कर अपना अब्यास जारी रख सकते है जिससे आपको c language के आने वाले टॉपिक अच्छे से समझ आयेंगे और आपको c language और भी ज्यादा आसान लगेगी | इसी तरह पढ़ते रहे और इस वेबसाइट को follow जरुर कर ले जिससे हमारी आने वाली पोस्ट आप तक सबसे पहले पहुचे |
धन्यवाद |
[…] What is pointer in C in hindi (सी में पॉइंटर क्या… […]