यदि आप एक सामान्य कंप्यूटर के न्यूनतम संचालन को खरोंच से बनाते हैं, तो "इटरेशन" पहले बिल्डिंग ब्लॉक के रूप में आता है और "रिकर्सन" की तुलना में कम संसाधन गहन होता है, एर्गो तेजी से होता है।
हम अवधारणाओं की एक पदानुक्रम की स्थापना करेंगे, जो पहले से ही मूल और मूल अवधारणाओं को खरोंच और परिभाषित करने से शुरू होती है, फिर उन लोगों के साथ दूसरे स्तर की अवधारणाओं का निर्माण करते हैं, और इसी तरह।
पहला कॉन्सेप्ट: मेमोरी सेल्स, स्टोरेज, स्टेट । कुछ करने के लिए आपको अंतिम और मध्यवर्ती परिणाम मूल्यों को संग्रहीत करने के लिए स्थानों की आवश्यकता होती है। मान लेते हैं कि हमारे पास "पूर्णांक" कोशिकाओं की एक अनंत सरणी है, जिसे मेमोरी कहा जाता है , एम [0..Infinite]।
निर्देश: कुछ करें - सेल को रूपांतरित करें, उसका मान बदलें। परिवर्तन की अवस्था । प्रत्येक दिलचस्प निर्देश एक परिवर्तन करता है। मूल निर्देश हैं:
a) मेमोरी सेल्स सेट और मूव करें
- एक मान को मेमोरी में स्टोर करें, जैसे: स्टोर 5 मीटर [4]
- मूल्य को किसी अन्य स्थिति में कॉपी करें: उदाहरण के लिए: स्टोर m [4] m [8]
b) तर्क और अंकगणित
- और, या, एक्सोर, नहीं
- जोड़ें, उप, mul, div। उदाहरण के लिए m [7] m [8] जोड़ें
एक निष्पादन एजेंट : एक आधुनिक सीपीयू में एक कोर । एक "एजेंट" कुछ ऐसा है जो निर्देशों को निष्पादित कर सकता है। एक एजेंट कागज पर एल्गोरिथ्म का पालन करने वाला व्यक्ति भी हो सकता है।
चरणों का क्रम : निर्देशों का एक क्रम : यानी: यह पहले करो, इसके बाद करो आदि। निर्देशों का अनिवार्य अनुक्रम। यहां तक कि एक पंक्ति के भाव "निर्देशों का अनिवार्य अनुक्रम" हैं। यदि आपके पास एक विशिष्ट "मूल्यांकन के आदेश" के साथ एक अभिव्यक्ति है, तो आपके पास कदम हैं । इसका मतलब यह है कि एक एकल रचित अभिव्यक्ति में "कदम" निहित है और एक अंतर्निहित स्थानीय चर भी है (इसे "परिणाम" कहते हैं)। उदाहरण के लिए:
4 + 3 * 2 - 5
(- (+ (* 3 2) 4 ) 5)
(sub (add (mul 3 2) 4 ) 5)
उपरोक्त अभिव्यक्ति का तात्पर्य 3 चरणों में निहित "परिणाम" चर से है।
// pseudocode
1. result = (mul 3 2)
2. result = (add 4 result)
3. result = (sub result 5)
इसलिए भी, जब आप मूल्यांकन का एक विशिष्ट क्रम रखते हैं, तो भी अभिव्यक्ति के भाव, निर्देशों का अनिवार्य क्रम होते हैं । अभिव्यक्ति एक विशिष्ट क्रम में किए जाने वाले संचालन के अनुक्रम का अर्थ है, और क्योंकि चरण हैं , एक अंतर्निहित "परिणाम" मध्यवर्ती चर भी है।
निर्देश सूचक : यदि आपके पास चरणों का अनुक्रम है, तो आपके पास एक अंतर्निहित "निर्देश सूचक" भी है। निर्देश सूचक अगला निर्देश चिह्नित करता है, और निर्देश पढ़ने के बाद अग्रिम होता है, लेकिन निर्देश निष्पादित होने से पहले।
इस छद्म-कंप्यूटिंग-मशीन में, इंस्ट्रक्शन पॉइंटर मेमोरी का हिस्सा है । (नोट: आम तौर पर निर्देश सूचक एक सीपीयू कोर में एक "विशेष रजिस्टर" होगा, लेकिन यहां हम अवधारणाओं को सरल बनाएंगे और सभी डेटा (रजिस्टरों में शामिल हैं) "मेमोरी" का हिस्सा हैं)
कूदो - एक बार जब आपके पास चरणों की संख्या और एक निर्देश सूचक होता है , तो आप निर्देश सूचक के मूल्य को बदलने के लिए " स्टोर " निर्देश को लागू कर सकते हैं । हम स्टोर निर्देश के इस विशिष्ट उपयोग को एक नए नाम के साथ कहेंगे : कूदो । हम एक नए नाम का उपयोग करते हैं क्योंकि एक नई अवधारणा के रूप में इसके बारे में सोचना आसान है। इंस्ट्रक्टर पॉइंटर को बदलकर हम एजेंट को "स्टेप x पर जाने" का निर्देश दे रहे हैं।
अनंत उत्थान : वापस कूदकर, अब आप एजेंट को एक निश्चित संख्या में "रिपीट" कर सकते हैं। इस बिंदु पर हमारे पास अनंत उत्तेजना है।
1. mov 1000 m[30]
2. sub m[30] 1
3. jmp-to 2 // infinite loop
सशर्त - निर्देशों का सशर्त निष्पादन। "सशर्त" खंड के साथ, आप वर्तमान स्थिति के आधार पर कई निर्देशों में से एक को निष्पादित कर सकते हैं (जो पिछले निर्देश के साथ सेट किया जा सकता है)।
उचित Iteration : अब सशर्त खंड के साथ, हम जंप बैक अनुदेश के अनंत लूप से बच सकते हैं । अब हमारे पास सशर्त लूप है और फिर उचित Iteration है
1. mov 1000 m[30]
2. sub m[30] 1
3. (if not-zero) jump 2 // jump only if the previous
// sub instruction did not result in 0
// this loop will be repeated 1000 times
// here we have proper ***iteration***, a conditional loop.
नामकरण : किसी विशिष्ट मेमोरी लोकेशन को डेटा देने या स्टेप रखने के लिए नाम देना । यह सिर्फ एक "सुविधा" है। हम स्मृति स्थानों के लिए "नाम" को परिभाषित करने की क्षमता होने से कोई नया निर्देश नहीं जोड़ते हैं। "नामकरण" एजेंट के लिए एक निर्देश नहीं है, यह हमारे लिए सिर्फ एक सुविधा है। नामकरण कोड बनाता है (इस बिंदु पर) पढ़ने में आसान और बदलने में आसान।
#define counter m[30] // name a memory location
mov 1000 counter
loop: // name a instruction pointer location
sub counter 1
(if not-zero) jmp-to loop
एक-स्तरीय सबरूटीन : मान लीजिए कि आपके द्वारा अक्सर निष्पादित किए जाने वाले चरणों की एक श्रृंखला है। आप स्मृति में एक नामित स्थिति में चरणों को संग्रहीत कर सकते हैं और फिर उस स्थिति में कूद सकते हैं जब आपको उन्हें (कॉल) निष्पादित करने की आवश्यकता होती है। अनुक्रम के अंत में आपको निष्पादन जारी रखने के लिए कॉलिंग के बिंदु पर वापस लौटना होगा । इस तंत्र के साथ, आप मुख्य निर्देशों की रचना करके नए निर्देश (सबरूटीन्स) बना रहे हैं ।
कार्यान्वयन: (कोई नई अवधारणाओं की आवश्यकता नहीं)
- पूर्वनिर्धारित स्मृति स्थिति में वर्तमान निर्देश सूचक को संग्रहीत करें
- कूद सबरूटीन के लिए
- सबरूटीन के अंत में, आप पूर्वनिर्धारित मेमोरी लोकेशन से इंस्ट्रक्शन पॉइंटर को पुनः प्राप्त करते हैं, प्रभावी रूप से मूल कॉल के निम्न निर्देश पर वापस कूदते हैं।
एक-स्तरीय कार्यान्वयन के साथ समस्या : आप एक सबरूटीन से दूसरे सबरूटीन को कॉल नहीं कर सकते। यदि आप करते हैं, तो आप रिटर्निंग एड्रेस (ग्लोबल वैरिएबल) को अधिलेखित कर देंगे, ताकि आप कॉल न कर सकें।
एक करवाने के लिए सबरूटीन्स के लिए बेहतर कार्यान्वयन: आप एक ढेर की जरूरत है
स्टैक : आप एक मेमोरी स्टैक को "स्टैक" के रूप में कार्य करने के लिए परिभाषित करते हैं, आप स्टैक पर मानों को "पुश" कर सकते हैं, और अंतिम "पुश" मान को "पॉप" भी कर सकते हैं। स्टैक को लागू करने के लिए आपको स्टैक पॉइंटर (इंस्ट्रक्शन पॉइंटर के समान) की आवश्यकता होगी जो स्टैक के वास्तविक "हेड" की ओर इशारा करता है। जब आप किसी मान को "पुश" करते हैं, तो स्टैक पॉइंटर घटता है और आप मूल्य को स्टोर करते हैं। जब आप "पॉप" करते हैं, तो आपको वास्तविक स्टैक पॉइंटर पर मूल्य मिलता है और फिर स्टैक पॉइंटर को बढ़ाया जाता है।
सबरूटीन्स अब जब हमारे पास एक स्टैक है तो हम नेस्टेड कॉल की अनुमति देते हुए उचित सबरूटीन्स लागू कर सकते हैं । कार्यान्वयन समान है, लेकिन पूर्वनिर्धारित स्मृति स्थिति में निर्देश सूचक को संग्रहीत करने के बजाय, हम स्टैक में आईपी के मूल्य को "पुश" करते हैं । सबरूटीन के अंत में, हम स्टैक से केवल "पॉप" करते हैं, प्रभावी रूप से मूल कॉल के बाद निर्देश पर वापस कूदते हैं । यह कार्यान्वयन, "स्टैक" होने से दूसरे सबरूटीन से एक सबरूटीन को कॉल करने की अनुमति देता है। इस कार्यान्वयन से हम नए निर्देशों को उप-खंडों के रूप में परिभाषित कर सकते हैं, जब मुख्य निर्देशों या अन्य उप-केंद्रों का उपयोग करके इमारत ब्लॉकों के रूप में नए निर्देशों को परिभाषित किया जा सकता है ।
पुनरावर्तन : क्या होता है जब एक सबरूटीन खुद को बुलाता है ?। इसे "पुनरावृत्ति" कहा जाता है।
समस्या: स्थानीय मध्यवर्ती परिणामों को अधिलेखित करने से एक सबरूटिन मेमोरी में स्टोर हो सकता है। चूंकि आप समान चरणों को कॉल / पुन: उपयोग कर रहे हैं, यदि मध्यवर्ती परिणाम पूर्वनिर्धारित मेमोरी लोकेशन (वैश्विक चर) में संग्रहीत हैं , तो वे नेस्टेड कॉल पर अधिलेखित हो जाएंगे।
समाधान: पुनरावृत्ति की अनुमति देने के लिए, सबरूटीन को स्टैक में स्थानीय मध्यवर्ती परिणाम संग्रहीत करना चाहिए , इसलिए, प्रत्येक पुनरावर्ती कॉल (प्रत्यक्ष या अप्रत्यक्ष) पर मध्यवर्ती परिणाम विभिन्न मेमोरी स्थानों में संग्रहीत होते हैं।
...
अंत में, ध्यान दें कि आपके पास पुनरावर्तन का उपयोग करने के बहुत सारे अवसर हैं। आपके पास हर जगह रिकर्सिव डेटा स्ट्रक्चर्स हैं , अब आप एक देख रहे हैं: डोम के कुछ हिस्से जो आप पढ़ रहे हैं उसका समर्थन कर रहे हैं एक आरडीएस, एक JSON एक्सप्रेशन एक आरडीएस है, आपके कंप्यूटर में पदानुक्रमित फाइल सिस्टम एक आरडीएस है, यानी आप: एक रूट डाइरेक्टरी, जिसमें फाइल्स और डाइरेक्टरीज़ होती हैं, हर डायरेक्टरीज़ जिनमें फाइल्स और डाइरेक्टरीज़ होती हैं, हर एक उन डायरेक्टरीज़ जिनमें फाइल्स और डाइरेक्टरीज़ होती हैं ...