2008-09-18 18 views
6

मैं कॉलेज से बाहर हूं और कुछ समय से सी ++ में काम कर रहा हूं। मैं सी ++ की सभी मूल बातें समझता हूं और उनका उपयोग करता हूं, लेकिन मुझे पॉइंटर्स और कक्षाओं जैसे अधिक उन्नत विषयों को समझने में कठिनाई हो रही है। मैंने कुछ किताबें और ट्यूटोरियल पढ़े हैं और मैं उन में उदाहरणों को समझता हूं, लेकिन फिर जब मैं कुछ उन्नत वास्तविक जीवन उदाहरणों को देखता हूं तो मैं उन्हें समझ नहीं सकता। यह मुझे मार रहा है क्योंकि मुझे लगता है कि यह मुझे अपने सी ++ प्रोग्रामिंग को अगले स्तर पर लाने से रोकता है। क्या किसी और को यह समस्या है? यदि हां, तो आपने इसे कैसे तोड़ दिया? क्या किसी को किसी पुस्तक या ट्यूटोरियल के बारे में पता है जो वास्तव में पॉइंटर्स और कक्षा अवधारणाओं का वर्णन करता है? या शायद उन्नत पॉइंटर्स और कक्षा तकनीकों का उपयोग कर अच्छी वर्णनात्मक टिप्पणियों के साथ कुछ उदाहरण कोड? किसी भी मदद की सराहना की जाएगी।सी ++ में मैं पॉइंटर्स और कक्षाओं को समझ नहीं सकता

+0

जिज्ञासा से, कॉलेज में रहते हुए आपने किन भाषाओं को सीखा? शुद्ध कार्यात्मक भाषाओं के अलावा मैं ऐसी किसी भी भाषा के बारे में नहीं सोच सकता जिसके पास पॉइंटर्स या कक्षाएं नहीं हैं। –

+9

एफवाईआई, पॉइंटर्स और कक्षाएं सी ++ की मूल बातें हैं। – Wedge

+0

पीएस सी ++ एक बहुत समृद्ध और व्यापक भाषा है। यदि आप उन्नत उदाहरणों को समझ नहीं सकते हैं जिसका अर्थ यह नहीं है कि आप कुछ खो रहे हैं ("उन्नत" सी ++ खरगोश छेद बहुत गहरा हो जाता है)। यदि आप हालांकि अधिक विशिष्ट जानकारी प्रदान करते हैं तो इससे मदद मिलेगी। – Wedge

उत्तर

0

एक पॉइंटर का बहाना एक सरणी पता है।

x = 500; // memory address for hello; 
MEMORY[x] = "hello"; 
print MEMORY[x]; 

अपने एक ग्राफिक अति सरलीकरण है, लेकिन सबसे अधिक भाग के रूप में लंबे समय आप जानते हैं कि उस नंबर है या हाथ से यह सेट तुम ठीक किया जाना चाहिए करना चाहते हैं कभी नहीं के रूप में करने के लिए।

वापस जब मुझे सी समझ में आया तो मेरे पास कुछ मैक्रोज़ थे, जिनके पास आपको स्मृति में एक सरणी अनुक्रमणिका जैसे पॉइंटर्स का उपयोग करने की अनुमति दी गई थी। लेकिन जब से मैं उस कोड को खो देता हूं और लंबे समय से भूल गया हूं।

मैं इसे

#define MEMORY 0; 
#define MEMORYADDRESS(a) *a; 

के साथ शुरू किया और कहा कि अपने दम पर शायद ही उपयोगी है याद। उम्मीद है कि कोई और उस तर्क पर विस्तार कर सकता है।

+0

मुझे लगता है कि यह एक बहुत ही उपयोगी excersize है। बहुत सारे एम्बेडेड सिस्टम में बिल्ली में मेरे पास आवंटित चीजों के लिए पॉइंटर नहीं था, मेरे पास एक सरणी अनुक्रमणिका थी :)। –

+0

आप में से उन लोगों के लिए जो इस पोस्ट के लिए मुझे नीचे दबा रहे हैं, यह काम करता है। मैंने इसका इस्तेमाल किया, मैंने इसके साथ दूसरों की मदद की। तथ्य यह है कि ओएस आपके लिए यह सब कुछ बताता है व्यायाम के लिए महत्वहीन है। –

+0

हाँ मैं इसे समझ में नहीं आता, मुझे लगता है कि यह पॉइंटर्स को समझने का एक शानदार तरीका है। तीर पॉइंटर्स, आईएमओ की तुलना में आसान समझते हैं, इसलिए मुझे लगता है कि यह एक महान प्रारंभिक बिंदु है .. –

1

सूचकों के लिए:

मैंने पाया this post संकेत के बारे में बहुत विचारशील चर्चा की थी। शायद वह मदद करेगा। क्या आप सी # में जैसे रिफ्रेंस के साथ familar हैं? ऐसा कुछ है जो वास्तव में को किसी और चीज़ से संदर्भित करता है? पॉइंटर्स को समझने के लिए शायद एक अच्छी शुरुआत है।

इसके अलावा, पॉइंटर्स को पेश करने के लिए एक और तरीके से केंट फ्रेड्रिक की पोस्ट को नीचे देखें।

4

