संकेत / पुनरावृत्ति के बारे में इतना मुश्किल क्या है? [बन्द है]


20

जावा स्कूलों के खतरों में जोएल पेन में अपने अनुभव और "विभाजन दोष" की कठिनाई पर चर्चा करता है। वह कहता है

[segfaults मुश्किल है जब तक आप] "गहरी सांस लें और वास्तव में अपने मन को एक साथ दो अलग-अलग स्तरों पर काम करने के लिए मजबूर करने की कोशिश करें।"

Segfaults के सामान्य कारणों की सूची को देखते हुए , मुझे समझ में नहीं आता है कि हमें अमूर्तता के 2 स्तरों पर कैसे काम करना है।

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


31
जोएल आपके बारे में क्या सोच सकता है, इसके बारे में चिंता करना बंद करें। यदि आपको पुनरावृत्ति आसान लगती है, तो यह अच्छा है। बाकी सब लोग नहीं करते।
FrustratedWithFormsDesigner

6
रिकर्सन डेफिनेशन (फंक्शन जिसे सेल्फ कहते हैं) द्वारा आसान है, लेकिन यह जानते हुए कि इसका उपयोग कब करना है और इसे कैसे काम करना है, यह कठिन हिस्सा है।
जेएफओ

9
फॉग क्रीक में नौकरी के लिए आवेदन करें और हमें बताएं कि यह कैसे जाता है। हम सभी आपके आत्म संवर्धन में बहुत रुचि रखते हैं।
जोएल एथरटन

4
@ P.Brian.Mackey: हमें गलतफहमी नहीं है। सवाल वास्तव में कुछ भी नहीं पूछता है। यह उदासीन आत्म-प्रचार है। यदि आप यह जानना चाहते हैं कि जोएल संकेत / पुनरावृत्ति के बारे में क्या पूछ रहा है, तो उससे पूछें: team@stackoverflow.com
जोएल इथरटन

19
इस सवाल का डुप्लिकेट ?
ओज

जवाबों:


38

मैंने पहली बार गौर किया कि कॉलेज में संकेत और पुनरावृत्ति कठिन थी। मैंने पहले साल के कुछ पाठ्यक्रमों में से एक लिया था (एक था सी और असेंबलर, दूसरा स्कीम में)। दोनों पाठ्यक्रम सैकड़ों छात्रों के साथ शुरू हुए, जिनमें से कई के पास वर्षों से हाई-स्कूल स्तर के प्रोग्रामिंग अनुभव थे (आमतौर पर उन दिनों में बेसिक और पास्कल)। लेकिन जैसे ही पॉइंटर्स को C कोर्स में पेश किया गया, और स्कीम कोर्स में रिकर्सन शुरू किया गया, बड़ी संख्या में छात्र - शायद यहां तक ​​कि बहुसंख्यक - पूरी तरह से हड़बड़ा गए थे। ये ऐसे बच्चे थे जिन्होंने पहले बहुत से कोड लिखे थे और उन्हें कोई समस्या नहीं थी, लेकिन जब उन्होंने संकेत और पुनरावृत्ति की, तो उन्होंने अपनी संज्ञानात्मक क्षमता के मामले में एक दीवार पर भी प्रहार किया।

मेरी परिकल्पना यह है कि संकेत और पुनरावृत्ति एक ही है कि उन्हें एक ही समय में आपके सिर में अमूर्त के दो स्तर रखने की आवश्यकता होती है। बहु-स्तर-एब्सट्रैक्शन के बारे में कुछ ऐसा है जिसे एक प्रकार की मानसिक योग्यता की आवश्यकता होती है जो कि बहुत संभव है कुछ लोगों के पास कभी नहीं होगा।

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

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


4
"बेस केस + आगमनात्मक मामले" के संदर्भ में एक एल्गोरिथम के बारे में सोचने के लिए "बहुत, बहुत अस्वाभाविक" - मुझे लगता है कि यह किसी भी तरह से अप्राकृतिक नहीं है, यह सिर्फ यह है कि बच्चों को तदनुसार प्रशिक्षित नहीं किया जा रहा है।
इंगो

