मुख्य की उचित घोषणा क्या है?


147

mainC ++ में फ़ंक्शन का उचित हस्ताक्षर क्या है ? सही वापसी प्रकार क्या है, और इससे मूल्य वापस करने का क्या मतलब है main? अनुमत पैरामीटर प्रकार क्या हैं, और उनके अर्थ क्या हैं?

क्या यह प्रणाली-विशिष्ट है? क्या समय के साथ वे नियम बदल गए हैं? यदि मैं उनका उल्लंघन करता हूं तो क्या होगा?


1
यह बहुत बारीकी से संबंधित है, या डुप्लिकेट से संबंधित है, C और C ++ में क्या mainलौटना चाहिए
जोनाथन लेफ़लर

@JonathanLeffler कोई मज़ाक नहीं ... इसे लगभग 8 महीने पहले संशोधन 6 में डुप्लिकेट की सूची में जोड़ा गया था।
fredoverflow

जवाबों:


192

mainसमारोह ग्लोबल नेम स्पेस में एक गैर सदस्य समारोह के रूप में घोषित किया जाना चाहिए। इसका अर्थ है कि यह किसी वर्ग का स्थिर या गैर-स्थिर सदस्य कार्य नहीं हो सकता है, न ही इसे किसी नाम स्थान (यहां तक ​​कि अनाम नाम स्थान) में रखा जा सकता है।

mainवैश्विक नामस्थान में एक फ़ंक्शन को छोड़कर सी ++ में नाम आरक्षित नहीं है। आप अन्य नामों की घोषणा करने के लिए स्वतंत्र हैं main, जिनमें अन्य चीजें, कक्षाएं, चर, गणना, सदस्य फ़ंक्शन और गैर-सदस्य फ़ंक्शन शामिल हैं जो वैश्विक नाम स्थान में नहीं हैं।

आप फ़ंक्शन फ़ंक्शन mainको सदस्य फ़ंक्शन या नामस्थान में घोषित कर सकते हैं , लेकिन ऐसा फ़ंक्शन ऐसा फ़ंक्शन नहीं होगा mainजो डिज़ाइन करता है जहां प्रोग्राम प्रारंभ होता है।

mainसमारोह के रूप में घोषित नहीं किया जा सकता staticया inline। यह भी अतिभारित नहीं किया जा सकता है; mainवैश्विक नाम स्थान में केवल एक फ़ंक्शन का नाम हो सकता है ।

mainसमारोह अपने कार्यक्रम में इस्तेमाल नहीं किया जा सकता: आप कॉल करने के लिए अनुमति नहीं है mainअपने कोड में कहीं से भी समारोह, न ही आप इसका पता लेने के लिए अनुमति दी जाती है।

वापसी का प्रकार mainहोना चाहिएint । किसी अन्य रिटर्न प्रकार की अनुमति नहीं है (यह नियम बोल्ड है क्योंकि यह गलत कार्यक्रमों को देखने के लिए बहुत आम है mainजो रिटर्न प्रकार के साथ घोषित करते हैं void; यह संभवतः mainफ़ंक्शन के विषय में सबसे अक्सर उल्लंघन किया जाने वाला नियम है )।

इसकी दो घोषणाएँ mainहोनी चाहिए:

int main()               // (1)
int main(int, char*[])   // (2)

में (1) , वहाँ कोई मापदंड हैं।

में (2) , वहाँ दो मापदंडों हैं और वे पारंपरिक नाम हैं argcऔर argvक्रमश:। argvकार्यक्रम के तर्कों का प्रतिनिधित्व करने वाले सी स्ट्रिंग की एक सरणी के लिए एक संकेतक है। सरणी argcमें तर्कों की संख्या है argv

आमतौर पर, argv[0]कार्यक्रम का नाम होता है, लेकिन यह हमेशा ऐसा नहीं होता है। argv[argc]एक शून्य सूचक होने की गारंटी है।

ध्यान दें कि सरणी प्रकार तर्क (जैसे char*[]) वास्तव में भेस में केवल एक सूचक प्रकार का तर्क है, निम्नलिखित दो (2) लिखने के लिए दोनों वैध तरीके हैं और वे दोनों बिल्कुल एक ही बात का अर्थ करते हैं:

int main(int argc, char* argv[])
int main(int argc, char** argv)

कुछ कार्यान्वयन अन्य प्रकार और मापदंडों की संख्या की अनुमति दे सकते हैं; आपको यह देखने के लिए अपने कार्यान्वयन के प्रलेखन की जांच करनी होगी कि यह क्या समर्थन करता है।

