वैरिएडिक फ़ंक्शन

गणित और कंप्यूटर प्रोग्रामिंग में, एक वैरिएडिक फ़ंक्शन अनिश्चितकालीन कार्य होता है, अर्थात, जो तर्कों की एक परिवर्तनीय संख्या को स्वीकार करता है। वैरिएडिक फ़ंक्शन के लिए समर्थन विभिन्न प्रोग्रामिंग लैंग्वेज में व्यापक रूप से भिन्न होता है।

परिवर्तनशील शब्द एक नवविज्ञानवाद है, जो 1936-1937 तक चला। 1970 के दशक तक इस शब्द का व्यापक रूप से उपयोग नहीं किया गया था।

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

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

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

कार्यात्मक लैंग्वेज में परिवर्तनशील को आवेदन करना कार्य का पूरक माना जा सकता है, जो एक कार्य और एक सूची/अनुक्रम/सरणी को तर्क के रूप में लेता है, और उस सूची में दिए गए तर्कों के साथ कार्य को कॉल करता है, इस प्रकार कार्य में तर्कों की एक चर संख्या पारित करता है। कार्यात्मक लैंग्वेज हास्केल (प्रोग्रामिंग लैंग्वेज) में, प्रकार वर्ग T का मान लौटाकर वैरिएडिक फ़ंक्शन को कार्यान्वित किया जा सकता है ; यदि के उदाहरण T अंतिम वापसी मान हैं r और एक कार्य (T t) => x -> t, यह किसी भी संख्या में अतिरिक्त तर्क की अनुमति देता है x.

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

सी में
C (प्रोग्रामिंग लैंग्वेज) में वैरिएडिक फ़ंक्शन को सुवाह्य रूप से लागू करने के लिए, मानक stdarg.h|stdarg.h हेडर पंक्ति का उपयोग किया जाता है. पुराने varargs.h|varargs.h हेडर के पक्ष में अस्वीकृत कर दिया गया है stdarg.h. C++ में, हेडर पंक्ति cstdarg प्रयोग किया जाता है।

यह तर्कों की मनमानी संख्या के औसत की गणना करेगा। ध्यान दें कि कार्यों तर्कों की संख्या या उनके प्रकारों को नहीं जानता है। उपरोक्त कार्य अपेक्षा करता है कि प्रकार int होंगे, और तर्कों की संख्या पहले तर्क में पारित की जाएगी (यह एक लगातार उपयोग है लेकिन लैंग्वेज या संकलनकर्ता द्वारा किसी भी तरह से लागू नहीं किया गया है)। कुछ अन्य मामलों में, उदाहरण के लिए मुद्रण , एक प्रारूप तार से तर्कों की संख्या और प्रकार का पता लगाया जाता है। दोनों ही मामलों में, यह प्रोग्रामर पर निर्भर करता है कि वह सही जानकारी प्रदान करे। (वैकल्पिक रूप से, संख्या इंगित करने के लिए  NULL जैसे प्रहरी मान का उपयोग किया जा सकता है।) यदि कार्य की अपेक्षा से कम तर्क पारित किए जाते हैं, या तर्क के प्रकार गलत हैं, तो यह इसे मेमोरी के अमान्य क्षेत्रों में पढ़ने का कारण बन सकता है और प्रारूप तार हमले जैसी कमजोरियों को जन्म दे सकता है।.