14
यदि यह स्वाभाविक था, तो आपको प्रशिक्षित होने की आवश्यकता नहीं होगी। : पी
योएल Spolsky

1
अच्छा बिंदु :), लेकिन हमें गणित, तर्क, भौतिकी आदि के प्रशिक्षण की आवश्यकता नहीं है, जो सभी व्यापक रूप से सबसे अधिक स्वाभाविक हैं। दिलचस्प बात यह है कि कुछ प्रोग्रामर को भाषाओं की वाक्य रचना में कोई समस्या है, फिर भी यह पुनरावृत्ति से भरा है।
इनगो

1
मेरे विश्वविद्यालय में, पहला कोर्स कार्यात्मक प्रोग्रामिंग और पुनरावृत्ति के साथ लगभग तुरंत शुरू हुआ, म्यूटेशन और पसंद को शुरू करने से पहले। मैंने पाया कि बिना अनुभव के कुछ छात्रों ने कुछ अनुभव वाले लोगों की तुलना में पुनरावृत्ति को बेहतर समझा । उस ने कहा, वर्ग का शीर्ष बहुत अनुभव वाले लोगों से बना था ।
तिखन जेल्विस

2
मुझे लगता है कि संकेत और पुनरावृत्ति को समझने में असमर्थता एक) समग्र बुद्धि स्तर और बी) खराब गणितीय शिक्षा से जुड़ी है।
क्वांट_देव

23

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

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


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

कई कार्यों के बीच पारस्परिक पुनरावृत्ति अनिवार्य रूप से के रूप में ही है goto
Starblue

2
@starblue, वास्तव में नहीं - चूंकि प्रत्येक स्टैकफ्रेम स्थानीय चर के नए उदाहरण बनाता है।
चार्ल्स साल्विया

आप सही हैं, केवल पूंछ पुनरावृत्ति के रूप में ही है goto
Starblue

3
@ int a() { return b(); }पता पुनरावर्ती हो सकता है, लेकिन यह परिभाषा पर निर्भर करता है b। तो यह उतना आसान नहीं है जितना लगता है ...
वैकल्पिक

14

जावा पॉइंटर्स (उन्हें संदर्भ कहा जाता है) का समर्थन करता है और यह पुनरावृत्ति का समर्थन करता है। इसलिए सतह पर, उनका तर्क व्यर्थ प्रतीत होता है।

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


5
प्रति सेकेण्ड पॉइंट एक विवरण है। जावा में संदर्भों का उपयोग करना सी में स्थानीय चर का उपयोग करने से अधिक जटिल नहीं है। यहां तक ​​कि उन्हें जिस तरह से लिस्प क्रियान्वयन करते हैं (एक परमाणु सीमित आकार का एक पूर्णांक, या एक चरित्र या एक सूचक हो सकता है) मिश्रण करना मुश्किल नहीं है। यह कठिन हो जाता है जब भाषा एक ही प्रकार के डेटा को स्थानीय या संदर्भित करने की अनुमति देती है, अलग-अलग वाक्यविन्यास के साथ, और वास्तव में बालों के लिए जब भाषा सूचक अंकगणित की अनुमति देती है।
डेविड थॉर्नले

@ डेविड - उम, इसका मेरी प्रतिक्रिया से क्या लेना-देना है?
Anon

1
जावा सहायक बिंदुओं के बारे में आपकी टिप्पणी।
डेविड थॉर्नले

"जहां आपने एक सूचक को खराब कर दिया है (यह एक स्टैकट्रेस में पाए गए बिंदु पर शायद ही कभी होता है)।" यदि आप एक स्टैकट्रेस पाने के लिए पर्याप्त भाग्यशाली हैं।
ओमेगा सेंटौरी

