दिलचस्प पोस्ट
PHP में cURL का उपयोग करने के लिए प्रतिक्रिया कैसे प्राप्त करें बिटबाकेट को धक्का जाने के बाद एटलसियन "लोगो" हैशटैग के लिए फेसबुक एपीआई खोज कैसे Firebase एंड्रॉइड से सभी बच्चे की सूची प्राप्त करने के लिए क्या बिट-शिफ्ट एंडियननेस पर निर्भर है? क्यों लोगों को कोड डालते हैं जैसे "1 फेंकें; json प्रतिक्रियाओं के सामने "बुरा मत बनो" और "के लिए (;;);" कौन सा HTTP विधि किस सीआरयूडी विधियों से मेल खाते हैं? एकाधिक फ़ाइलों के भीतर ग्लोबल वैरिएबल स्कैनर बनाम स्ट्रिंगटोकनाइज़र बनाम स्ट्रिंग। स्प्लिट वेब-आईएनएफ के तहत संसाधनों को आगे बढ़ाना अनक्यूट टाइप एरर: में 'लंबाई' के लिए 'ऑपरेटर' का प्रयोग नहीं कर सकता PDO :: प्रकार दशमलव के लिए PARAM? emberjs – रूटर इन्फ्रास्ट्रक्चर का उपयोग करके सक्रिय मेनू आइटम को कैसे चिह्नित करना है AngularJS: $ q -> आस्थगित एपीआई चीजों के आदेश (जीवन चक्र) और जो डाइजेक्ट को आमंत्रित करता है? मैं निर्दिष्ट POST पैरामीटर के साथ एंड्रॉइड ब्राउज़र कैसे खोल सकता / सकती हूं?

सूचक अंकगणित

क्या पॉइंटर अंकगणित के लिए किसी भी अच्छे लेख या स्पष्टीकरण (ब्लॉग, उदाहरण) हैं? चित्रा को दर्शाने के लिए जावा प्रोग्रामर का एक समूह C और C ++ सीख रहा है

Solutions Collecting From Web of "सूचक अंकगणित"

सबसे पहले, बंकी वीडियो मदद कर सकता है यह पॉइंटर्स के बारे में एक अच्छा वीडियो है अंकगणित के लिए, यहां एक उदाहरण है:

int * pa = NULL; int * pb = NULL; pa += 1; // pa++. behind the scenes, add sizeof(int) bytes assert((pa - pb) == 1); print_out(pa); // possibly outputs 0x4 print_out(pb); // possibly outputs 0x0 (if NULL is actually bit-wise 0x0) 

(ध्यान दें कि एक सूचक सूचक जो कि एक शून्य सूचक मूल्य को सख्ती से बढ़ाता है, वह अनिर्धारित व्यवहार है। हम नल का इस्तेमाल करते हैं क्योंकि हम केवल सूचक के मूल्य में दिलचस्पी रखते थे। आम तौर पर, केवल एक सरणी के तत्वों की ओर इशारा करते हुए / कमी का उपयोग करें)।

निम्नलिखित दो महत्वपूर्ण अवधारणाओं को दर्शाता है

  • सूचक के लिए एक पूर्णांक के अलावा / घटाव का मतलब है एन तत्वों द्वारा पॉइंट को आगे / पीछे ले जाना। इसलिए यदि कोई इंट 4 बाइट्स बड़ा है, तो हमारे प्लेटफॉर्म पर 1×4 बढ़ाकर 1 से बढ़ेगा।
  • एक अन्य संकेतक द्वारा पॉइंटर का घटाव का अर्थ है उनकी दूरी, तत्वों द्वारा मापा जाता है। इसलिए, पीए से पीसी घटाकर 1 मिलेगा, क्योंकि उनके पास एक तत्व दूरी है।

