क्या मुख्य कार्य में argc और argv का नाम बदलना सुरक्षित है?


82

बहुत सारे कार्यक्रम तार के कई तर्कों और सरणियों के लिए मानक नामों का उपयोग करते हैं। मुख्य फ़ंक्शन का प्रोटोटाइप ऐसा दिखता है int main(int argc, char *argv[]);:। लेकिन अगर मैं इन चरों के लिए कस्टम नाम चुनूं तो क्या मैं कुछ तोड़ूंगा?

उदाहरण के लिए int main(int n_of_args, char *args[]);

संकलक के संदर्भ में, सब कुछ ठीक है। ये चर मुख्य कार्य के लिए स्थानीय हैं, इसलिए उनका कोई भी नाम हो सकता है। और सरल कोड पूरी तरह से बनाता है और चलाता है। लेकिन इन नामों का उपयोग प्रीप्रोसेसर द्वारा किया जा सकता है। तो क्या इन तर्कों का नाम बदलना सुरक्षित है?

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


21
हां, पूरी तरह से सुरक्षित।
डेविड होल्ज़र

55
जैसा कि सभी जवाब कहते हैं, हां, यह सुरक्षित है। लेकिन कृपया ऐसा मत करो। सभी जानते हैं कि क्या argcऔर क्या argvहैं। n_of_argsऔर argsकिसी ऐसे व्यक्ति के लिए स्पष्ट हो सकता है जो सी या सी ++ नहीं जानता है - लेकिन यह आपके दर्शक नहीं हैं।
कीथ थॉम्पसन

4
आप ऐसा कर सकते हैं, ऐसा करने के लिए पर्याप्त कारण नहीं है। हर कोई जानता है कि वे क्या हैं, और वे उनसे वैसा ही होने की उम्मीद करते हैं।
सर्गेई

10
यदि प्रश्न ठीक है "क्या मैं कुछ तोड़ दूंगा यदि मैं कस्टम नाम चुनता हूं", तो सटीक उत्तर "हां, आप अच्छी तरह से तय की गई परंपरा को तोड़ देंगे";)
Frax

12
बस उन्हें फ्लिप! .. और शुरू से ही आप नौकरी की सुरक्षा के लिए नींव रख रहे हैं :)
yano

जवाबों:


121

हां, यह सुरक्षित है, इसलिए जब तक आप मान्य चर नामों का उपयोग करते हैं। वे स्थानीय चर हैं, इसलिए उनका दायरा mainकार्य से परे नहीं है ।

सी मानक के खंड 5.1.2.2.1 से :

कार्यक्रम को प्रोग्राम स्टार्टअप कहा जाता है main। कार्यान्वयन इस फ़ंक्शन के लिए कोई प्रोटोटाइप घोषित नहीं करता है। इसे किसी प्रकार के रिटर्न intपैरामीटर के साथ परिभाषित किया जाएगा :

int main(void) { /*  ... */ }

या दो मापदंडों के साथ (यहाँ करने के लिए भेजा के रूप में argcऔर argv, हालांकि किसी भी नाम का इस्तेमाल किया जा सकता है, वे समारोह में वे घोषित किये गए हैं करने के लिए स्थानीय कर रहे हैं के रूप में ):

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

या उसके बराबर; या कुछ अन्य कार्यान्वयन-परिभाषित तरीके से

कहा जा रहा है, के अलावा argcऔर कुछ का उपयोग कर और argvदूसरों को भ्रमित कर सकते हैं जो आपके कोड को पढ़ रहे हैं जो इन मापदंडों के लिए पारंपरिक नामों के लिए उपयोग किए जाते हैं। तो क्लैरिटी की तरफ गलती करना बेहतर है।


38

नाम argcऔर argvवास्तव में C ++ 11 से पहले C ++ मानक द्वारा अनिवार्य किए गए थे। यह कहा गया है:

सभी कार्यान्वयन मुख्य की निम्नलिखित परिभाषाओं की अनुमति देंगे:

int main ()

तथा

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

और पर argcऔर आवश्यकताओं पर चर्चा करने के लिए चला गया argv