stdarg.h एक प्रकार घोषित करता है, va_list, और चार मैक्रोज़ को परिभाषित करता है:va_start, va_arg,va_copy, औरva_end. प्रत्येक मंगलाचरण va_start और va_copy के अनुरूप मंगलाचरण से मेल खाना चाहिए va_end. परिवर्तनीय तर्कों के साथ काम करते समय, एक कार्य सामान्यता एक प्रकार का चर घोषित करता है va_list (ap उदाहरण में) जिसे वृहत् द्वारा कुशलतापूर्वक किया जाएगा।


 * 1) va_start दो तर्क लेता है, a va_list ऑब्जेक्ट और कार्य के अंतिम प्राचल का संदर्भ (अध्याहार से पहले वाला; बहुत बड़ा इसका उपयोग अपने चाल प्राप्त करने के लिए करता है)। C23 में, दूसरे तर्क की अब आवश्यकता नहीं होगी और वैरिएडिक फ़ंक्शन को दीर्घवृत्त से पहले नामित प्राचल की आवश्यकता नहीं होगी। यह आरंभ करता है va_list द्वारा उपयोग के लिए वस्तु va_arg या va_copy. यदि संदर्भ गलत है तो संकलनकर्ता सामान्यता एक चेतावनी जारी करेगा (उदाहरण के लिए पिछले प्राचल से भिन्न प्राचल का संदर्भ, या पूरी तरह से अलग ऑब्जेक्ट का संदर्भ), लेकिन संकलन को सामान्य रूप से पूरा होने से नहीं रोकेगा।
 * 2) va_arg दो तर्क लेता है, एक va_list ऑब्जेक्ट (पहले प्रारंभ किया गया) और एक प्रकार का वर्णनकर्ता। यह अगले चर तर्क तक विस्तारित होता है, और इसमें निर्दिष्ट प्रकार होता है। का क्रमिक आह्वान va_arg प्रत्येक परिवर्तनीय तर्क को बारी-बारी से संसाधित करने की अनुमति दें। अनिर्दिष्ट व्यवहार तब होता है जब प्रकार गलत है या कोई अगला चर तर्क नहीं है।
 * 3) va_end एक तर्क लेता है, एक va_list वस्तु। यह साफ़ करने का काम करता है. उदाहरण के लिए, यदि कोई चर तर्कों को एक से अधिक बार अवलोकन करना चाहता है, तो प्रोग्रामर आपका पुनः आरंभ करेगा va_list आह्वान द्वारा वस्तु va_end और तब va_start फिर से उस पर.
 * 4) va_copy दो तर्क लेता है, दोनों va_list वस्तुएं। यह दूसरे को (जिसे प्रारंभ किया गया होगा) पहले में प्रतिरूप करता है। एक से अधिक उदाहरणों में परिवर्तनीय तर्कों को अवलोकन करने पर वापस जाकर, इसे लागू करके प्राप्त किया जा सकता है va_start पहले पर va_list, फिर उपयोग करना va_copy इसे एक सेकंड में प्रतिरूप करने के लिए va_list. परिवर्तनीय तर्कों को पहली बार अवलोकन करने के बाद va_arg और पहला va_list (इसके साथ इसका निपटान va_end), प्रोग्रामर चर तर्कों को दूसरी बार अवलोकन कर सकता है va_arg और दूसरा va_list. va_end को प्रतिरूप पर भी कॉल करने की आवश्यकता है va_list युक्त कार्य के वापस आने से पहले।

C# में

सी पार्श्व संकेतशब्द का उपयोग करके वैरिएडिक फ़ंक्शन का वर्णन करता है।, तर्कों के लिए एक प्रकार प्रदान किया जाना चाहिए हालांकि object[] का उपयोग अर्थबोधक के रूप में उपयोग किया जा सकता है। आजीविका स्थान पर, आप या तो तर्कों को एक-एक करके सूचीबद्ध कर सकते हैं, या आवश्यक तत्व प्रकार वाले पहले से मौजूद सरणी को सौंप सकते हैं। वैरिएडिक रूप का उपयोग बाद के लिए वाक्यात्मक शर्करा है।

प्रणाली का उपयोग करना;

कक्षा कार्यक्रम

{   static int Foo(int a, int b, params int[] args) {       // Return the sum of the integers in args, ignoring a and b.          int sum = 0; foreach (int i in args) sum + = मैं; return sum; }   static void Main(string[] args) {       Console.WriteLine(Foo(1,2)); // 0 Console.WriteLine(Foo(1, 2, 3, 10, 20)); //33 int[] manyValues = new int[] {13, 14, 15 }; Console.WriteLine(Foo(1,2, manyValues)); //42 } }

C++ में
C++ में बुनियादी विविधतापूर्ण सुविधा बहुत हद तक C के समान है। एकमात्र अंतर वाक्य रचना में है, जहां दीर्घवृत्त से पहले अल्पविराम को छोड़ा जा सकता है। C++ नामित मापदंडों के बिना वैरिएडिक फ़ंक्शन की अनुमति देता है लेकिन तब से उन तर्कों तक पहुंचने का कोई तरीका प्रदान नहीं करता है  कार्य के अंतिम निश्चित तर्क के नाम की आवश्यकता है।


 * 1) include
 * 2) include