main()असफलता को इंगित करने के लिए शून्य और गैर-शून्य की वापसी की उम्मीद है। आपको स्पष्ट रूप से एक returnबयान लिखने की आवश्यकता नहीं है main(): यदि आप main()स्पष्ट returnविवरण के बिना वापसी करते हैं , तो यह वैसा ही है जैसा आपने लिखा था return 0;। निम्नलिखित दो main()कार्यों में समान व्यवहार है:

int main() { }
int main() { return 0; }

दो मैक्रोज़ हैं, EXIT_SUCCESSऔर इसमें EXIT_FAILUREपरिभाषित किया गया <cstdlib>है main(), क्रमशः सफलता और विफलता को इंगित करने के लिए से लौटाया जा सकता है।

द्वारा दिए गए मान main()को पारित कर दिया है exit()समारोह है, जो कार्यक्रम समाप्त हो जाता है।

ध्यान दें कि यह सब केवल एक होस्ट किए गए वातावरण (अनौपचारिक रूप से, आपके पास एक पूर्ण मानक पुस्तकालय है और वहाँ एक ओएस है जो आपका प्रोग्राम चला रहा है) के लिए संकलन करते समय लागू होता है। फ्रीस्टैंडिंग वातावरण (उदाहरण के लिए, कुछ प्रकार के एम्बेडेड सिस्टम) के लिए C ++ प्रोग्राम को संकलित करना भी संभव है, जिसमें स्टार्टअप और टर्मिनेशन पूरी तरह से कार्यान्वयन-परिभाषित हैं और एक main()फ़ंक्शन की आवश्यकता भी नहीं हो सकती है। यदि आप आधुनिक डेस्कटॉप OS के लिए C ++ लिख रहे हैं, हालांकि, आप एक होस्ट किए गए वातावरण के लिए संकलन कर रहे हैं।


1
IIRC केवल गारंटीकृत रिटर्न मान हैं, EXIT_SUCCESS (0 के समान प्रभाव), और EXIT_FAILURE। संपादित करें: आह, ठीक है, अन्य गैर-शून्य स्थिति मान वापस आ सकते हैं, लेकिन कार्यान्वयन-परिभाषित अर्थ के साथ। केवल EXIT_FAILURE को किसी तरह से विफलता मूल्य के रूप में व्याख्या करने की गारंटी है।
डेरिक तुर्क

4
@ सिंथे: सवाल अपने पहले वाक्य में पूछता है, "C ++ में मुख्य फ़ंक्शन का उचित हस्ताक्षर क्या है?" और प्रश्न को [c ++] और [c ++ - faq] दोनों में टैग किया गया है। यदि जावा या सी # उपयोगकर्ता (या कोई और) अभी भी भ्रमित हैं तो मैं इसकी मदद नहीं कर सकता। C # को Mainएक स्थिर सदस्य कार्य करने की आवश्यकता है क्योंकि इसमें नॉनमेम्बर फ़ंक्शन भी नहीं हैं। यहां तक ​​कि C89 को भी mainलौटना पड़ता है int। मैं इसके सटीक नियमों को जानने के लिए K & R C के साथ पर्याप्त रूप से परिचित नहीं हूं, लेकिन मुझे लगता है कि इसे mainवापस करने की भी आवश्यकता है intक्योंकि mainकोई रिटर्न प्रकार कुछ सामान्य नहीं था और intK & R में कोई प्रकार = निहित नहीं था ।
जेम्स मैकनेलिस

3
@ सुहैल: क्योंकि भाषा मानक कहता है कि वापसी का प्रकार होगा int
जेम्स मैक्नेलिस

1
@ सुहैल: हाँ। आपका कोड C ++ सही नहीं होगा और कई कंपाइलर आपके कोड को अस्वीकार कर देंगे।
जेम्स मैकनेलिस

2
@ सुहैल: विजुअल C ++ भाषा के विस्तार के रूप मेंvoid रिटर्न प्रकार की अनुमति देता है । संकलक जो इसे अनुमति नहीं देते हैं, उनमें जीसीसी और कोमो शामिल हैं।
जेम्स मैकनेलिस

15

मानक डॉक्स से, 3.6.1.2 मुख्य कार्य ,

इसमें वापसी का प्रकार int होगा, लेकिन अन्यथा इसका प्रकार कार्यान्वयन-परिभाषित है। सभी कार्यान्वयन मुख्य की निम्नलिखित परिभाषाओं की अनुमति देंगे:

int main() { / ... / } तथा int main(int argc, char* argv[]) { / ... / }

उत्तरार्द्ध में पर्यावरण से उस कार्यक्रम में पारित तर्कोंargc की संख्या होगी , जिसमें कार्यक्रम चलाया जाता है। यदि आर्गन नॉनजरो है, तो इन दलीलें को argv [argc-1] के माध्यम से प्रारंभिक के संकेत के रूप में argv [0] में आपूर्ति की जाएगी। अशक्त-बहुस्तरीय स्ट्रिंग्स के पात्र .....

