2017-06-03 10 views
6

आपको पॉइंटर्स के लिए एक प्रकार क्यों सेट करना है? क्या वे सिर्फ पते और उन सभी पते के लिए प्लेसहोल्डर नहीं हैं? इसलिए, सभी पॉइंटर्स कोई फर्क नहीं पड़ता कि निर्दिष्ट प्रकार किस प्रकार निर्दिष्ट स्मृति के बराबर है?आपको पॉइंटर्स के लिए एक प्रकार निर्दिष्ट क्यों करना है?

+5

कंपाइलर (और कोडर पढ़ने वाले प्रोग्रामर और अधिक महत्वपूर्ण रूप से) जानते हैं कि पॉइंटर वास्तव में क्या इंगित कर रहा है? –

+1

इसके अलावा, आप पॉइंटर्स और उनके आकार को गलत समझते हैं। जबकि वहां (पुराने) प्लेटफार्म हैं जहां विभिन्न प्रकार के पॉइंटर्स हो सकते हैं और संभवतः विभिन्न मात्रा में स्थान ले सकते हैं। इन दिनों एक सूचक मूल रूप से केवल एक हस्ताक्षरित 32 या 64 बिट पूर्णांक होता है जिसका मूल्य वह बिंदु है जो इंगित कर रहा है, इसलिए वास्तव में पॉइंटर्स * स्वयं * मेमोरी के समान आकार पर कब्जा करते हैं "। –

उत्तर

11

आपको पॉइंटर्स के लिए एक प्रकार निर्दिष्ट करने की आवश्यकता नहीं है। आप हर जगह void* का उपयोग कर सकते हैं, जो आपको प्रत्येक बार जब आप पॉइंटर द्वारा इंगित पते से कुछ पढ़ते हैं, या उस पते पर कुछ लिखते हैं, या बस वृद्धि/कमी या पॉइंटर के मूल्य में हेरफेर करते हैं तो एक स्पष्ट प्रकार का कलाकार डालने के लिए मजबूर करेंगे ।

लेकिन लोग एक लंबे समय पहले तय किया कि वे प्रोग्रामिंग के इस तरह के थक गए थे, और वरीय टाइप किया संकेत दिए गए कि

  • डाले
  • हमेशा के आकार का पता करने के लिए की आवश्यकता नहीं है की आवश्यकता नहीं है इशारा प्रकार (जो एक मुद्दा है जो उचित स्मृति संरेखण को ध्यान में रखे जाने पर और भी जटिल हो जाता है)
  • आपको गलत डेटा प्रकार को गलती से एक्सेस करने या बाइट्स की गलत संख्या से पॉइंटर को आगे बढ़ाने से रोकता है।

और हाँ, वास्तव में, सभी डेटा संकेत दिए गए, कोई बात नहीं क्या उनके प्रकार, स्मृति की एक ही राशि है, जो आमतौर पर 32-बिट सिस्टम पर 4 बाइट, और 64-बिट सिस्टम पर 8 बाइट्स पर कब्जा। डेटा पॉइंटर के प्रकार में पॉइंटर द्वारा कब्जा कर लिया गया स्मृति की मात्रा से कोई लेना देना नहीं है, और ऐसा इसलिए है क्योंकि पॉइंटर के साथ कोई भी प्रकार की जानकारी संग्रहीत नहीं होती है; सूचक प्रकार केवल मनुष्यों और कंपाइलर के लिए उपयोगी है, मशीन के लिए नहीं।

+0

धन्यवाद, यह अब और अधिक समझ में आता है। हालांकि, मुझे आपके लिए एक प्रश्न मिला: यदि मैंने इस सूचक 'शून्य * सूचक' घोषित किया है, तो इसका प्रकार 'शून्य *' या 'शून्य' होगा? –

+0

और क्या आप पॉइंटर ** के ** ** को भी निर्दिष्ट कर रहे हैं? या आप निर्दिष्ट कर रहे हैं कि यह किस प्रकार इंगित करेगा? यदि आप ** ** सूचक के प्रकार को निर्दिष्ट नहीं कर रहे हैं, तो आप फिर क्यों कह सकते हैं कि सूचक का प्रकार एक विशिष्ट प्रकार है? –

+1