5
मैं डेविड थॉर्नले से सहमत हूं; जावा तब तक पॉइंटर्स का समर्थन नहीं करता है जब तक कि मैं एक पॉइंटर को पॉइंटर से पॉइंटर को पॉइंटर करने के लिए पॉइंटर नहीं कर सकता। जो शायद मुझे लगता है कि मैं 4-5 वर्गों की तरह बना सकता हूं जो प्रत्येक संदर्भ में कुछ और है, लेकिन क्या यह वास्तव में संकेत है या यह एक बदसूरत वर्कअराउंड है?
वैकल्पिक

12

संकेत और पुनरावृत्ति के साथ समस्या यह नहीं है कि उन्हें समझना मुश्किल है, लेकिन यह कि उन्हें बुरी तरह से पढ़ाया जाता है, विशेष रूप से सी या सी ++ जैसी भाषाओं के संबंध में (मुख्य रूप से क्योंकि स्वयं भाषाओं को बुरी तरह सिखाया जा रहा है)। हर बार जब मैं सुनता हूं (या पढ़ता हूं) तो कोई कहता है "एक सरणी सिर्फ एक संकेतक है" मैं थोड़ा अंदर मर जाता हूं।

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

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


मैं सहमत हूँ, वास्तविक पॉइंटर्स देखने से पहले मेरे पास फोरट्रान के वर्ष / दशक थे, इसलिए मैं अपने काम के अपने तरीके का उपयोग पहले से ही कर रहा था, इससे पहले कि मुझे lanquage / compiler को मेरे लिए करने का मौका दिया जाए। मुझे यह भी लगता है कि पॉइंटर्स / एड्रेस के बारे में सी सिंटैक्स बहुत भ्रामक है, भले ही किसी एड्रेस पर संग्रहित मूल्य की अवधारणा बहुत सरल हो।
ओमेगा सेंटौरी

यदि आपके पास फोरट्रान IV में क्विकॉर्ट को लागू करने का लिंक है, तो मैं इसे देखना पसंद करूंगा। यह कहते हुए कि यह नहीं किया जा सकता है - वास्तव में, मैंने इसे कुछ 30 साल पहले बेसिक में लागू किया था - लेकिन मैं इसे देखना चाहूंगा।
आनन

मैंने फोरट्रान IV में कभी काम नहीं किया, लेकिन मैंने फोरट्रान 77 के VAX / VMS कार्यान्वयन में कुछ पुनरावर्ती एल्गोरिदम लागू किए (एक हुक था जो आपको एक विशेष प्रकार के चर के रूप में गोटो के लक्ष्य को बचाने की अनुमति देता है, इसलिए आप लिख सकते हैं GOTO target) । मुझे लगता है कि हमें अपना रनटाइम स्टैक बनाना था, हालांकि। यह बहुत पहले था कि मैं अब और विवरण याद नहीं कर सकता।
जॉन बोडे

8

संकेत के साथ कई कठिनाइयाँ हैं:

  1. अलियासिंग अलग-अलग नामों / वैरिएबल का उपयोग कर एक वस्तु का मान बदलने की संभावना।
  2. गैर-स्थानीयता किसी वस्तु के मूल्य को उस संदर्भ से अलग संदर्भ में बदलने की संभावना है जिसमें यह घोषित किया गया है (यह संदर्भ द्वारा पारित तर्कों के साथ भी होता है)।
  3. लाइफटाइम मिसमैच एक पॉइंटर का जीवनकाल उस ऑब्जेक्ट के जीवनकाल से अलग हो सकता है जो इसे इंगित करता है, और इससे अमान्य संदर्भ (SEGFAULTS) या कचरा हो सकता है।
  4. सूचक अंकगणित । कुछ प्रोग्रामिंग भाषाएं पॉइंटर्स को पूर्णांक के रूप में हेरफेर करने की अनुमति देती हैं, और इसका मतलब है कि पॉइंटर्स कहीं भी इंगित कर सकते हैं (एक बग मौजूद होने पर सबसे अप्रत्याशित स्थानों सहित)। सूचक अंकगणित को सही ढंग से उपयोग करने के लिए, एक प्रोग्रामर को इंगित की गई वस्तुओं के स्मृति आकारों के बारे में पता होना चाहिए, और इसके बारे में सोचने के लिए कुछ और है।
  5. टाइप कास्ट एक सूचक को एक प्रकार से दूसरे में डालने की क्षमता किसी इच्छित वस्तु की मेमोरी को ओवरराइट करने की अनुमति देती है।