उम्मीद है की वो मदद करदे..


2
क्या कोई विशेष कारण है कि वापसी का प्रकार क्यों mainहोना चाहिए int?
सुहैल गुप्ता

1
@ सुहेलगुप्ता: ताकि कॉलिंग प्रक्रिया जान सके कि इस प्रक्रिया को सफल माना जाना चाहिए या नहीं। अनुमति देने से voidवह मॉडल टूट जाता है। यह वास्तव में भी समझ में नहीं आता है अगर आप इसका मतलब था "हमेशा सफलता डीम"। क्योंकि आपके पास यह कहने का कोई तरीका नहीं था कि क्या प्रक्रिया वास्तव में विफल रही, तो क्या आप वास्तव में सफल हुए? नहीं, लौटो int
ऑर्बिट

4

नवीनतम प्रकाशित मानक (C ++ 14) का सटीक शब्द है:

एक कार्यान्वयन दोनों की अनुमति देगा

  • ()लौटने का एक समारोह intऔर

  • लौटने के (intलिए सूचक को सूचक का एक कार्यchar)int

के प्रकार के रूप में main

इससे यह स्पष्ट होता है कि वैकल्पिक वर्तनी की अनुमति तब तक दी जाती है जब तक कि प्रकार का mainप्रकार int()या है int(int, char**)। तो निम्नलिखित की भी अनुमति है:

  • int main(void)
  • auto main() -> int
  • int main ( )
  • signed int main()
  • typedef char **a; typedef int b, e; e main(b d, a c)

1
एनबी। मैंने इस उत्तर को अन्य थ्रेड में टिप्पणियों के रूप में पोस्ट किया, किसी ने इस थ्रेड को सबूत के रूप में उद्धृत करने का प्रयास किया int main(void)जो C ++ में सही नहीं था।
MM

3
@ स्टार्गिटर के auto main() -> intपास कम रिटर्न वाला प्रकार नहीं है। {In "(ऑटो मुख्य () {... की अनुमति नहीं है)" पर ध्यान दें और कृपया यह जानना सीखें कि आप अभी तक कुछ भी सार्थक जोड़ने के लिए पर्याप्त नहीं जानते हैं।

3

दो मान्य मुख्य हैं int main()और int main(int, char*[])। कोई और चीज संकलित हो सकती है या नहीं। यदि mainकोई मान स्पष्ट रूप से वापस नहीं करता है, तो 0 का निहितार्थ है।


1
जब मैंने वापसी के प्रकार का उल्लेख नहीं किया तो मैंने कभी भी कोड को संकलित नहीं देखा है mainक्या कोई विशिष्ट कारण है कि मुख्य का वापसी प्रकार इंट होना चाहिए?
सुहैल गुप्ता

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

2
मानक के कारण intवापसी के प्रकार की आवश्यकता होती mainहै, यह मान शेल को प्रोग्राम के एक्जिट कोड के रूप में दिया जाता है, और shए की उम्मीद करता है int
इक़ेलमैन

शायद इसका कारण अनुशासन है? एक से अधिक रास्ते हो सकते हैं। अगर वापसी का प्रकार voidवे सभी चुप हैं। साथ intहम से प्रत्येक वापसी के लिए विशिष्ट बाहर निकलें-मूल्य निर्धारित करने की main
एंड्रियास स्पिंडलर

2

वापसी मूल्यों और उनके अर्थ पर विवरण

प्रति 3.6.1 ( [basic.start.main]):

एक रिटर्न स्टेटमेंट में फ़ंक्शन mainको छोड़ने का प्रभाव होता है main(स्वचालित भंडारण अवधि के साथ किसी भी ऑब्जेक्ट को नष्ट करना) और std::exitतर्क के रूप में रिटर्न वैल्यू के साथ कॉल करना। यदि नियंत्रण mainएक returnबयान के सामना किए बिना अंत तक पहुंचता है , तो प्रभाव निष्पादन का है

return 0;

का व्यवहार std::exitधारा 18.5 ( [support.start.term]) में विस्तृत है , और स्थिति कोड का वर्णन करता है:

अंत में, नियंत्रण मेजबान वातावरण में वापस आ जाता है। यदि स्थिति शून्य है या EXIT_SUCCESS, स्थिति के सफल समापन का कार्यान्वयन-परिभाषित रूप वापस आ गया है। यदि स्थिति है EXIT_FAILURE, तो स्थिति का कार्यान्वयन-परिभाषित रूप असफल समाप्ति लौटा दी जाती है। अन्यथा दी गई स्थिति कार्यान्वयन-परिभाषित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.