2011-09-16 18 views
5

सी या सी ++ फ़ंक्शंस लिखने के लिए सर्वोत्तम प्रथाएं क्या हैं जो एक स्थिति कोड का प्रतिनिधित्व करने वाले int को वापस कर देती हैं?सी या सी ++ वापसी स्थिति

विशेष रूप से, मैं ग्राहक उपयोग के बारे में जानना चाहता हूं लेकिन अन्य युक्तियों का स्वागत है।

उदाहरण के लिए, मैं कुछ इस तरह लिख सकते हैं:

int foo() { 
    return 0; // because everything was cool 
} 

और फिर इस तरह इसका इस्तेमाल?

if (foo()) { 
    // what to do if false, e.g. non-zero, e.g. not OK 
} else { 
    // what to do if true, e.g. zero, e.g. OK 
} 

यह काम करना चाहिए क्योंकि सर्वोत्तम प्रथाओं आम तौर पर हुक्म चलाना 0 का स्थिति कोड का मतलब है कि सब कुछ ठीक था और यह भी 0 एक बूलियन बयान में false का मतलब है।

बहरहाल, यह अच्छा है, है ना होगा:

if (!foo()) { 
    // what to do if true 
} else { 
    // what to do if false 
} 
+9

'0' का मतलब बूलियन कथन में 'सत्य' नहीं है। – Chad

+1

आप सी ++ में अपवाद हैंडलिंग देखना चाहते हैं, जिसे आंशिक रूप से कोडिंग की इस शैली को खत्म करने के लिए डिज़ाइन किया गया था। – templatetypedef

+0

@ चाड: वह –

उत्तर

9

हम सी में इस का उपयोग जहां मैं काम करते हैं:

int err = foo(); 
if (err) { 
    // armageddon 
} 

असाइनमेंट और यदि जोड़ा जा सकता है, लेकिन और अधिक जटिल कार्य के साथ इसे और अधिक भ्रमित हो जाता है और कुछ लोगों को एक सशर्त में काम से उलझन में रहे हैं कॉल (और जीसीसी इसे नफरत करता है)।

सी ++ के लिए, यदि उपलब्ध हो तो मैं अपवादों को प्राथमिकता दूंगा, अन्यथा उपर्युक्त।

संपादित करें: मैं सफलता पर 0 और त्रुटि पर कुछ और लौटने की अनुशंसा करता हूं। यह यूनिक्स कमांड लाइन उपयोगिताओं क्या करता है।

+0

// और आर्मगेडन भी इसके बीमार हैं। :-) –

+6

मैं जोड़ता हूं कि ** कारण ** सफलता पर 0 और त्रुटि पर nonzero को वापस करने के लिए सबसे अच्छा है (जैसा कि बूलियन 1/0 का अर्थ सच/गलत है) यह है कि ऑपरेशन विफल होने के कई कारण हैं लेकिन केवल एक ही प्रकार की सफलता। –

+2

अपने आप में और इससे कोई फर्क नहीं पड़ता। 0 का महत्व यह है कि प्रोग्रामर आलसी हैं और इससे terse 'if (foo()) 'काम करने की अनुमति मिलती है। सफलता 42 के रूप में आसानी से हो सकती है, और हम सभी लिख सकते हैं 'अगर (foo()! = 42) ' –

1

वापसी स्थितियां आपके इंटरफ़ेस में निर्धारित और फोन करने वाले को पता होना चाहिए। कुछ विफलता पर 0 लौटते हैं (क्योंकि ! के साथ जांचना आसान है), सफलता पर कुछ वापसी 0 (क्योंकि OK पहले आइटम होने के साथ त्रुटि कोड के enum हैं)।

कोई कानून या मानक नहीं है, प्रत्येक इंटरफ़ेस अपने स्वयं के सम्मेलनों को परिभाषित करता है। सी ++ में - अपवादों का उपयोग करें।

-2
int foo() { 
    try{ 
    ... 
    return 1 
    } 
    catch 
    { 
    return 0; // because everything was cool 
    } 
} 

मैं कोशिश/पकड़ ब्लॉक में सबकुछ लपेटकर शुरू करूंगा। इसके अलावा उपयोग करने और int के बजाय यह एक बूलियन मान वापस करने के लिए और अधिक दृश्य बना सकता है। अगर कथन में परीक्षण करते समय यह थोड़ा और सहज है।

