संकेत को समझने और उन्हें क्या दूर करने के लिए किया जा सकता है के लिए बाधाओं को क्या हैं?

वोट
443

क्यों संकेत भ्रम के इस तरह के एक प्रमुख कारक कई नए के लिए यहां तक ​​कि पुराने, सी या सी ++ में कॉलेज स्तर के छात्रों के हैं, और? वहाँ किसी भी उपकरण या विचार प्रक्रिया है कि आप को समझने में मदद कैसे संकेत चर, समारोह में काम करते हैं, और स्तर से परे हैं?

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

08/08/2008 को 07:17
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


28 जवाब

वोट
28

क्यों संकेत भ्रम के इस तरह के एक प्रमुख कारक कई नए के लिए यहां तक ​​कि पुराने, C / C ++ भाषा में कॉलेज स्तर के छात्रों के हैं, और?

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

वहाँ किसी भी उपकरण या विचार प्रक्रिया है कि आप को समझने में मदद कैसे संकेत चर, समारोह में काम करते हैं, और स्तर से परे हैं?

बक्से संबोधित करते हैं। मुझे याद है जब मैं माइक्रो-कंप्यूटरों में मूल कार्यक्रम के लिए तैयार कर रही थी, वहाँ उन में खेल के साथ इन सुंदर किताबें थीं, और कभी कभी आप विशेष पतों में मूल्यों प्रहार किया था। वे बक्से का एक समूह की एक तस्वीर, संवर्द्धित 0, 1, 2 के साथ लेबल किया था ... और यह स्पष्ट किया गया था कि केवल एक छोटी बात है (बाइट) इन बक्सों में फिट सकता, और उनमें से एक बहुत वहाँ थे - कुछ कंप्यूटरों के रूप में कई के रूप में 65535 थी! वे एक दूसरे के बगल थे, और वे सभी एक पते की थी।

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

एक ड्रिल के लिए? एक struct करें:

struct {
char a;
char b;
char c;
char d;
} mystruct;
mystruct.a = 'r';
mystruct.b = 's';
mystruct.c = 't';
mystruct.d = 'u';

char* my_pointer;
my_pointer = &mystruct.b;
cout << 'Start: my_pointer = ' << *my_pointer << endl;
my_pointer++;
cout << 'After: my_pointer = ' << *my_pointer << endl;
my_pointer = &mystruct.a;
cout << 'Then: my_pointer = ' << *my_pointer << endl;
my_pointer = my_pointer + 3;
cout << 'End: my_pointer = ' << *my_pointer << endl;

एक ही उदाहरण के रूप में इसके बाद के संस्करण, सी में छोड़कर:

// Same example as above, except in C:
struct {
    char a;
    char b;
    char c;
    char d;
} mystruct;

mystruct.a = 'r';
mystruct.b = 's';
mystruct.c = 't';
mystruct.d = 'u';

char* my_pointer;
my_pointer = &mystruct.b;

printf("Start: my_pointer = %c\n", *my_pointer);
my_pointer++;
printf("After: my_pointer = %c\n", *my_pointer);
my_pointer = &mystruct.a;
printf("Then: my_pointer = %c\n", *my_pointer);
my_pointer = my_pointer + 3;
printf("End: my_pointer = %c\n", *my_pointer);

आउटपुट:

Start: my_pointer = s
After: my_pointer = t
Then: my_pointer = r
End: my_pointer = u

शायद यह है कि उदाहरण के माध्यम से बुनियादी बातों का कुछ बताते हैं?

08/08/2008 को 07:19
का स्रोत उपयोगकर्ता

वोट
10

मुझे नहीं लगता कि एक अवधारणा के रूप संकेत दिए गए विशेष रूप से मुश्किल कर रहे हैं करते हैं - सबसे छात्रों के मानसिक मॉडल कुछ इस तरह करने के लिए नक्शे और कुछ त्वरित बॉक्स नमूने कर सकते हैं।

कठिनाई, कम से कम है कि जो मैं अतीत में अनुभव और देखा अन्य लोगों के साथ सौदा किया है, कि C / C ++ में संकेत के प्रबंधन unncessarily जटिल हो सकता है।

08/08/2008 को 07:26
का स्रोत उपयोगकर्ता

वोट
1

मैं क्या संकेत के बारे में इतना भ्रामक है नहीं दिख रहा। वे याद में एक स्थान, वह यह है कि यह स्मृति पते संग्रहीत करता है को इंगित। C / C में आप करने के लिए प्रकार सूचक अंक निर्दिष्ट कर सकते हैं ++। उदाहरण के लिए:

int* my_int_pointer;

कहते हैं कि my_int_pointer एक स्थान है कि एक पूर्णांक शामिल करने के लिए पता है।