इसीलिए एक प्रोग्रामर को पॉइंटर्स का उपयोग करते समय अधिक अच्छी तरह से सोचना चाहिए (मुझे एब्सट्रैक्शन के दो स्तरों के बारे में पता नहीं है )। यह एक नौसिखिया द्वारा की गई विशिष्ट गलतियों का एक उदाहरण है:

Pair* make_pair(int a, int b)
{
    Pair p;
    p.a = a;
    p.b = b;
    return &p;
}

ध्यान दें कि ऊपर की तरह कोड उन भाषाओं में पूरी तरह से उचित है जिनके पास संकेत की अवधारणा नहीं है, बल्कि नामों (संदर्भों), वस्तुओं और मूल्यों में से एक है, कार्यात्मक प्रोग्रामिंग भाषाओं के रूप में, और कचरा संग्रह के साथ भाषाएं (जावा, पायथन) ।

पुनरावर्ती कार्यों के साथ कठिनाई तब होती है जब बिना गणितीय पृष्ठभूमि के लोग (जहां पुनरावर्तन सामान्य और आवश्यक ज्ञान है) यह सोचकर उनसे संपर्क करने की कोशिश करते हैं कि फ़ंक्शन पहले कितनी बार इस आधार पर अलग - अलग व्यवहार करेगा । यह समस्या बढ़ जाती है क्योंकि पुनरावर्ती कार्य वास्तव में उन तरीकों से बनाए जा सकते हैं जिनमें आपको उन्हें समझने के लिए उस तरह से सोचना पड़ता है।

पॉइंटर्स के साथ पुनरावर्ती कार्यों के बारे में सोचो, जैसे कि एक रेड-ब्लैक ट्री के एक प्रक्रियात्मक कार्यान्वयन में जिसमें डेटा संरचना को संशोधित किया गया है; एक कार्यात्मक समकक्ष की तुलना में इसके बारे में सोचना अधिक कठिन है ।

यह प्रश्न में उल्लिखित नहीं है, लेकिन अन्य महत्वपूर्ण मुद्दे जिनके साथ नौसिखियों को कठिनाई होती है, वह संक्षिप्त है

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


उस फ़ंक्शन का उपयोग करके एक वैध पॉइंटर लौटाया जाएगा लेकिन वेरिएबल उस स्कोप से अधिक स्कोप में होगा जिसे फंक्शन कहा जाता है, इसलिए जब मैलोक का उपयोग किया जा रहा है तो पॉइंटर को अवैध माना जा सकता है।
राइटफोल्ड

4
@ रोड एस: नहीं, यह नहीं होगा। यह एक अमान्य पॉइंटर लौटाएगा जो कुछ वातावरण पर तब तक काम करने के लिए होता है जब तक कि कुछ और इसे अधिलेखित नहीं कर देता। (व्यवहार में, यह ढेर होगा, ढेर नहीं। malloc()ऐसा करने के लिए किसी भी अन्य फ़ंक्शन की तुलना में अधिक संभावना नहीं है।)
wnoise

1
@Radeck नमूना फ़ंक्शन में, सूचक स्मृति को इंगित करता है कि फ़ंक्शन के वापस आने पर प्रोग्रामिंग भाषा (इस मामले में सी) की गारंटी दी जाएगी। इस प्रकार, लौटाया गया पॉइंटर कचरा करने के लिए इंगित करता है । कचरा संग्रह वाली भाषाएँ किसी भी संदर्भ में संदर्भित होने तक वस्तु को जीवित रखती हैं।
अपाला

वैसे, रस्ट में संकेत हैं लेकिन इन समस्याओं के बिना। (जब असुरक्षित संदर्भ में नहीं)
सर्ज बोर्स्च

2

