फ़ंक्शन (कंप्यूटर प्रोग्रामिंग)
अभिकलित्र क्रमादेशन में, एक फ़ंक्शन या उपनित्यक्रम निर्देश (कंप्यूटर विज्ञान) का एक अनुक्रम है जो एक विशिष्ट कार्य करता है, जिसे एक इकाई के रूप में पैक किया गया है। इस इकाई का उपयोग उन क्रमानुदेशों में किया जा सकता है जहां वह विशेष कार्य किया जाना चाहिए।
फ़ंक्शन को क्रमानुदेशों के भीतर, या अलग से लाइब्रेरी (क्रमादेश संग्रह) (कंप्यूटर विज्ञान) में परिभाषित किया जा सकता है जिसका उपयोग कई क्रमानुदेशों द्वारा किया जा सकता है। विभिन्न प्रोग्रामिंग भाषाओं में, एक फ़ंक्शन को नित्यक्रम, उपक्रमादेश, उपनित्यक्रम, विधि (संगणना), या प्रक्रिया कहा जा सकता है। तकनीकी रूप से, इन सभी शब्दों की अलग-अलग परिभाषाएँ हैं, और नामकरण भाषा-दर-भाषा अलग-अलग है। सामान्य व्यापक शब्द प्रतिदेय इकाई का प्रयोग कभी-कभी किया जाता है।[1]
एक फ़ंक्शन को अक्सर कोडित किया जाता है ताकि इसे क्रमानुदेश के एक निष्पादन (संगणना) के दौरान कई बार और कई स्थानों से आरम्भ किया जा सके, जिसमें अन्य फ़ंक्शन भी उपस्थित हैं, जिसमें अन्य फ़ंक्शन भी उपस्थित हैं, और फिर फ़ंक्शन का कार्य पूरा होने के बाद कॉल के बाद अगले निर्देश पर ब्रांच बैक (वापसी) किया जा सकता है।
उपनित्यक्रम के विचार की कल्पना सबसे पहले जॉन मौचली और कैथलीन एंटोनेली ने ENIAC पर अपने काम के दौरान की थी,[2] और "ई.डी.वी.ए.सी- प्रकार की मशीनों के लिए समस्याओं की तैयारी" पर जनवरी 1947 में हार्वर्ड संगोष्ठी में अभिलिखित किया गया।[3] मौरिस विल्केस, डेविड व्हीलर (ब्रिटिश कंप्यूटर वैज्ञानिक) और स्टेनली गिल को आम तौर पर इस अवधारणा के औपचारिक आविष्कार का श्रेय दिया जाता है, जिसे उन्होंने एक बंद उपनित्यक्रम कहा है,[4][5] जो एक खुले उपनित्यक्रम या मैक्रो (कंप्यूटर विज्ञान) के विपरीत है।[6] तथापि, एलन ट्यूरिंग ने 1945 के एक पेपर में एनपीएल स्वचालित संगणना इंजन के प्रारुपण प्रस्तावों पर उपनित्यक्रम्स पर चर्चा की थी, यहां तक कि कॉल स्टैक की अवधारणा का आविष्कार भी किया था।[7]
फ़ंक्शंस एक शक्तिशाली प्रोग्रामिंग साधन हैं,[8] और कई प्रोग्रामिंग भाषाओं के रचनाक्रम में उपनित्यक्रम्स को लिखने और उपयोग करने के लिए सहायक सम्मिलित है। कार्यों का विवेकपूर्ण उपयोग (उदाहरण के लिए, संरचित प्रोग्रामिंग दृष्टिकोण के माध्यम से) अक्सर एक बड़े क्रमानुदेश को विकसित करने और बनाए रखने की लागत को काफी हद तक कम कर देगा, जबकि इसकी गुणवत्ता और विश्वसनीयता में वृद्धि होगी।[9] फ़ंक्शंस, जिन्हें अक्सर पुस्तकालयों में एकत्र किया जाता है, सॉफ़्टवेयर साझा करने और व्यापार करने के लिए एक महत्वपूर्ण तरीका हैं। ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग का अनुशासन ऑब्जेक्ट (कंप्यूटर विज्ञान) और विधियों (जो इन ऑब्जेक्ट या ऑब्जेक्ट कक्षा (अभिकलित्र क्रमादेशन) से जुड़े फ़ंक्शन हैं) पर आधारित है।
मुख्य अवधारणाएँ
किसी फ़ंक्शन की सामग्री उसका निकाय है, जो क्रमानुदेश कोड का टुकड़ा है जिसे फ़ंक्शन को कॉल करने या लागू करने पर निष्पादित किया जाता है।
एक फ़ंक्शन लिखा जा सकता है ताकि वह कॉलिंग क्रमानुदेश से एक या अधिक डेटा मान प्राप्त करने की अपेक्षा कर सके (इसके मापदण्ड (कंप्यूटर विज्ञान) या औपचारिक मापदण्ड को बदलने के लिए)। कॉलिंग क्रमानुदेश इन मापदंडों के लिए वास्तविक मान प्रदान करता है, जिसे तर्क (संगणना) कहा जाता है। विभिन्न प्रोग्रामिंग भाषाएं तर्क पारित करने के लिए विभिन्न सम्मेलनों का उपयोग कर सकती हैं:
Convention | Description | Common use |
---|---|---|
मान के आधार पर कॉल | तर्क का मूल्यांकन किया जाता है और मान की प्रतिलिपि फ़ंक्शन में भेज दी जाती है | अल्गोल 60 के बाद अधिकांश अल्गोल जैसी भाषाओं में डिफ़ॉल्ट, जैसे पास्कल, डेल्फ़ी, सिमुला, सीपीएल, पीएल/एम, मोडुला, ओबेरॉन, एडा, और कई अन्य। सी, सी++, जावा (ऑब्जेक्ट्स और सरणियों के संदर्भ भी मूल्य द्वारा पारित किए जाते हैं) |
संदर्भ के आधार पर कॉल | किसी तर्क का संदर्भ, आमतौर पर उसका पता (संबोधन) पारित किया जाता है | अल्गोल 60 के बाद अधिकांश अल्गोल-जैसी भाषाओं में चयन योग्य, जैसे अल्गोल 68, पास्कल, डेल्फ़ी, सिमुला, सीपीएल, पीएल/एम, मोडुला, ओबेरॉन, एडा, और कई अन्य। सी++, फोरट्रान, पीएल/आई |
परिणाम के आधार पर कॉल | फ़ंक्शन से लौटने पर मापदण्ड मान को वापस तर्क में कॉपी किया जाता है | एडा आउट मापदण्ड |
मूल्य-परिणाम द्वारा कॉल | मापदण्ड मान को फ़ंक्शन में प्रवेश पर और वापस लौटने पर वापस कॉपी किया जाता है | अल्गोल, स्विफ्ट इन-आउट मापदण्ड |
नाम के आधार पर कॉल | मैक्रो की तरह - मापदण्ड को अमूल्यांकित तर्क अभिव्यक्तियों के साथ बदलें, फिर हर बार कॉल करने वाले के संदर्भ में तर्क का मूल्यांकन करें जब कॉल किया गया नित्यक्रम मापदण्ड का उपयोग करता है। | अल्गोल, स्काला |
स्थिर मान के आधार पर कॉल | मान के आधार पर कॉल करना, सिवाय इसके कि मापदण्ड को स्थिरांक के रूप में माना जाए | पीएल/आई गैर-असाइन करने योग्य मापदण्ड, एडीए इन मापदण्ड |
फ़ंक्शन कॉल के दुष्प्रभाव (कंप्यूटर विज्ञान) भी हो सकते हैं जैसे कंप्यूटर डेटा भंडारण में डेटा संरचनाओं को संशोधित करना, परिधीय उपकरण से पढ़ना या लिखना, फाइल बनाना, क्रमानुदेश या मशीन को रोकना, या यहां तक कि एक निर्दिष्ट समय के लिए क्रमानुदेश के निष्पादन में देरी करना। दुष्प्रभाव वाला उपक्रमानुदेश हर बार कॉल करने पर अलग-अलग परिणाम दे सकता है, भले ही इसे समान तर्कों के साथ कॉल किया गया हो। उदाहरण एक छद्म यादृच्छिक संख्या जनरेटर है, जो कई भाषाओं में उपलब्ध है, जो हर बार कॉल करने पर एक अलग छद्म यादृच्छिक संख्या लौटाता है। दुष्प्रभाव वाले फ़ंक्शंस का व्यापक उपयोग अनिवार्य प्रोग्रामिंग भाषाओं की एक विशेषता है।
किसी फ़ंक्शन को कोडित किया जा सकता है ताकि वह अपना कार्य करने के लिए एक या अधिक स्थानों पर पुनरावर्तन (कंप्यूटर विज्ञान) कर सके। यह विधि गणितीय प्रेरण और पुनरावर्ती विभाजन और विजय कलन विधि द्वारा परिभाषित कार्यों के प्रत्यक्ष कार्यान्वयन की अनुमति देती है।
एक फ़ंक्शन जिसका उद्देश्य एक बूलियन-मूल्य वाले फ़ंक्शन की गणना करना है (अर्थात हां/नहीं प्रश्न का उत्तर देना) कभी-कभी विधेय कहा जाता है। तर्क प्रोग्रामिंग भाषाओं में, अक्सर[vague] सभी फ़ंक्शन को विधेय कहा जाता है, क्योंकि वे मुख्य रूप से[vague] सफलता या विफलता का निर्धारण करते हैं।[citation needed]
एक फ़ंक्शन जो कोई मान नहीं लौटाता या शून्य मान लौटाता है उसे कभी-कभी प्रक्रिया कहा जाता है। प्रक्रियाएं आमतौर पर अपने तर्कों को संशोधित करती हैं और प्रक्रियात्मक प्रोग्रामिंग का एक मुख्य हिस्सा हैं।
शब्दावली
उपनित्यक्रम एक ऐसा फ़ंक्शन है जो कोई मान नहीं लौटाता है।[10] फ़ंक्शंस का प्राथमिक उद्देश्य जटिल गणनाओं को सार्थक भागों में विभाजित करना और उन्हें नाम देना है। फ़ंक्शन अपने कॉलर को एक परिकलित मान (इसका रिटर्न मान) लौटा सकता है, या विभिन्न परिणाम मान या आउटपुट मापदण्ड प्रदान कर सकता है। दरअसल, फ़ंक्शन का एक सामान्य उपयोग फ़ंक्शन (गणित) को कार्यान्वित करना है, जिसमें फ़ंक्शन का उद्देश्य पूरी तरह से एक या अधिक परिणामों की गणना करना है जिनके मान पूरी तरह से फ़ंक्शन में दिए गए तर्कों द्वारा निर्धारित होते हैं। (उदाहरणों में किसी संख्या के लघुगणक या आव्यूह (गणित) के निर्धारक की गणना सम्मिलित हो सकती है।) कुछ भाषाओं में एक प्रक्रिया के लिए रचनाक्रम जो एक मान लौटाता है, अनिवार्य रूप से उस प्रक्रिया के लिए रचनाक्रम के समान होता है जो एक मान नहीं लौटाता है, उदाहरण के लिए, रिटर्न खंड की अनुपस्थिति को छोड़कर। कुछ भाषाओं में एक प्रक्रिया अपने तर्कों के आधार पर गतिशील रूप से मूल्य के साथ या उसके बिना वापस लौटने का विकल्प चुन सकती है।
भाषा समर्थन
उच्च-स्तरीय प्रोग्रामिंग भाषाओं में आमतौर पर विशिष्ट निर्माण उपस्थित होते हैं:
- क्रमानुदेश (बॉडी) के उस भाग को परिसीमित करें जो फ़ंक्शन बनाता है
- फ़ंक्शन के लिए एक पहचानकर्ता (नाम) निर्दिष्ट करें
- इसके मापदण्ड और रिटर्न मान के नाम और डेटा प्रकार निर्दिष्ट करें
- इसके अस्थायी चर के लिए एक निजी नामकरण दायरा प्रदान करें
- फ़ंक्शन के बाहर परिवर्तनशील की पहचान करें जो इसके भीतर पहुंच योग्य हैं
- फ़ंक्शन को कॉल करें
- इसके मापदंडों को मान प्रदान करें
- मुख्य क्रमानुदेश में उपक्रमानुदेश का पता होता है
- उपक्रमानुदेश में मुख्य क्रमानुदेश में फ़ंक्शन कॉल के अगले निर्देश का पता होता है
- इसके निकाय के भीतर से रिटर्न मान निर्दिष्ट करें
- कॉलिंग क्रमानुदेश पर वापस लौटें
- कॉल द्वारा लौटाए गए मानों का निपटान करें
- कॉल के दौरान आने वाले किसी भी अपवाद प्रबंधन को संभालें
- पैकेज प्रतिरूपकर प्रोग्रामिंग, लाइब्रेरी (संगणना) , ऑब्जेक्ट (कंप्यूटर साइंस), या क्लास (अभिकलित्र क्रमादेशन) में कार्य करता है
कुछ प्रोग्रामिंग भाषाएं, जैसे पास्कल (प्रोग्रामिंग भाषा), फोरट्रान, एडा (प्रोग्रामिंग भाषा) और बेसिक की कई बोलियां (संगणना), फ़ंक्शन या फ़ंक्शन उपक्रमानुदेश के बीच अंतर करती हैं, जो कॉलिंग क्रमानुदेश को स्पष्ट रिटर्न मान प्रदान करती हैं, और उपनित्यक्रम या प्रक्रियाएं, जो ऐसा नहीं करती हैं। उन भाषाओं में, फ़ंक्शन कॉल सामान्यतः अभिव्यक्ति (प्रोग्रामिंग ) में सन्निहित होते हैं (उदाहरण के लिए, sqrt
फ़ंक्शन को y = z + sqrt(x)
के रूप में बुलाया जा सकता है)। प्रक्रिया कॉल या तो वाक्यात्मक रूप से कथन (कंप्यूटर विज्ञान) के रूप में व्यवहार करते हैं (उदाहरण के लिए, print
प्रक्रिया को कहा जा सकता है if x > 0 then print(x)
या स्पष्ट रूप से CALL
या GOSUB
जैसे किसी कथन द्वारा स्पष्ट रूप से कॉल किया जाता है (जैसे, call print(x)
)। अन्य भाषाएँ, जैसे C (प्रोग्रामिंग भाषा) और लिस्प (प्रोग्रामिंग भाषा), फ़ंक्शन और उपनित्यक्रम के बीच अंतर नहीं करती हैं।
हास्केल (प्रोग्रामिंग भाषा) जैसी कड़ाई से कार्यात्मक प्रोग्रामिंग भाषाओं में, उपक्रमानुदेश का कोई दुष्प्रभाव (कंप्यूटर विज्ञान) नहीं हो सकता है, जिसका अर्थ है कि क्रमानुदेश की विभिन्न आंतरिक स्थिति नहीं बदलेगी। यदि समान तर्कों के साथ बार-बार कॉल किया जाता है तो फ़ंक्शंस हमेशा एक ही परिणाम देंगे। ऐसी भाषाएँ आम तौर पर केवल उन फ़ंक्शंस का समर्थन करती हैं जो मान लौटाते हैं, क्योंकि जो फ़ंक्शंस कोई मान नहीं लौटाते हैं उनका तब तक कोई उपयोग नहीं होता जब तक कि वे कोई दुष्प्रभाव पैदा न करें।
C (प्रोग्रामिंग भाषा), C++, और C शार्प (प्रोग्रामिंग भाषा)|C# जैसी प्रोग्रामिंग भाषाओं में, वे फ़ंक्शन जो कोई मान लौटाते हैं और वे फ़ंक्शन जो कोई मान नहीं लौटाते हैं, दोनों को "फ़ंक्शन" कहा जाता है (गणितीय फ़ंक्शन या कार्यात्मक प्रोग्रामिंग के साथ भ्रमित न हों, जो अलग-अलग अवधारणाएं हैं)।
एक भाषा का संकलक आमतौर पर प्रक्रिया कॉल का अनुवाद करेगा और एक अच्छी तरह से परिभाषित कॉलिंग सम्मेलन के अनुसार मशीन निर्देशों में रिटर्न करेगा, ताकि फ़ंक्शन को उन क्रमानुदेशों से अलग से संकलित किया जा सके जो उन्हें कॉल करते हैं। कॉल और रिटर्न स्टेटमेंट के अनुरूप निर्देश अनुक्रम को प्रक्रिया की प्रस्तावना और उपसंहार कहा जाता है।
फायदे
किसी क्रमानुदेश को फ़ंक्शंस में विभाजित के फ़ायदों में सम्मिलित हैं:
- एक जटिल प्रोग्रामिंग कार्य को सरल चरणों में विघटित करना (कंप्यूटर विज्ञान): यह डेटा संरचनाओं के साथ-साथ संरचित प्रोग्रामिंग के दो मुख्य उपकरणों में से एक है
- क्रमानुदेश के भीतर समरूप कोड को कम करना
- कई क्रमानुदेशों में कोड का पुन: उपयोग सक्षम करना
- एक बड़े प्रोग्रामिंग कार्य को विभिन्न क्रमादेशित्र या किसी परियोजना के विभिन्न चरणों के बीच विभाजित करना
- फ़ंक्शन के उपयोगकर्ताओं से जानकारी छिपाना
- कोड के ब्लॉक को फ़ंक्शन कॉल से बदलकर कोड की पठनीयता में सुधार करना जहां एक वर्णनात्मक फ़ंक्शन नाम कोड के ब्लॉक का वर्णन करने के लिए कार्य करता है। यह कॉलिंग कोड को संक्षिप्त और पठनीय बनाता है, भले ही फ़ंक्शन का पुन: उपयोग न किया गया हो।
- ट्रैसेबिलिटी (पता लगाने की क्षमता) में सुधार (यानी अधिकांश भाषाएं कॉल ट्रेस प्राप्त करने के तरीके प्रदान करती हैं जिसमें उपस्थित कार्यों के नाम और संभवतया इससे भी अधिक जानकारी जैसे फ़ाइल नाम और लाइन नंबर उपस्थित हैं); कोड को फ़ंक्शंस में विघटित न करने से, डिबगिंग (दोषमार्जन) गंभीर रूप से ख़राब हो जाएगी
नुकसान
समरेखीय कोड का उपयोग करने की तुलना में, किसी फ़ंक्शन को लागू करने से कॉल क्रियाविधि में कुछ संगणनात्मक ओवरहेड (उपरिव्यय) लगाया जाता है।[citation needed]
किसी फ़ंक्शन को आम तौर पर मानक हाउसकीपिंग (संगणना) कोड की आवश्यकता होती है - फ़ंक्शन में प्रवेश और निकास दोनों पर (फ़ंक्शन प्रस्तावना और उपसंहार- आमतौर पर सामान्य प्रयोजन रजिस्टरों और वापसी पते को न्यूनतम के रूप में सहेजना)।
इतिहास
कुछ समय पहले से ही संगणना मशीनें उपस्थित होने के बाद एक उपनित्यक्रम के विचार पर काम किया गया था। अंकगणित और सशर्त जंप निर्देशों की योजना समय से पहले बनाई गई थी और उनमें अपेक्षाकृत कम बदलाव हुआ है, लेकिन प्रक्रिया कॉल के लिए उपयोग किए जाने वाले विशेष निर्देशों में पिछले कुछ वर्षों में काफी बदलाव आया है। मैनचेस्टर बेबी और आरसीए 1802 जैसे पूर्वतर कंप्यूटर और माइक्रोसंसाधक में एक भी उपनित्यक्रम कॉल निर्देश नहीं था। उपनित्यक्रम्स को लागू किया जा सकता था, लेकिन उन्हें क्रमादेशित्र को प्रत्येक कॉल स्थल पर कॉल अनुक्रम - निर्देशों की एक श्रृंखला - का उपयोग करने की आवश्यकता थी।
उपनित्यक्रम्स को 1945 में कोनराड ज़ूस के Z4 (कंप्यूटर) में लागू किया गया था।
1945 में, एलन एम. ट्यूरिंग ने कॉल करने और उपनित्यक्रम्स से लौटने के साधन के रूप में "बरी" और "अनबरी" शब्दों का उपयोग किया।[11][12]
जनवरी 1947 में जॉन मौचली ने हार्वर्ड यूनिवर्सिटी और ब्यूरो ऑफ ऑर्डनेंस (आयुध ब्यूरो), संयुक्त राज्य अमेरिका नौसेना के संयुक्त प्रायोजन के तहत 'ए सिम्पोजियम ऑफ लार्ज स्केल डिजिटल कैलकुलेटिंग मशीनरी' ('बड़े पैमाने पर डिजिटल गणना मशीनरी के एक संगोष्ठी') में सामान्य नोट्स प्रस्तुत किए। यहां उन्होंने आनुक्रमिक और समानांतर संचालन के सुझाव पर चर्चा की
...मशीन की संरचना को थोड़ा भी जटिल होने की आवश्यकता नहीं है। यह संभव है, क्योंकि इस प्रक्रिया के लिए आवश्यक सभी तार्किक विशेषताएँ उपलब्ध हैं, मशीन को ज्ञात स्थानों पर मेमोरी में उपनित्यक्रम रखने के लिए एक कोडिंग निर्देश विकसित करना, और इस तरह से कि उन्हें आसानी से उपयोग में लाया जा सके।
दूसरे शब्दों में, कोई उपनित्यक्रम ए को विभाजन के रूप में और उपनित्यक्रम बी को जटिल गुणन के रूप में और उपनित्यक्रम सी को संख्याओं के अनुक्रम की मानक त्रुटि के मूल्यांकन के रूप में नामित कर सकता है, और इसी तरह किसी विशेष समस्या के लिए आवश्यक उपनित्यक्रम की सूची के माध्यम से। ... फिर इन सभी उपनित्यक्रम को मशीन में संग्रहीत किया जाएगा, और सभी को संख्या के आधार पर उनका संक्षिप्त संदर्भ देना होगा, जैसा कि उन्हें कोडिंग में दर्शाया गया है।[3]
के मैकनल्टी ने ENIAC टीम में जॉन मौचली के साथ मिलकर काम किया था और द्वितीय विश्व युद्ध के दौरान जिस ENIAC कंप्यूटर की प्रोग्रामिंग कर रही थी, उसके लिए उपनित्यक्रम्स के लिए एक विचार विकसित किया था।[13] उसने और अन्य ENIAC क्रमादेशित्र ने प्रक्षेपणास्त्र प्रक्षेप पथ की गणना में मदद के लिए उपनित्यक्रम्स का उपयोग किया।[13]
हरमन गोल्डस्टाइन और जॉन वॉन न्यूमैन ने 16 अगस्त 1948 को उपनित्यक्रम्स के उपयोग पर चर्चा करते हुए एक पेपर लिखा था।[14]
कुछ बहुत पूर्वतर कंप्यूटर और माइक्रोसंसाधक, जैसे कि IBM 1620, Intel 4004 और Intel 8008, और पीआईसी माइक्रोकंट्रोलर, में एकल-निर्देश उपनित्यक्रम कॉल होता है जो रिटर्न पते को संग्रहीत करने के लिए एक समर्पित हार्डवेयर स्टैक का उपयोग करता है - ऐसा हार्डवेयर उपनित्यक्रम नेस्टिंग के केवल कुछ स्तरों का समर्थन करता है, लेकिन पुनरावर्ती उपनित्यक्रम का समर्थन कर सकता है। 1960 के दशक के मध्य से पहले की मशीनें - जैसे कि UNIVAC I, PDP-1, और IBM 1130 - आम तौर पर एक कॉलिंग सम्मेलन का उपयोग करती हैं जो निर्देश काउंटर को उपनित्यक्रम के पहले मेमोरी स्थान में सहेजती है। यह उपनित्यक्रम नेस्टिंग के प्रत्युत्तर से गहरे स्तर की अनुमति देता है लेकिन पुनरावर्ती उपनित्यक्रम का समर्थन नहीं करता है। आईबीएम सिस्टम/360 में एक उपनित्यक्रम कॉल निर्देश था जो सहेजे गए निर्देश काउंटर मान को एक सामान्य प्रयोजन रजिस्टर में रखता था; इसका उपयोग प्रत्युत्तर से गहरे उपनित्यक्रम नेस्टिंग और पुनरावर्ती उपनित्यक्रम का समर्थन करने के लिए किया जा सकता है। पीडीपी-11 (1970) स्टैक-पुशिंग उपनित्यक्रम कॉल निर्देश वाले पहले कंप्यूटरों में से एक है; यह सुविधा प्रत्युत्तर से गहरे उपनित्यक्रम नेस्टिंग और पुनरावर्ती उपनित्यक्रम दोनों का भी समर्थन करती है।[15]
भाषा समर्थन
पूर्वतर समायोजक में, उपनित्यक्रम समर्थन सीमित था। उपनित्यक्रम स्पष्ट रूप से एक दूसरे से या मुख्य क्रमानुदेश से अलग नहीं थे, और वास्तव में एक उपनित्यक्रम का स्रोत कोड अन्य उपक्रमानुदेश के साथ मिलाया जा सकता था। कुछ असेंबलर कॉल और रिटर्न अनुक्रम उत्पन्न करने के लिए पूर्वनिर्धारित मैक्रो (कंप्यूटर विज्ञान) की प्रस्तुतीकरण करेंगे। 1960 के दशक तक, समायोजक के पास आमतौर पर इनलाइन और अलग-अलग समन्वायोजित किए गए उपनित्यक्रम्स के लिए अधिक परिष्कृत समर्थन होता था जिन्हें एक साथ जोड़ा जा सकता था।
उपयोगकर्ता-लिखित उपनित्यक्रम्स और फ़ंक्शंस का समर्थन करने वाली पहली प्रोग्रामिंग भाषाओं में से एक फ़ोरट्रान II थी। IBM फ़ोरट्रान II संकलनकर्ता 1958 में जारी किया गया था। ALGOL 58 और अन्य प्रारंभिक प्रोग्रामिंग भाषाओं ने भी प्रक्रियात्मक प्रोग्रामिंग का समर्थन किया।
पुस्तकालय
इस बोझिल दृष्टिकोण के साथ भी, उपनित्यक्रम्स बहुत उपयोगी साबित हुए। उन्होंने कई अलग-अलग क्रमानुदेशों में एक ही कोड के उपयोग की अनुमति दी। प्रारंभिक कंप्यूटरों पर मेमोरी एक बहुत ही दुर्लभ संसाधन थी, और उपनित्यक्रम्स ने क्रमानुदेश के आकार में महत्वपूर्ण बचत की अनुमति दी थी।
कई पूर्वतर कंप्यूटरों ने क्रमानुदेश निर्देशों को एक छिद्रित टेप से मेमोरी में लोड किया। प्रत्येक उपनित्यक्रम को टेप के एक अलग टुकड़े द्वारा प्रदान किया जा सकता है, जिसे मुख्य क्रमानुदेश (या प्रमुख मार्ग) से पहले या बाद में लोड या जोड़ा जा सकता है।[16]); और फिर एक ही उपनित्यक्रम टेप का उपयोग कई अलग-अलग क्रमानुदेशों द्वारा किया जा सकता है। एक समान दृष्टिकोण उन कंप्यूटरों में लागू किया जाता है जो अपने मुख्य इनपुट के लिए छिद्रित कार्ड का उपयोग करते हैं। उपनित्यक्रम लाइब्रेरी नाम का शाब्दिक अर्थ मूल रूप से एक पुस्तकालय था, जो सामूहिक उपयोग के लिए टेप या कार्ड-डेक के अनुक्रमित संग्रह रखता था।
अप्रत्यक्ष जंप द्वारा रिटर्न
स्व-संशोधित कोड की आवश्यकता को दूर करने के लिए, कंप्यूटर डिजाइनरों ने अंततः एक अप्रत्यक्ष शाखा निर्देश प्रदान किया, जिसका ऑपरेंड, रिटर्न स्टेटमेंट होने के बजाय, रिटर्न एड्रेस वाले एक परिवर्तनीय या संसाधक रजिस्टर का स्थान (लोकेशन) था।
उन कंप्यूटरों पर, फ़ंक्शन के रिटर्न जंप को संशोधित करने के बजाय, कॉलिंग क्रमानुदेश रिटर्न एड्रेस को एक परिवर्तनीय में संग्रहीत करेगा ताकि जब फ़ंक्शन पूरा हो जाए, तो यह एक अप्रत्यक्ष जंप निष्पादित करेगा जो पूर्वनिर्धारित परिवर्तनीय द्वारा दिए गए स्थान पर निष्पादन को निर्देशित करेगा।
उपनित्यक्रम पर जाएं
एक और प्रगति उपनित्यक्रम निर्देश पर छलांग थी, जिसने कॉलिंग जंप के साथ रिटर्न एड्रेस की बचत को जोड़ दिया, जिससे कम्प्यूटेशनल ओवरहेड को काफी कम कर दिया गया।
उदाहरण के लिए, आईबीएम सिस्टम/360 में, प्रक्रिया कॉलिंग के लिए डिज़ाइन किए गए शाखा निर्देश बीएएल या बीएएलआर, सम्मेलन रजिस्टर 14 द्वारा निर्देश में निर्दिष्ट संसाधक रजिस्टर में रिटर्न एड्रेस को सेव करेंगे। वापस लौटने के लिए, उपनित्यक्रम को केवल निष्पादित करना होगा उस रजिस्टर के माध्यम से एक अप्रत्यक्ष शाखा निर्देश (बीआर)। यदि उपनित्यक्रम को किसी अन्य उद्देश्य के लिए उस रजिस्टर की आवश्यकता होती है (जैसे कि किसी अन्य उपनित्यक्रम को कॉल करना), तो यह रजिस्टर की सामग्री को एक निजी मेमोरी स्थान या रजिस्टर स्टैक (डेटा संरचना) में सहेज लेगा।
एचपी 2100 जैसी प्रणालियों में, जेएसबी निर्देश एक समान कार्य करेगा, सिवाय इसके कि रिटर्न पता उस मेमोरी स्थान में संग्रहीत किया गया था जो शाखा का लक्ष्य था। प्रक्रिया का निष्पादन वास्तव में अगले मेमोरी स्थान पर आरम्भ होगा। उदाहरण के लिए, एचपी 2100 असेंबली भाषा में कोई भी लिख सकता है
...
JSB MYSUB (Calls subroutine MYSUB.)
BB ... (Will return here after MYSUB is done.)
मुख्य क्रमानुदेश से MYSUB नामक उपनित्यक्रम को कॉल करने के लिए। उपनित्यक्रम को इस प्रकार कोडित किया जाएगा
MYSUB NOP (Storage for MYSUB's return address.)
AA ... (Start of MYSUB's body.)
...
JMP MYSUB,I (Returns to the calling program.)
JSB निर्देश ने NEXT निर्देश (अर्थात्, BB) के पते को उसके ऑपरेंड (अर्थात्, MYSUB) के रूप में निर्दिष्ट स्थान पर रखा, और फिर उसके बाद अगले स्थान (अर्थात्, AA = MYSUB + 1) पर शाखा दी। उपनित्यक्रम अप्रत्यक्ष जंप JMP MYSUB, I को क्रियान्वित करके मुख्य क्रमानुदेश में वापस आ सकता है, जो स्थान MYSUB पर संग्रहीत स्थान पर शाखाबद्ध होता है।
फोरट्रान और अन्य भाषाओं के संकलनकर्ता उपलब्ध होने पर इन निर्देशों का आसानी से उपयोग कर सकते हैं। इस दृष्टिकोण ने कॉल के कई स्तरों का समर्थन किया; तथापि, चूंकि उपनित्यक्रम के रिटर्न एड्रेस, मापदण्ड और रिटर्न वैल्यू को निश्चित मेमोरी स्थान दिए गए थे, इसलिए यह पुनरावर्ती कॉल की अनुमति नहीं देता था।
संयोग से, एक स्प्रेडशीट में पुनर्गणना निर्भरता की खोज के लिए, 1980 के दशक की शुरुआत में लोटस 1-2-3 द्वारा एक समान विधि का उपयोग किया गया था। अर्थात्, रिटर्न एड्रेस को संग्रहीत करने के लिए प्रत्येक सेल में एक स्थान आरक्षित किया गया था। चूंकि प्राकृतिक पुनर्गणना क्रम के लिए परिपत्र संदर्भों की अनुमति नहीं है, यह मेमोरी में स्टैक के लिए जगह आरक्षित किए बिना ट्री वॉक की अनुमति देता है, जो कि आईबीएम पीसी जैसे छोटे कंप्यूटरों पर बहुत सीमित था।
कॉल स्टैक
फ़ंक्शन कॉल के अधिकांश आधुनिक कार्यान्वयन फ़ंक्शन कॉल और रिटर्न को लागू करने के लिए कॉल स्टैक, स्टैक (डेटा संरचना) का एक विशेष मामला, का उपयोग करते हैं। प्रत्येक प्रक्रिया कॉल स्टैक के शीर्ष पर एक नई प्रविष्टि बनाती है, जिसे स्टैक फ़्रेम कहा जाता है; जब प्रक्रिया वापस आती है, तो इसका स्टैक फ्रेम स्टैक से हटा दिया जाता है, और इसके स्थान का उपयोग अन्य प्रक्रिया कॉल के लिए किया जा सकता है। प्रत्येक स्टैक फ्रेम में संबंधित कॉल का निजी डेटा होता है, जिसमें आम तौर पर प्रक्रिया के मापदण्ड और आंतरिक चर और रिटर्न पता उपस्थित होता है।
कॉल अनुक्रम को सामान्य निर्देशों के अनुक्रम द्वारा कार्यान्वित किया जा सकता है (एक दृष्टिकोण जो अभी भी कम निर्देश सेट संगणना (आरआईएससी) और बहुत लंबे निर्देश शब्द (वीएलआईडब्ल्यू) आर्किटेक्चर में उपयोग किया जाता है), लेकिन 1960 के दशक के उत्तरार्ध से डिज़ाइन की गई कई पारंपरिक मशीनों में विशेष निर्देश उपस्थित हैं वह उद्देश्य.
कॉल स्टैक को आमतौर पर मेमोरी के सन्निहित क्षेत्र के रूप में कार्यान्वित किया जाता है। यह एक मनमाना डिज़ाइन विकल्प है कि क्या स्टैक का निचला भाग इस क्षेत्र के भीतर सबसे निचला या उच्चतम पता है, ताकि स्टैक मेमोरी में आगे या पीछे की ओर बढ़ सके; तथापि, कई आर्किटेक्चर ने बाद वाले को चुना।[citation needed]
कुछ डिज़ाइन, विशेष रूप से कुछ फोर्थ (प्रोग्रामिंग भाषा) कार्यान्वयन, दो अलग-अलग स्टैक का उपयोग करते हैं, एक मुख्य रूप से नियंत्रण जानकारी (जैसे रिटर्न पते और लूप काउंटर) के लिए और दूसरा डेटा के लिए। पूर्व एक कॉल स्टैक था, या उसकी तरह काम करता था और केवल अन्य भाषा निर्माणों के माध्यम से क्रमादेशित्र के लिए अप्रत्यक्ष रूप से पहुंच योग्य था, जबकि बाद वाला अधिक प्रत्यक्ष रूप से पहुंच योग्य था।
जब स्टैक-आधारित प्रक्रिया कॉल पहली बार प्रस्तावित की गईं, तो एक महत्वपूर्ण प्रेरणा कीमती मेमोरी को सहेजना था।[citation needed] इस योजना के साथ, संकलनकर्ता को प्रत्येक प्रक्रिया के निजी डेटा (मापदण्ड, रिटर्न एड्रेस और स्थानीय चर) के लिए मेमोरी में अलग से स्थान आरक्षित नहीं करना पड़ता है। किसी भी समय, स्टैक में केवल उन कॉलों का निजी डेटा होता है जो वर्तमान में सक्रिय हैं (अर्थात्, जिन्हें कॉल किया गया है लेकिन अभी तक वापस नहीं किया गया है)। जिस तरह से क्रमानुदेश आमतौर पर पुस्तकालयों से इकट्ठे किए जाते थे, उसके कारण ऐसे क्रमानुदेश ढूंढना (और अभी भी है) असामान्य नहीं है, जिनमें हजारों फ़ंक्शन उपस्थित होते हैं, जिनमें से केवल कुछ ही किसी भी समय सक्रिय होते हैं।[citation needed] ऐसे क्रमानुदेशों के लिए, कॉल स्टैक तंत्र महत्वपूर्ण मात्रा में मेमोरी बचा सकता है। दरअसल, कॉल स्टैक तंत्र को कचरा संग्रहण (कंप्यूटर विज्ञान) के लिए सबसे प्रारंभिक और सरल विधि के रूप में देखा जा सकता है।
तथापि, कॉल स्टैक विधि का एक और फायदा यह है कि यह रिकर्सन (कंप्यूटर विज्ञान) की अनुमति देता है, क्योंकि एक ही प्रक्रिया में प्रत्येक नेस्टेड कॉल को उसके निजी डेटा का एक अलग उदाहरण मिलता है।
एक थ्रेड (कंप्यूटर विज्ञान)|बहु-थ्रेडेड वातावरण में, आम तौर पर एक से अधिक स्टैक होते हैं।[17] एक ऐसा वातावरण जो पूरी तरह से coroutine या आलसी मूल्यांकन का समर्थन करता है, अपने सक्रियण रिकॉर्ड को संग्रहीत करने के लिए स्टैक के अलावा अन्य डेटा संरचनाओं का उपयोग कर सकता है।
विलंबित स्टैकिंग
कॉल स्टैक तंत्र का एक नुकसान प्रक्रिया कॉल की बढ़ी हुई लागत और उसके मिलान रिटर्न है।[clarification needed] अतिरिक्त लागत में स्टैक पॉइंटर को बढ़ाना और घटाना उपस्थित है (और, कुछ आर्किटेक्चर में, स्टैक ओवरफ़्लो की जांच करना), और निरपेक्ष पतों के बजाय फ्रेम-सापेक्ष पतों द्वारा स्थानीय चर और मापदंडों तक पहुंच बनाना उपस्थित है। लागत को बढ़े हुए निष्पादन समय, या बढ़ी हुई संसाधक जटिलता, या दोनों में महसूस किया जा सकता है।
यह ओवरहेड लीफ प्रक्रियाओं या लीफ फ़ंक्शंस में सबसे स्पष्ट और आपत्तिजनक है, जो बिना किसी प्रक्रिया को कॉल किए वापस लौट आते हैं।[18][19][20] उस ओवरहेड को कम करने के लिए, कई आधुनिक संकलनकर्ता कॉल स्टैक के उपयोग में तब तक देरी करने का प्रयास करते हैं जब तक कि इसकी वास्तव में आवश्यकता न हो।[citation needed] उदाहरण के लिए, एक प्रक्रिया पी की कॉल कुछ संसाधक रजिस्टरों में कॉल की गई प्रक्रिया के रिटर्न पते और मापदंडों को संग्रहीत कर सकती है, और एक साधारण छलांग द्वारा प्रक्रिया के मुख्य भाग पर नियंत्रण स्थानांतरित कर सकती है। यदि प्रक्रिया P कोई अन्य कॉल किए बिना वापस आती है, तो कॉल स्टैक का उपयोग बिल्कुल नहीं किया जाता है। यदि P को किसी अन्य प्रक्रिया Q को कॉल करने की आवश्यकता है, तो यह किसी भी रजिस्टर (जैसे रिटर्न एड्रेस) की सामग्री को सहेजने के लिए कॉल स्टैक का उपयोग करेगा, जिसकी Q रिटर्न के बाद आवश्यकता होगी।
उदाहरण
सी और सी++
सी (प्रोग्रामिंग भाषा) और सी++ प्रोग्रामिंग भाषाओं में, उपक्रमानुदेश को फ़ंक्शंस कहा जाता है (किसी क्लास (अभिकलित्र क्रमादेशन), या फ्री फ़ंक्शंस से जुड़े होने पर इसे सदस्य फ़ंक्शंस के रूप में वर्गीकृत किया जाता है)[21] कब नहीं)। ये भाषाएँ विशेष संकेतशब्द का उपयोग करती हैं void
यह इंगित करने के लिए कि कोई फ़ंक्शन कोई मान नहीं लौटाता है। ध्यान दें कि C/C++ फ़ंक्शंस के दुष्प्रभाव हो सकते हैं, जिसमें किसी भी परिवर्तनीय को संशोधित करना भी उपस्थित है जिनके पते मापदण्ड के रूप में पारित किए गए हैं। उदाहरण:
void Function1() { /* some code */ }
फ़ंक्शन कोई मान नहीं लौटाता है और इसे स्टैंड-अलोन फ़ंक्शन के रूप में कॉल करना पड़ता है, उदाहरण के लिए, Function1();
int Function2() {
return 5;
}
यह फ़ंक्शन एक परिणाम (संख्या 5) देता है, और कॉल एक अभिव्यक्ति का हिस्सा हो सकता है, उदाहरण के लिए, x + Function2()
char Function3(int number) {
char selection[] = {'S', 'M', 'T', 'W', 'T', 'F', 'S'};
return selection[number];
}
यह फ़ंक्शन 0 और 6 के बीच की संख्या को सप्ताह के संबंधित दिन के प्रारंभिक अक्षर में परिवर्तित करता है, अर्थात् 0 से 'S', 1 से 'M', ..., 6 से 'S'। इसे कॉल करने का परिणाम एक परिवर्तनीय को सौंपा जा सकता है, उदाहरण के लिए, num_day = Function3(number);
.
void Function4(int* pointer_to_var) {
(*pointer_to_var)++;
}
यह फ़ंक्शन कोई मान नहीं लौटाता है बल्कि उस परिवर्तनीय को संशोधित करता है जिसका पता मापदण्ड के रूप में पारित किया गया है; इसे साथ बुलाया जाएगा Function4(&variable_to_increment);
.
बुनियादी बोलियाँ
माइक्रोसॉफ्ट स्मॉल बेसिक
Example() ' Calls the subroutine
Sub Example ' Begins the subroutine
TextWindow.WriteLine("This is an example of a subroutine in Microsoft Small Basic.") ' What the subroutine does
EndSub ' Ends the subroutine
उपरोक्त उदाहरण में, Example()
उपनित्यक्रम को कॉल करता है।[22] वास्तविक उपनित्यक्रम को परिभाषित करने के लिए, Sub
उपनित्यक्रम नाम के साथ संकेतशब्द का उपयोग किया जाना चाहिए, जिसमें उपनित्यक्रम नाम Sub
के बाद आता है। सामग्री का अनुसरण करने के बाद, EndSub
टाइप करना होगा।
विज़ुअल बेसिक (क्लासिक)
विज़ुअल बेसिक (क्लासिक) भाषा में, उपक्रमादेश को फ़ंक्शंस या सब (या किसी क्लास से जुड़े होने पर तरीके) कहा जाता है। एक मापदण्ड के रूप में क्या पारित किया जा रहा है, इसे परिभाषित करने के लिए विज़ुअल बेसिक 6 "प्रकार" नामक विभिन्न शब्दों का उपयोग करता है। न्यूनता रूप से, एक अनिर्दिष्ट चर को परिवर्त के प्रकार के रूप में पंजीकृत किया जाता है और इसे ByRef (डिफ़ॉल्ट) या ByVal के रूप में पारित किया जा सकता है। इसके अलावा, जब कोई फ़ंक्शन या उप घोषित किया जाता है, तो उसे एक सार्वजनिक, निजी या मित्र पदनाम दिया जाता है, जो यह निर्धारित करता है कि क्या इसे उस प्रतिरूपक या परियोजना के बाहर अभिगम किया जा सकता है जिसमें इसे घोषित किया गया था।
- 'वैल्यू द्वारा [ByVal]' - किसी तर्क के मान को पते को पास करने के बजाय मान की एक प्रति पास करके प्रक्रिया में भेजने का एक तरीका। परिणामस्वरूप, परिवर्तनीय का वास्तविक मान उस प्रक्रिया द्वारा नहीं बदला जा सकता है जिसके लिए इसे पारित किया गया है।
- 'संदर्भ द्वारा [ByRef]' - किसी प्रक्रिया में किसी तर्क के मान की एक प्रति पास करने के बजाय, परिवर्तनीय का एक पता पास करके उसके मान को पास करने का एक तरीका। यह प्रक्रिया को वास्तविक चर तक पहुंचने की अनुमति देता है। परिणामस्वरूप, परिवर्तनीय का वास्तविक मान उस प्रक्रिया द्वारा बदला जा सकता है जिसके लिए इसे पारित किया गया है। जब तक अन्यथा निर्दिष्ट न हो, तर्क संदर्भ द्वारा पारित किए जाते हैं।
- 'सार्वजनिक' (वैकल्पिक) - इंगित करता है कि फ़ंक्शन प्रक्रिया सभी प्रतिरूपक में अन्य सभी प्रक्रियाओं के लिए पहुंच योग्य है। यदि ऐसे प्रतिरूपक में उपयोग किया जाता है जिसमें विकल्प निजी है, तो प्रक्रिया परियोजना के बाहर उपलब्ध नहीं है।
- 'निजी' (वैकल्पिक) - इंगित करता है कि फ़ंक्शन प्रक्रिया केवल उस प्रतिरूपक में अन्य प्रक्रियाओं के लिए पहुंच योग्य है जहां इसे घोषित किया गया है।
- 'मित्र' (वैकल्पिक) - केवल क्लास प्रतिरूपक में उपयोग किया जाता है। इंगित करता है कि फ़ंक्शन प्रक्रिया पूरे परियोजना में दिखाई देती है, लेकिन किसी ऑब्जेक्ट के उदाहरण के नियंत्रक को दिखाई नहीं देती है।
Private Function Function1()
' Some Code Here
End Function
फ़ंक्शन कोई मान नहीं लौटाता है और इसे स्टैंड-अलोन फ़ंक्शन के रूप में कॉल करना पड़ता है, उदाहरण के लिए, Function1
Private Function Function2() as Integer
Function2 = 5
End Function
यह फ़ंक्शन एक परिणाम (संख्या 5) देता है, और कॉल एक अभिव्यक्ति का हिस्सा हो सकता है, उदाहरण के लिए, x + Function2()
Private Function Function3(ByVal intValue as Integer) as String
Dim strArray(6) as String
strArray = Array("M", "T", "W", "T", "F", "S", "S")
Function3 = strArray(intValue)
End Function
यह फ़ंक्शन 0 और 6 के बीच की संख्या को सप्ताह के संबंधित दिन के प्रारंभिक अक्षर में परिवर्तित करता है, अर्थात् 0 से 'M', 1 से 'T', ..., 6 से 'S'। इसे कॉल करने का परिणाम एक परिवर्तनीय को सौंपा जा सकता है, उदाहरण के लिए, num_day = Function3(number)
.
Private Function Function4(ByRef intValue as Integer)
intValue = intValue + 1
End Function
यह फ़ंक्शन कोई मान नहीं लौटाता है बल्कि उस परिवर्तनीय को संशोधित करता है जिसका पता मापदण्ड के रूप में पारित किया गया है; इसे "Function4(variable_to_increment)" के साथ बुलाया जाएगा।
पीएल/आई
पीएल/आई में एक तथाकथित प्रक्रिया को निरुपक पारित किया जा सकता है जो तर्क के बारे में जानकारी प्रदान करता है, जैसे कि स्ट्रिंग की लंबाई और सरणी सीमाएं। इससे प्रक्रिया अधिक सामान्य हो जाती है और क्रमादेशित्र को ऐसी जानकारी देने की आवश्यकता समाप्त हो जाती है। न्यूनता रूप से पीएल/आई संदर्भ के आधार पर तर्क पारित करता है। द्वि-आयामी सरणी के प्रत्येक तत्व के चिह्न को बदलने के लिए एक (साधारण) फ़ंक्शन इस तरह दिख सकता है:
change_sign: procedure(array); declare array(*,*) float; array = -array; end change_sign;
इसे विभिन्न सरणियों के साथ निम्नानुसार कहा जा सकता है:
/* first array bounds from -5 to +10 and 3 to 9 */ declare array1 (-5:10, 3:9)float; /* second array bounds from 1 to 16 and 1 to 16 */ declare array2 (16,16) float; call change_sign(array1); call change_sign(array2);
पायथन
पायथन (प्रोग्रामिंग भाषा) में, संकेतशब्द def
किसी फ़ंक्शन को परिभाषित करने के लिए उपयोग किया जाता है। फ़ंक्शन का मुख्य भाग बनाने वाले कथनों को या तो उसी पंक्ति पर जारी रहना चाहिए या अगली पंक्ति से आरम्भ होना चाहिए और दूरारंभ होना चाहिए।[23] निम्नलिखित उदाहरण क्रमानुदेश "हैलो, वर्ल्ड!" प्रिंट करता है, इसके बाद अगली पंक्ति में "विकिपीडिया" है।
def simple_function():
print('Hello world!')
print('Wikipedia')
simple_function()
# output will be:
Hello World!
Wikipedia
def func(name)
print("welcome "+name)
print(func("martin"))
#output will be: welcome martin
स्थानीय चर, पुनरावर्तन और पुनर्प्रवेश
एक उपक्रमानुदेश को एक निश्चित मात्रा में स्क्रैच स्पेस का उपयोग करना उपयोगी लग सकता है; अर्थात्, मध्यवर्ती परिणामों को रखने के लिए उस उपक्रमानुदेश के निष्पादन के दौरान उपयोग की जाने वाली आभासी मेमोरी । इस स्क्रैच स्पेस में संग्रहीत परिवर्तनशील को स्थानीय परिवर्तनशील कहा जाता है, और स्क्रैच स्पेस को सक्रियण रिकॉर्ड कहा जाता है। एक सक्रियण रिकॉर्ड में आम तौर पर एक वापसी पता (संगणना) होता है जो यह बताता है कि उपक्रमानुदेश समाप्त होने पर नियंत्रण कहाँ से वापस भेजना है।
एक उपक्रमानुदेश में कॉल साइटों की कोई भी संख्या और प्रकृति हो सकती है। यदि प्रत्यावर्तन समर्थित है, तो एक उपक्रमानुदेश खुद को भी कॉल कर सकता है, जिससे उसका निष्पादन निलंबित हो जाता है जबकि उसी उपक्रमानुदेश का एक और नेस्टेड निष्पादन होता है। कुछ जटिल कलन विधि को सरल बनाने और जटिल समस्याओं को तोड़ने के लिए रिकर्सन एक उपयोगी साधन है। पुनरावर्ती भाषाएँ आम तौर पर प्रत्येक कॉल पर स्थानीय चर की एक नई प्रति प्रदान करती हैं। यदि क्रमादेशित्र चाहता है कि कॉल के बीच स्थानीय चर का मान समान रहे, तो उन्हें कुछ भाषाओं में स्थिर घोषित किया जा सकता है, या वैश्विक मूल्यों या सामान्य क्षेत्रों का उपयोग किया जा सकता है। फाइबोनैचि संख्याएँ खोजने के लिए C/C++ में पुनरावर्ती फ़ंक्शन का एक उदाहरण यहां दिया गया है:
int Fib(int n) {
if (n <= 1) {
return n;
}
return Fib(n - 1) + Fib(n - 2);
}
फोरट्रान जैसी पूर्वतर भाषाओं ने आरम्भ में रिकर्सन का समर्थन नहीं किया क्योंकि चर को सांख्यिकीय रूप से आवंटित किया गया था, साथ ही रिटर्न पते के लिए स्थान भी।[24] प्रारंभिक कंप्यूटर अनुदेश सेटों ने रिटर्न पते और परिवर्तनशील को स्टैक पर संग्रहीत करना कठिन बना दिया था। सूचकांक रजिस्टर या सामान्य प्रयोजन रजिस्टर वाली मशीनें, जैसे, सीडीसी 6000 श्रृंखला, पीडीपी-6, जीई 635, सिस्टम/360, यूनिवैक 1100 श्रृंखला, उन रजिस्टरों में से एक को स्टेक सूचक के रूप में उपयोग कर सकती हैं।
ALGOL के बाद की आधुनिक भाषाएँ जैसे PL/I और C (प्रोग्रामिंग भाषा) लगभग हमेशा एक स्टैक का उपयोग करती हैं, जो आमतौर पर उपक्रमानुदेश के प्रत्येक निष्पादन के लिए एक नया सक्रियण रिकॉर्ड प्रदान करने के लिए अधिकांश आधुनिक कंप्यूटर निर्देश सेट द्वारा समर्थित होती है। इस तरह, नेस्टेड निष्पादन प्रगति में अन्य निलंबित निष्पादनों पर प्रभाव की चिंता किए बिना अपने स्थानीय चर को संशोधित करने के लिए स्वतंत्र है। जैसे ही नेस्टेड कॉल जमा होती हैं, एक कॉल स्टैक संरचना बनती है, जिसमें प्रत्येक निलंबित उपक्रमानुदेश के लिए एक सक्रियण रिकॉर्ड होता है। वास्तव में, यह स्टैक संरचना वस्तुतः सर्वव्यापी है, और इसलिए सक्रियण रिकॉर्ड को आमतौर पर स्टैक फ़्रेम कहा जाता है।
कुछ भाषाएँ जैसे पास्कल (प्रोग्रामिंग भाषा), पीएल/आई, और एडा (प्रोग्रामिंग भाषा) भी नेस्टेड फ़ंक्शन का समर्थन करती हैं, जो केवल बाहरी (मूल) फ़ंक्शन के दायरे (प्रोग्रामिंग ) के भीतर कॉल करने योग्य फ़ंक्शन हैं। आंतरिक फ़ंक्शन के पास बाहरी फ़ंक्शन के स्थानीय चर तक पहुंच होती है जो उन्हें कॉल करता है। यह सक्रियण रिकॉर्ड के भीतर अतिरिक्त संदर्भ जानकारी संग्रहीत करके पूरा किया जाता है, जिसे डिस्प्ले भी कहा जाता है।
यदि किसी उपक्रमानुदेश को ठीक से निष्पादित किया जा सकता है, भले ही उसी उपक्रमानुदेश का दूसरा निष्पादन पहले से ही प्रगति पर हो, तो उस उपक्रमानुदेश को रीएंट्रेंट (उपनित्यक्रम) कहा जाता है। एक पुनरावर्ती उपक्रमानुदेश पुनः प्रविष्ट होना चाहिए। रीएंट्रेंट उपक्रमादेश थ्रेड (कंप्यूटर साइंस)|मल्टी-थ्रेडेड स्थितियों में भी उपयोगी होते हैं क्योंकि कई थ्रेड एक-दूसरे के साथ हस्तक्षेप करने के डर के बिना एक ही उपक्रमादेश को कॉल कर सकते हैं। आईबीएम सीआईसीएस लेनदेन प्रसंस्करण प्रणाली में, अर्ध-पुनर्प्रवेशक थोड़ा कम प्रतिबंधात्मक था, लेकिन कई थ्रेड्स द्वारा साझा किए गए एप्लिकेशन क्रमानुदेशों के लिए समान आवश्यकता थी।
अतिभारक
दृढ़ता से टाइप की गई भाषाओं में, कभी-कभी एक ही नाम के साथ कई फ़ंक्शन होना वांछनीय होता है, लेकिन विभिन्न प्रकार के डेटा पर, या विभिन्न मापदण्ड वर्णन के साथ काम करना होता है। उदाहरण के लिए, एक वर्गमूल फ़ंक्शन को वास्तविक, जटिल मानों या मैट्रिक्स पर संचालित करने के लिए परिभाषित किया जा सकता है। प्रत्येक मामले में उपयोग किया जाने वाला कलन विधि अलग है, और रिटर्न परिणाम भिन्न हो सकता है। एक ही नाम से तीन अलग-अलग फ़ंक्शन लिखने से, क्रमादेशित्र को प्रत्येक प्रकार के डेटा के लिए अलग-अलग नाम याद रखने की आवश्यकता नहीं होती है। इसके अलावा, यदि एक उपप्रकार को वास्तविक के लिए परिभाषित किया जा सकता है, तो सकारात्मक और नकारात्मक वास्तविकता को अलग करने के लिए, वास्तविक के लिए दो फ़ंक्शन लिखे जा सकते हैं, एक मापदण्ड सकारात्मक होने पर वास्तविक को वापस करने के लिए, और दूसरा मापदण्ड के सकारात्मक होने पर एक जटिल मान को वापस करने के लिए नकारात्मक।
वस्तु अभिमुखित प्रोग्रामिंग में, जब एक ही नाम वाले फ़ंक्शंस की एक श्रृंखला विभिन्न मापदण्ड वर्णन या विभिन्न प्रकार के मापदण्ड स्वीकार कर सकती है, तो प्रत्येक फ़ंक्शन को अतिभारित कहा जाता है।
यहां C++ में फ़ंक्शन अतिभारक का एक उदाहरण दिया गया है, जो एक ही नाम (क्षेत्र) लेकिन विभिन्न मापदंडों के साथ दो कार्यों के कार्यान्वयन को प्रदर्शित करता है:
#include <iostream>
double Area(double h, double w) { return h * w; }
/* The first Area function is for finding the area of a rectangle,
* so it accepts two numbers as parameters, for the height and width. */
double Area(double r) { return r * r * 3.14; }
/* The second Area function is for finding the area of a circle,
* so it only accepts one number as a parameter, for the radius. */
int main() {
double rectangle_area = Area(3, 4); // This calls the first Area function, because two parameters are provided.
double circle_area = Area(5); // This calls the second Area function, because only one parameter is provided.
std::cout << "Area of a rectangle is " << rectangle_area << std::endl;
std::cout << "Area of a circle is " << circle_area << std::endl;
}
एक अन्य उदाहरण के रूप में, एक फ़ंक्शन एक ऑब्जेक्ट (कंप्यूटर विज्ञान) का निर्माण कर सकता है जो निर्देशों को स्वीकार करेगा, और स्क्रीन पर इन बिंदुओं पर अपना पथ ट्रेस करेगा। ऐसे ढेर सारे मापदण्ड हैं जिन्हें कंस्ट्रक्टर (ट्रेस का रंग, प्रारंभिक x और y निर्देशांक, ट्रेस गति) में पास किया जा सकता है। यदि क्रमादेशित्र चाहता है कि कंस्ट्रक्टर केवल रंग मापदण्ड को स्वीकार करने में सक्षम हो, तो वह किसी अन्य कंस्ट्रक्टर को कॉल कर सकता है जो केवल रंग स्वीकार करता है, जो बदले में अन्य सभी मापदंडों के लिए डिफ़ॉल्ट मानों के एक सेट में गुजरने वाले सभी मापदंडों के साथ कंस्ट्रक्टर को कॉल करता है ( एक्स और वाई आम तौर पर स्क्रीन पर केंद्रित होंगे या मूल पर रखे जाएंगे, और गति कोडर के चयन के किसी अन्य मूल्य पर सेट की जाएगी)।
पीएल/आई के पास विभिन्न प्रकार के तर्कों के साथ बुलाए गए प्रविष्टि संदर्भों के एक सेट के लिए एक सामान्य नाम परिभाषित करने के लिए GENERIC
विशेषता है। उदाहरण:
DECLARE gen_name GENERIC( name WHEN(FIXED BINARY), flame WHEN(FLOAT), pathname OTHERWISE );
प्रत्येक प्रविष्टि के लिए एकाधिक तर्क परिभाषाएँ निर्दिष्ट की जा सकती हैं। जब तर्क फिक्स्ड बाइनरी हो तो "gen_name" पर कॉल करने पर "नाम" पर कॉल आएगी, फ्लोट होने पर "फ्लेम" आदि पर कॉल आएगी। यदि तर्क किसी भी विकल्प से मेल नहीं खाता है तो "पथनाम" पर कॉल किया जाएगा।
समापन
समापन (कंप्यूटर विज्ञान) एक उपक्रमानुदेश है जिसमें इसके कुछ चर के मूल्यों को उस वातावरण से लिया गया है जिसमें इसे बनाया गया था। समापन लिस्प प्रोग्रामिंग भाषा की एक उल्लेखनीय विशेषता थी, जिसे जॉन मैक्कार्थी (कंप्यूटर वैज्ञानिक) द्वारा प्रस्तावित किया गया था। कार्यान्वयन के आधार पर, समापन करना दुष्प्रभावों के लिए क्रियाविधि के रूप में काम कर सकता है।
सम्मेलन
फ़ंक्शंस की कोडिंग के लिए व्यापक संख्या में सम्मेलन विकसित किए गए हैं। उनके नामकरण के संबंध में, कई विकासकर्ता ने यह दृष्टिकोण अपनाया है कि किसी फ़ंक्शन का नाम एक क्रिया होना चाहिए जब यह एक निश्चित कार्य करता है, और जब यह कुछ पूछताछ करता है तो विशेषण, और एक संज्ञा जब इसका उपयोग चर को प्रतिस्थापित करने के लिए किया जाता है।
कुछ क्रमादेशित्र सुझाव देते हैं कि एक फ़ंक्शन को केवल एक ही कार्य करना चाहिए, और यदि कोई फ़ंक्शन एक से अधिक कार्य करता है, तो उसे अधिक कार्यों में विभाजित किया जाना चाहिए। उनका तर्क है कि सॉफ़्टवेयर रखरखाव में फ़ंक्शंस प्रमुख घटक हैं, और क्रमानुदेश में उनकी भूमिकाएँ अलग रहनी चाहिए।
अनुखंडीय प्रोग्रामिंग (आधुनीकीकरण कोड) के समर्थक इस बात की वकालत करते हैं कि प्रत्येक फ़ंक्शन की कोड के अन्य टुकड़ों पर न्यूनतम निर्भरता होनी चाहिए। उदाहरण के लिए, इस परिप्रेक्ष्य के समर्थकों द्वारा वैश्विक चर के उपयोग को आम तौर पर नासमझी माना जाता है, क्योंकि यह फ़ंक्शन और इन वैश्विक चर के बीच मजबूत युग्मन जोड़ता है। यदि ऐसा युग्मन आवश्यक नहीं है, तो उनकी सलाह है कि इसके बजाय पारित मापदण्ड (अभिकलित्र क्रमादेशन) को स्वीकार करने के कोड रीफैक्टरिंग फ़ंक्शन को कोड करें। तथापि, फ़ंक्शंस में पारित मापदंडों की संख्या बढ़ने से कोड पठनीयता प्रभावित हो सकती है।
वापसी कोड
इसके मुख्य या सामान्य प्रभाव के अलावा, एक उपनित्यक्रम को कॉलिंग क्रमानुदेश को इसके निष्पादन के दौरान होने वाली असाधारण स्थितियों के बारे में सूचित करने की आवश्यकता हो सकती है। कुछ भाषाओं और प्रोग्रामिंग मानकों में, यह अक्सर रिटर्न कोड के माध्यम से किया जाता है, कुछ मानक स्थान पर उपक्रमानुदेश द्वारा रखा गया एक पूर्णांक मान, जो सामान्य और असाधारण स्थितियों को एन्कोड ( कोडित करना) करता है।
आईबीएम सिस्टम/360 में, जहां उपनित्यक्रम से रिटर्न कोड की अपेक्षा की जाती थी, रिटर्न वैल्यू को अक्सर 4 के गुणक के रूप में डिज़ाइन किया गया था - ताकि इसे अतिरिक्त सशर्त परीक्षणों से बचने के लिए कॉल निर्देश के तुरंत बाद स्थित शाखा तालिका में सीधे शाखा तालिका सूचकांक के रूप में उपयोग किया जा सके, जिससे दक्षता में और सुधार हो सके। उदाहरण के लिए, सिस्टम/360 कोडांतरण भाषा में कोई लिख सकता है:
BAL 14, SUBRTN01 go to a subroutine, storing return address in R14
B TABLE(15) use returned value in reg 15 to index the branch table,
* branching to the appropriate branch instr.
TABLE B OK return code =00 GOOD }
B BAD return code =04 Invalid input } Branch table
B ERROR return code =08 Unexpected condition }
फ़ंक्शन कॉल का अनुकूलन
किसी फ़ंक्शन को कॉल करने में एक महत्वपूर्ण रनटाइम (अर्थगत) ओवरहेड होता है, जिसमें तर्कों को पास करना, उपक्रमादेश में ब्रांच करना और कॉलर पर वापस ब्रांच करना सम्मिलित है। ओवरहेड में अक्सर कुछ संसाधक रजिस्टरों को सहेजना और पुनर्स्थापित करना, कॉल फ्रेम स्टोरेज को आवंटित करना और पुनः प्राप्त करना आदि सम्मिलित होता है।[example needed] कुछ भाषाओं में, प्रत्येक फ़ंक्शन कॉल का तात्पर्य फ़ंक्शन के रिटर्न कोड के स्वचालित परीक्षण या इसके द्वारा उठाए जा सकने वाले अपवाद (प्रोग्रामिंग ) से निपटने से भी है। वस्तु अभिमुखित भाषाओं में ओवरहेड का एक महत्वपूर्ण स्रोत विधि कॉल के लिए गहन रूप से उपयोग किया जाने वाला गतिशील प्रेषण है।
प्रक्रिया कॉल के कुछ स्पष्ट अनुकूलन हैं जिन्हें प्रक्रियाओं के दुष्प्रभाव होने पर लागू नहीं किया जा सकता है। उदाहरण के लिए, अभिव्यक्ति में (f(x)-1)/(f(x)+1)
, क्रमानुदेश f
दो बार कॉल किया जाना चाहिए, क्योंकि दोनों कॉल अलग-अलग परिणाम दे सकते हैं। इसके अलावा, x
का मूल्य दूसरी कॉल से पहले दोबारा प्राप्त करना होगा, क्योंकि पहली कॉल ने इसे बदल दिया होगा। यह निर्धारित करना कि क्या किसी उपक्रमानुदेश का दुष्प्रभाव हो सकता है, बहुत कठिन है (वास्तव में, राइस प्रमेय के आधार पर अनिर्णीत है)। इसलिए, जबकि वे अनुकूलन पूरी तरह से कार्यात्मक प्रोग्रामिंग भाषाओं में सुरक्षित हैं, विशिष्ट अनिवार्य प्रोग्रामिंग के संकलनकर्ताों को आमतौर पर सबसे खराब स्थिति माननी पड़ती है।
इनलाइनिंग
इस ओवरहेड (अतिरिक्त) को खत्म करने के लिए इस्तेमाल की जाने वाली एक विधि प्रत्येक कॉल साइट पर उपक्रमानुदेश के निकाय का इनलाइन विस्तार या इनलाइनिंग है (बनाम फ़ंक्शन और बैक में ब्रांचिंग)। यह न केवल कॉल ओवरहेड से बचता है, बल्कि यह संकलनकर्ता को उस कॉल के संदर्भ और तर्कों को ध्यान में रखकर प्रक्रिया के मुख्य भाग को अधिक प्रभावी ढंग से कोड अनुकूलन करने की अनुमति भी देता है। सम्मिलित बॉडी को संकलनकर्ता द्वारा अनुकूलित किया जा सकता है। तथापि, इनलाइनिंग से आमतौर पर कोड का आकार बढ़ जाएगा, जब तक कि क्रमानुदेश में फ़ंक्शन के लिए केवल एक कॉल न हो।
यह भी देखें
- अतुल्यकालिक प्रक्रिया कॉल, एक उपक्रमानुदेश जिसे अन्य गतिविधियों द्वारा इसके मापदण्ड सेट किए जाने के बाद कॉल किया जाता है
- बिल्टिन फ़ंक्शन
- कमांड-क्वेरी पृथक्करण (सीक्यूएस)
- कोरआउट्स, उपक्रमानुदेश जो एक दूसरे को ऐसे कॉल करते हैं जैसे कि दोनों मुख्य क्रमानुदेश हों
- मूल्यांकन रणनीति
- आयोजन प्रबंधकर्ता , एक उपक्रमानुदेश जिसे किसी इनपुट इवेंट या बाधा डालना के जवाब में बुलाया जाता है
- फ़ंक्शन (गणित)
- कार्यात्मक प्रोग्रामिंग
- लैम्ब्डा फ़ंक्शन (अभिकलित्र क्रमादेशन), एक फ़ंक्शन जो किसी पहचानकर्ता से बंधा नहीं है
- विधि (अभिकलित्र क्रमादेशन)
- प्रतिरूपकर प्रोग्रामिंग
- ऑपरेटर अतिभारक कर रहा है
- संरक्षित प्रक्रिया
- स्थानांतरण
संदर्भ
- ↑ U.S. Election Assistance Commission (2007). "Definitions of Words with Special Meanings". Voluntary Voting System Guidelines. Archived from the original on 2012-12-08. Retrieved 2013-01-14.
- ↑ Subrata Dasgupta (7 January 2014). It Began with Babbage: The Genesis of Computer Science. Oxford University Press. pp. 155–. ISBN 978-0-19-930943-6.
- ↑ 3.0 3.1 Mauchly, J.W. (1982). "Preparation of Problems for EDVAC-type Machines". In Randell, Brian (ed.). डिजिटल कंप्यूटर की उत्पत्ति. Springer. pp. 393–397. doi:10.1007/978-3-642-61812-3_31. ISBN 978-3-642-61814-7.
- ↑ Wheeler, D. J. (1952). "The use of sub-routines in programmes" (PDF). Proceedings of the 1952 ACM national meeting (Pittsburgh) on - ACM '52. p. 235. doi:10.1145/609784.609816.
- ↑ Wilkes, M. V.; Wheeler, D. J.; Gill, S. (1951). इलेक्ट्रॉनिक डिजिटल कंप्यूटर के लिए प्रोग्राम तैयार करना. Addison-Wesley.
- ↑ Dainith, John (2004). ""सबरूटीन खोलें।" कंप्यूटिंग का एक शब्दकोश". Encyclopedia.com. Retrieved January 14, 2013.
- ↑ Turing, Alan M. (1945), Report by Dr. A.M. Turing on proposals for the development of an Automatic Computing Engine (ACE): Submitted to the Executive Committee of the NPL in February 1946 reprinted in Copeland, B. J., ed. (2005). Alan Turing's Automatic Computing Engine. Oxford: Oxford University Press. p. 383. ISBN 0-19-856593-3.
- ↑ Donald E. Knuth (1997). The Art of Computer Programming, Volume I: Fundamental Algorithms. Addison-Wesley. ISBN 0-201-89683-4.
- ↑ O.-J. Dahl; E. W. Dijkstra; C. A. R. Hoare (1972). संरचित प्रोग्रामिंग. Academic Press. ISBN 0-12-200550-3.
- ↑ Wilson, Leslie B. (2001). तुलनात्मक प्रोग्रामिंग भाषाएँ, तीसरा संस्करण. Addison-Wesley. p. 140. ISBN 0-201-71012-9.
- ↑ Turing, Alan Mathison (1946-03-19) [1945], Proposals for Development in the Mathematics Division of an Automatic Computing Engine (ACE) (एनबी। 1946-03-19 को राष्ट्रीय भौतिक प्रयोगशाला (ग्रेट ब्रिटेन) की कार्यकारी समिति के समक्ष प्रस्तुत किया गया।)
- ↑ Carpenter, Brian Edward; Doran, Robert William (1977-01-01) [October 1975]. "दूसरी ट्यूरिंग मशीन". The Computer Journal. 20 (3): 269–279. doi:10.1093/comjnl/20.3.269. (11 पृष्ठ)
- ↑ 13.0 13.1 Isaacson, Walter (18 September 2014). "ENIAC की महिलाओं पर वाल्टर इसाकसन". Fortune (in English). Archived from the original on 12 December 2018. Retrieved 2018-12-14.
- ↑ Planning and Coding of Problems for an Electronic Computing Instrument, Pt 2, Vol. 3 https://library.ias.edu/files/pdfs/ecp/planningcodingof0103inst.pdf Archived 12 November 2018 at the Wayback Machine (see pg 163 of the pdf for the relevant page)
- ↑ Guy Lewis Steele Jr. AI Memo 443. 'Debunking the "Expensive Procedure Call" Myth; or, Procedure call implementations considered harmful". Section "C. Why Procedure Calls Have a Bad Reputation".
- ↑
Frank, Thomas S. (1983). Introduction to the PDP-11 and Its Assembly Language. Prentice-Hall software series. Prentice-Hall. p. 195. ISBN 9780134917047. Retrieved 2016-07-06.
We could supply our assembling clerk with copies of the source code for all of our useful subroutines and then when presenting him with a mainline program for assembly, tell him which subroutines will be called in the mainline [...]
- ↑ Buttlar, Dick; Farrell, Jacqueline; Nichols, Bradford (1996). PThreads Programming: A POSIX Standard for Better Multiprocessing. "O'Reilly Media, Inc.". pp. 2–5. ISBN 978-1-4493-6475-5. OCLC 1036778036.
- ↑ "एआरएम सूचना केंद्र". Infocenter.arm.com. Retrieved 2013-09-29.
- ↑ "x64 stack usage". Microsoft Docs. Microsoft. Retrieved 5 August 2019.
- ↑ "फ़ंक्शन प्रकार". Msdn.microsoft.com. Retrieved 2013-09-29.
- ↑ "निःशुल्क फ़ंक्शन से क्या तात्पर्य है".
- ↑ "Small Basic Getting Started Guide: Chapter 9: Subroutines". Microsoft.
- ↑ "4. More Control Flow Tools — Python 3.9.7 documentation".
- ↑ Verhoeff, Tom (2018). "A Master Class on Recursion". In Böckenhauer, Hans-Joachim; Komm, Dennis; Unger, Walter (eds.). निचली सीमा और उच्च ऊंचाई के बीच रोमांच: जुराज ह्रोमकोविच को उनके 60वें जन्मदिन के अवसर पर समर्पित निबंध. Springer. p. 616. ISBN 978-3-319-98355-4. OCLC 1050567095.