इसलिए तकनीकी रूप से, विभिन्न नामों का उपयोग करने वाला कोई भी कार्यक्रम मानक-अनुरूप नहीं था, और संकलक को इसे अस्वीकार करने की अनुमति दी गई थी। कोई भी कंपाइलर वास्तव में ऐसा नहीं करता था। इस थ्रेड को comp.std.c ++ या इस C ++ 03 ड्राफ्ट मानक के खंड 3.6.1 पर देखें ।

यह लगभग निश्चित रूप से एक मात्र निरीक्षण था, और C ++ 11 में बदल दिया गया था, जो इसके बजाय कहता है

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

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

के रूप में main(8.3.5)। बाद के रूप में, प्रदर्शनी के प्रयोजनों के लिए, पहला फ़ंक्शन पैरामीटर कहा जाता है argcऔर दूसरा फ़ंक्शन पैरामीटर कहा जाता है argv,…


29

सुनिश्चित करें कि आप इन मापदंडों को सुरक्षित रूप से अपनी इच्छानुसार नाम बदल सकते हैं

 int main(int wrzlbrnft, char* _42[]) {
 }

रेत में नाम लिखे गए हैं। अंत में संकलित कोड पर उनका कोई प्रभाव नहीं है।


केवल एक चीज जो मायने रखती है, वह है कि घोषणा और परिभाषा के पैरामीटर प्रकार वास्तव में मेल खाते हैं।

main()फ़ंक्शन के हस्ताक्षर को आंतरिक रूप से घोषित किया गया है

 int main(int, char*[]);

यदि आपको वास्तव में उन्हें कार्यान्वयन में उपयोग करने की आवश्यकता है, तो आपको उन्हें नाम देना होगा। जिन नामों का उपयोग किया जाता है वे वास्तव में अप्रासंगिक हैं जैसा कि पहले उल्लेख किया गया है।


5
जैसे ही आप इसे डालते हैं, केवल कुछ पहचानकर्ता "रेत में लिखे" होते हैं। फ़ंक्शन के नाम निश्चित रूप से नहीं हैं।
स्टीव कॉक्स

1
@SteveCox "फ़ंक्शन नाम निश्चित रूप से नहीं हैं।" अंत में वे हैं। बालू के दानों की बस संख्या :-P ...
τνῥεῖα '

3
ठीक है, लेकिन गंभीरता से। संकलन के बाद, ऑब्जेक्ट कोड में अभी भी फ़ंक्शन नाम हैं। अन्यथा जोड़ने से काम नहीं चलेगा
स्टीव कॉक्स

4
@ toν specialαῥεῖ: जब तक आप उन्हें हटाने के लिए विशेष प्रयास नहीं करते हैं, तब तक फ़ंक्शन नाम अंतिम निष्पादन योग्य नहीं रहते हैं।
निक मैट्टो

1
@ कुंदर: विंडोज पर लिंक करने के बाद, सभी गैर-विशेष कार्य नामों को बनाए नहीं रखते हैं
दानी

15

हाँ। यह सुरक्षित है, यह अजीब लगता है, लेकिन यह कुछ भी नहीं तोड़ेगा।


7

हां, विभिन्न नामों का उपयोग करना सुरक्षित है।

व्यक्तिगत रूप से, मैं इसकी अनुशंसा नहीं करूंगा, हालांकि, पारंपरिक के रूप में argcऔर argvइतने व्यापक रूप से ज्ञात हैं और हर दूसरे सी प्रोग्रामर से परिचित हैं जो कभी भी आपके कोड के लिए काम कर सकते हैं। लंबे समय में, अपने स्वयं के, विशेष, अलग-अलग नामों का उपयोग करने से आपके पाठकों के बीच कहीं अधिक भ्रम और / या निराशा पैदा होगी, क्योंकि यह कभी भी आपको बचाएगा क्योंकि आप अपने नामों को बेहतर पसंद करते हैं।

"जब रोम में हो तो वैसा ही करो जैसा की रोमन करते हैं।"


फिर भी कुछ अलग-अलग नामों का उपयोग करने के लिए स्पष्ट परिदृश्य हैं, एक कुख्यात व्यक्ति GLUT को इनिशियलाइज़ कर रहा है glutInit(&argc, argv), जहाँ तर्कों को घोषित किया जाना चाहिए और अलग-अलग तरीके से इनिशियलाइज़ किया जाना चाहिए, ताकि GLUT को कमांड लाइन आर्ग्युमेंट्स खाने न दें। SO लिंक
user3078414