मुझे पास्कल रास्ते में पॉइंटर्स को समझने में समस्या होती थी :) एक बार जब मैं एंबलर पॉइंटर्स करना शुरू कर देता था तो वास्तव में स्मृति तक पहुंचने का एकमात्र तरीका था और यह मुझे बस मारता था। यह एक बहुत ही शॉट की तरह लग सकता है, लेकिन असेंबलर की कोशिश कर रहा है (जो हमेशा कंप्यूटर के बारे में वास्तव में कोशिश करने और समझने का एक अच्छा विचार है) शायद आपको पॉइंटर्स सिखाएंगे। कक्षाएं - अच्छी तरह से मैं आपकी समस्या को समझ नहीं पा रहा हूं - क्या आपकी स्कूली शिक्षा शुद्ध संरचित प्रोग्रामिंग थी? एक वर्ग वास्तविक जीवन मॉडल को देखने का एक तार्किक तरीका है - आप ऐसी समस्या को हल करने की कोशिश कर रहे हैं जिसे कई वस्तुओं/वर्गों में समझा जा सकता है।

1

पॉइंटर्स को समझने के लिए, मैं K&R पुस्तक को अत्यधिक अनुशंसा नहीं कर सकता।

0

ब्रूस एकल द्वारा सी ++ में इन विषयों पर मैंने जो सबसे अच्छी पुस्तक पढ़ी है, वह है। आप इसे मुफ्त here पर डाउनलोड कर सकते हैं।

+0

धन्यवाद डाउनलोड की गई पुस्तक कई उदाहरणों के साथ आता है – timmyg

3

पॉइंटर्स और कक्षाएं पूरी तरह से अलग-अलग विषय हैं इसलिए मैं वास्तव में उन्हें इस तरह एक साथ नहीं जोड़ूंगा। दोनों में से, मैं कहूंगा कि पॉइंटर्स अधिक मौलिक हैं।

क्या संकेत दिए गए हैं के बारे में सीखने के लिए एक अच्छा व्यायाम है निम्नलिखित:

  1. एक लिंक्ड सूची खत्म करने के लिए
  2. यह रिवर्स शुरू से ही इसके माध्यम से
  3. पुनरावृति बनाने ताकि सिर अब वापस आ गया है और पीठ अब सिर

इसे सब एक व्हाइटबोर्ड पर पहले करें। यदि आप इसे आसानी से कर सकते हैं, तो आपको पॉइंटर्स समझने में कोई और समस्या नहीं होनी चाहिए।

7

This link में एक वीडियो है जो वर्णन करता है कि पॉइंटर्स क्लेमेशन के साथ कैसे काम करते हैं। जानकारीपूर्ण, और पचाने में आसान है।

This page कक्षाओं के मूलभूत पर कुछ अच्छी जानकारी है।

+1

मिट्टी के साथ कुछ भी मेरी पुस्तक में +1 हो जाता है। – Aardvark

18

पॉइंटर्स और कक्षाएं सी ++ में वास्तव में उन्नत विषय नहीं हैं। वे बहुत मौलिक हैं।

मेरे लिए, जब मैंने तीरों के साथ बक्से खींचना शुरू किया तो पॉइंटर्स ठोस हो गए। एक int के लिए एक बॉक्स ड्रा। और int * अब एक अलग बॉक्स है जो int बॉक्स को इंगित करने वाले तीर के साथ है।

तो:

int foo = 3;   // integer 
int* bar = &foo;  // assigns the address of foo to my pointer bar 

मेरी सूचक का पिटारा (बार) के साथ मैं या तो बॉक्स के अंदर पता को देखने का विकल्प नहीं है। (Foo का स्मृति पता कौन सा है)। या मैं जो कुछ भी पता कर सकता हूं उसका उपयोग कर सकता हूं। उस हेरफेर का मतलब है कि मैं उस तीर को पूर्णांक (foo) पर चला रहा हूं।

*bar = 5; // asterix means "dereference" (follow the arrow), foo is now 5 
bar = 0; // I just changed the address that bar points to 

कक्षाएं पूरी तरह से एक और विषय हैं। ऑब्जेक्ट ओरिएंटेड डिज़ाइन पर कुछ किताबें हैं, लेकिन मुझे अपने सिर के शीर्ष के शुरुआती लोगों के लिए अच्छा नहीं पता है। आपको एक परिचय जावा पुस्तक के साथ भाग्य हो सकता है।

+0

अच्छी तरह से वे मेरे लिए उन्नत विषय हैं, हाहा, मैं यहां आपके उदाहरणों को समझता हूं, लेकिन फिर जब मैं किसी और के कोड को समझने की कोशिश करता हूं तो मैं इसे समझ नहीं सकता ... शायद मुझे और अनुभव चाहिए ... उत्तर के लिए धन्यवाद। – timmyg

+0

मैं इसे दूसरा करता हूं। शुरुआती लोगों के लिए, हमेशा एक कार चलाने की तरह, 'पॉइंटर' को 'पता' और 'dereference' से 'ट्रैवल-टू-द-एड्रेस' में अनुवाद करें। पॉइंटर्स-टू-पॉइंटर्स पीओ-बक्से अग्रेषित कर रहे हैं - पते, कि जब आप वहां जाते हैं, तो आपको स्टोरेज स्थान के बजाय एक और पता मिलता है। – Aaron

+1

यह अच्छी तरह से हो सकता है कि उस कोड का अधिकतर बहुत अच्छी तरह लिखा नहीं गया है। मैंने एक बार काम करने की कोशिश करने में काफी समय बिताया कि कुछ पॉइंटर-भारी कोड कैसे काम करते हैं। मैंने छोड़ दिया और एक वरिष्ठ से पूछा। उसने इसे 2 सेकंड तक देखा और कहा "हू। यह एक दुर्घटना का कारण बन जाएगा। बेहतर इसे ठीक करें।" अनुभव: एक नमूना देखने की क्षमता, इसे कुछ विचित्र करें, और सोचें कि "मेरे साथ कुछ गड़बड़ है" के बजाय "इसमें कुछ गड़बड़ है"। – deworde

