2015-10-24 5 views
14

केस 1:मुख्य रूप से 'int मुख्य (शून्य)' के रूप में घोषित करते समय कमांड लाइन तर्कों को पार करते समय कोई त्रुटि क्यों नहीं है?

void hello(void) { 
    //something 
} 

int main() 
{ 
    hello(1); //error 
    return 0; 
} 

केस 2:

int main(void) { 
    //something 
    return 0; 
} 

निष्पादन:

./a.out something something //No error, Why? 

क्यों कोई त्रुटि नहीं है? main कोई तर्क नहीं ले पाएगा। तो कमांड लाइन से तर्क प्रदान करना क्यों संभव है?

+0

आप एक त्रुटि की अपेक्षा क्यों करेंगे? –

+0

@ ओलिवर चार्ल्सवर्थ क्योंकि हम मुख्य रूप से तर्क पारित कर रहे हैं? कंपाइलर तस्वीर में नहीं आता है लेकिन रनटाइम/लोडटाइम पर क्यों कोई त्रुटि नहीं है? – JagsVG

+2

शैल * हमेशा * प्रोग्राम में इसके तर्क भेजता है - भले ही आप कोई भी प्रदान न करें (आमतौर पर यह 'argv [0] 'भेजता है)। 'मुख्य 'समान रूप से' हैलो 'के रूप में कार्य नहीं है। – usr2564301

उत्तर

14

क्योंकि सी कंपाइलर और कमांड लाइन दुभाषिया (या जो भी आपके प्रोग्राम को आमंत्रित करने के लिए उपयोग किया जाता है) अलग-अलग चीजें हैं।

सी भाषा विभिन्न तरीकों की अनुमति देती है कि कैसे मुख्य() घोषित किया जा सकता है।

कमांड लाइन दुभाषिया कार्यक्रम के लिए कोई तर्क उपलब्ध कराएगा। यदि कार्यक्रम उन्हें अनदेखा करता है, तो इसका कोई भी व्यवसाय नहीं है।

कमांड लाइन दुभाषिया यह भी नहीं जानता कि आपने अपने प्रोग्राम को संकलित करने के लिए सी का उपयोग किया है। मेरे कंप्यूटर पर, कार्यक्रम सी, सी ++, उद्देश्य-सी, उद्देश्य-सी ++, स्विफ्ट, फोरट्रान, एडा, आदि में लिखा जा सकता है। इनमें से प्रत्येक कंपाइलर कमांड लाइन से कमांड स्वीकार करने के लिए चीजें कर सकता है या नहीं कर सकता है।

9

विनिर्देश और न ही संकलित परिणाम की जाँच नहीं है, यह कोई त्रुटि के कारण होगा, क्योंकि सी क्रम तर्क और उन्हें main() के पास जाएगा, लेकिन main() के इस प्रकार से पारित कर दिया तर्कों पर ध्यान नहीं देगा, और साफ करने के लिए फोन करने वाले का कर्तव्य अगर यह होता है तर्क के रूप में उपयोग की गई स्मृति (ढेर) को ऊपर उठाएं, इससे कुछ तर्क प्राप्त हो जाएंगे और कोड में उनका उपयोग नहीं किया जाएगा।

इस कोड सी में त्रुटियों उत्सर्जन नहीं होगा:

void hello(); // in C, the compiler won't check arguments 

int main() { 
    hello(1); //no error 
    return 0; 
} 

void hello(void) { 
    //something 
} 
+0

मुझे कभी नहीं पता था कि 'शून्य हैलो();' शून्य शून्य (शून्य) से अलग व्यवहार करेगा; 'दिलचस्प। और मैंने 1 9 8 9 में सी सीखा। ओह ठीक है। –

+0

मुझे लगता है कि आप यहां एक उत्कृष्ट बिंदु बनाते हैं, लेकिन यह छिपी हुई है: "मुख्य 'के' तर्क '* को स्टैक क्लीनअप की आवश्यकता नहीं है *"। क्या वो सही है? (दोनों का अर्थ है कि मैंने इसे आपके उत्तर से कैसे पढ़ा और, वास्तव में, वास्तव में।) – usr2564301

+3

@ जोंगवेयर 'मुख्य' को पारित तर्कों को उस कार्य द्वारा ढेर से साफ कर दिया गया है जो * कॉल * 'मुख्य 'है, जो एक शिम है सी पुस्तकालय, और वह कार्य नहीं जानता है कि कैसे 'मुख्य' घोषित किया गया था। यह 'मुख्य' के लिए विशेष नहीं है; यह सभी कार्यों के लिए सामान्य सी कॉलिंग सम्मेलन है। ('__stdcall' जैसे कंपाइलर एक्सटेंशन सम्मेलन को बदल सकते हैं। खराब चीजें तब होती हैं जब आप उन्हें' मुख्य 'पर लागू करते हैं - या सी लाइब्रेरी द्वारा बुलाए गए किसी अन्य फ़ंक्शन पर।) – zwol

5

क्योंकि ./a.out something something सीधे अपने मुख्य कार्य बुला नहीं है। सी रनटाइम लाइब्रेरी द्वारा मुख्य कार्य को बुलाया जा रहा है। कमांड लाइन तर्क लोडर/सी रनटाइम द्वारा स्टैक (बहुत शुरुआत) पर किसी क्षेत्र में कहीं भी रखा जाता है। यदि आप इन तर्कों का उपयोग करना चाहते हैं या नहीं, तो यह आपके ऊपर है।

प्लस जैसा कि टिप्पणियों में से एक में इंगित किया गया है, साथ ही कम से कम एक कमांड लाइन तर्क हमेशा किसी भी तरह से पारित किया जाता है (प्रोग्राम ./a.out का सटीक होना) - तो आपको उस मामले में भी एक त्रुटि के बारे में सोचना होगा ।

2

जब आप gcc program_name.c का उपयोग करके अपने प्रोग्राम को संकलित करते हैं, तो संकलक किसी संभावित संकलन समय चेतावनी या त्रुटि की रिपोर्ट करेगा। चूंकि कमांड लाइन तर्क संकलन समय पर पारित नहीं होते हैं, इसलिए संकलक इसके बारे में अनजान है और प्रोग्राम केवल उन तर्कों को अनदेखा करता है।

hello के मामले में, कंपाइलर इस फ़ंक्शन के प्रोटोटाइप को जानता है और इसकी कॉल में कोई तर्क पारित होने की अपेक्षा नहीं करता है और इसलिए किसी भी तर्क के मामले में त्रुटि रिपोर्ट की जाती है।

+0

@ डाउन मतदाता; एक टिप्पणी की सराहना की जाएगी? – haccks

3

याद रखें कि आईएसओ सी main के दो संभव हस्ताक्षर निर्दिष्ट करता है: int main(void) और int main(int, char *[]) और बराबर संस्करणों उसके सरणी-टू-सूचक क्षय की वजह से int main(int, char **) की तरह।यह here विस्तार से अधिक कवर किया गया है।

इस प्रश्न का उत्तर विपरीत प्रश्न पर विचार करके किया जा सकता है: सी रनटाइम को main पर कॉल करने के लिए कैसे पता चलता है? सी अधिभार संकल्प नहीं है! यह here समझाया गया है। संक्षेप में, दूसरों को धक्का दिया जाता है लेकिन इसका उपयोग नहीं किया जाता है क्योंकि सी से ऐसा कोई संकेत नहीं होता है।

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