@ user3078414 दिलचस्प उदाहरण है, लेकिन मैं नहीं देखता कि यह कैसे कुछ भी कहता है कि चर का नाम क्या है। उस अन्य प्रश्न के उदाहरणों के अनुसार, हम आसानी से लिख सकते हैं int dummyargc = 1; char *dummyargv[1] = {(char*)"Something"}; glutInit(&dummyargc, dummyargv);
स्टीव समिट

धन्यवाद, @ स्टीव-शिखर। कुछ एपीआई दस्तावेज़ीकरण गुमराह करने वाला होता है, इसलिए यह धागा argc argvनामकरण सम्मेलन को उजागर करने में सबसे अधिक मददगार है , जैसा कि आपका योगदान उत्तर है। मैं सिर्फ अलग-अलग नामों का उपयोग करके अपनी टिप्पणी को उदाहरण के तौर पर रखता हूं। यहाँ SO लिंक है
user3078414

5

हां आप जैसा चाहें वैसा उनका नाम बदल सकते हैं। वे केवल फ़ंक्शन पैरामीटर नाम हैं, अधिक कुछ नहीं।


3

मुझे लगता है कि सभी ने तकनीकी सी ++ नियमों को अच्छी तरह से कवर किया है और अच्छा है: उत्तर हां है। आइए एक तरफ परंपरा डालें और यह तथ्य कि यह 1 विशेष कार्य विशेष और प्रतिष्ठित है जिसमें इस आधार पर परिवर्तन नहीं करने के लिए मान्य बिंदु हैं।

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

मेरे लिए इस प्रश्न में सामान्य रूप से कोड में अंग्रेजी को व्यक्त करने का विकल्प शामिल है। आप शॉर्ट हैंड डिस्क्रिप्शन से परेशान होने लगते हैं, विशेष रूप से, अगर शॉर्ट हैंड लैंड समान दिखने वाला टेक्स्ट है। हालांकि आपके उदाहरण में, n_of_args के लिए आर्गन बदलने से शॉर्टहैंड के एक प्रकार के शॉर्टहैंड को किसी अन्य प्रकार के शॉर्टहैंड में बदलने में कोई वास्तविक मूल्य वृद्धि नहीं होती है: स्पष्टीकरण या अन्य दृश्य गुण।

'नंबर' शब्द को 'n' अक्षर से बदल दिया गया है।

यदि आप एंटी शॉर्ट हैंड के दर्शन के माध्यम से एक शॉर्ट हैंड नाम बदल रहे हैं, तो ऐसा कुछ अधिक उपयुक्त हो सकता है:

मुख्य (अंतर तर्क, चार ** तर्क)

मैं हमेशा दो चीजों के बारे में सोचता हूं: चीजों का नामकरण वे क्या हैं और / या उनके निहित उपयोग से। इसे एक तर्कविरोधी कहा जाता है क्योंकि मेरे पास एक वेक्टर होने की संपत्ति दोगुनी अप्रत्यक्ष रूप से निहित है। इस प्रकार, मैं कोड कैसे लिखूंगा इसके लिए एक बेहतर लंबा हाथ है: ** तर्क।

कुछ लोग कहेंगे कि तर्क नाम का चर एक इंट के रूप में घोषित किया गया है और एक गणना नकारात्मक नहीं हो सकती है, लेकिन आपके पास एक नकारात्मक int {अहस्ताक्षरित बेहतर है} हो सकता है।

फिर, यह क्या है और इसका उपयोग कैसे किया जाता है इस व्याख्या में खेलने के लिए आता है। यदि यह एक गणना है, तो मुझे लगता है कि यह कभी भी नकारात्मक नहीं होगा। आखिरकार, आप -2 सेब की गणना कैसे कर सकते हैं। मैं कहूंगा, आप दो सेब OWE। यदि यह एक संख्या है, तो मैं एक नकारात्मक मामले को संभव होने की उम्मीद करूंगा। यही कारण है कि 'का अतिरिक्त शब्द' आपके लिए महत्वपूर्ण है। कि, और शायद एक संग्रह द्वारा संदर्भित संख्या के रूप में एक विशेष आइटम का मतलब है कि संग्रह की संपत्ति के बजाय। Ie: आर्ग्युमेंट्सनंबर = 5 का तात्पर्य एक विशिष्ट तर्क है, लेकिन संख्यावाचन नहीं।