संकेत और पुनरावृत्ति दो अलग-अलग जानवर हैं और ऐसे अलग-अलग कारण हैं जो प्रत्येक को "कठिन" होने के योग्य बनाते हैं।

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

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

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


1

मैं पी। ब्रायन को ए 1 देता हूं, क्योंकि मुझे ऐसा लगता है कि वह ऐसा करता है: पुनरावृत्ति एक ऐसी मौलिक अवधारणा है, जिसे उसे थोड़ी सी भी कठिनाई होती है, उसे मैक डोनल्ड्स में नौकरी की तलाश करने पर बेहतर विचार करना चाहिए, लेकिन फिर भी, पुनरावृत्ति होती है:

make a burger:
   put a cold burger on the grill
   wait
   flip
   wait
   hand the fried burger over to the service personel
   unless its end of shift: make a burger

निश्चित रूप से, समझ की कमी का हमारे स्कूलों के साथ भी संबंध है। यहाँ एक को प्राकृतिक संख्याओं जैसे Peano, Dedekind और Frege का परिचय देना चाहिए, इसलिए हमें बाद में इतनी मुश्किलें नहीं होंगी।


6
यह पूंछ की पुनरावृत्ति है, जो यकीनन लूपिंग है।
माइकल के

6
क्षमा करें, मेरे लिए, पाशन यकीनन पूंछ पुनरावृत्ति है :)
इंगो

3
@Ingo: :) कार्यात्मक कट्टरपंथी!
माइकल के

1
@ मिचेल - हे, वास्तव में!, लेकिन मुझे लगता है कि कोई भी मामला बना सकता है कि पुनरावृत्ति अधिक मौलिक अवधारणा है।
इंगो

@Ingo: आप, वास्तव में (आपका उदाहरण यह अच्छी तरह से प्रदर्शित करता है) कर सकते हैं। हालांकि, किसी कारण से मानव के पास प्रोग्रामिंग में एक कठिन समय है - हम चाहते हैं कि goto topकिसी कारण से आईएमई अतिरिक्त हो ।
माइकल के

1

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

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

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

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


1
  DATA    |     CODE
          |
 pointer  |   recursion    SELF REFERENTIAL
----------+---------------------------------
 objects  |   macro        SELF MODIFYING
          |
          |

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

सेल्फ मॉडिफाइड डेटा और कोड की अवधारणा क्रमशः वस्तुओं (यानी स्मार्ट डेटा) और मैक्रोज़ की परिभाषा को रेखांकित करती है। मैं इनका उल्लेख करता हूं क्योंकि वे विशेष रूप से समझने में कठिन हैं जब रनटाइम की एक परिचालन समझ सभी चार अवधारणाओं के संयोजन से अपेक्षित होती है - उदाहरण के लिए एक मैक्रो ऑब्जेक्ट का एक सेट उत्पन्न करता है जो एक पुनरावर्ती सभ्य पार्सर को पॉइंटर्स के पेड़ की सहायता से लागू करता है । एक बार में अमूर्तता की हर परत के माध्यम से कार्यक्रम के राज्य के कदम-दर-चरण के पूरे संचालन का पता लगाने के बजाय, अनिवार्य प्रोग्रामर को यह विश्वास करना सीखना होगा कि उनके चर केवल एक बार शुद्ध कार्यों के भीतर सौंपे जाते हैं और उसी शुद्ध फ़ंक्शन के साथ बार-बार किए गए इनवॉइस। एक ही तर्क हमेशा एक ही परिणाम (यानी रेफरेंशियल ट्रांसपेरेंसी) देता है, यहां तक ​​कि ऐसी भाषा में भी जो जावा जैसे अशुद्ध कार्यों का समर्थन करती है। रनटाइम के बाद हलकों में दौड़ना एक बेकार प्रयास है। अमूर्तता को सरल बनाना चाहिए।


-1

अननोन के जवाब के समान।
Newbies के लिए संज्ञानात्मक कठिनाइयों के अलावा, दोनों संकेत और पुनरावृत्ति बहुत शक्तिशाली हैं, और क्रिप्टिक तरीकों से इस्तेमाल किया जा सकता है।

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.