9

उदाहरण के लिए,क्या होगा यदि मैं खाली पैरामीटर तालिका के साथ कोई फ़ंक्शन घोषित करता हूं, तो इसके लिए तर्क पास करें?

#include <stdio.h> 

void foo(); 

int main(void) 
{ 
     foo(); 
     foo(42); 
     foo("a string", 'C', 1.0); 
     return 0; 
} 

void foo() 
{ 
     puts("foo() is called"); 
} 

आउटपुट:

foo() is called 
foo() is called 
foo() is called 

इस कोड (बजना का उपयोग कर चेतावनी के बिना) अच्छी तरह से संकलित करता है तथा अच्छी तरह से चलाता है। लेकिन मुझे आश्चर्य है कि foo() पर दिए गए मानों का क्या होता है? क्या वे ढेर में धकेल गए हैं या सिर्फ त्याग दिए गए हैं?

शायद यह प्रश्न बेकार लगता है, लेकिन यह समझ में आता है। उदाहरण के लिए, जब मेरे पास की बजाय int main() है, और इसके लिए कुछ कमांड लाइन तर्क पास करते हैं, तो main() का व्यवहार प्रभावित होगा?

इसके अलावा, जब <stdarg.h> का उपयोग कर, कम से कम एक का नाम पैरामीटर ... से पहले आईएसओ सी के लिए आवश्यक है यह है कि हम void foo() के रूप में ऐसी घोषणाओं के उपयोग के एक समारोह के लिए अनंत तर्क शून्य से पारित करने के लिए कर सकते हैं संभव है?

मैंने देखा कि void foo() एक "गैर-प्रोटोटाइप घोषणा" है और void foo(void) अभी "प्रोटोटाइप घोषणा" है। क्या यह कुछ हद तक प्रासंगिक है?


स्पष्टीकरण

लगता है कि इस सवाल का चिह्नित है What does an empty parameter list mean? [duplicate] (दिलचस्प बात यह है कि प्रश्न भी नकल कर रहा है ...) के लिए नकल। असल में, मुझे नहीं लगता कि मेरे प्रश्न के साथ कुछ भी करना है। यह "void foo() का अर्थ सी में है" पर केंद्रित है, लेकिन मुझे पता है कि इसका मतलब है कि "मैं इसमें किसी भी तर्क को पारित कर सकता हूं", और मुझे यह भी पता है कि यह एक अश्लील विशेषता है।

लेकिन यह सवाल काफी अलग है। कीवर्ड "क्या होगा अगर" है। मैं बस जानना चाहता हूं कि क्या मैं void foo() पर विभिन्न प्रकार के तर्कों को पास करता हूं, बस ऊपर दिए गए उदाहरण कोड की तरह, क्या उन्हें foo() के अंदर उपयोग किया जा सकता है? यदि हां, तो यह कैसे किया जाता है? यदि नहीं, तो पास किए गए तर्क कोई फर्क पड़ता है? यह मेरा सवाल है।

+0

ध्यान दें कि आप शून्य या अधिक चर तर्क पारित करने के लिए एक parameterless फ़ंक्शन का उपयोग नहीं कर सकते क्योंकि 'va_start()' मैक्रो पिछले नामित तर्क के नाम की आवश्यकता है - और अगर कोई नामित तर्क हैं, यह काम नहीं कर सकता । –

+0

आप सही हैं, '' कम से कम एक तर्क की आवश्यकता है। यही कारण है कि मैं जानना चाहता हूं कि यह '()' का उपयोग कर संभव है या नहीं। बीटीडब्लू: मैंने इस सवाल को स्पष्ट किया है, क्या आप इसे देख सकते हैं? –

+2