0

कक्षाओं के लिए:

जब मैं इंटरफेस के बारे में सीखा मेरे लिए breakthru क्षण था। आपने जिस समस्या को हल किया है, उसके बारे में ब्योरा देने का विचार, और कक्षा के साथ बातचीत करने वाली विधियों की एक सूची देना बहुत अंतर्दृष्टिपूर्ण था।

वास्तव में, मेरे प्रोफेसर ने स्पष्ट रूप से हमें बताया कि वह हमारे वर्गों को अपने परीक्षण दोहन में जोड़कर हमारे कार्यक्रमों को ग्रेड करेगा। ग्रेडिंग हमें दी गई आवश्यकताओं के आधार पर की जाएगी और क्या कार्यक्रम क्रैश हो गया है।

लंबी कहानी संक्षेप में, कक्षाओं आप कार्यक्षमता लपेट और एक क्लीनर ढंग से इसे कहते (ज्यादातर समय, वहाँ हमेशा अपवाद हैं)

+0

"परीक्षण दोहन" क्या है? – DarenW

+0

एक परीक्षण दोहन कोड है जो कोड का एक और सेट व्यायाम करता है। मेरे प्रोफेसर के मूल रूप से एक मुख्य कार्यक्रम था जिसे हमारी कक्षा में कार्य कहा जाता था। वह परीक्षा चलाएगा, ग्रेड चिह्नित करेगा, अपनी फाइल हटा देगा, और अगले छात्रों को अपने समाधान में फाइल करेगा और पूरी प्रक्रिया दोहराएगा। –

0

किताब कि डोनाल्ड Alcock द्वारा मेरे लिए संकेत फटा था Illustrating Ansi C करते हैं। इसके हाथों से बनाए गए शैली बॉक्स और तीर आरेख कि संकेत दिए गए उदाहरण देकर स्पष्ट करना, सूचक अंकगणित, सरणियों, स्ट्रिंग कार्यों आदि का पूरा ...

जाहिर है इसकी एक 'सी' किताब लेकिन कोर बुनियादी बातों के लिए अपने कठिन

0

हरा इन अवधारणाओं को समझने में वास्तव में मेरी मदद करने वाली चीजों में से एक यूएमएल - एकीकृत मॉडलिंग भाषा सीखना है। एक ग्राफिकल प्रारूप में ऑब्जेक्ट उन्मुख डिजाइन की अवधारणाओं को देखकर वास्तव में मुझे यह जानने में मदद मिली कि उनका क्या मतलब है। कभी-कभी इन अवधारणाओं को समझने की कोशिश कर रहे हैं कि स्रोत कोड लागू करने के लिए उन्हें समझना मुश्किल हो सकता है।

ग्राफिकल रूप में विरासत की तरह वस्तु-उन्मुख प्रतिमानों को देखना अवधारणा को समझने का एक बहुत ही शक्तिशाली तरीका है।

मार्टिन फाउलर का यूएमएल डिस्टिल्ड एक अच्छा, संक्षिप्त परिचय है।

0

एक similar question on SO को lassevek की प्रतिक्रिया से:

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

मैं पाया है कि सबसे अच्छा सादृश्य को उस पर एक घर के पते के साथ कागज के एक टुकड़े के रूप में सूचक मानते हैं, और स्मृति ब्लॉक यह वास्तविक घर के रूप में संदर्भ देता है। संचालन सभी प्रकार के इस तरह आसानी से किया जा सकता है के बारे में बताया:

  • कॉपी सूचक मूल्य, बस पता कागज का एक नया टुकड़ा पर
  • लिंक्ड सूचियों कागज का टुकड़ा घर में अगले के पते के साथ लिखते हैं, घर यह
  • स्मृति मुक्त पर, घर का पता
  • मेमोरी रिसाव ध्वस्त और मिटाने की, आप कागज का टुकड़ा खो देते हैं और घर
  • स्मृति मुक्त लेकिन एक (अब अमान्य) संदर्भ रखने नहीं मिल रहा है, ध्वस्त घर, पेपर के टुकड़ों में से एक को मिटा दें, लेकिन पर उस पते पर पुराने पते के साथ कागज का दूसरा टुकड़ा है, जब आप पते पर जाएं, तो आपको घर नहीं मिलेगा, लेकिन आपको कुछ मिल सकता है जो दिखता है एक
  • बफर सीमा से अधिक के खंडहर, आप घर में और अधिक सामान ले जाने से आपको संभवतः फिट, पड़ोसियों घर में फैलने
0

बेहतर संकेत समझने के लिए, मुझे लगता है, यह उपयोगी हो सकते हैं यह देखने के लिए कि असेंबली भाषा पॉइंटर्स के साथ कैसे काम करती है। पॉइंटर्स की अवधारणा वास्तव में असेंबली भाषा और x86 प्रोसेसर निर्देश वास्तुकला के मौलिक भागों में से एक है। शायद यह आपको तरह की तरह गिरने देगा जैसे पॉइंटर्स एक कार्यक्रम का एक प्राकृतिक हिस्सा हैं।