+0

कई कारणों से निगलने का अपवाद खराब अभ्यास है: http://www.google.com.ar/search? स्रोत आईडी = क्रोम और यानी = यूटीएफ -8 और क्यू = निगलने + अपवाद –

1

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

5

तुम सच में, स्थिति कोड उस तरह का उपयोग उन्हें एक enum या #define बयान है कि स्थिति कोड के इरादा वर्णन के ब्लॉक के साथ उपयोग करना चाहते हैं।

उदाहरण के लिए:

enum 
{ 
    kSuccess = 0, 
    kFailure = -1, 
} 

function foo() 
{ 
    return kSuccess; 
} 

if (kSuccess == foo()) 
{ 
    // Handle successful call to foo 
} 
else 
{ 
    // Handle failed call to foo 
} 

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

+0

"के" का क्या अर्थ है? –

+0

यह सिर्फ एक स्टाइल चीज है, जो निरंतर मानों को चर और अन्य पहचानकर्ताओं से बाहर खड़े होने में मदद करने के लिए उपयोग की जाती है। – adpalumbo

+0

@adpalumbo: लेकिन उन्हें खड़े होने की आवश्यकता क्यों है?:) – GManNickG

0

बस एक और विकल्प है कि अपनी परिस्थितियों में उपयुक्त हो सकता है के साथ बोर्ड पर कूद:

enum fooret { GOOD, BAD, UGLY, WORSE }; 

fooret foo(); // defined elsewhere 

switch(foo()) 
{ 
case BAD: 
case UGLY: 
    // maybe a recoverable failure(s)... 
    // take appropriate actions 
    break; 
case WORSE: 
    // maybe non-recoverable 
    break; 
case GOOD: 
    // successful, take appropriate actions 
    break; 
} 
2
if (foo()) { 
    // what to do if false 
} else { 
    // what to do if true 
} 

इस दृष्टिकोण के साथ समस्या अतिरिक्त नेस्टिंग है। मान लीजिए आप तीन कार्यों आप कॉल करना चाहते हैं:

if(foo1()) { 
    if(foo2()) { 
     if(foo3()) { 
      // the rest of your code 
     } else { 
      // handle error 
     } 
    } else { 
     // handle error 
    } 
} else { 
    // handle error 
} 

अतिरिक्त नेस्टिंग समस्या को हल करने के लिए, वापसी मान को उलटने:

if(!foo1()) { 
    // handle error 
    return; 
} 

if(!foo2()) { 
    // handle error 
    return; 
} 

if(!foo3()) { 
    // handle error 
    return; 
} 

यह समाधान एक और समस्या से ग्रस्त है। यह त्रुटि प्रबंधन कोड के साथ प्रोग्राम तर्क मिश्रण करता है। यह सबकुछ जटिल करता है। आदर्श रूप में, आप प्रोग्राम तर्क और त्रुटि प्रबंधन अलग करना चाहते हैं। इस समस्या को गोटो

if(!foo1()) 
    goto error1; 

if(!foo2()) 
    goto error2; 

if(!foo3()) 
    goto error3; 

return; 

error1: 
    // handle error 
    return; 
error2: 
    // handle error 
    return; 
error3: 
    // handle error 
    return; 

अधिक क्लीनर के साथ तय किया जा सकता है।

इसके अलावा, गोटो संसाधन संसाधनों की समस्या को हल कर सकता है। अधिक जानकारी के लिए एली बेंडरस्की द्वारा Using goto for error handling in C देखें।

+0

रुको, लेकिन कुछ भी शून्य नहीं होने पर "नहीं" जरूरी नहीं है, है ना? –

+0

"परिणाम 1 है यदि ऑपरेंड 0 है, और परिणाम 0 है यदि ऑपरेंड 0 नहीं है।" http://c.comsci.us/etymology/operator/logicalnot.html – Jay

+0

हां, लेकिन चूंकि सी में कोई प्रथम श्रेणी के बूलियन प्रकार नहीं है, है ना! पूर्णांक ऑपरेंड पर सिर्फ एक अंकगणित अस्वीकृति? यह एक तार्किक अस्वीकृति नहीं है, है ना? यह बस बिट्स flips। –

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