मूल्यों को ढेर पर धकेल दिया जाता है; फ़ंक्शन लौटने पर कॉलिंग फ़ंक्शन द्वारा स्टैक को साफ़ कर दिया जाता है (वह सी कॉलिंग कन्वेंशन है; अन्य भाषाएं विभिन्न सम्मेलनों का उपयोग करती हैं, क्योंकि बुलाया गया फ़ंक्शन जानता है कि यह कितने तर्क पारित किए गए थे, या इसके तर्कों को पारित करने के लिए कितनी तर्क स्थान का उपयोग किया गया था, और इसलिए ढेर को साफ़ कर सकते हैं)। 'Foo() 'जैसे फ़ंक्शन में दिए गए तर्कों का उपयोग करने के लिए कोई पोर्टेबल तरीका नहीं है। –

उत्तर

2

सी में, void foo() एक ऐसा फ़ंक्शन घोषित करता है जो पैरामीटर की अनिर्दिष्ट संख्या लेता है। एक function निम्नलिखित तरीके से घोषित किया जाता है:

return-type function-name(parameter-list,...) { body... } 

parameter-list पैरामीटर समारोह अल्पविराम के द्वारा अलग कर लेता है की सूची है। यदि कोई पैरामीटर नहीं दिया जाता है, तो फ़ंक्शन कोई नहीं लेता है और इसे ब्रांड्स के खाली सेट या कीवर्ड शून्य के साथ परिभाषित किया जाना चाहिए। यदि कोई चर प्रकार किसी पैरामीटर सूची में चर के सामने नहीं है, तो int माना जाता है।

1

जैसा कि जोनाथन लेफ्लर ने कहा, सी के कॉलिंग सम्मेलन में यह कहा गया है कि कॉलिंग फ़ंक्शन (जिसे कॉल नहीं किया गया है) स्टैक से तर्कों को पॉप करने के लिए ज़िम्मेदार है, इसलिए प्रोग्राम क्रैश नहीं होगा, भले ही तर्कों को मेल नहीं किया जाता है ।

मैं जोड़ देंगे सी बुला सम्मेलन भी स्थापित करता है कि उस तर्क उलटे क्रम में ढेर पर धकेल दिया जाता है (अर्थात कॉल foo (1, 2)2 तो 1 धक्का)। यह बुलाए गए फ़ंक्शन को पहले पैरामीटर तक पहुंचने की इजाजत देता है भले ही वह बाकी को नहीं जानता।उदाहरण के लिए, एक समारोह घोषित int foo (int a, int b, ...) भी जानने के अन्य पैरामीटर पारित कर दिया है बिना a और b उपयोग करने में सक्षम हो जाएगा: a और b ढेर शीर्ष पर बस रहे हैं। अन्य तर्कों तक पहुंचने के लिए स्टैक पॉइंटर हैक्स की आवश्यकता होगी, जो कि printf करता है। बेशक, किसी भी उम्मीद से अपेक्षाकृत विभिन्न तर्कों का उपयोग कर मजेदार परिणाम प्राप्त कर सकते हैं (कहें, printf ("%d%d", 3.5);)।

तो, सवाल के अनुसार, हाँ, int foo() सुरक्षित रूप से तर्क के किसी भी संख्या/प्रकार के साथ कहा जा सकता है, और 1980 के दशक में यह अज्ञात मानकों तक पहुँचने के लिए स्टैक पर सूचक हैक्स उपयोग करने के लिए "सामान्य अभ्यास" पर विचार किया जाएगा। जब पोर्टेबिलिटी और पठनीयता अधिक और एक चिंता का विषय बन गया, <stdarg.h> इन सूचक हैक्स लागू करने के लिए एक पोर्टेबल तरीके के रूप में दिखाई दिया (संकलक लक्ष्य मंच के लिए सही कोड उत्पन्न होगा, तो यह एक "हैक" नहीं रह गया है)। हालांकि, के रूप में यह कहा गया है, <stdarg.h> कम से कम एक पैरामीटर, आवश्यकता है तो यह int foo() के साथ मदद नहीं कर सकता।

संबंधित मुद्दे

 संबंधित मुद्दे