कक्षाओं के रूप में, ओओ प्रतिमान से अलग मुझे लगता है कि निम्न स्तर के बाइनरी परिप्रेक्ष्य से कक्षाओं को देखना दिलचस्प हो सकता है। वे मूल स्तर पर इस संबंध में जटिल नहीं हैं।

यदि आप सी ++ ऑब्जेक्ट मॉडल के नीचे क्या है, तो बेहतर समझना चाहते हैं तो आप Inside the C++ Object Model पढ़ सकते हैं।

2

पॉइंटर्स को अन्य उत्तरों में पहले ही संबोधित किया जा सकता है (कोई इरादा नहीं है)।

कक्षाएं ओओ के लिए मौलिक हैं। मुझे ओओ में अपने सिर को तोड़ने में जबरदस्त परेशानी थी - जैसे दस साल के असफल प्रयास। जिस पुस्तक ने आखिरकार मेरी मदद की वह क्रेग लार्मन की "यूएमएल और पैटर्न लागू करना" था। मुझे पता है कि ऐसा लगता है जैसे यह कुछ अलग है, लेकिन यह वास्तव में कक्षाओं और वस्तुओं की दुनिया में आपको आसान बनाने का एक अच्छा काम करता है।

2

हम सिर्फ दोपहर के भोजन पर सी ++ और ओओ के कुछ पहलुओं पर चर्चा कर रहे थे, कोई (वास्तव में एक महान इंजीनियर) कह रहा था कि जब तक आप सी ++ सीखने से पहले वास्तव में एक मजबूत प्रोग्रामिंग पृष्ठभूमि नहीं रखते हैं, तो यह सचमुच आपको बर्बाद कर देगा।

मैं अत्यधिक पहले एक और भाषा सीखने की सलाह देता हूं, फिर जब आपको इसकी आवश्यकता होती है तो सी ++ में स्थानांतरित हो जाती है। ऐसा नहीं है कि पॉइंटर्स के बारे में कुछ भी बढ़िया है, वे केवल एक वेस्टिगियल टुकड़ा हैं जब एक कंपाइलर ऑपरेशन को उनके बिना कुशलता से असेंबली में परिवर्तित करना मुश्किल था।

इन दिनों यदि कोई कंपाइलर एक सरणी ऑपरेशन को बेहतर ढंग से अनुकूलित नहीं कर सकता है तो आप पॉइंटर्स का उपयोग कर सकते हैं, आपका कंपाइलर टूटा हुआ है।

कृपया मुझे गलत मत समझो, मैं नहीं कह रहा हूं कि सी ++ भयानक है या कुछ भी है और वकालत की चर्चा शुरू नहीं करना चाहता, मैंने इसका इस्तेमाल किया है और इसे कभी-कभी उपयोग कर रहा हूं, मैं बस आपको सलाह दे रहा हूं कुछ और के साथ शुरू करो।

यह वास्तव में एक मैन्युअल कार चलाने के लिए सीखना पसंद नहीं है, तो आसानी से इसे स्वचालित रूप से लागू करने में सक्षम होने के नाते, यह उन विशाल निर्माण क्रेनों में से एक पर ड्राइव करना सीखने की तरह है, यह मानते हुए कि जब आप कार ड्राइव करना शुरू करेंगे तो लागू होगा - फिर आप अपने आपातकालीन रोशनी के साथ 5 मीटर प्रति घंटे सड़क पर सड़क के बीच अपनी गाड़ी चलाते हैं।

[पिछला अनुच्छेद) की समीक्षा [संपादित करें] - मुझे लगता है कि शायद मेरा सबसे सटीक सादृश्य हो सकता है!

+0

कोई भी भाषा जो आप पहले सीखने के लिए सुझाव देते हैं? क्या पाइथन अच्छा विकल्प होगा? मैं वर्तमान में PHP और सी ++ सीखने की कोशिश कर रहा हूं, सिंटैक्स के अनुसार वे बहुत समान हैं। – timmyg

+0

सी # और जावा अच्छे हैं क्योंकि वे संकलित समय की जांच और ईमानदारी से हैं कि यह वास्तव में अच्छी आदत है। यदि आप बस मूर्ख बनाना चाहते हैं, तो पाइथन अच्छा है। यदि आप एक वेबसाइट कर रहे हैं, रूबी ऑन रेल्स - अवधि। –

+0

ओह, और यदि आप वास्तव में रक्तस्राव एज प्रोग्रामिंग अवधारणाओं को सीखना चाहते हैं, तो स्कैला को देखें। ईमानदारी से यह उन सभी अवधारणाओं के कारण सबसे अच्छा हो सकता है जो आपको सही तरीके से उजागर करते हैं। हास्कल और लिस्प भी अच्छी प्रोग्रामिंग अवधारणाओं को पढ़ाने के लिए जाने जाते हैं। –

1

असेंबली भाषा सीखें और फिर सी सीखें। फिर आपको पता चलेगा कि मशीन के अंतर्निहित सिद्धांत क्या हैं (और फिर संकेतक)।

पॉइंटर्स और कक्षाएं सी ++ के मौलिक पहलू हैं। यदि आप उन्हें समझ नहीं पाते हैं तो इसका मतलब है कि आप वास्तव में सी ++ को नहीं समझते हैं।

व्यक्तिगत रूप से मैंने कई वर्षों तक सी ++ पर वापस रखा जब तक मुझे लगा कि मुझे सी की दृढ़ समझ है और असेंबली भाषा में हुड के तहत क्या हो रहा था। हालांकि यह काफी समय पहले था, मुझे लगता है कि यह समझने के लिए कि यह कंप्यूटर निम्न स्तर पर कैसे काम करता है, यह वास्तव में मेरे करियर को लाभान्वित हुआ।