एक व्यावहारिक उदाहरण पर मान लीजिए कि आप एक फ़ंक्शन लिखते हैं और लोगों को आपको प्रारंभ और समाप्ति सूचक (सी ++ में बहुत ही सामान्य चीज) प्रदान करते हैं:

 void mutate_them(int *begin, int *end) { // get the amount of elements ptrdiff_t n = end - begin; // allocate space for n elements to do something... // then iterate. increment begin until it hits end while(begin != end) { // do something begin++; } } 

ptrdiff_t है (अंत – शुरू) का प्रकार क्या है यह कुछ कंपाइलर के लिए "इंट" के लिए एक पर्याय है, लेकिन हो सकता है कि वह दूसरे एक के लिए दूसरा प्रकार हो। कोई नहीं जान सकता है, इसलिए एक सामान्य typedef ptrdiff_t चुनता है

यहां पर मुझे पॉइंटर्स सिखाए गए हैं: http://www.cplusplus.com/doc/tutorial/pointers.html

संकेतक समझने के बाद, पॉइंटर अंकगणित आसान है। इसके और नियमित अंकगणितीय के बीच एकमात्र अंतर यह है कि जो अंक आप सूचक में जोड़ रहे हैं वह उस प्रकार के आकार से गुणा किया जाएगा जो संकेतक इंगित कर रहा है। उदाहरण के लिए, यदि आपके पास कोई (pointer_to_int + 4) लिए एक पॉइंटर है और int का आकार 4 बाइट्स है, (pointer_to_int + 4) ) आगे मेमोरी एड्रेस 16 बाइट्स (4 (pointer_to_int + 4) का मूल्यांकन करेगा।

तो जब आप लिखते हैं

 (a_pointer + a_number) 

सूचक अंकगणितीय में, वास्तव में क्या हो रहा है

 (a_pointer + (a_number * sizeof(*a_pointer))) 

नियमित अंकगणित में

एनएलपी आवेदन करना, इसे अंकगणित को संबोधित कर दें। 'पॉइंटर्स' का डर है और गलत समझा जाता है क्योंकि वे गलत तरीके से गलत तरीके से और गलत तरीके से गलत तरीके से सिखाए जाते हैं। यह कोई आश्चर्य नहीं कि कोई भी 'इसे' नहीं मिल रहा है

जब अध्यापकों को पढ़ाते हैं, संकाय "पी के लिए एक सूचक होता है, पी का मान एक का पता होता है" और इसी प्रकार यह सिर्फ काम अभ्यस्त यहां आपके साथ कच्चे माल का निर्माण करना है इसके साथ अभ्यास करें और आपके छात्रों को यह मिलेगा।

'इंट ए', एक पूर्णांक है, यह पूर्णांक प्रकार मूल्यों को स्टोर करता है। 'इंट * पी', पी एक 'इंट स्टार' है, यह 'इंट स्टार' प्रकार के मूल्यों को स्टोर करता है।

'ए' है कि आप 'क्या' पूर्णांक में संग्रहीत करते हैं ('के मूल्य' का उपयोग न करने की कोशिश करें) 'ए' और यह है कि आप 'कहाँ' खुद को जमा करते हैं ('पता' कहने की कोशिश करें)

इसके लिए काम करने के लिए 'बी = ए', दोनों पक्ष एक ही प्रकार के होते हैं। यदि कोई int है, बी एक int को संग्रहित करने में सक्षम होना चाहिए। (इसलिए ______ बी, रिक्त 'इंट' से भर जाता है)

'p = & a' इसके लिए काम करने के लिए, दोनों पक्ष एक ही प्रकार का होना चाहिए। यदि कोई एक पूर्णांक है, और एक एक पता है, पी पूर्णांक के पते को स्टोर करने में सक्षम होना चाहिए। (इसलिए ______ पी, रिक्त 'int *' से भरा हुआ है)

अब प्रकार टाइप जानकारी लाने के लिए अलग-अलग int * p लिखें:

int * | पी

'पी' क्या है? ans: यह 'int *' है इसलिए 'पी' एक पूर्णांक का एक पता है

int | * p

'पी' क्या है? ans: यह एक 'इंट' है इसलिए '* p' एक पूर्णांक है

अब पता अंकगणित पर:

int a; एक = 1; एक = एक + 1;

हम 'a = a + 1' में क्या कर रहे हैं? इसे 'अगले' के रूप में सोचें क्योंकि कोई एक संख्या है, यह 'अगली संख्या' कहने की तरह है चूंकि 1 के पास है, कह रहा है कि 'अगला' 2 इसे बना देगा

// भ्रामक उदाहरण आपको चेतावनी दी गई है!!! int * p int a; पी = & ए; पी = पी + 1;

हम 'पी = पी + 1' में क्या कर रहे हैं? यह अभी भी 'अगले' कह रहा है इस बार, पी संख्या नहीं है लेकिन एक पता है। तो हम जो कह रहे हैं वह 'अगला पता' है अगला पता डेटा प्रकार पर निर्भर करता है, विशेष रूप से डेटा प्रकार के आकार पर।

printf ("% d% d% d", आकारफ (वर्ण), आकार (int), आकार (फ्लोट));

इसलिए एक पते के लिए 'अगली' sizeof (डेटा प्रकार) आगे बढ़ेंगे

यह मेरे लिए और उन सभी लोगों के लिए काम किया है जो मैं सिखाना था

मैं सूचक अंकगणित का एक अच्छा उदाहरण निम्न स्ट्रिंग लंबाई फ़ंक्शन पर विचार करता हूँ:

 int length(char *s) { char *str = s; while(*str++); return str - s; } 

इसलिए, याद रखने वाली चाबी यह है कि एक सूचक केवल एक शब्द-आकार की चर है जो कि dereferencing के लिए टाइप किया गया है। इसका अर्थ है कि क्या यह शून्य है *, int *, लंबे समय तक **, यह अभी भी एक शब्द आकार का चर है इन प्रकारों के बीच का अंतर है कि कंपाइलर dereferenced प्रकार को समझता है। बस स्पष्ट करने के लिए, शब्द आकार का मतलब वर्चुअल पते की चौड़ाई है। यदि आपको नहीं पता कि इसका क्या अर्थ है, बस 64-बिट मशीन पर ध्यान दें, संकेतक 8 बाइट्स हैं, और 32-बिट मशीन पर, पॉइंटर्स 4 बाइट्स हैं। एक बिंदु की अवधारणा को समझने के संकेतों में महत्वपूर्ण है। एक पता स्मृति में विशिष्ट स्थान की पहचान करने में सक्षम एक संख्या है। स्मृति में सब कुछ एक पता है हमारे उद्देश्यों के लिए, हम यह कह सकते हैं कि हर चर में एक पता है। यह जरूरी हमेशा सही नहीं है, लेकिन कंपाइलर हमें यह मान देता है। पता ही बाइट ग्रैन्यूलर है, जिसका अर्थ 0x0000000 स्मृति की शुरुआत को निर्दिष्ट करता है, और 0x00000001 स्मृति में एक बाइट है। इसका मतलब है कि एक को एक पॉइंटर जोड़कर, हम एक बाइट को आगे मेमोरी में ले जा रहे हैं। अब, सरणियों को ले जाओ। यदि आप अरेंज प्रकार के quux को बनाते हैं जो कि 32 तत्वों का बड़ा है, तो यह आवंटन की शुरुआत से, यह आवंटन की शुरुआत से 32 * आकार (quux) की अवधि तक होगा, क्योंकि सरणी के प्रत्येक कक्ष आकार (quux) बड़ा है इसलिए, वास्तव में जब हम सरणी [ए] के साथ एक सरणी के तत्व को निर्दिष्ट करते हैं, तो यह सिर्फ * (सरणी + आकार का (क्विन) * n) के लिए वाक्यविन्यास चीनी (शॉर्टहैंड) है। पॉइंटर अंकगणित वास्तव में केवल उस पते को बदल रहा है जिसे आप जिक्र कर रहे हैं, यही कारण है कि हम साथ strlen को लागू कर सकते हैं

 while(*n++ != '\0'){ len++; } 

चूंकि हम सिर्फ स्कैनिंग कर रहे हैं, बाइट बाय बाइट जब तक हम शून्य नहीं मारते उम्मीद है की वो मदद करदे!

इसके निपटने के कई तरीके हैं

सहज ज्ञान युक्त दृष्टिकोण, जो कि सबसे C / C ++ प्रोग्रामर के बारे में सोचते हैं, वह संकेतक स्मृति पते हैं। लिटब के उदाहरण इस दृष्टिकोण को लेते हैं यदि आपके पास एक रिक्त सूचक (जो अधिकतर मशीनों को पता 0 से मेल खाती है) है, और आप एक इंट के आकार को जोड़ते हैं, तो आपको पता 4 मिलता है। यह दर्शाता है कि पॉइंटर्स मूल रूप से सिर्फ फैंसी इंटिजर्स हैं

दुर्भाग्य से, इसके साथ कुछ समस्याएं हैं। शुरू करने के लिए, यह काम नहीं कर सकता किसी नल सूचक को वास्तव में पता 0 का उपयोग करने की गारंटी नहीं है। (यद्यपि एक सूचक को निरंतर 0 असाइन करने पर शून्य सूचक उत्पन्न होता है)

इसके अलावा, आपको शून्य सूचक को बढ़ने की इजाजत नहीं है, या अधिक सामान्यतः, सूचक को हमेशा आवंटित स्मृति (या एक तत्व अतीत), या विशेष नल सूचक स्थिरांक को इंगित करना चाहिए।

इसलिए इसके बारे में सोचने का एक और सही तरीका यह है कि पॉइंटर्स केवल इटेटेटर हैं जो आपको आवंटित स्मृति पर पुनरावृत्त करने की इजाजत देता है। यह वास्तव में एसटीएल इटरेटर के पीछे प्रमुख विचारों में से एक है। वे बहुत ज्यादा संकेतक के रूप में व्यवहार करने के लिए तैयार किए जाते हैं, और ऐसे विशेषज्ञों को प्रदान करने के लिए होते हैं जो कच्चे पॉइंटर्स को उचित इटेरेटर के रूप में काम करने के लिए तैयार करते हैं।

उदाहरण के लिए, यहां दिए गए एक अधिक विस्तृत विवरण दिया गया है ।

लेकिन बाद के दृश्य का मतलब है कि आपको वास्तव में एसटीएल इटरेटर समझा जाना चाहिए, और फिर बस कहना है कि पॉइंटर्स इन विशेष मामलों का है आप बफर में अगले तत्व को इंगित करने के लिए एक सूचक को std::vector<int>::iterator सकते हैं, जैसे कि आप std::vector<int>::iterator । यह किसी तत्व को किसी सरणी के अंत में इंगित कर सकता है, जैसे किसी अन्य कंटेनर के अंत इटरेटर की तरह। आप दो बिंदुओं को घटा सकते हैं जो एक ही बफर में इंगित करते हैं, उन दोनों के बीच तत्वों की संख्या प्राप्त करने के लिए, जैसे कि आप तेरेटर के साथ कर सकते हैं, और बस इटरेटर की तरह, यदि पॉइंटर्स अलग बफ़र्स में इंगित करते हैं, तो आप उन्हें तुलना नहीं कर सकते। (एक व्यावहारिक उदाहरण के लिए क्यों नहीं, विचार करें कि खंडित मेमोरी स्पेस में क्या होता है। दो बिंदुओं के बीच की दूरी क्या अलग खंडों की ओर इशारा करती है?)

वास्तव में व्यवहार में, सीपीयू पते और सी / सी + + पॉइंटर्स के बीच बहुत निकट संबंध होता है लेकिन वे वास्तव में एक ही बात नहीं हैं संकेतक के पास कुछ सीमाएं हैं जो आपके सीपीयू पर कड़ाई से जरूरी नहीं हो सकती हैं।

बेशक, अधिकांश सी ++ प्रोग्रामर पहले समझने से उलझन में हैं, भले ही यह तकनीकी रूप से गलत है। यह आम तौर पर काफी करीब होता है कि आपका कोड कैसे बर्ताव करता है कि लोगों को लगता है कि वे इसे प्राप्त करते हैं, और आगे बढ़ें

लेकिन किसी के लिए जावा से आ रहा है, और सिर्फ स्क्रैच से पॉइंटर्स के बारे में सीखना, बाद का स्पष्टीकरण उतना आसानी से समझा जा सकता है, और बाद में उन्हें कम आश्चर्यचकित करने जा रहे हैं

यह पॉइंटर अंकगणित के बारे में यहां लिंक पर बहुत अच्छा है

उदाहरण के लिए:

पॉइंटर और सरणी

पीटीआर + आई के पते की गणना करने के लिए फार्मूला जहां पीटीआर का प्रकार टी * है तो पता के लिए सूत्र है:

एड्रर (पीटीआर + आई) = एडर (पीटीआर) + [साइज़फ (टी) * आई]

32bit प्लेटफार्म पर इंट के प्रकार के लिए, एडिट (पीटीआर + आई) = एडर (पीटीआर) + 4 * आई;

घटाव

हम पीटीआर-आई भी गणना कर सकते हैं। उदाहरण के लिए, मान लीजिए कि हमारे पास एआरएआर नामक एक पूर्ण सरणी है इंट एआरआर [10]; int * p1, * p2;

 p1 = arr + 3 ; // p1 == & arr[ 3 ] p2 = p1 - 2 ; // p1 == & arr[ 1 ]