void simple_printf(const char* fmt...) // C-style const char* fmt, ... is also valid

{   va_list args; va_start(args, fmt); while (*fmt != '\0') { if (*fmt == 'd') { int i = va_arg(args, int); std::cout << i << '\n'; } else if (*fmt == 'c') { // note automatic conversion to integral type int c = va_arg(args, int); std::cout << static_cast (c) << '\n'; } else if (*fmt == 'f') { double d = va_arg(args, double); std::cout << d << '\n'; }       ++ fmt; }   va_end(args); }

int main

{   simple_printf(dcff, 3, 'a', 1.999, 42.5); }

वैरिएडिक नमूना (पैरामीटर पैक) का उपयोग C++ में अंतर्निहित लैंग्वेज (उच्च-क्रम कार्य) के साथ भी किया जा सकता है।


 * 1) include

template 

void foo_print(Ts... args)

{   ((std::cout << args << ''), ...); }

int main

{   std::cout << std::boolalpha; foo_print(1, 3.14f); // 1 3.14 foo_print(Foo, 'b', true, nullptr); // Foo b true nullptr }

सी++ के लिए सीईआरटी कोडिंग मानक दुरुपयोग के कम जोखिम के कारण सी-स्टाइल वैरिएडिक फ़ंक्शन की तुलना में सी++ में वैरिएडिक नमूना (पैरामीटर पैक) के उपयोग को दृढ़ता से प्राथमिकता देते हैं।

गो में
गो (प्रोग्रामिंग लैंग्वेज) में वैरिएडिक फ़ंक्शन को किसी भी संख्या में अनुगामी तर्कों के साथ बुलाया जा सकता है। fmt.Println एक सामान्य वैरिएडिक फ़ंक्शन है; यह कैच-ऑल प्रकार के रूप में एक खाली अंतराफलक का उपयोग करता है।

आउटपुट:

कुल मिलाकर [1 2] का योग 3 है

कुल मिलाकर [1 2 3] का योग 6 है

कुल मिलाकर [1 2 3 4] का योग 10 है

जावा में
C# की तरह, जावा (प्रोग्रामिंग लैंग्वेज) में } प्रकार कैच-ऑल के रूप में उपलब्ध है।

जावास्क्रिप्ट में
जावास्क्रिप्ट विभिन्न प्रकार के तर्कों की परवाह नहीं करता है।

तर्क ऑब्जेक्ट का उपयोग करके एक वैरिएडिक फ़ंक्शन बनाना भी संभव है, हालांकि यह केवल प्रकार्य संकेतशब्द के साथ बनाए गए प्रकार्य के साथ प्रयोग करने योग्य है।

लुआ (प्रोग्रामिंग लैंग्वेज) में
लुआ (प्रोग्रामिंग लैंग्वेज) प्रकार्य वापसी संकेतशब्द का उपयोग करके अन्य मानों की तरह ही अन्य प्रकार्य में वेरार्ग पास कर सकते हैं। लूआ संस्करण 5.2 या उच्चतर का उपयोग करके तालिकाओं को वैरिएडिक फ़ंक्शन में पारित किया जा सकता है table.unpack, या लुआ 5.1 या उससे कम unpack. वेरार्ग को एक मान के रूप में वेरार्ग के साथ एक तालिका बनाकर उपयोग किया जा सकता है।

पास्कल (प्रोग्रामिंग लैंग्वेज) में
पास्कल (प्रोग्रामिंग लैंग्वेज) में चार अंतर्निहित प्रक्रियाएं हैं जिन्हें वैरिएडिक के रूप में परिभाषित किया गया है, जो इस विशेष स्थिति के कारण, संकलक के लिए आंतरिक हैं। ये हैं पढ़ें, readln, लिखें, और writeln प्रक्रियाएं. हालाँकि, प्रक्रियाओं या कार्यों के लिए डिफ़ॉल्ट तर्क की अनुमति देने वाले वैकल्पिक विनिर्देश हैं जो उन्हें वैरिएडिक रूप से काम करते हैं, साथ ही बहुरूपता (कंप्यूटर विज्ञान)भी है जो एक प्रक्रिया या प्रकार्य को अलग-अलग पैरामीटर रखने की अनुमति देता है। वह read[ln] और write[ln] सभी प्रक्रियाओं का प्रारूप समान है:

पढ़ें[एलएन] [( [फ़ाइल ,] चर [, चर ...] )] ;

लिखें[एलएन] [( [फ़ाइल][, मूल्य [, मूल्य ...] )] ;

कहाँ


 * file एक वैकल्पिक फ़ाइल चर है, जिसे यदि छोड़ दिया जाए तो यह डिफ़ॉल्ट हो जाता है input के लिए read और readln, या डिफ़ॉल्ट output के लिए write और writeln;
 * variable एक अदिश राशि है जैसे कि चार (वर्ण), पूर्णांक, या वास्तविक (या कुछ संकलक के लिए, कुछ रिकॉर्ड प्रकार या सरणी प्रकार जैसे स्ट्रिंग); और
 * value एक चर या स्थिरांक है।

उदाहरण:

उपरोक्त उदाहरण में, जहां तक ​​संकलक का सवाल है, लाइनें 9 और 13 समान हैं, क्योंकि यदि input फ़ाइल चर को read या readln कथन द्वारा पढ़ा जा रहा है तो फ़ाइल चर को छोड़ा जा सकता है। साथ ही, संकलक पंक्ति 15 और 20 को समान मानता है, क्योंकि यदि फ़ाइल चर को outputमें लिखा जा रहा है ,तो इसे छोड़ा जा सकता है, जिसका अर्थ है (पंक्ति 20 पर) क्योंकि प्रक्रिया में कोई तर्क पारित नहीं किया जा रहा है, कोष्ठक तर्कों को सूचीबद्ध करते हैं मिटाया जा सकता है। पंक्ति 26 से पता चलता है कि writeln कथन में किसी भी संख्या में तर्क हो सकते हैं, और वे एक उद्धृत स्ट्रिंग, एक चर, या यहां तक ​​कि एक सूत्र परिणाम भी हो सकते हैं।

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

पास्कल अनुपस्थिति तर्कों का भी समर्थन करता है, जहां तर्क का मान, यदि प्रदान नहीं किया गया है, तो एक अनुपस्थिति मान दिया जाता है।

पहले उदाहरण के लिए, बहुरूपता, निम्नलिखित पर विचार करें:

उपरोक्त उदाहरण में, यदि दो पूर्णांक मानों के साथ कोadd कहा जाता है, पंक्ति 1 पर घोषित प्रकार्य को बुलाया जाएगा; यदि तर्कों में से एक पूर्णांक है और एक वास्तविक है, तो पंक्ति 3 या 4 पर प्रकार्य को कॉल किया जाता है, जो इस पर निर्भर करता है कि कौन सा पूर्णांक है। यदि दोनों वास्तविक हैं, तो पंक्ति 2 पर प्रकार्य को कॉल किया जाता है।

अनुपस्थिति पैरामीटर के लिए, निम्नलिखित पर विचार करें:

पंक्ति 6 ​​पर, (और नीचे की पंक्तियाँ में) पैरामीटर = 0 संकलक को बताता है, "यदि कोई तर्क प्रदान नहीं किया गया है, तो तर्क को शून्य मानें"। पंक्ति 19 पर, कोई तर्क नहीं दिया गया, इसलिए प्रकार्य 0 लौटाता है। लाइन 20 पर, किसी भी तर्क के लिए या तो एक संख्या या एक चर प्रदान किया जा सकता है, और जैसा कि लाइन 22 पर दिखाया गया है, एक स्थिरांक।

पीएचपी में
जब तक तर्क टाइप नहीं किया जाता है तब तक PHP विभिन्न प्रकार के तर्कों की परवाह नहीं करता है।

और वैरिएडिक तर्क टाइप किए:

पायथन में
पायथन (प्रोग्रामिंग लैंग्वेज) विभिन्न प्रकार के तर्कों की परवाह नहीं करता है।

कीवर्ड तर्कों को शब्दकोश में संग्रहित किया जा सकता है, उदा. def bar(*args, **kwargs).

रकु में
राकू (प्रोग्रामिंग लैंग्वेज) में, विभिन्न प्रकार के प्रकार्य बनाने वाले पैरामीटर के प्रकार को स्लर्पी एरे पैरामीटर के रूप में जाना जाता है और उन्हें तीन समूहों में वर्गीकृत किया जाता है:

चपटा घोल
इन मापदंडों को एक एकल तारांकन (*) के साथ घोषित किया जाता है और वे तत्वों की एक या अधिक परतों को भंग करके तर्कों को समतल करते हैं जिन्हें पुनरावृत्त किया जा सकता है (यानी, Iterables))।

sub foo($a, $b, *@args) { say @args.perl; }

foo(1,2) # []

foo(1,2,3) # [3]

foo(1, 2, 3, "hello" ) # [3 "hello" ]

foo(1, 2, 3, [4, 5], [6]); # [3, 4, 5, 6]

बिना चपटा घोल
ये पैरामीटर दो तारांकन के साथ घोषित किए गए हैं और वे सूची के अंदर किसी भी पुनरावृत्त तर्क को समतल नहीं करते हैं, लेकिन तर्क को कमोबेश वैसे ही रखते हैं:

sub bar($a, $b, **@args) { say @args.perl; }

bar(1,2); # []

bar(1, 2, 3); #[3]

bar(1, 2, 3, "hello" ); # [3  "hello" ]

bar(1, 2, 3, [4, 5], [6]); # [3, [4, 5], [6]]

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

sub zaz($a, $b, +@args) { say @args.perl; }

zaz(1, 2); # []

zaz(1, 2, 3); #[3]

zaz(1, 2, 3, "hello"); # [3 "hello" ]

zaz(1, 2, [4, 5]); # [4, 5], single argument fills up array

zaz(1, 2, 3, [4, 5]); # [3, [4, 5, **behaving as **@

zaz(1, 2, 3, [4, 5], [6]); # [3, [4, 5], [6, **behaving as **@

रूबी में
रूबी (प्रोग्रामिंग लैंग्वेज) विभिन्न प्रकार के तर्कों की परवाह नहीं करती है।

जंग में
ज़ंग (प्रोग्रामिंग लैंग्वेज) प्रकार्य में वैरिएडिक तर्कों का समर्थन नहीं करता है। इसके अतिरिक्त, यह मैक्रो (कंप्यूटर विज्ञान) का उपयोग करता है।

जंग एक c_variadic फीचर स्विच के माध्यम से C के वैरिएडिक प्रणाली के साथ बातचीत करने में सक्षम है। अन्य C इंटरफेस की तरह, सिस्टम को जंग के लिए unsafe माना जाता है।

स्विफ्ट में
स्विफ्ट (प्रोग्रामिंग लैंग्वेज) विभिन्न प्रकार के तर्कों की परवाह करती है, लेकिन सभी को पकड़ती है Any प्रकार उपलब्ध है.

टी.सी.एल में
एक टीसीएल प्रक्रिया या लैम्ब्डा तब वैरिएडिक होती है जब इसका अंतिम तर्क argsहोता है : इसमें शेष सभी तर्कों की एक सूची (संभवतः खाली) होगी। यह पैटर्न कई अन्य प्रक्रिया-जैसी विधियों में आम है।

यह भी देखें

 * जावा सिंटैक्स#Varargs
 * वैरिएडिक स्थूल (सी प्रोग्रामिंग लैंग्वेज)
 * वैरिएडिक टेम्पलेट

बाहरी संबंध

 * Variadic function. Rosetta Code task showing the implementation of variadic functions in over fifty programming languages.
 * Variable Argument Functions — A tutorial on Variable Argument Functions for C++
 * GNU libc manual