प्रोग्राम सीखना कई सालों लग सकता है, लेकिन आपको इसके साथ रहना चाहिए क्योंकि यह एक बहुत ही पुरस्कृत करियर है।

0

कक्षाएं समझने के लिए अपेक्षाकृत आसान हैं; ओओपी आपको कई सालों ले सकता है। निजी तौर पर, मैंने पिछले साल तक आईओपी को पूरी तरह से समझ नहीं लिया था। यह बहुत बुरा है कि छोटे-छोटे कॉलेजों में उतना व्यापक नहीं है जितना होना चाहिए। यह वास्तव में घर को इस बिंदु पर चलाता है कि ओओपी वस्तुओं के व्यापार संदेशों के बारे में है, बजाय वर्गों के कार्यों के साथ आत्मनिर्भर वैश्विक चर है।

यदि आप वास्तव में कक्षाओं के लिए नए हैं, तो अवधारणा को समझने में कुछ समय लग सकता है। जब मैंने पहली बार 10 वीं कक्षा में उनका सामना किया, तो मुझे तब तक यह नहीं मिला जब तक कि मेरे पास कोई ऐसा व्यक्ति न हो जो जानता था कि वे कोड के माध्यम से क्या कर रहे थे और बता रहे थे कि क्या हो रहा था। यही सुझाव है कि आप सुझाव देते हैं कि आप कोशिश करें।

1

अभ्यास के लिए कोई विकल्प नहीं है।

पुस्तक के माध्यम से पढ़ना या व्याख्यान सुनना आसान है और ऐसा लगता है कि आप क्या चल रहे हैं इसका पालन कर रहे हैं।

मैं जो कुछ अनुशंसा करता हूं वह कुछ उदाहरण उदाहरण ले रहा है (मुझे लगता है कि आप उन्हें डिस्क पर कहीं भी लेते हैं), उन्हें संकलित करें और उन्हें चलाएं, फिर उन्हें कुछ अलग करने के लिए बदलने का प्रयास करें।

  • एक पदानुक्रम
  • के लिए एक और उपवर्ग जोड़ें एक मौजूदा वर्ग
  • बदलें एक एल्गोरिथ्म है कि आगे iterates एक संग्रह के माध्यम से पीछे जाने के लिए बजाय करने के लिए एक विधि जोड़ें।

मुझे नहीं लगता कि वहां कोई "चांदी बुलेट" पुस्तक है जो इसे करने जा रही है।

मेरे लिए, घर पर क्या चल रहा था, जो संकेतक असेंबली में काम कर रहा था, और यह देखते हुए कि एक सूचक वास्तव में सिर्फ एक पता था, और यह कि पॉइंटर होने का मतलब यह नहीं था कि यह एक सार्थक वस्तु थी।

0

जिस बिंदु पर मुझे वास्तव में पॉइंटर्स मिलते थे, वह फ़ैटमैक (लगभग 1 9 84 या उससे भी कम) पर टर्बोपास्कल को कोड कर रहा था - जो उस समय मूल मैक भाषा थी।

मैक में एक अजीब मेमोरी मॉडल था, जिससे पता लगाया गया था कि स्मृति को ढेर पर एक सूचक में संग्रहीत किया गया था, लेकिन उस स्थान का स्वयं की गारंटी नहीं थी और इसके बजाय मेमोरी हैंडलिंग रूटीन पॉइंटर को पॉइंटर में लौटा दी गई - संदर्भित एक हैंडल के रूप में। नतीजतन आवंटित स्मृति के किसी भी हिस्से तक पहुंचने के लिए इसे दो बार संभाल को हटाना आवश्यक था। इसमें थोड़ी देर लग गई, लेकिन निरंतर अभ्यास ने अंततः पाठ घर चलाया।

पास्कल का पॉइंटर हैंडलिंग सी ++ से समझना आसान है, जहां सिंटैक्स शुरुआत करने में मदद नहीं करता है। यदि आप वास्तव में और सचमुच सी में समझने वाले पॉइंटर्स फंस गए हैं तो आपका सबसे अच्छा विकल्प कॉपी ए पास्कल कंपाइलर प्राप्त करना और इसमें कुछ मूल सूचक कोड लिखने का प्रयास करना चाहिए (पास्कल सी के पास पर्याप्त है, आपको कुछ घंटों में मूल बातें मिलेंगी)। लिंक्ड सूचियां और पसंद एक अच्छी पसंद होगी। एक बार जब आप उन लोगों के साथ सहज महसूस कर सकें जो सी ++ पर वापस आते हैं और अवधारणाओं के साथ आपको पता चलेगा कि चट्टान इतनी खड़ी नहीं दिखाई देगी।

0

एक अर्थ में, आप "पॉइंटर्स" को सॉफ़्टवेयर में दो सबसे मौलिक प्रकारों में से एक मान सकते हैं - दूसरा "मूल्य" (या "डेटा") - जो विशिष्ट रूप से संबोधित स्मृति के विशाल ब्लॉक में मौजूद है स्थानों। इसके बारे में सोचो। ऑब्जेक्ट्स और स्ट्रक्चर इत्यादि वास्तव में स्मृति में मौजूद नहीं हैं, केवल मूल्य और पॉइंटर्स करते हैं। वास्तव में, एक सूचक भी एक मान है .... एक स्मृति पते का मूल्य, जो बदले में एक और मूल्य है .... और इसी तरह।