'शून्य * सूचक 'के मामले में, चर का प्रकार' शून्य * है, क्योंकि यह एक सूचक है, और जिस प्रकार से यह इंगित करता है वह' शून्य 'है। (यह '* सूचक 'का प्रकार है।) इसलिए, जब हम कहते हैं कि हम सूचक का प्रकार निर्दिष्ट करते हैं, तो हम" पॉइंटिंग "खाते में लेते हैं। जब हम कहते हैं "एक इंट पॉइंटर" या "int के लिए पॉइंटर" का अर्थ है "टाइप 'int *' "का एक चर, यानी एक पॉइंटर जो' int' टाइप करने के लिए इंगित करता है। –

1

विभिन्न प्रकार मेमोरी की अलग-अलग मात्रा लेते हैं। तो जब एक सूचक (जैसे सरणी में) को आगे बढ़ाते हैं, तो हमें प्रकार के आकार को ध्यान में रखना होगा। उदाहरण के लिए, क्योंकि एक char केवल एक बाइट लेता है, अगले तत्व पर जाने का मतलब है पते पर 0x01 जोड़ना। लेकिन चूंकि एक int 4 बाइट्स (कई आर्किटेक्चर पर) लेता है, इसलिए अगले तत्व को प्राप्त करने के लिए पॉइंटर में संग्रहीत पते पर 0x04 जोड़ना आवश्यक है। अब, हमारे पास एक एकल सूचक प्रकार हो सकता है जो बिना किसी प्रकार की जानकारी के पते का वर्णन करता है (वास्तव में, यह शून्य है * के लिए है), लेकिन फिर हर बार जब हम इसे बढ़ाना या घटाना चाहते थे, तो हमें उसे देना होगा प्रकार का आकार भी। यहाँ सूचना के लिए

#include <stdlib.h> 
typedef void* pointer; 
int main(void) { 
    pointer numbers = calloc(10, sizeof(int)); 
    int i; 
    for (i = 0; i < 10; i++) 
     *(int*)(numbers + i * sizeof(int)) = i; 
     /* this could have been simply "numbers[i] = i;" */ 
    /* ... */ 
    return 0; 
} 

तीन महत्वपूर्ण बातों:

यहाँ कुछ असली सी कोड है जो दर्द को दर्शाता है आप के माध्यम से जाना करेंगे

  • हम (int) sizeof द्वारा सूचकांक गुणा करने के लिए है हर बार; जोड़कर मैं बस नहीं करूँगा: पहला पुनरावृत्ति पहले 4-बाइट पूर्णांक तक सही ढंग से पहुंच जाएगा, लेकिन दूसरा पुनरावृत्ति पूर्णांक की तलाश करेगा जो पहले पूर्णांक के दूसरे बाइट से शुरू होता है, तीसरा प्रारंभ होगा पहले पूर्णांक का तीसरा बाइट, और चालू। यह बहुत ही असंभव है कि यह वांछनीय है!
  • कंपाइलर को पता होना चाहिए कि यह पॉइंटर में कितनी जानकारी संग्रहीत कर सकता है जब पता इंगित करता है।उदाहरण के लिए, यदि आप चार में 2^8 से अधिक संख्या को स्टोर करने का प्रयास करते हैं, तो कंपाइलर को संख्या को छोटा करने के लिए पता होना चाहिए और अगले कुछ मेमोरी बाइट्स को ओवरराइट नहीं करना चाहिए, जो अगले पृष्ठ में बढ़ सकता है (जिसके कारण सेगमेंटेशन गलती) या, बदतर, अपने प्रोग्राम में अन्य डेटा स्टोर करने के लिए उपयोग किया जा सकता है, जिसके परिणामस्वरूप सूक्ष्म बग होता है।
  • चौड़ाई की बात करते हुए, हम ऊपर दिए गए हमारे कार्यक्रम में जानते हैं कि संख्या इनट्स स्टोर करती है - क्या होगा यदि हमने नहीं किया? क्या होगा, उदाहरण के लिए, हमने एक बड़े डेटा प्रकार (कुछ आर्किटेक्चर पर) की एक सरणी की ओर इशारा करते हुए पते में int स्टोर करने का प्रयास किया, जैसे लंबे समय तक? फिर हमारे जेनेरिक फ़ंक्शंस को दोनों प्रकार की चौड़ाई की तुलना करने के लिए समाप्त कर सकते हैं, शायद का उपयोग करके दो में से कम से कम, और फिर यदि संग्रहीत किया जा रहा प्रकार से छोटा है तो इसके कंटेनर को सुनिश्चित करने के लिए आप अंतहीनता के बारे में चिंता करना शुरू कर दें आप कंटेनर के सही छोर से संग्रहीत मूल्य को संरेखित करते हैं।
संबंधित मुद्दे

 संबंधित मुद्दे