मुख्य (int maxArgumentsIndex, char ** आर्ग्युमेंट्स)।

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

किसी भी अन्य समारोह और मैं पूरी तरह से उपयोग करेंगे:

शून्य फ़ंक्शन (const अहस्ताक्षरित int maxArgumentsIndex, const char ** तर्क)

सभी स्थितियों में लंबे हाथ के विवरणों का गुण नहीं होता है। वास्तव में, कुछ समय में एक छोटा हाथ अधिक पठनीयता प्राप्त करता है, विशेष रूप से, गणित की कक्षाएं लिखने के मामले में जैसे कि Vec3f, मैट्रिक्स, Quaternion, आदि ... मैं लगभग हमेशा गणित भाषा के बजाय गणित की भाषा से मेल खाने की कोशिश करूंगा। । फ्लोट एक्स, वाई, जेड वीआरएस। फ्लोट xComponent और पसंद

मैं समझता हूं कि यह सब एक शैली पसंद है, लेकिन विकल्पों के प्रति सचेत रहने से वास्तव में लंबे समय में मदद मिलेगी। मैं गारंटी देता हूं कि अनुभवी प्रोग्रामर परेशान हो जाते हैं जब सरणियों को बहुवचन रूप में नहीं लिखा जाता है, लेकिन फिर से, मुख्य अस्तित्व का एक विशेष खतरा है;)


2

सी मानकों के अनुसार, हाँ, आप नाम बदल सकते हैं, कुछ भी असर नहीं होने वाला है। जैसा कि मैंने समझा था, सी लैंग्वेज में, डिफ़ॉल्ट कीवर्ड / प्रकार / टोकन नामों को उद्देश्य / उपयोग के साथ परिभाषित किया गया था, उसी प्रकार यह नामों को परिभाषित किया गया था।

argc --> argument count

argv --> argument vector

जो उपयोग के संदर्भ में भी समझ में आता है, इसलिए आप किसी भी नाम की उम्मीद में बदल सकते हैं Reserved names

जीसीसी में, प्रोग्राम का निष्पादन फ़ंक्शन नाम से शुरू होता है जो mainउसके मापदंडों पर निर्भर नहीं करता है।

जब आप माइक्रो कंट्रोलर के लिए स्टैंडअलोन प्रोग्राम लिखते हैं, तो आपको नाम के बारे में परेशान होने की ज़रूरत नहीं है, mainबजाय इसके कि आप अपने स्वयं को परिभाषित कर सकें nameऔर अपने फ़ंक्शन को इंगित करने के लिए असेंबली entry_point बदल सकते हैं। यह नियंत्रक संकलक और पूर्व-परिभाषित नियंत्रक स्रोत कोड की उपलब्धता पर निर्भर करता है। मैंने कोड-योद्धा के तहत फ्रीस्केल कंट्रोलर में ऐसा किया है।

मेरा नोट:

कोड को अधिक दृश्यमान और पठनीय बनाने के लिए सामान्य मानकों / कोड शैली का पालन करना बेहतर है


0

जहां तक ​​संकलक का संबंध है यह सुरक्षित है।

केवल समस्या यह भ्रम पैदा कर सकती है। जो लोग आपके कोड को पढ़ते हैं, वे उन दो चर को उम्मीद करेंगे कि उनके मानक नाम होंगे। आप भी ऐसा कुछ कर सकते हैं:

int main(int foo, char ** bar)
{
    int argc;
    float argv;

लेकिन मुझे नहीं लगता कि मुझे यह बताने की जरूरत है कि यह कितना बुरा व्यवहार होगा।


-1

यदि आपको चर नाम पसंद नहीं हैं, तो उन्हें मैक्रो #define के साथ प्रतिस्थापित क्यों नहीं करना चाहिए :

#define yourCounterName argc
#define yourVectorName  argv 

आप कोई जोखिम नहीं लेंगे और "स्वच्छ समाधान" का उत्पादन करेंगे।


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