तो, सी/सी ++ में, जब आप "int" (intA) घोषित करते हैं, तो आप एक 32 बिट खंड की स्मृति को परिभाषित कर रहे हैं जिसमें एक मान - संख्या है। यदि आप एक "int सूचक" (intB) घोषित करते हैं, तो आप एक 32 बिट खंड की स्मृति को परिभाषित कर रहे हैं जिसमें एक int का पता होता है। मैं बाद वाले को "intB = & intA" बताकर पूर्व को इंगित करने के लिए असाइन कर सकता हूं, और अब intB के रूप में परिभाषित स्मृति की 32 बिट्स में स्मृति में intA के स्थान से संबंधित एक पता होता है।

जब आप इंट्यूब पॉइंटर को "अव्यवस्था" करते हैं, तो आप इंट्यूब की स्मृति में संग्रहीत पते को देख रहे हैं, उस स्थान को ढूंढ रहे हैं, और फिर वहां संग्रहीत मूल्य को देख रहे हैं (एक संख्या)।

आम तौर पर, मुझे भ्रम का सामना करना पड़ता है जब लोग "", "*" और "->" ऑपरेटरों का उपयोग करते हैं, तो वे वास्तव में क्या ट्रैक कर रहे हैं - यह एक पता, मूल्य या क्या? आपको केवल इस तथ्य पर ध्यान केंद्रित करने की आवश्यकता है कि स्मृति पते केवल स्थान हैं, और यह मान वहां संग्रहीत बाइनरी जानकारी हैं।

0

क्या आपने Bjarne Stroustrup के सी ++ प्रोग्रामिंग भाषा पढ़ा था? उन्होंने सी ++ बनाया।

सी ++ एफएक्यू लाइट भी अच्छा है।

0

पॉइंटर्स और कक्षाओं के लिए, यहां मेरा सादृश्य है। मैं कार्ड के डेक का उपयोग करूंगा। कार्ड के डेक में चेहरे का मूल्य होता है और एक प्रकार (9 दिल, 4 हुकुम के इत्यादि)।

HeartCard card = 4; // 4 of hearts! 

अब, तुम्हें पता है, जहां दिल के 4 है, क्योंकि गोली से, आप डेक रोक रखी है, का सामना: तो हमारे सी ++ "कार्ड के डेक" की प्रोग्रामिंग भाषा की तरह में हम निम्नलिखित कहूँगा अपने हाथ में, और यह शीर्ष पर है! तो बाकी कार्डों के संबंध में, हम केवल यह कहेंगे कि 4 दिल दिल में हैं। इसलिए, अगर मैंने आपको पूछा कि कौन सा कार्ड शुरू हो रहा है, तो आप कहेंगे, "निश्चित रूप से दिल के 4!"। खैर, आपने मुझे "इंगित किया" जहां कार्ड है। हमारे "कार्ड के डेक" प्रोग्रामिंग भाषा में, आप बस के रूप में अच्छी निम्नलिखित कह सकते हैं:

HeartCard card = 4; // 4 of hearts! 
print &card // the address is BEGINNING! 

अब, अधिक ताश के पत्तों की अपने डेक बदल जाते हैं। पिछली तरफ अब शुरू हो रहा है और आप नहीं जानते कि कार्ड क्या है। लेकिन, मान लें कि आप इसे जो कुछ भी चाहते हैं उसे बना सकते हैं क्योंकि आप जादू से भरे हुए हैं। आइए हम अपने "डेक ऑफ कार्ड्स" लैंगेज में ऐसा करते हैं!

HeartCard *pointerToCard = MakeMyCard("10 of hearts"); 
print pointerToCard // the value of this is BEGINNING! 
print *pointerToCard // this will be 10 of hearts! 

खैर, MakeMyCard ("दिल की 10") आप अपने जादू कर रहे हैं और जानते हुए भी कि आप शुरू करने के लिए बात करने के लिए चाहता था, कार्ड दिलों की एक 10 बनाने था! आप अपना कार्ड बदलते हैं और वॉयला! अब, * आपको फेंक सकता है। HeartCard के रूप में एक प्रकार परिभाषित करते हुए

HeartCard *pointerToCard = MakeMyCard("10 of hearts"); 
HeartCard card = 4; // 4 of hearts! 
print *pointerToCard; // prints 10 of hearts 
print pointerToCard; // prints BEGINNING 
print card; // prints 4 of hearts 
print &card; // prints END - the 4 of hearts used to be on top but we flipped over the deck! 

कक्षाओं के लिए के रूप में, हम उदाहरण में वर्गों का उपयोग किया गया है: यदि हां, तो इस पर गौर करें। हम जानते हैं कि हार्टकार्ड क्या है ... यह एक मूल्य और दिल के प्रकार वाला कार्ड है! इसलिए, हमने इसे हार्टकार्ड के रूप में वर्गीकृत किया है। प्रत्येक भाषा में आप जो चाहते हैं उसे परिभाषित करने या "वर्गीकृत" करने का एक समान तरीका है, लेकिन वे सभी एक ही अवधारणा साझा करते हैं! उम्मीद है कि यह मदद की ...

+0

वह एक काफी हंसमुख समानता थी। – FlySwat

0

आपको यह article by Joel निर्देशक मिल सकता है। एक तरफ, यदि आप "कुछ समय के लिए सी ++ में काम कर रहे हैं" और सीएस में स्नातक की उपाधि प्राप्त की है, तो आप जावास्कूल में जा सकते हैं (मैं तर्क दूंगा कि आप सी ++ में बिल्कुल काम नहीं कर रहे हैं; आपके पास है सी में काम कर रहा है लेकिन सी ++ कंपाइलर का उपयोग कर रहा है)।

