मैं मैक्रो कॉन्सेप्ट को अच्छी तरह से नहीं समझता। स्थूल क्या है? मुझे समझ में नहीं आता कि यह फ़ंक्शन से कैसे अलग है? फ़ंक्शन और मैक्रो दोनों में कोड का एक ब्लॉक होता है। तो मैक्रो और फ़ंक्शन कैसे भिन्न होते हैं?
मैं मैक्रो कॉन्सेप्ट को अच्छी तरह से नहीं समझता। स्थूल क्या है? मुझे समझ में नहीं आता कि यह फ़ंक्शन से कैसे अलग है? फ़ंक्शन और मैक्रो दोनों में कोड का एक ब्लॉक होता है। तो मैक्रो और फ़ंक्शन कैसे भिन्न होते हैं?
जवाबों:
मैं इस उत्तर पर ध्रुवीकरण वाले मतदान पैटर्न को देखने के बाद निम्नलिखित स्पष्टीकरण जोड़ना चाहूंगा।
उत्तर तकनीकी सटीकता और व्यापक सामान्यीकरण को ध्यान में रखते हुए नहीं लिखा गया था। यह सरल भाषा में व्याख्या करने का एक विनम्र प्रयास था, मैक्रो और फ़ंक्शंस के बीच एक प्रोग्रामिंग नौसिखिया के बीच का अंतर, पूर्ण या सटीक होने की कोशिश के बिना (वास्तव में यह सटीक होने से बहुत दूर है)। उत्तर का प्रारूपण करते समय सी प्रोग्रामिंग भाषा मेरे दिमाग में थी, लेकिन इसका स्पष्ट रूप से उल्लेख नहीं करने और किसी भी (संभावित) भ्रम का कारण बनने के लिए मेरी माफी।
मैं वास्तव में Jörg W Mittag द्वारा साझा किए गए उत्तर का संबंध है । यह पढ़ने में बहुत आनंददायक था (मैं कितना कम जानता हूं) और मैंने इसे पोस्ट किए जाने के तुरंत बाद इसे अपटूडेट किया। मैं अभी सॉफ्टवेयर इंजीनियरिंग स्टैक एक्सचेंज में शुरू हुआ, और अब तक का अनुभव और चर्चा वास्तव में आनंददायक रही है।
मैं इस उत्तर को यहां छोड़ दूंगा क्योंकि यह अन्य सॉफ्टवेयर डेवलपमेंट न्यूबायर्स के लिए मददगार हो सकता है, तकनीकी कॉन्सेप्ट में फंसने के बिना एक अवधारणा को समझने की कोशिश कर रहा है।
मैक्रो और फंक्शन दोनों कोड की स्व निहित इकाई का प्रतिनिधित्व करते हैं। वे दोनों उपकरण हैं जो एक कार्यक्रम के मॉड्यूलर डिजाइन में सहायता करते हैं। प्रोग्रामर के दृष्टिकोण से जो स्रोत कोड लिख रहे हैं, वे काफी समान दिखाई देते हैं। हालांकि, वे अलग-अलग हैं कि प्रोग्राम निष्पादन जीवनचक्र के दौरान उन्हें कैसे संभाला जाता है।
एक मैक्रो को एक बार परिभाषित किया जाता है और एक कार्यक्रम में बहुत सारे स्थानों पर उपयोग किया जाता है। प्री-प्रोसेसिंग स्टेज के दौरान मैक्रो को इनलाइन का विस्तार मिलता है। स्रोत कोड संकलित होने के बाद, यह तकनीकी रूप से एक अलग इकाई नहीं रहता है। मैक्रो की परिभाषा में दिए गए बयान अन्य निर्देशों की तरह ही प्रोग्राम निर्देशों का हिस्सा बन जाते हैं।
मैक्रो लिखने के पीछे मकसद प्रोग्रामर के लिए सोर्स कोड लिखना और मैनेज करना है। मैक्रों आमतौर पर सरल कार्यों के लिए वांछित होते हैं, जहां एक पूर्ण कार्य लिखना एक प्रदर्शन ओवरहेड / रनटाइम जुर्माना होगा। उन स्थितियों के उदाहरण जहां फ़ंक्शन पर एक मैक्रो बेहतर है:
निरंतर मूल्यों (जैसे गणितीय या वैज्ञानिक मान), या कुछ प्रोग्राम विशिष्ट पैरामीटर का उपयोग करना।
लॉग संदेश मुद्रित करना या जोर देना।
सरल गणना या स्थिति जांच करना।
मैक्रो का उपयोग करते समय, एक स्थान पर परिवर्तन / सुधार करना आसान होता है जो प्रोग्राम में मैक्रो का उपयोग करने पर हर जगह तुरंत उपलब्ध होता है। परिवर्तनों को प्रभावी करने के लिए कार्यक्रम का एक सरल पुनर्संयोजन आवश्यक है।
दूसरी ओर फ़ंक्शन कोड को प्रोग्राम के भीतर एक अलग इकाई के रूप में संकलित किया जाता है और आवश्यकता होने पर ही प्रोग्राम निष्पादन के दौरान मेमोरी में लोड किया जाता है। फंक्शन कोड बाकी प्रोग्राम से स्वतंत्र पहचान रखता है। यदि फ़ंक्शन को एक से अधिक बार कॉल किया जाता है, तो लोड किए गए कोड का पुन: उपयोग किया जाता है। जब रनिंग प्रोग्राम में फंक्शन कॉल का सामना करना पड़ता है, तो रनटाइम सबसिस्टम द्वारा इसे नियंत्रित किया जाता है और रनिंग प्रोग्राम (रिटर्न इंस्ट्रक्शन एड्रेस) के संदर्भ को संरक्षित किया जाता है।
हालांकि, एक मामूली प्रदर्शन जुर्माना है जिसे किसी फ़ंक्शन को कॉल करते समय सामना करना पड़ता है (संदर्भ स्विच करना, मुख्य प्रोग्राम निर्देशों के रिटर्न एड्रेस को संरक्षित करना, पैरामीटर पारित करना और रिटर्न वैल्यू को संभालना आदि)। इसलिए, फ़ंक्शन का उपयोग केवल कोड के जटिल ब्लॉकों के लिए वांछित है (मैक्रोज़ के खिलाफ जो सरल मामलों को संभालता है)।
अनुभव के साथ, एक प्रोग्रामर एक विवेकपूर्ण निर्णय लेता है कि क्या समग्र कार्यक्रम वास्तुकला में मैक्रो या फ़ंक्शन के रूप में कोड का एक टुकड़ा एक अच्छा फिट होगा।
दुर्भाग्य से, प्रोग्रामिंग में "मैक्रो" शब्द के कई अलग-अलग उपयोग हैं।
भाषाओं के लिस्प परिवार में, और उनके द्वारा प्रेरित भाषाएं, साथ ही स्काला और हास्केल जैसी कई आधुनिक कार्यात्मक या कार्यात्मक-प्रेरित भाषाएं, साथ ही साथ कुछ अनिवार्य भाषाएं जैसे बू, एक मैक्रो कोड का एक टुकड़ा है जो संकलन के समय चलता है (या कम से कम एक कंपाइलर के बिना कार्यान्वयन के लिए रनटाइम से पहले) और सार सिंटैक्स ट्री (या जो कुछ विशेष भाषा में समतुल्य है, जैसे लिस्प में बदल सकता है, यह एस-एक्सप्रेशंस होगा) संकलन के दौरान कुछ और। उदाहरण के लिए, कई योजना कार्यान्वयन में, for
एक मैक्रो है जो शरीर में कई कॉल में फैलता है। सांख्यिकीय रूप से टाइप की जाने वाली भाषाओं में, मैक्रोज़ अक्सर टाइप-सुरक्षित होते हैं, अर्थात वे ऐसे कोड का उत्पादन नहीं कर सकते हैं जो अच्छी तरह से टाइप न किए गए हों।
भाषाओं के सी परिवार में, मैक्रोज़ पाठ प्रतिस्थापन के समान हैं। जिसका अर्थ यह भी है कि वे ऐसे कोड का उत्पादन कर सकते हैं जो अच्छी तरह से टाइप नहीं किया गया है, या यहां तक कि वाक्यगत रूप से कानूनी नहीं है।
मैक्रो-असेम्बलर्स में, "मैक्रोज़" "वर्चुअल निर्देश" को संदर्भित करता है, अर्थात निर्देश जो कि सीपीयू मूल रूप से समर्थन नहीं करता है लेकिन यह उपयोगी है, और इसलिए कोडांतरक आपको उन निर्देशों का उपयोग करने की अनुमति देता है और उन्हें कई निर्देशों में विस्तारित करेगा जो सीपीयू समझता है ।
एप्लिकेशन स्क्रिप्टिंग में, एक "मैक्रो" उन कार्यों की एक श्रृंखला को संदर्भित करता है जो उपयोगकर्ता "रिकॉर्ड" और "बैक प्ले" कर सकता है।
वे सभी कुछ प्रकार के निष्पादन योग्य कोड में हैं, जिसका अर्थ है कि वे कुछ अर्थों में कार्यों के रूप में देखे जा सकते हैं। हालांकि, लिस्प मैक्रो के मामले में, उदाहरण के लिए, उनके इनपुट और आउटपुट प्रोग्राम के टुकड़े हैं। सी के मामले में, उनका इनपुट और आउटपुट टोकन हैं। पहले तीन में भी बहुत महत्वपूर्ण अंतर है कि उन्हें संकलन के समय निष्पादित किया जाता है । वास्तव में, सी प्रीप्रोसेसर मैक्रोज़, जैसा कि नाम से पता चलता है, वास्तव में संकलक तक पहुंचने से पहले ही निष्पादित हो जाते हैं ।
सी भाषा परिवार में एक मैक्रो डेफिनिशन , एक प्रीप्रोसेसर कमांड, कोड के एक पैरामीरिज्ड टेम्प्लेट को निर्दिष्ट करता है जिसे परिभाषा में संकलित किए बिना मैक्रो कॉल पर प्रतिस्थापित किया जाता है। इसका मतलब यह है कि सभी मुफ्त चर मैक्रो कॉल के संदर्भ में बाध्य होना चाहिए। पैरामीटर के i++
बहुवचन उपयोग द्वारा एक पक्ष प्रभाव के साथ पैरामीटर तर्क दोहराया जा सकता है। 1 + 2
कुछ पैरामीटर के तर्क का पाठ प्रतिस्थापन x
, संकलन से पहले होता है, और अप्रत्याशित व्यवहार x * 3
( 7
io 9
) का कारण हो सकता है । मैक्रो परिभाषा के मैक्रो बॉडी में एक त्रुटि मैक्रो कॉल पर संकलन पर ही दिखाई देगी।
समारोह परिभाषा मुक्त चर समारोह शरीर के संदर्भ के लिए बाध्य के साथ निर्दिष्ट कोड; नहीं समारोह कॉल ।
मैक्रो हालांकि प्रतीत होता है नकारात्मक कॉल, लाइन नंबर और स्रोत फ़ाइल, स्ट्रिंग के रूप में तर्क तक पहुंच प्रदान करता है ।
थोड़े अधिक सार शब्दों में, एक मैक्रो सिंटैक्स को एक फ़ंक्शन के रूप में डेटा के लिए है। एक फ़ंक्शन (अमूर्त में) डेटा पर कुछ परिवर्तन को एन्क्रिप्ट करता है। यह मूल्यांकन किए गए डेटा के रूप में अपनी दलीलें लेता है, उन पर कुछ कार्य करता है, और एक परिणाम देता है जो केवल डेटा भी है।
इसके विपरीत एक मैक्रो कुछ अविकसित सिंटैक्स लेता है और उस पर काम करता है। सी जैसी भाषाओं के लिए, वाक्यविन्यास टोकन स्तर पर आता है। LISP जैसे मैक्रोज़ वाली भाषाओं के लिए, उन्हें वाक्यविन्यास का प्रतिनिधित्व AST के रूप में मिलता है। मैक्रो को सिंटैक्स का एक नया हिस्सा वापस करना होगा।
एक मैक्रो आम तौर पर कुछ है कि है को संदर्भित करता जगह में विस्तार संकलन या लक्ष्य भाषा में अलग-अलग निर्देश के साथ पहले से संसाधित करने के दौरान मैक्रो "कॉल" की जगह,। रनटाइम के दौरान, आमतौर पर कोई संकेत नहीं होगा कि मैक्रो कहां से शुरू और समाप्त होता है।
यह एक सबरूटीन से अलग है , जो कोड का पुन: प्रयोज्य टुकड़ा है जो स्मृति में अलग से स्थित है, जिस पर नियंत्रण रनटाइम में पारित किया जाता है । अधिकांश प्रोग्रामिंग भाषाओं में "फ़ंक्शन", "प्रक्रियाएं" और "तरीके" इस श्रेणी में आते हैं।
जैसा कि Jörg W Mittag का जवाब चर्चा करता है, सटीक विवरण भाषाओं के बीच भिन्न होते हैं: कुछ में, जैसे C, एक मैक्रो स्रोत कोड में पाठ प्रतिस्थापन करता है; कुछ में, जैसे लिस्प, यह एक सार सिंटेक्स ट्री की तरह एक मध्यस्थ रूप में हेरफेर करता है। कुछ ग्रे क्षेत्र भी हैं: कुछ भाषाओं में "इनलाइन फ़ंक्शंस" के लिए अंकन है, जिन्हें एक फ़ंक्शन की तरह परिभाषित किया गया है, लेकिन मैक्रो जैसे संकलित कार्यक्रम में विस्तारित किया गया है।
अधिकांश भाषाएं प्रोग्रामर को प्रत्येक सबट्रॉइन के बारे में अलग-थलग करने के लिए प्रोत्साहित करती हैं, इनपुट और आउटपुट के लिए प्रकार के अनुबंधों को परिभाषित करती हैं, और कॉलिंग कोड के बारे में अन्य जानकारी छिपाती हैं। एक सबरूटीन को कॉल करने के लिए अक्सर एक प्रदर्शन प्रभाव होता है जो मैक्रोज़ को उकसाता नहीं है, और मैक्रोज़ उन तरीकों से कार्यक्रम में हेरफेर करने में सक्षम हो सकता है जो एक सबरूटीन नहीं कर सकता है। इसलिए मैक्रों को सबरूटीन्स की तुलना में "निचला स्तर" माना जा सकता है, क्योंकि वे कम सार आधार पर काम करते हैं।
मैक्रो को संकलन के दौरान निष्पादित किया जाता है, और फ़ंक्शन को रन टाइम पर निष्पादित किया जाता है।
उदाहरण:
#include <stdio.h>
#define macro_sum(x,y) (x+y)
int func_sum(x,y) {
return x+y;
}
int main(void) {
printf("%d\n", macro_sum(2,3));
printf("%d\n", func_sum(2,3));
return 0;
}
इसलिए संकलन के दौरान कोड वास्तव में बदल जाता है:
#include <stdio.h>
int func_sum(x,y) {
return x+y;
}
int main(void) {
printf("%d\n", (2+3));
printf("%d\n", func_sum(2,3));
return 0;
}