संकेत के साथ समस्या यह है कि वे याद में एक स्थान को इंगित है, इसलिए यह कुछ स्थान आप में नहीं होना चाहिए में बंद पीछा करने के लिए आसान है। सी / C ++ बफर अतिप्रवाह से आवेदन कई सुरक्षा संबंधी दोषों पर सबूत देखो के रूप में (सूचक incrementing आवंटित सीमा अतीत)।

08/08/2008 को 07:28
का स्रोत उपयोगकर्ता

वोट
48

कारण संकेत इतने सारे लोगों को भ्रमित करने के लिए कि वे अधिकतर कंप्यूटर वास्तुकला में कम या कोई पृष्ठभूमि के साथ आते है लग रहे हैं। है के बाद से कई कैसे कंप्यूटर (मशीन) वास्तव में कार्यान्वित किया जाता है की एक विचार है लगता नहीं - सी में काम कर रहे / C ++ विदेशी लगता है।

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

सरल इसके अलावा तुलना में थोड़ा अधिक की आवश्यकता होती है कुछ भी संकेत दिए गए शामिल हो रहा है और वे इसे पाने के लिए सुनिश्चित कर रहे हैं।

08/08/2008 को 07:29
का स्रोत उपयोगकर्ता

वोट
4

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

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

08/08/2008 को 07:52
का स्रोत उपयोगकर्ता

वोट
722

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

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

मैं नीचे नीचे कुछ डेल्फी कोड जोड़ दिया है, और कुछ टिप्पणियां जहां उपयुक्त हो। मैं अपने अन्य मुख्य प्रोग्रामिंग भाषा, सी # के बाद से डेल्फी चुना है, उसी तरह से मेमोरी लीक जैसी चीजों का प्रदर्शन नहीं करता।

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

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


मान लेते हैं THouse नीचे इस्तेमाल किया वर्ग इस तरह दिखता है:

type
    THouse = class
    private
        FName : array[0..9] of Char;
    public
        constructor Create(name: PChar);
    end;

जब आप घर वस्तु को प्रारंभ, नाम निर्माता के लिए दिया निजी क्षेत्र fName में बनाई जाए। वहाँ एक कारण यह एक निश्चित-आकार सरणी के रूप में परिभाषित किया जाता है।

स्मृति में, कुछ घर आवंटन के साथ जुड़े भूमि के ऊपर हो जाएगा, मैं इस तरह नीचे इस उदाहरण देकर स्पष्ट करना होगा:

--- [ttttNNNNNNNNNN] ---
     ^ ^
     | |
     | + - fName सरणी
     |
     + - भूमि के ऊपर

"Tttt" क्षेत्र भूमि के ऊपर है, वहाँ आम तौर पर runtimes और भाषाओं, 8 या 12 बाइट्स की तरह के विभिन्न प्रकार के लिए इस के अधिक हो जाएगा। यह आवश्यक है कि जो कुछ भी मान इस क्षेत्र स्मृति allocator या कोर प्रणाली दिनचर्या के अलावा और कुछ से बदल जाती है कभी नहीं में जमा हो जाती है, या आप कार्यक्रम दुर्घटनाग्रस्त जोखिम।


स्मृति को आबंटित

अपने घर बनाने के लिए एक उद्यमी जाओ, और आप घर में पता दे। असली दुनिया के विपरीत, स्मृति आवंटन जहां आवंटित करने के लिए है, लेकिन पर्याप्त जगह के साथ एक उपयुक्त स्थान मिलेगा, और आबंटित स्मृति को पता वापस रिपोर्ट नहीं बताया जा सकता है।

दूसरे शब्दों में, उद्यमी स्थान का चयन करेंगे।

THouse.Create('My house');

मेमोरी लेआउट:

--- [ttttNNNNNNNNNN] ---
    1234My घर

पते के साथ एक चर रखें

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

var
    h: THouse;
begin
    h := THouse.Create('My house');
    ...

मेमोरी लेआउट:


    v
--- [ttttNNNNNNNNNN] ---
    1234My घर

कॉपी सूचक मूल्य

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

नोट यह आमतौर पर धारणा यह है कि मैं सबसे समस्या लोगों को समझाने है, दो संकेत दिए गए दो वस्तुओं या स्मृति ब्लॉक मतलब यह नहीं है।

var
    h1, h2: THouse;
begin
    h1 := THouse.Create('My house');
    h2 := h1; // copies the address, not the house
    ...
    h1
    v
--- [ttttNNNNNNNNNN] ---
    1234My घर
    ^
    h2

स्मृति मुक्त

घर ध्वस्त। फिर आप बाद में पर अगर आप चाहें तो एक नया पते के लिए कागज का पुन: उपयोग, या यह स्पष्ट घर अब मौजूद नहीं है के लिए पता भूल कर सकते हैं।

var
    h: THouse;
begin
    h := THouse.Create('My house');<