इसके अलावा, होजौ और एनएसैंडर्स के जवाबों के अलावा, पॉइंटर्स सी ++ के लिए बहुत मौलिक हैं। यदि आप पॉइंटर्स को नहीं समझते हैं, तो आप सी ++ की मूल बातें समझ नहीं पाते हैं (इस तथ्य को स्वीकार करना सी ++ को समझने की शुरुआत है)। इसी तरह, यदि आप कक्षाओं को नहीं समझते हैं, तो आप सी ++ (या उस मामले के लिए ओओ) की मूल बातें नहीं समझते हैं।

पॉइंटर्स के लिए, मुझे लगता है कि बक्से के साथ ड्राइंग एक अच्छा विचार है, लेकिन असेंबली में काम करना भी एक अच्छा विचार है। रिश्तेदार पते का उपयोग करने वाले कोई भी निर्देश आपको समझने के लिए समझेंगे कि कौन से पॉइंटर्स अपेक्षाकृत जल्दी हैं, मुझे लगता है।

कक्षाओं (और ऑब्जेक्ट उन्मुख प्रोग्रामिंग अधिक आम तौर पर) के रूप में, मैं स्ट्रॉस्ट्रप्स "द सी ++ प्रोग्रामिंग भाषा" नवीनतम संस्करण की अनुशंसा करता हूं। न केवल यह कैनोलिक सी ++ संदर्भ सामग्री है, बल्कि मूल ऑब्जेक्ट उन्मुख वर्ग पदानुक्रमों और विरासत से बड़ी प्रणालियों में सिद्धांतों को डिजाइन करने के लिए सभी अन्य चीजों पर भी बहुत सारी सामग्री है। यह एक बहुत अच्छा पढ़ा है (अगर थोड़ा मोटी नहीं है और धब्बे में terse)। सी में

+0

लॉल, मैंने जोएल द्वारा उस लेख को पढ़ा और यही कारण है कि मुझे यहां आ गया और पॉइंटर्स के बारे में प्रश्नों की खोज की। – Spidey

18

समझना प्वाइंटर/C++

से पहले एक समझ सकते हैं कैसे संकेत दिए गए काम है, यह समझने के लिए कि चर संग्रहीत और कार्यक्रमों में पहुंचा जा सकता है आवश्यक है। प्रत्येक चर के पास 2 भाग होते हैं - (1) स्मृति पता जहां डेटा संग्रहीत किया जाता है और (2) संग्रहीत डेटा का मान।

स्मृति पता अक्सर एक चर के अंतराल के रूप में जाना जाता है, और संग्रहीत डेटा के मूल्य को रावल्यू (एल और आर अर्थ बाएं और दाएं) के रूप में जाना जाता है।

बयान पर विचार करें:

int x = 10; 

आंतरिक रूप से, कार्यक्रम के साथ चर x एक स्मृति पता एकत्रित करती है। इस मामले में, मान लीजिए कि कार्यक्रम x को पते 1001 (यथार्थवादी पता नहीं, बल्कि सादगी के लिए चुना गया) पर रहने के लिए निर्दिष्ट करता है। इसलिए, x का lvalue (स्मृति पता) x1 है, और x का रावल (डेटा मान) 10.

रैल्यू को केवल "x" चर का उपयोग करके एक्सेस किया जाता है। लालू तक पहुंचने के लिए, "पता" ऑपरेटर ('&') की आवश्यकता है। अभिव्यक्ति '& x' को "एक्स का पता" के रूप में पढ़ा जाता है।

Expression   Value 
---------------------------------- 
x     10 
&x     1001 

एक्स में संग्रहीत मूल्य किसी भी समय बदला जा सकता है (उदाहरण के लिए एक्स = 20), लेकिन एक्स (& एक्स) की पता बदल गया कभी नहीं किया जा सकता।

एक सूचक केवल एक चर है जिसका उपयोग किसी अन्य चर को संशोधित करने के लिए किया जा सकता है। यह इसके रावल्यू के लिए स्मृति पता रखते हुए करता है। यही है, यह स्मृति में एक और स्थान को इंगित करता है।

एक सूचक बनाना "x" इस प्रकार से किया जाता है करने के लिए:

int* xptr = &x; 

"int *" संकलक है कि हम एक पूर्णांक मूल्य के लिए सूचक पैदा कर रहे बताता है। "= & x" भाग संकलक को बताता है कि हम xptr के rvalue को x का पता निर्दिष्ट कर रहे हैं। इस प्रकार, हम संकलक को बता रहे हैं कि xptr "इंगित करता है" x।

यह मानते हुए कि xptr 1002 एक स्मृति पता करने के लिए सौंपा है, तो कार्यक्रम की स्मृति इस प्रकार दिखाई देंगे:

Variable lvalue rvalue 
-------------------------------------------- 
x   1001  10 
xptr  1002  1001 

पहेली के अगले टुकड़ा "अविवेक ऑपरेटर" ('*') है, जो इस प्रकार प्रयोग किया जाता है:

int y = *xptr; 

अविवेक ऑपरेटर समस्या के लिए डेटा मूल्य एक स्मृति पते के बजाय xptr की rvalue व्याख्या करने के लिए कहता है। यही है, कार्यक्रम xptr (1001) द्वारा दिए गए पते पर संग्रहीत डेटा मान (10) की तलाश करता है।

यह सबको एक साथ रखें:

int x = 10; 
int *xptr = &x; 

printf("x = %d\n", x); 
printf("&x = %d\n", &x);   
printf("xptr = %d\n", xptr); 
printf("*xptr = %d\n", *xptr); 

*xptr = 20; 

printf("x = %d\n", x); 
printf("*xptr = %d\n", *xptr); 

उत्पादन के लिए आप देखना होगा (नोट:

Expression  Value 
-------------------------------------------- 
x     10 
&x     1001 
xptr    1001 
&xptr    1002 
*xptr    10 

अब जब कि अवधारणाओं स्पष्ट किया गया है, यहाँ संकेत की शक्ति को प्रदर्शित करने के लिए कुछ कोड है: स्मृति पता हर बार अलग होगा):

x = 10 
&x = 3537176 
xptr = 3537176 
*xptr = 10 
x = 20 
*xptr = 20 

ध्यान दें कि कैसे एवी '* xptr' के कारण 'x' का मान बदल गया। ऐसा इसलिए है क्योंकि '* xptr' और 'x' स्मृति में उसी स्थान का संदर्भ लेते हैं, जैसा कि '& x' और 'xptr' द्वारा प्रमाणित किया गया है।

+0

बहुत उपयोगी प्रतिक्रिया – timmyg

+0

के लिए धन्यवाद lvalues ​​और rvalues ​​को स्मृति पते के साथ कुछ भी नहीं मिला। – Puppy

0

पॉइंटर्स कुछ प्रकार की जादुई चीजें नहीं हैं, आप उन्हें हर समय उपयोग कर रहे हैं!
जब आप कहते हैं:

int a;

और संकलक 'ए' के ​​लिए भंडारण उत्पन्न करता है, तो आप व्यावहारिक रूप से कह रहे हैं कि आप
एक int घोषित कर रहे हैं और आप इसकी स्मृति स्थान 'ए' नाम देना चाहते हैं।

आप जब कहते हैं:

पूर्णांक * एक;

आप एक चर घोषित कर रहे हैं जो एक int के स्मृति स्थान को पकड़ सकता है। यह इतना आसान है। साथ ही, पॉइंटर अंकगणित के बारे में डरो मत, हमेशा को "मेमोरी मैप" दिमाग में ध्यान दें जब आप पॉइंटर्स से बात कर रहे हों और मेमोरी पतों के माध्यम से चलने के मामले में सोचें।

सी ++ में कक्षाएं सार डेटा प्रकारों को परिभाषित करने का एक ही तरीका हैं। मैं अवधारणा को समझने के लिए एक अच्छी ओओपी पुस्तक पढ़ने का सुझाव दूंगा, फिर, यदि आप रुचि रखते हैं, तो सीखें कि सी ++ कंपाइलर्स ओओपी अनुकरण करने के लिए कोड कैसे उत्पन्न करते हैं। लेकिन यह ज्ञान समय पर आ जाएगा, यदि आप सी ++ के साथ काफी लंबे समय तक चिपके रहते हैं :)

0

आपकी समस्या सी ++ में सी कोर है, सी ++ स्वयं नहीं। अपने आप को Kernighan & रिची (सी प्रोग्रामिंग भाषा) प्राप्त करें। इसे श्वास लें यह बहुत अच्छी चीजें है, जो कभी भी लिखी जाने वाली सर्वश्रेष्ठ प्रोग्रामिंग भाषा पुस्तकों में से एक है।

1

कक्षाओं के मामले में मेरे पास तीन तकनीकें थीं जो वास्तव में मुझे वास्तविक ऑब्जेक्ट उन्मुख प्रोग्रामिंग में कूदने में मदद करती थीं।

पहला मैंने एक गेम प्रोजेक्ट पर काम किया था जिसने सामान्यीकरण के भारी उपयोग के साथ कक्षाओं और वस्तुओं का भारी उपयोग किया था (उदाहरण के लिए या एक रिश्ते, पूर्व छात्र एक प्रकार का व्यक्ति है) और रचना (है - एक रिश्ते, पूर्व छात्र के छात्र ऋण है)। इस कोड को तोड़ने से बहुत सारे काम हुए, लेकिन वास्तव में चीजों को परिप्रेक्ष्य में लाया।

दूसरी चीज जिसने मेरी सिस्टम विश्लेषण कक्षा में मदद की थी, जहां मुझे http://www.agilemodeling.com/artifacts/classDiagram.htm">UML क्लास आरेख बनाना था। इन्हें वास्तव में मुझे समझने में मदद मिली एक कार्यक्रम में कक्षाओं की संरचना।

आखिरकार, मैं प्रोग्रामिंग में अपने कॉलेज में शिक्षक छात्रों की सहायता करता हूं। मैं वास्तव में इस बारे में कह सकता हूं कि आप सिखाकर और किसी समस्या के लिए अन्य लोगों के दृष्टिकोण को देखकर बहुत कुछ सीखते हैं। कई बार एक छात्र उन चीजों को आजमाएगा जिनके बारे में मैंने कभी सोचा नहीं होगा, लेकिन आम तौर पर बहुत समझदारी होती है और उन्हें सिर्फ उनके विचार को लागू करने में समस्याएं होती हैं।

मेरी सलाह का सबसे अच्छा शब्द यह है कि यह बहुत अभ्यास करता है, जितना अधिक आप प्रोग्राम बेहतर करेंगे उतना ही आप इसे समझेंगे।

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